Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error parsing -M option arguments: Invalid key Xmp.GCamera.MotionPhoto #3016

Closed
arty-name opened this issue Jul 11, 2024 · 21 comments
Closed
Labels
enhancement feature / functionality enhancements

Comments

@arty-name
Copy link

Describe the bug

My phone sometimes includes "Motion Photos" in the photos it takes. Sometimes I want to remove them to save on file size. I see them in the XMP section. When I try to delete these XMP tags I get an error that the key I provided is invalid. The same command with an EXIF tag works flawlessly.

To Reproduce

Steps to reproduce the behavior:

  1. Attached is the PoC. I took this photo, do whatever you need with it. It’s directly from the "camera", I only renamed it.
    test2
  2. List the exact commands/functions to reproduce the issue and include any related output: exiv2 -M"del Xmp.GCamera.MotionPhoto" test2.jpg or exiv2 -M"del Xmp.Container.Directory[3]/Container:Item/Item:Padding" test2.jpg
  3. The version 0.27.6 available in the latest Ubuntu

Expected behavior

I expect the XMP tag to be deleted. Instead I get an error message like this:

$ exiv2 -M "del Xmp.GCamera.MotionPhoto" test2.jpg
-M option 1: Invalid key `Xmp.GCamera.MotionPhoto'
exiv2: Error parsing -M option arguments
Usage: exiv2 [ options ] [ action ] file ...

Manipulate the Exif metadata of images.

Desktop (please complete the following information):

  • OS and version: Ubuntu 24.04
  • Exiv2 version and source: 0.27.6 from Ubuntu repositories
  • Compiler and version: G++ 13.2.0
  • Compilation mode and/or compiler flags:
bits=64
dll=1
debug=1
cplusplus=199711
package_name=exiv2
curl=0
have_inttypes=0
have_libintl=0
have_lensdata=1
have_iconv=1
have_memory=1
have_lstat=0
have_regex=0
have_regex_h=1
have_stdbool=1
have_stdint=1
have_stdlib=0
have_strlib=0
have_strerror_r=1
have_strings_h=0
have_mmap=1
have_munmap=1
have_sys_stat=1
have_unistd_h=0
have_sys_mman=1
have_libz=1
have_xmptoolkit=1
adobe_xmpsdk=0
have_bool=0
have_strings=1
have_sys_types=1
have_unistd=1
have_unicode_path=0
enable_bmff=1
enable_video=1
enable_webready=1
enable_nls=1
use_curl=0
use_ssh=0

Additional context

Add any other information about the problem here.

@arty-name arty-name added the bug label Jul 11, 2024
@clanmills
Copy link
Collaborator

I don't understand XMP or Adobe's XMPSDK. The exiv2 option -dX will totally remove the XMP, and that might be the solution to your needs.

$ exiv2 -dX ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg 
$ exiv2 -px ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg  
$

Your image contains the following XMP data:

$ exiv2 -pX ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg  > ~/temp/xmp.xmp ; ls -l ~/temp/xmp.xmp
-rw-r--r--  1 rmills  staff  53702 19 Jul 11:52 /Users/rmills/temp/xmp.xmp
545 rmills@rmillsm1:~/Desktop/Harry $ exiv2 -dX ~/Desktop/347813082-6f745ba6
$ exiv2 -pX ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg  | xmllint --pretty 2 - 
<?xml version="1.0"?>
<x:xmpmeta
    xmlns:x="adobe:ns:meta/"
    x:xmptk="Adobe XMP Core 5.1.0-jc003"
  >
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description
        xmlns:GCamera="http://ns.google.com/photos/1.0/camera/"
        rdf:about=""
        GCamera:HdrPlusMakernote="SERSUAPvZDVtXnAeLOr..."
    />
  </rdf:RDF>
</x:xmpmeta>
$ exiv2 -px ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg  
Xmp.hdrgm.Version                            XmpText     3  1.0
Xmp.xmpNote.HasExtendedXMP                   XmpText    32  4679D2A911D710DA7FB6725847403E22
Xmp.GCamera.MotionPhoto                      XmpText     1  1
Xmp.GCamera.MotionPhotoVersion               XmpText     1  1
Xmp.GCamera.MotionPhotoPresentationTimestampUs XmpText     7  1201486
Xmp.Container.Directory                      XmpText     0  type="Seq"
Xmp.Container.Directory[1]                   XmpText     0  type="Struct"
Xmp.Container.Directory[1]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[1]/Container:Item/Item:Semantic XmpText     7  Primary
Xmp.Container.Directory[1]/Container:Item/Item:Mime XmpText    10  image/jpeg
Xmp.Container.Directory[2]                   XmpText     0  type="Struct"
Xmp.Container.Directory[2]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[2]/Container:Item/Item:Semantic XmpText     7  GainMap
Xmp.Container.Directory[2]/Container:Item/Item:Mime XmpText    10  image/jpeg
Xmp.Container.Directory[2]/Container:Item/Item:Length XmpText     5  98874
Xmp.Container.Directory[3]                   XmpText     0  type="Struct"
Xmp.Container.Directory[3]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[3]/Container:Item/Item:Mime XmpText     9  video/mp4
Xmp.Container.Directory[3]/Container:Item/Item:Semantic XmpText    11  MotionPhoto
Xmp.Container.Directory[3]/Container:Item/Item:Length XmpText     7  2604886
Xmp.Container.Directory[3]/Container:Item/Item:Padding XmpText     1  0
$

XMPSDK understands the data and can modify it. I have insufficient knowledge to explain this.

I see that your image contains ExtendedXMP which is not supported by XMPSDK 5.4 embedded in exiv2. So the option -dX deletes the XMP data and ignores the extended XMP.

Looking at your file with program tvisitor (which is thoroughly documented in my book), I see:

547 rmills@rmillsm1:~/Desktop/Harry $ tvisitor -pRU ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg 
STRUCTURE OF JPEG FILE (II): /Users/rmills/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg
 address | marker       |  length | signature
       0 | 0xffd8 SOI  
       2 | 0xffe0 APP0  |      16 | JFIF_..__._.__..
      20 | 0xffe2 APP2  |     600 | ICC_PROFILE_..__.H____.___mntrRGB XYZ ..
     622 | 0xffe1 APP1  |   53779 | http://ns.adobe.com/xmp/extension/_4679D
   54403 | 0xffe2 APP2  |      88 | MPF_II*_.___.__.._.___0100..._.___.___..
   54493 | 0xffdb DQT   |      67 | _.......................................
   54562 | 0xffdb DQT   |      67 | ........................................
   54631 | 0xffc0 SOF0  |      17 | ......."_........ = h,w = 3472,4624
   54650 | 0xffc4 DHT   |      31 | __........________.............
   54683 | 0xffc4 DHT   |     181 | ._...........__.}..._....!1A..Qa."q.2...
   54866 | 0xffc4 DHT   |      31 | ._..........______.............
   54899 | 0xffc4 DHT   |     181 | ._..........._..w_......!1..AQ.aq."2...B
   55082 | 0xffda SOS  
 3870002 | 0xffd9 EOI  
 3870004 | 0xffd8 SOI  
 3870006 | 0xffe0 APP0  |      16 | JFIF_..__._.__..
 3870024 | 0xffe1 APP1  |     571 | http://ns.adobe.com/xap/1.0/_<?xpacket b
 3870597 | 0xffdb DQT   |      67 | _.......................................
 3870666 | 0xffc0 SOF0  |      11 | ..d....._.. = h,w = 868,1156
 3870679 | 0xffc4 DHT   |      31 | __........________.............
 3870712 | 0xffc4 DHT   |     181 | ._...........__.}..._....!1A..Qa."q.2...
 3870895 | 0xffda SOS  
 3968876 | 0xffd9 EOI  
....

Almost 50% of the file (from 3870002 onwards) is XMP, previews, and various APPn segments. As discussed in 3.1 of my book, you can remove that data with dd.

$ cp 347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg 34.jpg
$ dd count=1 bs=3870004 if=34.jpg > foo.jpg ; ls -l 34.jpg foo.jpg
1+0 records in
1+0 records out
3870004 bytes transferred in 0.002577 secs (1501747769 bytes/sec)
-rw-r--r--@ 1 rmills  staff  6573764 19 Jul 12:41 34.jpg
-rw-r--r--  1 rmills  staff  3870004 19 Jul 12:43 foo.jpg
$ open foo.jpg 
$ 

I think this is what you want to save storage space. This could be added as a new option -dZ (delete and zap junk in the file), I would be happy to mentor you to write the code and submit a PR.

@arty-name
Copy link
Author

Thank you for the response!

I believe I have tried removing the whole XMP section, and this has an unfortunate downside: the Ultra HDR data is also removed, as it is apparently stored in the XMP. Since this is important to me I decided against this approach.

@clanmills
Copy link
Collaborator

@arty-name. I attach foo.jpg. I think the XMP (and extended XMP) remains in the file. Is the "Ultra HDR" still present?

$ dd count=1 bs=3870004 if=~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg of=~/Desktop/foo.jpg

foo

@arty-name
Copy link
Author

I don’t know what happened but Google Photos doesn’t recognize this file as having Ultra HDR and doesn’t display it with extra brightness

@clanmills
Copy link
Collaborator

clanmills commented Jul 19, 2024

Well, I threw away half the data in the file, so it must be in the stuff I removed.

Here's the specification: for "Ultra HDR" https://developer.android.com/media/platform/hdr-image-format

So, I'm not convinced this is a bug. It's an enhancement request to support ExtendedXMP and remove the Ultra HDR information. If you're happy with the -dX feature to remove XMP, it's probably easy to remove the segments that store the extended XMP (without supporting extended XMP).

I'm only offering to mentor and am not coming out of retirement to work on this. If you can't work on this, you'll have to wait to see if another engineer offers to help.

@clanmills
Copy link
Collaborator

clanmills commented Jul 19, 2024

I've put 34...jpg and foo.jpg on Google Photos. The colours on 34...jpg are impressive. Maybe I should buy a Google Pixel 7.

https://photos.app.goo.gl/3aWMWPbR62U2VYJq7

I like and use Google Photos. The 90,000 images on my website are stored in Google Photos. https://clanmills.com

@clanmills
Copy link
Collaborator

clanmills commented Jul 19, 2024

Progress.

$ dd count=1 bs=6041484 if=~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg of=~/Desktop/foo2.jpg
1+0 records in
1+0 records out
6041484 bytes transferred in 0.004738 secs (1275112706 bytes/sec)
$

I've uploaded foo2.jpg to Google Photos. I figured out bs=6041484 from tvisitor -pRU 34...jpg output. The bummer is that the MotionPhoto is big (length is 2604886). We'll need to rewrite the file to store GainMap (length is 98874) without the MotionPhoto.

$ ls -lh foo2.jpg 347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg 
-rw-r--r--@ 1 rmills  staff   6.3M 19 Jul 13:16 347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg
-rw-r--r--@ 1 rmills  staff   5.8M 19 Jul 17:47 foo2.jpg
$ 

Apologies: @arty-name Tom: I'm on vacation with my family and can't spend more time on this. This is an interesting challenge. I hope somebody can find time to work on it.

@clanmills
Copy link
Collaborator

WhatsApp Image 2024-07-19 at 15 48 49

@arty-name
Copy link
Author

Thank you for your work, Robin! I have the utmost respect for people being able to handle these insane data structures.

I didn’t intend, of course, to distract you from your vacation, not even mentioning the retirement. The view is very cozy!

The colors with Ultra HDR are quite nice indeed. I found the technical approach there a bit of smart cheating: bumping up the OLED screen brightness. Nevertheless it’s nice to see screens finally competing not only on resolution and refresh rate.

@clanmills
Copy link
Collaborator

@arty-name. Tom: I'm happy to investigate this matter. I've been busy travelling, gardening, and performing music and should take time to investigate software puzzles. I was bored on Friday morning, and you presented an interesting issue. Thank You for bringing up this topic.

Your file uses extended XMP and MPF segments, as shown in this drawing from https://developer.android.com/media/platform/hdr-image-format.

hdrimageformatexample

The GainMap is a low-resolution bitmap of colour magic. We need to retain that to get the beautiful colours. The MotionPhoto is an mp4 similar to this shot of my wife on vacation last year in Whitby, North Yorks. Google Photos created this from a phone image using server-side magic. Count Dracula lives in the ruins of Whitby Abbey.

20230713_123442-CINEMATIC.1.mp4

I didn't document MPF in my book and will investigate this when I get home in two weeks.

The file foo.jpg contains the GainMap, however the offsets in the MPF will need to be modified. So, to achieve your goal, we need to rewrite the MPF segment and the XMP. The Extended XMP with the GainMap parameters is good.

The colours on my MBP are beautiful, and I look forward to seeing them on my ALOGIC touch-sensitive UHD desktop when I return from vacation. Progress in display and camera technology is excellent.

Exiv2 has no code to manage MPF or Extended XMP and therefore the changes to Exiv2 involve architectural changes to Exiv2. Until this work can be undertaken, the solution to your issue is to use Phil's excellent exiftool.

@clanmills
Copy link
Collaborator

clanmills commented Jul 21, 2024

I'm awake. The family are still asleep. Here's your video:

34.mp4
$ dd bs=1 count=2604886 skip=3985462 if=~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg  of=~/temp/34.mp4

count=2604886 is in the XMP:

...
Xmp.Container.Directory[3]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[3]/Container:Item/Item:Mime XmpText     9  video/mp4
Xmp.Container.Directory[3]/Container:Item/Item:Semantic XmpText    11  MotionPhoto
Xmp.Container.Directory[3]/Container:Item/Item:Length XmpText     7  2604886
Xmp.Container.Directory[3]/Container:Item/Item:Padding XmpText     1  0

How did I figure out skip=3985462? It should be in the MPF segment and isn't. So, I sniffed in the file for ftyp, which normally starts an mp4. It's also implied by the output from $tvisitor -pRU ~/Desktop/34....jpg. When I add a section to my book about MPF, I will document the exact location of the MP4.

I've signed up for an August Google alert about the Pixel 9 Pro. I know what I'm going to get for Christmas.

@arty-name
Copy link
Author

I know what I'm going to get for Christmas.

Oooh, exciting!

use Phil's excellent exiftool.

I’ve tried it out as well, and extracting data is relatively straightforward with it, but modification turned out to be too much of a challenge for me.

@clanmills
Copy link
Collaborator

Making progress. It's painful, I don't think I've written any C++ for a couple of years.

When dumping Stonehenge.jpg, tvisitor shows:

STRUCTURE OF JPEG FILE (II): /Users/rmills/Stonehenge.jpg
 address | marker       |  length | signature
       0 | 0xffd8 SOI  
       2 | 0xffe1 APP1  |   15272 | Exif__II*_.___._..._.___.___..._.___.___
   15276 | 0xffe1 APP1  |    2786 | http://ns.adobe.com/xap/1.0/_<?xpacket b
   18064 | 0xffed APP13 |      96 | Photoshop 3.0_8BIM.._____'..__._...Z_..%
   18162 | 0xffe2 APP2  |    4094 | MPF_II*_.___.__.._.___0100..._.___.___..
   22258 | 0xffdb DQT   |     132 | _.......................................
   22392 | 0xffc0 SOF0  |      17 | ....p..!_........ = h,w = 4000,6000
   22411 | 0xffc4 DHT   |     418 | __........________............_.........
   22831 | 0xffda SOS  
 6196491 | 0xffd9 EOI  
 6196976 | 0xffd8 SOI  
 6196978 | 0xffe1 APP1  |    1022 | Exif__II*_.___._i.._.___._________._..._
 6198002 | 0xffdb DQT   |     132 | _..........................!.#"!. .%)4,%
 6198136 | 0xffc0 SOF0  |      17 | .......!_........ = h,w = 424,640
 6198155 | 0xffc4 DHT   |     418 | __........________............_.........
 6198575 | 0xffda SOS  
 6234770 | 0xffd9 EOI  
 6234864 | 0xffd8 SOI  
 6234866 | 0xffe1 APP1  |    1022 | Exif__II*_.___._i.._.___._________._..._
 6235890 | 0xffdb DQT   |     132 | _.......................................
 6236024 | 0xffc0 SOF0  |      17 | ..8.T..!_........ = h,w = 1080,1620
 6236043 | 0xffc4 DHT   |     418 | __........________............_.........
 6236463 | 0xffda SOS  
 6757985 | 0xffd9 EOI  
END: /Users/rmills/Stonehenge.jpg

I've added a dictionary to understand MPF and the recursive dump shows:

   18162 | 0xffe2 APP2  |    4094 | MPF_II*_.___.__.._.___0100..._.___.___..
  STRUCTURE OF TIFF FILE (II): /Users/rmills/Stonehenge.jpg+12->15264+18170->4088
   address |    tag                                  |      type |    count |    offset | value
        10 | 0xb000 MPF.MPF.Version                  | UNDEFINED |        4 |           | 0100
        22 | 0xb001 MPF.MPF.nPhotos                  |      LONG |        1 |           | 3
        34 | 0xb002 MPF.MPF.Photos                   | UNDEFINED |       48 |        52 | __...N______._._._.@..__.G^_____._.@ +++
  END: /Users/rmills/Stonehenge.jpg+12->15264+18170->4088

I hope to add the decoder to handle MPF.MPF.Photos tomorrow.

No good news about the Pixel 9 Pro. Alison asked the killer question: "Will that work with your Samsung Watch?"

@clanmills
Copy link
Collaborator

This is difficult.

Specifications:
Google: https://developer.android.com/media/platform/hdr-image-format#motivation
MPF White Paper DC-X007-KEY_E.pdf: https://www.cipa.jp/std/documents/e/DC-X007-KEY_E.pdf_5https://www.cipa.jp/std/documents/e/DC-X007-KEY_E.pdf
MPF Specification DC-007_E.pdf: https://web.archive.org/web/20190713230858if_/http://www.cipa.jp:80/std/documents/e/DC-007_E.pdf_`https://web.archive.org/web/20190713230858if_/http://www.cipa.jp:80/std/documents/e/DC-007_E.pdf
Exiftool MPF Documentation: https://exiftool.org/TagNames/MPF.html

Challenges:

  1. Reconciling the test files with the google spec
  2. There is XMP and Extended XMP
  3. I don't understand the coding ofGCamera:HdrPlusMakernote="SERSUAPvZD...
1178 rmills@rmillsm1:~/gnu/github/tvisitor/book/b $ ./tvisitor  -pRU ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg 
STRUCTURE OF JPEG FILE (II): /Users/rmills/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg
 address | marker       |  length | signature
       0 | 0xffd8 SOI  
       2 | 0xffe1 APP1  |   15086 | Exif__II*_.___._..._.___.___..._.___.___
...
   15090 | 0xffe0 APP0  |      16 | JFIF_..__._.__..
   15108 | 0xffe2 APP2  |     600 | ICC_PROFILE_..__.H____.___mntrRGB XYZ ..
   15710 | 0xffe1 APP1  |    1494 | http://ns.adobe.com/xap/1.0/_<x:xmpmeta 
   17206 | 0xffe1 APP1  |   53779 | http://ns.adobe.com/xmp/extension/_4679D
   70987 | 0xffe2 APP2  |      88 | MPF_II*_.___.__.._.___0100..._.___.___..
  STRUCTURE OF TIFF FILE (II): /Users/rmills/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg:70995->82
   address |    tag                                  |      type |    count |    offset | value
        10 | 0xb000 MPF.MPF.Version                  | UNDEFINED |        4 |           | 0100
        22 | 0xb001 MPF.MPF.nPhotos                  |      LONG |        1 |           | 2
        34 | 0xb002 MPF.MPF.Photos                   | UNDEFINED |       32 |        50 | __._.K;_____________:.._.8:_____
  END: /Users/rmills/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg:70995->82
...
END: /Users/rmills/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg

Dumping MPF.MPF.Photos:

1180 rmills@rmillsm1:~/gnu/github/tvisitor/book/b $ dmpf bs=4 hex=0 count=32 start=$((70995+50)) /Users/rmills/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg
       0        0: __._.K;_____________:.._.8:_____  ->      196608    3886064          0          0          0      98874    3815593          0
1181 rmills@rmillsm1:~/gnu/github/tvisitor/book/b $ 

I'm not certain that this conforms with this drawing:
hdrimageformatexample

@arty-name
Copy link
Author

I didn’t have to look at Android-related documentation often, nor too deep, but it was always a bad experience. I would not be surprised if the implementation does not 100% match the specification.

Regarding the Samsung Watch, this depends on its generation. Recent versions switched away from Tizen OS and started using Google’s Wear OS, which supposedly should be better compatible. However even my old Tizen OS based Samsung Watch worked okay with Android phone. Not Pixel though, I cannot vouch for it.

@clanmills
Copy link
Collaborator

@arty-name Alison doesn't want a solution. My current Samsung Watch/Phone setup is working fine and will be upgraded eventually.

I have a lot of confidence in Google Engineers. Can you confirm that 347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg has not been edited?

I've been out for a walk and thought about this puzzle. Three useful conclusions:

  1. The Extended XMP is a distraction and not at the centre of this puzzle.
  2. I don't need to understand GCamera:HdrPlusMakernote="SERSUAPvZD.. - that's Google Magic.
  3. I can see the greyscale JPG (used by Google's HDR). That image has an XMP segment with the HDR parameters.
$ dd bs=1 count=$((3985460+4-3886588)) skip=3886588 if=~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg of=foo.jpg
$ echo $((3985460+4-3886588))
98876
$ exiv2 -pX foo.jpg 
<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 5.5.0">
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about=""
    xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/"
   hdrgm:Version="1.0"
   hdrgm:GainMapMin="0.000000"
   hdrgm:GainMapMax="1.117083"
   hdrgm:HDRCapacityMin="0.000000"
   hdrgm:HDRCapacityMax="1.117083"
   hdrgm:OffsetSDR="0.000000"
   hdrgm:OffsetHDR="0.000000"/>
 </rdf:RDF>
</x:xmpmeta>
 <?xpacket end="w"?> 

MPF.nPhotos is:

   196608    3886064          0          0          0      98874    3815593          0

And we know the two images (greyscale image + movie) are located at:

-start-     -length-
3886588        98874   
3985462      2604886

Only 98874 is correct. The other three numbers seem to be wrong.

Next step. I'll inspect the files with exiftool debugging options.

Here's the greyscale jpg
foo

@clanmills
Copy link
Collaborator

clanmills commented Aug 15, 2024

I've had more thoughts about this. The MPF segment offset/length data is unsafe. When we rewrite the JPG, the segment order is unchanged, however the segment lengths can change, which implies that when a JPG is rewritten, the MPF segment data should be updated. Exiv2 does not support MPF.

The exiv2 rewrite strategy to blindly copy after EOI is good because the additional images/movies will be preserved. That is to say, the additional images/movies are undamaged and lie in sequence after the primary image.

Now that I understand your file, I return to the bug report concerning Xmp.GCamera.MotionPhoto. We know why that doesn't work! It's because it's in the ExtendedXMP segment and not supported by Exiv2.

Your aim is to delete the embedded movie in the file (to save space). Let's suppose we had an option on the exiv2 command to "delete embedded movies". It would have to:

  1. Locate the embedded movies (by searching after EOI)
  2. Remove the movie and update this XMP:
511 rmills@rmillsm1:~/gnu/github/tvisitor/book $ exiv2 -px ~/Desktop/347813082-6f745ba6-4fbd-4d3e-b9e9-98108dbb745d.jpg 
Xmp.hdrgm.Version                            XmpText     3  1.0
Xmp.xmpNote.HasExtendedXMP                   XmpText    32  4679D2A911D710DA7FB6725847403E22
Xmp.GCamera.MotionPhoto                      XmpText     1  1
Xmp.GCamera.MotionPhotoVersion               XmpText     1  1
Xmp.GCamera.MotionPhotoPresentationTimestampUs XmpText     7  1201486
Xmp.Container.Directory                      XmpText     0  type="Seq"
Xmp.Container.Directory[1]                   XmpText     0  type="Struct"
Xmp.Container.Directory[1]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[1]/Container:Item/Item:Semantic XmpText     7  Primary
Xmp.Container.Directory[1]/Container:Item/Item:Mime XmpText    10  image/jpeg
Xmp.Container.Directory[2]                   XmpText     0  type="Struct"
Xmp.Container.Directory[2]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[2]/Container:Item/Item:Semantic XmpText     7  GainMap
Xmp.Container.Directory[2]/Container:Item/Item:Mime XmpText    10  image/jpeg
Xmp.Container.Directory[2]/Container:Item/Item:Length XmpText     5  98874
Xmp.Container.Directory[3]                   XmpText     0  type="Struct"
Xmp.Container.Directory[3]/Container:Item    XmpText     0  type="Struct"
Xmp.Container.Directory[3]/Container:Item/Item:Mime XmpText     9  video/mp4
Xmp.Container.Directory[3]/Container:Item/Item:Semantic XmpText    11  MotionPhoto
Xmp.Container.Directory[3]/Container:Item/Item:Length XmpText     7  2604886
Xmp.Container.Directory[3]/Container:Item/Item:Padding XmpText     1  0
512 rmills@rmillsm1:~/gnu/github/tvisitor/book $ 
  1. Locate and update the MPF segment.

Exiv2 cannot delete embedded movies. May I ask you to close this issue?

@clanmills clanmills added enhancement feature / functionality enhancements and removed bug labels Aug 15, 2024
@arty-name
Copy link
Author

Thank you for looking into this, Robin!

That’s fair, an unsupported feature is definitely not a bug.

@clanmills
Copy link
Collaborator

@arty-name Tom: Thank you for logging this interesting matter. I'm surprised to learn that JPG files may contain embedded movies and HDR Gain Maps. I'm going to update my book with this discovery.

I'm going to put the book and utilities (tvisitor and dmpf) on GitHub. When I wrote it, the code was on the Exiv2 SVN repository which was abandoned when the exiv2.org server was rehosted. That code is useful for debugging files. One day somebody will discover and appreciate the value. AFIK, it's the only book ever written about how metadata is stored in images.

@arty-name
Copy link
Author

This way of extending JPGs was a total surprise to me as well!

It’s great to have a central place documenting data formats like these, especially when it’s kept up-to date.

I vaguely remember the existence of tools for converting the SVN commit history into git. Such history could be quite valuable.

@clanmills
Copy link
Collaborator

All code going into Exiv2 on GitHub has to be reviewed/approved by other team members. I put the book into SVN to avoid that. When we changed the host for exiv2.org, the SVN repository didn't move. I'll open a new repository on github and put the book there.

Image file formats are a software nightmare. Exiv2 and tvisitor support 18 different formats (TIFF, JPG, PNG etc). What's the difference? We've had several efforts to kill JPEG (for example: JP2000, WebP, JXL, HEIF). All different and none have displaced JPEG. Canon have three different RAW formats (CRW, CR2 and CR3).

A JPEG file is a linked list of segments. Adobe added transparency to JPEG about 20 years ago using a clippath segment. Adding capability, by extension, seems better than inventing new formats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement feature / functionality enhancements
Projects
None yet
Development

No branches or pull requests

2 participants