From bb7db6e4596e496586c8de7515352bfc5087265d Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Sun, 17 Feb 2008 07:53:02 +0000 Subject: [PATCH] invert on jpeg cmyk write --- TODO | 25 +++++++++++++++------ libsrc/conversion/im_jpeg2vips.c | 6 +++--- libsrc/conversion/im_vips2jpeg.c | 37 +++++++++++++++++++++----------- 3 files changed, 47 insertions(+), 21 deletions(-) diff --git a/TODO b/TODO index f69ab308..29432192 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,12 @@ - JPEG write should know about CMYK as well, maybe write all 4 band images as - CMYK? + CMYK? probably need to test Type so we don't get confused by RGBA test CMYK JPEG write, also PNG write with new saveable can we use convert_saveable for PPM and friends as well? + should we invert CMYK on JPEG save? + - HAVE_HYPOT could define a hypot() macro? - write our own python extension to call a vips operation by name @@ -48,10 +50,12 @@ - test maxpos_avg, quite a few changes -- im_exr2vips can now use c++ api +WONTFIX +======= -Python binding -============== +- HAVE_HYPOT could define a hypot() macro? + +- im_exr2vips can now use c++ api - python startup fails with plugins in vipslib: @@ -68,8 +72,17 @@ Python binding http://www.swig.org/Doc1.3/SWIGDocumentation.html#Python_nn8 http://docs.python.org/dist/dist.html -WONTFIX -======= +- write our own python extension to call a vips operation by name + + result = vips_call ("name", args) + + then call that from VImage_method + +- do we really need VImage_method? Can't we write + + __getattr__ (self, name) = lambda (obj_to_call, arguments): + + or something like that? - can we use GraphicsMagick instead of ImageMagick? diff --git a/libsrc/conversion/im_jpeg2vips.c b/libsrc/conversion/im_jpeg2vips.c index a7d17972..a557df84 100644 --- a/libsrc/conversion/im_jpeg2vips.c +++ b/libsrc/conversion/im_jpeg2vips.c @@ -460,10 +460,10 @@ read_jpeg_header( struct jpeg_decompress_struct *cinfo, case JCS_CMYK: type = IM_TYPE_CMYK; - /* Photoshop writes CMYK JPEG inverted :-( Hopefully this is a - * reliable way to spot photoshop CMYK JPGs. + /* Photoshop writes CMYK JPEG inverted :-( Maybe this is a + * way to spot photoshop CMYK JPGs. */ - if( cinfo->saw_Adobe_marker ) + if( cinfo->saw_Adobe_marker ) *invert_pels = TRUE; break; diff --git a/libsrc/conversion/im_vips2jpeg.c b/libsrc/conversion/im_vips2jpeg.c index 8a306c12..2f08d635 100644 --- a/libsrc/conversion/im_vips2jpeg.c +++ b/libsrc/conversion/im_vips2jpeg.c @@ -196,6 +196,7 @@ typedef struct { JSAMPROW *row_pointer; char *profile_bytes; unsigned int profile_length; + IMAGE *inverted; } Write; static void @@ -207,6 +208,7 @@ write_destroy( Write *write ) IM_FREEF( fclose, write->eman.fp ); IM_FREE( write->row_pointer ); IM_FREE( write->profile_bytes ); + IM_FREEF( im_close, write->inverted ); im_free( write ); } @@ -226,22 +228,16 @@ write_new( IMAGE *in ) return( NULL ); } - write->tg = im_threadgroup_create( write->in ); - - write->row_pointer = IM_ARRAY( NULL, write->tg->nlines, JSAMPROW ); - + write->tg = NULL; + write->row_pointer = NULL; write->cinfo.err = jpeg_std_error( &write->eman.pub ); write->eman.pub.error_exit = new_error_exit; write->eman.pub.output_message = new_output_message; write->eman.fp = NULL; write->profile_bytes = NULL; write->profile_length = 0; + write->inverted = NULL; - if( !write->tg || !write->row_pointer ) { - write_destroy( write ); - return( NULL ); - } - return( write ); } @@ -542,9 +538,13 @@ write_jpeg_block( REGION *region, Rect *area, void *a, void *b ) static int write_vips( Write *write, int qfac, const char *profile ) { - IMAGE *in = write->in; + IMAGE *in; J_COLOR_SPACE space; + /* The image we'll be writing ... can change, see CMYK. + */ + in = write->in; + /* Should have been converted for save. */ assert( in->BandFmt == IM_BANDFMT_UCHAR ); @@ -565,8 +565,15 @@ write_vips( Write *write, int qfac, const char *profile ) write->cinfo.image_width = in->Xsize; write->cinfo.image_height = in->Ysize; write->cinfo.input_components = in->Bands; - if( in->Bands == 4 && in->Type == IM_TYPE_CMYK ) + if( in->Bands == 4 && in->Type == IM_TYPE_CMYK ) { space = JCS_CMYK; + /* IJG always sets an Adobe marker, so we should invert CMYK. + */ + if( !(write->inverted = im_open( "vips2jpeg_invert", "p" )) || + im_invert( in, write->inverted ) ) + return( -1 ); + in = write->inverted; + } else if( in->Bands == 3 ) space = JCS_RGB; else if( in->Bands == 1 ) @@ -577,6 +584,13 @@ write_vips( Write *write, int qfac, const char *profile ) space = JCS_UNKNOWN; write->cinfo.in_color_space = space; + /* Build VIPS output stuff now we know the image we'll be writing. + */ + write->tg = im_threadgroup_create( in ); + write->row_pointer = IM_ARRAY( NULL, write->tg->nlines, JSAMPROW ); + if( !write->tg || !write->row_pointer ) + return( -1 ); + /* Rest to default. */ jpeg_set_defaults( &write->cinfo ); @@ -607,7 +621,6 @@ write_vips( Write *write, int qfac, const char *profile ) return( -1 ); /* We have to reinstate the setjmp() before we jpeg_finish_compress(). - * No need to destroy the write: our parent does that. */ if( setjmp( write->eman.jmp ) ) return( -1 );