GraphicsMagick: HEIF: Take row stride into account when reading ...
GraphicsMagick Commits <[email protected]>
| Newsgroups | gmane.comp.video.graphicsmagick.cvs |
|---|---|
| Message-ID | <mailman.823.1642355894.1940.graphicsmagick-commit@lists.sourceforge.net> |
changeset 743f1bcf3052 in /hg/GraphicsMagick details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=743f1bcf3052 summary: HEIF: Take row stride into account when reading pixel rows. Add support for 'ping' mode. Add header magic detection. Add module aliases. Add useful traces. diffstat: ChangeLog | 6 + VisualMagick/installer/inc/version.isx | 4 +- coders/heif.c | 122 ++++++++++++++++++++++++++++++-- cscope.files | 2 + magick/magic.c | 4 + magick/module_aliases.h | 3 +- magick/version.h | 4 +- www/Changelog.html | 5 + 8 files changed, 137 insertions(+), 13 deletions(-) diffs (326 lines): diff -r 6ca5dbc2fb4f -r 743f1bcf3052 ChangeLog --- a/ChangeLog Sat Jan 15 17:09:46 2022 -0600 +++ b/ChangeLog Sun Jan 16 11:57:59 2022 -0600 @@ -1,3 +1,9 @@ +2022-01-16 Bob Friesenhahn <[email protected]> + + * coders/heif.c (ReadHEIFImage): Take row stride into account when + reading pixel rows. Add support for 'ping' mode. Add header magic + detection. Add module aliases. Add useful traces. + 2022-01-15 Bob Friesenhahn <[email protected]> * coders/jxl.c: Added preliminary JPEG XL support written by diff -r 6ca5dbc2fb4f -r 743f1bcf3052 VisualMagick/installer/inc/version.isx --- a/VisualMagick/installer/inc/version.isx Sat Jan 15 17:09:46 2022 -0600 +++ b/VisualMagick/installer/inc/version.isx Sun Jan 16 11:57:59 2022 -0600 @@ -10,5 +10,5 @@ #define public MagickPackageName "GraphicsMagick" #define public MagickPackageVersion "1.4" -#define public MagickPackageVersionAddendum ".020220115" -#define public MagickPackageReleaseDate "snapshot-20220115" +#define public MagickPackageVersionAddendum ".020220116" +#define public MagickPackageReleaseDate "snapshot-20220116" diff -r 6ca5dbc2fb4f -r 743f1bcf3052 coders/heif.c --- a/coders/heif.c Sat Jan 15 17:09:46 2022 -0600 +++ b/coders/heif.c Sun Jan 16 11:57:59 2022 -0600 @@ -34,7 +34,50 @@ #if defined(HasHEIF) #include <libheif/heif.h> + +/* +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% % +% % +% % +% I s H E I F % +% % +% % +% % +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% Method IsHEIF returns True if the image format type, identified by the +% magick string, is supported by this HEIF reader. +% +% The format of the IsHEIF method is: +% +% unsigned int IsHEIF(const unsigned char *magick,const size_t length) +% +% A description of each parameter follows: +% +% o status: Method IsHEIF returns True if the image format type is HEIF. +% +% o magick: This string is generally the first few bytes of an image file +% or blob. +% +% o length: Specifies the length of the magick string. +% +% +*/ +static unsigned int IsHEIF(const unsigned char *magick,const size_t length) +{ + enum heif_filetype_result + heif_filetype; + if (length < 12) + return(False); + + heif_filetype = heif_check_filetype(magick, (int) length); + if (heif_filetype == heif_filetype_yes_supported) + return True; + + return(False); +} /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % @@ -109,6 +152,11 @@ unsigned char* profile; + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Profile \"%s\" with size %" MAGICK_SIZE_T_F "u bytes", + profile_name, (MAGICK_SIZE_T) profile_size); + profile=MagickAllocateResourceLimitedArray(unsigned char*,profile_size, sizeof(*profile)); if (profile == (unsigned char*) NULL) @@ -121,6 +169,10 @@ if (err.code != heif_error_Ok) { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "heif_image_handle_get_metadata() reports error \"%s\"", + err.message); MagickFreeResourceLimitedMemory(profile); MagickFreeResourceLimitedMemory(ids); ThrowReaderException(CorruptImageError, @@ -210,7 +262,13 @@ || heif_status.code == heif_error_Unsupported_feature) ThrowHEIFReaderException(CoderError, ImageTypeNotSupported, image); if (heif_status.code != heif_error_Ok) - ThrowHEIFReaderException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); + { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "heif_context_read_from_memory() reports error \"%s\"", + heif_status.message); + ThrowHEIFReaderException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); + } /* no support for reading multiple images but could be added */ if (heif_context_get_number_of_top_level_images(heif) != 1) @@ -220,30 +278,68 @@ if (heif_status.code == heif_error_Memory_allocation_error) ThrowHEIFReaderException(ResourceLimitError,MemoryAllocationFailed,image); if (heif_status.code != heif_error_Ok) - ThrowHEIFReaderException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); + { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "heif_context_get_primary_image_handle() reports error \"%s\"", + heif_status.message); + ThrowHEIFReaderException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); + } image->columns=heif_image_handle_get_width(heif_image_handle); image->rows=heif_image_handle_get_height(heif_image_handle); if (heif_image_handle_has_alpha_channel(heif_image_handle)) image->matte=MagickTrue; + if (image->logging) + { + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Geometry: %lux%lu", image->columns, image->rows); + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Matte: %s", image->matte ? "True" : "False"); + } + if (!ReadMetadata(heif_image_handle, image, exception)) { HEIFReadCleanup(); return NULL; } + if (image_info->ping) + { + image->depth = 8; + HEIFReadCleanup(); + CloseBlob(image); + return image; + } + + if (CheckImagePixelLimits(image, exception) != MagickPass) + ThrowHEIFReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); + + /* FIXME: Add decoding options support such as a progress monitor */ heif_status=heif_decode_image(heif_image_handle, &heif_image, heif_colorspace_RGB, image->matte ? heif_chroma_interleaved_RGBA : - heif_chroma_interleaved_RGB, NULL); + heif_chroma_interleaved_RGB, + /* const struct heif_decoding_options* */ NULL ); if (heif_status.code == heif_error_Memory_allocation_error) ThrowHEIFReaderException(ResourceLimitError,MemoryAllocationFailed,image); if (heif_status.code != heif_error_Ok) - ThrowHEIFReaderException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); + { + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "heif_decode_image() reports error \"%s\"", + heif_status.message); + ThrowHEIFReaderException(CorruptImageError, AnErrorHasOccurredReadingFromFile, image); + } image->depth=heif_image_get_bits_per_pixel(heif_image, heif_channel_interleaved); /* the requested channel is interleaved there depth is a sum of all channels split it up again: */ + if (image->logging) + { + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "heif_image_get_bits_per_pixel: bits_per_pixel=%u", image->depth); + } if (image->depth == 32 && image->matte) image->depth = 8; else if (image->depth == 24 && !image->matte) @@ -255,18 +351,26 @@ if (!pixels) ThrowHEIFReaderException(CoderError, NoDataReturned, image); + if (image->logging) + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "heif_image_get_plane_readonly: bytes-per-line=%d", + row_stride); + + /* Transfer pixels to image, using row stride to find start of each row. */ for (y=0; y < (long)image->rows; y++) { + const uint8_t *line; q=SetImagePixelsEx(image,0,y,image->columns,1,exception); if (q == (PixelPacket *) NULL) ThrowHEIFReaderException(ResourceLimitError,MemoryAllocationFailed,image); + line=pixels+y*row_stride; for (x=0; x < (long)image->columns; x++) { - SetRedSample(q,ScaleCharToQuantum(*pixels++)); - SetGreenSample(q,ScaleCharToQuantum(*pixels++)); - SetBlueSample(q,ScaleCharToQuantum(*pixels++)); + SetRedSample(q,ScaleCharToQuantum(*line++)); + SetGreenSample(q,ScaleCharToQuantum(*line++)); + SetBlueSample(q,ScaleCharToQuantum(*line++)); if (image->matte) { - SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*pixels++)); + SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*line++)); } else { SetOpacitySample(q,OpaqueOpacity); } @@ -332,6 +436,7 @@ entry=SetMagickInfo("HEIF"); #if defined(HasHEIF) entry->decoder=(DecoderHandler) ReadHEIFImage; + entry->magick=(MagickHandler) IsHEIF; #endif entry->description=description; entry->adjoin=False; @@ -345,6 +450,7 @@ entry=SetMagickInfo("HEIC"); #if defined(HasHEIF) entry->decoder=(DecoderHandler) ReadHEIFImage; + entry->magick=(MagickHandler) IsHEIF; #endif entry->description=description; entry->adjoin=False; diff -r 6ca5dbc2fb4f -r 743f1bcf3052 cscope.files --- a/cscope.files Sat Jan 15 17:09:46 2022 -0600 +++ b/cscope.files Sun Jan 16 11:57:59 2022 -0600 @@ -27,6 +27,7 @@ coders/gif.c coders/gradient.c coders/gray.c +coders/heif.c coders/histogram.c coders/hrz.c coders/html.c @@ -35,6 +36,7 @@ coders/info.c coders/jbig.c coders/jnx.c +coders/jpx.c coders/jp2.c coders/jpeg.c coders/label.c diff -r 6ca5dbc2fb4f -r 743f1bcf3052 magick/magic.c --- a/magick/magic.c Sat Jan 15 17:09:46 2022 -0600 +++ b/magick/magic.c Sun Jan 16 11:57:59 2022 -0600 @@ -60,6 +60,7 @@ { #define MAGIC(name,offset,magic) {name,(const unsigned char * const)magic,sizeof(magic)-1,offset} MAGIC("WEBP", 8, "WEBP"), + MAGIC("AVIF", 4, "ftypavif"), /* MAGIC("AVI", 0, "RIFF"), */ MAGIC("8BIMWTEXT", 0, "8\000B\000I\000M\000#"), MAGIC("8BIMTEXT", 0, "8BIM#"), @@ -90,6 +91,9 @@ MAGIC("FITS", 0, "SIMPLE"), MAGIC("FPX", 0, "\320\317\021\340"), MAGIC("GIF", 0, "GIF8"), + MAGIC("HEIC", 4, "ftypheic"), + MAGIC("HEIC", 4, "ftypheix"), + MAGIC("HEIC", 4, "ftypmif1"), MAGIC("HDF", 1, "HDF"), MAGIC("HPGL", 0, "IN;"), MAGIC("HTML", 1, "HTML"), diff -r 6ca5dbc2fb4f -r 743f1bcf3052 magick/module_aliases.h --- a/magick/module_aliases.h Sat Jan 15 17:09:46 2022 -0600 +++ b/magick/module_aliases.h Sun Jan 16 11:57:59 2022 -0600 @@ -35,6 +35,7 @@ MODULEALIAS("APP1","META"), MODULEALIAS("APP1JPEG","META"), MODULEALIAS("ARW","DCRAW"), + MODULEALIAS("AVIF","HEIF"), MODULEALIAS("B","GRAY"), MODULEALIAS("BIE","JBIG"), MODULEALIAS("BIGTIFF","TIFF"), @@ -72,9 +73,9 @@ MODULEALIAS("GRAYA","GRAY"), MODULEALIAS("GROUP4RAW","TIFF"), MODULEALIAS("H","LOGO"), + MODULEALIAS("HEIC","HEIF"), MODULEALIAS("HTM","HTML"), MODULEALIAS("HTTP","URL"), - MODULEALIAS("HEIC","HEIF"), MODULEALIAS("ICB","TGA"), MODULEALIAS("ICC","META"), MODULEALIAS("ICM","META"), diff -r 6ca5dbc2fb4f -r 743f1bcf3052 magick/version.h --- a/magick/version.h Sat Jan 15 17:09:46 2022 -0600 +++ b/magick/version.h Sun Jan 16 11:57:59 2022 -0600 @@ -38,8 +38,8 @@ #define MagickLibVersion 0x262300 #define MagickLibVersionText "1.4" #define MagickLibVersionNumber 26,23,0 -#define MagickChangeDate "20220115" -#define MagickReleaseDate "snapshot-20220115" +#define MagickChangeDate "20220116" +#define MagickReleaseDate "snapshot-20220116" /* The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines diff -r 6ca5dbc2fb4f -r 743f1bcf3052 www/Changelog.html --- a/www/Changelog.html Sat Jan 15 17:09:46 2022 -0600 +++ b/www/Changelog.html Sun Jan 16 11:57:59 2022 -0600 @@ -35,6 +35,11 @@ <div class="document"> +<p>2022-01-16 Bob Friesenhahn <<a class="reference external" href="mailto:bfriesen%40simple.dallas.tx.us">bfriesen<span>@</span>simple<span>.</span>dallas<span>.</span>tx<span>.</span>us</a>></p> +<blockquote> +* coders/heif.c (ReadHEIFImage): Take row stride into account when +reading pixel rows. Add support for 'ping' mode. Add header magic +detection. Add module aliases. Add useful traces.</blockquote> <p>2022-01-15 Bob Friesenhahn <<a class="reference external" href="mailto:bfriesen%40simple.dallas.tx.us">bfriesen<span>@</span>simple<span>.</span>dallas<span>.</span>tx<span>.</span>us</a>></p> <blockquote> <p>* coders/jxl.c: Added preliminary JPEG XL support written by