Skip to content
Snippets Groups Projects
Commit b540cd3e authored by Deucе's avatar Deucе :ok_hand_tone4:
Browse files

Add support for runtime-linking libjxl

This also supports static linking for OSs that don't have sane ways
of sharing libraries system-wide.
parent af5ec10b
No related branches found
No related tags found
No related merge requests found
Pipeline #7450 passed
...@@ -59,6 +59,12 @@ if(NOT WITHOUT_OOII) ...@@ -59,6 +59,12 @@ if(NOT WITHOUT_OOII)
list(APPEND SOURCE ooii.c ooii_bmenus.c ooii_cmenus.c ooii_logons.c ooii_sounds.c) list(APPEND SOURCE ooii.c ooii_bmenus.c ooii_cmenus.c ooii_logons.c ooii_sounds.c)
endif() endif()
if(NOT WITHOUT_JPEG_XL)
if (JPEG_XL_FOUND)
list(APPEND SOURCE libjxl.c)
endif()
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(APPEND SOURCE DarwinWrappers.m) list(APPEND SOURCE DarwinWrappers.m)
find_library(FOUNDATION_LIBRARY Foundation) find_library(FOUNDATION_LIBRARY Foundation)
......
#include "libjxl.h"
#include "xp_dl.h"
#ifdef WITH_JPEG_XL
struct jxlfuncs Jxl;
#ifdef WITH_STATIC_JXL
bool load_jxl_funcs(void)
{
Jxl.ColorEncodingSetToSRGB = JxlColorEncodingSetToSRGB;
Jxl.DecoderCloseInput = JxlDecoderCloseInput;
Jxl.DecoderCreate = JxlDecoderCreate;
Jxl.DecoderDestroy = JxlDecoderDestroy;
Jxl.DecoderGetBasicInfo = JxlDecoderGetBasicInfo;
Jxl.DecoderImageOutBufferSize = JxlDecoderImageOutBufferSize;
Jxl.DecoderProcessInput = JxlDecoderProcessInput;
Jxl.DecoderReleaseInput = JxlDecoderReleaseInput;
Jxl.DecoderSetImageOutBuffer = JxlDecoderSetImageOutBuffer;
Jxl.DecoderSetInput = JxlDecoderSetInput;
#ifdef WITH_JPEG_XL_THREADS
Jxl.DecoderSetParallelRunner = JxlDecoderSetParallelRunner;
#endif
Jxl.DecoderSetPreferredColorProfile = JxlDecoderSetPreferredColorProfile;
Jxl.DecoderSubscribeEvents = JxlDecoderSubscribeEvents;
#ifdef WITH_JPEG_XL_THREADS
Jxl.ResizableParallelRunner = JxlResizableParallelRunner;
Jxl.ResizableParallelRunnerCreate = JxlResizableParallelRunnerCreate;
Jxl.ResizableParallelRunnerDestroy = JxlResizableParallelRunnerDestroy;
Jxl.ResizableParallelRunnerSetThreads = JxlResizableParallelRunnerSetThreads;
Jxl.ResizableParallelRunnerSuggestThreads = JxlResizableParallelRunnerSuggestThreads;
#endif
if (Jxl.DecoderSetParallelRunner == NULL ||
Jxl.ResizableParallelRunner == NULL ||
Jxl.ResizableParallelRunnerCreate == NULL ||
Jxl.ResizableParallelRunnerDestroy == NULL ||
Jxl.ResizableParallelRunnerSetThreads == NULL ||
Jxl.ResizableParallelRunnerSuggestThreads == NULL)
Jxl.status = JXL_STATUS_NOTHREADS;
else
Jxl.status = JXL_STATUS_OK;
return true;
}
#else
bool load_jxl_funcs(void)
{
dll_handle jxl_dll;
const char *libnames[] = {"jxl", NULL};
if (Jxl.status == JXL_STATUS_OK)
return true;
if (Jxl.status == JXL_STATUS_NOTHREADS)
return true;
if (Jxl.status == JXL_STATUS_FAILED)
return false;
Jxl.status = JXL_STATUS_FAILED;
if ((jxl_dll = xp_dlopen(libnames, RTLD_LAZY | RTLD_GLOBAL, JPEGXL_MAJOR_VERSION)) == NULL)
return false;
if ((Jxl.ColorEncodingSetToSRGB = xp_dlsym(jxl_dll, JxlColorEncodingSetToSRGB)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderCloseInput = xp_dlsym(jxl_dll, JxlDecoderCloseInput)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderCreate = xp_dlsym(jxl_dll, JxlDecoderCreate)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderDestroy = xp_dlsym(jxl_dll, JxlDecoderDestroy)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderGetBasicInfo = xp_dlsym(jxl_dll, JxlDecoderGetBasicInfo)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderImageOutBufferSize = xp_dlsym(jxl_dll, JxlDecoderImageOutBufferSize)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderProcessInput = xp_dlsym(jxl_dll, JxlDecoderProcessInput)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderReleaseInput = xp_dlsym(jxl_dll, JxlDecoderReleaseInput)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderSetImageOutBuffer = xp_dlsym(jxl_dll, JxlDecoderSetImageOutBuffer)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderSetInput = xp_dlsym(jxl_dll, JxlDecoderSetInput)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
#ifdef WITH_JPEG_XL_THREADS
if ((Jxl.DecoderSetParallelRunner = xp_dlsym(jxl_dll, JxlDecoderSetParallelRunner)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
#endif
if ((Jxl.DecoderSetPreferredColorProfile = xp_dlsym(jxl_dll, JxlDecoderSetPreferredColorProfile)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
if ((Jxl.DecoderSubscribeEvents = xp_dlsym(jxl_dll, JxlDecoderSubscribeEvents)) == NULL) {
xp_dlclose(jxl_dll);
return false;
}
Jxl.status = JXL_STATUS_NOTHREADS;
#ifdef WITH_JPEG_XL_THREADS
dll_handle jxlt_dll;
const char *tlibnames[] = {"jxl_threads", NULL};
Jxl.status = JXL_STATUS_FAILED;
if ((jxlt_dll = xp_dlopen(tlibnames, RTLD_LAZY | RTLD_GLOBAL, JPEGXL_MAJOR_VERSION)) == NULL)
return true;
if ((Jxl.ResizableParallelRunner = xp_dlsym(jxlt_dll, JxlResizableParallelRunner)) == NULL) {
xp_dlclose(jxl_dll);
return true;
}
if ((Jxl.ResizableParallelRunnerCreate = xp_dlsym(jxlt_dll, JxlResizableParallelRunnerCreate)) == NULL) {
xp_dlclose(jxl_dll);
return true;
}
if ((Jxl.ResizableParallelRunnerDestroy = xp_dlsym(jxlt_dll, JxlResizableParallelRunnerDestroy)) == NULL) {
xp_dlclose(jxl_dll);
return true;
}
if ((Jxl.ResizableParallelRunnerSetThreads = xp_dlsym(jxlt_dll, JxlResizableParallelRunnerSetThreads)) == NULL) {
xp_dlclose(jxl_dll);
return true;
}
if ((Jxl.ResizableParallelRunnerSuggestThreads = xp_dlsym(jxlt_dll, JxlResizableParallelRunnerSuggestThreads)) == NULL) {
xp_dlclose(jxl_dll);
return true;
}
Jxl.status = JXL_STATUS_OK;
#endif
return true;
}
#endif
#endif
#ifndef JXLFUNCS_H
#define JXLFUNCS_H
#ifdef WITH_JPEG_XL
#include <stdbool.h>
#include <jxl/decode.h>
#include <jxl/encode.h>
#ifdef WITH_JPEG_XL_THREADS
#include <jxl/resizable_parallel_runner.h>
#endif
enum JxlStatus {
JXL_STATUS_UNINITIALIZED,
JXL_STATUS_FAILED,
JXL_STATUS_NOTHREADS,
JXL_STATUS_OK
};
struct jxlfuncs {
void (*ColorEncodingSetToSRGB)(JxlColorEncoding*, JXL_BOOL);
void (*DecoderCloseInput)(JxlDecoder*);
JxlDecoder *(*DecoderCreate)(const JxlMemoryManager*);
void (*DecoderDestroy)(JxlDecoder*);
JxlDecoderStatus (*DecoderGetBasicInfo)(const JxlDecoder*, JxlBasicInfo* info);
JxlDecoderStatus (*DecoderImageOutBufferSize)(const JxlDecoder*, const JxlPixelFormat*, size_t*);
JxlDecoderStatus (*DecoderProcessInput)(JxlDecoder*);
size_t (*DecoderReleaseInput)(JxlDecoder*);
JxlDecoderStatus (*DecoderSetImageOutBuffer)(JxlDecoder*, const JxlPixelFormat*, void*, size_t);
JxlDecoderStatus (*DecoderSetInput)(JxlDecoder*, const uint8_t*, size_t);
JxlDecoderStatus (*DecoderSetParallelRunner)(JxlDecoder*, JxlParallelRunner, void*);
JxlDecoderStatus (*DecoderSetPreferredColorProfile)(JxlDecoder*, const JxlColorEncoding*);
JxlDecoderStatus (*DecoderSubscribeEvents)(JxlDecoder*, int);
JxlParallelRetCode (*ResizableParallelRunner)(void*, void*, JxlParallelRunInit, JxlParallelRunFunction, uint32_t, uint32_t);
void *(*ResizableParallelRunnerCreate)(const JxlMemoryManager*);
void (*ResizableParallelRunnerDestroy)(void*);
void (*ResizableParallelRunnerSetThreads)(void*, size_t);
uint32_t (*ResizableParallelRunnerSuggestThreads)(uint64_t, uint64_t);
int status;
};
extern struct jxlfuncs Jxl;
bool load_jxl_funcs(void);
#endif
#endif
...@@ -44,11 +44,7 @@ ...@@ -44,11 +44,7 @@
#include "ripper.h" #include "ripper.h"
#ifdef WITH_JPEG_XL #ifdef WITH_JPEG_XL
#include <jxl/decode.h> #include "libjxl.h"
#include <jxl/encode.h>
#ifdef WITH_JPEG_XL_THREADS
#include <jxl/resizable_parallel_runner.h>
#endif
#include "xpmap.h" #include "xpmap.h"
#endif #endif
...@@ -95,7 +91,8 @@ static uint8_t pnm_gamma[256] = { ...@@ -95,7 +91,8 @@ static uint8_t pnm_gamma[256] = {
248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254,
254, 255, 255 254, 255, 255
}; };
uint8_t pnm_gamma_max = 255; static uint8_t pnm_gamma_max = 255;
static bool jxl_support = false;
void void
get_cterm_size(int *cols, int *rows, int ns) get_cterm_size(int *cols, int *rows, int ns)
...@@ -3109,58 +3106,62 @@ read_jxl(const char *fn) ...@@ -3109,58 +3106,62 @@ read_jxl(const char *fn)
.endianness = JXL_NATIVE_ENDIAN, .endianness = JXL_NATIVE_ENDIAN,
.align = 1 .align = 1
}; };
JxlColorEncodingSetToSRGB(&ce, JXL_FALSE); Jxl.ColorEncodingSetToSRGB(&ce, JXL_FALSE);
JxlDecoder *dec = JxlDecoderCreate(NULL); JxlDecoder *dec = Jxl.DecoderCreate(NULL);
if (dec == NULL) { if (dec == NULL) {
xpunmap(map); xpunmap(map);
return NULL; return NULL;
} }
#ifdef WITH_JPEG_XL_THREADS #ifdef WITH_JPEG_XL_THREADS
void *rpr = JxlResizableParallelRunnerCreate(NULL); void *rpr = NULL;
if (Jxl.status == JXL_STATUS_OK) {
rpr = Jxl.ResizableParallelRunnerCreate(NULL);
if (rpr) { if (rpr) {
if (JxlDecoderSetParallelRunner(dec, JxlResizableParallelRunner, rpr) != JXL_DEC_SUCCESS) { if (Jxl.DecoderSetParallelRunner(dec, Jxl.ResizableParallelRunner, rpr) != JXL_DEC_SUCCESS) {
JxlResizableParallelRunnerDestroy(rpr); Jxl.ResizableParallelRunnerDestroy(rpr);
rpr = NULL; rpr = NULL;
} }
} }
}
#endif #endif
if (JxlDecoderSetInput(dec, map->addr, map->size) != JXL_DEC_SUCCESS) { if (Jxl.DecoderSetInput(dec, map->addr, map->size) != JXL_DEC_SUCCESS) {
xpunmap(map); xpunmap(map);
JxlDecoderDestroy(dec); Jxl.DecoderDestroy(dec);
return NULL; return NULL;
} }
JxlDecoderCloseInput(dec); Jxl.DecoderCloseInput(dec);
if (JxlDecoderSubscribeEvents(dec, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) { if (Jxl.DecoderSubscribeEvents(dec, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FULL_IMAGE) != JXL_DEC_SUCCESS) {
xpunmap(map); xpunmap(map);
JxlDecoderDestroy(dec); Jxl.DecoderDestroy(dec);
return NULL; return NULL;
} }
for (bool done = false; !done;) { for (bool done = false; !done;) {
st = JxlDecoderProcessInput(dec); st = Jxl.DecoderProcessInput(dec);
switch(st) { switch(st) {
case JXL_DEC_ERROR: case JXL_DEC_ERROR:
done = true; done = true;
break; break;
case JXL_DEC_BASIC_INFO: case JXL_DEC_BASIC_INFO:
if (JxlDecoderGetBasicInfo(dec, &info) != JXL_DEC_SUCCESS) { if (Jxl.DecoderGetBasicInfo(dec, &info) != JXL_DEC_SUCCESS) {
done = true; done = true;
break; break;
} }
width = info.xsize; width = info.xsize;
height = info.ysize; height = info.ysize;
#ifdef WITH_JPEG_XL_THREADS #ifdef WITH_JPEG_XL_THREADS
JxlResizableParallelRunnerSetThreads(rpr, JxlResizableParallelRunnerSuggestThreads(info.xsize, info.ysize)); if (Jxl.status == JXL_STATUS_OK)
Jxl.ResizableParallelRunnerSetThreads(rpr, Jxl.ResizableParallelRunnerSuggestThreads(info.xsize, info.ysize));
#endif #endif
break; break;
case JXL_DEC_COLOR_ENCODING: case JXL_DEC_COLOR_ENCODING:
// TODO... // TODO...
if (JxlDecoderSetPreferredColorProfile(dec, &ce) != JXL_DEC_SUCCESS) { if (Jxl.DecoderSetPreferredColorProfile(dec, &ce) != JXL_DEC_SUCCESS) {
done = true; done = true;
break; break;
} }
break; break;
case JXL_DEC_NEED_IMAGE_OUT_BUFFER: case JXL_DEC_NEED_IMAGE_OUT_BUFFER:
if (JxlDecoderImageOutBufferSize(dec, &format, &sz) != JXL_DEC_SUCCESS) { if (Jxl.DecoderImageOutBufferSize(dec, &format, &sz) != JXL_DEC_SUCCESS) {
done = true; done = true;
break; break;
} }
...@@ -3174,7 +3175,7 @@ read_jxl(const char *fn) ...@@ -3174,7 +3175,7 @@ read_jxl(const char *fn)
done = true; done = true;
break; break;
} }
JxlDecoderSetImageOutBuffer(dec, &format, pbuf, sz); Jxl.DecoderSetImageOutBuffer(dec, &format, pbuf, sz);
break; break;
case JXL_DEC_FULL_IMAGE: case JXL_DEC_FULL_IMAGE:
// Got a single frame... this is not necessarily the whole image though. // Got a single frame... this is not necessarily the whole image though.
...@@ -3204,11 +3205,11 @@ read_jxl(const char *fn) ...@@ -3204,11 +3205,11 @@ read_jxl(const char *fn)
free(pbuf); free(pbuf);
#ifdef WITH_JPEG_XL_THREADS #ifdef WITH_JPEG_XL_THREADS
if (rpr) if (rpr)
JxlResizableParallelRunnerDestroy(rpr); Jxl.ResizableParallelRunnerDestroy(rpr);
#endif #endif
JxlDecoderReleaseInput(dec); Jxl.DecoderReleaseInput(dec);
xpunmap(map); xpunmap(map);
JxlDecoderDestroy(dec); Jxl.DecoderDestroy(dec);
return pret; return pret;
} }
...@@ -4150,6 +4151,9 @@ doterm(struct bbslist *bbs) ...@@ -4150,6 +4151,9 @@ doterm(struct bbslist *bbs)
#ifndef WITHOUT_OOII #ifndef WITHOUT_OOII
ooii_buf[0] = 0; ooii_buf[0] = 0;
#endif #endif
#ifdef WITH_JPEG_XL
jxl_support = load_jxl_funcs();
#endif
/* Main input loop */ /* Main input loop */
oldmc = hold_update; oldmc = hold_update;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment