1 /* wrap jpeg libray for write
2  *
3  * 28/11/03 JC
4  *	- better no-overshoot on tile loop
5  * 12/11/04
6  *	- better demand size choice for eval
7  * 30/6/05 JC
8  *	- update im_error()/im_warn()
9  *	- now loads and saves exif data
10  * 30/7/05
11  * 	- now loads ICC profiles
12  * 	- now saves ICC profiles from the VIPS header
13  * 24/8/05
14  * 	- jpeg load sets vips xres/yres from exif, if possible
15  * 	- jpeg save sets exif xres/yres from vips, if possible
16  * 29/8/05
17  * 	- cut from old vips_jpeg.c
18  * 20/4/06
19  * 	- auto convert to sRGB/mono for save
20  * 13/10/06
21  * 	- add </libexif/ prefix if required
22  * 19/1/07
23  * 	- oop, libexif confusion
24  * 2/11/07
25  * 	- use im_wbuffer() API for BG writes
26  * 15/2/08
27  * 	- write CMYK if Bands == 4 and Type == CMYK
28  * 12/5/09
29  *	- fix signed/unsigned warning
30  * 13/8/09
31  * 	- allow "none" for profile, meaning don't embed one
32  * 4/2/10
33  * 	- gtkdoc
34  * 17/7/10
35  * 	- use g_assert()
36  * 	- allow space for the header in init_destination(), helps writing very
37  * 	  small JPEGs (thanks Tim Elliott)
38  * 18/7/10
39  * 	- collect im_vips2bufjpeg() output in a list of blocks ... we no
40  * 	  longer overallocate or underallocate
41  * 8/7/11
42  * 	- oop CMYK write was not inverting, thanks Ole
43  * 12/10/2011
44  * 	- write XMP data
45  * 18/10/2011
46  * 	- update Orientation as well
47  * 3/11/11
48  * 	- rebuild exif tags from coded metadata values
49  * 24/11/11
50  * 	- turn into a set of write fns ready to be called from a class
51  * 7/8/12
52  * 	- use VIPS_META_RESOLUTION_UNIT to select resolution unit
53  * 16/11/12
54  * 	- read ifds from exif fields
55  * 	- optionally parse rationals as a/b
56  * 	- update exif image dimensions
57  * 21/11/12
58  * 	- attach IPTC data (app13), thanks Gary
59  * 2/10/13 Lovell Fuller
60  * 	- add optimize_coding parameter
61  * 	- add progressive mode
62  * 12/11/13
63  * 	- add "strip" option to remove all metadata
64  * 13/11/13
65  * 	- add a "no_subsample" option to disable chroma subsample
66  * 9/9/14
67  * 	- support "none" as a resolution unit
68  * 8/7/15
69  * 	- omit oversized jpeg markers
70  * 15/7/15
71  * 	- exif tags use @name, not @title
72  * 	- set arbitrary exif tags from metadata
73  * 25/11/15
74  * 	- don't write JFIF headers if we are stripping, thanks Benjamin
75  * 13/4/16
76  * 	- remove deleted exif fields more carefully
77  * 9/5/16 felixbuenemann
78  * 	- add quant_table
79  * 26/5/16
80  * 	- switch to new orientation tag
81  * 9/7/16
82  * 	- turn off chroma subsample for Q >= 90
83  * 7/11/16
84  * 	- move exif handling out to exif.c
85  * 27/2/17
86  * 	- use dbuf for memory output
87  * 19/12/17 Lovell
88  * 	- fix a leak with an error during buffer output
89  * 19/4/19
90  * 	- fix another leak with error during buffer output
91  * 19/7/19
92  * 	- ignore large XMP
93  * 14/10/19
94  * 	- revise for target IO
95  * 18/2/20 Elad-Laufer
96  * 	- add subsample_mode, deprecate no_subsample
97  * 13/9/20
98  * 	- only write JFIF resolution if we don't have EXIF
99  * 7/10/21 Manthey
100  * 	- add restart_interval
101  * 21/10/21 usualuse
102  * 	- raise single-chunk limit on APP to 65533
103  */
104 
105 /*
106 
107     This file is part of VIPS.
108 
109     VIPS is free software; you can redistribute it and/or modify
110     it under the terms of the GNU Lesser General Public License as published by
111     the Free Software Foundation; either version 2 of the License, or
112     (at your option) any later version.
113 
114     This program is distributed in the hope that it will be useful,
115     but WITHOUT ANY WARRANTY; without even the implied warranty of
116     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
117     GNU Lesser General Public License for more details.
118 
119     You should have received a copy of the GNU Lesser General Public License
120     along with this program; if not, write to the Free Software
121     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
122     02110-1301  USA
123 
124  */
125 
126 /*
127 
128     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
129 
130  */
131 
132 /*
133 #define VIPS_DEBUG
134 #define DEBUG
135  */
136 
137 #ifdef HAVE_CONFIG_H
138 #include <config.h>
139 #endif /*HAVE_CONFIG_H*/
140 #include <vips/intl.h>
141 
142 #ifdef HAVE_JPEG
143 
144 #include <stdio.h>
145 #include <stdlib.h>
146 #include <string.h>
147 #include <setjmp.h>
148 #include <math.h>
149 
150 #include <vips/vips.h>
151 #include <vips/debug.h>
152 #include <vips/internal.h>
153 
154 #include "pforeign.h"
155 
156 #include "jpeg.h"
157 
158 #define ICC_MARKER  (JPEG_APP0 + 2)     /* JPEG marker code for ICC */
159 #define ICC_OVERHEAD_LEN  14            /* size of non-profile data in APP2 */
160 #define MAX_BYTES_IN_MARKER  65533      /* maximum data len of a JPEG marker */
161 #define MAX_DATA_BYTES_IN_MARKER  (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
162 
163 /* New output message method - send to VIPS.
164  */
165 void
vips__new_output_message(j_common_ptr cinfo)166 vips__new_output_message( j_common_ptr cinfo )
167 {
168 	char buffer[JMSG_LENGTH_MAX];
169 
170 	(*cinfo->err->format_message)( cinfo, buffer );
171 	vips_error( "VipsJpeg", _( "%s" ), buffer );
172 
173 #ifdef DEBUG
174 	printf( "vips__new_output_message: \"%s\"\n", buffer );
175 #endif /*DEBUG*/
176 
177 	/* This is run for things like file truncated. Signal invalidate to
178 	 * force this op out of cache.
179 	 */
180         if( cinfo->client_data )
181 		vips_foreign_load_invalidate( VIPS_IMAGE( cinfo->client_data ) );
182 }
183 
184 /* New error_exit handler.
185  */
186 void
vips__new_error_exit(j_common_ptr cinfo)187 vips__new_error_exit( j_common_ptr cinfo )
188 {
189 	ErrorManager *eman = (ErrorManager *) cinfo->err;
190 
191 #ifdef DEBUG
192 	printf( "vips__new_error_exit:\n" );
193 #endif /*DEBUG*/
194 
195 	/* Close the fp if necessary.
196 	 */
197 	if( eman->fp ) {
198 		(void) fclose( eman->fp );
199 		eman->fp = NULL;
200 	}
201 
202 	/* Send the error message to VIPS. This method is overridden above.
203 	 */
204 	(*cinfo->err->output_message)( cinfo );
205 
206 	/* Jump back.
207 	 */
208 	longjmp( eman->jmp, 1 );
209 }
210 
211 /* What we track during a JPEG write.
212  */
213 typedef struct {
214 	VipsImage *in;
215 	struct jpeg_compress_struct cinfo;
216         ErrorManager eman;
217 	JSAMPROW *row_pointer;
218 	VipsImage *inverted;
219 } Write;
220 
221 static void
write_destroy(Write * write)222 write_destroy( Write *write )
223 {
224 	jpeg_destroy_compress( &write->cinfo );
225 	VIPS_FREE( write->row_pointer );
226 	VIPS_UNREF( write->inverted );
227 	VIPS_UNREF( write->in );
228 
229 	g_free( write );
230 }
231 
232 static Write *
write_new(VipsImage * in)233 write_new( VipsImage *in )
234 {
235 	Write *write;
236 
237 	if( !(write = g_new0( Write, 1 )) )
238 		return( NULL );
239 
240 	write->in = NULL;
241 	write->row_pointer = NULL;
242         write->cinfo.err = jpeg_std_error( &write->eman.pub );
243 	write->cinfo.dest = NULL;
244 	write->eman.pub.error_exit = vips__new_error_exit;
245 	write->eman.pub.output_message = vips__new_output_message;
246 	write->eman.fp = NULL;
247 	write->inverted = NULL;
248 
249 	/* Make a copy of the input image since we may modify it with
250 	 * vips__exif_update() etc.
251 	 */
252 	if( vips_copy( in, &write->in, NULL ) ) {
253 		write_destroy( write );
254 		return( NULL );
255 	}
256 
257         return( write );
258 }
259 
260 static int
write_blob(Write * write,const char * field,int app)261 write_blob( Write *write, const char *field, int app )
262 {
263 	unsigned char *data;
264 	size_t data_length;
265 
266 	if( vips_image_get_typeof( write->in, field ) ) {
267 		if( vips_image_get_blob( write->in, field,
268 			(void *) &data, &data_length ) )
269 			return( -1 );
270 
271 		/* Single jpeg markers can only hold 64kb, large objects must
272 		 * be split into multiple markers.
273 		 *
274 		 * Unfortunately, how this splitting is done depends on the
275 		 * data type. For example, ICC and XMP have completely
276 		 * different ways of doing this.
277 		 *
278 		 * For now, just ignore oversize objects and warn.
279 		 */
280 		if( data_length > MAX_BYTES_IN_MARKER )
281 			g_warning( _( "field \"%s\" is too large "
282 				"for a single JPEG marker, ignoring" ),
283 				field );
284 		else {
285 #ifdef DEBUG
286 			printf( "write_blob: attaching %zd bytes of %s\n",
287 				data_length, field );
288 #endif /*DEBUG*/
289 
290 			jpeg_write_marker( &write->cinfo, app,
291 				data, data_length );
292 		}
293 	}
294 
295 	return( 0 );
296 }
297 
298 #define XML_URL "http://ns.adobe.com/xap/1.0/"
299 
300 static int
write_xmp(Write * write)301 write_xmp( Write *write )
302 {
303 	unsigned char *data;
304 	size_t data_length;
305 	char *p;
306 
307 	if( !vips_image_get_typeof( write->in, VIPS_META_XMP_NAME ) )
308 		return( 0 );
309 	if( vips_image_get_blob( write->in, VIPS_META_XMP_NAME,
310 		(void *) &data, &data_length ) )
311 		return( -1 );
312 
313 	/* To write >64kb XMP it you need to parse the whole XMP object,
314 	 * pull out the most important fields, code just them into the main
315 	 * XMP block, then write any remaining XMP objects into a set of
316 	 * extended XMP markers.
317 	 *
318 	 * http://wwwimages.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/ \
319 	 * 	XMPSpecificationPart3.pdf
320 	 *
321 	 * jpeg_write_marker() with some libjpeg versions will throw a fatal
322 	 * error with large chunks.
323 	 */
324 	if( data_length > 60000 ) {
325 		g_warning( "%s", _( "VipsJpeg: large XMP not saved" ) );
326 		return( 0 );
327 	}
328 
329 	/* We need to add the magic XML URL to the start, then a null
330 	 * character, then the data.
331 	 */
332 	p = g_malloc( data_length + strlen( XML_URL ) + 1 );
333 	strcpy( p, XML_URL );
334 	memcpy( p + strlen( XML_URL ) + 1, data, data_length );
335 
336 	jpeg_write_marker( &write->cinfo, JPEG_APP0 + 1,
337 		(unsigned char *) p, data_length + strlen( XML_URL ) + 1 );
338 
339 	g_free( p );
340 
341 	return( 0 );
342 }
343 
344 static int
write_exif(Write * write)345 write_exif( Write *write )
346 {
347 	if( write_blob( write, VIPS_META_EXIF_NAME, JPEG_APP0 + 1 ) )
348 		return( -1 );
349 
350 	return( 0 );
351 }
352 
353 /* ICC writer from lcms, slight tweaks.
354  */
355 
356 /*
357  * This routine writes the given ICC profile data into a JPEG file.
358  * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
359  * the first call to jpeg_write_scanlines().
360  * (This ordering ensures that the APP2 marker(s) will appear after the
361  * SOI and JFIF or Adobe markers, but before all else.)
362  */
363 
364 static void
write_profile_data(j_compress_ptr cinfo,const JOCTET * icc_data_ptr,unsigned int icc_data_len)365 write_profile_data (j_compress_ptr cinfo,
366                    const JOCTET *icc_data_ptr,
367                    unsigned int icc_data_len)
368 {
369   unsigned int num_markers;     /* total number of markers we'll write */
370   int cur_marker = 1;           /* per spec, counting starts at 1 */
371   unsigned int length;          /* number of bytes to write in this marker */
372 
373   /* rounding up will fail for length == 0 */
374   g_assert( icc_data_len > 0 );
375 
376   /* Calculate the number of markers we'll need, rounding up of course */
377   num_markers = (icc_data_len + MAX_DATA_BYTES_IN_MARKER - 1) /
378 	  MAX_DATA_BYTES_IN_MARKER;
379 
380   while (icc_data_len > 0) {
381     /* length of profile to put in this marker */
382     length = icc_data_len;
383     if (length > MAX_DATA_BYTES_IN_MARKER)
384       length = MAX_DATA_BYTES_IN_MARKER;
385     icc_data_len -= length;
386 
387     /* Write the JPEG marker header (APP2 code and marker length) */
388     jpeg_write_m_header(cinfo, ICC_MARKER,
389                         (unsigned int) (length + ICC_OVERHEAD_LEN));
390 
391     /* Write the marker identifying string "ICC_PROFILE" (null-terminated).
392      * We code it in this less-than-transparent way so that the code works
393      * even if the local character set is not ASCII.
394      */
395     jpeg_write_m_byte(cinfo, 0x49);
396     jpeg_write_m_byte(cinfo, 0x43);
397     jpeg_write_m_byte(cinfo, 0x43);
398     jpeg_write_m_byte(cinfo, 0x5F);
399     jpeg_write_m_byte(cinfo, 0x50);
400     jpeg_write_m_byte(cinfo, 0x52);
401     jpeg_write_m_byte(cinfo, 0x4F);
402     jpeg_write_m_byte(cinfo, 0x46);
403     jpeg_write_m_byte(cinfo, 0x49);
404     jpeg_write_m_byte(cinfo, 0x4C);
405     jpeg_write_m_byte(cinfo, 0x45);
406     jpeg_write_m_byte(cinfo, 0x0);
407 
408     /* Add the sequencing info */
409     jpeg_write_m_byte(cinfo, cur_marker);
410     jpeg_write_m_byte(cinfo, (int) num_markers);
411 
412     /* Add the profile data */
413     while (length--) {
414       jpeg_write_m_byte(cinfo, *icc_data_ptr);
415       icc_data_ptr++;
416     }
417     cur_marker++;
418   }
419 }
420 
421 #ifndef HAVE_EXIF
422 /* Set the JFIF resolution from the vips xres/yres tags.
423  */
424 static void
vips_jfif_resolution_from_image(struct jpeg_compress_struct * cinfo,VipsImage * image)425 vips_jfif_resolution_from_image( struct jpeg_compress_struct *cinfo,
426 	VipsImage *image )
427 {
428 	int xres, yres;
429 	const char *p;
430 	int unit;
431 
432 	/* Default to inches, more progs support it.
433 	 */
434 	unit = 1;
435 	if( vips_image_get_typeof( image, VIPS_META_RESOLUTION_UNIT ) &&
436 		!vips_image_get_string( image,
437 			VIPS_META_RESOLUTION_UNIT, &p ) ) {
438 		if( vips_isprefix( "cm", p ) )
439 			unit = 2;
440 		else if( vips_isprefix( "none", p ) )
441 			unit = 0;
442 	}
443 
444 	switch( unit ) {
445 	case 0:
446 		xres = VIPS_RINT( image->Xres );
447 		yres = VIPS_RINT( image->Yres );
448 		break;
449 
450 	case 1:
451 		xres = VIPS_RINT( image->Xres * 25.4 );
452 		yres = VIPS_RINT( image->Yres * 25.4 );
453 		break;
454 
455 	case 2:
456 		xres = VIPS_RINT( image->Xres * 10.0 );
457 		yres = VIPS_RINT( image->Yres * 10.0 );
458 		break;
459 
460 	default:
461 		g_assert_not_reached();
462 		break;
463 	}
464 
465 	VIPS_DEBUG_MSG( "vips_jfif_resolution_from_image: "
466 		"setting xres = %d, yres = %d, unit = %d\n", xres, yres, unit );
467 
468 	cinfo->density_unit = unit;
469 	cinfo->X_density = xres;
470 	cinfo->Y_density = yres;
471 }
472 #endif /*HAVE_EXIF*/
473 
474 /* Write an ICC Profile from a file into the JPEG stream.
475  */
476 static int
write_profile_file(Write * write,const char * profile)477 write_profile_file( Write *write, const char *profile )
478 {
479 	VipsBlob *blob;
480 
481 	if( vips_profile_load( profile, &blob, NULL ) )
482 		return( -1 );
483 
484 	if( blob ) {
485 		size_t length;
486 		const void *data = vips_blob_get( blob, &length );
487 
488 		write_profile_data( &write->cinfo, (JOCTET *) data, length );
489 
490 #ifdef DEBUG
491 		printf( "write_profile_file: "
492 			"attached profile \"%s\"\n", profile );
493 #endif /*DEBUG*/
494 
495 		vips_area_unref( (VipsArea *) blob );
496 	}
497 
498 	return( 0 );
499 }
500 
501 static int
write_profile_meta(Write * write)502 write_profile_meta( Write *write )
503 {
504 	const void *data;
505 	size_t length;
506 
507 	if( vips_image_get_blob( write->in,
508 		VIPS_META_ICC_NAME, &data, &length ) )
509 		return( -1 );
510 	write_profile_data( &write->cinfo, data, length );
511 
512 #ifdef DEBUG
513 	printf( "write_profile_meta: attached %zd byte profile from header\n",
514 		length );
515 #endif /*DEBUG*/
516 
517 	return( 0 );
518 }
519 
520 static int
write_jpeg_block(VipsRegion * region,VipsRect * area,void * a)521 write_jpeg_block( VipsRegion *region, VipsRect *area, void *a )
522 {
523 	Write *write = (Write *) a;
524 	int i;
525 
526 	for( i = 0; i < area->height; i++ )
527 		write->row_pointer[i] = (JSAMPROW)
528 			VIPS_REGION_ADDR( region, 0, area->top + i );
529 
530 	/* Catch any longjmp()s from jpeg_write_scanlines() here.
531 	 */
532 	if( setjmp( write->eman.jmp ) )
533 		return( -1 );
534 
535 	jpeg_write_scanlines( &write->cinfo, write->row_pointer, area->height );
536 
537 	return( 0 );
538 }
539 
540 /* Write a VIPS image to a JPEG compress struct.
541  */
542 static int
write_vips(Write * write,int qfac,const char * profile,gboolean optimize_coding,gboolean progressive,gboolean strip,gboolean trellis_quant,gboolean overshoot_deringing,gboolean optimize_scans,int quant_table,VipsForeignSubsample subsample_mode,int restart_interval)543 write_vips( Write *write, int qfac, const char *profile,
544 	gboolean optimize_coding, gboolean progressive, gboolean strip,
545 	gboolean trellis_quant, gboolean overshoot_deringing,
546 	gboolean optimize_scans, int quant_table,
547 	VipsForeignSubsample subsample_mode, int restart_interval )
548 {
549 	VipsImage *in;
550 	J_COLOR_SPACE space;
551 
552 	/* The image we'll be writing ... can change, see CMYK.
553 	 */
554 	in = write->in;
555 
556 	/* Should have been converted for save.
557 	 */
558         g_assert( in->BandFmt == VIPS_FORMAT_UCHAR );
559 	g_assert( in->Coding == VIPS_CODING_NONE );
560         g_assert( in->Bands == 1 ||
561 		in->Bands == 3 ||
562 		in->Bands == 4 );
563 
564         /* Check input image.
565          */
566 	if( vips_image_pio_input( in ) )
567 		return( -1 );
568 
569 	/* Set compression parameters.
570 	 */
571         write->cinfo.image_width = in->Xsize;
572         write->cinfo.image_height = in->Ysize;
573 	write->cinfo.input_components = in->Bands;
574 	if( in->Bands == 4 &&
575 		in->Type == VIPS_INTERPRETATION_CMYK ) {
576 		space = JCS_CMYK;
577 		/* IJG always sets an Adobe marker, so we should invert CMYK.
578 		 */
579 		if( vips_invert( in, &write->inverted, NULL ) )
580 			return( -1 );
581 		in = write->inverted;
582 	}
583 	else if( in->Bands == 3 )
584 		space = JCS_RGB;
585 	else if( in->Bands == 1 )
586 		space = JCS_GRAYSCALE;
587 	else
588 		/* Use luminance compression for all channels.
589 		 */
590 		space = JCS_UNKNOWN;
591 	write->cinfo.in_color_space = space;
592 
593 	/* Build VIPS output stuff now we know the image we'll be writing.
594 	 */
595 	if( !(write->row_pointer = VIPS_ARRAY( NULL, in->Ysize, JSAMPROW )) )
596 		return( -1 );
597 
598 #ifdef HAVE_JPEG_EXT_PARAMS
599 	/* Reset compression profile to libjpeg defaults
600 	 */
601 	if( jpeg_c_int_param_supported( &write->cinfo, JINT_COMPRESS_PROFILE ) )
602 		jpeg_c_set_int_param( &write->cinfo,
603 			JINT_COMPRESS_PROFILE, JCP_FASTEST );
604 #endif
605 
606 	/* Reset to default.
607 	 */
608         jpeg_set_defaults( &write->cinfo );
609 
610  	/* Compute optimal Huffman coding tables.
611 	 */
612 	write->cinfo.optimize_coding = optimize_coding;
613 
614 	/* Use a restart interval.
615 	 */
616 	if( restart_interval > 0 )
617 		write->cinfo.restart_interval = restart_interval;
618 
619 #ifdef HAVE_JPEG_EXT_PARAMS
620 	/* Apply trellis quantisation to each 8x8 block. Implies
621 	 * "optimize_coding".
622 	 */
623 	if( trellis_quant ) {
624 		if( jpeg_c_bool_param_supported( &write->cinfo,
625 			JBOOLEAN_TRELLIS_QUANT ) ) {
626 			jpeg_c_set_bool_param( &write->cinfo,
627 				JBOOLEAN_TRELLIS_QUANT, TRUE );
628 			write->cinfo.optimize_coding = TRUE;
629 		}
630 		else
631 			g_warning( "%s", _( "trellis_quant unsupported" ) );
632 	}
633 
634 	/* Apply overshooting to samples with extreme values e.g. 0 & 255
635 	 * for 8-bit.
636 	 */
637 	if( overshoot_deringing ) {
638 		if( jpeg_c_bool_param_supported( &write->cinfo,
639 			JBOOLEAN_OVERSHOOT_DERINGING ) )
640 			jpeg_c_set_bool_param( &write->cinfo,
641 				JBOOLEAN_OVERSHOOT_DERINGING, TRUE );
642 		else
643 			g_warning( "%s",
644 				_( "overshoot_deringing unsupported" ) );
645 	}
646 	/* Split the spectrum of DCT coefficients into separate scans.
647 	 * Requires progressive output. Must be set before
648 	 * jpeg_simple_progression.
649 	 */
650 	if( optimize_scans ) {
651 		if( progressive ) {
652 			if( jpeg_c_bool_param_supported( &write->cinfo,
653 				JBOOLEAN_OPTIMIZE_SCANS ) )
654 				jpeg_c_set_bool_param( &write->cinfo,
655 					JBOOLEAN_OPTIMIZE_SCANS, TRUE );
656 			else
657 				g_warning( "%s",
658 					_( "ignoring optimize_scans" ) );
659 		}
660 		else
661 			g_warning( "%s",
662 				_( "ignoring optimize_scans for baseline" ) );
663 	}
664 
665 	/* Use predefined quantization table.
666 	 */
667 	if( quant_table > 0 ) {
668 		if( jpeg_c_int_param_supported( &write->cinfo,
669 			JINT_BASE_QUANT_TBL_IDX ) )
670 			jpeg_c_set_int_param( &write->cinfo,
671 				JINT_BASE_QUANT_TBL_IDX, quant_table );
672 		else
673 			g_warning( "%s",
674 				_( "setting quant_table unsupported" ) );
675 	}
676 #else
677 	/* Using jpeglib.h without extension parameters, warn of ignored
678 	 * options.
679 	 */
680 	if( trellis_quant )
681 		g_warning( "%s", _( "ignoring trellis_quant" ) );
682 	if( overshoot_deringing )
683 		g_warning( "%s", _( "ignoring overshoot_deringing" ) );
684 	if( optimize_scans )
685 		g_warning( "%s", _( "ignoring optimize_scans" ) );
686 	if( quant_table > 0 )
687 		g_warning( "%s", _( "ignoring quant_table" ) );
688 #endif
689 
690 	/* Set compression quality. Must be called after setting params above.
691 	 */
692         jpeg_set_quality( &write->cinfo, qfac, TRUE );
693 
694 	/* Enable progressive write.
695 	 */
696 	if( progressive )
697 		jpeg_simple_progression( &write->cinfo );
698 
699 	if( subsample_mode == VIPS_FOREIGN_SUBSAMPLE_OFF ||
700 		(subsample_mode == VIPS_FOREIGN_SUBSAMPLE_AUTO &&
701 			qfac >= 90) ) {
702 		int i;
703 
704 		for( i = 0; i < in->Bands; i++ ) {
705 			write->cinfo.comp_info[i].h_samp_factor = 1;
706 			write->cinfo.comp_info[i].v_samp_factor = 1;
707 		}
708 	}
709 
710 	/* Only write the JFIF headers if we are not stripping and we have no
711 	 * EXIF. Some readers get confused if you set both.
712 	 */
713 	write->cinfo.write_JFIF_header = FALSE;
714 #ifndef HAVE_EXIF
715 	if( !strip ) {
716 		vips_jfif_resolution_from_image( &write->cinfo,  write->in );
717 		write->cinfo.write_JFIF_header = TRUE;
718 	}
719 #endif /*HAVE_EXIF*/
720 
721 	/* Write app0 and build compress tables.
722 	 */
723 	jpeg_start_compress( &write->cinfo, TRUE );
724 
725 	/* All the other APP chunks come next.
726 	 */
727 	if( !strip ) {
728 		/* We need to rebuild the exif data block from any exif tags
729 		 * on the image.
730 		 */
731 		if( vips__exif_update( write->in ) ||
732 			write_exif( write ) ||
733 			write_xmp( write ) ||
734 			write_blob( write,
735 				VIPS_META_IPTC_NAME, JPEG_APP0 + 13 ) )
736 			return( -1 );
737 
738 		/* A profile supplied as an argument overrides an embedded
739 		 * profile.
740 		 */
741 		if( profile ) {
742 			if( write_profile_file( write, profile ) )
743 				return( -1 );
744 		}
745 		else {
746 			if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) &&
747 				write_profile_meta( write ) )
748 				return( -1 );
749 		}
750 	}
751 
752 	/* Write data. Note that the write function grabs the longjmp()!
753 	 */
754 	if( vips_sink_disc( in, write_jpeg_block, write ) )
755 		return( -1 );
756 
757 	/* We have to reinstate the setjmp() before we jpeg_finish_compress().
758 	 */
759 	if( setjmp( write->eman.jmp ) )
760 		return( -1 );
761 
762 	/* This should only be called on a successful write.
763 	 */
764 	jpeg_finish_compress( &write->cinfo );
765 
766 	return( 0 );
767 }
768 
769 #define TARGET_BUFFER_SIZE (4096)
770 
771 typedef struct {
772 	/* Public jpeg fields.
773 	 */
774 	struct jpeg_destination_mgr pub;
775 
776 	/* Private stuff during write.
777 	 */
778 
779 	/* Build the output area here.
780 	 */
781 	VipsTarget *target;
782 
783 	/* Our output buffer.
784 	 */
785 	unsigned char buf[TARGET_BUFFER_SIZE];
786 } Dest;
787 
788 /* Buffer full method. This is only called when the output area is exactly
789  * full.
790  */
791 static jboolean
empty_output_buffer(j_compress_ptr cinfo)792 empty_output_buffer( j_compress_ptr cinfo )
793 {
794 	Dest *dest = (Dest *) cinfo->dest;
795 
796 	if( vips_target_write( dest->target,
797 		dest->buf, TARGET_BUFFER_SIZE ) )
798 		ERREXIT( cinfo, JERR_FILE_WRITE );
799 
800 	dest->pub.next_output_byte = dest->buf;
801 	dest->pub.free_in_buffer = TARGET_BUFFER_SIZE;
802 
803 	return( TRUE );
804 }
805 
806 /* Init dest method.
807  */
808 static void
init_destination(j_compress_ptr cinfo)809 init_destination( j_compress_ptr cinfo )
810 {
811 	Dest *dest = (Dest *) cinfo->dest;
812 
813 	dest->pub.next_output_byte = dest->buf;
814 	dest->pub.free_in_buffer = TARGET_BUFFER_SIZE;
815 }
816 
817 /* Flush any remaining bytes to the output.
818  */
819 static void
term_destination(j_compress_ptr cinfo)820 term_destination( j_compress_ptr cinfo )
821 {
822         Dest *dest = (Dest *) cinfo->dest;
823 
824 	if( vips_target_write( dest->target,
825 		dest->buf, TARGET_BUFFER_SIZE - dest->pub.free_in_buffer ) )
826 		ERREXIT( cinfo, JERR_FILE_WRITE );
827 
828 	vips_target_finish( dest->target );
829 }
830 
831 /* Set dest to one of our objects.
832  */
833 static void
target_dest(j_compress_ptr cinfo,VipsTarget * target)834 target_dest( j_compress_ptr cinfo, VipsTarget *target )
835 {
836 	Dest *dest;
837 
838 	if( !cinfo->dest ) {    /* first time for this JPEG object? */
839 		cinfo->dest = (struct jpeg_destination_mgr *)
840 			(*cinfo->mem->alloc_small)
841 				( (j_common_ptr) cinfo, JPOOL_PERMANENT,
842 				  sizeof( Dest ) );
843 	}
844 
845 	dest = (Dest *) cinfo->dest;
846 	dest->pub.init_destination = init_destination;
847 	dest->pub.empty_output_buffer = empty_output_buffer;
848 	dest->pub.term_destination = term_destination;
849 	dest->target = target;
850 }
851 
852 int
vips__jpeg_write_target(VipsImage * in,VipsTarget * target,int Q,const char * profile,gboolean optimize_coding,gboolean progressive,gboolean strip,gboolean trellis_quant,gboolean overshoot_deringing,gboolean optimize_scans,int quant_table,VipsForeignSubsample subsample_mode,int restart_interval)853 vips__jpeg_write_target( VipsImage *in, VipsTarget *target,
854 	int Q, const char *profile,
855 	gboolean optimize_coding, gboolean progressive,
856 	gboolean strip, gboolean trellis_quant,
857 	gboolean overshoot_deringing, gboolean optimize_scans,
858 	int quant_table, VipsForeignSubsample subsample_mode,
859 	int restart_interval )
860 {
861 	Write *write;
862 
863 	if( !(write = write_new( in )) )
864 		return( -1 );
865 
866 	/* Make jpeg compression object.
867  	 */
868 	if( setjmp( write->eman.jmp ) ) {
869 		/* Here for longjmp() during write_vips().
870 		 */
871 		write_destroy( write );
872 
873 		return( -1 );
874 	}
875         jpeg_create_compress( &write->cinfo );
876 
877 	/* Attach output.
878 	 */
879         target_dest( &write->cinfo, target );
880 
881 	/* Convert! Write errors come back here as an error return.
882 	 */
883 	if( write_vips( write,
884 		Q, profile, optimize_coding, progressive, strip,
885 		trellis_quant, overshoot_deringing, optimize_scans,
886 		quant_table, subsample_mode, restart_interval ) ) {
887 		write_destroy( write );
888 		return( -1 );
889 	}
890 	write_destroy( write );
891 
892 	return( 0 );
893 }
894 
895 const char *vips__jpeg_suffs[] = { ".jpg", ".jpeg", ".jpe", NULL };
896 
897 #endif /*HAVE_JPEG*/
898