14
14
* - rename "speed" as "effort" for consistency with other savers
15
15
* 22/12/21
16
16
* - add >8 bit support
17
+ * 22/10/11
18
+ * - improve rules for 16-bit write [johntrunc]
17
19
*/
18
20
19
21
/*
48
50
#define DEBUG
49
51
*/
50
52
51
- /*
52
- *
53
-
54
- TODO:
55
-
56
- what about a 16-bit PNG saved with bitdepth=8? does this work?
57
-
58
- no!
59
-
60
- what about a 8-bit PNG saved with bitdepth=12? does this work?
61
-
62
- *
63
- */
64
-
65
-
66
53
#ifdef HAVE_CONFIG_H
67
54
#include <config.h>
68
55
#endif /*HAVE_CONFIG_H*/
@@ -320,7 +307,7 @@ vips_foreign_save_heif_pack( VipsForeignSaveHeif *heif,
320
307
321
308
if ( heif -> image -> BandFmt == VIPS_FORMAT_UCHAR &&
322
309
heif -> bitdepth == 8 )
323
- /* Most common cases -- 8 bit to 8 bit.
310
+ /* Most common case -- 8 bit to 8 bit.
324
311
*/
325
312
memcpy ( q , p , ne );
326
313
else if ( heif -> image -> BandFmt == VIPS_FORMAT_UCHAR &&
@@ -341,8 +328,14 @@ vips_foreign_save_heif_pack( VipsForeignSaveHeif *heif,
341
328
else if ( heif -> image -> BandFmt == VIPS_FORMAT_USHORT &&
342
329
heif -> bitdepth <= 8 ) {
343
330
/* 16-bit native byte order source, 8 bit write.
344
- */
345
- int shift = 16 - heif -> bitdepth ;
331
+ *
332
+ * Pick the high or low bits of the source.
333
+ */
334
+ int vips_bitdepth =
335
+ heif -> image -> Type == VIPS_INTERPRETATION_RGB16 ||
336
+ heif -> image -> Type == VIPS_INTERPRETATION_GREY16 ?
337
+ 16 : 8 ;
338
+ int shift = vips_bitdepth - heif -> bitdepth ;
346
339
347
340
for ( i = 0 ; i < ne ; i ++ ) {
348
341
guint16 v = * ((gushort * ) p ) >> shift ;
@@ -356,7 +349,11 @@ vips_foreign_save_heif_pack( VipsForeignSaveHeif *heif,
356
349
heif -> bitdepth > 8 ) {
357
350
/* 16-bit native byte order source, 16 bit bigendian write.
358
351
*/
359
- int shift = 16 - heif -> bitdepth ;
352
+ int vips_bitdepth =
353
+ heif -> image -> Type == VIPS_INTERPRETATION_RGB16 ||
354
+ heif -> image -> Type == VIPS_INTERPRETATION_GREY16 ?
355
+ 16 : 8 ;
356
+ int shift = vips_bitdepth - heif -> bitdepth ;
360
357
361
358
for ( i = 0 ; i < ne ; i ++ ) {
362
359
guint16 v = * ((gushort * ) p ) >> shift ;
@@ -446,25 +443,27 @@ vips_foreign_save_heif_build( VipsObject *object )
446
443
build ( object ) )
447
444
return ( -1 );
448
445
446
+ /* Make a copy of the image in case we modify the metadata eg. for
447
+ * exif_update.
448
+ */
449
+ if ( vips_copy ( save -> ready , & heif -> image , NULL ) )
450
+ return ( -1 );
451
+
449
452
/* If the old, deprecated "speed" param is being used and the new
450
453
* "effort" param is not, use speed to init effort.
451
454
*/
452
455
if ( vips_object_argument_isset ( object , "speed" ) &&
453
456
!vips_object_argument_isset ( object , "effort" ) )
454
457
heif -> effort = 9 - heif -> speed ;
455
458
456
- /* Default 12 bit save for ushort . HEIC (for example) implements
459
+ /* Default 12 bit save for 16-bit images . HEIC (for example) implements
457
460
* 8 / 10 / 12.
458
461
*/
459
462
if ( !vips_object_argument_isset ( object , "bitdepth" ) )
460
- heif -> bitdepth = save -> ready -> BandFmt == VIPS_FORMAT_UCHAR ?
461
- 8 : 12 ;
462
-
463
- /* Make a copy of the image in case we modify the metadata eg. for
464
- * exif_update.
465
- */
466
- if ( vips_copy ( save -> ready , & heif -> image , NULL ) )
467
- return ( -1 );
463
+ heif -> bitdepth =
464
+ heif -> image -> Type == VIPS_INTERPRETATION_RGB16 ||
465
+ heif -> image -> Type == VIPS_INTERPRETATION_GREY16 ?
466
+ 12 : 8 ;
468
467
469
468
error = heif_context_get_encoder_for_format ( heif -> ctx ,
470
469
(enum heif_compression_format ) heif -> compression ,
0 commit comments