1 /* Copyright (C) 2005-2011 Fabio Riccardi */
2 
3 package com.lightcrafts.image.metadata.makernotes;
4 
5 import java.awt.image.RenderedImage;
6 import java.io.IOException;
7 import java.util.Arrays;
8 import java.util.HashMap;
9 import java.util.Map;
10 import java.util.ResourceBundle;
11 import java.util.regex.Matcher;
12 import java.util.regex.Pattern;
13 
14 import com.lightcrafts.image.ImageInfo;
15 import com.lightcrafts.image.BadImageFileException;
16 import com.lightcrafts.image.metadata.ImageMetadataDirectory;
17 import com.lightcrafts.image.metadata.ImageMetaTagInfo;
18 import com.lightcrafts.image.metadata.ImageMetaType;
19 import com.lightcrafts.image.metadata.ImageMetaTags;
20 import com.lightcrafts.image.metadata.providers.*;
21 import com.lightcrafts.image.metadata.values.*;
22 import com.lightcrafts.image.types.NEFImageType;
23 import com.lightcrafts.image.UnknownImageTypeException;
24 import com.lightcrafts.utils.bytebuffer.LCByteBuffer;
25 import com.lightcrafts.utils.NumberUtil;
26 import com.lightcrafts.utils.TextUtil;
27 
28 import static com.lightcrafts.image.metadata.makernotes.NikonConstants.*;
29 import static com.lightcrafts.image.metadata.makernotes.NikonTags.*;
30 import static com.lightcrafts.image.metadata.ImageMetaType.*;
31 import static com.lightcrafts.image.types.TIFFConstants.*;
32 
33 /**
34  * A <code>NikonDirectory</code> is-an {@link ImageMetadataDirectory} for
35  * holding Nikon-specific maker-note metadata.
36  *
37  * @author Paul J. Lucas [paul@lightcrafts.com]
38  */
39 @SuppressWarnings({"CloneableClassWithoutClone"})
40 public final class NikonDirectory extends MakerNotesDirectory implements
41     FocalLengthProvider, ISOProvider, PreviewImageProvider {
42 
43     ////////// public /////////////////////////////////////////////////////////
44 
45     /**
46      * {@inheritDoc}
47      */
48     @Override
getFocalLength()49     public float getFocalLength() {
50         final ImageMetaValue value = getValue( NIKON_LD21_FOCAL_LENGTH );
51         return value != null ? value.getFloatValue() : 0;
52     }
53 
54     /**
55      * {@inheritDoc}
56      */
57     @Override
getISO()58     public int getISO() {
59         ImageMetaValue value = getValue( NIKON_ISO );
60         if ( value == null )
61             value = getValue( NIKON_ISO_D70 );
62         if ( value == null )
63             value = getValue( NIKON_ISO_D70_2 );
64         if ( value == null )
65             value = getValue( NIKON_II_ISO2 );
66         if ( value == null )
67             value = getValue( NIKON_II_ISO );
68         return value != null ? value.getIntValue() : 0;
69     }
70 
71     /**
72      * {@inheritDoc}
73      */
74     @Override
getLens()75     public String getLens() {
76         final ImageMetaValue value = getValue(NIKON_LENS);
77         if (value != null) {
78             final String name = valueToString(value);
79             if (name != null) {
80                 return name;
81             }
82         }
83         return super.getLens();
84     }
85 
86     /**
87      * Gets the maker-notes adjustments for Nikon.
88      *
89      * @param buf The {@link LCByteBuffer} the metadata is in.
90      * @param offset The offset to adjust.
91      * @return If the maker-notes are either versions 1 or 2, returns said
92      * adjustments; otherwise returns <code>null</code>.
93      */
94     @Override
getMakerNotesAdjustments( LCByteBuffer buf, int offset )95     public int[] getMakerNotesAdjustments( LCByteBuffer buf, int offset )
96         throws IOException
97     {
98         final byte[] header = buf.getBytes( offset, 7 );
99         if ( Arrays.equals( header, "Nikon\0\2".getBytes( "ASCII" ) ) )
100             return new int[]{
101                 NIKON_MAKER_NOTES_HEADER_SIZE + TIFF_HEADER_SIZE,
102                 offset + NIKON_MAKER_NOTES_HEADER_SIZE
103             };
104         else if ( Arrays.equals( header, "Nikon\0\1".getBytes( "ASCII" ) ) )
105             return new int[]{ TIFF_HEADER_SIZE, 0 };
106         return null;
107     }
108 
109     /**
110      * Gets the name of this directory.
111      *
112      * @return Always returns &quot;Nikon&quot;.
113      */
114     @Override
getName()115     public String getName() {
116         return "Nikon";
117     }
118 
119     /**
120      * {@inheritDoc}
121      */
122     @Override
getPreviewImage( ImageInfo imageInfo, int maxWidth, int maxHeight )123     public RenderedImage getPreviewImage( ImageInfo imageInfo, int maxWidth,
124                                           int maxHeight )
125         throws BadImageFileException, IOException, UnknownImageTypeException
126     {
127         return NEFImageType.INSTANCE.getPreviewImage(
128             imageInfo, maxWidth, maxHeight
129         );
130     }
131 
132     /**
133      * {@inheritDoc}
134      */
135     @Override
getTagInfoFor( Integer id )136     public ImageMetaTagInfo getTagInfoFor( Integer id ) {
137         return m_tagsByID.get( id );
138     }
139 
140     /**
141      * {@inheritDoc}
142      */
143     @Override
getTagInfoFor( String name )144     public ImageMetaTagInfo getTagInfoFor( String name ) {
145         return m_tagsByName.get( name );
146     }
147 
148     /**
149      * Puts a key/value pair into this directory.  Additionally, handle all the
150      * special cases for Nikon.
151      *
152      * @param tagID The metadata tag ID (the key).
153      * @param value The value to put.
154      */
155     @Override
putValue( Integer tagID, ImageMetaValue value )156     public void putValue( Integer tagID, ImageMetaValue value ) {
157 switch_tagID:
158         switch ( tagID ) {
159             case NIKON_ISO:
160             case NIKON_ISO_D70:
161             case NIKON_ISO_D70_2: {
162                 if ( !(value instanceof UnsignedShortMetaValue) ) {
163                     //
164                     // Apparently some Nikon cameras use the ISO tag values for
165                     // other things, e.g., the Nikon Coolpix 3500 has the tag
166                     // for NIKON_ISO_D70 (0x000F) as a string.  Since we
167                     // currently don't know what to do with such cases, ignore
168                     // the metadata.
169                     //
170                     return;
171                 }
172                 final long[] values = ((LongMetaValue)value).getLongValues();
173                 if ( values.length > 1 ) {
174                     //
175                     // The ISO value for some Nikon cameras is actually 2
176                     // integers.  The first always seems to be 0 so remove it.
177                     //
178                     value = new UnsignedShortMetaValue( (int)values[1] );
179                 }
180                 break;
181             }
182             case NIKON_ISO_INFO: {
183                 final byte[] data = ((UndefinedMetaValue)value).getUndefinedValue();
184                 explodeSubfields( tagID, data, 0 );
185                 return;
186             }
187             case NIKON_II_ISO:
188             case NIKON_II_ISO2: {
189                 final double n = value.getIntValue();
190                 final int iso = (int)(100 * Math.pow( 2, n / 12 - 5 ) + 0.5);
191                 if ( iso <= 0 )
192                     return;
193                 value = new UnsignedLongMetaValue( iso );
194                 break;
195             }
196             case NIKON_LD21_AF_APERTURE:
197             case NIKON_LD21_APERTURE_AT_MIN_FOCAL:
198             case NIKON_LD21_APERTURE_AT_MAX_FOCAL:
199             case NIKON_LD21_EFFECTIVE_MAX_APERTURE: {
200                 final int n = value.getUnsignedByteValue();
201                 value = new FloatMetaValue(
202                     (float)NumberUtil.tenths( Math.pow( 2, n / 24.0 ) )
203                 );
204                 break;
205             }
206             case NIKON_LD21_FOCAL_LENGTH:
207             case NIKON_LD1X_MIN_FOCAL_LENGTH:
208             case NIKON_LD1X_MAX_FOCAL_LENGTH: {
209                 final int n = value.getUnsignedByteValue();
210                 value = new FloatMetaValue(
211                     (float)NumberUtil.tenths( 5 * Math.pow( 2, n / 24.0 ) )
212                 );
213                 break;
214             }
215             case NIKON_LD21_FOCUS_DISTANCE: {
216                 //
217                 // Apparently, the Nikon D70 (at least) already has this as a
218                 // string, so make sure the value is numeric before continuing.
219                 //
220                 if ( value instanceof UnsignedByteMetaValue ) {
221                     final int n = value.getUnsignedByteValue();
222                     value = new StringMetaValue(
223                         TextUtil.tenths( Math.pow( 10, n / 40.0 ) ) + "cm"
224                     );
225                 }
226                 break;
227             }
228             case NIKON_LD21_LENS_FSTOPS: {
229                 final int n = value.getUnsignedByteValue();
230                 value = new FloatMetaValue(
231                     (float)NumberUtil.tenths( n / 12.0 )
232                 );
233                 break;
234             }
235             case NIKON_LENS_DATA: {
236                 final byte[] data =
237                     ((UndefinedMetaValue)value).getUndefinedValue();
238                 final byte[] versionBuf = new byte[4];
239                 System.arraycopy( data, 0, versionBuf, 0, 4 );
240                 final int version =
241                     versionBuf[0] - '0' << 12 |
242                     versionBuf[1] - '0' <<  8 |
243                     versionBuf[2] - '0' <<  4 |
244                     versionBuf[3] - '0';
245                 super.putValue(
246                     NIKON_LD_VERSION, new UnsignedShortMetaValue( version )
247                 );
248                 switch ( version ) {
249                     case 0x0100:
250                     case 0x0101:
251                         //
252                         // Since we support two versions of Nikon lens data, we
253                         // use NIKON_LENS_DATA << 8 | 0x10 for these versions.
254                         //
255                         explodeSubfields( tagID << 8 | 0x10, data, 4 );
256                         break;
257                     case 0x0201:
258                     case 0x0204:
259                         //
260                         // These versions of lens data are encrypted. To decrypt
261                         // it, the serial-number and shutter-count metadata are
262                         // needed but they might not have been encountered yet
263                         // so just increment a counter for now.
264                         //
265                         ++m_decryptCount;
266                         break switch_tagID;
267                 }
268                 return;
269             }
270             case NIKON_LENS_TYPE: {
271                 //
272                 // Apparently, the Nikon D70 (at least) already has this as a
273                 // string, so make sure the value is numeric before continuing.
274                 //
275                 if ( value instanceof UnsignedByteMetaValue ) {
276                     //
277                     // Replace the lens type's bit value with an array of
278                     // labels, one for each '1' bit.
279                     //
280                     final int lensType = value.getUnsignedByteValue();
281                     final String[] labels = explodeBits( tagID, lensType );
282                     value = new StringMetaValue( labels );
283                 }
284                 break;
285             }
286             case NIKON_SERIAL_NUMBER:
287             case NIKON_SHUTTER_COUNT:
288                 ++m_decryptCount;
289                 break;
290             case NIKON_SHOOTING_MODE: {
291                 //
292                 // Apparently, the Nikon D70 (at least) already has this as a
293                 // string, so make sure the value is numeric before continuing.
294                 //
295                 if ( value.isNumeric() ) {
296                     //
297                     // Replace the shooting mode's bit value with an array of
298                     // labels, one for each '1' bit.
299                     //
300                     int shootingMode = value.getIntValue();
301                     if ( (shootingMode & 0x87) == 0 ) {
302                         //
303                         // The ShootingMode is complicated.  Rather than try to
304                         // explain it myself, here's the original comment taken
305                         // from the ExifTool's Nikon.pm file:
306                         //
307                         //      The (new?) bit 5 seriously complicates our life
308                         //      here: after firmware B's 1.03, bit 5 turns on
309                         //      when you ask for BUT DO NOT USE the long-range
310                         //      noise reduction feature, probably because even
311                         //      not using it, it still slows down your drive
312                         //      operation to 50% (1.5fps max not 3fps).  But no
313                         //      longer does !$val alone indicate single-frame
314                         //      operation.
315                         //
316                         if ( shootingMode == 0 )
317                             shootingMode = 1 << 3;  // bit 3 = "single frame"
318                         else
319                             shootingMode |= 1 << 3;
320                     }
321                     final String[] labels = explodeBits( tagID, shootingMode );
322                     value = new StringMetaValue( labels );
323                 }
324                 break;
325             }
326         }
327         super.putValue( tagID, value );
328 
329         if ( m_decryptCount == 3 ) {
330             //
331             // We've got all the pieces needed to decrypt the encrypted lens
332             // data so do it now.
333             //
334             final ImageMetaValue lensDataValue = removeValue(NIKON_LENS_DATA);
335             final ImageMetaValue serialNumberValue = getValue(NIKON_SERIAL_NUMBER);
336             final ImageMetaValue shutterCountValue = getValue(NIKON_SHUTTER_COUNT);
337             if (lensDataValue != null && serialNumberValue != null
338                     && shutterCountValue != null) {
339                 final byte[] lensData =
340                         ((UndefinedMetaValue) lensDataValue).getUndefinedValue();
341                 final long serialNumber = serialNumberValue.getLongValue();
342                 final long shutterCount = shutterCountValue.getLongValue();
343                 decrypt(lensData, 4, serialNumber, shutterCount);
344                 m_decryptCount = Integer.MIN_VALUE; // never do this "if" again
345                 //
346                 // Since we support two version of Nikon lens data, we use
347                 // NIKON_LENS_DATA << 8 | 0x21 for this version.
348                 //
349                 // TODO: support tag version 0x0204
350                 explodeSubfields(NIKON_LENS_DATA << 8 | 0x21, lensData, 4);
351             }
352         }
353     }
354 
355     /**
356      * {@inheritDoc}
357      */
358     @Override
valueToString( ImageMetaValue value )359     public String valueToString( ImageMetaValue value ) {
360         switch ( value.getOwningTagID() ) {
361             case NIKON_CROP_HIGH_SPEED: {
362                 if ( !(value instanceof LongMetaValue) )
363                     return "?";
364                 final long[] v = ((LongMetaValue)value).getLongValues();
365                 if ( v.length != 7 )
366                     return "?";
367                 if ( v[0] == 0 )
368                     return getTagValueLabelFor( NIKON_CROP_HIGH_SPEED, v[0] );
369                 return  v[1] + 'x' + v[2] + " -> " +
370                         v[3] + 'x' + v[4] + " @ " +
371                         v[5] + ',' + v[6];
372             }
373             case NIKON_FLASH_EXPOSURE_BRACKET_VALUE:
374             case NIKON_FLASH_EXPOSURE_COMPENSATION: {
375                 if ( !(value instanceof LongMetaValue) )
376                     return "?";
377                 final long n = value.getLongValue() >>> 24;
378                 return TextUtil.tenths( n / 6.0 );
379             }
380             case NIKON_LD21_FOCAL_LENGTH:
381                 return value.getStringValue() + "mm";   // TODO: localize "mm"
382             case NIKON_LD1X_LENS_ID:
383             case NIKON_LD21_LENS_ID: {
384                 final String label = hasTagValueLabelFor( NIKON_LD1X_LENS_ID );
385                 return label != null ? label : "unknown"; // TODO: localize
386             }
387             case NIKON_LD1X_MAX_FOCAL_LENGTH:
388             case NIKON_LD1X_MIN_FOCAL_LENGTH:
389             case NIKON_LD21_MAX_FOCAL_LENGTH:
390             case NIKON_LD21_MIN_FOCAL_LENGTH: {
391                 final int n = value.getUnsignedByteValue();
392                 return TextUtil.tenths( 5 * Math.pow( 2, n / 24.0 ) ) + "mm"; // TODO: localize
393             }
394             case NIKON_LENS: {
395                 final String lensLabel = makeLensLabelFrom( value );
396                 if ( lensLabel != null )
397                     return lensLabel;
398                 break;
399             }
400             case NIKON_LENS_FSTOPS: {
401                 if ( !(value instanceof UndefinedMetaValue) )
402                     return "?";
403                 final byte[] b = ((UndefinedMetaValue)value).getUndefinedValue();
404                 final float f = b[2] != 0 ? b[0] * (b[1] / (float)b[2]) : 0;
405                 return TextUtil.tenths( f );
406             }
407         }
408         return super.valueToString( value );
409     }
410 
411     ////////// protected //////////////////////////////////////////////////////
412 
413     /**
414      * {@inheritDoc}
415      */
416     @Override
getLensNamesValue()417     protected ImageMetaValue getLensNamesValue() {
418         //
419         // Here, we always use the NIKON_LD1X_LENS_ID tag ID because the
420         // resources file doesn't have the lens labels duplicated for
421         // NIKON_LD21_LENS_ID.  This is done to eliminate redundancy since the
422         // labels are the same for both versions.
423         //
424         return getValue( NIKON_LD1X_LENS_ID );
425     }
426 
427     @Override
getLongFocalValue()428     protected ImageMetaValue getLongFocalValue() {
429         return getLensData( NIKON_LD1X_MAX_FOCAL_LENGTH,
430                             NIKON_LD21_MAX_FOCAL_LENGTH,
431                             NIKON_LD24_MAX_FOCAL_LENGTH );
432     }
433 
434     @Override
getShortFocalValue()435     protected ImageMetaValue getShortFocalValue() {
436         return getLensData( NIKON_LD1X_MIN_FOCAL_LENGTH,
437                             NIKON_LD21_MIN_FOCAL_LENGTH,
438                             NIKON_LD24_MIN_FOCAL_LENGTH );
439     }
440 
441     @Override
getMaxApertureValue()442     protected ImageMetaValue getMaxApertureValue() {
443         return getLensData( NIKON_LD1X_APERTURE_AT_MAX_FOCAL,
444                             NIKON_LD21_EFFECTIVE_MAX_APERTURE,
445                             NIKON_LD24_EFFECTIVE_MAX_APERTURE );
446     }
447 
448     /**
449      * Gets the priority of this directory for providing the metadata supplied
450      * by implementing the given provider interface.
451      * <p>
452      * The priority for {@link ShutterSpeedProvider} for Nikon is the lowest
453      * because it yields weird values.
454      *
455      * @param provider The provider interface to get the priority for.
456      * @return Returns said priority.
457      */
458     @Override
getProviderPriorityFor( Class<? extends ImageMetadataProvider> provider )459     protected int getProviderPriorityFor(
460         Class<? extends ImageMetadataProvider> provider )
461     {
462         return (provider == FocalLengthProvider.class)
463                 ? PROVIDER_PRIORITY_MIN
464                 : super.getProviderPriorityFor( provider );
465     }
466 
467     /**
468      * Get the {@link ResourceBundle} to use for tags.
469      *
470      * @return Returns said {@link ResourceBundle}.
471      */
472     @Override
getTagLabelBundle()473     protected ResourceBundle getTagLabelBundle() {
474         return m_tagBundle;
475     }
476 
477     /**
478      * {@inheritDoc}
479      */
480     @Override
getTagsInterface()481     protected Class<? extends ImageMetaTags> getTagsInterface() {
482         return NikonTags.class;
483     }
484 
485     ////////// private ////////////////////////////////////////////////////////
486 
487     /**
488      * Add the tag mappings.
489      *
490      * @param id The tag's ID.
491      * @param name The tag's name.
492      * @param type The tag's {@link ImageMetaType}.
493      */
add( int id, String name, ImageMetaType type )494     private static void add( int id, String name, ImageMetaType type ) {
495         final ImageMetaTagInfo tagInfo =
496             new ImageMetaTagInfo( id, name, type, false );
497         m_tagsByID.put( id, tagInfo );
498         m_tagsByName.put( name, tagInfo );
499     }
500 
501     /**
502      * Count the number of '1' bits in an integer.
503      *
504      * @param n The integer.
505      * @return Returns the number of '1' bits.
506      */
count1BitsOf( int n )507     private static int count1BitsOf( int n ) {
508         int count = 0;
509         while ( n != 0 ) {
510             ++count;
511             n &= n - 1;
512         }
513         return count;
514     }
515 
516     /**
517      * Decrypt an encrypted data block.
518      *
519      * @param buf The array containing the binary data to be decrypted.
520      * @param offset The offset into <code>buf</code> at which to start.
521      * @param serialNumber The camera serial number.
522      * @param shutterCount The number of photos that have been taken by the
523      * camera.
524      * @see <a href="http://owl.phy.queensu.ca/~phil/exiftool/">ExifTool</a>.
525      */
decrypt( byte[] buf, int offset, long serialNumber, long shutterCount )526     private static void decrypt( byte[] buf, int offset, long serialNumber,
527                                  long shutterCount ) {
528         //
529         // Below is the original Perl code taken from ExifTool:
530         // lib/Image/ExifTool/Nikon.pm Decrypt()
531         //
532 /*
533         my ($dataPt, $serial, $count, $start, $len) = @_;
534         $start or $start = 0;
535         my $end = $len ? $start + $len : length($$dataPt);
536         my $i;
537         my $key = 0;
538         for ($i=0; $i<4; ++$i) {
539             $key ^= ($count >> ($i*8)) & 0xff;
540         }
541         my $ci = $xlat[0][$serial & 0xff];
542         my $cj = $xlat[1][$key];
543         my $ck = 0x60;
544         my @data = unpack('C*',$$dataPt);
545         for ($i=$start; $i<$end; ++$i) {
546             $cj = ($cj + $ci * $ck) & 0xff;
547             $ck = ($ck + 1) & 0xff;
548             $data[$i] ^= $cj;
549         }
550         return pack('C*',@data);
551 */
552         int key = 0;
553         for ( int i = 0; i < 4; ++i )
554             key ^= (shutterCount >>> i * 8) & 0xFF;
555 
556         final int ci = m_decrypt[0][ (int)(serialNumber & 0xFF) ] & 0xFF;
557         int cj = m_decrypt[1][ key ] & 0xFF;
558         int ck = 0x60;
559         for ( int i = offset; i < buf.length; ++i ) {
560             cj = (cj + ci * ck) & 0xFF;
561             ck = (ck + 1) & 0xFF;
562             buf[i] ^= cj;
563         }
564     }
565 
566     /**
567      * &quot;Explode&quot; a tag's value that is a set of bits into an array of
568      * strings where each element is the label for the corresponding bit.
569      *
570      * @param tagID The metadata tag ID.
571      * @param bits The bits to explode.
572      * @return Returns said array.
573      */
explodeBits( int tagID, int bits )574     private String[] explodeBits( int tagID, int bits ) {
575         final int num1Bits = count1BitsOf( bits );
576         final String[] labels = new String[ num1Bits ];
577         for ( int bit = 0, i = 0; bit < 32; ++bit ) {
578             if ( (bits & (1 << bit)) != 0 ) {
579                 //noinspection AssignmentToForLoopParameter
580                 labels[i++] = getTagValueLabelFor( tagID, bit );
581             }
582         }
583         return labels;
584     }
585 
586     /**
587      * &quot;Explode&quot; a tag's value that has subfields into individual
588      * {@link ImageMetaValue}s.
589      *
590      * @param tagID The tag ID of the field to be exploded.
591      * @param buf The array containing the binary data to be exploded.
592      * @param offset The offset into <code>buf</code> at which to start.
593      */
explodeSubfields( int tagID, byte[] buf, int offset )594     private void explodeSubfields( int tagID, byte[] buf, int offset ) {
595         tagID <<= 8;
596         tagID += offset;
597         for ( int i = offset; i < buf.length; ++i )
598             putValue( tagID++, new UnsignedByteMetaValue( buf[i] & 0xFF ) );
599     }
600 
601     /**
602      * Get lens metadata value depending on the version of the lens metadata.
603      *
604      * @param tag0100 The tag ID for versions 0x0100 and 0x0101.
605      * @param tag0201 The tag ID for version 0x0201.
606      * @param tag0204 The tag ID for version 0x0204.
607      * @return Returns the metadata or <code>null</code> if there is no such
608      * metadata.
609      */
getLensData( int tag0100, int tag0201, int tag0204 )610     private ImageMetaValue getLensData( int tag0100, int tag0201, int tag0204 ) {
611         final ImageMetaValue version = getValue( NIKON_LD_VERSION );
612         if ( version != null )
613             switch ( version.getUnsignedShortValue() ) {
614                 case 0x0100: // D100, D1X
615                 case 0x0101: // D70, D70s
616                     return getValue( tag0100 );
617                 case 0x0201: // D200, D2Hs, D2X, D2Xs
618                 case 0x0202: // D40, D40X, D80
619                 case 0x0203: // D300
620                     return getValue( tag0201 );
621                 case 0x0204: // D90, D7000
622                     return getValue( tag0204 );
623                 case 0x0400: // 1J1, 1V1
624                     // TODO:
625                 default:
626                     break;
627             }
628         return null;
629     }
630 
631     /**
632      * A counter used to know when an encrypted data block can be decrypted,
633      * i.e., when all needed metadata has been obtained.
634      * @see #decrypt(byte[],int,long,long shutterCount)
635      */
636     private int m_decryptCount;
637 
638     /**
639      * A two-dimensional table of data used to decrypt encrypted data blocks.
640      * @see #decrypt(byte[],int,long,long shutterCount)
641      */
642     private static final byte[][] m_decrypt = {
643         {
644             (byte)0xc1, (byte)0xbf, (byte)0x6d, (byte)0x0d, (byte)0x59,
645             (byte)0xc5, (byte)0x13, (byte)0x9d, (byte)0x83, (byte)0x61,
646             (byte)0x6b, (byte)0x4f, (byte)0xc7, (byte)0x7f, (byte)0x3d,
647             (byte)0x3d, (byte)0x53, (byte)0x59, (byte)0xe3, (byte)0xc7,
648             (byte)0xe9, (byte)0x2f, (byte)0x95, (byte)0xa7, (byte)0x95,
649             (byte)0x1f, (byte)0xdf, (byte)0x7f, (byte)0x2b, (byte)0x29,
650             (byte)0xc7, (byte)0x0d, (byte)0xdf, (byte)0x07, (byte)0xef,
651             (byte)0x71, (byte)0x89, (byte)0x3d, (byte)0x13, (byte)0x3d,
652             (byte)0x3b, (byte)0x13, (byte)0xfb, (byte)0x0d, (byte)0x89,
653             (byte)0xc1, (byte)0x65, (byte)0x1f, (byte)0xb3, (byte)0x0d,
654             (byte)0x6b, (byte)0x29, (byte)0xe3, (byte)0xfb, (byte)0xef,
655             (byte)0xa3, (byte)0x6b, (byte)0x47, (byte)0x7f, (byte)0x95,
656             (byte)0x35, (byte)0xa7, (byte)0x47, (byte)0x4f, (byte)0xc7,
657             (byte)0xf1, (byte)0x59, (byte)0x95, (byte)0x35, (byte)0x11,
658             (byte)0x29, (byte)0x61, (byte)0xf1, (byte)0x3d, (byte)0xb3,
659             (byte)0x2b, (byte)0x0d, (byte)0x43, (byte)0x89, (byte)0xc1,
660             (byte)0x9d, (byte)0x9d, (byte)0x89, (byte)0x65, (byte)0xf1,
661             (byte)0xe9, (byte)0xdf, (byte)0xbf, (byte)0x3d, (byte)0x7f,
662             (byte)0x53, (byte)0x97, (byte)0xe5, (byte)0xe9, (byte)0x95,
663             (byte)0x17, (byte)0x1d, (byte)0x3d, (byte)0x8b, (byte)0xfb,
664             (byte)0xc7, (byte)0xe3, (byte)0x67, (byte)0xa7, (byte)0x07,
665             (byte)0xf1, (byte)0x71, (byte)0xa7, (byte)0x53, (byte)0xb5,
666             (byte)0x29, (byte)0x89, (byte)0xe5, (byte)0x2b, (byte)0xa7,
667             (byte)0x17, (byte)0x29, (byte)0xe9, (byte)0x4f, (byte)0xc5,
668             (byte)0x65, (byte)0x6d, (byte)0x6b, (byte)0xef, (byte)0x0d,
669             (byte)0x89, (byte)0x49, (byte)0x2f, (byte)0xb3, (byte)0x43,
670             (byte)0x53, (byte)0x65, (byte)0x1d, (byte)0x49, (byte)0xa3,
671             (byte)0x13, (byte)0x89, (byte)0x59, (byte)0xef, (byte)0x6b,
672             (byte)0xef, (byte)0x65, (byte)0x1d, (byte)0x0b, (byte)0x59,
673             (byte)0x13, (byte)0xe3, (byte)0x4f, (byte)0x9d, (byte)0xb3,
674             (byte)0x29, (byte)0x43, (byte)0x2b, (byte)0x07, (byte)0x1d,
675             (byte)0x95, (byte)0x59, (byte)0x59, (byte)0x47, (byte)0xfb,
676             (byte)0xe5, (byte)0xe9, (byte)0x61, (byte)0x47, (byte)0x2f,
677             (byte)0x35, (byte)0x7f, (byte)0x17, (byte)0x7f, (byte)0xef,
678             (byte)0x7f, (byte)0x95, (byte)0x95, (byte)0x71, (byte)0xd3,
679             (byte)0xa3, (byte)0x0b, (byte)0x71, (byte)0xa3, (byte)0xad,
680             (byte)0x0b, (byte)0x3b, (byte)0xb5, (byte)0xfb, (byte)0xa3,
681             (byte)0xbf, (byte)0x4f, (byte)0x83, (byte)0x1d, (byte)0xad,
682             (byte)0xe9, (byte)0x2f, (byte)0x71, (byte)0x65, (byte)0xa3,
683             (byte)0xe5, (byte)0x07, (byte)0x35, (byte)0x3d, (byte)0x0d,
684             (byte)0xb5, (byte)0xe9, (byte)0xe5, (byte)0x47, (byte)0x3b,
685             (byte)0x9d, (byte)0xef, (byte)0x35, (byte)0xa3, (byte)0xbf,
686             (byte)0xb3, (byte)0xdf, (byte)0x53, (byte)0xd3, (byte)0x97,
687             (byte)0x53, (byte)0x49, (byte)0x71, (byte)0x07, (byte)0x35,
688             (byte)0x61, (byte)0x71, (byte)0x2f, (byte)0x43, (byte)0x2f,
689             (byte)0x11, (byte)0xdf, (byte)0x17, (byte)0x97, (byte)0xfb,
690             (byte)0x95, (byte)0x3b, (byte)0x7f, (byte)0x6b, (byte)0xd3,
691             (byte)0x25, (byte)0xbf, (byte)0xad, (byte)0xc7, (byte)0xc5,
692             (byte)0xc5, (byte)0xb5, (byte)0x8b, (byte)0xef, (byte)0x2f,
693             (byte)0xd3, (byte)0x07, (byte)0x6b, (byte)0x25, (byte)0x49,
694             (byte)0x95, (byte)0x25, (byte)0x49, (byte)0x6d, (byte)0x71,
695             (byte)0xc7
696         },
697         {
698             (byte)0xa7, (byte)0xbc, (byte)0xc9, (byte)0xad, (byte)0x91,
699             (byte)0xdf, (byte)0x85, (byte)0xe5, (byte)0xd4, (byte)0x78,
700             (byte)0xd5, (byte)0x17, (byte)0x46, (byte)0x7c, (byte)0x29,
701             (byte)0x4c, (byte)0x4d, (byte)0x03, (byte)0xe9, (byte)0x25,
702             (byte)0x68, (byte)0x11, (byte)0x86, (byte)0xb3, (byte)0xbd,
703             (byte)0xf7, (byte)0x6f, (byte)0x61, (byte)0x22, (byte)0xa2,
704             (byte)0x26, (byte)0x34, (byte)0x2a, (byte)0xbe, (byte)0x1e,
705             (byte)0x46, (byte)0x14, (byte)0x68, (byte)0x9d, (byte)0x44,
706             (byte)0x18, (byte)0xc2, (byte)0x40, (byte)0xf4, (byte)0x7e,
707             (byte)0x5f, (byte)0x1b, (byte)0xad, (byte)0x0b, (byte)0x94,
708             (byte)0xb6, (byte)0x67, (byte)0xb4, (byte)0x0b, (byte)0xe1,
709             (byte)0xea, (byte)0x95, (byte)0x9c, (byte)0x66, (byte)0xdc,
710             (byte)0xe7, (byte)0x5d, (byte)0x6c, (byte)0x05, (byte)0xda,
711             (byte)0xd5, (byte)0xdf, (byte)0x7a, (byte)0xef, (byte)0xf6,
712             (byte)0xdb, (byte)0x1f, (byte)0x82, (byte)0x4c, (byte)0xc0,
713             (byte)0x68, (byte)0x47, (byte)0xa1, (byte)0xbd, (byte)0xee,
714             (byte)0x39, (byte)0x50, (byte)0x56, (byte)0x4a, (byte)0xdd,
715             (byte)0xdf, (byte)0xa5, (byte)0xf8, (byte)0xc6, (byte)0xda,
716             (byte)0xca, (byte)0x90, (byte)0xca, (byte)0x01, (byte)0x42,
717             (byte)0x9d, (byte)0x8b, (byte)0x0c, (byte)0x73, (byte)0x43,
718             (byte)0x75, (byte)0x05, (byte)0x94, (byte)0xde, (byte)0x24,
719             (byte)0xb3, (byte)0x80, (byte)0x34, (byte)0xe5, (byte)0x2c,
720             (byte)0xdc, (byte)0x9b, (byte)0x3f, (byte)0xca, (byte)0x33,
721             (byte)0x45, (byte)0xd0, (byte)0xdb, (byte)0x5f, (byte)0xf5,
722             (byte)0x52, (byte)0xc3, (byte)0x21, (byte)0xda, (byte)0xe2,
723             (byte)0x22, (byte)0x72, (byte)0x6b, (byte)0x3e, (byte)0xd0,
724             (byte)0x5b, (byte)0xa8, (byte)0x87, (byte)0x8c, (byte)0x06,
725             (byte)0x5d, (byte)0x0f, (byte)0xdd, (byte)0x09, (byte)0x19,
726             (byte)0x93, (byte)0xd0, (byte)0xb9, (byte)0xfc, (byte)0x8b,
727             (byte)0x0f, (byte)0x84, (byte)0x60, (byte)0x33, (byte)0x1c,
728             (byte)0x9b, (byte)0x45, (byte)0xf1, (byte)0xf0, (byte)0xa3,
729             (byte)0x94, (byte)0x3a, (byte)0x12, (byte)0x77, (byte)0x33,
730             (byte)0x4d, (byte)0x44, (byte)0x78, (byte)0x28, (byte)0x3c,
731             (byte)0x9e, (byte)0xfd, (byte)0x65, (byte)0x57, (byte)0x16,
732             (byte)0x94, (byte)0x6b, (byte)0xfb, (byte)0x59, (byte)0xd0,
733             (byte)0xc8, (byte)0x22, (byte)0x36, (byte)0xdb, (byte)0xd2,
734             (byte)0x63, (byte)0x98, (byte)0x43, (byte)0xa1, (byte)0x04,
735             (byte)0x87, (byte)0x86, (byte)0xf7, (byte)0xa6, (byte)0x26,
736             (byte)0xbb, (byte)0xd6, (byte)0x59, (byte)0x4d, (byte)0xbf,
737             (byte)0x6a, (byte)0x2e, (byte)0xaa, (byte)0x2b, (byte)0xef,
738             (byte)0xe6, (byte)0x78, (byte)0xb6, (byte)0x4e, (byte)0xe0,
739             (byte)0x2f, (byte)0xdc, (byte)0x7c, (byte)0xbe, (byte)0x57,
740             (byte)0x19, (byte)0x32, (byte)0x7e, (byte)0x2a, (byte)0xd0,
741             (byte)0xb8, (byte)0xba, (byte)0x29, (byte)0x00, (byte)0x3c,
742             (byte)0x52, (byte)0x7d, (byte)0xa8, (byte)0x49, (byte)0x3b,
743             (byte)0x2d, (byte)0xeb, (byte)0x25, (byte)0x49, (byte)0xfa,
744             (byte)0xa3, (byte)0xaa, (byte)0x39, (byte)0xa7, (byte)0xc5,
745             (byte)0xa7, (byte)0x50, (byte)0x11, (byte)0x36, (byte)0xfb,
746             (byte)0xc6, (byte)0x67, (byte)0x4a, (byte)0xf5, (byte)0xa5,
747             (byte)0x12, (byte)0x65, (byte)0x7e, (byte)0xb0, (byte)0xdf,
748             (byte)0xaf, (byte)0x4e, (byte)0xb3, (byte)0x61, (byte)0x7f,
749             (byte)0x2f
750         }
751     };
752 
753     /**
754      * This is where the actual labels for the Nikon tags are.
755      */
756     private static final ResourceBundle m_tagBundle = ResourceBundle.getBundle(
757         "com.lightcrafts.image.metadata.makernotes.NikonTags"
758     );
759 
760     /**
761      * A mapping of tags by ID.
762      */
763     private static final Map<Integer,ImageMetaTagInfo> m_tagsByID =
764         new HashMap<Integer,ImageMetaTagInfo>();
765 
766     /**
767      * A mapping of tags by name.
768      */
769     private static final Map<String,ImageMetaTagInfo> m_tagsByName =
770         new HashMap<String,ImageMetaTagInfo>();
771 
772     static {
add( NIKON_AF_POINT, R, META_ULONG )773         add( NIKON_AF_POINT, "AFPoint", META_ULONG );
add( NIKON_AF_RESPONSE, R, META_STRING )774         add( NIKON_AF_RESPONSE, "AFResponse", META_STRING );
add( NIKON_AUTO_BRACKET_RELEASE, R, META_USHORT )775         add( NIKON_AUTO_BRACKET_RELEASE, "AutoBracketRelease", META_USHORT );
add( NIKON_AUXILIARY_LENS, R, META_STRING )776         add( NIKON_AUXILIARY_LENS, "AuxiliaryLens", META_STRING );
add( NIKON_COLOR_HUE, R, META_STRING )777         add( NIKON_COLOR_HUE, "ColorHue", META_STRING );
add( NIKON_COLOR_MODE, R, META_STRING )778         add( NIKON_COLOR_MODE, "ColorMode", META_STRING );
add( NIKON_COLOR_SPACE, R, META_USHORT )779         add( NIKON_COLOR_SPACE, "ColorSpace", META_USHORT );
add( NIKON_CROP_HIGH_SPEED, R, META_STRING )780         add( NIKON_CROP_HIGH_SPEED, "CropHighSpeed", META_STRING );
add( NIKON_DIGITAL_ZOOM, R, META_URATIONAL )781         add( NIKON_DIGITAL_ZOOM, "DigitalZoom", META_URATIONAL );
add( NIKON_EXPOSURE_BRACKET_VALUE, R, META_URATIONAL )782         add( NIKON_EXPOSURE_BRACKET_VALUE, "ExposureBracketValue", META_URATIONAL );
add( NIKON_EXPOSURE_DIFFERENCE, R, META_UNDEFINED )783         add( NIKON_EXPOSURE_DIFFERENCE, "ExposureDifference", META_UNDEFINED );
add( NIKON_FIRMWARE_VERSION, R, META_STRING )784         add( NIKON_FIRMWARE_VERSION, "FirmwareVersion", META_STRING );
add( NIKON_FLASH_EXPOSURE_BRACKET_VALUE, R, META_ULONG )785         add( NIKON_FLASH_EXPOSURE_BRACKET_VALUE, "FlashExposureBracketValue", META_ULONG );
add( NIKON_FLASH_EXPOSURE_COMPENSATION, R, META_ULONG )786         add( NIKON_FLASH_EXPOSURE_COMPENSATION, "FlashExposureCompensation", META_ULONG );
add( NIKON_FLASH_MODE, R, META_UBYTE )787         add( NIKON_FLASH_MODE, "FlashMode", META_UBYTE );
add( NIKON_FLASH_SETTING, R, META_STRING )788         add( NIKON_FLASH_SETTING, "FlashSetting", META_STRING );
add( NIKON_FLASH_TYPE, R, META_STRING )789         add( NIKON_FLASH_TYPE, "FlashType", META_STRING );
add( NIKON_FOCUS_MODE, R, META_STRING )790         add( NIKON_FOCUS_MODE, "FocusMode", META_STRING );
add( NIKON_HIGH_ISO_NOISE_REDUCTION, R, META_USHORT )791         add( NIKON_HIGH_ISO_NOISE_REDUCTION, "HighISONoiseReduction", META_USHORT );
add( NIKON_HUE_ADJUSTMENT, R, META_SSHORT )792         add( NIKON_HUE_ADJUSTMENT, "HueAdjustment", META_SSHORT );
add( NIKON_IMAGE_ADJUSTMENT, R, META_STRING )793         add( NIKON_IMAGE_ADJUSTMENT, "ImageAdjustment", META_STRING );
add( NIKON_IMAGE_DATA_SIZE, R, META_ULONG )794         add( NIKON_IMAGE_DATA_SIZE, "ImageDataSize", META_ULONG );
add( NIKON_IMAGE_OPTIMIZATION, R, META_UNKNOWN )795         add( NIKON_IMAGE_OPTIMIZATION, "ImageOptimization", META_UNKNOWN );
add( NIKON_IMAGE_PROCESSING, R, META_STRING )796         add( NIKON_IMAGE_PROCESSING, "ImageProcessing", META_STRING );
add( NIKON_IMAGE_STABILIZATION, R, META_STRING )797         add( NIKON_IMAGE_STABILIZATION, "ImageStabilization", META_STRING );
add( NIKON_ISO, R, META_USHORT )798         add( NIKON_ISO, "ISO", META_USHORT );
add( NIKON_ISO_D70, R, META_USHORT )799         add( NIKON_ISO_D70, "ISO_D70", META_USHORT );
add( NIKON_ISO_D70_2, R, META_USHORT )800         add( NIKON_ISO_D70_2, "ISO_D70_2", META_USHORT );
add( NIKON_LD_VERSION, R, META_UNKNOWN )801         add( NIKON_LD_VERSION, "LDVersion", META_UNKNOWN );
add( NIKON_LD1X_APERTURE_AT_MAX_FOCAL, R, META_UNKNOWN )802         add( NIKON_LD1X_APERTURE_AT_MAX_FOCAL, "LD1XApertureAtMaxFocal", META_UNKNOWN );
add( NIKON_LD1X_APERTURE_AT_MIN_FOCAL, R, META_UNKNOWN )803         add( NIKON_LD1X_APERTURE_AT_MIN_FOCAL, "LD1XApertureAtMinFocal", META_UNKNOWN );
add( NIKON_LD1X_LENS_FSTOPS, R, META_UNKNOWN )804         add( NIKON_LD1X_LENS_FSTOPS, "LD1XLensFstops", META_UNKNOWN );
add( NIKON_LD1X_LENS_ID, R, META_UNKNOWN )805         add( NIKON_LD1X_LENS_ID, "LD1XLensId", META_UNKNOWN );
add( NIKON_LD1X_MAX_FOCAL_LENGTH, R, META_UNKNOWN )806         add( NIKON_LD1X_MAX_FOCAL_LENGTH, "LD1XMaxFocalLength", META_UNKNOWN );
add( NIKON_LD1X_MCU_VERSION, R, META_UNKNOWN )807         add( NIKON_LD1X_MCU_VERSION, "LD1XMcuVersion", META_UNKNOWN );
add( NIKON_LD21_MIN_FOCAL_LENGTH, R, META_UNKNOWN )808         add( NIKON_LD21_MIN_FOCAL_LENGTH, "LD21MinFocalLength", META_UNKNOWN );
add( NIKON_LD21_AF_APERTURE, R, META_UNKNOWN )809         add( NIKON_LD21_AF_APERTURE, "LD21AFAperture", META_UNKNOWN );
add( NIKON_LD21_APERTURE_AT_MAX_FOCAL, R, META_UNKNOWN )810         add( NIKON_LD21_APERTURE_AT_MAX_FOCAL, "LD21ApertureAtMaxFocal", META_UNKNOWN );
add( NIKON_LD21_APERTURE_AT_MIN_FOCAL, R, META_UNKNOWN )811         add( NIKON_LD21_APERTURE_AT_MIN_FOCAL, "LD21ApertureAtMinFocal", META_UNKNOWN );
add( NIKON_LD21_EFFECTIVE_MAX_APERTURE, R, META_UNKNOWN )812         add( NIKON_LD21_EFFECTIVE_MAX_APERTURE, "LD21EffectiveMaxAperture", META_UNKNOWN );
add( NIKON_LD21_FOCAL_LENGTH, R, META_UNKNOWN )813         add( NIKON_LD21_FOCAL_LENGTH, "LD21FocalLength", META_UNKNOWN );
add( NIKON_LD21_FOCUS_DISTANCE, R, META_UNKNOWN )814         add( NIKON_LD21_FOCUS_DISTANCE, "LD21FocusDistance", META_UNKNOWN );
add( NIKON_LD21_FOCUS_POSITION, R, META_UNKNOWN )815         add( NIKON_LD21_FOCUS_POSITION, "LD21FocusPosition", META_UNKNOWN );
add( NIKON_LD21_LENS_FSTOPS, R, META_UNKNOWN )816         add( NIKON_LD21_LENS_FSTOPS, "LD21LensFstops", META_UNKNOWN );
add( NIKON_LD21_LENS_ID, R, META_UNKNOWN )817         add( NIKON_LD21_LENS_ID, "LD21LensId", META_UNKNOWN );
add( NIKON_LD21_MAX_FOCAL_LENGTH, R, META_UNKNOWN )818         add( NIKON_LD21_MAX_FOCAL_LENGTH, "LD21MaxFocalLength", META_UNKNOWN );
add( NIKON_LD21_MCU_VERSION, R, META_UNKNOWN )819         add( NIKON_LD21_MCU_VERSION, "LD21McuVersion", META_UNKNOWN );
add( NIKON_LD21_MIN_FOCAL_LENGTH, R, META_UNKNOWN )820         add( NIKON_LD21_MIN_FOCAL_LENGTH, "LD21MinFocalLength", META_UNKNOWN );
add( NIKON_LENS, R, META_URATIONAL )821         add( NIKON_LENS, "Lens", META_URATIONAL );
add( NIKON_LENS_DATA, R, META_UNDEFINED )822         add( NIKON_LENS_DATA, "LensData", META_UNDEFINED );
add( NIKON_LENS_FSTOPS, R, META_UNDEFINED )823         add( NIKON_LENS_FSTOPS, "LensFStops", META_UNDEFINED );
add( NIKON_LENS_TYPE, R, META_UBYTE )824         add( NIKON_LENS_TYPE, "LensType", META_UBYTE );
add( NIKON_LIGHT_SOURCE, R, META_STRING )825         add( NIKON_LIGHT_SOURCE, "LightSource", META_STRING );
add( NIKON_MANUAL_FOCUS_DISTANCE, R, META_URATIONAL )826         add( NIKON_MANUAL_FOCUS_DISTANCE, "ManualFocusDistance", META_URATIONAL );
add( NIKON_NOISE_REDUCTION, R, META_STRING )827         add( NIKON_NOISE_REDUCTION, "NoiseReduction", META_STRING );
add( NIKON_PREVIEW_IMAGE_IFD_POINTER, R, META_ULONG )828         add( NIKON_PREVIEW_IMAGE_IFD_POINTER, "PreviewImageIFDPointer", META_ULONG );
add( NIKON_QUALITY, R, META_STRING )829         add( NIKON_QUALITY, "Quality", META_STRING );
add( NIKON_SATURATION, R, META_STRING )830         add( NIKON_SATURATION, "Saturation", META_STRING );
add( NIKON_SCENE_MODE, R, META_STRING )831         add( NIKON_SCENE_MODE, "SceneMode", META_STRING );
add( NIKON_SENSOR_PIXEL_SIZE, R, META_URATIONAL )832         add( NIKON_SENSOR_PIXEL_SIZE, "SensorPixelSize", META_URATIONAL );
add( NIKON_SERIAL_NUMBER, R, META_STRING )833         add( NIKON_SERIAL_NUMBER, "SerialNumber", META_STRING );
add( NIKON_SERIAL_NUMBER_2, R, META_UNKNOWN )834         add( NIKON_SERIAL_NUMBER_2, "SerialNumber2", META_UNKNOWN );
add( NIKON_SHARPENING, R, META_STRING )835         add( NIKON_SHARPENING, "Sharpening", META_STRING );
add( NIKON_SHOOTING_MODE, R, META_USHORT )836         add( NIKON_SHOOTING_MODE, "ShootingMode", META_USHORT );
add( NIKON_SHUTTER_COUNT, R, META_ULONG )837         add( NIKON_SHUTTER_COUNT, "ShutterCount", META_ULONG );
add( NIKON_TONE_COMPENSATION, R, META_STRING )838         add( NIKON_TONE_COMPENSATION, "ToneCompensation", META_STRING );
add( NIKON_VARI_PROGRAM, R, META_STRING )839         add( NIKON_VARI_PROGRAM, "VariProgram", META_STRING );
add( NIKON_WHITE_BALANCE, R, META_STRING )840         add( NIKON_WHITE_BALANCE, "WhiteBalance", META_STRING );
add( NIKON_WHITE_BALANCE_FINE_TUNE, R, META_USHORT )841         add( NIKON_WHITE_BALANCE_FINE_TUNE, "WhiteBalanceFineTune", META_USHORT );
842     }
843 }
844 /* vim:set et sw=4 ts=4: */
845