📄 tif_getimage.c
字号:
{ int32 Cb = pp[2]; int32 Cr = pp[3]; YCbCrtoRGB(cp [0], pp[0]); cp += 1; pp += 4; } cp += toskew; pp += fromskew; } while (--h);}/* * 8-bit packed YCbCr samples w/ no subsampling => RGB */DECLAREContigPutFunc(putcontig8bitYCbCr11tile){ (void) y; fromskew *= 3; do { x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ do { int32 Cb = pp[1]; int32 Cr = pp[2]; YCbCrtoRGB(*cp++, pp[0]); pp += 3; } while (--x); cp += toskew; pp += fromskew; } while (--h);}#undef YCbCrtoRGBstatic tileContigRoutineinitYCbCrConversion(TIFFRGBAImage* img){ static char module[] = "initCIELabConversion"; float *luma, *refBlackWhite; uint16 hs, vs; if (img->ycbcr == NULL) { img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc( TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)) + 4*256*sizeof (TIFFRGBValue) + 2*256*sizeof (int) + 3*256*sizeof (int32) ); if (img->ycbcr == NULL) { TIFFErrorExt(img->tif->tif_clientdata, module, "No space for YCbCr->RGB conversion state"); return (NULL); } } TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma); TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE, &refBlackWhite); if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0) return NULL; /* * The 6.0 spec says that subsampling must be * one of 1, 2, or 4, and that vertical subsampling * must always be <= horizontal subsampling; so * there are only a few possibilities and we just * enumerate the cases. */ TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs); switch ((hs<<4)|vs) { case 0x44: return (putcontig8bitYCbCr44tile); case 0x42: return (putcontig8bitYCbCr42tile); case 0x41: return (putcontig8bitYCbCr41tile); case 0x22: return (putcontig8bitYCbCr22tile); case 0x21: return (putcontig8bitYCbCr21tile); case 0x11: return (putcontig8bitYCbCr11tile); } return (NULL);}static tileContigRoutineinitCIELabConversion(TIFFRGBAImage* img){ static char module[] = "initCIELabConversion"; float *whitePoint; float refWhite[3]; if (!img->cielab) { img->cielab = (TIFFCIELabToRGB *) _TIFFmalloc(sizeof(TIFFCIELabToRGB)); if (!img->cielab) { TIFFErrorExt(img->tif->tif_clientdata, module, "No space for CIE L*a*b*->RGB conversion state."); return NULL; } } TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint); refWhite[1] = 100.0F; refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1]; refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1]) / whitePoint[1] * refWhite[1]; if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) { TIFFErrorExt(img->tif->tif_clientdata, module, "Failed to initialize CIE L*a*b*->RGB conversion state."); _TIFFfree(img->cielab); return NULL; } return putcontig8bitCIELab;}/* * 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 intmakebwmap(TIFFRGBAImage* img){ TIFFRGBValue* Map = img->Map; int bitspersample = img->bitspersample; int nsamples = 8 / bitspersample; int i; uint32* p; if( nsamples == 0 ) nsamples = 1; img->BWmap = (uint32**) _TIFFmalloc( 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); if (img->BWmap == NULL) { TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table"); return (0); } p = (uint32*)(img->BWmap + 256); for (i = 0; i < 256; i++) { TIFFRGBValue c; img->BWmap[i] = p; switch (bitspersample) {#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); case 1: GREY(i>>7); GREY((i>>6)&1); GREY((i>>5)&1); GREY((i>>4)&1); GREY((i>>3)&1); GREY((i>>2)&1); GREY((i>>1)&1); GREY(i&1); break; case 2: GREY(i>>6); GREY((i>>4)&3); GREY((i>>2)&3); GREY(i&3); break; case 4: GREY(i>>4); GREY(i&0xf); break; case 8: case 16: GREY(i); break; }#undef GREY } return (1);}/* * 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 intsetupMap(TIFFRGBAImage* img){ int32 x, range; range = (int32)((1L<<img->bitspersample)-1); /* treat 16 bit the same as eight bit */ if( img->bitspersample == 16 ) range = (int32) 255; img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue)); if (img->Map == NULL) { TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for photometric conversion table"); return (0); } if (img->photometric == PHOTOMETRIC_MINISWHITE) { for (x = 0; x <= range; x++) img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range); } else { for (x = 0; x <= range; x++) img->Map[x] = (TIFFRGBValue) ((x * 255) / range); } if (img->bitspersample <= 16 && (img->photometric == PHOTOMETRIC_MINISBLACK || img->photometric == PHOTOMETRIC_MINISWHITE)) { /* * Use photometric mapping table to construct * unpacking tables for samples <= 8 bits. */ if (!makebwmap(img)) return (0); /* no longer need Map, free it */ _TIFFfree(img->Map), img->Map = NULL; } return (1);}static intcheckcmap(TIFFRGBAImage* img){ uint16* r = img->redcmap; uint16* g = img->greencmap; uint16* b = img->bluecmap; long n = 1L<<img->bitspersample; while (n-- > 0) if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256) return (16); return (8);}static voidcvtcmap(TIFFRGBAImage* img){ uint16* r = img->redcmap; uint16* g = img->greencmap; uint16* b = img->bluecmap; long i; for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {#define CVT(x) ((uint16)((x)>>8)) r[i] = CVT(r[i]); g[i] = CVT(g[i]); b[i] = CVT(b[i]);#undef CVT }}/* * 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 intmakecmap(TIFFRGBAImage* img){ int bitspersample = img->bitspersample; int nsamples = 8 / bitspersample; uint16* r = img->redcmap; uint16* g = img->greencmap; uint16* b = img->bluecmap; uint32 *p; int i; img->PALmap = (uint32**) _TIFFmalloc( 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32))); if (img->PALmap == NULL) { TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table"); return (0); } p = (uint32*)(img->PALmap + 256); for (i = 0; i < 256; i++) { TIFFRGBValue c; img->PALmap[i] = p;#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); switch (bitspersample) { case 1: CMAP(i>>7); CMAP((i>>6)&1); CMAP((i>>5)&1); CMAP((i>>4)&1); CMAP((i>>3)&1); CMAP((i>>2)&1); CMAP((i>>1)&1); CMAP(i&1); break; case 2: CMAP(i>>6); CMAP((i>>4)&3); CMAP((i>>2)&3); CMAP(i&3); break; case 4: CMAP(i>>4); CMAP(i&0xf); break; case 8: CMAP(i); break; }#undef CMAP } return (1);}/* * Construct any mapping table used * by the associated put routine. */static intbuildMap(TIFFRGBAImage* img){ switch (img->photometric) { case PHOTOMETRIC_RGB: case PHOTOMETRIC_YCBCR: case PHOTOMETRIC_SEPARATED: if (img->bitspersample == 8) break; /* fall thru... */ case PHOTOMETRIC_MINISBLACK: case PHOTOMETRIC_MINISWHITE: if (!setupMap(img)) return (0); break; case PHOTOMETRIC_PALETTE: /* * Convert 16-bit colormap to 8-bit (unless it looks * like an old-style 8-bit colormap). */ if (checkcmap(img) == 16) cvtcmap(img); else TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap"); /* * Use mapping table and colormap to construct * unpacking tables for samples < 8 bits. */ if (img->bitspersample <= 8 && !makecmap(img)) return (0); break; } return (1);}/* * Select the appropriate conversion routine for packed data. */static intpickTileContigCase(TIFFRGBAImage* img){ tileContigRoutine put = 0; if (buildMap(img)) { switch (img->photometric) { case PHOTOMETRIC_RGB: switch (img->bitspersample) { case 8: if (!img->Map) { if (img->alpha == EXTRASAMPLE_ASSOCALPHA) put = putRGBAAcontig8bittile; else if (img->alpha == EXTRASAMPLE_UNASSALPHA) put = putRGBUAcontig8bittile; else put = putRGBcontig8bittile; } else put = putRGBcontig8bitMaptile; break; case 16: put = putRGBcontig16bittile; if (!img->Map) { if (img->alpha == EXTRASAMPLE_ASSOCALPHA) put = putRGBAAcontig16bittile; else if (img->alpha == EXTRASAMPLE_UNASSALPHA) put = putRGBUAcontig16bittile; } break; } break; case PHOTOMETRIC_SEPARATED: if (img->bitspersample == 8) { if (!img->Map) put = putRGBcontig8bitCMYKtile; else put = putRGBcontig8bitCMYKMaptile; } break; case PHOTOMETRIC_PALETTE: switch (img->bitspersample) { case 8: put = put8bitcmaptile; break; case 4: put = put4bitcmaptile; break; case 2: put = put2bitcmaptile; break; case 1: put = put1bitcmaptile; break; } break; case PHOTOMETRIC_MINISWHITE: case PHOTOMETRIC_MINISBLACK: switch (img->bitspersample) { case 16: put = put16bitbwtile; break; case 8: put = putgreytile; break; case 4: put = put4bitbwtile; break; case 2: put = put2bitbwtile; break; case 1: put = put1bitbwtile; break; } break; case PHOTOMETRIC_YCBCR: if (img->bitspersample == 8) put = initYCbCrConversion(img); break; case PHOTOMETRIC_CIELAB: if (img->bitspersample == 8) put = initCIELabConversion(img); break; } } return ((img->put.contig = put) != 0);}/* * Select the appropriate conversion routine for unpacked data. * * NB: we assume that unpacked single channel data is directed * to the "packed routines. */static intpickTileSeparateCase(TIFFRGBAImage* img){ tileSeparateRoutine put = 0; if (buildMap(img)) { switch (img->photometric) { case PHOTOMETRIC_RGB: switch (img->bitspersample) { case 8: if (!img->Map) { if (img->alpha == EXTRASAMPLE_ASSOCALPHA) put = putRGBAAseparate8bittile; else if (img->alpha == EXTRASAMPLE_UNASSALPHA) put = putRGBUAseparate8bittile; else put = putRGBseparate8bittile; } else put = putRGBseparate8bitMaptile; break; case 16: put = putRGBseparate16bittile; if (!img->Map) { if (img->alpha == EXTRASAMPLE_ASSOCALPHA) put = putRGBAAseparate16bittile; else if (img->alpha == EXTRASAMPLE_UNASSALPHA) put = putRGBUAseparate16bittile; } break; } break; } } return ((img->put.separate = put) != 0);}/* * 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. */intTIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster ){ char emsg[1024] = ""; TIFFRGBAImage img; int ok; uint32 rowsperstrip, rows_to_read; if( TIFFIsTiled( tif ) ) { TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Can't use TIFFReadRGBAStrip() with tiled file."); return (0); } TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -