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

Missing Lens Information for Nikon Z6 + FTZ + F-Mount Lens #1433

Closed
hassec opened this issue Dec 11, 2020 · 10 comments
Closed

Missing Lens Information for Nikon Z6 + FTZ + F-Mount Lens #1433

hassec opened this issue Dec 11, 2020 · 10 comments
Labels
lens Issue related to lens detection

Comments

@hassec
Copy link
Member

hassec commented Dec 11, 2020

Describe the bug

The problem I encountered is trying to get lens info out of an image file produced with a Nikon Z6 + FTZ Adapter + 70-200mm f2.8/G IF ED VR

❯ exiv2 -pt --grep Lens CH0_0140.NEF
Exif.Nikon3.LensType                         Byte        1  D G VR
Exif.Nikon3.Lens                             Rational    4  70-200mm F2.8
Exif.Nikon3.LensFStops                       Undefined   4  6
Exif.Nikon3.LensData                         Undefined 108  48 56 48 49 189 42 43 240 44 217 10 107 129 69 232 21 173 104 130 64 47 23 15 206 202 144 73 47 215  ...
Exif.Photo.LensSpecification                 Rational    4  700/10 2000/10 280/100 280/100
Exif.Photo.LensMake                          Ascii       6  
Exif.Photo.LensModel                         Ascii      65  
Exif.Photo.LensSerialNumber                  Ascii      11  

Compared to a picture taken with a native Z mount lens:

Exif.Nikon3.LensType                         Byte        1  (0)
Exif.Nikon3.Lens                             Rational    4  24-70mm F4
Exif.Nikon3.LensFStops                       Undefined   4  5
Exif.Nikon3.LensData                         Undefined 108  48 56 48 49 149 240 134 87 99 170 44 233 225 20 130 43 15 46 136 29 237 248 62 191 123 114 164 17 18 ...
Exif.Photo.LensSpecification                 Rational    4  240/10 700/10 400/100 400/100
Exif.Photo.LensMake                          Ascii       6  NIKON
Exif.Photo.LensModel                         Ascii      65  NIKKOR Z 24-70mm f/4 S

As you can see it's missing for example LensMake, LensModel, and LensSerialNumber information.

I googled a bit and found this link describing a similar problem in exiftool.

This was fixed in exiftool shortly after in this github commit

And now it produces:

❯ ./exiftool -a -G1 -s "-*lens*" CH0_0140.NEF
[Nikon]         LensType                        : G VR
[Nikon]         Lens                            : 70-200mm f/2.8
[Nikon]         LensFStops                      : 6.00
[Nikon]         LensDataVersion                 : 0801
[Nikon]         LensIDNumber                    : 119
[Nikon]         LensFStops                      : 6.00
[ExifIFD]       LensInfo                        : 70-200mm f/2.8
[ExifIFD]       LensMake                        : 
[ExifIFD]       LensModel                       : 
[ExifIFD]       LensSerialNumber                : 
[Composite]     LensID                          : AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED
[Composite]     LensSpec                        : 70-200mm f/2.8 G VR

which still misses the above mentioned fields but adds LensID and provides a LensIDNumber.

exiv2 fails to produce a LensIDNumber and thus doesn't allow me to workaround missing information with a local config file as is described in the man pages.

Note, I tried with the current release, and build the master and 0.27-maintenance but had the same result for all three versions

To Reproduce
I've provided a file to @clanmills

Expected behavior
Ideally provide LensMake and LensModel but at least a LensIDNumber

Desktop (please complete the following information):

  • OS: Linux
  • Compiler & Version Gcc 10.2
  • Compilation release mode
@hassec hassec added the bug label Dec 11, 2020
@clanmills
Copy link
Collaborator

I think ExifTool knows how to decode LensData and Exiv2 can't decode that.: https://exiv2.org/tags-nikon.html
screenshot_37
There's a binary record of 108 bytes. There's a conversation here about it. Appears to encrypted: https://exiftool.org/forum/index.php?topic=6139.0

567 rmills@rmillsmm-local:~/gnu/github/exiv2/0.27-maintenance $ exiv2 -g lens/i ~/Downloads/CH0_0174.NEF  
Exif.Nikon3.LensType                         Byte        1  D G VR
Exif.Nikon3.Lens                             Rational    4  70-200mm F2.8
Exif.Nikon3.LensFStops                       Undefined   4  6
Exif.Nikon3.LensData                         Undefined 108  48 56 48 49 254 111 102 54 19 20 199 37 85 24 149 218 234 173 199 3 108 90 202 9 133 205 121 108 20 247 21 110 2 209 219 32 160 91 81 130 238 149 119 148 236 127 77 86 154 25 211 200 248 99 9 234 6 93 239 188 196 7 133 62 50 97 203 112 80 107 193 82 30 37 103 228 156 143 189 38 202 169 195 24 168 115 121 186 54 237 223 12 116 23 245 45 98 241 187 192 0 123 49 34 78 181 87 52
Exif.Photo.LensSpecification                 Rational    4  700/10 2000/10 280/100 280/100
Exif.Photo.LensMake                          Ascii       6  
Exif.Photo.LensModel                         Ascii      65  
Exif.Photo.LensSerialNumber                  Ascii      11  
568 rmills@rmillsmm-local:~/gnu/github/exiv2/0.27-maintenance $ 

I'll study this next week.

@clanmills clanmills self-assigned this Dec 11, 2020
@clanmills clanmills added this to the v0.27.4 milestone Dec 11, 2020
@clanmills clanmills added lens Issue related to lens detection and removed bug labels Dec 11, 2020
@clanmills clanmills removed their assignment Dec 14, 2020
@clanmills clanmills removed this from the v0.27.4 milestone Dec 14, 2020
@clanmills
Copy link
Collaborator

clanmills commented Dec 14, 2020

I've looked at this and regret that I cannot help. The main reason is that the data is encrypted and I don't know the algorithm. The other reason is that, after 12 years of working on Exiv2, I intend to retire at the end of 2020. My last working day will be Thursday 2020-12-17. I have other matters I'd like to finish before Thursday.

However, here's what I have discovered in looking at your issue.

There is a Nikon decoded in dcraw.c which is really available on the internet. When I run you file with that code it outputs:

515 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ ./parse  /Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens/CH0_0174.NEF | grep 98
tag=0x131 305, type=2, count=13, offset=00000198, data="Ver.03.12...."
tag=0x8298 33432, type=2, count=55, offset=00003228, data="ALL RIGHTS RESERVED...................................."
    tag=0x1b 27, type=3, count=7, offset=00003984, data= 000b 17b0 0fc8 17b0 0fc8 0000 0000
    tag=0x98 152, type=7, count=108, offset=00012748, data=
    tag=0xc0 192, type=7, count=8, offset=00012984, data= 3c 01 0c 00 a8 01 0c 00
  tag=0xa401 41985, type=3, count=1, offset=000033aa, data= 0001
  tag=0xa402 41986, type=3, count=1, offset=000033b6, data= 0000
  tag=0xa403 41987, type=3, count=1, offset=000033c2, data= 0000
  tag=0xa405 41989, type=3, count=1, offset=000033ce, data= 0066
tag=0x9216 37398, type=1, count=4, offset=00000156, data= 01 00 00 00
516 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ 

As you can see, it located tag 0x98 of 108 bytes at offset 00012748. My tvisitor program locates that also:

517 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ ./tvisitor  -pRU /Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens/CH0_0174.NEF | grep -e 0x98 -e STR
STRUCTURE OF TIFF FILE (II): /Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens/CH0_0174.NEF
...
    STRUCTURE OF TIFF FILE (II): /Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens/CH0_0174.NEF:13690->73846
         718 | 0x0098 Exif.Nikon.0x98              | UNDEFINED |      108 |     61902 | 0801.of6...%U.......lZ....yl...n...  +++
  STRUCTURE OF TIFF FILE (II): /Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens/CH0_0174.NEF
518 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ 

And I can correctly locate the data as follows:

519 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ dmpf '/Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens/CH0_0174.NEF:13690->73846' count=108 skip=61902
  0xf1ce    61902: 0801.of6...%U.......lZ....yl...n  ->  30 38 30 31 fe 6f 66 36 13 14 c7 25 55 18 95 da ea ad c7 03 6c 5a ca 09 85 cd 79 6c 14 f7 15 6e
  0xf1ee    61934: ... .[Q...w...MV.....c...].....>  ->  02 d1 db 20 a0 5b 51 82 ee 95 77 94 ec 7f 4d 56 9a 19 d3 c8 f8 63 09 ea 06 5d ef bc c4 07 85 3e
  0xf20e    61966: 2a.pPk.R.%g....&.....sy.6...t..-  ->  32 61 cb 70 50 6b c1 52 1e 25 67 e4 9c 8f bd 26 ca a9 c3 18 a8 73 79 ba 36 ed df 0c 74 17 f5 2d
  0xf22e    61998: b..._{1"N.W4                      ->  62 f1 bb c0 00 7b 31 22 4e b5 57 34
520 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $

When I run your file with ExifTool -v5, we see:

  | | | 59) LensDataUnknown (SubDirectory) -->
  | | |     - Tag 0x0098 (108 bytes, undef[108]):
  | | |        12748: 30 38 30 31 fe 6f 66 36 13 14 c7 25 55 18 95 da [0801.of6...%U...]
  | | |        12758: ea ad c7 03 6c 5a ca 09 85 cd 79 6c 14 f7 15 6e [....lZ....yl...n]
  | | |        12768: 02 d1 db 20 a0 5b 51 82 ee 95 77 94 ec 7f 4d 56 [... .[Q...w...MV]
  | | |        12778: 9a 19 d3 c8 f8 63 09 ea 06 5d ef bc c4 07 85 3e [.....c...].....>]
  | | |        12788: 32 61 cb 70 50 6b c1 52 1e 25 67 e4 9c 8f bd 26 [2a.pPk.R.%g....&]
  | | |        12798: ca a9 c3 18 a8 73 79 ba 36 ed df 0c 74 17 f5 2d [.....sy.6...t..-]
  | | |        127a8: 62 f1 bb c0 00 7b 31 22 4e b5 57 34             [b....{1"N.W4]
  | | | + [Decrypted LensDataUnknown directory]
  | | | |       0000: 30 38 30 31 0e 24 87 84 ad 11 40 61 69 77 48 5c [0801.$....@aiwH\]
  | | | |       0010: 80 24 24 7b 24 09 53 13 53 00 86 00 00 00 00 00 [.$${$.S.S.......]
  | | | |       0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
  | | | |       0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
  | | | |       0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [................]
  | | | |       0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 23 [...............#]
  | | | |       0060: 00 00 00 00 00 00 00 00 00 00 00 00             [............]

I've looked up the ExifTool code in Nikon.pm and it is:

#------------------------------------------------------------------------------
# decoding tables from ref 4
my @xlat = (
  [ 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d,
    0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d,
    0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f,
    0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f,
    0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1,
    0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17,
    0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89,
    0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f,
    0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b,
    0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb,
    0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3,
    0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f,
    0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35,
    0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43,
    0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5,
    0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 ],
  [ 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c,
    0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34,
    0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad,
    0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05,
    0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee,
    0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d,
    0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b,
    0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b,
    0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc,
    0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33,
    0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8,
    0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6,
    0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c,
    0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49,
    0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb,
    0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f ]
);

# Decrypt Nikon data block (ref 4)
# Inputs: 0) reference to data block, 1) serial number key, 2) shutter count key
#         4) optional start offset (default 0)
#         5) optional number of bytes to decode (default to the end of the data)
# Returns: data block with specified data decrypted
sub Decrypt($$$;$$)
{
    my ($dataPt, $serial, $count, $start, $len) = @_;
    my ($i, $dat);

    $start or $start = 0;
    my $maxLen = length($$dataPt) - $start;
    $len = $maxLen if not defined $len or $len > $maxLen;
    return $$dataPt if $len <= 0;
    my $key = 0;
    for ($i=0; $i<4; ++$i) {
        $key ^= ($count >> ($i*8)) & 0xff;
    }
    my $ci = $xlat[0][$serial & 0xff];
    my $cj = $xlat[1][$key];
    my $ck = 0x60;
    my @data = unpack("x${start}C$len", $$dataPt);
    foreach $dat (@data) {
        $cj = ($cj + $ci * $ck) & 0xff;
        $ck = ($ck + 1) & 0xff;
        $dat ^= $cj;
    }
    my $end = $start + $len;
    my $pre = $start ? substr($$dataPt, 0, $start) : '';
    my $post = $end < length($$dataPt) ? substr($$dataPt, $end) : '';
    return $pre . pack('C*',@data) . $post;
}

@hassec
Copy link
Member Author

hassec commented Dec 14, 2020

Thanks for having a look @clanmills.
I only see an empty markdown code box for the output above though, is it maybe missing something?

@clanmills
Copy link
Collaborator

I clicked the "comment" button in error. You can read about it now!

@clanmills
Copy link
Collaborator

clanmills commented Dec 14, 2020

I see ExifTool references the decryption at: 4) http://www.cybercom.net/~dcoffin/dcraw/. It's rather odd that my version of that code does not decode that data. Oh well, somebody's going to have fun with this.

@clanmills
Copy link
Collaborator

clanmills commented Dec 17, 2020

The latest version of Dave's code is here and has the code to decrypt 0x98: https://github.com/ncruces/dcraw/blob/master/parse.c

The decrypter requires the serial number which is stored in the MakerNote.

864 rmills@rmillsmm-local:/Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens $ exiv2 -pv --unknown CH0_0174.NEF | grep 1d
0x001d Nikon3       SerialNumber                Ascii       8  6078248
865 rmills@rmillsmm-local:/Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens $ 

And the LensData is:

865 rmills@rmillsmm-local:/Users/Shared/Jenkins/Home/userContent/testfiles/Exiv2/NikonLens $ exiv2 -pv --unknown CH0_0174.NEF | grep LensData
0x0098 Nikon3       LensData                    Undefined 108  48 56 48 49 254 111 102 54 19 20 199 37 85 24 149 218 234 173

So fixing this doesn't look very difficult. However, I'm now retired. Somebody else will have to deal with this.

@clanmills
Copy link
Collaborator

Good News:

I've added the nikon_decrypt() function from parse.c to the tvisitor.cpp code in my book. At the moment, it is not successfully decrypting the data because the function expects the data to start "02" and it starts "08". Puzzling. Some debugging in parse.c and I'll probably solve that.

As far as Exiv2 is concerned, I am retired and will not be submit code in future. However, I want the book to deal with everything I know about Exiv2 to help a future maintainer to understand the code (which is non-trivial). Currently in the book, I say:

Metadata is occasionally compressed (PNG), encrypted (Nikon) or ciphered (Sony).

I'm happy to develop the decryption and document it in my book. The ciphered code for Sony is discussed here: #906 and is the mostly complex change I every made to Exiv2. It is discussed in the book. I'll solve nikon_decrypt() and document/discuss it in the book.

Not so happy news:

I'm disappointed that no member of the Community has shown any interest in becoming the maintainer of Exiv2. I've done everything I can to leave the project in a clean and tidy state and my book explains everything I know about Metadata and Exiv2. https://clanmills.com/exiv2/book/

I will support, mentor and encourage somebody to maintain Exiv2. At this moment, it seems unlikely! However, Exiv2 is a unique and critical resource to the Open Source Graphics Community, and I expect a maintainer will volunteer in 2021. I intend to give a presentation at LGM in Rennes in May 2021 and to run an afternoon workshop based on my book.

https://discuss.pixls.us/t/maintainer-urgently-needed-for-exiv2/21547

So now I leave, with my head held high

I remain optimistic about the future of Exiv2. Don't think that I will change my mind and return from retirement. I have to retire some day and that day is ..... today.

@clanmills
Copy link
Collaborator

Success!

1022 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ ./tvisitor -pR ../files/CH0_0174.NEF | grep LensIDNumber
         187 | 0x00a7 Exif.Nikon.LdLensIDNumber    |     UBYTE |        1 |           | 119
1023 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ exiftool -a -G1 -s "-*lens*" ../files/CH0_0174.NEF | grep LensIDNumber
[Nikon]         LensIDNumber                    : 119
1024 rmills@rmillsmm-local:~/gnu/exiv2/team/book/build $ 

@hassec
Copy link
Member Author

hassec commented Jan 4, 2021

@clanmills should we close this issue, since it's now supported in the maintenance branch?

@hassec hassec closed this as completed Jan 11, 2021
@clanmills
Copy link
Collaborator

Yip. Close it.

We had the meeting with the darktable (and rawspeed) people on Saturday and we have a plan for v0.27.4. The meeting notes are on the chat-server and I'll update the Exiv2 RoadMap today.

One day, there will be a 0.28 release from 'master'. This feature and about 100 PRs will have to merged from 0.27-maintenance into master. Who will do this and when will that happen? I have no idea. If everybody behaved as you have, everything will be fine and a new maintainer will appear to make this happen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lens Issue related to lens detection
Projects
None yet
Development

No branches or pull requests

2 participants