diff --git a/ChangeLog b/ChangeLog index 447c3333..4e05a2e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ overlap now matches the openslide writer - wrap VipsInterpolate for C++ - so affinei and affinei_all appear in Python +- be more cautious enabling YCbCr mode in tiff write 20/7/12 started 7.30.0 - support "rs" mode in vips7 diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 55d17e7b..d383412e 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -131,6 +131,8 @@ * 2/6/12 * - copy jpeg pyramid in gather in RGB mode ... tiff4 doesn't do ycbcr * mode + * 7/8/12 + * - be more cautious enabling YCbCr mode */ /* @@ -458,15 +460,9 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) TIFFSetField( tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT ); TIFFSetField( tif, TIFFTAG_COMPRESSION, tw->compression ); - if( tw->compression == COMPRESSION_JPEG ) { + if( tw->compression == COMPRESSION_JPEG ) TIFFSetField( tif, TIFFTAG_JPEGQUALITY, tw->jpqual ); - /* Enable rgb->ycbcr conversion in the jpeg write. See also - * the photometric selection below. - */ - TIFFSetField( tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); - } - if( tw->predictor != VIPS_FOREIGN_TIFF_PREDICTOR_NONE ) TIFFSetField( tif, TIFFTAG_PREDICTOR, tw->predictor ); @@ -515,6 +511,9 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) case 3: case 4: + /* could be: RGB, RGBA, CMYK, LAB, LABA, generic + * multi-band image. + */ if( tw->im->Type == VIPS_INTERPRETATION_LAB || tw->im->Type == VIPS_INTERPRETATION_LABS ) photometric = PHOTOMETRIC_CIELAB; @@ -524,12 +523,16 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) TIFFTAG_INKSET, INKSET_CMYK ); } else if( tw->compression == COMPRESSION_JPEG && - tw->im->Bands == 3 ) + tw->im->Bands == 3 && + tw->im->BandFmt == VIPS_FORMAT_UCHAR ) { /* This signals to libjpeg that it can do * YCbCr chrominance subsampling from RGB, not * that we will supply the image as YCbCr. */ photometric = PHOTOMETRIC_YCBCR; + TIFFSetField( tif, TIFFTAG_JPEGCOLORMODE, + JPEGCOLORMODE_RGB ); + } else photometric = PHOTOMETRIC_RGB; @@ -538,9 +541,12 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) v[0] = EXTRASAMPLE_ASSOCALPHA; TIFFSetField( tif, TIFFTAG_EXTRASAMPLES, 1, v ); } + break; case 5: + /* Only CMYKA + */ if( tw->im->Type == VIPS_INTERPRETATION_CMYK ) { photometric = PHOTOMETRIC_SEPARATED; TIFFSetField( tif, @@ -1358,16 +1364,22 @@ tiff_copy( TiffWrite *tw, TIFF *out, TIFF *in ) if( tw->compression == COMPRESSION_JPEG ) { TIFFSetField( out, TIFFTAG_JPEGQUALITY, tw->jpqual ); - /* Enable rgb->ycbcr conversion in the jpeg write. See also - * the photometric selection below. + /* Only for three-band, 8-bit images. */ - TIFFSetField( out, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); + if( tw->im->Bands == 3 && + tw->im->BandFmt == VIPS_FORMAT_UCHAR ) { + /* Enable rgb->ycbcr conversion in the jpeg write. + */ + TIFFSetField( out, + TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); - /* And we want ycbcr expanded to rgb on read. Otherwise - * TIFFTileSize() will give us the size of a chrominance - * subsampled tile. - */ - TIFFSetField( in, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); + /* And we want ycbcr expanded to rgb on read. Otherwise + * TIFFTileSize() will give us the size of a chrominance + * subsampled tile. + */ + TIFFSetField( in, + TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB ); + } } /* We can't copy profiles :( Set again from TiffWrite.