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*/
@@ -309,7 +296,7 @@ vips_foreign_save_heif_pack( VipsForeignSaveHeif *heif,
309
296
310
297
if ( heif -> image -> BandFmt == VIPS_FORMAT_UCHAR &&
311
298
heif -> bitdepth == 8 )
312
- /* Most common cases -- 8 bit to 8 bit.
299
+ /* Most common case -- 8 bit to 8 bit.
313
300
*/
314
301
memcpy ( q , p , ne );
315
302
else if ( heif -> image -> BandFmt == VIPS_FORMAT_UCHAR &&
@@ -330,8 +317,14 @@ vips_foreign_save_heif_pack( VipsForeignSaveHeif *heif,
330
317
else if ( heif -> image -> BandFmt == VIPS_FORMAT_USHORT &&
331
318
heif -> bitdepth <= 8 ) {
332
319
/* 16-bit native byte order source, 8 bit write.
333
- */
334
- int shift = 16 - heif -> bitdepth ;
320
+ *
321
+ * Pick the high or low bits of the source.
322
+ */
323
+ int vips_bitdepth =
324
+ heif -> image -> Type == VIPS_INTERPRETATION_RGB16 ||
325
+ heif -> image -> Type == VIPS_INTERPRETATION_GREY16 ?
326
+ 16 : 8 ;
327
+ int shift = vips_bitdepth - heif -> bitdepth ;
335
328
336
329
for ( i = 0 ; i < ne ; i ++ ) {
337
330
guint16 v = * ((gushort * ) p ) >> shift ;
@@ -345,7 +338,11 @@ vips_foreign_save_heif_pack( VipsForeignSaveHeif *heif,
345
338
heif -> bitdepth > 8 ) {
346
339
/* 16-bit native byte order source, 16 bit bigendian write.
347
340
*/
348
- int shift = 16 - heif -> bitdepth ;
341
+ int vips_bitdepth =
342
+ heif -> image -> Type == VIPS_INTERPRETATION_RGB16 ||
343
+ heif -> image -> Type == VIPS_INTERPRETATION_GREY16 ?
344
+ 16 : 8 ;
345
+ int shift = vips_bitdepth - heif -> bitdepth ;
349
346
350
347
for ( i = 0 ; i < ne ; i ++ ) {
351
348
guint16 v = * ((gushort * ) p ) >> shift ;
@@ -435,25 +432,27 @@ vips_foreign_save_heif_build( VipsObject *object )
435
432
build ( object ) )
436
433
return ( -1 );
437
434
435
+ /* Make a copy of the image in case we modify the metadata eg. for
436
+ * exif_update.
437
+ */
438
+ if ( vips_copy ( save -> ready , & heif -> image , NULL ) )
439
+ return ( -1 );
440
+
438
441
/* If the old, deprecated "speed" param is being used and the new
439
442
* "effort" param is not, use speed to init effort.
440
443
*/
441
444
if ( vips_object_argument_isset ( object , "speed" ) &&
442
445
!vips_object_argument_isset ( object , "effort" ) )
443
446
heif -> effort = 9 - heif -> speed ;
444
447
445
- /* Default 12 bit save for ushort . HEIC (for example) implements
448
+ /* Default 12 bit save for 16-bit images . HEIC (for example) implements
446
449
* 8 / 10 / 12.
447
450
*/
448
451
if ( !vips_object_argument_isset ( object , "bitdepth" ) )
449
- heif -> bitdepth = save -> ready -> BandFmt == VIPS_FORMAT_UCHAR ?
450
- 8 : 12 ;
451
-
452
- /* Make a copy of the image in case we modify the metadata eg. for
453
- * exif_update.
454
- */
455
- if ( vips_copy ( save -> ready , & heif -> image , NULL ) )
456
- return ( -1 );
452
+ heif -> bitdepth =
453
+ heif -> image -> Type == VIPS_INTERPRETATION_RGB16 ||
454
+ heif -> image -> Type == VIPS_INTERPRETATION_GREY16 ?
455
+ 12 : 8 ;
457
456
458
457
error = heif_context_get_encoder_for_format ( heif -> ctx ,
459
458
(enum heif_compression_format ) heif -> compression ,
0 commit comments