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 "Nikon". 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 * "Explode" 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 * "Explode" 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