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 42 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
14 changes: 13 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 Expand Up @@ -80,6 +81,7 @@ script:
local project_path="$1"
local sail_cmake_path="$2"
local build_type="$3"
local old_dir="$PWD"

echo
echo "External Windows Test '$project_path' '$build_type'"
Expand All @@ -93,13 +95,16 @@ script:

fail_on_error cmake -A x64 -DSAIL_DEV=ON -DCMAKE_PREFIX_PATH="$sail_cmake_path" ..
fail_on_error cmake --build . --config $build_type

cd "$old_dir"
}

test_external_unix()
{
local project_path="$1"
local build_type="$2"
local exe="$3"
local old_dir="$PWD"

echo
echo "External Unix Test '$project_path' '$build_type'"
Expand All @@ -114,6 +119,8 @@ script:
fail_on_error cmake -DSAIL_DEV=ON -DCMAKE_BUILD_TYPE="$build_type" ..
fail_on_error cmake --build .
fail_on_error "$exe"

cd "$old_dir"
}

build()
Expand Down Expand Up @@ -145,6 +152,8 @@ script:

test_external_windows "tests/external/link/c" "$CMAKE_INSTALL_PREFIX/lib/cmake" "$CMAKE_BUILD_TYPE"
test_external_windows "tests/external/link/c++" "$CMAKE_INSTALL_PREFIX/lib/cmake" "$CMAKE_BUILD_TYPE"

rm -rf "$CMAKE_INSTALL_PREFIX"
;;
osx | linux)
CMAKE_INSTALL_PREFIX="/usr/local"
Expand All @@ -160,11 +169,14 @@ script:

cd tests
fail_on_error ctest --verbose
cd -

fail_on_error "$CMAKE_INSTALL_PREFIX/bin/sail" --version

test_external_unix "tests/external/link/c" "$CMAKE_BUILD_TYPE" "./external-c-api-link"
test_external_unix "tests/external/link/c++" "$CMAKE_BUILD_TYPE" "./external-c++-api-link"

xargs sudo rm -v < install_manifest.txt
;;
esac
}
Expand Down
30 changes: 16 additions & 14 deletions cmake/sail_codec.cmake
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Intended to be included by every codec. Sets up necessary dependencies,
# installation targets, codec info.
#
# Creates SAIL_CODEC_TARGET variable with the created target name.
#
macro(sail_codec)
cmake_parse_arguments(SAIL_CODEC "" "NAME;ICON" "SOURCES;LINK;DEPENDENCY_COMPILE_OPTIONS;DEPENDENCY_INCLUDE_DIRS;DEPENDENCY_LIBS" ${ARGN})
cmake_parse_arguments(SAIL_CODEC "" "NAME;ICON" "SOURCES;LINK;DEPENDENCY_COMPILE_DEFINITIONS;DEPENDENCY_INCLUDE_DIRS;DEPENDENCY_LIBS" ${ARGN})

if (NOT SAIL_CODEC_NAME MATCHES "^[a-z0-9]+$")
message(FATAL_ERROR "Invalid codec name '${SAIL_CODEC_NAME}'. Only lower-case letters and numbers are allowed.")
Expand All @@ -12,33 +14,33 @@ macro(sail_codec)
# with libpng cmake configs (they also export a 'png' target)
# and possibly other libs in the future.
#
set(TARGET sail-codec-${SAIL_CODEC_NAME})
set(SAIL_CODEC_TARGET sail-codec-${SAIL_CODEC_NAME})

# Add a codec
#
if (SAIL_COMBINE_CODECS)
add_library(${TARGET} OBJECT ${SAIL_CODEC_SOURCES})
add_library(${SAIL_CODEC_TARGET} OBJECT ${SAIL_CODEC_SOURCES})
else()
add_library(${TARGET} MODULE ${SAIL_CODEC_SOURCES})
add_library(${SAIL_CODEC_TARGET} MODULE ${SAIL_CODEC_SOURCES})

sail_enable_asan(TARGET ${TARGET})
sail_enable_asan(TARGET ${SAIL_CODEC_TARGET})
endif()

# Disable a "lib" prefix on Unix
#
set_target_properties(${TARGET} PROPERTIES PREFIX "")
set_target_properties(${SAIL_CODEC_TARGET} PROPERTIES PREFIX "")

# Rename to 'sail-codec-png.dll'
#
set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME sail-codec-${SAIL_CODEC_NAME})
set_target_properties(${SAIL_CODEC_TARGET} PROPERTIES OUTPUT_NAME sail-codec-${SAIL_CODEC_NAME})

# Depend on sail-common
#
target_link_libraries(${TARGET} PRIVATE sail-common)
target_link_libraries(${SAIL_CODEC_TARGET} PRIVATE sail-common)

# Depend on user-defined targets
#
target_link_libraries(${TARGET} PRIVATE ${SAIL_CODEC_LINK})
target_link_libraries(${SAIL_CODEC_TARGET} PRIVATE ${SAIL_CODEC_LINK})

# This hack is needed for static builds where we have the following dependencies
# ("->" is "links to"):
Expand All @@ -57,16 +59,16 @@ macro(sail_codec)
get_target_property(TARGET_TYPE ${LINK_DEPENDENCY} TYPE)

if (TARGET_TYPE STREQUAL "OBJECT_LIBRARY")
target_sources(${TARGET} INTERFACE $<TARGET_OBJECTS:${LINK_DEPENDENCY}>)
target_sources(${SAIL_CODEC_TARGET} INTERFACE $<TARGET_OBJECTS:${LINK_DEPENDENCY}>)
endif()
endif()
endforeach()

# Link against the found libs
#
target_compile_options(${TARGET} PRIVATE ${SAIL_CODEC_DEPENDENCY_COMPILE_OPTIONS})
target_include_directories(${TARGET} PRIVATE ${SAIL_CODEC_DEPENDENCY_INCLUDE_DIRS})
target_link_libraries(${TARGET} PRIVATE ${SAIL_CODEC_DEPENDENCY_LIBS})
target_compile_definitions(${SAIL_CODEC_TARGET} PRIVATE ${SAIL_CODEC_DEPENDENCY_COMPILE_DEFINITIONS})
target_include_directories(${SAIL_CODEC_TARGET} PRIVATE ${SAIL_CODEC_DEPENDENCY_INCLUDE_DIRS})
target_link_libraries(${SAIL_CODEC_TARGET} PRIVATE ${SAIL_CODEC_DEPENDENCY_LIBS})

# Generate and copy .codec.info into the build dir
#
Expand All @@ -77,7 +79,7 @@ macro(sail_codec)
# Installation
#
if (NOT SAIL_COMBINE_CODECS)
install(TARGETS ${TARGET} DESTINATION "${CMAKE_INSTALL_LIBDIR}/sail/codecs")
install(TARGETS ${SAIL_CODEC_TARGET} DESTINATION "${CMAKE_INSTALL_LIBDIR}/sail/codecs")

install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sail-codec-${SAIL_CODEC_NAME}.codec.info"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/sail/codecs")
Expand Down
146 changes: 104 additions & 42 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,6 +125,41 @@
return SAIL_OK;
}

static void print_aligned_image_info(const struct sail_image *image) {

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);

if (image->meta_data_node != NULL) {
printf("Meta data :\n");

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;
const char *meta_data_str = NULL;

if (meta_data->key == SAIL_META_DATA_UNKNOWN) {
meta_data_str = meta_data->key_unknown;
} else {
meta_data_str = sail_meta_data_to_string(meta_data->key);
}

printf(" %-12s: ", meta_data_str);
sail_printf_variant(meta_data->value);
printf("\n");
}
}
}

static sail_status_t probe_impl(const char *path) {

SAIL_CHECK_PTR(path);
Expand All @@ -139,63 +172,86 @@

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

uint64_t elapsed_time = sail_now() - start_time;

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("Probe time : %lu ms.\n", (unsigned long)elapsed_time);

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;
const char *meta_data_str = NULL;
print_aligned_image_info(image);

if (meta_data->key == SAIL_META_DATA_UNKNOWN) {
meta_data_str = meta_data->key_unknown;
} else {
meta_data_str = sail_meta_data_to_string(meta_data->key);
}
sail_destroy_image(image);

printf("%-14s: ", meta_data_str);

switch (meta_data->value->type) {
case SAIL_VARIANT_TYPE_BOOL: printf("%s\n", sail_variant_to_bool(meta_data->value) ? "<set>" : "<unset>"); break;
case SAIL_VARIANT_TYPE_CHAR: printf("%d\n", sail_variant_to_char(meta_data->value)); break;
case SAIL_VARIANT_TYPE_UNSIGNED_CHAR: printf("%u\n", sail_variant_to_unsigned_char(meta_data->value)); break;
case SAIL_VARIANT_TYPE_SHORT: printf("%d\n", sail_variant_to_short(meta_data->value)); break;
case SAIL_VARIANT_TYPE_UNSIGNED_SHORT: printf("%u\n", sail_variant_to_unsigned_short(meta_data->value)); break;
case SAIL_VARIANT_TYPE_INT: printf("%d\n", sail_variant_to_int(meta_data->value)); break;
case SAIL_VARIANT_TYPE_UNSIGNED_INT: printf("%u\n", sail_variant_to_unsigned_int(meta_data->value)); break;
case SAIL_VARIANT_TYPE_LONG: printf("%ld\n", sail_variant_to_long(meta_data->value)); break;
case SAIL_VARIANT_TYPE_UNSIGNED_LONG: printf("%lu\n", sail_variant_to_unsigned_long(meta_data->value)); break;
case SAIL_VARIANT_TYPE_FLOAT: printf("%.1f\n", sail_variant_to_float(meta_data->value)); break;
case SAIL_VARIANT_TYPE_DOUBLE: printf("%.1f\n", sail_variant_to_double(meta_data->value)); break;
case SAIL_VARIANT_TYPE_STRING: printf("%s\n", sail_variant_to_string(meta_data->value)); break;
case SAIL_VARIANT_TYPE_DATA: printf("<binary data, length: %u byte(s)>\n", (unsigned)meta_data->value->size); break;
case SAIL_VARIANT_TYPE_INVALID: printf("<invalid value>\n"); break;
}
return SAIL_OK;
}

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

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

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

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 probe(int argc, char *argv[]) {
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(probe_impl(argv[2]));
SAIL_TRY(decode_impl(argv[2]));
Dismissed Show dismissed Hide dismissed

return SAIL_OK;
}
Expand Down Expand Up @@ -260,9 +316,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 +351,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
2 changes: 1 addition & 1 deletion extra
Submodule extra updated from 6385ed to 2773b2
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
Loading