MediaInfoLib icon indicating copy to clipboard operation
MediaInfoLib copied to clipboard

Parse gain map metadata

Open cjee21 opened this issue 6 months ago • 14 comments

Parse ISO 21496-1 Gain map metadata for JPEG and PNG.

cjee21 avatar Jun 23 '25 13:06 cjee21

@JeromeMartinez only for JPEG and PNG for now. JPEG one is tested but PNG one no sample file to test. AVIF have trouble getting MediaInfo to parse the correct position. Since the spec is not final yet, there may be changes. For example, it seems use_common_denominator is no longer present.


Side note: Noticed there is XMP present in AVIF. Also Exif in AVIF has some issues which the new commit in Exif PR fixes.

cjee21 avatar Jun 23 '25 13:06 cjee21

I guess this is why AVIF gain map metadata cannot be obtained....

0000C1   item - item_ID 5 (84 bytes)
0000C1    item_ID:                             5 (0x0005) - (16 bits)
0000C3    reserved:                            0 (0x000) - (12 bits)
0000C4    construction_method:                 1 (0x1) - (4 bits)
0000C5    data_reference_index:                0 (0x0000) - (16 bits)
0000C7    base_offset:                         0 (0x0) - (0 bits)
0000C7    extent_count:                        1 (0x0001) - (16 bits)
0000C9    extent (84 bytes)
0000C9     extent_offset:                      0 (0x00000000)
0000CD     extent_length:                      142 (0x0000008E)

Construction method is 1 but...

Skip_S1( 4,                                         "construction_method");

cjee21 avatar Jun 24 '25 09:06 cjee21

Found the metadata in AVIF, added a temp commit to parse/show it. This commit is made in very simple/hack method.

cjee21 avatar Jun 24 '25 11:06 cjee21

Found the metadata in AVIF, added a temp commit to parse/show it.

Sample file please :).

Side note: Noticed there is XMP present in AVIF. Also Exif in AVIF has some issues which the new commit in Exif PR fixes.

Same :)

I won't handle the PRs now but at least I have the file in my regression tests so I see when something changes.

JeromeMartinez avatar Jun 24 '25 11:06 JeromeMartinez

Sample file please :).

Same :)

The same link as previously posted in Ultra HDR issue:

https://www.adobe.com/go/gainmap_sample_photos

For AVIF, the Exif will only parse after the fix in the Exif PR. The XMP is not handled/parsed. The ISO 21496-1 data will be shown in trace on this PR.

cjee21 avatar Jun 24 '25 12:06 cjee21

Also, parsespeed=1 crashes for AVIF:

Screenshot 2025-06-24 200945

cjee21 avatar Jun 24 '25 12:06 cjee21

The same link as previously posted in Ultra HDR issue:

oops, so they are already in my regression test samples, thank you.

JeromeMartinez avatar Jun 24 '25 12:06 JeromeMartinez

Also, parsespeed=1 crashes for AVIF:

No crash on my side 01_base_hdr.avif

000000 File Type (36 bytes)
000000  Header (8 bytes)
000000   Size:                                 36 (0x00000024)
000004   Name:                                 ftyp
000008  MajorBrand:                            avif
00000C  MajorBrandVersion:                     0 (0x00000000)
000010  CompatibleBrand:                       avif
000014  CompatibleBrand:                       mif1
000018  CompatibleBrand:                       miaf
00001C  CompatibleBrand:                       MA1A
000020  CompatibleBrand:                       tmap
[...]
000171  Item data (150 bytes)
000171   Header (8 bytes)
000171    Size:                                150 (0x00000096)
000175    Name:                                idat
000179   ISO 21496-1 Metadata (142 bytes)
000179    version:                             0 (0x00)
00017A    minimum_version:                     0 (0x0000)
00017C    writer_version:                      0 (0x0000)
00017E    flags:                               192 (0xC0)
00017F    backward_direction:                  No
00017F    is_multichannel:                     Yes
00017F    use_base_colour_space:               Yes
00017F    use_common_denominator:              No
00017F    base_hdr_headroom_numerator:         81130 (0x00013CEA)
000183    base_hdr_headroom_denominator:       32768 (0x00008000)
000187    alternate_hdr_headroom_numerator:    0 (0x00000000)
00018B    alternate_hdr_headroom_denominator:  1 (0x00000001)
00018F    channel 1 (40 bytes)
00018F     gain_map_min_numerator:             4253765028 (0xFD8B4DA4)
000193     gain_map_min_denominator:           1073741824 (0x40000000)
000197     gain_map_max_numerator:             71624 (0x000117C8)
00019B     gain_map_max_denominator:           32768 (0x00008000)
00019F     gamma_numerator:                    268435456 (0x10000000)
0001A3     gamma_denominator:                  1073741824 (0x40000000)
0001A7     base_offset_numerator:              16777216 (0x01000000)
0001AB     base_offset_denominator:            1073741824 (0x40000000)
0001AF     alternate_offset_numerator:         16777216 (0x01000000)
0001B3     alternate_offset_denominator:       1073741824 (0x40000000)
0001B7    channel 2 (40 bytes)
0001B7     gain_map_min_numerator:             4260237736 (0xFDEE11A8)
0001BB     gain_map_min_denominator:           1073741824 (0x40000000)
0001BF     gain_map_max_numerator:             70001 (0x00011171)
0001C3     gain_map_max_denominator:           32768 (0x00008000)
0001C7     gamma_numerator:                    270236027 (0x101B797B)
0001CB     gamma_denominator:                  1073741824 (0x40000000)
0001CF     base_offset_numerator:              16777216 (0x01000000)
0001D3     base_offset_denominator:            1073741824 (0x40000000)
0001D7     alternate_offset_numerator:         16777216 (0x01000000)
0001DB     alternate_offset_denominator:       1073741824 (0x40000000)
0001DF    channel 3 (40 bytes)
0001DF     gain_map_min_numerator:             4202179432 (0xFA782B68)
0001E3     gain_map_min_denominator:           1073741824 (0x40000000)
0001E7     gain_map_max_numerator:             69532 (0x00010F9C)
0001EB     gain_map_max_denominator:           32768 (0x00008000)
0001EF     gamma_numerator:                    281119308 (0x10C18A4C)
0001F3     gamma_denominator:                  1073741824 (0x40000000)
0001F7     base_offset_numerator:              16777216 (0x01000000)
0001FB     base_offset_denominator:            1073741824 (0x40000000)
0001FF     alternate_offset_numerator:         16777216 (0x01000000)
000203     alternate_offset_denominator:       1073741824 (0x40000000)

JeromeMartinez avatar Jun 24 '25 12:06 JeromeMartinez

No crash on my side 01_base_hdr.avif

Try 01_base_sdr.avif

cjee21 avatar Jun 24 '25 12:06 cjee21

Try 01_base_sdr.avif

Same.

JeromeMartinez avatar Jun 24 '25 12:06 JeromeMartinez

Same.

Hmm.. here it crashes on parsespeed=1 on CLI in Visual Studio debug mode or activating full parse in Qt GUI even on master branch.

cjee21 avatar Jun 24 '25 12:06 cjee21

Hmm.. here it crashes on parsespeed=1 on CLI

I was using the Wx GUI. I can reproduce with CLI.

JeromeMartinez avatar Jun 24 '25 12:06 JeromeMartinez

Hmm.. here it crashes on parsespeed=1 on CLI in Visual Studio debug mode or activating full parse in Qt GUI even on master branch.

Mixup with Wx GUI, can be reproduced + backtrace with Wx GUI, I added a hot fix, I'll check later why it is so.

JeromeMartinez avatar Jun 24 '25 12:06 JeromeMartinez

Looked at more samples and updated the parsing, edited above comment that is wrong. Should now be able to parse all available samples. Also found that for AVIF, it may be stored either in idat or mdat, so two temporary commits to see it for both cases.

cjee21 avatar Jun 25 '25 15:06 cjee21

There are still some bugs with the new tfsxml based XMP parser. In some cases it does not reach the Finish() point.

cjee21 avatar Jun 29 '25 18:06 cjee21

In some cases it does not reach the Finish() point

Name or sample file please.

JeromeMartinez avatar Jun 29 '25 19:06 JeromeMartinez

In some cases it does not reach the Finish() point

Name or sample file please.

9931408803 from Google Pixel 9 Pro. It seems there is early return somewhere when there is a <?xpacket end="w"?> or a self-closing rdf:Description.

cjee21 avatar Jun 30 '25 06:06 cjee21

XMP parsing should be okay now. I modified the macros some more that were originally based on ones in spherical video. Let me know if you want to move the XMP fixes to a new PR.

cjee21 avatar Jun 30 '25 11:06 cjee21

XMP parsing should be okay now. I modified the macros some more that were originally based on ones in spherical video.

The spherical video macros were based on the ADM macros, and I hope that at long term I could have identical XML parsing related code, in the meantime it is good to have such implementation so when I finalize common XML parsing code I have enough for testing.

Let me know if you want to move the XMP fixes to a new PR.

It will be slow on my side for gain map, so if you need the XMP fixes for something else, I am fine for a dedicated PR and I merge it after quick regression checks, else it may stay there until I have the time for checking the whole PR.

JeromeMartinez avatar Jun 30 '25 16:06 JeromeMartinez

It will be slow on my side for gain map, so if you need the XMP fixes for something else, I am fine for a dedicated PR and I merge it after quick regression checks

I don't think I need it for something else but since the XMP PR is already merged, I think it'll be good to get it fixed earlier in case there are files that don't parse properly so I made the new PR.

After a quick review, the quality of the PR seems fine (also AVIF) for merging it

The AVIF part (the TEMP commits) are definitely not good. That is a really quick and 'hackish' way that would not work properly for different files. It likely requires some restructuring to handle the different construction methods which I do not have an idea how.

PR 2334 should be easy to review and maybe also 2336. The others require more work (likely need you to do some restructuring) so those can be put to the following release after a new release version if there is a release soon.

cjee21 avatar Jun 30 '25 18:06 cjee21

The AVIF part (the TEMP commits) are definitely not good. That is a really quick and 'hackish' way that would not work properly for different files. It likely requires some restructuring to handle the different construction methods which I do not have an idea how.

It seems to work well on files I tested, please an example of non working file.

JeromeMartinez avatar Jun 30 '25 18:06 JeromeMartinez

I don't find something with the XMP stuff

The last three links in Ultra HDR issue should have gain map metadata in XMP. Pixel 9 with single channel and the photography link with multi channel.

or the PNG

I do not have samples for this yet. Need a screenshot of HDR content from an Android 16 device.

cjee21 avatar Jun 30 '25 18:06 cjee21

It seems to work well on files I tested, please an example of non working file.

It will appear to work properly on Gain Map files since that is the purpose of the temp commits but I don;t know if it will break when there is a file with other content in IDAT. Also, the two TEMP commits are either one or the other. They both don't work together. One of them parses gain map from Adobe samples. The other parses gain map from libavif test files. The 2nd TEMP comments out the first.

cjee21 avatar Jun 30 '25 18:06 cjee21

One of them parses gain map from Adobe samples. The other parses gain map from libavif test files. The 2nd TEMP comments out the first.

Got it, I'll test both and I'll find a way to merge them.

or the PNG

I do not have samples for this yet. Need a screenshot of HDR content from an Android 16 device.

I was thinking to merge this PR with PNG only but as we don't have file it can wait.

JeromeMartinez avatar Jun 30 '25 18:06 JeromeMartinez

Got it, I'll test both and I'll find a way to merge them.

For the IDAT, probably need to implement parsing similar to MDAT (the part I do not know how). So that can parse other metadata that may be in IDAT as well. Need to read the construction method and handle appropriately, whether it is mdat or idat.

I was thinking to merge this PR with PNG only but as we don't have file it can wait.

If you want, can merge the JPEG part first (this PR has JPEG, PNG and AVIF but AVIF not ready and PNG no samples). But right now it is just parsing and populating a struct. Not yet do anything with the data. Probably in JPEG, check that we have gain map and metadata present (which type) then fill the HDR format along with necessary data.

cjee21 avatar Jun 30 '25 18:06 cjee21

then fill the HDR format along with necessary data.

For the moment it is not clear about how I would fill the HDR field, there are so many formats and hacks, I'll think about that but later.

JeromeMartinez avatar Jun 30 '25 18:06 JeromeMartinez

Completed the PNG one. Now left the AVIF idat/mdat handling and filling HDR format.

cjee21 avatar Jul 01 '25 16:07 cjee21

Rebased + some simplification of XMP part.

cjee21 avatar Jul 04 '25 09:07 cjee21

What is blocking the AVIF gain map parsing is the iloc construction method.

https://github.com/MediaArea/MediaInfoLib/blob/b5e97926de3409bec2613f6673fbb723a4909494/Source/MediaInfo/Multiple/File_Mpeg4_Elements.cpp#L2649

Screenshot 2025-07-27 010455

The ISO 21496-1 data can be in either mdat or idat based on different sample files and they have different construction method.

I do not know how the current mdat parsing works. Seems complex. Once the construction method is handled, adding gain map parsing should be as simple as adding Exif parsing.

cjee21 avatar Jul 26 '25 17:07 cjee21

Please 2 files with different method, and I check.

JeromeMartinez avatar Jul 26 '25 17:07 JeromeMartinez