| /* -*- C++ -*- |
| * Copyright 2019-2025 LibRaw LLC (info@libraw.org) |
| * |
| |
| LibRaw is free software; you can redistribute it and/or modify |
| it under the terms of the one of two licenses as you choose: |
| |
| 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 |
| (See file LICENSE.LGPL provided in LibRaw distribution archive for details). |
| |
| 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 |
| (See file LICENSE.CDDL provided in LibRaw distribution archive for details). |
| */ |
| |
| /* Library for accessing X3F Files |
| ---------------------------------------------------------------- |
| BSD-style License |
| ---------------------------------------------------------------- |
| |
| * Copyright (c) 2010, Roland Karlsson (roland@proxel.se) |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * * Neither the name of the organization nor the |
| * names of its contributors may be used to endorse or promote products |
| * derived from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY ROLAND KARLSSON ''AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL ROLAND KARLSSON BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| */ |
| |
| #ifndef THIRD_PARTY_LIBRAW_INTERNAL_X3F_TOOLS_H_ |
| #define THIRD_PARTY_LIBRAW_INTERNAL_X3F_TOOLS_H_ |
| #define X3F_TOOLS_H THIRD_PARTY_LIBRAW_INTERNAL_X3F_TOOLS_H_ // upstream guard |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <math.h> |
| #include <stdio.h> |
| #include "third_party/libraw/libraw/libraw_datastream.h" |
| |
| /* From X3F_IO.H */ |
| |
| #define SIZE_UNIQUE_IDENTIFIER 16 |
| #define SIZE_WHITE_BALANCE 32 |
| #define SIZE_COLOR_MODE 32 |
| #define NUM_EXT_DATA_2_1 32 |
| #define NUM_EXT_DATA_3_0 64 |
| #define NUM_EXT_DATA NUM_EXT_DATA_3_0 |
| |
| #define X3F_VERSION(MAJ, MIN) (uint32_t)(((MAJ) << 16) + MIN) |
| #define X3F_VERSION_2_0 X3F_VERSION(2, 0) |
| #define X3F_VERSION_2_1 X3F_VERSION(2, 1) |
| #define X3F_VERSION_2_2 X3F_VERSION(2, 2) |
| #define X3F_VERSION_2_3 X3F_VERSION(2, 3) |
| #define X3F_VERSION_3_0 X3F_VERSION(3, 0) |
| #define X3F_VERSION_4_0 X3F_VERSION(4, 0) |
| |
| /* Main file identifier */ |
| #define X3F_FOVb (uint32_t)(0x62564f46) |
| /* Directory identifier */ |
| #define X3F_SECd (uint32_t)(0x64434553) |
| /* Property section identifiers */ |
| #define X3F_PROP (uint32_t)(0x504f5250) |
| #define X3F_SECp (uint32_t)(0x70434553) |
| /* Image section identifiers */ |
| #define X3F_IMAG (uint32_t)(0x46414d49) |
| #define X3F_IMA2 (uint32_t)(0x32414d49) |
| #define X3F_SECi (uint32_t)(0x69434553) |
| /* CAMF section identifiers */ |
| #define X3F_CAMF (uint32_t)(0x464d4143) |
| #define X3F_SECc (uint32_t)(0x63434553) |
| /* CAMF entry identifiers */ |
| #define X3F_CMbP (uint32_t)(0x50624d43) |
| #define X3F_CMbT (uint32_t)(0x54624d43) |
| #define X3F_CMbM (uint32_t)(0x4d624d43) |
| #define X3F_CMb (uint32_t)(0x00624d43) |
| /* SDQ section identifiers ? - TODO */ |
| #define X3F_SPPA (uint32_t)(0x41505053) |
| #define X3F_SECs (uint32_t)(0x73434553) |
| |
| #define X3F_IMAGE_THUMB_PLAIN (uint32_t)(0x00020003) |
| #define X3F_IMAGE_THUMB_HUFFMAN (uint32_t)(0x0002000b) |
| #define X3F_IMAGE_THUMB_JPEG (uint32_t)(0x00020012) |
| #define X3F_IMAGE_THUMB_SDQ (uint32_t)(0x00020019) /* SDQ ? - TODO */ |
| |
| #define X3F_IMAGE_RAW_HUFFMAN_X530 (uint32_t)(0x00030005) |
| #define X3F_IMAGE_RAW_HUFFMAN_10BIT (uint32_t)(0x00030006) |
| #define X3F_IMAGE_RAW_TRUE (uint32_t)(0x0003001e) |
| #define X3F_IMAGE_RAW_MERRILL (uint32_t)(0x0001001e) |
| #define X3F_IMAGE_RAW_QUATTRO (uint32_t)(0x00010023) |
| #define X3F_IMAGE_RAW_SDQ (uint32_t)(0x00010025) |
| #define X3F_IMAGE_RAW_SDQH (uint32_t)(0x00010027) |
| #define X3F_IMAGE_RAW_SDQH2 (uint32_t)(0x00010029) |
| |
| #define X3F_IMAGE_HEADER_SIZE 28 |
| #define X3F_CAMF_HEADER_SIZE 28 |
| #define X3F_PROPERTY_LIST_HEADER_SIZE 24 |
| |
| typedef uint16_t utf16_t; |
| |
| typedef int bool_t; |
| |
| typedef enum x3f_extended_types_e |
| { |
| X3F_EXT_TYPE_NONE = 0, |
| X3F_EXT_TYPE_EXPOSURE_ADJUST = 1, |
| X3F_EXT_TYPE_CONTRAST_ADJUST = 2, |
| X3F_EXT_TYPE_SHADOW_ADJUST = 3, |
| X3F_EXT_TYPE_HIGHLIGHT_ADJUST = 4, |
| X3F_EXT_TYPE_SATURATION_ADJUST = 5, |
| X3F_EXT_TYPE_SHARPNESS_ADJUST = 6, |
| X3F_EXT_TYPE_RED_ADJUST = 7, |
| X3F_EXT_TYPE_GREEN_ADJUST = 8, |
| X3F_EXT_TYPE_BLUE_ADJUST = 9, |
| X3F_EXT_TYPE_FILL_LIGHT_ADJUST = 10 |
| } x3f_extended_types_t; |
| |
| typedef struct x3f_property_s |
| { |
| /* Read from file */ |
| uint32_t name_offset; |
| uint32_t value_offset; |
| |
| /* Computed */ |
| utf16_t *name; /* 0x0000 terminated UTF 16 */ |
| utf16_t *value; /* 0x0000 terminated UTF 16 */ |
| } x3f_property_t; |
| |
| typedef struct x3f_property_table_s |
| { |
| uint32_t size; |
| x3f_property_t *element; |
| } x3f_property_table_t; |
| |
| typedef struct x3f_property_list_s |
| { |
| /* 2.0 Fields */ |
| uint32_t num_properties; |
| uint32_t character_format; |
| uint32_t reserved; |
| uint32_t total_length; |
| |
| x3f_property_table_t property_table; |
| |
| void *data; |
| |
| uint32_t data_size; |
| |
| } x3f_property_list_t; |
| |
| typedef struct x3f_table8_s |
| { |
| uint32_t size; |
| uint8_t *element; |
| } x3f_table8_t; |
| |
| typedef struct x3f_table16_s |
| { |
| uint32_t size; |
| uint16_t *element; |
| } x3f_table16_t; |
| |
| typedef struct x3f_table32_s |
| { |
| uint32_t size; |
| uint32_t *element; |
| } x3f_table32_t; |
| |
| typedef struct |
| { |
| uint8_t *data; /* Pointer to actual image data */ |
| void *buf; /* Pointer to allocated buffer for free() */ |
| uint32_t rows; |
| uint32_t columns; |
| uint32_t channels; |
| uint32_t row_stride; |
| } x3f_area8_t; |
| |
| typedef struct |
| { |
| uint16_t *data; /* Pointer to actual image data */ |
| void *buf; /* Pointer to allocated buffer for free() */ |
| uint32_t rows; |
| uint32_t columns; |
| uint32_t channels; |
| uint32_t row_stride; |
| } x3f_area16_t; |
| |
| #define UNDEFINED_LEAF 0xffffffff |
| |
| typedef struct x3f_huffnode_s |
| { |
| struct x3f_huffnode_s *branch[2]; |
| uint32_t leaf; |
| } x3f_huffnode_t; |
| |
| typedef struct x3f_hufftree_s |
| { |
| uint32_t free_node_index; /* Free node index in huffman tree array */ |
| uint32_t total_node_index; |
| x3f_huffnode_t *nodes; /* Coding tree */ |
| } x3f_hufftree_t; |
| |
| typedef struct x3f_true_huffman_element_s |
| { |
| uint8_t code_size; |
| uint8_t code; |
| } x3f_true_huffman_element_t; |
| |
| typedef struct x3f_true_huffman_s |
| { |
| uint32_t size; |
| x3f_true_huffman_element_t *element; |
| } x3f_true_huffman_t; |
| |
| /* 0=bottom, 1=middle, 2=top */ |
| #define TRUE_PLANES 3 |
| |
| typedef struct x3f_true_s |
| { |
| uint16_t seed[TRUE_PLANES]; /* Always 512,512,512 */ |
| uint16_t unknown; /* Always 0 */ |
| x3f_true_huffman_t table; /* Huffman table - zero |
| terminated. size is the number of |
| leaves plus 1.*/ |
| |
| x3f_table32_t plane_size; /* Size of the 3 planes */ |
| uint8_t *plane_address[TRUE_PLANES]; /* computed offset to the planes */ |
| x3f_hufftree_t tree; /* Coding tree */ |
| x3f_area16_t x3rgb16; /* 3x16 bit X3-RGB data */ |
| } x3f_true_t; |
| |
| typedef struct x3f_quattro_s |
| { |
| struct |
| { |
| uint16_t columns; |
| uint16_t rows; |
| } plane[TRUE_PLANES]; |
| uint32_t unknown; |
| |
| bool_t quattro_layout; |
| x3f_area16_t top16; /* Container for the bigger top layer */ |
| } x3f_quattro_t; |
| |
| typedef struct x3f_huffman_s |
| { |
| x3f_table16_t mapping; /* Value Mapping = X3F lossy compression */ |
| x3f_table32_t table; /* Coding Table */ |
| x3f_hufftree_t tree; /* Coding tree */ |
| x3f_table32_t row_offsets; /* Row offsets */ |
| x3f_area8_t rgb8; /* 3x8 bit RGB data */ |
| x3f_area16_t x3rgb16; /* 3x16 bit X3-RGB data */ |
| } x3f_huffman_t; |
| |
| typedef struct x3f_image_data_s |
| { |
| /* 2.0 Fields */ |
| /* ------------------------------------------------------------------ */ |
| /* Known combinations of type and format are: |
| 1-6, 2-3, 2-11, 2-18, 3-6 */ |
| uint32_t type; /* 1 = RAW X3 (SD1) |
| 2 = thumbnail or maybe just RGB |
| 3 = RAW X3 */ |
| uint32_t format; /* 3 = 3x8 bit pixmap |
| 6 = 3x10 bit huffman with map table |
| 11 = 3x8 bit huffman |
| 18 = JPEG */ |
| uint32_t type_format; /* type<<16 + format */ |
| /* ------------------------------------------------------------------ */ |
| |
| uint32_t columns; /* width / row size in pixels */ |
| uint32_t rows; /* height */ |
| uint32_t row_stride; /* row size in bytes */ |
| |
| /* NULL if not used */ |
| x3f_huffman_t *huffman; /* Huffman help data */ |
| x3f_true_t *tru; /* TRUE help data */ |
| x3f_quattro_t *quattro; /* Quattro help data */ |
| |
| void *data; /* Take from file if NULL. Otherwise, |
| this is the actual data bytes in |
| the file. */ |
| uint32_t data_size; |
| |
| } x3f_image_data_t; |
| |
| typedef struct camf_dim_entry_s |
| { |
| uint32_t size; |
| uint32_t name_offset; |
| uint32_t n; /* 0,1,2,3... */ |
| char *name; |
| } camf_dim_entry_t; |
| |
| typedef enum |
| { |
| M_FLOAT, |
| M_INT, |
| M_UINT |
| } matrix_type_t; |
| |
| typedef struct camf_entry_s |
| { |
| /* pointer into decoded data */ |
| void *entry; |
| |
| /* entry header */ |
| uint32_t id; |
| uint32_t version; |
| uint32_t entry_size; |
| uint32_t name_offset; |
| uint32_t value_offset; |
| |
| /* computed values */ |
| char *name_address; |
| void *value_address; |
| uint32_t name_size; |
| uint32_t value_size; |
| |
| /* extracted values for explicit CAMF entry types*/ |
| uint32_t text_size; |
| char *text; |
| |
| uint32_t property_num; |
| char **property_name; |
| uint8_t **property_value; |
| |
| uint32_t matrix_dim; |
| camf_dim_entry_t *matrix_dim_entry; |
| |
| /* Offset, pointer and size and type of raw data */ |
| uint32_t matrix_type; |
| uint32_t matrix_data_off; |
| void *matrix_data; |
| uint32_t matrix_element_size; |
| |
| /* Pointer and type of copied data */ |
| matrix_type_t matrix_decoded_type; |
| void *matrix_decoded; |
| |
| /* Help data to try to estimate element size */ |
| uint32_t matrix_elements; |
| uint32_t matrix_used_space; |
| double matrix_estimated_element_size; |
| |
| } camf_entry_t; |
| |
| typedef struct camf_entry_table_s |
| { |
| uint32_t size; |
| camf_entry_t *element; |
| } camf_entry_table_t; |
| |
| typedef struct x3f_camf_typeN_s |
| { |
| uint32_t val0; |
| uint32_t val1; |
| uint32_t val2; |
| uint32_t val3; |
| } x3f_camf_typeN_t; |
| |
| typedef struct x3f_camf_type2_s |
| { |
| uint32_t reserved; |
| uint32_t infotype; |
| uint32_t infotype_version; |
| uint32_t crypt_key; |
| } x3f_camf_type2_t; |
| |
| typedef struct x3f_camf_type4_s |
| { |
| uint32_t decoded_data_size; |
| uint32_t decode_bias; |
| uint32_t block_size; |
| uint32_t block_count; |
| } x3f_camf_type4_t; |
| |
| typedef struct x3f_camf_type5_s |
| { |
| uint32_t decoded_data_size; |
| uint32_t decode_bias; |
| uint32_t unknown2; |
| uint32_t unknown3; |
| } x3f_camf_type5_t; |
| |
| typedef struct x3f_camf_s |
| { |
| |
| /* Header info */ |
| uint32_t type; |
| union { |
| x3f_camf_typeN_t tN; |
| x3f_camf_type2_t t2; |
| x3f_camf_type4_t t4; |
| x3f_camf_type5_t t5; |
| }; |
| |
| /* The encrypted raw data */ |
| void *data; |
| uint32_t data_size; |
| |
| /* Help data for type 4 Huffman compression */ |
| x3f_true_huffman_t table; |
| x3f_hufftree_t tree; |
| uint8_t *decoding_start; |
| uint32_t decoding_size; |
| |
| /* The decrypted data */ |
| void *decoded_data; |
| uint32_t decoded_data_size; |
| |
| /* Pointers into the decrypted data */ |
| camf_entry_table_t entry_table; |
| } x3f_camf_t; |
| |
| typedef struct x3f_directory_entry_header_s |
| { |
| uint32_t identifier; /* Should be ´SECp´, "SECi", ... */ |
| uint32_t version; /* 0x00020001 is version 2.1 */ |
| union { |
| x3f_property_list_t property_list; |
| x3f_image_data_t image_data; |
| x3f_camf_t camf; |
| } data_subsection; |
| } x3f_directory_entry_header_t; |
| |
| typedef struct x3f_directory_entry_s |
| { |
| struct |
| { |
| uint32_t offset; |
| uint32_t size; |
| } input, output; |
| |
| uint32_t type; |
| |
| x3f_directory_entry_header_t header; |
| } x3f_directory_entry_t; |
| |
| typedef struct x3f_directory_section_s |
| { |
| uint32_t identifier; /* Should be ´SECd´ */ |
| uint32_t version; /* 0x00020001 is version 2.1 */ |
| |
| /* 2.0 Fields */ |
| uint32_t num_directory_entries; |
| x3f_directory_entry_t *directory_entry; |
| } x3f_directory_section_t; |
| |
| typedef struct x3f_header_s |
| { |
| /* 2.0 Fields */ |
| uint32_t identifier; /* Should be ´FOVb´ */ |
| uint32_t version; /* 0x00020001 means 2.1 */ |
| uint8_t unique_identifier[SIZE_UNIQUE_IDENTIFIER]; |
| uint32_t mark_bits; |
| uint32_t columns; /* Columns and rows ... */ |
| uint32_t rows; /* ... before rotation */ |
| uint32_t rotation; /* 0, 90, 180, 270 */ |
| |
| char white_balance[SIZE_WHITE_BALANCE]; /* Introduced in 2.1 */ |
| char color_mode[SIZE_COLOR_MODE]; /* Introduced in 2.3 */ |
| |
| /* Introduced in 2.1 and extended from 32 to 64 in 3.0 */ |
| uint8_t extended_types[NUM_EXT_DATA]; /* x3f_extended_types_t */ |
| float extended_data[NUM_EXT_DATA]; /* 32 bits, but do type differ? */ |
| } x3f_header_t; |
| |
| typedef struct x3f_info_s |
| { |
| char *error; |
| struct |
| { |
| LibRaw_abstract_datastream *file; /* Use if more data is needed */ |
| } input, output; |
| } x3f_info_t; |
| |
| typedef struct x3f_s |
| { |
| x3f_info_t info; |
| x3f_header_t header; |
| x3f_directory_section_t directory_section; |
| } x3f_t; |
| |
| typedef enum x3f_return_e |
| { |
| X3F_OK = 0, |
| X3F_ARGUMENT_ERROR = 1, |
| X3F_INFILE_ERROR = 2, |
| X3F_OUTFILE_ERROR = 3, |
| X3F_INTERNAL_ERROR = 4 |
| } x3f_return_t; |
| |
| x3f_return_t x3f_delete(x3f_t *x3f); |
| |
| /* Hacky external flags */ |
| /* --------------------------------------------------------------------- */ |
| |
| extern int legacy_offset; |
| extern bool_t auto_legacy_offset; |
| |
| /* --------------------------------------------------------------------- */ |
| /* Huffman Decode Macros */ |
| /* --------------------------------------------------------------------- */ |
| |
| #define HUF_TREE_MAX_LENGTH 27 |
| #define HUF_TREE_MAX_NODES(_leaves) ((HUF_TREE_MAX_LENGTH + 1) * (_leaves)) |
| #define HUF_TREE_GET_LENGTH(_v) (((_v) >> 27) & 0x1f) |
| #define HUF_TREE_GET_CODE(_v) ((_v)&0x07ffffff) |
| |
| x3f_t *x3f_new_from_file(LibRaw_abstract_datastream *infile); |
| x3f_return_t x3f_delete(x3f_t *x3f); |
| x3f_directory_entry_t *x3f_get_raw(x3f_t *x3f); |
| x3f_directory_entry_t *x3f_get_thumb_plain(x3f_t *x3f); |
| x3f_return_t x3f_load_data(x3f_t *x3f, x3f_directory_entry_t *DE); |
| x3f_directory_entry_t *x3f_get_thumb_huffman(x3f_t *x3f); |
| x3f_directory_entry_t *x3f_get_thumb_jpeg(x3f_t *x3f); |
| x3f_directory_entry_t *x3f_get_camf(x3f_t *x3f); |
| x3f_directory_entry_t *x3f_get_prop(x3f_t *x3f); |
| /* extern */ int32_t x3f_load_data_size(x3f_t *x3f, x3f_directory_entry_t *DE); |
| |
| #endif |