Last active
June 2, 2025 13:38
-
-
Save alastairmccormack/fc8888adb40d80824fb80d3c1523425a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| meta: | |
| id: tiff | |
| seq: | |
| - id: bom | |
| size: 2 # first two bytes determines endianness | |
| - id: body | |
| type: tiff_body | |
| types: | |
| tiff_body: | |
| meta: | |
| endian: | |
| switch-on: _root.bom | |
| cases: | |
| '[0x49, 0x49]': le | |
| '[0x4d, 0x4d]': be | |
| enums: | |
| tiff_tag: | |
| 254: new_subfile_type | |
| 255: subfile_type | |
| 256: image_width | |
| 257: image_length | |
| 258: bits_per_sample | |
| 259: compression | |
| 262: photometric_interpretation | |
| 263: threshholding | |
| 264: cell_width | |
| 265: cell_length | |
| 266: fill_order | |
| 270: image_description | |
| 271: make | |
| 272: model | |
| 273: strip_offsets | |
| 274: orientation | |
| 277: samples_per_pixel | |
| 278: rows_per_strip | |
| 279: strip_byte_counts | |
| 282: x_resolution | |
| 283: y_resolution | |
| 284: planar_configuration | |
| 296: resolution_unit | |
| 305: software | |
| 306: date_time | |
| 315: artist | |
| 320: color_map | |
| 321: halftone_hints | |
| 322: tile_width | |
| 323: tile_length | |
| 324: tile_offsets | |
| 325: tile_byte_counts | |
| 332: ink_set | |
| 333: ink_names | |
| 330: sub_ifds | |
| 338: extra_samples | |
| # EXIF | |
| 33432: copyright | |
| 33434: exposure_time | |
| 33437: f_number | |
| 34850: exposure_program | |
| 36864: exif_version | |
| 36867: date_time_original | |
| 37383: metering_mode | |
| 37384: light_source | |
| 37385: flash | |
| 40962: pixel_x_dimension | |
| 40963: pixel_y_dimension | |
| # GeoTIFF | |
| 33550: model_pixel_scale | |
| 33922: model_tiepoint | |
| 34264: model_transformation | |
| 34735: geo_key_directory | |
| 34736: geo_double_params | |
| 34737: geo_ascii_params | |
| # XMP, etc. | |
| 34665: exif_ifd_pointer | |
| 34853: gps_info_ifd_pointer | |
| 40960: flashpix_version | |
| 700: xmp | |
| # DNG | |
| 50706: dng_version | |
| 50707: dng_backward_version | |
| 50708: unique_camera_model | |
| 50709: localized_camera_model | |
| 50710: cfa_plane_color | |
| 50711: cfa_layout | |
| 50712: linearization_table | |
| 50713: black_level_repeat_dim | |
| 50714: black_level | |
| 50715: black_level_delta_h | |
| 50716: black_level_delta_v | |
| 50717: white_level | |
| 50718: default_scale | |
| 50719: default_crop_origin | |
| 50720: default_crop_size | |
| 50721: color_matrix1 | |
| 50722: color_matrix2 | |
| 50723: camera_calibration1 | |
| 50724: camera_calibration2 | |
| 50725: reduction_matrix1 | |
| 50726: reduction_matrix2 | |
| 50727: analog_balance | |
| 50728: as_shot_neutral | |
| 50729: as_shot_white_xy | |
| 50730: baseline_exposure | |
| 50731: baseline_noise | |
| 50732: baseline_sharpness | |
| 50733: bayer_green_split | |
| 50734: linear_response_limit | |
| 50735: camera_serial_number | |
| 50736: lens_info | |
| 50737: chroma_blur_radius | |
| 50738: anti_alias_strength | |
| 50739: shadow_scale | |
| 50740: dng_private_data | |
| 50741: maker_note_safety | |
| 50778: calibration_illuminant1 | |
| 50779: calibration_illuminant2 | |
| 50780: best_quality_scale | |
| 50781: raw_data_unique_id | |
| 50827: original_raw_file_name | |
| 50828: original_raw_file_data | |
| 50829: active_area | |
| 50830: masked_areas | |
| 50831: as_shot_icc_profile | |
| 50832: as_shot_pre_profile_matrix | |
| 50833: current_icc_profile | |
| 50834: current_pre_profile_matrix | |
| 50879: colorimetric_reference | |
| 50931: camera_calibration_signature | |
| 50932: profile_calibration_signature | |
| 50933: extra_camera_profiles | |
| 50934: as_shot_profile_name | |
| 50935: noise_reduction_applied | |
| 50936: profile_name | |
| 50937: profile_hue_sat_map_dims | |
| 50938: profile_hue_sat_map_data1 | |
| 50939: profile_hue_sat_map_data2 | |
| 50940: profile_tone_curve | |
| 50941: profile_embed_policy | |
| 50942: profile_copyright | |
| 50964: forward_matrix1 | |
| 50965: forward_matrix2 | |
| 50966: preview_application_name | |
| 50967: preview_application_version | |
| 50968: preview_settings_name | |
| 50969: preview_settings_digest | |
| 50970: preview_color_space | |
| 50971: preview_date_time | |
| 50972: raw_image_digest | |
| 50973: original_raw_file_digest | |
| 50974: sub_tile_block_size | |
| 50975: row_interleave_factor | |
| 50981: profile_look_table_dims | |
| 50982: profile_look_table_data | |
| 51125: default_user_crop | |
| 51178: depth_near | |
| 51179: depth_far | |
| 51180: depth_units | |
| 52535: illuminant_data3 | |
| 52536: mask_sub_area | |
| 52537: profile_hue_sat_map_data3 | |
| 52543: rgb_tables | |
| 52544: profile_gain_table_map2 | |
| 52547: column_interleave_factor | |
| 51041: noise_profile | |
| 51125: default_user_crop | |
| 51110: default_black_render | |
| 52525: profile_gain_table_map | |
| types: | |
| ifd_entry: | |
| enums: | |
| ftype: | |
| 1: byte | |
| 2: ascii | |
| 3: short | |
| 4: long | |
| 5: rational | |
| 6: signed_byte | |
| 7: undefined | |
| 8: signed_short | |
| 9: signed_long | |
| 10: signed_rational | |
| 11: float | |
| 12: double | |
| types: | |
| byte: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: u1 | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| ascii: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: str | |
| encoding: UTF-8 | |
| size: _parent.count | |
| terminator: 0 | |
| consume: false | |
| short: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: | |
| switch-on: _parent.field_type | |
| cases: | |
| 'ftype::short': u2 | |
| 'ftype::signed_short': s2 | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| long: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: | |
| switch-on: _parent.field_type | |
| cases: | |
| 'ftype::long': u4 | |
| 'ftype::signed_long': s4 | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| float: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: f4 | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| double: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: f8 | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| undefined: | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| size: 1 | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| rational: | |
| types: | |
| rational_pair: | |
| seq: | |
| - id: numerator | |
| type: | |
| switch-on: _parent._parent.field_type | |
| cases: | |
| 'ftype::rational': u8 | |
| 'ftype::signed_rational': s8 | |
| - id: denominator | |
| type: | |
| switch-on: _parent._parent.field_type | |
| cases: | |
| 'ftype::rational': u8 | |
| 'ftype::signed_rational': s8 | |
| instances: | |
| value: | |
| io: '_parent.direct_value ? _parent.raw_value._io : _root._io ' | |
| pos: '_parent.direct_value ? 0 : _parent.offset ' | |
| type: rational_pair | |
| repeat: expr | |
| repeat-expr: _parent.count | |
| data_exif: | |
| instances: | |
| offset: | |
| io: _parent.raw_value._io | |
| pos: 0 | |
| type: u4 | |
| exif: | |
| io: _root._io | |
| pos: offset | |
| type: ifd | |
| sub_ifds: | |
| instances: | |
| offset: | |
| io: _parent.raw_value._io | |
| pos: 0 | |
| type: u4 | |
| sub_ifds: | |
| io: _root._io | |
| pos: offset | |
| type: ifd | |
| raw_value: | |
| seq: | |
| - id: value | |
| size: 4 | |
| instances: | |
| direct_value: | |
| value: | | |
| (field_type == ftype::byte and count <= 4) or | |
| (field_type == ftype::signed_byte and count <= 4) or | |
| (field_type == ftype::ascii and count <= 4) or | |
| (field_type == ftype::short and count <= 2) or | |
| (field_type == ftype::signed_short and count <= 2) or | |
| (field_type == ftype::long and count == 1) or | |
| (field_type == ftype::signed_long and count == 1) or | |
| (field_type == ftype::undefined and count <= 4) | |
| seq: | |
| - id: tag | |
| type: u2 | |
| enum: tiff_tag | |
| - id: field_type | |
| type: u2 | |
| enum: ftype | |
| - id: count | |
| type: u4 | |
| - id: raw_value | |
| size: 4 | |
| type: raw_value | |
| if: direct_value == true | |
| - id: offset | |
| type: u4 | |
| if: direct_value == false | |
| - id: data | |
| type: | |
| switch-on: field_type | |
| cases: | |
| 'ftype::byte': byte | |
| 'ftype::ascii': ascii | |
| 'ftype::short': short | |
| 'ftype::signed_short': short | |
| 'ftype::long': long | |
| 'ftype::signed_long': long | |
| 'ftype::rational': rational | |
| 'ftype::signed_rational': rational | |
| 'ftype::undefined': undefined | |
| 'ftype::double': double | |
| 'ftype::float': float | |
| - id: parsed_data | |
| type: | |
| switch-on: tag | |
| cases: | |
| 'tiff_tag::exif_ifd_pointer': data_exif | |
| 'tiff_tag::sub_ifds': sub_ifds | |
| ifd_wrapper: | |
| params: | |
| - id: i | |
| type: u4 | |
| instances: | |
| ifd: | |
| io: _root._io | |
| type: ifd | |
| # On the first iteration use ifd_offset, | |
| # then use next_ifd_offset from the previous run | |
| pos: 'i == 0 ? _parent.ifd_offset : _parent.ifds[i - 1].ifd.next_ifd_offset' | |
| ifd: | |
| seq: | |
| - id: num_entries | |
| type: u2 | |
| - id: entries | |
| type: ifd_entry | |
| repeat: expr | |
| repeat-expr: num_entries | |
| - id: next_ifd_offset | |
| type: u4 | |
| seq: | |
| - id: version | |
| type: u2 | |
| - id: ifd_offset | |
| type: u4 | |
| - id: ifds | |
| type: ifd_wrapper(_index) | |
| repeat: until | |
| # next_ifd_offset will be 0 when no more ifds are available | |
| repeat-until: _.ifd.next_ifd_offset == 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment