GraphicsMagick: JXL: Support reading and writing 32-bit 'float' ...
GraphicsMagick Commits <[email protected]>
| Newsgroups | gmane.comp.video.graphicsmagick.cvs |
|---|---|
| Message-ID | <mailman.33666.1671400394.1567.graphicsmagick-commit@lists.sourceforge.net> |
changeset ad870e7ecd12 in /hg/GraphicsMagick details: http://hg.GraphicsMagick.org/hg/GraphicsMagick?cmd=changeset;node=ad870e7ecd12 summary: JXL: Support reading and writing 32-bit 'float' images. diffstat: ChangeLog | 9 +++ NEWS.txt | 6 +- coders/jxl.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++------ magick/image.c | 6 ++ www/Changelog.html | 6 ++ www/NEWS.html | 5 +- 6 files changed, 149 insertions(+), 19 deletions(-) diffs (322 lines): diff -r 6e880ceeaece -r ad870e7ecd12 ChangeLog --- a/ChangeLog Sun Dec 18 09:11:27 2022 -0600 +++ b/ChangeLog Sun Dec 18 15:53:02 2022 -0600 @@ -1,5 +1,14 @@ 2022-12-18 Bob Friesenhahn <[email protected]> + * NEWS.txt: Updated the news. + + * magick/image.c (SetImageDepth): Restore is_monochrome and + is_grayscale image flags. Changing depth should not change the + nature of 'gray'. + + * coders/jxl.c: Support reading and writing 32-bit 'float' + images. Need a Q32 build in order to write 32-bit 'float' images. + * fuzzing/oss-fuzz-build.sh: Remove xz --with-pic=yes option which now seems to annoy oss-fuzz build. diff -r 6e880ceeaece -r ad870e7ecd12 NEWS.txt --- a/NEWS.txt Sun Dec 18 09:11:27 2022 -0600 +++ b/NEWS.txt Sun Dec 18 15:53:02 2022 -0600 @@ -140,6 +140,10 @@ * Blob: The ReadBlobString() function has been re-written to perform better when reading from files. +* JXL: The JXL coder is updated to compile with what will likely + become JXL 0.8.0. Support for 16-bit 'short' samples and 32-bit + float samples added. + * MIME: GM "magick" to MIME mappings have been added for apng, avif, bmp, ico, and webp (regardless of if they are supported). @@ -154,7 +158,7 @@ * Update bundled libjpeg to version 9e. -* Update bundled libtiff to version 4.4.0 (but still compilable using MSVC2008!). +* Update bundled libtiff to version 4.5.0 (but still compilable using MSVC2008!). Build Changes: diff -r 6e880ceeaece -r ad870e7ecd12 coders/jxl.c --- a/coders/jxl.c Sun Dec 18 09:11:27 2022 -0600 +++ b/coders/jxl.c Sun Dec 18 15:53:02 2022 -0600 @@ -19,8 +19,15 @@ % Status: Only support basic images (no animations) with grayscale/SRGB colorspace * Note that JXL is a C++ library so does require linking with a c++ compiler. * -* Currently tested vs libjxl-0.6.1 on ubuntu only, likely will have build problems +* Currently tested vs libjxl-0.7.0 on ubuntu only, likely will have build problems * on other platforms. Also note the amount of third-party-libs required! +* +* Features still to be completed: +* +* * Support linear gray +* * Support CMYK +* * Support embedded profiles +* * Support 16-bit float ("Half") format */ #include "magick/studio.h" @@ -294,9 +301,10 @@ if (image->matte) { FOR_PIXEL_PACKETS { - SetRedSample(q,ScaleCharToQuantum(*p)); - SetGreenSample(q,ScaleCharToQuantum(*p)); - SetBlueSample(q,ScaleCharToQuantum(*p)); p++; + const Quantum s = ScaleCharToQuantum(*p); p++; + SetRedSample(q,s); + SetGreenSample(q,s); + SetBlueSample(q,s); SetOpacitySample(q,MaxRGB-ScaleCharToQuantum(*p)); p++; q++; } @@ -304,9 +312,10 @@ } else { FOR_PIXEL_PACKETS { - SetRedSample(q,ScaleCharToQuantum(*p)); - SetGreenSample(q,ScaleCharToQuantum(*p)); - SetBlueSample(q,ScaleCharToQuantum(*p)); p++; + const Quantum s = ScaleCharToQuantum(*p); p++; + SetRedSample(q,s); + SetGreenSample(q,s); + SetBlueSample(q,s); p++; SetOpacitySample(q,OpaqueOpacity); q++; } @@ -361,9 +370,10 @@ if (image->matte) { FOR_PIXEL_PACKETS { - SetRedSample(q,ScaleShortToQuantum(*p)); - SetGreenSample(q,ScaleShortToQuantum(*p)); - SetBlueSample(q,ScaleShortToQuantum(*p)); p++; + Quantum s = ScaleShortToQuantum(*p); p++; + SetRedSample(q,s); + SetGreenSample(q,s); + SetBlueSample(q,s); SetOpacitySample(q,MaxRGB-ScaleShortToQuantum(*p)); p++; q++; } @@ -371,9 +381,10 @@ } else { FOR_PIXEL_PACKETS { - SetRedSample(q,ScaleShortToQuantum(*p)); - SetGreenSample(q,ScaleShortToQuantum(*p)); - SetBlueSample(q,ScaleShortToQuantum(*p)); p++; + Quantum s = ScaleShortToQuantum(*p); p++; + SetRedSample(q,s); + SetGreenSample(q,s); + SetBlueSample(q,s); SetOpacitySample(q,OpaqueOpacity); q++; } @@ -384,6 +395,47 @@ } +static MagickBool fill_pixels_float_grayscale(Image *image, + ExceptionInfo *exception, + float *p) +{ + long + x, + y; + + PixelPacket + *q; + + image->storage_class = DirectClass; + + if (image->matte) { + FOR_PIXEL_PACKETS + { + Quantum s = RoundFloatToQuantum(*p * MaxRGBFloat); p++; + SetRedSample(q,s); + SetGreenSample(q,s); + SetBlueSample(q,s); + SetOpacitySample(q,MaxRGB-RoundFloatToQuantum(*p * MaxRGBFloat)); p++; + q++; + } + END_FOR_PIXEL_PACKETS + } else { + FOR_PIXEL_PACKETS + { + Quantum s = RoundFloatToQuantum(*p * MaxRGBFloat); p++; + SetRedSample(q,s); + SetGreenSample(q,s); + SetBlueSample(q,s); + SetOpacitySample(q,OpaqueOpacity); + q++; + } + END_FOR_PIXEL_PACKETS + } + + return MagickTrue; +} + + /** Convert any linear RGB to SRGB * Formula from wikipedia: * https://en.wikipedia.org/wiki/SRGB @@ -587,6 +639,29 @@ return str; } +static const char *JxlDataTypeAsString(const JxlDataType data_type) +{ + const char *str = "Unknown"; + + switch (data_type) + { + case JXL_TYPE_FLOAT: + str = "Float"; + break; + case JXL_TYPE_UINT8: + str = "UINT8"; + break; + case JXL_TYPE_UINT16: + str = "UINT16"; + break; + case JXL_TYPE_FLOAT16: + str = "FLOAT16"; + break; + } + + return str; +} + #define JXLReadCleanup() \ MagickFreeResourceLimitedMemory(out_buf); \ MagickFreeResourceLimitedMemory(in_buf); \ @@ -955,6 +1030,10 @@ { res=fill_pixels_short_grayscale(image, exception, (unsigned short *) out_buf); } + else if (format.data_type == JXL_TYPE_FLOAT) + { + res=fill_pixels_float_grayscale(image, exception, (float *) out_buf); + } } if (!res) @@ -1020,6 +1099,28 @@ ThrowWriterException(code_,reason_,image_); \ } while(1) +static StorageType JxlDataTypeToDispatchStorageType(const JxlDataType data_type) +{ + StorageType storage_type = 0; + + switch (data_type) + { + case JXL_TYPE_FLOAT: + storage_type = FloatPixel; + break; + case JXL_TYPE_UINT8: + storage_type = CharPixel; + break; + case JXL_TYPE_UINT16: + storage_type = ShortPixel; + break; + case JXL_TYPE_FLOAT16: + storage_type = ShortPixel; // FIXME: Not actually supported yet + break; + } + + return storage_type; +} static unsigned int WriteJXLImage(const ImageInfo *image_info,Image *image) { @@ -1133,10 +1234,13 @@ else if (image->depth <= 16) pixel_format.data_type = JXL_TYPE_UINT16; else if (image->depth <= 32) - pixel_format.data_type = JXL_TYPE_UINT16; /* or JXL_TYPE_FLOAT */ + pixel_format.data_type = JXL_TYPE_FLOAT; /* or JXL_TYPE_FLOAT JXL_TYPE_UINT16 */ else ThrowJXLWriterException(CoderError,ColorspaceModelIsNotSupported,image); + (void) LogMagickEvent(CoderEvent,GetMagickModule(), + "Using JXL '%s' data type", JxlDataTypeAsString(pixel_format.data_type)); + /* Initialize JxlBasicInfo struct to default values. */ JxlEncoderInitBasicInfo(&basic_info); /* Width of the image in pixels, before applying orientation. */ @@ -1272,9 +1376,7 @@ status=DispatchImage(image,0,0,image->columns,image->rows, characteristics.grayscale ? "I" : (image->matte ? "RGBA" : "RGB"), - basic_info.bits_per_sample == 8 ? CharPixel : - (basic_info.bits_per_sample == 16 ? ShortPixel : - basic_info.bits_per_sample == LongPixel), + JxlDataTypeToDispatchStorageType(pixel_format.data_type), in_buf,&image->exception); if (status == MagickFail) ThrowJXLWriterException(ResourceLimitError,MemoryAllocationFailed,image); diff -r 6e880ceeaece -r ad870e7ecd12 magick/image.c --- a/magick/image.c Sun Dec 18 09:11:27 2022 -0600 +++ b/magick/image.c Sun Dec 18 15:53:02 2022 -0600 @@ -2700,6 +2700,10 @@ MagickPassFail status=MagickPass; + MagickBool + is_monochrome = image->is_monochrome, + is_grayscale = image->is_grayscale; + assert(image != (Image *) NULL); status=QuantumOperatorImage(image,AllChannels,DepthQuantumOp,(double) depth, @@ -2708,6 +2712,8 @@ status=QuantumOperatorImage(image,OpacityChannel,DepthQuantumOp,(double) depth, &image->exception); image->depth=Min(depth,QuantumDepth); + image->is_monochrome = is_monochrome; + image->is_grayscale = is_grayscale; return status; } diff -r 6e880ceeaece -r ad870e7ecd12 www/Changelog.html --- a/www/Changelog.html Sun Dec 18 09:11:27 2022 -0600 +++ b/www/Changelog.html Sun Dec 18 15:53:02 2022 -0600 @@ -40,6 +40,12 @@ <p>2022-12-18 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> <ul class="simple"> +<li><p>NEWS.txt: Updated the news.</p></li> +<li><p>magick/image.c (SetImageDepth): Restore is_monochrome and +is_grayscale image flags. Changing depth should not change the +nature of 'gray'.</p></li> +<li><p>coders/jxl.c: Support reading and writing 32-bit 'float' +images. Need a Q32 build in order to write 32-bit 'float' images.</p></li> <li><p>fuzzing/oss-fuzz-build.sh: Remove xz --with-pic=yes option which now seems to annoy oss-fuzz build.</p></li> </ul> diff -r 6e880ceeaece -r ad870e7ecd12 www/NEWS.html --- a/www/NEWS.html Sun Dec 18 09:11:27 2022 -0600 +++ b/www/NEWS.html Sun Dec 18 15:53:02 2022 -0600 @@ -189,6 +189,9 @@ distribution size.</p></li> <li><p>Blob: The ReadBlobString() function has been re-written to perform better when reading from files.</p></li> +<li><p>JXL: The JXL coder is updated to compile with what will likely +become JXL 0.8.0. Support for 16-bit 'short' samples and 32-bit +float samples added.</p></li> <li><p>MIME: GM "magick" to MIME mappings have been added for apng, avif, bmp, ico, and webp (regardless of if they are supported).</p></li> <li><p>XPM: The XPM reader performance is dramatically improved and is @@ -200,7 +203,7 @@ <p>Windows Delegate Updates/Additions:</p> <ul class="simple"> <li><p>Update bundled libjpeg to version 9e.</p></li> -<li><p>Update bundled libtiff to version 4.4.0 (but still compilable using MSVC2008!).</p></li> +<li><p>Update bundled libtiff to version 4.5.0 (but still compilable using MSVC2008!).</p></li> </ul> <p>Build Changes:</p> <ul class="simple">