@@ -362,8 +362,6 @@ vips_foreign_save_spng_write( VipsForeignSaveSpng *spng, VipsImage *in )
362
362
int error ;
363
363
struct spng_ihdr ihdr ;
364
364
struct spng_phys phys ;
365
- struct spng_plte plte = { 0 };
366
- struct spng_trns trns = { 0 };
367
365
int fmt ;
368
366
enum spng_encode_flags encode_flags ;
369
367
@@ -375,8 +373,76 @@ vips_foreign_save_spng_write( VipsForeignSaveSpng *spng, VipsImage *in )
375
373
return ( -1 );
376
374
}
377
375
376
+ ihdr .width = in -> Xsize ;
377
+ ihdr .height = in -> Ysize ;
378
+ ihdr .bit_depth = spng -> bitdepth ;
379
+
380
+ switch ( in -> Bands ) {
381
+ case 1 :
382
+ ihdr .color_type = SPNG_COLOR_TYPE_GRAYSCALE ;
383
+ break ;
384
+
385
+ case 2 :
386
+ ihdr .color_type = SPNG_COLOR_TYPE_GRAYSCALE_ALPHA ;
387
+ break ;
388
+
389
+ case 3 :
390
+ ihdr .color_type = SPNG_COLOR_TYPE_TRUECOLOR ;
391
+ break ;
392
+
393
+ case 4 :
394
+ ihdr .color_type = SPNG_COLOR_TYPE_TRUECOLOR_ALPHA ;
395
+ break ;
396
+
397
+ default :
398
+ vips_error ( class -> nickname , "%s" , _ ( "bad bands" ) );
399
+ return ( -1 );
400
+ }
401
+
402
+ #ifdef HAVE_QUANTIZATION
403
+ /* Enable image quantisation to paletted 8bpp PNG if palette is set.
404
+ */
405
+ if ( spng -> palette )
406
+ ihdr .color_type = SPNG_COLOR_TYPE_INDEXED ;
407
+ #else
408
+ if ( spng -> palette )
409
+ g_warning ( "%s" ,
410
+ _ ( "ignoring palette (no quantisation support)" ) );
411
+ #endif /*HAVE_QUANTIZATION*/
412
+
413
+ ihdr .compression_method = 0 ;
414
+ ihdr .filter_method = 0 ;
415
+ ihdr .interlace_method = spng -> interlace ? 1 : 0 ;
416
+ if ( (error = spng_set_ihdr ( spng -> ctx , & ihdr )) ) {
417
+ vips_error ( class -> nickname , "%s" , spng_strerror ( error ) );
418
+ return ( -1 );
419
+ }
420
+
421
+ spng_set_option ( spng -> ctx ,
422
+ SPNG_IMG_COMPRESSION_LEVEL , spng -> compression );
423
+ spng_set_option ( spng -> ctx ,
424
+ SPNG_TEXT_COMPRESSION_LEVEL , spng -> compression );
425
+ spng_set_option ( spng -> ctx ,
426
+ SPNG_FILTER_CHOICE , spng -> filter );
427
+
428
+ /* Set resolution. spng uses pixels per meter.
429
+ */
430
+ phys .unit_specifier = 1 ;
431
+ phys .ppu_x = VIPS_RINT ( in -> Xres * 1000.0 );
432
+ phys .ppu_y = VIPS_RINT ( in -> Xres * 1000.0 );
433
+ spng_set_phys ( spng -> ctx , & phys );
434
+
435
+ /* Metadata.
436
+ */
437
+ if ( !save -> strip &&
438
+ vips_foreign_save_spng_metadata ( spng , in ) )
439
+ return ( -1 );
440
+
378
441
#ifdef HAVE_QUANTIZATION
379
442
if ( spng -> palette ) {
443
+ struct spng_plte plte = { 0 };
444
+ struct spng_trns trns = { 0 };
445
+
380
446
VipsImage * im_index ;
381
447
VipsImage * im_palette ;
382
448
int palette_count ;
@@ -426,14 +492,14 @@ vips_foreign_save_spng_write( VipsForeignSaveSpng *spng, VipsImage *in )
426
492
427
493
VIPS_UNREF ( im_palette );
428
494
495
+ spng_set_plte ( spng -> ctx , & plte );
496
+ if ( trns .n_type3_entries )
497
+ spng_set_trns ( spng -> ctx , & trns );
498
+
429
499
in = spng -> memory = im_index ;
430
500
}
431
501
#endif /*HAVE_QUANTIZATION*/
432
502
433
- ihdr .width = in -> Xsize ;
434
- ihdr .height = in -> Ysize ;
435
- ihdr .bit_depth = spng -> bitdepth ;
436
-
437
503
/* Low-bitdepth write needs an extra buffer for packing pixels.
438
504
*/
439
505
if ( spng -> bitdepth < 8 ) {
@@ -445,67 +511,6 @@ vips_foreign_save_spng_write( VipsForeignSaveSpng *spng, VipsImage *in )
445
511
return ( -1 );
446
512
}
447
513
448
- switch ( in -> Bands ) {
449
- case 1 :
450
- if ( spng -> palette )
451
- ihdr .color_type = SPNG_COLOR_TYPE_INDEXED ;
452
- else
453
- ihdr .color_type = SPNG_COLOR_TYPE_GRAYSCALE ;
454
- break ;
455
-
456
- case 2 :
457
- ihdr .color_type = SPNG_COLOR_TYPE_GRAYSCALE_ALPHA ;
458
- break ;
459
-
460
- case 3 :
461
- ihdr .color_type = SPNG_COLOR_TYPE_TRUECOLOR ;
462
- break ;
463
-
464
- case 4 :
465
- ihdr .color_type = SPNG_COLOR_TYPE_TRUECOLOR_ALPHA ;
466
- break ;
467
-
468
- default :
469
- vips_error ( class -> nickname , "%s" , _ ( "bad bands" ) );
470
- return ( -1 );
471
- }
472
-
473
- ihdr .compression_method = 0 ;
474
- ihdr .filter_method = 0 ;
475
- ihdr .interlace_method = spng -> interlace ? 1 : 0 ;
476
- if ( (error = spng_set_ihdr ( spng -> ctx , & ihdr )) ) {
477
- vips_error ( class -> nickname , "%s" , spng_strerror ( error ) );
478
- return ( -1 );
479
- }
480
-
481
- spng_set_option ( spng -> ctx ,
482
- SPNG_IMG_COMPRESSION_LEVEL , spng -> compression );
483
- spng_set_option ( spng -> ctx ,
484
- SPNG_TEXT_COMPRESSION_LEVEL , spng -> compression );
485
- spng_set_option ( spng -> ctx ,
486
- SPNG_FILTER_CHOICE , spng -> filter );
487
-
488
- /* Set resolution. png uses pixels per meter.
489
- */
490
- phys .unit_specifier = 1 ;
491
- phys .ppu_x = VIPS_RINT ( in -> Xres * 1000.0 );
492
- phys .ppu_y = VIPS_RINT ( in -> Xres * 1000.0 );
493
- spng_set_phys ( spng -> ctx , & phys );
494
-
495
- /* Metadata.
496
- */
497
- if ( !save -> strip &&
498
- vips_foreign_save_spng_metadata ( spng , in ) )
499
- return ( -1 );
500
-
501
- #ifdef HAVE_QUANTIZATION
502
- if ( spng -> palette ) {
503
- spng_set_plte ( spng -> ctx , & plte );
504
- if ( trns .n_type3_entries )
505
- spng_set_trns ( spng -> ctx , & trns );
506
- }
507
- #endif /*HAVE_QUANTIZATION*/
508
-
509
514
/* SPNG_FMT_PNG is a special value that matches the format in ihdr
510
515
*/
511
516
fmt = SPNG_FMT_PNG ;
0 commit comments