From 742cd132b18c3612e00f5f7d47bc24dbae2e76f9 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 8 May 2022 14:35:18 -0700
Subject: [PATCH] Added support for JXL images (https://jpegxl.info/)
Fixes https://github.com/libsdl-org/SDL_image/issues/204
---
.gitmodules | 4 +
CHANGES.txt | 2 +
IMG.c | 11 ++
IMG_jxl.c | 263 ++++++++++++++++++++++++++++++++++++++++++++++++
Makefile.am | 1 +
Makefile.in | 33 +++---
SDL_image.h | 5 +-
configure | 277 ++++++++++++++++++++++++++++++++++++++++++++++++---
configure.ac | 58 +++++++++++
9 files changed, 626 insertions(+), 28 deletions(-)
create mode 100644 IMG_jxl.c
diff --git a/.gitmodules b/.gitmodules
index 2303971c..88ed07bc 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -18,3 +18,7 @@
path = external/zlib
url = https://github.com/libsdl-org/zlib.git
branch = v1.2.12-SDL
+[submodule "external/libjxl"]
+ path = external/libjxl
+ url = https://github.com/libsdl-org/libjxl.git
+ branch = v0.6.1-SDL
diff --git a/CHANGES.txt b/CHANGES.txt
index 3bddcc79..728df2bc 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,6 @@
2.0.6:
+Sam Lantinga - Sun May 8 14:31:27 PDT 2022
+ * Added support for JXL images (https://jpegxl.info/)
Thomas Bernard - Mon Oct 26 23:32:10 2020
* Fixed XCF regression introduced in 2.0.5
Sam Lantinga - Thu Oct 3 18:09:17 PDT 2019
diff --git a/IMG.c b/IMG.c
index 456c6ef4..68b79921 100644
--- a/IMG.c
+++ b/IMG.c
@@ -63,6 +63,7 @@ static struct {
{ "BMP", IMG_isBMP, IMG_LoadBMP_RW },
{ "GIF", IMG_isGIF, IMG_LoadGIF_RW },
{ "JPG", IMG_isJPG, IMG_LoadJPG_RW },
+ { "JXL", IMG_isJXL, IMG_LoadJXL_RW },
{ "LBM", IMG_isLBM, IMG_LoadLBM_RW },
{ "PCX", IMG_isPCX, IMG_LoadPCX_RW },
{ "PNG", IMG_isPNG, IMG_LoadPNG_RW },
@@ -95,6 +96,8 @@ const SDL_version *IMG_Linked_Version(void)
extern int IMG_InitJPG(void);
extern void IMG_QuitJPG(void);
+extern int IMG_InitJXL(void);
+extern void IMG_QuitJXL(void);
extern int IMG_InitPNG(void);
extern void IMG_QuitPNG(void);
extern int IMG_InitTIF(void);
@@ -114,6 +117,11 @@ int IMG_Init(int flags)
result |= IMG_INIT_JPG;
}
}
+ if (flags & IMG_INIT_JXL) {
+ if ((initialized & IMG_INIT_JXL) || IMG_InitJXL() == 0) {
+ result |= IMG_INIT_JXL;
+ }
+ }
if (flags & IMG_INIT_PNG) {
if ((initialized & IMG_INIT_PNG) || IMG_InitPNG() == 0) {
result |= IMG_INIT_PNG;
@@ -139,6 +147,9 @@ void IMG_Quit()
if (initialized & IMG_INIT_JPG) {
IMG_QuitJPG();
}
+ if (initialized & IMG_INIT_JXL) {
+ IMG_QuitJXL();
+ }
if (initialized & IMG_INIT_PNG) {
IMG_QuitPNG();
}
diff --git a/IMG_jxl.c b/IMG_jxl.c
new file mode 100644
index 00000000..0e51d3e9
--- /dev/null
+++ b/IMG_jxl.c
@@ -0,0 +1,263 @@
+/*
+ SDL_image: An example image loading library for use with SDL
+ Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
+/* This is a JXL image file loading framework */
+
+#include "SDL_image.h"
+
+#ifdef LOAD_JXL
+
+#include <jxl/decode.h>
+
+
+static struct {
+ int loaded;
+ void *handle;
+ JxlDecoder* (*JxlDecoderCreate)(const JxlMemoryManager* memory_manager);
+ JxlDecoderStatus (*JxlDecoderSubscribeEvents)(JxlDecoder* dec, int events_wanted);
+ JxlDecoderStatus (*JxlDecoderSetInput)(JxlDecoder* dec, const uint8_t* data, size_t size);
+ JxlDecoderStatus (*JxlDecoderProcessInput)(JxlDecoder* dec);
+ JxlDecoderStatus (*JxlDecoderGetBasicInfo)(const JxlDecoder* dec, JxlBasicInfo* info);
+ JxlDecoderStatus (*JxlDecoderImageOutBufferSize)(const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size);
+ JxlDecoderStatus (*JxlDecoderSetImageOutBuffer)(JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size);
+ void (*JxlDecoderDestroy)(JxlDecoder* dec);
+} lib;
+
+#ifdef LOAD_JXL_DYNAMIC
+#define FUNCTION_LOADER(FUNC, SIG) \
+ lib.FUNC = (SIG) SDL_LoadFunction(lib.handle, #FUNC); \
+ if (lib.FUNC == NULL) { SDL_UnloadObject(lib.handle); return -1; }
+#else
+#define FUNCTION_LOADER(FUNC, SIG) \
+ lib.FUNC = FUNC;
+#endif
+
+int IMG_InitJXL()
+{
+ if ( lib.loaded == 0 ) {
+#ifdef LOAD_JXL_DYNAMIC
+ lib.handle = SDL_LoadObject(LOAD_JXL_DYNAMIC);
+ if ( lib.handle == NULL ) {
+ return -1;
+ }
+#endif
+ FUNCTION_LOADER(JxlDecoderCreate, JxlDecoder* (*)(const JxlMemoryManager* memory_manager))
+ FUNCTION_LOADER(JxlDecoderSubscribeEvents, JxlDecoderStatus (*)(JxlDecoder* dec, int events_wanted))
+ FUNCTION_LOADER(JxlDecoderSetInput, JxlDecoderStatus (*)(JxlDecoder* dec, const uint8_t* data, size_t size))
+ FUNCTION_LOADER(JxlDecoderProcessInput, JxlDecoderStatus (*)(JxlDecoder* dec))
+ FUNCTION_LOADER(JxlDecoderGetBasicInfo, JxlDecoderStatus (*)(const JxlDecoder* dec, JxlBasicInfo* info))
+ FUNCTION_LOADER(JxlDecoderImageOutBufferSize, JxlDecoderStatus (*)(const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size))
+ FUNCTION_LOADER(JxlDecoderSetImageOutBuffer, JxlDecoderStatus (*)(JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size))
+ FUNCTION_LOADER(JxlDecoderDestroy, void (*)(JxlDecoder* dec))
+ }
+ ++lib.loaded;
+
+ return 0;
+}
+void IMG_QuitJXL()
+{
+ if ( lib.loaded == 0 ) {
+ return;
+ }
+ if ( lib.loaded == 1 ) {
+#ifdef LOAD_JXL_DYNAMIC
+ SDL_UnloadObject(lib.handle);
+#endif
+ }
+ --lib.loaded;
+}
+
+/* See if an image is contained in a data source */
+int IMG_isJXL(SDL_RWops *src)
+{
+ Sint64 start;
+ int is_JXL;
+ Uint8 magic[12];
+
+ if ( !src )
+ return 0;
+ start = SDL_RWtell(src);
+ is_JXL = 0;
+ if ( SDL_RWread(src, magic, 2, 1) ) {
+ if ( magic[0] == 0xFF && magic[1] == 0x0A ) {
+ /* This is a JXL codestream */
+ is_JXL = 1;
+ } else {
+ if ( SDL_RWread(src, &magic[2], sizeof(magic) - 2, 1) ) {
+ if ( magic[0] == 0x00 && magic[1] == 0x00 &&
+ magic[2] == 0x00 && magic[3] == 0x0C &&
+ magic[4] == 'J' && magic[5] == 'X' &&
+ magic[6] == 'L' && magic[7] == ' ' &&
+ magic[8] == 0x0D && magic[9] == 0x0A &&
+ magic[10] == 0x87 && magic[11] == 0x0A ) {
+ /* This is a JXL container */
+ is_JXL = 1;
+ }
+ }
+ }
+ }
+ SDL_RWseek(src, start, RW_SEEK_SET);
+ return(is_JXL);
+}
+
+/* Load a JXL type image from an SDL datasource */
+SDL_Surface *IMG_LoadJXL_RW(SDL_RWops *src)
+{
+ Sint64 start;
+ unsigned char *data;
+ size_t datasize;
+ JxlDecoder *decoder = NULL;
+ JxlBasicInfo info;
+ JxlPixelFormat format = { 4, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0 };
+ size_t outputsize;
+ void *pixels = NULL;
+ int pitch = 0;
+ SDL_Surface *surface = NULL;
+
+ if (!src) {
+ /* The error message has been set in SDL_RWFromFile */
+ return NULL;
+ }
+ start = SDL_RWtell(src);
+
+ if ((IMG_Init(IMG_INIT_JXL) & IMG_INIT_JXL) == 0) {
+ return NULL;
+ }
+
+ data = (unsigned char *)SDL_LoadFile_RW(src, &datasize, SDL_FALSE);
+ if (!data) {
+ return NULL;
+ }
+
+ decoder = lib.JxlDecoderCreate(NULL);
+ if (!decoder) {
+ IMG_SetError("Couldn't create JXL decoder");
+ goto done;
+ }
+
+ if (lib.JxlDecoderSubscribeEvents(decoder, JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) {
+ IMG_SetError("Couldn't subscribe to JXL events");
+ goto done;
+ }
+
+ if (lib.JxlDecoderSetInput(decoder, data, datasize) != JXL_DEC_SUCCESS) {
+ IMG_SetError("Couldn't set JXL input");
+ goto done;
+ }
+
+ SDL_zero(info);
+
+ for ( ; ; ) {
+ JxlDecoderStatus status = lib.JxlDecoderProcessInput(decoder);
+
+ switch (status ) {
+ case JXL_DEC_ERROR:
+ IMG_SetError("JXL decoder error");
+ goto done;
+ case JXL_DEC_NEED_MORE_INPUT:
+ IMG_SetError("Incomplete JXL image");
+ goto done;
+ case JXL_DEC_BASIC_INFO:
+ if (lib.JxlDecoderGetBasicInfo(decoder, &info) != JXL_DEC_SUCCESS) {
+ IMG_SetError("Couldn't get JXL image info");
+ goto done;
+ }
+ break;
+ case JXL_DEC_NEED_IMAGE_OUT_BUFFER:
+ if (lib.JxlDecoderImageOutBufferSize(decoder, &format, &outputsize) != JXL_DEC_SUCCESS) {
+ IMG_SetError("Couldn't get JXL image size");
+ goto done;
+ }
+ if (info.xsize == 0 || info.ysize == 0) {
+ IMG_SetError("Couldn't get pixels for %dx%d JXL image", info.xsize, info.ysize);
+ goto done;
+ }
+ if (pixels) {
+ SDL_free(pixels);
+ }
+ pixels = SDL_malloc(outputsize);
+ if (!pixels) {
+ SDL_OutOfMemory();
+ goto done;
+ }
+ pitch = outputsize / info.ysize;
+ if (lib.JxlDecoderSetImageOutBuffer(decoder, &format, pixels, outputsize) != JXL_DEC_SUCCESS) {
+ IMG_SetError("Couldn't set JXL output buffer");
+ goto done;
+ }
+ break;
+ case JXL_DEC_FULL_IMAGE:
+ /* We have a full image - in the case of an animation, keep decoding until the last frame */
+ break;
+ case JXL_DEC_SUCCESS:
+ /* All done! */
+ surface = SDL_CreateRGBSurfaceWithFormatFrom(pixels, info.xsize, info.ysize, 0, pitch, SDL_PIXELFORMAT_RGBA32);
+ goto done;
+ default:
+ IMG_SetError("Unknown JXL decoding status: %d", status);
+ goto done;
+ }
+ }
+
+done:
+ if (decoder) {
+ lib.JxlDecoderDestroy(decoder);
+ }
+ if (data) {
+ SDL_free(data);
+ }
+ if (pixels) {
+ SDL_free(pixels);
+ }
+ if (!surface) {
+ SDL_RWseek(src, start, RW_SEEK_SET);
+ }
+ return surface;
+}
+
+#else
+#if _MSC_VER >= 1300
+#pragma warning(disable : 4100) /* warning C4100: 'op' : unreferenced formal parameter */
+#endif
+
+int IMG_InitJXL()
+{
+ IMG_SetError("JXL images are not supported");
+ return(-1);
+}
+
+void IMG_QuitJXL()
+{
+}
+
+/* See if an image is contained in a data source */
+int IMG_isJXL(SDL_RWops *src)
+{
+ return(0);
+}
+
+/* Load a JXL type image from an SDL datasource */
+SDL_Surface *IMG_LoadJXL_RW(SDL_RWops *src)
+{
+ return(NULL);
+}
+
+#endif /* LOAD_JXL */
diff --git a/Makefile.am b/Makefile.am
index c57491a4..77a61a27 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,6 +16,7 @@ libSDL2_image_la_SOURCES = \
IMG_bmp.c \
IMG_gif.c \
IMG_jpg.c \
+ IMG_jxl.c \
IMG_lbm.c \
IMG_pcx.c \
IMG_png.c \
diff --git a/Makefile.in b/Makefile.in
index 90d20a7f..57b42f54 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -146,15 +146,15 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(pkgconfigdir)" \
LTLIBRARIES = $(lib_LTLIBRARIES)
am__DEPENDENCIES_1 =
am__libSDL2_image_la_SOURCES_DIST = IMG.c IMG_bmp.c IMG_gif.c \
- IMG_jpg.c IMG_lbm.c IMG_pcx.c IMG_png.c IMG_pnm.c IMG_qoi.c \
- IMG_svg.c IMG_tga.c IMG_tif.c IMG_xcf.c IMG_xpm.c IMG_xv.c \
- IMG_webp.c IMG_WIC.c IMG_ImageIO.m miniz.h nanosvg.h \
+ IMG_jpg.c IMG_jxl.c IMG_lbm.c IMG_pcx.c IMG_png.c IMG_pnm.c \
+ IMG_qoi.c IMG_svg.c IMG_tga.c IMG_tif.c IMG_xcf.c IMG_xpm.c \
+ IMG_xv.c IMG_webp.c IMG_WIC.c IMG_ImageIO.m miniz.h nanosvg.h \
nanosvgrast.h qoi.h
@USE_IMAGEIO_TRUE@am__objects_1 = IMG_ImageIO.lo
am_libSDL2_image_la_OBJECTS = IMG.lo IMG_bmp.lo IMG_gif.lo IMG_jpg.lo \
- IMG_lbm.lo IMG_pcx.lo IMG_png.lo IMG_pnm.lo IMG_qoi.lo \
- IMG_svg.lo IMG_tga.lo IMG_tif.lo IMG_xcf.lo IMG_xpm.lo \
- IMG_xv.lo IMG_webp.lo IMG_WIC.lo $(am__objects_1)
+ IMG_jxl.lo IMG_lbm.lo IMG_pcx.lo IMG_png.lo IMG_pnm.lo \
+ IMG_qoi.lo IMG_svg.lo IMG_tga.lo IMG_tif.lo IMG_xcf.lo \
+ IMG_xpm.lo IMG_xv.lo IMG_webp.lo IMG_WIC.lo $(am__objects_1)
libSDL2_image_la_OBJECTS = $(am_libSDL2_image_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -187,13 +187,14 @@ am__maybe_remake_depfiles = depfiles
am__depfiles_remade = ./$(DEPDIR)/IMG.Plo ./$(DEPDIR)/IMG_ImageIO.Plo \
./$(DEPDIR)/IMG_WIC.Plo ./$(DEPDIR)/IMG_bmp.Plo \
./$(DEPDIR)/IMG_gif.Plo ./$(DEPDIR)/IMG_jpg.Plo \
- ./$(DEPDIR)/IMG_lbm.Plo ./$(DEPDIR)/IMG_pcx.Plo \
- ./$(DEPDIR)/IMG_png.Plo ./$(DEPDIR)/IMG_pnm.Plo \
- ./$(DEPDIR)/IMG_qoi.Plo ./$(DEPDIR)/IMG_svg.Plo \
- ./$(DEPDIR)/IMG_tga.Plo ./$(DEPDIR)/IMG_tif.Plo \
- ./$(DEPDIR)/IMG_webp.Plo ./$(DEPDIR)/IMG_xcf.Plo \
- ./$(DEPDIR)/IMG_xpm.Plo ./$(DEPDIR)/IMG_xv.Plo \
- ./$(DEPDIR)/showanim.Po ./$(DEPDIR)/showimage.Po
+ ./$(DEPDIR)/IMG_jxl.Plo ./$(DEPDIR)/IMG_lbm.Plo \
+ ./$(DEPDIR)/IMG_pcx.Plo ./$(DEPDIR)/IMG_png.Plo \
+ ./$(DEPDIR)/IMG_pnm.Plo ./$(DEPDIR)/IMG_qoi.Plo \
+ ./$(DEPDIR)/IMG_svg.Plo ./$(DEPDIR)/IMG_tga.Plo \
+ ./$(DEPDIR)/IMG_tif.Plo ./$(DEPDIR)/IMG_webp.Plo \
+ ./$(DEPDIR)/IMG_xcf.Plo ./$(DEPDIR)/IMG_xpm.Plo \
+ ./$(DEPDIR)/IMG_xv.Plo ./$(DEPDIR)/showanim.Po \
+ ./$(DEPDIR)/showimage.Po
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -321,6 +322,8 @@ LD = @LD@
LDFLAGS = @LDFLAGS@
LIBJPEG_CFLAGS = @LIBJPEG_CFLAGS@
LIBJPEG_LIBS = @LIBJPEG_LIBS@
+LIBJXL_CFLAGS = @LIBJXL_CFLAGS@
+LIBJXL_LIBS = @LIBJXL_LIBS@
LIBOBJS = @LIBOBJS@
LIBPNG_CFLAGS = @LIBPNG_CFLAGS@
LIBPNG_LIBS = @LIBPNG_LIBS@
@@ -444,6 +447,7 @@ libSDL2_image_la_SOURCES = \
IMG_bmp.c \
IMG_gif.c \
IMG_jpg.c \
+ IMG_jxl.c \
IMG_lbm.c \
IMG_pcx.c \
IMG_png.c \
@@ -597,6 +601,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_bmp.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_gif.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_jpg.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_jxl.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_lbm.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_pcx.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IMG_png.Plo@am__quote@ # am--include-marker
@@ -994,6 +999,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/IMG_bmp.Plo
-rm -f ./$(DEPDIR)/IMG_gif.Plo
-rm -f ./$(DEPDIR)/IMG_jpg.Plo
+ -rm -f ./$(DEPDIR)/IMG_jxl.Plo
-rm -f ./$(DEPDIR)/IMG_lbm.Plo
-rm -f ./$(DEPDIR)/IMG_pcx.Plo
-rm -f ./$(DEPDIR)/IMG_png.Plo
@@ -1062,6 +1068,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/IMG_bmp.Plo
-rm -f ./$(DEPDIR)/IMG_gif.Plo
-rm -f ./$(DEPDIR)/IMG_jpg.Plo
+ -rm -f ./$(DEPDIR)/IMG_jxl.Plo
-rm -f ./$(DEPDIR)/IMG_lbm.Plo
-rm -f ./$(DEPDIR)/IMG_pcx.Plo
-rm -f ./$(DEPDIR)/IMG_png.Plo
diff --git a/SDL_image.h b/SDL_image.h
index 4af45d31..3834e27b 100644
--- a/SDL_image.h
+++ b/SDL_image.h
@@ -82,7 +82,8 @@ typedef enum
IMG_INIT_JPG = 0x00000001,
IMG_INIT_PNG = 0x00000002,
IMG_INIT_TIF = 0x00000004,
- IMG_INIT_WEBP = 0x00000008
+ IMG_INIT_WEBP = 0x00000008,
+ IMG_INIT_JXL = 0x00000010
} IMG_InitFlags;
/* Loads dynamic libraries and prepares them for use. Flags should be
@@ -121,6 +122,7 @@ extern DECLSPEC int SDLCALL IMG_isCUR(SDL_RWops *src);
extern DECLSPEC int SDLCALL IMG_isBMP(SDL_RWops *src);
extern DECLSPEC int SDLCALL IMG_isGIF(SDL_RWops *src);
extern DECLSPEC int SDLCALL IMG_isJPG(SDL_RWops *src);
+extern DECLSPEC int SDLCALL IMG_isJXL(SDL_RWops *src);
extern DECLSPEC int SDLCALL IMG_isLBM(SDL_RWops *src);
extern DECLSPEC int SDLCALL IMG_isPCX(SDL_RWops *src);
extern DECLSPEC int SDLCALL IMG_isPNG(SDL_RWops *src);
@@ -139,6 +141,7 @@ extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadCUR_RW(SDL_RWops *src);
extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadBMP_RW(SDL_RWops *src);
extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadGIF_RW(SDL_RWops *src);
extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadJPG_RW(SDL_RWops *src);
+extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadJXL_RW(SDL_RWops *src);
extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadLBM_RW(SDL_RWops *src);
extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPCX_RW(SDL_RWops *src);
extern DECLSPEC SDL_Surface * SDLCALL IMG_LoadPNG_RW(SDL_RWops *src);
diff --git a/configure b/configure
index 68e9800b..32a85438 100755
--- a/configure
+++ b/configure
@@ -784,6 +784,8 @@ LIBTIFF_LIBS
LIBTIFF_CFLAGS
LIBPNG_LIBS
LIBPNG_CFLAGS
+LIBJXL_LIBS
+LIBJXL_CFLAGS
LIBJPEG_LIBS
LIBJPEG_CFLAGS
SDL2_CONFIG
@@ -943,6 +945,8 @@ enable_bmp
enable_gif
enable_jpg
enable_jpg_shared
+enable_jxl
+enable_jxl_shared
enable_lbm
enable_pcx
enable_png
@@ -981,6 +985,8 @@ SDL_CFLAGS
SDL_LIBS
LIBJPEG_CFLAGS
LIBJPEG_LIBS
+LIBJXL_CFLAGS
+LIBJXL_LIBS
LIBPNG_CFLAGS
LIBPNG_LIBS
LIBTIFF_CFLAGS
@@ -1622,6 +1628,8 @@ Optional Features:
--enable-gif support loading GIF images [default=yes]
--enable-jpg support loading JPG images [default=yes]
--enable-jpg-shared dynamically load JPG support [default=yes]
+ --enable-jxl support loading JXL images [default=yes]
+ --enable-jxl-shared dynamically load JXL support [default=yes]
--enable-lbm support loading LBM images [default=yes]
--enable-pcx support loading PCX images [default=yes]
--enable-png support loading PNG images [default=yes]
@@ -1672,6 +1680,9 @@ Some influential environment variables:
C compiler flags for LIBJPEG, overriding pkg-config
LIBJPEG_LIBS
linker flags for LIBJPEG, overriding pkg-config
+ LIBJXL_CFLAGS
+ C compiler flags for LIBJXL, overriding pkg-config
+ LIBJXL_LIBS linker flags for LIBJXL, overriding pkg-config
LIBPNG_CFLAGS
C compiler flags for LIBPNG, overriding pkg-config
LIBPNG_LIBS linker flags for LIBPNG, overriding pkg-config
@@ -4085,13 +4096,13 @@ if ${lt_cv_nm_interface+:} false; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:4088: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:4099: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:4091: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:4102: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:4094: output\"" >&5)
+ (eval echo "\"\$as_me:4105: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5305,7 +5316,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5308 "configure"' > conftest.$ac_ext
+ echo '#line 5319 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7130,11 +7141,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7133: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7144: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7137: \$? = $ac_status" >&5
+ echo "$as_me:7148: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7479,11 +7490,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7482: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7493: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7486: \$? = $ac_status" >&5
+ echo "$as_me:7497: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7584,11 +7595,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7587: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7598: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7591: \$? = $ac_status" >&5
+ echo "$as_me:7602: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7639,11 +7650,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7642: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7653: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7646: \$? = $ac_status" >&5
+ echo "$as_me:7657: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -10074,7 +10085,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10077 "configure"
+#line 10088 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10170,7 +10181,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10173 "configure"
+#line 10184 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12800,6 +12811,20 @@ else
enable_jpg_shared=yes
fi
+# Check whether --enable-jxl was given.
+if test "${enable_jxl+set}" = set; then :
+ enableval=$enable_jxl;
+else
+ enable_jxl=yes
+fi
+
+# Check whether --enable-jxl-shared was given.
+if test "${enable_jxl_shared+set}" = set; then :
+ enableval=$enable_jxl_shared;
+else
+ enable_jxl_shared=yes
+fi
+
# Check whether --enable-lbm was given.
if test "${enable_lbm+set}" = set; then :
enableval=$enable_lbm;
@@ -13444,6 +13469,213 @@ $as_echo "$as_me: WARNING: JPG image loading disabled" >&2;}
fi
fi
+if test x$enable_jxl = xyes; then
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libjxl" >&5
+$as_echo_n "checking for libjxl... " >&6; }
+
+if test -n "$LIBJXL_CFLAGS"; then
+ pkg_cv_LIBJXL_CFLAGS="$LIBJXL_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libjxl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libjxl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBJXL_CFLAGS=`$PKG_CONFIG --cflags "libjxl" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$LIBJXL_LIBS"; then
+ pkg_cv_LIBJXL_LIBS="$LIBJXL_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libjxl\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libjxl") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_LIBJXL_LIBS=`$PKG_CONFIG --libs "libjxl" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ LIBJXL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libjxl" 2>&1`
+ else
+ LIBJXL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libjxl" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$LIBJXL_PKG_ERRORS" >&5
+
+ ac_fn_c_check_header_mongrel "$LINENO" "jxl/decode.h" "ac_cv_header_jxl_decode_h" "$ac_includes_default"
+if test "x$ac_cv_header_jxl_decode_h" = xyes; then :
+
+ have_jxl_hdr=yes
+ LIBJXL_CFLAGS=""
+
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JxlSignatureCheck in -ljxl" >&5
+$as_echo_n "checking for JxlSignatureCheck in -ljxl... " >&6; }
+if ${ac_cv_lib_jxl_JxlSignatureCheck+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljxl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char JxlSignatureCheck ();
+int
+main ()
+{
+return JxlSignatureCheck ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jxl_JxlSignatureCheck=yes
+else
+ ac_cv_lib_jxl_JxlSignatureCheck=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jxl_JxlSignatureCheck" >&5
+$as_echo "$ac_cv_lib_jxl_JxlSignatureCheck" >&6; }
+if test "x$ac_cv_lib_jxl_JxlSignatureCheck" = xyes; then :
+
+ have_jxl_lib=yes
+ LIBJXL_LIBS="-ljxl"
+
+fi
+
+
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ac_fn_c_check_header_mongrel "$LINENO" "jxl/decode.h" "ac_cv_header_jxl_decode_h" "$ac_includes_default"
+if test "x$ac_cv_header_jxl_decode_h" = xyes; then :
+
+ have_jxl_hdr=yes
+ LIBJXL_CFLAGS=""
+
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JxlSignatureCheck in -ljxl" >&5
+$as_echo_n "checking for JxlSignatureCheck in -ljxl... " >&6; }
+if ${ac_cv_lib_jxl_JxlSignatureCheck+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ljxl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char JxlSignatureCheck ();
+int
+main ()
+{
+return JxlSignatureCheck ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_jxl_JxlSignatureCheck=yes
+else
+ ac_cv_lib_jxl_JxlSignatureCheck=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_jxl_JxlSignatureCheck" >&5
+$as_echo "$ac_cv_lib_jxl_JxlSignatureCheck" >&6; }
+if test "x$ac_cv_lib_jxl_JxlSignatureCheck" = xyes; then :
+
+ have_jxl_lib=yes
+ LIBJXL_LIBS="-ljxl"
+
+fi
+
+
+else
+ LIBJXL_CFLAGS=$pkg_cv_LIBJXL_CFLAGS
+ LIBJXL_LIBS=$pkg_cv_LIBJXL_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ have_jxl_hdr=yes
+ have_jxl_lib=yes
+ have_jxl_pc=yes
+
+fi
+ if test x$have_jxl_hdr = xyes -a x$have_jxl_lib = xyes; then
+ if test x$enable_jxl = xyes; then
+ $as_echo "#define LOAD_JXL 1" >>confdefs.h
+
+ fi
+
+ case "$host" in
+ *-*-darwin*)
+ jxl_lib=`find_lib libjxl.dylib`
+ ;;
+ *-*-cygwin* | *-*-mingw*)
+ jxl_lib=`find_lib "libjxl*.dll"`
+ ;;
+ *)
+ jxl_lib=`find_lib "libjxl[0-9]*.so.*"`
+ if test x$jxl_lib = x; then
+ jxl_lib=`find_lib "libjxl.so.*"`
+ fi
+ ;;
+ esac
+ elif test x$enable_jxl = xyes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Unable to find JXL library (https://jpegxl.info/)" >&5
+$as_echo "$as_me: WARNING: *** Unable to find JXL library (https://jpegxl.info/)" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: JXL image loading disabled" >&5
+$as_echo "$as_me: WARNING: JXL image loading disabled" >&2;}
+ fi
+fi
+
if test x$enable_png = xyes -a x$enable_imageio != xyes; then
pkg_failed=no
@@ -14179,6 +14411,23 @@ _ACEOF
fi
fi
fi
+if test x$enable_jxl = xyes -a x$have_jxl_hdr = xyes -a x$have_jxl_lib = xyes; then
+ CFLAGS="$LIBJXL_CFLAGS $CFLAGS"
+ if test x$enable_jxl_shared = xyes && test x$jxl_lib != x; then
+ echo "-- dynamic libjxl -> $jxl_lib"
+ cat >>confdefs.h <<_ACEOF
+#define LOAD_JXL_DYNAMIC "$jxl_lib"
+_ACEOF
+
+ else
+ IMG_LIBS="$LIBJXL_LIBS $IMG_LIBS"
+ if test x$have_jxl_pc = xyes; then
+ PC_REQUIRES="libjxl $PC_REQUIRES"
+ else
+ PC_LIBS="$LIBJXL_LIBS $PC_LIBS"
+ fi
+ fi
+fi
if test x$enable_png = xyes -a x$have_png_hdr = xyes -a x$have_png_lib = xyes; then
CFLAGS="$LIBPNG_CFLAGS $CFLAGS"
if test x$enable_png_shared = xyes && test x$png_lib != x; then
diff --git a/configure.ac b/configure.ac
index e37c543f..a2d25475 100644
--- a/configure.ac
+++ b/configure.ac
@@ -204,6 +204,10 @@ AC_ARG_ENABLE([jpg], [AS_HELP_STRING([--enable-jpg], [support loading JPG images
[], [enable_jpg=yes])
AC_ARG_ENABLE([jpg-shared], [AS_HELP_STRING([--enable-jpg-shared], [dynamically load JPG support [default=yes]])],
[], [enable_jpg_shared=yes])
+AC_ARG_ENABLE([jxl], [AS_HELP_STRING([--enable-jxl], [support loading JXL images [default=yes]])],
+ [], [enable_jxl=yes])
+AC_ARG_ENABLE([jxl-shared], [AS_HELP_STRING([--enable-jxl-shared], [dynamically load JXL support [default=yes]])],
+ [], [enable_jxl_shared=yes])
AC_ARG_ENABLE([lbm], [AS_HELP_STRING([--enable-lbm], [support loading LBM images [default=yes]])],
[], [enable_lbm=yes])
AC_ARG_ENABLE([pcx], [AS_HELP_ST
(Patch may be truncated, please check the link at the top of this post.)