Skip to content

Commit

Permalink
Added support for writing animated jxl images.
Browse files Browse the repository at this point in the history
  • Loading branch information
dlemstra committed Dec 29, 2022
1 parent 56814b9 commit 555b2cd
Showing 1 changed file with 61 additions and 22 deletions.
83 changes: 61 additions & 22 deletions coders/jxl.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,9 @@ static MagickBooleanType WriteJXLImage(const ImageInfo *image_info,Image *image,
JxlEncoderStatus
jxl_status;

JxlFrameHeader
frame_header = { 0 };

JxlMemoryManager
memory_manager;

Expand Down Expand Up @@ -893,6 +896,16 @@ static MagickBooleanType WriteJXLImage(const ImageInfo *image_info,Image *image,
}
if (image_info->quality == 100)
basic_info.uses_original_profile=JXL_TRUE;
if ((image_info->adjoin != MagickFalse) &&
(GetNextImageInList(image) != (Image *) NULL))
{
basic_info.have_animation=JXL_TRUE;
basic_info.animation.num_loops=(uint32_t) image->iterations;
basic_info.animation.tps_numerator=(uint32_t) image->ticks_per_second;
basic_info.animation.tps_denominator=1;
JxlEncoderInitFrameHeader(&frame_header);
frame_header.duration=1;
}
jxl_status=JxlEncoderSetBasicInfo(jxl_info,&basic_info);
if (jxl_status != JXL_ENC_SUCCESS)
{
Expand Down Expand Up @@ -980,26 +993,54 @@ static MagickBooleanType WriteJXLImage(const ImageInfo *image_info,Image *image,
JxlEncoderDestroy(jxl_info);
ThrowWriterException(CoderError,"MemoryAllocationFailed");
}
pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
if (IsGrayColorspace(image->colorspace) != MagickFalse)
status=ExportImagePixels(image,0,0,image->columns,image->rows,
image->alpha_trait == BlendPixelTrait ? "IA" : "I",
JXLDataTypeToStorageType(image,pixel_format.data_type,exception),pixels,
exception);
else
status=ExportImagePixels(image,0,0,image->columns,image->rows,
image->alpha_trait == BlendPixelTrait ? "RGBA" : "RGB",
JXLDataTypeToStorageType(image,pixel_format.data_type,exception),pixels,
exception);
if (status == MagickFalse)
{
pixel_info=RelinquishVirtualMemory(pixel_info);
JxlThreadParallelRunnerDestroy(runner);
JxlEncoderDestroy(jxl_info);
ThrowWriterException(CoderError,"MemoryAllocationFailed");
}
jxl_status=JxlEncoderAddImageFrame(frame_settings,&pixel_format,pixels,
bytes_per_row*image->rows);
do
{
Image
*next;

if (basic_info.have_animation == JXL_TRUE)
{
jxl_status=JxlEncoderSetFrameHeader(frame_settings,&frame_header);
if (jxl_status != JXL_ENC_SUCCESS)
break;
}
pixels=(unsigned char *) GetVirtualMemoryBlob(pixel_info);
if (IsGrayColorspace(image->colorspace) != MagickFalse)
status=ExportImagePixels(image,0,0,image->columns,image->rows,
image->alpha_trait == BlendPixelTrait ? "IA" : "I",
JXLDataTypeToStorageType(image,pixel_format.data_type,exception),
pixels,exception);
else
status=ExportImagePixels(image,0,0,image->columns,image->rows,
image->alpha_trait == BlendPixelTrait ? "RGBA" : "RGB",
JXLDataTypeToStorageType(image,pixel_format.data_type,exception),
pixels,exception);
if (status == MagickFalse)
{
(void) ThrowMagickException(exception,GetMagickModule(),CoderError,
"MemoryAllocationFailed","`%s'",image->filename);
status=MagickFalse;
break;
}
if (jxl_status != JXL_ENC_SUCCESS)
break;
jxl_status=JxlEncoderAddImageFrame(frame_settings,&pixel_format,pixels,
bytes_per_row*image->rows);
if (jxl_status != JXL_ENC_SUCCESS)
break;
next=GetNextImageInList(image);
if (next == (Image*) NULL)
break;
if ((next->columns != image->columns) || (next->rows != image->rows))
{
(void) ThrowMagickException(exception,GetMagickModule(),ImageError,
"FramesNotSameDimensions","`%s'",image->filename);
status=MagickFalse;
break;
}
image=SyncNextImageInList(image);
} while (image_info->adjoin != MagickFalse);
pixel_info=RelinquishVirtualMemory(pixel_info);
if (jxl_status == JXL_ENC_SUCCESS)
{
unsigned char
Expand All @@ -1010,7 +1051,6 @@ static MagickBooleanType WriteJXLImage(const ImageInfo *image_info,Image *image,
MagickMaxBufferExtent,sizeof(*output_buffer));
if (output_buffer == (unsigned char *) NULL)
{
pixel_info=RelinquishVirtualMemory(pixel_info);
JxlThreadParallelRunnerDestroy(runner);
JxlEncoderDestroy(jxl_info);
ThrowWriterException(CoderError,"MemoryAllocationFailed");
Expand Down Expand Up @@ -1042,7 +1082,6 @@ static MagickBooleanType WriteJXLImage(const ImageInfo *image_info,Image *image,
}
output_buffer=(unsigned char *) RelinquishMagickMemory(output_buffer);
}
pixel_info=RelinquishVirtualMemory(pixel_info);
JxlThreadParallelRunnerDestroy(runner);
JxlEncoderDestroy(jxl_info);
if (jxl_status != JXL_ENC_SUCCESS)
Expand Down

0 comments on commit 555b2cd

Please sign in to comment.