ThrowBinaryException(CorruptImageError,error->message,image->filename);
}
-static Image *ReadHEICImage(const ImageInfo *image_info,
- ExceptionInfo *exception)
+static MagickBooleanType ReadHEICColorProfile(Image *image,
+ struct heif_image_handle *image_handle,ExceptionInfo *exception)
{
- const char
- *option;
-
- const StringInfo
- *profile;
-
- heif_item_id
- exif_id;
-
- Image
- *image;
-
- int
- count,
- stride_y,
- stride_cb,
- stride_cr;
-
- MagickBooleanType
- status;
-
size_t
length;
- ssize_t
- y;
-
- struct heif_context
- *heif_context;
-
- struct heif_decoding_options
- *decode_options;
-
- struct heif_error
- error;
-
- struct heif_image
- *heif_image;
-
- struct heif_image_handle
- *image_handle;
-
- uint8_t
- *p_y,
- *p_cb,
- *p_cr;
-
- void
- *file_data;
-
- /*
- Open image file.
- */
- assert(image_info != (const ImageInfo *) NULL);
- assert(image_info->signature == MagickCoreSignature);
- if (image_info->debug != MagickFalse)
- (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
- image_info->filename);
- assert(exception != (ExceptionInfo *) NULL);
- assert(exception->signature == MagickCoreSignature);
- image=AcquireImage(image_info,exception);
- status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
- if (status == MagickFalse)
- return(DestroyImageList(image));
- if (GetBlobSize(image) > (MagickSizeType) SSIZE_MAX)
- ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
- length=(size_t) GetBlobSize(image);
- file_data=AcquireMagickMemory(length);
- if (file_data == (void *) NULL)
- ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
- if (ReadBlob(image,length,file_data) != (ssize_t) length)
- {
- file_data=RelinquishMagickMemory(file_data);
- ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
- }
- /*
- Decode HEIF file
- */
- heif_context=heif_context_alloc();
- error=heif_context_read_from_memory(heif_context,file_data,length,NULL);
- file_data=RelinquishMagickMemory(file_data);
- if (IsHeifSuccess(&error,image,exception) == MagickFalse)
- {
- heif_context_free(heif_context);
- return(DestroyImageList(image));
- }
- image_handle=(struct heif_image_handle *) NULL;
- error=heif_context_get_primary_image_handle(heif_context,&image_handle);
- if (IsHeifSuccess(&error,image,exception) == MagickFalse)
- {
- heif_context_free(heif_context);
- return(DestroyImageList(image));
- }
#if LIBHEIF_NUMERIC_VERSION >= 0x01040000
length=heif_image_handle_get_raw_color_profile_size(image_handle);
if (length > 0)
Read color profile.
*/
if ((MagickSizeType) length > GetBlobSize(image))
- {
- heif_image_handle_release(image_handle);
- heif_context_free(heif_context);
- ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
- }
+ ThrowBinaryException(CorruptImageError,"InsufficientImageDataInFile",
+ image->filename);
color_buffer=(unsigned char *) AcquireMagickMemory(length);
if (color_buffer != (unsigned char *) NULL)
{
+ struct heif_error
+ error;
+
error=heif_image_handle_get_raw_color_profile(image_handle,
color_buffer);
if (error.code == 0)
color_buffer=(unsigned char *) RelinquishMagickMemory(color_buffer);
}
#endif
+ return(MagickTrue);
+}
+
+static MagickBooleanType ReadHEICExifProfile(Image *image,
+ struct heif_image_handle *image_handle,ExceptionInfo *exception)
+{
+ heif_item_id
+ exif_id;
+
+ int
+ count;
+
count=heif_image_handle_get_list_of_metadata_block_IDs(image_handle,"Exif",
&exif_id,1);
if (count > 0)
*/
exif_size=heif_image_handle_get_metadata_size(image_handle,exif_id);
if ((MagickSizeType) exif_size > GetBlobSize(image))
- {
- heif_image_handle_release(image_handle);
- heif_context_free(heif_context);
- ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
- }
+ ThrowBinaryException(CorruptImageError,"InsufficientImageDataInFile",
+ image->filename);
exif_buffer=(unsigned char *) AcquireMagickMemory(exif_size);
if (exif_buffer != (unsigned char *) NULL)
{
+ struct heif_error
+ error;
+
error=heif_image_handle_get_metadata(image_handle,
exif_id,exif_buffer);
if (error.code == 0)
}
exif_buffer=(unsigned char *) RelinquishMagickMemory(exif_buffer);
}
+ return(MagickTrue);
+}
+
+static MagickBooleanType ReadHEICImageByID(const ImageInfo *image_info,
+ Image *image,struct heif_context *heif_context,heif_item_id image_id,
+ ExceptionInfo *exception)
+{
+ const char
+ *option;
+
+ const StringInfo
+ *profile;
+
+ int
+ stride_y,
+ stride_cb,
+ stride_cr;
+
+ MagickBooleanType
+ status;
+
+ ssize_t
+ y;
+
+ struct heif_decoding_options
+ *decode_options;
+
+ struct heif_error
+ error;
+
+ struct heif_image
+ *heif_image;
+
+ struct heif_image_handle
+ *image_handle;
+
+ uint8_t
+ *p_y,
+ *p_cb,
+ *p_cr;
+
+ error=heif_context_get_image_handle(heif_context,image_id,&image_handle);
+ if (IsHeifSuccess(&error,image,exception) == MagickFalse)
+ return(MagickFalse);
+ if (ReadHEICColorProfile(image,image_handle,exception) == MagickFalse)
+ {
+ heif_image_handle_release(image_handle);
+ return(MagickFalse);
+ }
+ if (ReadHEICExifProfile(image,image_handle,exception) == MagickFalse)
+ {
+ heif_image_handle_release(image_handle);
+ return(MagickFalse);
+ }
/*
Set image size.
*/
if (image_info->ping != MagickFalse)
{
image->colorspace=YCbCrColorspace;
+ profile=GetImageProfile(image,"icc");
+ if (profile != (const StringInfo *) NULL)
+ image->colorspace=sRGBColorspace;
heif_image_handle_release(image_handle);
- heif_context_free(heif_context);
- return(GetFirstImageInList(image));
+ return(MagickTrue);
}
status=SetImageExtent(image,image->columns,image->rows,exception);
if (status == MagickFalse)
{
heif_image_handle_release(image_handle);
- heif_context_free(heif_context);
- return(DestroyImageList(image));
+ return(MagickFalse);
}
/*
Copy HEIF image into ImageMagick data structures.
if ((IsHeifSuccess(&error,image,exception) == MagickFalse) ||
(status == MagickFalse))
{
+ heif_image_release(heif_image);
heif_image_handle_release(image_handle);
- heif_context_free(heif_context);
- return(DestroyImageList(image));
+ return(MagickFalse);
}
p_y=heif_image_get_plane(heif_image,heif_channel_Y,&stride_y);
p_cb=heif_image_get_plane(heif_image,heif_channel_Cb,&stride_cb);
}
heif_image_release(heif_image);
heif_image_handle_release(image_handle);
- heif_context_free(heif_context);
profile=GetImageProfile(image,"icc");
if (profile != (const StringInfo *) NULL)
(void) TransformImageColorspace(image,sRGBColorspace,exception);
+ return(MagickTrue);
+}
+
+static Image *ReadHEICImage(const ImageInfo *image_info,
+ ExceptionInfo *exception)
+{
+ heif_item_id
+ primary_image_id;
+
+ Image
+ *image;
+
+ MagickBooleanType
+ status;
+
+ size_t
+ length;
+
+ struct heif_context
+ *heif_context;
+
+ struct heif_error
+ error;
+
+ void
+ *file_data;
+
+ /*
+ Open image file.
+ */
+ assert(image_info != (const ImageInfo *) NULL);
+ assert(image_info->signature == MagickCoreSignature);
+ if (image_info->debug != MagickFalse)
+ (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
+ image_info->filename);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickCoreSignature);
+ image=AcquireImage(image_info,exception);
+ status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
+ if (status == MagickFalse)
+ return(DestroyImageList(image));
+ if (GetBlobSize(image) > (MagickSizeType) SSIZE_MAX)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ length=(size_t) GetBlobSize(image);
+ file_data=AcquireMagickMemory(length);
+ if (file_data == (void *) NULL)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ if (ReadBlob(image,length,file_data) != (ssize_t) length)
+ {
+ file_data=RelinquishMagickMemory(file_data);
+ ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
+ }
+ /*
+ Decode HEIF file
+ */
+ heif_context=heif_context_alloc();
+ error=heif_context_read_from_memory(heif_context,file_data,length,NULL);
+ file_data=RelinquishMagickMemory(file_data);
+ if (IsHeifSuccess(&error,image,exception) == MagickFalse)
+ {
+ heif_context_free(heif_context);
+ return(DestroyImageList(image));
+ }
+ error=heif_context_get_primary_image_ID(heif_context,&primary_image_id);
+ if (IsHeifSuccess(&error,image,exception) == MagickFalse)
+ {
+ heif_context_free(heif_context);
+ return(DestroyImageList(image));
+ }
+ status=ReadHEICImageByID(image_info,image,heif_context,primary_image_id,
+ exception);
+ heif_context_free(heif_context);
+ if (status == MagickFalse)
+ return(DestroyImageList(image));
return(GetFirstImageInList(image));
}
#endif