📄 tif_getimage.c
字号:
while (h > 0) {
for (x = w; x > 0;) {
int32 Cb = pp[4];
int32 Cr = pp[5];
switch (x) {
default:
switch (h) {
default: YCbCrtoRGB(cp1[1], pp[ 3]); /* FALLTHROUGH */
case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
} /* FALLTHROUGH */
case 1:
switch (h) {
default: YCbCrtoRGB(cp1[0], pp[ 2]); /* FALLTHROUGH */
case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
} /* FALLTHROUGH */
}
if (x < 2) {
cp += x; cp1 += x;
x = 0;
}
else {
cp += 2; cp1 += 2;
x -= 2;
}
pp += 6;
}
if (h <= 2)
break;
h -= 2;
cp += incr, cp1 += incr;
pp += fromskew;
}
}
}
/*
* 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
*/
DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
{
(void) y;
fromskew = (fromskew * 4) / 2;
do {
x = w>>1;
do {
int32 Cb = pp[2];
int32 Cr = pp[3];
YCbCrtoRGB(cp[0], pp[0]);
YCbCrtoRGB(cp[1], pp[1]);
cp += 2;
pp += 4;
} while (--x);
if( (w&1) != 0 )
{
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 YCbCrtoRGB
static tileContigRoutine
initYCbCrConversion(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) {
TIFFError(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 tileContigRoutine
initCIELabConversion(TIFFRGBAImage* img)
{
static char module[] = "initCIELabConversion";
float *whitePoint;
float refWhite[3];
if (!img->cielab) {
img->cielab = (TIFFCIELabToRGB *)
_TIFFmalloc(sizeof(TIFFCIELabToRGB));
if (!img->cielab) {
TIFFError(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) {
TIFFError(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 int
makebwmap(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) {
TIFFError(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 int
setupMap(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) {
TIFFError(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 int
checkcmap(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 void
cvtcmap(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 int
makecmap(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) {
TIFFError(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 int
buildMap(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
TIFFWarning(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 int
pickTileContigCase(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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -