DNG: adding preview success but no record in exif SubIFD1

Started by whatdoido, November 09, 2023, 01:22:15 PM

Previous topic - Next topic

whatdoido

Using exiftool-12.69 on Linux/Fedora 35 (directly downloaded from exiftool, perl 5.34.1)

I am using iphone appl Halide that generates DNG.  Running the exiftool appears to work but when I examine the updated file, there appears to be no corresponding preview image (exiv2 -pp states the same) show in the metadata, however I can use exiftool to extract the preview image.

I see Phil's response to a 2021 request/report by me: https://exiftool.org/forum/index.php?topic=12063.msg65176#msg65176 that notes that "ExifTool will not add a PreviewImage to a file that didn't have one."

Is this the same issue?  In this case, it appears exiftool added the preview to a DNG that beleives it had one small 512x384 preview image.

$ identify random.jpg
random.jpg JPEG 3000x2000 3000x2000+0+0 8-bit sRGB 202326B 0.000u 0:00.000

$ exiftool -v4 "-previewImage<=random.jpg" -tagsfromfile random.jpg "-subifd1:imagewidth<imagewidth" "-subifd1:imageheight<imageheight" halide.dng
Writing All:PreviewImage (+PreviewImageLength,+PreviewImageStart,+PreviewImageValid):
+Writing Canon:PreviewImageLength if tag exists
+Writing Casio:PreviewImageLength if tag exists
+Writing IFD0:PreviewImageLength if tag exists
+Writing Minolta:PreviewImageLength if tag exists
+Writing PreviewIFD:PreviewImageLength if tag exists
+Writing Olympus:PreviewImageLength if tag exists
+Writing Olympus:PreviewImageLength if tag exists
+Writing Pentax:PreviewImageLength if tag exists
+Writing Ricoh:PreviewImageLength if tag exists
+Writing Samsung:PreviewImageLength if tag exists
+Writing Sigma:PreviewImageLength if tag exists
+Writing Sigma:PreviewImageLength if tag exists
+Writing Sony:PreviewImageLength if tag exists
+Writing IFD0:PreviewImageLength if tag exists
+Writing All:PreviewImageLength if tag exists
+Writing IFD0:PreviewImageLength if tag exists
+Writing Canon:PreviewImageStart if tag exists
+Writing Casio:PreviewImageStart if tag exists
+Writing IFD0:PreviewImageStart if tag exists
+Writing Minolta:PreviewImageStart if tag exists
+Writing PreviewIFD:PreviewImageStart if tag exists
+Writing Olympus:PreviewImageStart if tag exists
+Writing Olympus:PreviewImageStart if tag exists
+Writing Pentax:PreviewImageStart if tag exists
+Writing Ricoh:PreviewImageStart if tag exists
+Writing Samsung:PreviewImageStart if tag exists
+Writing Sigma:PreviewImageStart if tag exists
+Writing Sigma:PreviewImageStart if tag exists
+Writing Sony:PreviewImageStart if tag exists
+Writing IFD0:PreviewImageStart if tag exists
+Writing All:PreviewImageStart if tag exists
+Writing IFD0:PreviewImageStart if tag exists
+Writing Olympus:PreviewImageValid if tag exists
+Writing Olympus:PreviewImageValid if tag exists
Writing FotoStation:PreviewImage if tag exists
Writing MIE-Preview:PreviewImage
Writing UserData:PreviewImage
Writing Casio:PreviewImage if tag exists
Writing Minolta:PreviewImage if tag exists
Writing Olympus:PreviewImage if tag exists
Writing Leica:PreviewImage if tag exists
Writing Sony:PreviewImage if tag exists
Writing All:PreviewImage
Setting new values from random.jpg
Writing SubIFD1:ImageWidth
Writing SubIFD1:ImageHeight
======== halide.dng
Rewriting halide.dng...
  Editing tags in: All ExifIFD FotoStation IFD0 MIE-Preview MakerNotes SubIFD1 TIFF UserData
  Creating tags in: All MIE-Preview SubIFD1 UserData
  FileType = DNG
  FileTypeExtension = DNG
  MIMEType = image/x-adobe-dng
  Rewriting IFD0
    - IFD0:PreviewImageStart = '10951174'
    + IFD0:PreviewImageStart = <tbd>
    - IFD0:PreviewImageLength = '72470'
    + IFD0:PreviewImageLength = <tbd>
  Rewriting SubIFD
    [nothing changed in SubIFD]
  Rewriting ExifIFD
  Rewriting MakerNoteApple
    [nothing changed in MakerNoteApple]
    [nothing changed in ExifIFD]
  Copying 64 image data blocks
    1 image files updated

$ exiftool -previewimage -b -w %f_preview.jpg halide.dng
    1 output files created

$ cksum halide_preview.jpg random.jpg
3679013453 202326 halide_preview.jpg
3679013453 202326 random.jpg

I am expecting to find an entry in SubIFD1 with the correspoding image width/height and preview image length

$ exiftool -v2 halide.dng
  ExifToolVersion = 12.69
  FileName = halide.dng
  Directory = .
  FileSize = 11153500
  FileModifyDate = 1699553732
  FileAccessDate = 1699553780
  FileInodeChangeDate = 1699553732
  FilePermissions = 33188
  FileType = DNG
  FileTypeExtension = DNG
  MIMEType = image/x-adobe-dng
  ExifByteOrder = MM
  + [IFD0 directory with 27 entries]
  | 0)  SubfileType = 1
  |     - Tag 0x00fe (4 bytes, int32u[1])
  | 1)  ImageWidth = 512
  |     - Tag 0x0100 (4 bytes, int32u[1])
  | 2)  ImageHeight = 384
  |     - Tag 0x0101 (4 bytes, int32u[1])
  | 3)  BitsPerSample = 8 8 8
  |     - Tag 0x0102 (6 bytes, int16u[3])
  | 4)  Compression = 7
  |     - Tag 0x0103 (2 bytes, int16u[1])
  | 5)  PhotometricInterpretation = 6
  |     - Tag 0x0106 (2 bytes, int16u[1])
  | 6)  Make = Apple
  |     - Tag 0x010f (6 bytes, string[6])
  | 7)  Model = iPhone 7
  |     - Tag 0x0110 (9 bytes, string[9])
  | 8)  PreviewImageStart = 1986
  |     - Tag 0x0111 (4 bytes, int32u[1])
  | 9)  Orientation = 1
  |     - Tag 0x0112 (2 bytes, int16u[1])
  | 10) SamplesPerPixel = 3
  |     - Tag 0x0115 (2 bytes, int16u[1])
  | 11) RowsPerStrip = 384
  |     - Tag 0x0116 (4 bytes, int32u[1])
  | 12) PreviewImageLength = 202326
  |     - Tag 0x0117 (4 bytes, int32u[1])
  | 13) Software = 15.7.9
  |     - Tag 0x0131 (7 bytes, string[7])
  | 14) ModifyDate = 2023:11:09 17:30:21
  |     - Tag 0x0132 (20 bytes, string[20])
  | 15) SubIFD (SubDirectory) -->
  |     - Tag 0x014a (4 bytes, int32u[1])
  | + [SubIFD directory with 20 entries]
  | | 0)  SubfileType = 0
  | |     - Tag 0x00fe (4 bytes, int32u[1])
  | | 1)  ImageWidth = 4032
  | |     - Tag 0x0100 (4 bytes, int32u[1])
  | | 2)  ImageHeight = 3024
  | |     - Tag 0x0101 (4 bytes, int32u[1])
  | | 3)  BitsPerSample = 16
  | |     - Tag 0x0102 (2 bytes, int16u[1])
  | | 4)  Compression = 7
  | |     - Tag 0x0103 (2 bytes, int16u[1])
  | | 5)  PhotometricInterpretation = 32803
  | |     - Tag 0x0106 (2 bytes, int16u[1])
  | | 6)  SamplesPerPixel = 1
  | |     - Tag 0x0115 (2 bytes, int16u[1])
  | | 7)  PlanarConfiguration = 1
  | |     - Tag 0x011c (2 bytes, int16u[1])
  | | 8)  TileWidth = 504
  | |     - Tag 0x0142 (4 bytes, int32u[1])
  | | 9)  TileLength = 378
  | |     - Tag 0x0143 (4 bytes, int32u[1])
  | | 10) TileOffsets = 204312 384530 552784 721187 888925 1054948 1218696 1380843 1543[snip]
  | |     - Tag 0x0144 (256 bytes, int32u[64])
  | | 11) TileByteCounts = 180218 168254 168403 167738 166023 163748 162147 162404 1792[snip]
  | |     - Tag 0x0145 (256 bytes, int32u[64])
  | | 12) CFARepeatPatternDim = 2 2
  | |     - Tag 0x828d (4 bytes, int16u[2])
  | | 13) CFAPattern2 = 0 1 1 2
  | |     - Tag 0x828e (4 bytes, int8u[4])
  | | 14) CFAPlaneColor = 0 1 2
  | |     - Tag 0xc616 (3 bytes, int8u[3])
  | | 15) BlackLevelRepeatDim = 1 1
  | |     - Tag 0xc619 (4 bytes, int16u[2])
  | | 16) BlackLevel = 528
  | |     - Tag 0xc61a (2 bytes, int16u[1])
  | | 17) WhiteLevel = 4095
  | |     - Tag 0xc61d (2 bytes, int16u[1])
  | | 18) OpcodeList3 = ....8@..}..M....F..3@4..w>.|.;.SF..9@).V..'.?.?.
  | |     - Tag 0xc74e (76 bytes, undef[76])
  | | 19) NoiseProfile = 0.00022907125201 5.4902581969e-06
  | |     - Tag 0xc761 (16 bytes, double[2])
  | 16) ExifOffset (SubDirectory) -->
  |     - Tag 0x8769 (4 bytes, int32u[1])
  | + [ExifIFD directory with 30 entries]
  | | 0)  ExposureTime = 0.05882352941 (1/17)
  | |     - Tag 0x829a (8 bytes, rational64u[1])
  | | 1)  FNumber = 1.8 (9/5)
  | |     - Tag 0x829d (8 bytes, rational64u[1])
  | | 2)  ExposureProgram = 2
  | |     - Tag 0x8822 (2 bytes, int16u[1])
  | | 3)  ISO = 400
  | |     - Tag 0x8827 (2 bytes, int16u[1])
  | | 4)  ExifVersion = 0232
  | |     - Tag 0x9000 (4 bytes, undef[4])
  | | 5)  DateTimeOriginal = 2023:11:09 17:30:21
  | |     - Tag 0x9003 (20 bytes, string[20])
  | | 6)  CreateDate = 2023:11:09 17:30:21
  | |     - Tag 0x9004 (20 bytes, string[20])
  | | 7)  OffsetTime = Z
  | |     - Tag 0x9010 (2 bytes, string[2])
  | | 8)  OffsetTimeOriginal = Z
  | |     - Tag 0x9011 (2 bytes, string[2])
  | | 9)  OffsetTimeDigitized = Z
  | |     - Tag 0x9012 (2 bytes, string[2])
  | | 10) ShutterSpeedValue = 4.060698186 (38735/9539)
  | |     - Tag 0x9201 (8 bytes, rational64s[1])
  | | 11) ApertureValue = 1.695993813 (54823/32325)
  | |     - Tag 0x9202 (8 bytes, rational64u[1])
  | | 12) BrightnessValue = -1.644211372 (-196429/119467)
  | |     - Tag 0x9203 (8 bytes, rational64s[1])
  | | 13) ExposureCompensation = 0 (0/1)
  | |     - Tag 0x9204 (8 bytes, rational64s[1])
  | | 14) MeteringMode = 5
  | |     - Tag 0x9207 (2 bytes, int16u[1])
  | | 15) Flash = 16
  | |     - Tag 0x9209 (2 bytes, int16u[1])
  | | 16) FocalLength = 3.99 (399/100)
  | |     - Tag 0x920a (8 bytes, rational64u[1])
  | | 17) SubjectArea = 2015 1511 2217 1330
  | |     - Tag 0x9214 (8 bytes, int16u[4])
  | | 18) SubSecTimeOriginal = 200
  | |     - Tag 0x9291 (4 bytes, string[4])
  | | 19) SubSecTimeDigitized = 200
  | |     - Tag 0x9292 (4 bytes, string[4])
  | | 20) ExifImageWidth = 4032
  | |     - Tag 0xa002 (4 bytes, int32u[1])
  | | 21) ExifImageHeight = 3024
  | |     - Tag 0xa003 (4 bytes, int32u[1])
  | | 22) SensingMethod = 2
  | |     - Tag 0xa217 (2 bytes, int16u[1])
  | | 23) SceneType = 1
  | |     - Tag 0xa301 (1 bytes, undef[1])
  | | 24) ExposureMode = 0
  | |     - Tag 0xa402 (2 bytes, int16u[1])
  | | 25) WhiteBalance = 0
  | |     - Tag 0xa403 (2 bytes, int16u[1])
  | | 26) FocalLengthIn35mmFormat = 28
  | |     - Tag 0xa405 (2 bytes, int16u[1])
  | | 27) LensInfo = 3.99000001 3.99000001 1.8 1.8 (4183519/1048501 4183519/1048501 9/5 9/5)
  | |     - Tag 0xa432 (32 bytes, rational64u[4])
  | | 28) LensMake = Apple
  | |     - Tag 0xa433 (6 bytes, string[6])
  | | 29) LensModel = iPhone 7 back camera 3.99mm f/1.8
  | |     - Tag 0xa434 (34 bytes, string[34])
  | 17) DNGVersion = 1 3 0 0
  |     - Tag 0xc612 (4 bytes, int8u[4])
  | 18) DNGBackwardVersion = 1 3 0 0
  |     - Tag 0xc613 (4 bytes, int8u[4])
  | 19) UniqueCameraModel = iPhone9,3 back camera
  |     - Tag 0xc614 (22 bytes, string[22])
  | 20) ColorMatrix1 = 0.960891664 -0.3389831483 -0.1510143578 -0.5156005025 1.49590683[snip]
  |     - Tag 0xc621 (72 bytes, rational64s[9])
  | 21) ColorMatrix2 = 0.7027078867 -0.2211241722 -0.06593866646 -0.4639235735 1.217428[snip]
  |     - Tag 0xc622 (72 bytes, rational64s[9])
  | 22) AsShotNeutral = 0.5637990236 1 0.3646399081 (605374592/1073741824 1073741824/10[snip]
  |     - Tag 0xc628 (24 bytes, rational64u[3])
  | 23) BaselineExposure = 0.4701086879 (504775360/1073741824)
  |     - Tag 0xc62a (8 bytes, rational64s[1])
  | 24) CalibrationIlluminant1 = 17
  |     - Tag 0xc65a (2 bytes, int16u[1])
  | 25) CalibrationIlluminant2 = 21
  |     - Tag 0xc65b (2 bytes, int16u[1])
  | 26) NoiseReductionApplied = undef (0/0)
  |     - Tag 0xc6f7 (8 bytes, rational64u[1])

The DNG is 11mb so unable to upload directly but below is the MS onedrive link to the dng file with the embedded jpg attached.  The GPS and apple makernotes were removed ahead of the test above - same results on the file straight off the iphone.

https://1drv.ms/i/c/af953de1d58a6f5f/EdodwL9inxpOuctFyeQNOWABQRQJ2LbNgmY0d5C0uBo-JQ?e=dk9rrq

Phil Harvey

The DNG you uploaded has 202 kB 3000x2000-pixel JPEG-format PreviewImage stored in IFD0 (however, the ImageWidth and ImageHeight in IFD0 are set incorrectly).  The preview is a wash of colours, while the main image is of a keyboard.  MacOS shows the preview image as the file icon and the keyboard when you open the image.

If I write PreviewImage with ExifTool, MacOS shows the new preview as the file icon.  This is what I would have expected.

It seems that the file you uploaded has already been modified.  It would have been more useful to have the original DNG to start from.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

whatdoido

#2
Thanks Phil.  Yes the embedded preview image is a random colour wash image for testing.  Can you confirm the command I used to embedd the preview image is correct and can you share your command to update/write the preivew image for it to work for your mac?


Below is the attached original DNG minus the GPS stripped using `exiftool '-GPS*=' foo.dng` - if you need the original/out of camera, let me know and I'll email/find another way to share.

https://1drv.ms/i/c/af953de1d58a6f5f/EXoUHym_D5pDqMxvPJPSZ5MBZSm6tl8X8qMhwYtV4xLMSQ?e=rjxQ7M

The original file as one preview image of 512x384.  I wanted to add (or replace) a larger (processed) jpg to the DNG for archive prurposes

Phil Harvey

This command worked for me:

exiftool "-previewimage<=test.jpg" -ifd0:imagewidth=WIDTH_OF_NEW_PREVIEW -ifd0:imageheight=HEIGHT_OF_NEW_PREVIEW FILE.dng

But I wouldn't recommend this procedure for archival purposes.  It works for me with the DNG you provided, but won't work for all DNG layouts.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

whatdoido

Thanks - it looks like we also need to respecify the ifd0:rowsperstrip too but this works now with exiv2 now.

exiftool \
  -v4 "-previewImage<=random.jpg" \
  -tagsfromfile random.jpg \
  "-ifd0:imagewidth<imagewidth" "-ifd0:imageheight<imageheight" "-ifd0:rowsperstrip<imageheight" \
  halide.dng

Phil Harvey

...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).