J40: Independent, self-contained JPEG XL decoder
J40 (Jay-forty) is a decoder for ISO/IEC 18181 JPEG XL image format. It intends to be a fully compatible reimplementation to the reference implementation, libjxl, and also serves as a verification that the specification allows for an independent implementation besides from libjxl.
J40 is a single-file C99 library with zero dependencies, making it trivial to insert to your project and dependencies. It is also a public domain software and can be used for absolutely every purpose.
As of version 2270 (2022-09), J40 is a highly experimental software. Expect breakage, bug and incomplete format support. In order to discourage accidental uses, you need to define an additional macro for now.
Quick Start
The following is a simple but complete converter from JPEG XL to Portable Arbitrary Map format, and covers all the currently available API functions.
#define J40_IMPLEMENTATION // only a SINGLE file should have this #include "j40.h" // you also need to define a macro for experimental versions; follow the error. #include <stdio.h> #include <stdarg.h> // for va_* static int oops(const char *fmt, ...) { va_list args; va_start(args, fmt); vfprintf(stderr, fmt, args); va_end(args); return 1; } int main(int argc, char **argv) { if (argc < 3) return oops("Usage: %s input.jxl output.pam\n", argv[0]); FILE *out = fopen(argv[2], "wb"); if (!out) return oops("Error: Cannot open an output file.\n"); j40_image image; j40_from_file(&image, argv[1]); // or: j40_from_memory(&image, buf, bufsize, freefunc); j40_output_format(&image, J40_RGBA, J40_U8X4); // JPEG XL supports animation, so `j40_next_frame` calls can be called multiple times if (j40_next_frame(&image)) { j40_frame frame = j40_current_frame(&image); j40_pixels_u8x4 pixels = j40_frame_pixels_u8x4(&frame, J40_RGBA); fprintf(out, "P7\n" "WIDTH %d\n" "HEIGHT %d\n" "DEPTH 4\n" "MAXVAL 255\n" "TUPLTYPE RGB_ALPHA\n" "ENDHDR\n", pixels.width, pixels.height); for (int y = 0; y < height; ++y) { fwrite(j40_row_u8x4(pixels, y), 4, pixels.width, out); } } // J40 stops once the first error is encountered; its error can be checked at the very end if (j40_error(&image)) return oops("Error: %s\n", j40_error_string(&image)); if (ferror(out)) return oops("Error: Cannot fully write to the output file.\n"); j40_free(&image); // also frees all memory associated to j40_frame etc. fclose(out); return 0; }
Alternatively, you can use a dj40
executable to convert a JPEG XL file into a PNG file, which can be built as follows:
# if your system has make: $ make # otherwise, do the equivalent of: $ cc -O3 dj40.c -o dj40
Format Support
As of version 2270, J40 can decode:
- Any image encoded with fjxl, or
- Most images encoded with cjxl containing...
- No animations or previews
- No image features (
--dots
and--patches
), which implies:- Efforts (
-e
) up to 6 - For lossy compression, target distance (
-d
) less than 3.0
- Efforts (
- No progressive encoding (
-p
) - No lossless JPEG transcoding in use (can be disabled with
-j
) - No floating point samples
There are some known cases where J40 and libjxl can significantly diverge:
- Restoration filters (
--epf
,--gaborish
) are currently ignored. - Crop retangles are currently ignored and can reveal a frame larger than the actual image.
- ICC profiles are only decoded to the point that the actual image can be decoded.
from Hacker News https://ift.tt/DPl0Npd
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.