1 /* Load/save png image with libpng
2  *
3  * 28/11/03 JC
4  *	- better no-overshoot on tile loop
5  * 22/2/05
6  *	- read non-interlaced PNG with a line buffer (thanks Michel Brabants)
7  * 11/1/06
8  * 	- read RGBA palette-ized images more robustly (thanks Tom)
9  * 20/4/06
10  * 	- auto convert to sRGB/mono (with optional alpha) for save
11  * 1/5/06
12  * 	- from vips_png.c
13  * 8/5/06
14  * 	- set RGB16/GREY16 if appropriate
15  * 2/11/07
16  * 	- use im_wbuffer() API for BG writes
17  * 28/2/09
18  * 	- small cleanups
19  * 4/2/10
20  * 	- gtkdoc
21  * 	- fixed 16-bit save
22  * 12/5/10
23  * 	- lololo but broke 8-bit save, fixed again
24  * 20/7/10 Tim Elliott
25  * 	- added im_vips2bufpng()
26  * 8/1/11
27  * 	- get set png resolution (thanks Zhiyu Wu)
28  * 17/3/11
29  * 	- update for libpng-1.5 API changes
30  * 	- better handling of palette and 1-bit images
31  * 	- ... but we are now png 1.2.9 and later only :-( argh
32  * 28/3/11
33  * 	- argh gamma was wrong when viewed in firefox
34  * 19/12/11
35  * 	- rework as a set of fns ready for wrapping as a class
36  * 7/2/12
37  * 	- mild refactoring
38  * 	- add support for sequential reads
39  * 23/2/12
40  * 	- add a longjmp() to our error handler to stop the default one running
41  * 13/3/12
42  * 	- add ICC profile read/write
43  * 15/3/12
44  * 	- better alpha handling
45  * 	- sanity check pixel geometry before allowing read
46  * 17/6/12
47  * 	- more alpha fixes ... some images have no transparency chunk but
48  * 	  still set color_type to alpha
49  * 16/7/13
50  * 	- more robust error handling from libpng
51  * 9/8/14
52  * 	- don't check profiles, helps with libpng >=1.6.11
53  * 27/10/14 Lovell
54  * 	- add @filter option
55  * 26/2/15
56  * 	- close the read down early for a header read ... this saves an
57  * 	  fd during file read, handy for large numbers of input images
58  * 31/7/16
59  * 	- support --strip option
60  * 17/1/17
61  * 	- invalidate operation on read error
62  * 27/2/17
63  * 	- use dbuf for buffer output
64  * 30/3/17
65  * 	- better behaviour for truncated png files, thanks Yury
66  * 26/4/17
67  * 	- better @fail handling with truncated PNGs
68  * 9/4/18
69  * 	- set interlaced=1 for interlaced images
70  * 20/6/18 [felixbuenemann]
71  * 	- support png8 palette write with palette, colours, Q, dither
72  * 25/8/18
73  * 	- support xmp read/write
74  * 20/4/19
75  * 	- allow huge xmp metadata
76  * 7/10/19
77  * 	- restart after minimise
78  * 14/10/19
79  * 	- revise for connection IO
80  * 11/5/20
81  * 	- only warn for saving bad profiles, don't fail
82  * 19/2/21 781545872
83  * 	- read out background, if we can
84  * 29/8/21 joshuamsager
85  *	-  add "unlimited" flag to png load
86  */
87 
88 /*
89 
90     This file is part of VIPS.
91 
92     VIPS is free software; you can redistribute it and/or modify
93     it under the terms of the GNU Lesser General Public License as published by
94     the Free Software Foundation; either version 2 of the License, or
95     (at your option) any later version.
96 
97     This program is distributed in the hope that it will be useful,
98     but WITHOUT ANY WARRANTY; without even the implied warranty of
99     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
100     GNU Lesser General Public License for more details.
101 
102     You should have received a copy of the GNU Lesser General Public License
103     along with this program; if not, write to the Free Software
104     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
105     02110-1301  USA
106 
107  */
108 
109 /*
110 
111     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
112 
113  */
114 
115 /*
116 #define DEBUG
117 #define VIPS_DEBUG
118  */
119 
120 #ifdef HAVE_CONFIG_H
121 #include <config.h>
122 #endif /*HAVE_CONFIG_H*/
123 #include <vips/intl.h>
124 
125 #ifdef HAVE_PNG
126 
127 #include <stdio.h>
128 #include <stdlib.h>
129 #include <string.h>
130 
131 #include <vips/vips.h>
132 #include <vips/internal.h>
133 #include <vips/debug.h>
134 
135 #include "pforeign.h"
136 
137 #include <png.h>
138 
139 #if PNG_LIBPNG_VER < 10003
140 #error "PNG library too old."
141 #endif
142 
143 static void
user_error_function(png_structp png_ptr,png_const_charp error_msg)144 user_error_function( png_structp png_ptr, png_const_charp error_msg )
145 {
146 #ifdef DEBUG
147 	printf( "user_error_function: %s\n", error_msg );
148 #endif /*DEBUG*/
149 
150 	g_warning( "%s", error_msg );
151 
152 	/* This function must not return or the default error handler will be
153 	 * invoked.
154 	 */
155 	longjmp( png_jmpbuf( png_ptr ), -1 );
156 }
157 
158 static void
user_warning_function(png_structp png_ptr,png_const_charp warning_msg)159 user_warning_function( png_structp png_ptr, png_const_charp warning_msg )
160 {
161 #ifdef DEBUG
162 	printf( "user_warning_function: %s\n", warning_msg );
163 #endif /*DEBUG*/
164 
165 	g_warning( "%s", warning_msg );
166 }
167 
168 #ifndef HAVE_SPNG
169 
170 #define INPUT_BUFFER_SIZE (4096)
171 
172 /* What we track during a PNG read.
173  */
174 typedef struct {
175 	char *name;
176 	VipsImage *out;
177 	VipsFailOn fail_on;
178 	gboolean unlimited;
179 
180 	int y_pos;
181 	png_structp pPng;
182 	png_infop pInfo;
183 	png_bytep *row_pointer;
184 
185 	VipsSource *source;
186 
187 	/* read() to this buffer, copy to png as required. libpng does many
188 	 * very small reads and we want to avoid a syscall for each one.
189 	 */
190 	unsigned char input_buffer[INPUT_BUFFER_SIZE];
191 	unsigned char *next_byte;
192 	gint64 bytes_in_buffer;
193 
194 } Read;
195 
196 /* Can be called many times.
197  */
198 static void
read_destroy(Read * read)199 read_destroy( Read *read )
200 {
201 	/* We never call png_read_end(), perhaps we should. It can fail on
202 	 * truncated files, so we'd need a setjmp().
203 	 */
204 
205 	if( read->pPng )
206 		png_destroy_read_struct( &read->pPng, &read->pInfo, NULL );
207 	VIPS_UNREF( read->source );
208 	VIPS_FREE( read->row_pointer );
209 }
210 
211 static void
read_close_cb(VipsImage * out,Read * read)212 read_close_cb( VipsImage *out, Read *read )
213 {
214 	read_destroy( read );
215 }
216 
217 static void
read_minimise_cb(VipsImage * image,Read * read)218 read_minimise_cb( VipsImage *image, Read *read )
219 {
220 	if( read->source )
221 		vips_source_minimise( read->source );
222 }
223 
224 static void
vips_png_read_source(png_structp pPng,png_bytep data,png_size_t length)225 vips_png_read_source( png_structp pPng, png_bytep data, png_size_t length )
226 {
227 	Read *read = png_get_io_ptr( pPng );
228 
229 #ifdef DEBUG
230 	printf( "vips_png_read_source: read %zd bytes\n", length );
231 #endif /*DEBUG*/
232 
233 	/* libpng makes many small reads, which hurts performance if you do a
234 	 * syscall for each one. Read via our own buffer.
235 	 */
236 	while( length > 0 ) {
237 		gint64 bytes_available;
238 
239 		if( read->bytes_in_buffer <= 0 ) {
240 			gint64 bytes_read;
241 
242 			bytes_read = vips_source_read( read->source,
243 				read->input_buffer, INPUT_BUFFER_SIZE );
244 			if( bytes_read <= 0 )
245 				png_error( pPng, "not enough data" );
246 
247 			read->next_byte = read->input_buffer;
248 			read->bytes_in_buffer = bytes_read;
249 		}
250 
251 		bytes_available = VIPS_MIN( read->bytes_in_buffer, length );
252 		memcpy( data, read->next_byte, bytes_available );
253 		data += bytes_available;
254 		length -= bytes_available;
255 		read->next_byte += bytes_available;
256 		read->bytes_in_buffer -= bytes_available;
257 	}
258 }
259 
260 static Read *
read_new(VipsSource * source,VipsImage * out,VipsFailOn fail_on,gboolean unlimited)261 read_new( VipsSource *source, VipsImage *out,
262 	VipsFailOn fail_on, gboolean unlimited )
263 {
264 	Read *read;
265 
266 	if( !(read = VIPS_NEW( out, Read )) )
267 		return( NULL );
268 
269 	read->name = NULL;
270 	read->fail_on = fail_on;
271 	read->out = out;
272 	read->y_pos = 0;
273 	read->pPng = NULL;
274 	read->pInfo = NULL;
275 	read->row_pointer = NULL;
276 	read->source = source;
277 	read->unlimited = unlimited;
278 
279 	g_object_ref( source );
280 
281 	g_signal_connect( out, "close",
282 		G_CALLBACK( read_close_cb ), read );
283 	g_signal_connect( out, "minimise",
284 		G_CALLBACK( read_minimise_cb ), read );
285 
286 	if( !(read->pPng = png_create_read_struct(
287 		PNG_LIBPNG_VER_STRING, NULL,
288 		user_error_function, user_warning_function )) )
289 		return( NULL );
290 
291 	/* Prevent libpng (>=1.6.11) verifying sRGB profiles. Many PNGs have
292 	 * broken profiles, but we still want to be able to open them.
293 	 */
294 #ifdef PNG_SKIP_sRGB_CHECK_PROFILE
295 	png_set_option( read->pPng,
296 		PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON );
297 #endif /*PNG_SKIP_sRGB_CHECK_PROFILE*/
298 
299 	/* Disable CRC checking in fuzzing mode. Most fuzzed images will have
300 	 * bad CRCs so this check would break fuzzing.
301 	 */
302 #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
303 	png_set_crc_action( read->pPng,
304 		PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE );
305 #endif /*FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION*/
306 
307 	if( vips_source_rewind( source ) )
308 		return( NULL );
309 	png_set_read_fn( read->pPng, read, vips_png_read_source );
310 
311 	/* Catch PNG errors from png_read_info() etc.
312 	 */
313 	if( setjmp( png_jmpbuf( read->pPng ) ) )
314 		return( NULL );
315 
316 	if( !(read->pInfo = png_create_info_struct( read->pPng )) )
317 		return( NULL );
318 
319 #ifdef HAVE_PNG_SET_CHUNK_MALLOC_MAX
320 
321 	/* By default, libpng refuses to open files with a metadata chunk
322 	 * larger than 8mb. We've seen real files with 20mb, so set 50mb.
323 	 */
324 	png_set_chunk_malloc_max( read->pPng, 50 * 1024 * 1024 );
325 
326 	/* This limits the number of chunks. The limit from
327 	 * png_set_chunk_malloc_max() times this value is the maximum
328 	 * memory use.
329 	 *
330 	 * libnpng defaults to 1000, which is rather high.
331 	 */
332 	png_set_chunk_cache_max( read->pPng, 100 );
333 
334 #endif /*HAVE_PNG_SET_CHUNK_MALLOC_MAX*/
335 
336 	png_read_info( read->pPng, read->pInfo );
337 
338 	return( read );
339 }
340 
341 /* Set the png text data as metadata on the vips image. These are always
342  * null-terminated strings.
343  */
344 static int
vips__set_text(VipsImage * out,int i,const char * key,const char * text)345 vips__set_text( VipsImage *out, int i, const char *key, const char *text )
346 {
347 	char name[256];
348 
349 	if( strcmp( key, "XML:com.adobe.xmp" ) == 0 ) {
350 		/* Save as an XMP tag. This must be a BLOB, for compatibility
351 		 * for things like the XMP blob that the tiff loader adds.
352 		 *
353 		 * Note that this will remove the null-termination from the
354 		 * string. We must carefully reattach this.
355 		 */
356 		vips_image_set_blob_copy( out,
357 			VIPS_META_XMP_NAME, text, strlen( text ) );
358 	}
359 	else  {
360 		/* Save as a string comment. Some PNGs have EXIF data as
361 		 * text segments, but the correct way to support this is with
362 		 * png_get_eXIf_1().
363 		 */
364 		vips_snprintf( name, 256, "png-comment-%d-%s", i, key );
365 
366 		vips_image_set_string( out, name, text );
367 	}
368 
369 	return( 0 );
370 }
371 
372 /* Read a png header.
373  */
374 static int
png2vips_header(Read * read,VipsImage * out)375 png2vips_header( Read *read, VipsImage *out )
376 {
377 	png_uint_32 width, height;
378 	int bitdepth, color_type;
379 	int interlace_type;
380 	VipsDemandStyle hint;
381 
382 	png_uint_32 res_x, res_y;
383 	int unit_type;
384 
385 	png_charp name;
386 	int compression_type;
387 
388 	png_textp text_ptr;
389         int num_text;
390 
391 	/* Well thank you, libpng.
392 	 */
393 #if PNG_LIBPNG_VER < 10400
394 	png_charp profile;
395 #else
396 	png_bytep profile;
397 #endif
398 
399 	png_uint_32 proflen;
400 
401 	int bands;
402 	VipsInterpretation interpretation;
403 	double Xres, Yres;
404 
405 	if( setjmp( png_jmpbuf( read->pPng ) ) )
406 		return( -1 );
407 
408 	png_get_IHDR( read->pPng, read->pInfo,
409 		&width, &height, &bitdepth, &color_type,
410 		&interlace_type, NULL, NULL );
411 
412 	/* png_get_channels() gives us 1 band for palette images ... so look
413 	 * at colour_type for output bands.
414 	 *
415 	 * Ignore alpha, we detect that separately below.
416 	 */
417 	switch( color_type ) {
418 	case PNG_COLOR_TYPE_PALETTE:
419 		bands = 3;
420 		break;
421 
422 	case PNG_COLOR_TYPE_GRAY_ALPHA:
423 	case PNG_COLOR_TYPE_GRAY:
424 		bands = 1;
425 		break;
426 
427 	case PNG_COLOR_TYPE_RGB:
428 	case PNG_COLOR_TYPE_RGB_ALPHA:
429 		bands = 3;
430 		break;
431 
432 	default:
433 		vips_error( "png2vips", "%s", _( "unsupported color type" ) );
434 		return( -1 );
435 	}
436 
437 	if( bitdepth > 8 ) {
438 		if( bands < 3 )
439 			interpretation = VIPS_INTERPRETATION_GREY16;
440 		else
441 			interpretation = VIPS_INTERPRETATION_RGB16;
442 	}
443 	else {
444 		if( bands < 3 )
445 			interpretation = VIPS_INTERPRETATION_B_W;
446 		else
447 			interpretation = VIPS_INTERPRETATION_sRGB;
448 	}
449 
450 	/* Expand palette images.
451 	 */
452 	if( color_type == PNG_COLOR_TYPE_PALETTE )
453 		png_set_palette_to_rgb( read->pPng );
454 
455 	/* Expand transparency.
456 	 */
457 	if( png_get_valid( read->pPng, read->pInfo, PNG_INFO_tRNS ) ) {
458 		png_set_tRNS_to_alpha( read->pPng );
459 		bands += 1;
460 	}
461 	else if( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
462 		color_type == PNG_COLOR_TYPE_RGB_ALPHA ) {
463 		/* Some images have no transparency chunk, but still set
464 		 * color_type to alpha.
465 		 */
466 		bands += 1;
467 	}
468 
469 	/* Expand <8 bit images to full bytes.
470 	 */
471 	if( color_type == PNG_COLOR_TYPE_GRAY &&
472 		bitdepth < 8 )
473 		png_set_expand_gray_1_2_4_to_8( read->pPng );
474 
475 	/* If we're an INTEL byte order machine and this is 16bits, we need
476 	 * to swap bytes.
477 	 */
478 	if( bitdepth > 8 &&
479 		!vips_amiMSBfirst() )
480 		png_set_swap( read->pPng );
481 
482 	/* Get resolution. Default to 72 pixels per inch, the usual png value.
483 	 */
484 	unit_type = PNG_RESOLUTION_METER;
485 	res_x = 72.0 / 2.54 * 100.0;
486 	res_y = 72.0 / 2.54 * 100.0;
487 	png_get_pHYs( read->pPng, read->pInfo, &res_x, &res_y, &unit_type );
488 	switch( unit_type ) {
489 	case PNG_RESOLUTION_METER:
490 		Xres = res_x / 1000.0;
491 		Yres = res_y / 1000.0;
492 		break;
493 
494 	default:
495 		Xres = res_x;
496 		Yres = res_y;
497 		break;
498 	}
499 
500 	/* Set VIPS header.
501 	 */
502 	vips_image_init_fields( out,
503 		width, height, bands,
504 		bitdepth > 8 ? VIPS_FORMAT_USHORT : VIPS_FORMAT_UCHAR,
505 		VIPS_CODING_NONE, interpretation,
506 		Xres, Yres );
507 
508 	VIPS_SETSTR( out->filename,
509 		vips_connection_filename( VIPS_CONNECTION( read->source ) ) );
510 
511 	/* Uninterlaced images will be read in seq mode. Interlaced images are
512 	 * read via a huge memory buffer.
513 	 */
514 	if( interlace_type == PNG_INTERLACE_NONE )
515 		/* Sequential mode needs thinstrip to work with things like
516 		 * vips_shrink().
517 		 */
518 		hint = VIPS_DEMAND_STYLE_THINSTRIP;
519 	else
520 		hint = VIPS_DEMAND_STYLE_ANY;
521 	if( vips_image_pipelinev( out, hint, NULL ) )
522 		return( -1 );
523 
524 	/* Fetch the ICC profile. @name is useless, something like "icc" or
525 	 * "ICC Profile" etc. Ignore it.
526 	 *
527 	 * @profile was png_charpp in libpngs < 1.5, png_bytepp is the
528 	 * modern one. Ignore the warning, if any.
529 	 */
530 	if( png_get_iCCP( read->pPng, read->pInfo,
531 		&name, &compression_type, &profile, &proflen ) ) {
532 #ifdef DEBUG
533 		printf( "png2vips_header: attaching %d bytes of ICC profile\n",
534 			proflen );
535 		printf( "png2vips_header: name = \"%s\"\n", name );
536 #endif /*DEBUG*/
537 
538 		vips_image_set_blob_copy( out,
539 			VIPS_META_ICC_NAME, profile, proflen );
540 	}
541 
542 	/* Some libpng warn you to call png_set_interlace_handling(); here, but
543 	 * that can actually break interlace on older libpngs.
544 	 *
545 	 * Only set this for libpng 1.6+.
546 	 */
547 #if PNG_LIBPNG_VER > 10600
548 	(void) png_set_interlace_handling( read->pPng );
549 #endif
550 
551 	/* Sanity-check line size.
552 	 */
553 	png_read_update_info( read->pPng, read->pInfo );
554 	if( png_get_rowbytes( read->pPng, read->pInfo ) !=
555 		VIPS_IMAGE_SIZEOF_LINE( out ) ) {
556 		vips_error( "vipspng",
557 			"%s", _( "unable to read PNG header" ) );
558 		return( -1 );
559 	}
560 
561 	/* Let our caller know. These are very expensive to decode.
562 	 */
563 	if( interlace_type != PNG_INTERLACE_NONE )
564 		vips_image_set_int( out, "interlaced", 1 );
565 
566 	if( png_get_text( read->pPng, read->pInfo,
567 		&text_ptr, &num_text ) > 0 ) {
568 		int i;
569 
570 		/* Very large numbers of text chunks are used in DoS
571 		 * attacks.
572 		 */
573 		if( !read->unlimited &&
574 			num_text > MAX_PNG_TEXT_CHUNKS ) {
575 			vips_error( "vipspng",
576 				_( "%d text chunks, image blocked" ),
577 			       num_text );
578 			return( -1 );
579 		}
580 
581 		for( i = 0; i < num_text; i++ )
582 			/* .text is always a null-terminated C string.
583 			 */
584 			if( vips__set_text( out, i,
585 				text_ptr[i].key, text_ptr[i].text ) )
586 				return( -1 );
587 	}
588 
589 	/* Attach original palette bit depth, if any, as metadata.
590 	 */
591 	if( color_type == PNG_COLOR_TYPE_PALETTE )
592 		vips_image_set_int( out, "palette-bit-depth", bitdepth );
593 
594 	/* Note the PNG background colour, if any.
595 	 */
596 #ifdef PNG_bKGD_SUPPORTED
597 {
598 	png_color_16 *background;
599 
600 	if( png_get_bKGD( read->pPng, read->pInfo, &background ) ) {
601 		const int scale = out->BandFmt == VIPS_FORMAT_UCHAR ? 1 : 256;
602 
603 		double array[3];
604 		int n;
605 
606 		switch( color_type ) {
607 		case PNG_COLOR_TYPE_GRAY:
608 		case PNG_COLOR_TYPE_GRAY_ALPHA:
609 			array[0] = background->gray / scale;
610 			n = 1;
611 			break;
612 
613 		case PNG_COLOR_TYPE_RGB:
614 		case PNG_COLOR_TYPE_RGB_ALPHA:
615 			array[0] = background->red / scale;
616 			array[1] = background->green / scale;
617 			array[2] = background->blue / scale;
618 			n = 3;
619 			break;
620 
621 		case PNG_COLOR_TYPE_PALETTE:
622 		default:
623 			/* Not sure what to do here. I suppose we should read
624 			 * the palette.
625 			 */
626 			n = 0;
627 			break;
628 		}
629 
630 		if( n > 0 )
631 			vips_image_set_array_double( out, "background",
632 				array, n );
633 	}
634 }
635 #endif
636 
637 	return( 0 );
638 }
639 
640 /* Out is a huge "t" buffer we decompress to.
641  */
642 static int
png2vips_interlace(Read * read,VipsImage * out)643 png2vips_interlace( Read *read, VipsImage *out )
644 {
645 	int y;
646 
647 #ifdef DEBUG
648 	printf( "png2vips_interlace: reading whole image\n" );
649 #endif /*DEBUG*/
650 
651 	if( vips_image_write_prepare( out ) )
652 		return( -1 );
653 
654 	if( setjmp( png_jmpbuf( read->pPng ) ) )
655 		return( -1 );
656 
657 	if( !(read->row_pointer = VIPS_ARRAY( NULL, out->Ysize, png_bytep )) )
658 		return( -1 );
659 	for( y = 0; y < out->Ysize; y++ )
660 		read->row_pointer[y] = VIPS_IMAGE_ADDR( out, 0, y );
661 
662 	png_read_image( read->pPng, read->row_pointer );
663 
664 	read_destroy( read );
665 
666 	return( 0 );
667 }
668 
669 static int
png2vips_generate(VipsRegion * or,void * seq,void * a,void * b,gboolean * stop)670 png2vips_generate( VipsRegion *or,
671 	void *seq, void *a, void *b, gboolean *stop )
672 {
673         VipsRect *r = &or->valid;
674 	Read *read = (Read *) a;
675 
676 	int y;
677 
678 #ifdef DEBUG
679 	printf( "png2vips_generate: line %d, %d rows\n", r->top, r->height );
680 	printf( "png2vips_generate: y_top = %d\n", read->y_pos );
681 #endif /*DEBUG*/
682 
683 	/* We're inside a tilecache where tiles are the full image width, so
684 	 * this should always be true.
685 	 */
686 	g_assert( r->left == 0 );
687 	g_assert( r->width == or->im->Xsize );
688 	g_assert( VIPS_RECT_BOTTOM( r ) <= or->im->Ysize );
689 
690 	/* Tiles should always be a strip in height, unless it's the final
691 	 * strip.
692 	 */
693 	g_assert( r->height == VIPS_MIN( VIPS__FATSTRIP_HEIGHT,
694 		or->im->Ysize - r->top ) );
695 
696 	/* And check that y_pos is correct. It should be, since we are inside
697 	 * a vips_sequential().
698 	 */
699 	if( r->top != read->y_pos ) {
700 		vips_error( "vipspng",
701 			_( "out of order read at line %d" ), read->y_pos );
702 		return( -1 );
703 	}
704 
705 	for( y = 0; y < r->height; y++ ) {
706 		png_bytep q = (png_bytep) VIPS_REGION_ADDR( or, 0, r->top + y );
707 
708 		/* We need to catch errors from read_row().
709 		 */
710 		if( !setjmp( png_jmpbuf( read->pPng ) ) )
711 			png_read_row( read->pPng, q, NULL );
712 		else {
713 			/* We've failed to read some pixels. Knock this
714 			 * operation out of cache.
715 			 */
716 			vips_foreign_load_invalidate( read->out );
717 
718 #ifdef DEBUG
719 			printf( "png2vips_generate: png_read_row() failed, "
720 				"line %d\n", r->top + y );
721 			printf( "png2vips_generate: file %s\n", read->name );
722 			printf( "png2vips_generate: thread %p\n",
723 				g_thread_self() );
724 #endif /*DEBUG*/
725 
726 			/* And bail if fail is on. We have to add an error
727 			 * message, since the handler we install just does
728 			 * g_warning().
729 			 */
730 			if( read->fail_on >= VIPS_FAIL_ON_TRUNCATED ) {
731 				vips_error( "vipspng",
732 					"%s", _( "libpng read error" ) );
733 				return( -1 );
734 			}
735 		}
736 
737 		read->y_pos += 1;
738 	}
739 
740 	return( 0 );
741 }
742 
743 static int
png2vips_image(Read * read,VipsImage * out)744 png2vips_image( Read *read, VipsImage *out )
745 {
746 	int interlace_type = png_get_interlace_type( read->pPng, read->pInfo );
747 	VipsImage **t = (VipsImage **)
748 		vips_object_local_array( VIPS_OBJECT( out ), 3 );
749 
750 	if( interlace_type != PNG_INTERLACE_NONE ) {
751 		/* Arg awful interlaced image. We have to load to a huge mem
752 		 * buffer, then copy to out.
753 		 */
754 		t[0] = vips_image_new_memory();
755 		if( png2vips_header( read, t[0] ) ||
756 			png2vips_interlace( read, t[0] ) ||
757 			vips_image_write( t[0], out ) )
758 			return( -1 );
759 	}
760 	else {
761 		t[0] = vips_image_new();
762 		if( png2vips_header( read, t[0] ) ||
763 			vips_image_generate( t[0],
764 				NULL, png2vips_generate, NULL,
765 				read, NULL ) ||
766 			vips_sequential( t[0], &t[1],
767 				"tile_height", VIPS__FATSTRIP_HEIGHT,
768 				NULL ) ||
769 			vips_image_write( t[1], out ) )
770 			return( -1 );
771 	}
772 
773 	return( 0 );
774 }
775 
776 gboolean
vips__png_ispng_source(VipsSource * source)777 vips__png_ispng_source( VipsSource *source )
778 {
779 	const unsigned char *p;
780 
781 	if( (p = vips_source_sniff( source, 8 )) &&
782 		!png_sig_cmp( (png_bytep) p, 0, 8 ) )
783 		return( TRUE );
784 
785 	return( FALSE );
786 }
787 
788 int
vips__png_header_source(VipsSource * source,VipsImage * out,gboolean unlimited)789 vips__png_header_source( VipsSource *source, VipsImage *out,
790 	gboolean unlimited )
791 {
792 	Read *read;
793 
794 	if( !(read = read_new( source, out, TRUE, unlimited )) ||
795 		png2vips_header( read, out ) ) {
796 		vips_error( "png2vips", _( "unable to read source %s" ),
797 			vips_connection_nick( VIPS_CONNECTION( source ) ) );
798 		return( -1 );
799 	}
800 
801 	vips_source_minimise( source );
802 
803 	return( 0 );
804 }
805 
806 int
vips__png_read_source(VipsSource * source,VipsImage * out,VipsFailOn fail_on,gboolean unlimited)807 vips__png_read_source( VipsSource *source, VipsImage *out,
808 	VipsFailOn fail_on, gboolean unlimited )
809 {
810 	Read *read;
811 
812 	if( !(read = read_new( source, out, fail_on, unlimited )) ||
813 		png2vips_image( read, out ) ||
814 		vips_source_decode( source ) ) {
815 		vips_error( "png2vips", _( "unable to read source %s" ),
816 			vips_connection_nick( VIPS_CONNECTION( source ) ) );
817 		return( -1 );
818 	}
819 
820 	return( 0 );
821 }
822 
823 /* Interlaced PNGs need to be entirely decompressed into memory then can be
824  * served partially from there. Non-interlaced PNGs may be read sequentially.
825  */
826 gboolean
vips__png_isinterlaced_source(VipsSource * source)827 vips__png_isinterlaced_source( VipsSource *source )
828 {
829 	VipsImage *image;
830 	Read *read;
831 	int interlace_type;
832 
833 	image = vips_image_new();
834 
835 	if( !(read = read_new( source, image, TRUE, FALSE )) ) {
836 		g_object_unref( image );
837 		return( -1 );
838 	}
839 	interlace_type = png_get_interlace_type( read->pPng, read->pInfo );
840 	g_object_unref( image );
841 
842 	return( interlace_type != PNG_INTERLACE_NONE );
843 }
844 
845 #endif /*!defined(HAVE_SPNG)*/
846 
847 const char *vips__png_suffs[] = { ".png", NULL };
848 
849 /* What we track during a PNG write.
850  */
851 typedef struct {
852 	VipsImage *in;
853 	VipsImage *memory;
854 
855 	VipsTarget *target;
856 
857 	png_structp pPng;
858 	png_infop pInfo;
859 	png_bytep *row_pointer;
860 } Write;
861 
862 static void
write_destroy(Write * write)863 write_destroy( Write *write )
864 {
865 #ifdef DEBUG
866 	printf( "write_destroy: %p\n", write );
867 #endif /*DEBUG*/
868 
869 	VIPS_UNREF( write->memory );
870 	if( write->target )
871 		vips_target_finish( write->target );
872 	if( write->pPng )
873 		png_destroy_write_struct( &write->pPng, &write->pInfo );
874 	VIPS_FREE( write->row_pointer );
875 	VIPS_FREE( write );
876 }
877 
878 static void
user_write_data(png_structp pPng,png_bytep data,png_size_t length)879 user_write_data( png_structp pPng, png_bytep data, png_size_t length )
880 {
881 	Write *write = (Write *) png_get_io_ptr( pPng );
882 
883 	if( vips_target_write( write->target, data, length ) )
884 		png_error( pPng, "not enough data" );
885 }
886 
887 static Write *
write_new(VipsImage * in,VipsTarget * target)888 write_new( VipsImage *in, VipsTarget *target )
889 {
890 	Write *write;
891 
892 	if( !(write = VIPS_NEW( NULL, Write )) )
893 		return( NULL );
894 	write->in = in;
895 	write->target = target;
896 
897 #ifdef DEBUG
898 	printf( "write_new: %p\n", write );
899 #endif /*DEBUG*/
900 
901 	if( !(write->row_pointer = VIPS_ARRAY( NULL, in->Ysize, png_bytep )) )
902 		return( NULL );
903 	if( !(write->pPng = png_create_write_struct(
904 		PNG_LIBPNG_VER_STRING, NULL,
905 		user_error_function, user_warning_function )) ) {
906 		write_destroy( write );
907 		return( NULL );
908 	}
909 
910 	/* Prevent libpng (>=1.6.11) verifying sRGB profiles. We are often
911 	 * asked to copy images containing bad profiles, and this check would
912 	 * prevent that.
913 	 */
914 #ifdef PNG_SKIP_sRGB_CHECK_PROFILE
915 	png_set_option( write->pPng,
916 		PNG_SKIP_sRGB_CHECK_PROFILE, PNG_OPTION_ON );
917 #endif /*PNG_SKIP_sRGB_CHECK_PROFILE*/
918 
919 	png_set_write_fn( write->pPng, write, user_write_data, NULL );
920 
921 	/* Catch PNG errors from png_create_info_struct().
922 	 */
923 	if( setjmp( png_jmpbuf( write->pPng ) ) ) {
924 		write_destroy( write );
925 		return( NULL );
926 	}
927 
928 	if( !(write->pInfo = png_create_info_struct( write->pPng )) ) {
929 		write_destroy( write );
930 		return( NULL );
931 	}
932 
933 	return( write );
934 }
935 
936 static int
write_png_block(VipsRegion * region,VipsRect * area,void * a)937 write_png_block( VipsRegion *region, VipsRect *area, void *a )
938 {
939 	Write *write = (Write *) a;
940 
941 	int i;
942 
943 	/* The area to write is always a set of complete scanlines.
944 	 */
945 	g_assert( area->left == 0 );
946 	g_assert( area->width == region->im->Xsize );
947 	g_assert( area->top + area->height <= region->im->Ysize );
948 
949 	/* Catch PNG errors.
950 	 */
951 	if( setjmp( png_jmpbuf( write->pPng ) ) )
952 		return( -1 );
953 
954 	for( i = 0; i < area->height; i++ )
955 		write->row_pointer[i] = (png_bytep)
956 			VIPS_REGION_ADDR( region, 0, area->top + i );
957 
958 	png_write_rows( write->pPng, write->row_pointer, area->height );
959 
960 	return( 0 );
961 }
962 
963 static void
vips__png_set_text(png_structp pPng,png_infop pInfo,const char * key,const char * value)964 vips__png_set_text( png_structp pPng, png_infop pInfo,
965 	const char *key, const char *value )
966 {
967 	png_text text;
968 
969 	text.compression = 0;
970 	text.key = (char *) key;
971 	text.text = (char *) value;
972 	text.text_length = strlen( value );
973 
974 	/* Before 1.4, these fields were only there if explicitly enabled.
975 	 */
976 #if PNG_LIBPNG_VER > 10400
977 	text.itxt_length = 0;
978 	text.lang = NULL;
979 #endif
980 
981 	png_set_text( pPng, pInfo, &text, 1 );
982 }
983 
984 static void *
write_png_comment(VipsImage * image,const char * field,GValue * value,void * data)985 write_png_comment( VipsImage *image,
986 	const char *field, GValue *value, void *data )
987 {
988 	Write *write = (Write *) data;
989 
990 	if( vips_isprefix( "png-comment-", field ) ) {
991 		const char *str;
992 		int i;
993 		char key[256];
994 
995 		if( vips_image_get_string( write->in, field, &str ) )
996 			return( image );
997 
998 		if( strlen( field ) > 256 ||
999 			sscanf( field, "png-comment-%d-%80s", &i, key ) != 2 ) {
1000 			vips_error( "vips2png",
1001 				"%s", _( "bad png comment key" ) );
1002 			return( image );
1003 		}
1004 
1005 		vips__png_set_text( write->pPng, write->pInfo, key, str );
1006 	}
1007 
1008 	return( NULL );
1009 }
1010 
1011 /* Write a VIPS image to PNG.
1012  */
1013 static int
write_vips(Write * write,int compress,int interlace,const char * profile,VipsForeignPngFilter filter,gboolean strip,gboolean palette,int Q,double dither,int bitdepth,int effort)1014 write_vips( Write *write,
1015 	int compress, int interlace, const char *profile,
1016 	VipsForeignPngFilter filter, gboolean strip,
1017 	gboolean palette, int Q, double dither,
1018 	int bitdepth, int effort )
1019 {
1020 	VipsImage *in = write->in;
1021 
1022 	int color_type;
1023 	int interlace_type;
1024 	int i, nb_passes;
1025 
1026         g_assert( in->BandFmt == VIPS_FORMAT_UCHAR ||
1027 		in->BandFmt == VIPS_FORMAT_USHORT );
1028 	g_assert( in->Coding == VIPS_CODING_NONE );
1029         g_assert( in->Bands > 0 && in->Bands < 5 );
1030 
1031 	/* Catch PNG errors.
1032 	 */
1033 	if( setjmp( png_jmpbuf( write->pPng ) ) )
1034 		return( -1 );
1035 
1036 	/* Check input image. If we are writing interlaced, we need to make 7
1037 	 * passes over the image. We advertise ourselves as seq, so to ensure
1038 	 * we only suck once from upstream, switch to WIO.
1039 	 */
1040 	if( interlace ) {
1041 		if( !(write->memory = vips_image_copy_memory( in )) )
1042 			return( -1 );
1043 		in = write->memory;
1044 	}
1045 	else {
1046 		if( vips_image_pio_input( in ) )
1047 			return( -1 );
1048 	}
1049 	if( compress < 0 || compress > 9 ) {
1050 		vips_error( "vips2png",
1051 			"%s", _( "compress should be in [0,9]" ) );
1052 		return( -1 );
1053 	}
1054 
1055 	/* Set compression parameters.
1056 	 */
1057 	png_set_compression_level( write->pPng, compress );
1058 
1059 	/* Set row filter.
1060 	 */
1061 	png_set_filter( write->pPng, 0, filter );
1062 
1063 	switch( in->Bands ) {
1064 	case 1: color_type = PNG_COLOR_TYPE_GRAY; break;
1065 	case 2: color_type = PNG_COLOR_TYPE_GRAY_ALPHA; break;
1066 	case 3: color_type = PNG_COLOR_TYPE_RGB; break;
1067 	case 4: color_type = PNG_COLOR_TYPE_RGB_ALPHA; break;
1068 
1069 	default:
1070 		vips_error( "vips2png",
1071 			_( "can't save %d band image as png" ), in->Bands );
1072 		return( -1 );
1073 	}
1074 
1075 #ifdef HAVE_IMAGEQUANT
1076 	/* Enable image quantisation to paletted 8bpp PNG if colours is set.
1077 	 */
1078 	if( palette )
1079 		color_type = PNG_COLOR_TYPE_PALETTE;
1080 #else
1081 	if( palette )
1082 		g_warning( "%s",
1083 			_( "ignoring palette (no quantisation support)" ) );
1084 #endif /*HAVE_IMAGEQUANT*/
1085 
1086 	interlace_type = interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE;
1087 
1088 	png_set_IHDR( write->pPng, write->pInfo,
1089 		in->Xsize, in->Ysize, bitdepth, color_type, interlace_type,
1090 		PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT );
1091 
1092 	/* Set resolution. libpng uses pixels per meter.
1093 	 */
1094 	png_set_pHYs( write->pPng, write->pInfo,
1095 		VIPS_RINT( in->Xres * 1000 ), VIPS_RINT( in->Yres * 1000 ),
1096 		PNG_RESOLUTION_METER );
1097 
1098 	/* Metadata
1099 	 */
1100 	if( !strip ) {
1101 		if( profile ) {
1102 			VipsBlob *blob;
1103 
1104 			if( vips_profile_load( profile, &blob, NULL ) )
1105 				return( -1 );
1106 			if( blob ) {
1107 				size_t length;
1108 				const void *data
1109 					= vips_blob_get( blob, &length );
1110 
1111 #ifdef DEBUG
1112 				printf( "write_vips: attaching %zd bytes "
1113 					"of ICC profile\n", length );
1114 #endif /*DEBUG*/
1115 
1116 				png_set_iCCP( write->pPng, write->pInfo,
1117 					"icc", PNG_COMPRESSION_TYPE_BASE,
1118 					(void *) data, length );
1119 
1120 				vips_area_unref( (VipsArea *) blob );
1121 			}
1122 		}
1123 		else if( vips_image_get_typeof( in, VIPS_META_ICC_NAME ) ) {
1124 			const void *data;
1125 			size_t length;
1126 
1127 			if( vips_image_get_blob( in, VIPS_META_ICC_NAME,
1128 				&data, &length ) )
1129 				return( -1 );
1130 
1131 #ifdef DEBUG
1132 			printf( "write_vips: attaching %zd bytes "
1133 				"of ICC profile\n", length );
1134 #endif /*DEBUG*/
1135 
1136 			/* We need to ignore any errors from png_set_iCCP()
1137 			 * since we want to drop incompatible profiles rather
1138 			 * than simply failing.
1139 			 */
1140 			if( setjmp( png_jmpbuf( write->pPng ) ) ) {
1141 				/* Silent ignore of error.
1142 				 */
1143 				g_warning( "bad ICC profile not saved" );
1144 			}
1145 			else {
1146 				/* This will jump back to the line above on
1147 				 * error.
1148 				 */
1149 				png_set_iCCP( write->pPng, write->pInfo, "icc",
1150 					PNG_COMPRESSION_TYPE_BASE,
1151 					(void *) data, length );
1152 			}
1153 
1154 			/* And restore the setjmp.
1155 			 */
1156 			if( setjmp( png_jmpbuf( write->pPng ) ) )
1157 				return( -1 );
1158 		}
1159 
1160 		if( vips_image_get_typeof( in, VIPS_META_XMP_NAME ) ) {
1161 			const void *data;
1162 			size_t length;
1163 			char *str;
1164 
1165 			/* XMP is attached as a BLOB with no null-termination.
1166 			 * We must re-add this.
1167 			 */
1168 			if( vips_image_get_blob( in,
1169 				VIPS_META_XMP_NAME, &data, &length ) )
1170 				return( -1 );
1171 
1172 			str = g_malloc( length + 1 );
1173 			vips_strncpy( str, data, length + 1 );
1174 			vips__png_set_text( write->pPng, write->pInfo,
1175 				"XML:com.adobe.xmp", str );
1176 			g_free( str );
1177 		}
1178 
1179 		if( vips_image_map( in,
1180 			write_png_comment, write ) )
1181 			return( -1 );
1182 	}
1183 
1184 #ifdef HAVE_IMAGEQUANT
1185 	if( palette ) {
1186 		VipsImage *im_index;
1187 		VipsImage *im_palette;
1188 		int palette_count;
1189 		png_color *png_palette;
1190 		png_byte *png_trans;
1191 		int trans_count;
1192 
1193 		if( vips__quantise_image( in, &im_index, &im_palette,
1194 			1 << bitdepth, Q, dither, effort, FALSE ) )
1195 			return( -1 );
1196 
1197 		palette_count = im_palette->Xsize;
1198 
1199 		g_assert( palette_count <= PNG_MAX_PALETTE_LENGTH );
1200 
1201 		png_palette = (png_color *) png_malloc( write->pPng,
1202 			palette_count * sizeof( png_color ) );
1203 		png_trans = (png_byte *) png_malloc( write->pPng,
1204 			palette_count * sizeof( png_byte ) );
1205 		trans_count = 0;
1206 		for( i = 0; i < palette_count; i++ ) {
1207 			VipsPel *p = (VipsPel *)
1208 				VIPS_IMAGE_ADDR( im_palette, i, 0 );
1209 			png_color *col = &png_palette[i];
1210 
1211 			col->red = p[0];
1212 			col->green = p[1];
1213 			col->blue = p[2];
1214 			png_trans[i] = p[3];
1215 			if( p[3] != 255 )
1216 				trans_count = i + 1;
1217 #ifdef DEBUG
1218 			printf( "write_vips: palette[%d] %d %d %d %d\n",
1219 				i + 1, p[0], p[1], p[2], p[3] );
1220 #endif /*DEBUG*/
1221 		}
1222 
1223 #ifdef DEBUG
1224 		printf( "write_vips: attaching %d color palette\n",
1225 			palette_count );
1226 #endif /*DEBUG*/
1227 		png_set_PLTE( write->pPng, write->pInfo, png_palette,
1228 			palette_count );
1229 		if( trans_count ) {
1230 #ifdef DEBUG
1231 			printf( "write_vips: attaching %d alpha values\n",
1232 				trans_count );
1233 #endif /*DEBUG*/
1234 			png_set_tRNS( write->pPng, write->pInfo, png_trans,
1235 				trans_count, NULL );
1236 		}
1237 
1238 		png_free( write->pPng, (void *) png_palette );
1239 		png_free( write->pPng, (void *) png_trans );
1240 
1241 		VIPS_UNREF( im_palette );
1242 
1243 		VIPS_UNREF( write->memory );
1244 		write->memory = im_index;
1245 		in = write->memory;
1246 	}
1247 #endif /*HAVE_IMAGEQUANT*/
1248 
1249 	png_write_info( write->pPng, write->pInfo );
1250 
1251 	/* If we're an intel byte order CPU and this is a 16bit image, we need
1252 	 * to swap bytes.
1253 	 */
1254 	if( bitdepth > 8 &&
1255 		!vips_amiMSBfirst() )
1256 		png_set_swap( write->pPng );
1257 
1258 	/* If bitdepth is 1/2/4, pack pixels into bytes.
1259 	 */
1260 	png_set_packing( write->pPng );
1261 
1262 	if( interlace )
1263 		nb_passes = png_set_interlace_handling( write->pPng );
1264 	else
1265 		nb_passes = 1;
1266 
1267 	/* Write data.
1268 	 */
1269 	for( i = 0; i < nb_passes; i++ )
1270 		if( vips_sink_disc( in, write_png_block, write ) )
1271 			return( -1 );
1272 
1273 	/* The setjmp() was held by our background writer: reset it.
1274 	 */
1275 	if( setjmp( png_jmpbuf( write->pPng ) ) )
1276 		return( -1 );
1277 
1278 	png_write_end( write->pPng, write->pInfo );
1279 
1280 	return( 0 );
1281 }
1282 
1283 int
vips__png_write_target(VipsImage * in,VipsTarget * target,int compression,int interlace,const char * profile,VipsForeignPngFilter filter,gboolean strip,gboolean palette,int Q,double dither,int bitdepth,int effort)1284 vips__png_write_target( VipsImage *in, VipsTarget *target,
1285 	int compression, int interlace,
1286 	const char *profile, VipsForeignPngFilter filter, gboolean strip,
1287 	gboolean palette, int Q, double dither,
1288 	int bitdepth, int effort )
1289 {
1290 	Write *write;
1291 
1292 	if( !(write = write_new( in, target )) )
1293 		return( -1 );
1294 
1295 	if( write_vips( write,
1296 		compression, interlace, profile, filter, strip, palette,
1297 		Q, dither, bitdepth, effort ) ) {
1298 		write_destroy( write );
1299 		vips_error( "vips2png", _( "unable to write to target %s" ),
1300 			vips_connection_nick( VIPS_CONNECTION( target ) ) );
1301 		return( -1 );
1302 	}
1303 
1304 	write_destroy( write );
1305 
1306 	return( 0 );
1307 }
1308 
1309 #endif /*HAVE_PNG*/
1310