/* $Header: /usr/people/rmullick/cvs/tdips/tiff/src/tif_getimage.c,v 1.1 2000/04/11 18:00:18 rmullick Exp $ */
/*
* Copyright (c) 1991-1997 Sam Leffler
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the names of
* Sam Leffler and Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Sam Leffler and Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/*
* TIFF Library
*
* Read and return a packed RGBA image.
*/
#include "tiffiop.h"
#include <assert.h>
#include <stdio.h>
static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
static int pickTileContigCase(TIFFRGBAImage*);
static int pickTileSeparateCase(TIFFRGBAImage*);
static const char photoTag[] = "PhotometricInterpretation";
/*
* Check the image to see if TIFFReadRGBAImage can deal with it.
* 1/0 is returned according to whether or not the image can
* be handled. If 0 is returned, emsg contains the reason
* why it is being rejected.
*/
int
TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
{
TIFFDirectory* td = &tif->tif_dir;
uint16 photometric;
int colorchannels;
switch (td->td_bitspersample) {
case 1: case 2: case 4:
case 8: case 16:
break;
default:
sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
td->td_bitspersample);
return (0);
}
colorchannels = td->td_samplesperpixel - td->td_extrasamples;
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
switch (colorchannels) {
case 1:
photometric = PHOTOMETRIC_MINISBLACK;
break;
case 3:
photometric = PHOTOMETRIC_RGB;
break;
default:
sprintf(emsg, "Missing needed %s tag", photoTag);
return (0);
}
}
switch (photometric) {
case PHOTOMETRIC_MINISWHITE:
case PHOTOMETRIC_MINISBLACK:
case PHOTOMETRIC_PALETTE:
if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_samplesperpixel != 1) {
sprintf(emsg,
"Sorry, can not handle contiguous data with %s=%d, and %s=%d",
photoTag, photometric,
"Samples/pixel", td->td_samplesperpixel);
return (0);
}
break;
case PHOTOMETRIC_YCBCR:
if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
"Planarconfiguration", td->td_planarconfig);
return (0);
}
break;
case PHOTOMETRIC_RGB:
if (colorchannels < 3) {
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
"Color channels", colorchannels);
return (0);
}
break;
#ifdef CMYK_SUPPORT
case PHOTOMETRIC_SEPARATED:
if (td->td_inkset != INKSET_CMYK) {
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
"InkSet", td->td_inkset);
return (0);
}
if (td->td_samplesperpixel != 4) {
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
"Samples/pixel", td->td_samplesperpixel);
return (0);
}
break;
#endif
case PHOTOMETRIC_LOGL:
if (td->td_compression != COMPRESSION_SGILOG) {
sprintf(emsg, "Sorry, LogL data must have %s=%d",
"Compression", COMPRESSION_SGILOG);
return (0);
}
break;
case PHOTOMETRIC_LOGLUV:
if (td->td_compression != COMPRESSION_SGILOG &&
td->td_compression != COMPRESSION_SGILOG24) {
sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
return (0);
}
if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
"Planarconfiguration", td->td_planarconfig);
return (0);
}
break;
default:
sprintf(emsg, "Sorry, can not handle image with %s=%d",
photoTag, photometric);
return (0);
}
return (1);
}
void
TIFFRGBAImageEnd(TIFFRGBAImage* img)
{
if (img->Map)
_TIFFfree(img->Map), img->Map = NULL;
if (img->BWmap)
_TIFFfree(img->BWmap), img->BWmap = NULL;
if (img->PALmap)
_TIFFfree(img->PALmap), img->PALmap = NULL;
if (img->ycbcr)
_TIFFfree(img->ycbcr), img->ycbcr = NULL;
if( img->redcmap ) {
_TIFFfree( img->redcmap );
_TIFFfree( img->greencmap );
_TIFFfree( img->bluecmap );
}
}
static int
isCCITTCompression(TIFF* tif)
{
uint16 compress;
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
return (compress == COMPRESSION_CCITTFAX3 ||
compress == COMPRESSION_CCITTFAX4 ||
compress == COMPRESSION_CCITTRLE ||
compress == COMPRESSION_CCITTRLEW);
}
int
TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
{
uint16* sampleinfo;
uint16 extrasamples;
uint16 planarconfig;
uint16 compress;
int colorchannels;
uint16 *red_orig, *green_orig, *blue_orig;
int n_color;
/* Initialize to normal values */
img->row_offset = 0;
img->col_offset = 0;
img->redcmap = NULL;
img->greencmap = NULL;
img->bluecmap = NULL;
img->tif = tif;
img->stoponerr = stop;
TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
switch (img->bitspersample) {
case 1: case 2: case 4:
case 8: case 16:
break;
default:
sprintf(emsg, "Sorry, can not image with %d-bit samples",
img->bitspersample);
return (0);
}
img->alpha = 0;
TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
&extrasamples, &sampleinfo);
if (extrasamples == 1)
switch (sampleinfo[0]) {
case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
img->alpha = sampleinfo[0];
break;
}
colorchannels = img->samplesperpixel - extrasamples;
TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
switch (colorchannels) {
case 1:
if (isCCITTCompression(tif))
img->photometric = PHOTOMETRIC_MINISWHITE;
else
img->photometric = PHOTOMETRIC_MINISBLACK;
break;
case 3:
img->photometric = PHOTOMETRIC_RGB;
break;
default:
sprintf(emsg, "Missing needed %s tag", photoTag);
return (0);
}
}
switch (img->photometric) {
case PHOTOMETRIC_PALETTE:
if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
&red_orig, &green_orig, &blue_orig)) {
TIFFError(TIFFFileName(tif), "Missing required \"Colormap\" tag");
return (0);
}
/* copy the colormaps so we can modify them */
n_color = (1L << img->bitspersample);
img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
img->greencmap = (u
- 1
- 2
前往页