/* * 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 <limits.h> #include <stdio.h> static int gtTileContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); static int gtTileSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); static int gtStripContig(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); static int gtStripSeparate(TIFFRGBAImage *, uint32_t *, uint32_t, uint32_t); static int PickContigCase(TIFFRGBAImage *); static int PickSeparateCase(TIFFRGBAImage *); static int BuildMapUaToAa(TIFFRGBAImage *img); static int BuildMapBitdepth16To8(TIFFRGBAImage *img); static const char photoTag[] = …; /* * Helper constants used in Orientation tag handling */ #define FLIP_VERTICALLY … #define FLIP_HORIZONTALLY … #define EMSG_BUF_SIZE … /* * Color conversion constants. We will define display types here. */ static const TIFFDisplay display_sRGB = …; /* * 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[EMSG_BUF_SIZE]) { … } void TIFFRGBAImageEnd(TIFFRGBAImage *img) { … } static int isCCITTCompression(TIFF *tif) { … } int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, char emsg[EMSG_BUF_SIZE]) { … } int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t h) { … } /* * Read the specified image into an ABGR-format rastertaking in account * specified orientation. */ int TIFFReadRGBAImageOriented(TIFF *tif, uint32_t rwidth, uint32_t rheight, uint32_t *raster, int orientation, int stop) { … } /* * Read the specified image into an ABGR-format raster. Use bottom left * origin for raster by default. */ int TIFFReadRGBAImage(TIFF *tif, uint32_t rwidth, uint32_t rheight, uint32_t *raster, int stop) { … } static int setorientation(TIFFRGBAImage *img) { … } /* * Get an tile-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ static int gtTileContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t h) { … } /* * Get an tile-organized image that has * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */ static int gtTileSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t h) { … } /* * Get a strip-organized image that has * PlanarConfiguration contiguous if SamplesPerPixel > 1 * or * SamplesPerPixel == 1 */ static int gtStripContig(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t h) { … } /* * Get a strip-organized image with * SamplesPerPixel > 1 * PlanarConfiguration separated * We assume that all such images are RGB. */ static int gtStripSeparate(TIFFRGBAImage *img, uint32_t *raster, uint32_t w, uint32_t h) { … } /* * The following routines move decoded data returned * from the TIFF library into rasters filled with packed * ABGR pixels (i.e. suitable for passing to lrecwrite.) * * The routines have been created according to the most * important cases and optimized. PickContigCase and * PickSeparateCase analyze the parameters and select * the appropriate "get" and "put" routine to use. */ #define REPEAT8(op) … #define REPEAT4(op) … #define REPEAT2(op) … #define CASE8(x, op) … #define CASE4(x, op) … #define NOP #define UNROLL8(w, op1, op2) … #define UNROLL4(w, op1, op2) … #define UNROLL2(w, op1, op2) … #define SKEW(r, g, b, skew) … #define SKEW4(r, g, b, a, skew) … #define A1 … #define PACK(r, g, b) … #define PACK4(r, g, b, a) … #define W2B(v) … /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */ #define PACKW(r, g, b) … #define PACKW4(r, g, b, a) … #define DECLAREContigPutFunc(name) … /* * 8-bit palette => colormap/RGB */ DECLAREContigPutFunc(put8bitcmaptile) { … } /* * 4-bit palette => colormap/RGB */ DECLAREContigPutFunc(put4bitcmaptile) { … } /* * 2-bit palette => colormap/RGB */ DECLAREContigPutFunc(put2bitcmaptile) { … } /* * 1-bit palette => colormap/RGB */ DECLAREContigPutFunc(put1bitcmaptile) { … } /* * 8-bit greyscale => colormap/RGB */ DECLAREContigPutFunc(putgreytile) { … } /* * 8-bit greyscale with associated alpha => colormap/RGBA */ DECLAREContigPutFunc(putagreytile) { … } /* * 16-bit greyscale => colormap/RGB */ DECLAREContigPutFunc(put16bitbwtile) { … } /* * 1-bit bilevel => colormap/RGB */ DECLAREContigPutFunc(put1bitbwtile) { … } /* * 2-bit greyscale => colormap/RGB */ DECLAREContigPutFunc(put2bitbwtile) { … } /* * 4-bit greyscale => colormap/RGB */ DECLAREContigPutFunc(put4bitbwtile) { … } /* * 8-bit packed samples, no Map => RGB */ DECLAREContigPutFunc(putRGBcontig8bittile) { … } /* * 8-bit packed samples => RGBA w/ associated alpha * (known to have Map == NULL) */ DECLAREContigPutFunc(putRGBAAcontig8bittile) { … } /* * 8-bit packed samples => RGBA w/ unassociated alpha * (known to have Map == NULL) */ DECLAREContigPutFunc(putRGBUAcontig8bittile) { … } /* * 16-bit packed samples => RGB */ DECLAREContigPutFunc(putRGBcontig16bittile) { … } /* * 16-bit packed samples => RGBA w/ associated alpha * (known to have Map == NULL) */ DECLAREContigPutFunc(putRGBAAcontig16bittile) { … } /* * 16-bit packed samples => RGBA w/ unassociated alpha * (known to have Map == NULL) */ DECLAREContigPutFunc(putRGBUAcontig16bittile) { … } /* * 8-bit packed CMYK samples w/o Map => RGB * * NB: The conversion of CMYK->RGB is *very* crude. */ DECLAREContigPutFunc(putRGBcontig8bitCMYKtile) { … } /* * 8-bit packed CMYK samples w/Map => RGB * * NB: The conversion of CMYK->RGB is *very* crude. */ DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile) { … } #define DECLARESepPutFunc(name) … /* * 8-bit unpacked samples => RGB */ DECLARESepPutFunc(putRGBseparate8bittile) { … } /* * 8-bit unpacked samples => RGBA w/ associated alpha */ DECLARESepPutFunc(putRGBAAseparate8bittile) { … } /* * 8-bit unpacked CMYK samples => RGBA */ DECLARESepPutFunc(putCMYKseparate8bittile) { … } /* * 8-bit unpacked samples => RGBA w/ unassociated alpha */ DECLARESepPutFunc(putRGBUAseparate8bittile) { … } /* * 16-bit unpacked samples => RGB */ DECLARESepPutFunc(putRGBseparate16bittile) { … } /* * 16-bit unpacked samples => RGBA w/ associated alpha */ DECLARESepPutFunc(putRGBAAseparate16bittile) { … } /* * 16-bit unpacked samples => RGBA w/ unassociated alpha */ DECLARESepPutFunc(putRGBUAseparate16bittile) { … } /* * 8-bit packed CIE L*a*b 1976 samples => RGB */ DECLAREContigPutFunc(putcontig8bitCIELab8) { … } /* * 16-bit packed CIE L*a*b 1976 samples => RGB */ DECLAREContigPutFunc(putcontig8bitCIELab16) { … } /* * YCbCr -> RGB conversion and packing routines. */ #define YCbCrtoRGB … /* * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr44tile) { … } /* * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr42tile) { … } /* * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr41tile) { … } /* * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr22tile) { … } /* * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr21tile) { … } /* * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr12tile) { … } /* * 8-bit packed YCbCr samples w/ no subsampling => RGB */ DECLAREContigPutFunc(putcontig8bitYCbCr11tile) { … } /* * 8-bit packed YCbCr samples w/ no subsampling => RGB */ DECLARESepPutFunc(putseparate8bitYCbCr11tile) { … } #undef YCbCrtoRGB static int isInRefBlackWhiteRange(float f) { … } static int initYCbCrConversion(TIFFRGBAImage *img) { … } static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img) { … } /* * Greyscale images with less than 8 bits/sample are handled * with a table to avoid lots of shifts and masks. The table * is setup so that put*bwtile (below) can retrieve 8/bitspersample * pixel values simply by indexing into the table with one * number. */ static int makebwmap(TIFFRGBAImage *img) { … } /* * Construct a mapping table to convert from the range * of the data samples to [0,255] --for display. This * process also handles inverting B&W images when needed. */ static int setupMap(TIFFRGBAImage *img) { … } static int checkcmap(TIFFRGBAImage *img) { … } static void cvtcmap(TIFFRGBAImage *img) { … } /* * Palette images with <= 8 bits/sample are handled * with a table to avoid lots of shifts and masks. The table * is setup so that put*cmaptile (below) can retrieve 8/bitspersample * pixel values simply by indexing into the table with one * number. */ static int makecmap(TIFFRGBAImage *img) { … } /* * Construct any mapping table used * by the associated put routine. */ static int buildMap(TIFFRGBAImage *img) { … } /* * Select the appropriate conversion routine for packed data. */ static int PickContigCase(TIFFRGBAImage *img) { … } /* * Select the appropriate conversion routine for unpacked data. * * NB: we assume that unpacked single channel data is directed * to the "packed routines. */ static int PickSeparateCase(TIFFRGBAImage *img) { … } static int BuildMapUaToAa(TIFFRGBAImage *img) { … } static int BuildMapBitdepth16To8(TIFFRGBAImage *img) { … } /* * Read a whole strip off data from the file, and convert to RGBA form. * If this is the last strip, then it will only contain the portion of * the strip that is actually within the image space. The result is * organized in bottom to top form. */ int TIFFReadRGBAStrip(TIFF *tif, uint32_t row, uint32_t *raster) { … } int TIFFReadRGBAStripExt(TIFF *tif, uint32_t row, uint32_t *raster, int stop_on_error) { … } /* * Read a whole tile off data from the file, and convert to RGBA form. * The returned RGBA data is organized from bottom to top of tile, * and may include zeroed areas if the tile extends off the image. */ int TIFFReadRGBATile(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster) { … } int TIFFReadRGBATileExt(TIFF *tif, uint32_t col, uint32_t row, uint32_t *raster, int stop_on_error) { … }