diff options
Diffstat (limited to 'examples/jxlinfo.c')
-rw-r--r-- | examples/jxlinfo.c | 317 |
1 files changed, 0 insertions, 317 deletions
diff --git a/examples/jxlinfo.c b/examples/jxlinfo.c deleted file mode 100644 index 5827974..0000000 --- a/examples/jxlinfo.c +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (c) the JPEG XL Project Authors. All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This example prints information from the main codestream header. - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "jxl/decode.h" - -int PrintBasicInfo(FILE* file) { - uint8_t* data = NULL; - size_t data_size = 0; - // In how large chunks to read from the file and try decoding the basic info. - const size_t chunk_size = 64; - - JxlDecoder* dec = JxlDecoderCreate(NULL); - if (!dec) { - fprintf(stderr, "JxlDecoderCreate failed\n"); - return 0; - } - - JxlDecoderSetKeepOrientation(dec, 1); - - if (JXL_DEC_SUCCESS != - JxlDecoderSubscribeEvents( - dec, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME)) { - fprintf(stderr, "JxlDecoderSubscribeEvents failed\n"); - JxlDecoderDestroy(dec); - return 0; - } - - JxlBasicInfo info; - int seen_basic_info = 0; - JxlFrameHeader frame_header; - - for (;;) { - // The first time, this will output JXL_DEC_NEED_MORE_INPUT because no - // input is set yet, this is ok since the input is set when handling this - // event. - JxlDecoderStatus status = JxlDecoderProcessInput(dec); - - if (status == JXL_DEC_ERROR) { - fprintf(stderr, "Decoder error\n"); - break; - } else if (status == JXL_DEC_NEED_MORE_INPUT) { - // The first time there is nothing to release and it returns 0, but that - // is ok. - size_t remaining = JxlDecoderReleaseInput(dec); - // move any remaining bytes to the front if necessary - if (remaining != 0) { - memmove(data, data + data_size - remaining, remaining); - } - // resize the buffer to append one more chunk of data - // TODO(lode): avoid unnecessary reallocations - data = (uint8_t*)realloc(data, remaining + chunk_size); - // append bytes read from the file behind the remaining bytes - size_t read_size = fread(data + remaining, 1, chunk_size, file); - if (read_size == 0 && feof(file)) { - fprintf(stderr, "Unexpected EOF\n"); - break; - } - data_size = remaining + read_size; - JxlDecoderSetInput(dec, data, data_size); - } else if (status == JXL_DEC_SUCCESS) { - // Finished all processing. - break; - } else if (status == JXL_DEC_BASIC_INFO) { - if (JXL_DEC_SUCCESS != JxlDecoderGetBasicInfo(dec, &info)) { - fprintf(stderr, "JxlDecoderGetBasicInfo failed\n"); - break; - } - - seen_basic_info = 1; - - printf("dimensions: %ux%u\n", info.xsize, info.ysize); - printf("have_container: %d\n", info.have_container); - printf("uses_original_profile: %d\n", info.uses_original_profile); - printf("bits_per_sample: %d\n", info.bits_per_sample); - if (info.exponent_bits_per_sample) - printf("float, with exponent_bits_per_sample: %d\n", - info.exponent_bits_per_sample); - if (info.intensity_target != 255.f || info.min_nits != 0.f || - info.relative_to_max_display != 0 || - info.relative_to_max_display != 0.f) { - printf("intensity_target: %f\n", info.intensity_target); - printf("min_nits: %f\n", info.min_nits); - printf("relative_to_max_display: %d\n", info.relative_to_max_display); - printf("linear_below: %f\n", info.linear_below); - } - printf("have_preview: %d\n", info.have_preview); - if (info.have_preview) { - printf("preview xsize: %u\n", info.preview.xsize); - printf("preview ysize: %u\n", info.preview.ysize); - } - printf("have_animation: %d\n", info.have_animation); - if (info.have_animation) { - printf("ticks per second (numerator / denominator): %u / %u\n", - info.animation.tps_numerator, info.animation.tps_denominator); - printf("num_loops: %u\n", info.animation.num_loops); - printf("have_timecodes: %d\n", info.animation.have_timecodes); - } - const char* const orientation_string[8] = { - "Normal", "Flipped horizontally", - "Upside down", "Flipped vertically", - "Transposed", "90 degrees clockwise", - "Anti-Transposed", "90 degrees counter-clockwise"}; - if (info.orientation > 0 && info.orientation < 9) { - printf("orientation: %d (%s)\n", info.orientation, - orientation_string[info.orientation - 1]); - } else { - fprintf(stderr, "Invalid orientation\n"); - } - printf("num_extra_channels: %d\n", info.num_extra_channels); - - const char* const ec_type_names[7] = {"Alpha", "Depth", - "Spot color", "Selection mask", - "K (of CMYK)", "CFA (Bayer data)", - "Thermal"}; - for (uint32_t i = 0; i < info.num_extra_channels; i++) { - JxlExtraChannelInfo extra; - if (JXL_DEC_SUCCESS != JxlDecoderGetExtraChannelInfo(dec, i, &extra)) { - fprintf(stderr, "JxlDecoderGetExtraChannelInfo failed\n"); - break; - } - printf("extra channel %u:\n", i); - printf(" type: %s\n", - (extra.type < 7 ? ec_type_names[extra.type] - : (extra.type == JXL_CHANNEL_OPTIONAL - ? "Unknown but can be ignored" - : "Unknown, please update your libjxl"))); - printf(" bits_per_sample: %u\n", extra.bits_per_sample); - if (extra.exponent_bits_per_sample > 0) { - printf(" float, with exponent_bits_per_sample: %u\n", - extra.exponent_bits_per_sample); - } - if (extra.dim_shift > 0) { - printf(" dim_shift: %u (upsampled %ux)\n", extra.dim_shift, - 1 << extra.dim_shift); - } - if (extra.name_length) { - char* name = malloc(extra.name_length + 1); - if (JXL_DEC_SUCCESS != JxlDecoderGetExtraChannelName( - dec, i, name, extra.name_length + 1)) { - fprintf(stderr, "JxlDecoderGetExtraChannelName failed\n"); - free(name); - break; - } - free(name); - printf(" name: %s\n", name); - } - if (extra.type == JXL_CHANNEL_ALPHA) - printf(" alpha_premultiplied: %d (%s)\n", extra.alpha_premultiplied, - extra.alpha_premultiplied ? "Premultiplied" - : "Non-premultiplied"); - if (extra.type == JXL_CHANNEL_SPOT_COLOR) { - printf(" spot_color: (%f, %f, %f) with opacity %f\n", - extra.spot_color[0], extra.spot_color[1], extra.spot_color[2], - extra.spot_color[3]); - } - if (extra.type == JXL_CHANNEL_CFA) - printf(" cfa_channel: %u\n", extra.cfa_channel); - } - } else if (status == JXL_DEC_COLOR_ENCODING) { - JxlPixelFormat format = {4, JXL_TYPE_FLOAT, JXL_LITTLE_ENDIAN, 0}; - printf("color profile:\n"); - - JxlColorEncoding color_encoding; - if (JXL_DEC_SUCCESS == - JxlDecoderGetColorAsEncodedProfile(dec, &format, - JXL_COLOR_PROFILE_TARGET_ORIGINAL, - &color_encoding)) { - printf(" format: JPEG XL encoded color profile\n"); - const char* const cs_string[4] = {"RGB color", "Grayscale", "XYB", - "Unknown"}; - const char* const wp_string[12] = {"", "D65", "Custom", "", "", "", - "", "", "", "", "E", "P3"}; - const char* const pr_string[12] = { - "", "sRGB", "Custom", "", "", "", "", "", "", "Rec.2100", "", "P3"}; - const char* const tf_string[19] = { - "", "709", "Unknown", "", "", "", "", "", "Linear", "", - "", "", "", "sRGB", "", "", "PQ", "DCI", "HLG"}; - const char* const ri_string[4] = {"Perceptual", "Relative", - "Saturation", "Absolute"}; - printf(" color_space: %d (%s)\n", color_encoding.color_space, - cs_string[color_encoding.color_space]); - printf(" white_point: %d (%s)\n", color_encoding.white_point, - wp_string[color_encoding.white_point]); - if (color_encoding.white_point == JXL_WHITE_POINT_CUSTOM) { - printf(" white_point XY: %f %f\n", color_encoding.white_point_xy[0], - color_encoding.white_point_xy[1]); - } - if (color_encoding.color_space == JXL_COLOR_SPACE_RGB || - color_encoding.color_space == JXL_COLOR_SPACE_UNKNOWN) { - printf(" primaries: %d (%s)\n", color_encoding.primaries, - pr_string[color_encoding.primaries]); - if (color_encoding.primaries == JXL_PRIMARIES_CUSTOM) { - printf(" red primaries XY: %f %f\n", - color_encoding.primaries_red_xy[0], - color_encoding.primaries_red_xy[1]); - printf(" green primaries XY: %f %f\n", - color_encoding.primaries_green_xy[0], - color_encoding.primaries_green_xy[1]); - printf(" blue primaries XY: %f %f\n", - color_encoding.primaries_blue_xy[0], - color_encoding.primaries_blue_xy[1]); - } - } - if (color_encoding.transfer_function == JXL_TRANSFER_FUNCTION_GAMMA) { - printf(" transfer_function: gamma: %f\n", color_encoding.gamma); - } else { - printf(" transfer_function: %d (%s)\n", - color_encoding.transfer_function, - tf_string[color_encoding.transfer_function]); - } - printf(" rendering_intent: %d (%s)\n", color_encoding.rendering_intent, - ri_string[color_encoding.rendering_intent]); - - } else { - // The profile is not in JPEG XL encoded form, get as ICC profile - // instead. - printf(" format: ICC profile\n"); - size_t profile_size; - if (JXL_DEC_SUCCESS != - JxlDecoderGetICCProfileSize(dec, &format, - JXL_COLOR_PROFILE_TARGET_ORIGINAL, - &profile_size)) { - fprintf(stderr, "JxlDecoderGetICCProfileSize failed\n"); - continue; - } - printf(" ICC profile size: %zu\n", profile_size); - if (profile_size < 132) { - fprintf(stderr, "ICC profile too small\n"); - continue; - } - uint8_t* profile = (uint8_t*)malloc(profile_size); - if (JXL_DEC_SUCCESS != - JxlDecoderGetColorAsICCProfile(dec, &format, - JXL_COLOR_PROFILE_TARGET_ORIGINAL, - profile, profile_size)) { - fprintf(stderr, "JxlDecoderGetColorAsICCProfile failed\n"); - free(profile); - continue; - } - printf(" CMM type: \"%.4s\"\n", profile + 4); - printf(" color space: \"%.4s\"\n", profile + 16); - printf(" rendering intent: %d\n", (int)profile[67]); - free(profile); - } - - } else if (status == JXL_DEC_FRAME) { - if (JXL_DEC_SUCCESS != JxlDecoderGetFrameHeader(dec, &frame_header)) { - fprintf(stderr, "JxlDecoderGetFrameHeader failed\n"); - break; - } - printf("frame:\n"); - if (frame_header.name_length) { - char* name = malloc(frame_header.name_length + 1); - if (JXL_DEC_SUCCESS != - JxlDecoderGetFrameName(dec, name, frame_header.name_length + 1)) { - fprintf(stderr, "JxlDecoderGetFrameName failed\n"); - free(name); - break; - } - free(name); - printf(" name: %s\n", name); - } - float ms = frame_header.duration * 1000.f * - info.animation.tps_denominator / info.animation.tps_numerator; - if (info.have_animation) { - printf(" Duration: %u ticks (%f ms)\n", frame_header.duration, ms); - if (info.animation.have_timecodes) { - printf(" Time code: %X\n", frame_header.timecode); - } - } - - // This is the last expected event, no need to read the rest of the file. - } else { - fprintf(stderr, "Unexpected decoder status\n"); - break; - } - } - - JxlDecoderDestroy(dec); - free(data); - - return seen_basic_info; -} - -int main(int argc, char* argv[]) { - if (argc != 2) { - fprintf(stderr, - "Usage: %s <jxl>\n" - "Where:\n" - " jxl = input JPEG XL image filename\n", - argv[0]); - return 1; - } - - const char* jxl_filename = argv[1]; - - FILE* file = fopen(jxl_filename, "rb"); - if (!file) { - fprintf(stderr, "Failed to read file %s\n", jxl_filename); - return 1; - } - - if (!PrintBasicInfo(file)) { - fprintf(stderr, "Couldn't print basic info\n"); - return 1; - } - - return 0; -} |