Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/jxl #194

Merged
merged 61 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
a362daa
JXL: JPEG XL work start
HappySeaFox Sep 21, 2023
6032da9
JXL: Update icon
HappySeaFox Sep 21, 2023
849af44
JXL: JPEG XL work start
HappySeaFox Sep 21, 2023
aa37c4a
JXL: Update icon
HappySeaFox Sep 21, 2023
c5ed699
Merge branch 'feature/jxl' of https://github.com/smoked-herring/sail …
HappySeaFox Sep 25, 2023
5775cea
JPEGXL: Rename JXL codec name to JPEGXL
HappySeaFox Sep 25, 2023
9cffafb
SAIL: Update XCode to 14.2 in Travis
HappySeaFox Sep 25, 2023
15e4885
Merge remote-tracking branch 'origin/master' into feature/jxl
HappySeaFox Sep 25, 2023
3e2ace7
JPEGXL: WIP in decoding loop
HappySeaFox Sep 25, 2023
44b3c0f
JPEGXL: Cosmetic
HappySeaFox Oct 1, 2023
dbe4423
COMMON: Added more float formats
HappySeaFox Oct 1, 2023
e37ba70
SAIL: Added jpeg-xl in Travis on macOS
HappySeaFox Oct 6, 2023
b18ddb5
COMMON: Pixels layout clarification
HappySeaFox Oct 7, 2023
9c5c5aa
EXAMPLES: Remove extra print 'Success'
HappySeaFox Oct 7, 2023
dcfdd65
EXAMPLES: Added new command 'decode' to the sail app
HappySeaFox Oct 7, 2023
1295d9f
JPEGXL: Decode images and animations
HappySeaFox Oct 7, 2023
16933df
JPEGXL: Add jxl-static to find_library()
HappySeaFox Oct 7, 2023
52affa0
COMMON: Added sail_alloc_iccp_for_data()
HappySeaFox Oct 8, 2023
7271748
JPEGXL: Fetch ICCP
HappySeaFox Oct 8, 2023
e1563ad
JPEGXL: Test adding brotli and hwy dependencies
HappySeaFox Oct 8, 2023
ff08b5c
JPEGXL: Update version
HappySeaFox Oct 8, 2023
e22c37e
JPEGXL: Export hwy and brotli deps for clients
HappySeaFox Oct 8, 2023
923f6e0
JPEGXL: Update print format to use ()
HappySeaFox Oct 8, 2023
10b99b9
JPEGXL: Define JXL_STATIC_DEFINE for static builds
HappySeaFox Oct 8, 2023
10a2248
SAIL: Rename DEPENDENCY_COMPILE_OPTIONS to DEPENDENCY_COMPILE_DEFINIT…
HappySeaFox Oct 8, 2023
2683d4a
CODECS: Fix using SAIL_CODEC_TARGET
HappySeaFox Oct 8, 2023
f23b726
JPEGXL: Use DEPENDENCY_COMPILE_DEFINITIONS
HappySeaFox Oct 8, 2023
4d80ca9
JPEGXL: Added lcms2 dependency
HappySeaFox Oct 8, 2023
c2a65b8
SAIL: Added comment
HappySeaFox Oct 9, 2023
4fd1eba
SAIL: Added --verbose in Travis to debug the jpeg-xl linking issue
HappySeaFox Oct 9, 2023
4dd3b17
SAIL: Remove installed SAIL after testing in Travis
HappySeaFox Oct 9, 2023
b2680d5
SAIL: Remove --verbose in Travis
HappySeaFox Oct 9, 2023
34dda23
JPEGXL: Fix exporting SAIL_CODECS_FIND_DEPENDENCIES
HappySeaFox Oct 9, 2023
975dd13
JPEGXL: Support older libjxl API < 0.9.0
HappySeaFox Oct 9, 2023
967cd72
JPEGXL: Remove lcms2 dependency
HappySeaFox Oct 9, 2023
1c93559
EXTRA: Added libjxl
HappySeaFox Oct 9, 2023
991e86f
JPEGXL: Use progressive decoding
HappySeaFox Oct 10, 2023
0e92715
Merge remote-tracking branch 'origin/master' into feature/jxl
HappySeaFox Oct 10, 2023
5f55547
COMMON: Fixed merge conflict
HappySeaFox Oct 11, 2023
845ebc0
JPEGXL: Fetch frame name
HappySeaFox Oct 11, 2023
504db04
EXAMPLES: Simplify binary data printf
HappySeaFox Oct 11, 2023
2d8e20d
COMMON: Added variant printf functions
HappySeaFox Oct 11, 2023
260bc9d
EXAMPLES: Print special properties
HappySeaFox Oct 11, 2023
1f5a6ac
JPEGXL: Export special properties
HappySeaFox Oct 11, 2023
837065b
JPEGXL: All images in animations now have source image set
HappySeaFox Oct 11, 2023
4bc9f63
EXAMPLES: Print extra space in special properties before :
HappySeaFox Oct 11, 2023
a207045
JPEGXL: Set read buffer size from 10 Kb to 8192
HappySeaFox Oct 11, 2023
bc5df3d
JPEGXL: Move unnecessary lines to fill out source image
HappySeaFox Oct 11, 2023
b409a06
EXAMPLES: Don't use probe() to fetch codec info
HappySeaFox Oct 11, 2023
7d1ecb7
JPEGXL: Fetch meta data
HappySeaFox Oct 12, 2023
5d2b872
COMMON: Added SAIL_META_DATA_JUMBF
HappySeaFox Oct 12, 2023
75835d6
JPEGXL: Support JUMBF meta data
HappySeaFox Oct 12, 2023
257b9a9
JPEGXL: Support CMYK source pixel format
HappySeaFox Oct 13, 2023
36adb58
JPEGXL: Added jpegxl-exponent-bits-per-sample special property
HappySeaFox Oct 13, 2023
6fb2f24
DOC: Added JPEG-XL to FORMATS
HappySeaFox Oct 13, 2023
b8648de
DOC: Added JPEG-XL to README
HappySeaFox Oct 13, 2023
f599208
DOC: Rename JPEG-XL to JPEG XL
HappySeaFox Oct 13, 2023
4a8db7a
TESTS: Added JPEGXL test image
HappySeaFox Oct 13, 2023
4e2e8e2
COMMON: Added CMYKA pixel format
HappySeaFox Oct 13, 2023
e187352
JPEGXL: Added support of CMYKA input
HappySeaFox Oct 13, 2023
61ac677
COMMON: Revert "COMMON: Added more float formats"
HappySeaFox Oct 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ addons:
- giflib
- jasper
- jpeg-turbo
- jpeg-xl
- libavif
- libpng
- libtiff
Expand Down Expand Up @@ -38,7 +39,7 @@ jobs:
dist: jammy
name: "Ubuntu 22.04 Jammy"
- os: osx
osx_image: xcode14.1
osx_image: xcode14.2
name: "macOS 12.6"
env:
- CMAKE_PREFIX_PATH="/usr/local/opt/jpeg-turbo;$CMAKE_PREFIX_PATH"
Expand Down
111 changes: 92 additions & 19 deletions examples/c/sail/sail.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@

sail_destroy_image(image);

SAIL_LOG_INFO("\n*** Success ***\n");

return SAIL_OK;
}

Expand Down Expand Up @@ -127,31 +125,20 @@
return SAIL_OK;
}

static sail_status_t probe_impl(const char *path) {

SAIL_CHECK_PTR(path);

/* Time counter. */
uint64_t start_time = sail_now();

struct sail_image *image;
const struct sail_codec_info *codec_info;

SAIL_TRY(sail_probe_file(path, &image, &codec_info));
static void print_aligned_image_info(const struct sail_image *image) {

printf("File : %s\n", path);
printf("Probe time : %lu ms.\n", (unsigned long)(sail_now() - start_time));
printf("Codec : %s [%s]\n", codec_info->name, codec_info->description);
printf("Codec version : %s\n", codec_info->version);
printf("Size : %ux%u\n", image->width, image->height);

if (image->resolution == NULL) {
printf("Resolution: : -\n");
} else {
printf("Resolution: : %.1fx%.1f\n", image->resolution->x, image->resolution->y);
}

printf("Pixel format : %s\n", sail_pixel_format_to_string(image->source_image->pixel_format));
printf("ICC profile : %s\n", image->iccp == NULL ? "no" : "yes");
printf("Interlaced : %s\n", image->source_image->interlaced ? "yes" : "no");
printf("Delay : %d ms.\n", image->delay);

for (const struct sail_meta_data_node *meta_data_node = image->meta_data_node; meta_data_node != NULL; meta_data_node = meta_data_node->next) {
const struct sail_meta_data *meta_data = meta_data_node->meta_data;
Expand Down Expand Up @@ -182,6 +169,28 @@
case SAIL_VARIANT_TYPE_INVALID: printf("<invalid value>\n"); break;
}
}
}

static sail_status_t probe_impl(const char *path) {

SAIL_CHECK_PTR(path);

/* Time counter. */
uint64_t start_time = sail_now();

struct sail_image *image;
const struct sail_codec_info *codec_info;

SAIL_TRY(sail_probe_file(path, &image, &codec_info));

uint64_t elapsed_time = sail_now() - start_time;

printf("File : %s\n", path);
printf("Codec : %s [%s]\n", codec_info->name, codec_info->description);
printf("Codec version : %s\n", codec_info->version);
printf("Probe time : %lu ms.\n", (unsigned long)elapsed_time);

print_aligned_image_info(image);

sail_destroy_image(image);

Expand All @@ -200,6 +209,64 @@
return SAIL_OK;
}

static sail_status_t decode_impl(const char *path) {

SAIL_CHECK_PTR(path);

struct sail_image *image;
const struct sail_codec_info *codec_info;

SAIL_TRY(sail_probe_file(path, &image, &codec_info));

printf("File : %s\n", path);
printf("Codec : %s [%s]\n", codec_info->name, codec_info->description);
printf("Codec version : %s\n", codec_info->version);

sail_destroy_image(image);

/* Time counter. */
uint64_t start_time = sail_now();

/* Decode. */
void *state;
SAIL_TRY(sail_start_loading_from_file(path, codec_info, &state));

sail_status_t status;
unsigned frame = 0;

while ((status = sail_load_next_frame(state, &image)) == SAIL_OK) {
printf("Frame #%u\n", frame++);
print_aligned_image_info(image);
sail_destroy_image(image);
}

if (status != SAIL_ERROR_NO_MORE_FRAMES) {
sail_stop_loading(state);
fprintf(stderr, "Error: Decoder error %d.\n", status);
SAIL_LOG_AND_RETURN(SAIL_ERROR_BROKEN_IMAGE);
}

SAIL_TRY(sail_stop_loading(state));

uint64_t elapsed_time = sail_now() - start_time;

printf("Decode time : %lu ms.\n", (unsigned long)elapsed_time);

return SAIL_OK;
}

static sail_status_t decode(int argc, char *argv[]) {

if (argc != 3) {
print_invalid_argument();
SAIL_LOG_AND_RETURN(SAIL_ERROR_INVALID_ARGUMENT);
}

SAIL_TRY(decode_impl(argv[2]));
Dismissed Show dismissed Hide dismissed

return SAIL_OK;
}

static sail_status_t list_impl(bool verbose) {

const struct sail_codec_bundle_node *codec_bundle_node = sail_codec_bundle_list();
Expand Down Expand Up @@ -260,9 +327,13 @@
fprintf(stderr, " %s [-v | --version]\n", app);
fprintf(stderr, " %s [-h | --help]\n", app);
fprintf(stderr, "Commands:\n");
fprintf(stderr, " convert <INPUT PATH> <OUTPUT PATH> [-c | --compression <value>] - Convert one image format to another.\n");
fprintf(stderr, " list [-v] - List supported codecs.\n");
fprintf(stderr, " probe <PATH> - Retrieve image information.\n");
fprintf(stderr, "\n");
fprintf(stderr, " convert <INPUT PATH> <OUTPUT PATH> [-c | --compression <value>] - Convert one image format to another.\n");
fprintf(stderr, "\n");
fprintf(stderr, " probe <PATH> - Retrieve information of the very first image found in the file.\n");
fprintf(stderr, " In most cases probing doesn't decode the image data.\n");
fprintf(stderr, " decode <PATH> - Decode the whole file and print information of all its frames.\n");
}

int main(int argc, char *argv[]) {
Expand Down Expand Up @@ -291,6 +362,8 @@
SAIL_TRY(list(argc, argv));
} else if (strcmp(argv[1], "probe") == 0) {
SAIL_TRY(probe(argc, argv));
} else if (strcmp(argv[1], "decode") == 0) {
SAIL_TRY(decode(argc, argv));
} else {
print_invalid_argument();
SAIL_LOG_AND_RETURN(SAIL_ERROR_INVALID_ARGUMENT);
Expand Down
6 changes: 4 additions & 2 deletions src/bindings/c++/image-c++.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,15 +248,17 @@ class SAIL_EXPORT image
const sail::source_image& source_image() const;

/*
* Returns the editable pixel data if any.
* Returns the editable pixel data if any. The channels are interleaved per pixel.
* The pixels are organized row by row, left to right, top to bottom.
*
* LOAD: Set by SAIL to valid pixel data.
* SAVE: Must be set by a caller to valid pixel data.
*/
void* pixels();

/*
* Returns the constant pixel data if any.
* Returns the constant pixel data if any. The channels are interleaved per pixel.
* The pixels are organized row by row, left to right, top to bottom.
*
* LOAD: Set by SAIL to valid pixel data.
* SAVE: Must be set by a caller to valid pixel data.
Expand Down
6 changes: 4 additions & 2 deletions src/libsail-common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,12 @@ enum SailPixelFormat {
SAIL_PIXEL_FORMAT_BPP64_ABGR,

/*
* Float formats.
* 32-bit single-precision floating point formats.
*/
SAIL_PIXEL_FORMAT_BPP16_FLOAT,
SAIL_PIXEL_FORMAT_BPP32_FLOAT,
SAIL_PIXEL_FORMAT_BPP64_FLOAT,
SAIL_PIXEL_FORMAT_BPP96_FLOAT,
SAIL_PIXEL_FORMAT_BPP128_FLOAT,

/*
* CMYK formats.
Expand Down
8 changes: 6 additions & 2 deletions src/libsail-common/common_serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,10 @@ const char* sail_pixel_format_to_string(enum SailPixelFormat pixel_format) {
case SAIL_PIXEL_FORMAT_BPP64_ARGB: return "BPP64-ARGB";
case SAIL_PIXEL_FORMAT_BPP64_ABGR: return "BPP64-ABGR";

case SAIL_PIXEL_FORMAT_BPP16_FLOAT: return "BPP16-FLOAT";
case SAIL_PIXEL_FORMAT_BPP32_FLOAT: return "BPP32-FLOAT";
case SAIL_PIXEL_FORMAT_BPP64_FLOAT: return "BPP64-FLOAT";
case SAIL_PIXEL_FORMAT_BPP96_FLOAT: return "BPP96-FLOAT";
case SAIL_PIXEL_FORMAT_BPP128_FLOAT: return "BPP128-FLOAT";

case SAIL_PIXEL_FORMAT_BPP32_CMYK: return "BPP32-CMYK";
case SAIL_PIXEL_FORMAT_BPP64_CMYK: return "BPP64-CMYK";
Expand Down Expand Up @@ -208,8 +210,10 @@ enum SailPixelFormat sail_pixel_format_from_string(const char *str) {
case UINT64_C(8244605671673531226): return SAIL_PIXEL_FORMAT_BPP64_ARGB;
case UINT64_C(8244605671673513818): return SAIL_PIXEL_FORMAT_BPP64_ABGR;

case UINT64_C(13817569922789251633): return SAIL_PIXEL_FORMAT_BPP16_FLOAT;
case UINT64_C(13817570002860265711): return SAIL_PIXEL_FORMAT_BPP32_FLOAT;
case UINT64_C(13817570133298530580): return SAIL_PIXEL_FORMAT_BPP64_FLOAT;
case UINT64_C(13817570263736795449): return SAIL_PIXEL_FORMAT_BPP96_FLOAT;
case UINT64_C(13257949525762847397): return SAIL_PIXEL_FORMAT_BPP128_FLOAT;

case UINT64_C(8244605667720923565): return SAIL_PIXEL_FORMAT_BPP32_CMYK;
case UINT64_C(8244605671673598258): return SAIL_PIXEL_FORMAT_BPP64_CMYK;
Expand Down
3 changes: 2 additions & 1 deletion src/libsail-common/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ struct sail_source_image;
struct sail_image {

/*
* Image pixels.
* Image pixels. The channels are interleaved per pixel. The pixels are
* organized row by row, left to right, top to bottom.
*
* LOAD: Set by SAIL to an allocated array of pixels.
* SAVE: Must be set by a caller to an allocated array of pixels.
Expand Down
6 changes: 4 additions & 2 deletions src/libsail-common/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,10 @@ unsigned sail_bits_per_pixel(enum SailPixelFormat pixel_format) {
case SAIL_PIXEL_FORMAT_BPP64_ARGB:
case SAIL_PIXEL_FORMAT_BPP64_ABGR: return 64;

case SAIL_PIXEL_FORMAT_BPP16_FLOAT: return 16;
case SAIL_PIXEL_FORMAT_BPP32_FLOAT: return 32;
case SAIL_PIXEL_FORMAT_BPP32_FLOAT: return 32;
case SAIL_PIXEL_FORMAT_BPP64_FLOAT: return 64;
case SAIL_PIXEL_FORMAT_BPP96_FLOAT: return 96;
case SAIL_PIXEL_FORMAT_BPP128_FLOAT: return 128;

case SAIL_PIXEL_FORMAT_BPP32_CMYK: return 32;
case SAIL_PIXEL_FORMAT_BPP64_CMYK: return 64;
Expand Down
2 changes: 1 addition & 1 deletion src/sail-codecs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ add_subdirectory(common/bmp)

# List of codecs
#
set(CODECS avif bmp gif ico jpeg jpeg2000 pcx png psd qoi svg tga tiff wal webp xbm)
set(CODECS avif bmp gif ico jpeg jpeg2000 jpegxl pcx png psd qoi svg tga tiff wal webp xbm)

list(SORT CODECS)

Expand Down
28 changes: 28 additions & 0 deletions src/sail-codecs/jpegxl/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
find_library(JPEGXL_LIBRARY jxl ${SAIL_CODEC_JPEGXL_REQUIRED_OPTION})
find_library(JPEGXL_THREADS_LIBRARY jxl_threads ${SAIL_CODEC_JPEGXL_REQUIRED_OPTION})
find_path(JPEGXL_INCLUDE_DIRS jxl/decode.h ${SAIL_CODEC_JPEGXL_REQUIRED_OPTION})

if (NOT JPEGXL_LIBRARY OR NOT JPEGXL_THREADS_LIBRARY OR NOT JPEGXL_INCLUDE_DIRS)
return()
endif()

# This will add the following CMake rules to the CMake config for static builds so a client
# application links against the required dependencies:
#
# find_library(jxl_RELEASE_LIBRARY NAMES jxl)
# find_library(jxl_DEBUG_LIBRARY NAMES jxl)
# set_property(TARGET SAIL::sail-codecs APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<$<CONFIG:Release>:${jxl_RELEASE_LIBRARY}> $<$<CONFIG:Debug>:${jxl_DEBUG_LIBRARY}>)
# find_library(jxl_threads_RELEASE_LIBRARY NAMES jxl_threads)
# find_library(jxl_threads_DEBUG_LIBRARY NAMES jxl_threads)
# set_property(TARGET SAIL::sail-codecs APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<$<CONFIG:Release>:${jxl_threads_RELEASE_LIBRARY}> $<$<CONFIG:Debug>:${jxl_threads_DEBUG_LIBRARY}>)
#
set(SAIL_CODECS_FIND_DEPENDENCIES ${SAIL_CODECS_FIND_DEPENDENCIES} "find_library,jxl,jxl" PARENT_SCOPE)
set(SAIL_CODECS_FIND_DEPENDENCIES ${SAIL_CODECS_FIND_DEPENDENCIES} "find_library,jxl_threads,jxl_threads" PARENT_SCOPE)

# Common codec configuration
#
sail_codec(NAME jpegxl
SOURCES helpers.h helpers.c jpegxl.c memory.h memory.c
ICON jpegxl.png
DEPENDENCY_INCLUDE_DIRS ${JPEGXL_INCLUDE_DIRS}
DEPENDENCY_LIBS ${JPEGXL_LIBRARY} ${JPEGXL_THREADS_LIBRARY})
Loading