From acbb77ac40d0889f4115fd4c66d0dfc967200580 Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 26 Jan 2014 10:43:32 +0000 Subject: [PATCH] add "rgbjpeg" flag to tiffsave add a secret "rgbjpeg" flag to tiffsave to help IIPImage server iipimage server 0.9.9 and earlier don't handle YCbCr-coded JPEG tiffs correctly ... setting --rgbjpeg makes vips output RGB coded JPEG tiff which iipsrv can handle. Using this flag makes files 2x to 3x larger with no quality improvement, so it is tagged as deprecated to keep it hidden. --- ChangeLog | 1 + libvips/foreign/tiff.h | 3 ++- libvips/foreign/tiffsave.c | 13 ++++++++++++- libvips/foreign/vips2tiff.c | 15 +++++++++++---- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1cc4d0ab..a9386b99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ - foreign memory buffer images did not have the right dhint, broke command-line falsecolour on sequential images - support many Radiance readers active at once +- add secret "rgbjpeg" flag to vips_tiffsave() to help IIP 19/1/14 started 7.38.1 - bump soname, thanks benjamin diff --git a/libvips/foreign/tiff.h b/libvips/foreign/tiff.h index af8a308f..5090df53 100644 --- a/libvips/foreign/tiff.h +++ b/libvips/foreign/tiff.h @@ -47,7 +47,8 @@ int vips__tiff_write( VipsImage *in, const char *filename, gboolean pyramid, gboolean squash, VipsForeignTiffResunit resunit, double xres, double yres, - gboolean bigtiff ); + gboolean bigtiff, + gboolean rgbjpeg ); int vips__tiff_read( const char *filename, VipsImage *out, int page, gboolean readbehind ); diff --git a/libvips/foreign/tiffsave.c b/libvips/foreign/tiffsave.c index aa20c34a..14f71a92 100644 --- a/libvips/foreign/tiffsave.c +++ b/libvips/foreign/tiffsave.c @@ -4,6 +4,8 @@ * - wrap a class around the tiff writer * 17/3/12 * - argh xres/yres macro was wrong + * 26/1/14 + * - add rgbjpeg flag */ /* @@ -75,6 +77,7 @@ typedef struct _VipsForeignSaveTiff { double xres; double yres; gboolean bigtiff; + gboolean rgbjpeg; } VipsForeignSaveTiff; typedef VipsForeignSaveClass VipsForeignSaveTiffClass; @@ -123,7 +126,8 @@ vips_foreign_save_tiff_build( VipsObject *object ) tiff->pyramid, tiff->squash, tiff->resunit, tiff->xres, tiff->yres, - tiff->bigtiff ) ) + tiff->bigtiff, + tiff->rgbjpeg ) ) return( -1 ); return( 0 ); @@ -249,6 +253,13 @@ vips_foreign_save_tiff_class_init( VipsForeignSaveTiffClass *class ) VIPS_ARGUMENT_OPTIONAL_INPUT, G_STRUCT_OFFSET( VipsForeignSaveTiff, bigtiff ), FALSE ); + + VIPS_ARG_BOOL( class, "rgbjpeg", 20, + _( "RGB JPEG" ), + _( "Output RGB JPEG rather than YCbCr" ), + VIPS_ARGUMENT_OPTIONAL_INPUT | VIPS_ARGUMENT_DEPRECATED, + G_STRUCT_OFFSET( VipsForeignSaveTiff, rgbjpeg ), + FALSE ); } static void diff --git a/libvips/foreign/vips2tiff.c b/libvips/foreign/vips2tiff.c index 73081cda..0294f9ba 100644 --- a/libvips/foreign/vips2tiff.c +++ b/libvips/foreign/vips2tiff.c @@ -136,6 +136,8 @@ * 24/9/13 * - support many more vips formats, eg. complex, 32-bit int, any number * of bands, etc., see the tiff loader + * 26/1/14 + * - add RGB as well as YCbCr write */ /* @@ -261,6 +263,7 @@ typedef struct tiff_write { float yres; /* Resolution in Y */ char *icc_profile; /* Profile to embed */ int bigtiff; /* True for bigtiff write */ + int rgbjpeg; /* True for RGB not YCbCr */ GMutex *write_lock; /* Lock TIFF*() calls with this */ } TiffWrite; @@ -529,7 +532,8 @@ write_tiff_header( TiffWrite *tw, TIFF *tif, int width, int height ) } else if( tw->compression == COMPRESSION_JPEG && tw->im->Bands == 3 && - tw->im->BandFmt == VIPS_FORMAT_UCHAR ) { + tw->im->BandFmt == VIPS_FORMAT_UCHAR && + !tw->rgbjpeg ) { /* This signals to libjpeg that it can do * YCbCr chrominance subsampling from RGB, not * that we will supply the image as YCbCr. @@ -1291,7 +1295,8 @@ make_tiff_write( VipsImage *im, const char *filename, gboolean pyramid, gboolean squash, VipsForeignTiffResunit resunit, double xres, double yres, - gboolean bigtiff ) + gboolean bigtiff, + gboolean rgbjpeg ) { TiffWrite *tw; @@ -1313,6 +1318,7 @@ make_tiff_write( VipsImage *im, const char *filename, tw->onebit = squash; tw->icc_profile = profile; tw->bigtiff = bigtiff; + tw->rgbjpeg = rgbjpeg; tw->write_lock = NULL; tw->resunit = get_resunit( resunit ); @@ -1531,7 +1537,8 @@ vips__tiff_write( VipsImage *in, const char *filename, gboolean pyramid, gboolean squash, VipsForeignTiffResunit resunit, double xres, double yres, - gboolean bigtiff ) + gboolean bigtiff, + gboolean rgbjpeg ) { TiffWrite *tw; int res; @@ -1553,7 +1560,7 @@ vips__tiff_write( VipsImage *in, const char *filename, if( !(tw = make_tiff_write( in, filename, compression, Q, predictor, profile, tile, tile_width, tile_height, pyramid, squash, - resunit, xres, yres, bigtiff )) ) + resunit, xres, yres, bigtiff, rgbjpeg )) ) return( -1 ); if( tw->pyramid ) { if( !(tw->bname = vips__temp_name( "%s.tif" )) ||