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.HashMap;
8 import java.util.Map;
9 import java.util.ResourceBundle;
10 
11 import com.lightcrafts.image.BadImageFileException;
12 import com.lightcrafts.image.ImageInfo;
13 import com.lightcrafts.image.UnknownImageTypeException;
14 import com.lightcrafts.image.metadata.*;
15 import com.lightcrafts.image.metadata.providers.*;
16 import com.lightcrafts.image.metadata.values.ImageMetaValue;
17 import com.lightcrafts.image.metadata.values.LongMetaValue;
18 import com.lightcrafts.image.metadata.values.ShortMetaValue;
19 import com.lightcrafts.image.types.JPEGImageType;
20 import com.lightcrafts.utils.TextUtil;
21 
22 import static com.lightcrafts.image.metadata.EXIFConstants.*;
23 import static com.lightcrafts.image.metadata.ImageMetaType.*;
24 import static com.lightcrafts.image.metadata.ImageOrientation.*;
25 import static com.lightcrafts.image.metadata.makernotes.CanonTags.*;
26 import static com.lightcrafts.image.metadata.TIFFTags.*;
27 import static com.lightcrafts.image.types.CIFFConstants.*;
28 
29 /**
30  * A <code>CanonDirectory</code> is-an {@link ImageMetadataDirectory} for
31  * holding Canon-specific maker-note metadata.
32  *
33  * @author Paul J. Lucas [paul@lightcrafts.com]
34  */
35 @SuppressWarnings({"CloneableClassWithoutClone"})
36 public final class CanonDirectory extends MakerNotesDirectory implements
37     ApertureProvider, ArtistProvider, ColorTemperatureProvider,
38     FocalLengthProvider, ISOProvider, LensProvider, OrientationProvider,
39     PreviewImageProvider, ShutterSpeedProvider, ThumbnailImageProvider,
40     WidthHeightProvider {
41 
42     ////////// public /////////////////////////////////////////////////////////
43 
44     /**
45      * {@inheritDoc}
46      */
getAperture()47     public float getAperture() {
48         final ImageMetaValue value = getValue( CANON_SI_FNUMBER );
49         return  value != null ?
50                 (float)MetadataUtil.convertFStopFromAPEX(
51                     value.getIntValue()
52                 ) : 0;
53     }
54 
55     /**
56      * {@inheritDoc}
57      */
getArtist()58     public String getArtist() {
59         final ImageMetaValue value = getValue( CANON_OWNER_NAME );
60         return value != null ? value.getStringValue() : null;
61     }
62 
63     /**
64      * {@inheritDoc}
65      */
getColorTemperature()66     public int getColorTemperature() {
67         ImageMetaValue value = getValue( CANON_PI_COLOR_TEMPERATURE );
68         if ( value == null )
69             value = getValue( CANON_CI_D30_COLOR_TEMPERATURE );
70         if ( value == null )
71             value = getValue( CANON_COLOR_TEMPERATURE );
72         return value != null ? value.getIntValue() : 0;
73     }
74 
75     /**
76      * {@inheritDoc}
77      */
getFocalLength()78     public float getFocalLength() {
79         final ImageMetaValue value = getValue( CANON_FL_FOCAL_LENGTH );
80         return value != null ? value.getFloatValue() : 0;
81     }
82 
83     /**
84      * {@inheritDoc}
85      */
getImageHeight()86     public int getImageHeight() {
87         final ImageMetaValue value = getValue( CANON_PI_IMAGE_HEIGHT );
88         return value != null ? value.getIntValue() : 0;
89     }
90 
91     /**
92      * {@inheritDoc}
93      */
getImageWidth()94     public int getImageWidth() {
95         final ImageMetaValue value = getValue( CANON_PI_IMAGE_WIDTH );
96         return value != null ? value.getIntValue() : 0;
97     }
98 
99     /**
100      * {@inheritDoc}
101      */
getISO()102     public int getISO() {
103         ImageMetaValue value = getValue( CANON_SI_ISO );
104         boolean isAPEX = true;
105         if ( value == null ) {
106             //
107             // CANON_CS_ISO can be "Auto" that is not a number,
108             // therefore it shouldn't be a default choice.
109             //
110             value = getValue( CANON_CS_ISO );
111             isAPEX = false;
112         }
113         if ( value == null )
114             return 0;
115         int iso = value.getIntValue();
116         if ( isAPEX )
117             iso = MetadataUtil.convertISOFromAPEX( iso );
118         return iso >= 1 && iso <= 10000 ? iso : 0;
119     }
120 
121     /**
122      * Gets the name of this directory.
123      *
124      * @return Always returns &quot;Canon&quot;.
125      */
getName()126     public String getName() {
127         return "Canon";
128     }
129 
130     /**
131      * {@inheritDoc}
132      */
getLens()133     public String getLens() {
134         final ImageMetaValue lensValue = getValue( CANON_CS_LENS_TYPE );
135         final String label = hasTagValueLabelFor( lensValue );
136         if ( label != null )
137             return label;
138         return makeLensLabelFrom(
139             getValue( CANON_CS_SHORT_FOCAL_LENGTH ),
140             getValue( CANON_CS_LONG_FOCAL_LENGTH ),
141             getValue( CANON_CS_FOCAL_UNITS_PER_MM )
142         );
143     }
144 
145     /**
146      * {@inheritDoc}
147      */
getOrientation()148     public ImageOrientation getOrientation() {
149         final ImageMetaValue value = getValue( CANON_SI_AUTO_ROTATE );
150         if ( value != null ) {
151             switch ( value.getIntValue() ) {
152                 //
153                 // The CIFF constants are the same for the CanonDirectory.
154                 //
155                 case CIFF_AUTO_ROTATE_NONE:
156                     return ORIENTATION_LANDSCAPE;
157                 case CIFF_AUTO_ROTATE_90CCW:
158                     return ORIENTATION_90CCW;
159                 case CIFF_AUTO_ROTATE_180:
160                     return ORIENTATION_180;
161                 case CIFF_AUTO_ROTATE_90CW:
162                     return ORIENTATION_90CW;
163             }
164         }
165         return ORIENTATION_UNKNOWN;
166     }
167 
168     /**
169      * {@inheritDoc}
170      */
getPreviewImage( ImageInfo imageInfo, int maxWidth, int maxHeight )171     public RenderedImage getPreviewImage( ImageInfo imageInfo, int maxWidth,
172                                           int maxHeight )
173         throws BadImageFileException
174     {
175         // TODO: verify that this is actually an sRGB image, what about Adobe RGB shooting, etc.?
176         return JPEGImageType.getImageFromBuffer(
177             imageInfo.getByteBuffer(),
178             getValue( CANON_PII_IMAGE_START ),
179             1       // JPEG_MARKER_BYTE
180                 + 1 // JPEG_SOI_MARKER
181                 + 1 // JPEG_MARKER_BYTE
182                 + 1 // JPEG_APP1_MARKER
183                 + 2 // APP1 length
184                 + EXIF_HEADER_START_SIZE,
185             getValue( CANON_PII_IMAGE_LENGTH ),
186             maxWidth, maxHeight
187         );
188     }
189 
190     /**
191      * {@inheritDoc}
192      */
getThumbnailImage( ImageInfo imageInfo )193     public RenderedImage getThumbnailImage( ImageInfo imageInfo )
194         throws BadImageFileException, IOException, UnknownImageTypeException
195     {
196         final ImageMetadataDirectory dir =
197             imageInfo.getMetadata().getDirectoryFor( TIFFDirectory.class );
198         if ( dir == null ) {
199             //
200             // This should never be null, but just in case ...
201             //
202             return null;
203         }
204         return JPEGImageType.getImageFromBuffer(
205             imageInfo.getByteBuffer(),
206             dir.getValue( TIFF_JPEG_INTERCHANGE_FORMAT ), 0,
207             dir.getValue( TIFF_JPEG_INTERCHANGE_FORMAT_LENGTH ),
208             0, 0
209         );
210     }
211 
212     /**
213      * {@inheritDoc}
214      */
getShutterSpeed()215     public float getShutterSpeed() {
216         final ImageMetaValue value = getValue( CANON_SI_EXPOSURE_TIME );
217         return value != null ? getShutterSpeedFrom( value ) : 0;
218     }
219 
220     /**
221      * {@inheritDoc}
222      */
getTagInfoFor( Integer id )223     public ImageMetaTagInfo getTagInfoFor( Integer id ) {
224         return m_tagsByID.get( id );
225     }
226 
227     /**
228      * {@inheritDoc}
229      */
getTagInfoFor( String name )230     public ImageMetaTagInfo getTagInfoFor( String name ) {
231         return m_tagsByName.get( name );
232     }
233 
234     /**
235      * Puts a key/value pair into this directory.  For a Canon tag that has
236      * subfields, expands the values into multiple key/value pairs.
237      *
238      * @param tagID The metadata tag ID (the key).
239      * @param value The value to put.
240      * @see #valueToString(ImageMetaValue)
241      */
putValue( Integer tagID, final ImageMetaValue value )242     public void putValue( Integer tagID, final ImageMetaValue value ) {
243         switch ( tagID ) {
244             case CANON_CAMERA_SETTINGS:
245             case CANON_COLOR_INFO_D30:
246             case CANON_FOCAL_LENGTH:
247             case CANON_PROCESSING_INFO:
248             case CANON_SENSOR_INFO:
249             case CANON_SHOT_INFO:
250                 explodeSubfields( tagID, 1, value, false );
251                 return;
252             case CANON_COLOR_DATA:
253             case CANON_COLOR_INFO:
254             case CANON_FILE_INFO:
255             case CANON_PICTURE_INFO:
256             case CANON_PREVIEW_IMAGE_INFO:
257                 explodeSubfields( tagID, 1, value, true );
258                 return;
259             case CANON_CUSTOM_FUNCTIONS:
260                 value.setNonDisplayable();
261                 if ( value instanceof LongMetaValue ) {
262                     final long[] longs = ((LongMetaValue)value).getLongValues();
263                     final int cfTagIDStart = tagID << 8;
264                     for ( int i = 1; i < longs.length; ++i ) {
265                         final int n = (int)longs[i];
266                         putValue(
267                             cfTagIDStart | (n >>> 8),
268                             new ShortMetaValue( (short)(n & 0xFF) )
269                         );
270                     }
271                 }
272                 return;
273             case CANON_FLASH_INFO:
274                 // TODO: handle this case
275                 return;
276         }
277         super.putValue( tagID, value );
278     }
279 
280     /**
281      * {@inheritDoc}
282      */
valueToString( ImageMetaValue value )283     public String valueToString( ImageMetaValue value ) {
284         switch ( value.getOwningTagID() ) {
285             case CANON_CS_LENS_TYPE: {
286                 final String label = hasTagValueLabelFor( CANON_CS_LENS_TYPE );
287                 return label != null ? label : "unknown"; // TODO: localize
288             }
289             case CANON_CS_LONG_FOCAL_LENGTH:
290             case CANON_CS_SHORT_FOCAL_LENGTH:
291             case CANON_FL_FOCAL_LENGTH:
292             case CANON_LI_FOCAL_LENGTH:
293             case CANON_LI_LONG_FOCAL_LENGTH:
294             case CANON_LI_SHORT_FOCAL_LENGTH:
295                 return TextUtil.tenthsNoDotZero( value.getShortValue() )  + "mm"; // TODO: localize "mm"
296             case CANON_CS_MAX_APERTURE:
297             case CANON_CS_MIN_APERTURE:
298                 return TextUtil.tenthsNoDotZero( value.getShortValue() );
299             case CANON_PI_DIGITAL_GAIN:
300                 return TextUtil.tenths( value.getIntValue() / 10F );
301             case CANON_SI_EXPOSURE_TIME:
302             case CANON_SI_TARGET_EXPOSURE_TIME: {
303                 final float shutterSpeed = getShutterSpeedFrom( value );
304                 return MetadataUtil.shutterSpeedString( shutterSpeed );
305             }
306             case CANON_SI_FNUMBER:
307             case CANON_SI_TARGET_APERTURE: {
308                 final int apex = value.getIntValue();
309                 return TextUtil.tenths(
310                     MetadataUtil.convertFStopFromAPEX( apex )
311                 );
312             }
313             default:
314                 return super.valueToString( value );
315         }
316     }
317 
318     ////////// protected //////////////////////////////////////////////////////
319 
320     /**
321      * {@inheritDoc}
322      */
323     @Override
getLensNamesValue()324     protected ImageMetaValue getLensNamesValue() {
325         return getValue( CANON_CS_LENS_TYPE );
326     }
327 
328     /**
329      * {@inheritDoc}
330      */
331     @Override
getFocalUnitsPerMMValue()332     protected ImageMetaValue getFocalUnitsPerMMValue() {
333         return getValue( CANON_CS_FOCAL_UNITS_PER_MM );
334     }
335 
336     /**
337      * {@inheritDoc}
338      */
339     @Override
getLongFocalValue()340     protected ImageMetaValue getLongFocalValue() {
341         return getValue( CANON_CS_LONG_FOCAL_LENGTH );
342     }
343 
344     /**
345      * {@inheritDoc}
346      */
347     @Override
getShortFocalValue()348     protected ImageMetaValue getShortFocalValue() {
349         return getValue( CANON_CS_SHORT_FOCAL_LENGTH );
350     }
351 
352     /**
353      * {@inheritDoc}
354      */
355     @Override
getMaxApertureValue()356     protected ImageMetaValue getMaxApertureValue() {
357         return getValue( CANON_CS_MAX_APERTURE );
358     }
359 
360     /**
361      * Gets the priority of this directory for providing the metadata supplied
362      * by implementing the given provider interface.
363      * <p>
364      * The priority for {@link ShutterSpeedProvider} for Canon is the lowest
365      * because it yields weird values.
366      *
367      * @param provider The provider interface to get the priority for.
368      * @return Returns said priority.
369      */
getProviderPriorityFor( Class<? extends ImageMetadataProvider> provider )370     protected int getProviderPriorityFor(
371         Class<? extends ImageMetadataProvider> provider )
372     {
373         return (provider == ShutterSpeedProvider.class)
374                 ? PROVIDER_PRIORITY_MIN
375                 : super.getProviderPriorityFor( provider );
376     }
377 
378     /**
379      * Get the {@link ResourceBundle} to use for tags.
380      *
381      * @return Returns said {@link ResourceBundle}.
382      */
getTagLabelBundle()383     protected ResourceBundle getTagLabelBundle() {
384         return m_tagBundle;
385     }
386 
387     /**
388      * {@inheritDoc}
389      */
getTagsInterface()390     protected Class<? extends ImageMetaTags> getTagsInterface() {
391         return CanonTags.class;
392     }
393 
394     ////////// private ////////////////////////////////////////////////////////
395 
396     /**
397      * Add the tag mappings.
398      *
399      * @param id The tag's ID.
400      * @param name The tag's name.
401      * @param type The tag's {@link ImageMetaType}.
402      */
add( int id, String name, ImageMetaType type )403     private static void add( int id, String name, ImageMetaType type ) {
404         final ImageMetaTagInfo tagInfo =
405             new ImageMetaTagInfo( id, name, type, false );
406         m_tagsByID.put( id, tagInfo );
407         m_tagsByName.put( name, tagInfo );
408     }
409 
410     /**
411      * Gets the shutter speed from the given {@link ImageMetaValue}.
412      *
413      * @param value The {@link ImageMetaValue} to get the shutter speed from.
414      * @return Returns the shutter speed.
415      */
getShutterSpeedFrom( ImageMetaValue value )416     private float getShutterSpeedFrom( ImageMetaValue value ) {
417         final int apex = value.getIntValue();
418         double speed = Math.exp(
419             - MetadataUtil.convertAPEXToEV( apex ) * MetadataUtil.LN_2
420         );
421         final String model = getOwningMetadata().getCameraMake( true );
422         if ( model != null ) {
423             if ( model.contains( "20D"      ) ||
424                  model.contains( "350D"     ) ||
425                  model.contains( "REBEL XT" ) )
426                 speed *= 1000.0 / 32.0;
427         }
428         return (float)speed;
429     }
430 
431     /**
432      * This is where the actual labels for the tags are.
433      */
434     private static final ResourceBundle m_tagBundle = ResourceBundle.getBundle(
435         "com.lightcrafts.image.metadata.makernotes.CanonTags"
436     );
437 
438     /**
439      * A mapping of tags by ID.
440      */
441     private static final Map<Integer,ImageMetaTagInfo> m_tagsByID =
442         new HashMap<Integer,ImageMetaTagInfo>();
443 
444     /**
445      * A mapping of tags by name.
446      */
447     private static final Map<String,ImageMetaTagInfo> m_tagsByName =
448         new HashMap<String,ImageMetaTagInfo>();
449 
450     static {
add( CANON_CAMERA_SETTINGS, R, META_UNDEFINED )451         add( CANON_CAMERA_SETTINGS, "CameraSettings", META_UNDEFINED );
add( CANON_CD_VERSION, R, META_SSHORT )452         add( CANON_CD_VERSION, "CDVersion", META_SSHORT );
add( CANON_CF_AF_ASSIST_LIGHT, R, META_SSHORT )453         add( CANON_CF_AF_ASSIST_LIGHT, "CFAssistLight", META_SSHORT );
add( CANON_CF_AUTO_EXPOSURE_BRACKETING, R, META_SSHORT )454         add( CANON_CF_AUTO_EXPOSURE_BRACKETING, "CFAutoExposureBracketing", META_SSHORT );
add( CANON_CF_AUTO_EXPOSURE_LOCK_BUTTONS, R, META_SSHORT )455         add( CANON_CF_AUTO_EXPOSURE_LOCK_BUTTONS, "CFAutoExposureLockButtons", META_SSHORT );
add( CANON_CF_FILL_FLASH_AUTO_REDUCTION, R, META_SSHORT )456         add( CANON_CF_FILL_FLASH_AUTO_REDUCTION, "CFFillFlashAutoReduction", META_SSHORT );
add( CANON_CF_LENS_AUTO_FOCUS_STOP_BUTTON, R, META_SSHORT )457         add( CANON_CF_LENS_AUTO_FOCUS_STOP_BUTTON, "CFLensAutoFocusStopButton", META_SSHORT );
add( CANON_CF_LONG_EXPOSURE_NOISE_REDUCTION, R, META_SSHORT )458         add( CANON_CF_LONG_EXPOSURE_NOISE_REDUCTION, "CFLongExposureNoiseReduction", META_SSHORT );
add( CANON_CF_MENU_BUTTON_RETURN_POSITION, R, META_SSHORT )459         add( CANON_CF_MENU_BUTTON_RETURN_POSITION, "CFMenuButtonReturnPosition", META_SSHORT );
add( CANON_CF_MIRROR_LOCKUP, R, META_SSHORT )460         add( CANON_CF_MIRROR_LOCKUP, "CFMirrorLockup", META_SSHORT );
add( CANON_CF_SENSOR_CLEANING, R, META_SSHORT )461         add( CANON_CF_SENSOR_CLEANING, "CFSensorCleaning", META_SSHORT );
add( CANON_CF_SET_BUTTON_FUNCTION, R, META_SSHORT )462         add( CANON_CF_SET_BUTTON_FUNCTION, "CFSetButtonFunction", META_SSHORT );
add( CANON_CF_SHUTTER_CURTAIN_SYNC, R, META_SSHORT )463         add( CANON_CF_SHUTTER_CURTAIN_SYNC, "CFShutterCurtainSync", META_SSHORT );
add( CANON_CF_SHUTTER_SPEED_IN_AV_MODE, R, META_SSHORT )464         add( CANON_CF_SHUTTER_SPEED_IN_AV_MODE, "CFShutterSpeedInAvMode", META_SSHORT );
add( CANON_CF_TV_AV_EXPOSURE_LEVEL, R, META_SSHORT )465         add( CANON_CF_TV_AV_EXPOSURE_LEVEL, "CFTVAVExposureLevel", META_SSHORT );
add( CANON_CI_COLOR_HUE, R, META_SSHORT )466         add( CANON_CI_COLOR_HUE, "CIColorHue", META_SSHORT );
add( CANON_CI_COLOR_SPACE, R, META_SSHORT )467         add( CANON_CI_COLOR_SPACE, "CIColorSpace", META_SSHORT );
add( CANON_CI_D30_COLOR_MATRIX, R, META_SSHORT )468         add( CANON_CI_D30_COLOR_MATRIX, "CID30ColorMatrix", META_SSHORT );
add( CANON_CI_D30_COLOR_TEMPERATURE, R, META_USHORT )469         add( CANON_CI_D30_COLOR_TEMPERATURE, "CID30ColorTemperature", META_USHORT );
add( CANON_COLOR_INFO, R, META_UNDEFINED )470         add( CANON_COLOR_INFO, "ColorInfo", META_UNDEFINED );
add( CANON_COLOR_INFO_D30, R, META_UNDEFINED )471         add( CANON_COLOR_INFO_D30, "ColorInfoD30", META_UNDEFINED );
add( CANON_COLOR_SPACE, R, META_USHORT )472         add( CANON_COLOR_SPACE, "ColorSpace", META_USHORT );
add( CANON_COLOR_TEMPERATURE, R, META_USHORT )473         add( CANON_COLOR_TEMPERATURE, "ColorTemperature", META_USHORT );
add( CANON_CS_AF_POINT_SELECTED, R, META_SSHORT )474         add( CANON_CS_AF_POINT_SELECTED, "CSAFPointSelected", META_SSHORT );
add( CANON_CS_CONTINUOUS_DRIVE_MODE, R, META_SSHORT )475         add( CANON_CS_CONTINUOUS_DRIVE_MODE, "CSContinuousDriveMode", META_SSHORT );
add( CANON_CS_CONTRAST, R, META_SSHORT )476         add( CANON_CS_CONTRAST, "CSContrast", META_SSHORT );
add( CANON_CS_DIGITAL_ZOOM, R, META_SSHORT )477         add( CANON_CS_DIGITAL_ZOOM, "CSDigitalZoom", META_SSHORT );
add( CANON_CS_EASY_SHOOTING_MODE, R, META_SSHORT )478         add( CANON_CS_EASY_SHOOTING_MODE, "CSEasyShootingMode", META_SSHORT );
add( CANON_CS_EXPOSURE_MODE, R, META_SSHORT )479         add( CANON_CS_EXPOSURE_MODE, "CSExposureMode", META_SSHORT );
add( CANON_CS_FLASH_ACTIVITY, R, META_SSHORT )480         add( CANON_CS_FLASH_ACTIVITY, "CSFlashActivity", META_SSHORT );
add( CANON_CS_FLASH_DETAILS, R, META_SSHORT )481         add( CANON_CS_FLASH_DETAILS, "CSFlashDetails", META_SSHORT );
add( CANON_CS_FLASH_MODE, R, META_SSHORT )482         add( CANON_CS_FLASH_MODE, "CSFlashMode", META_SSHORT );
add( CANON_CS_FOCAL_UNITS_PER_MM, R, META_SSHORT )483         add( CANON_CS_FOCAL_UNITS_PER_MM, "CSFocalUnitsPerMM", META_SSHORT );
add( CANON_CS_FOCUS_MODE, R, META_SSHORT )484         add( CANON_CS_FOCUS_MODE, "CSFocusMode", META_SSHORT );
add( CANON_CS_FOCUS_MODE_G1, R, META_SSHORT )485         add( CANON_CS_FOCUS_MODE_G1, "CSFocusModeG1", META_SSHORT );
add( CANON_CS_FOCUS_TYPE, R, META_SSHORT )486         add( CANON_CS_FOCUS_TYPE, "CSFocusType", META_SSHORT );
add( CANON_CS_IMAGE_SIZE, R, META_SSHORT )487         add( CANON_CS_IMAGE_SIZE, "CSImageSize", META_SSHORT );
add( CANON_CS_ISO, R, META_SSHORT )488         add( CANON_CS_ISO, "CSISO", META_SSHORT );
add( CANON_CS_LENS_TYPE, R, META_SSHORT )489         add( CANON_CS_LENS_TYPE, "CSLensType", META_SSHORT );
add( CANON_CS_LONG_FOCAL_LENGTH, R, META_SSHORT )490         add( CANON_CS_LONG_FOCAL_LENGTH, "CSLongFocalLength", META_SSHORT );
add( CANON_CS_MAX_APERTURE, R, META_SSHORT )491         add( CANON_CS_MAX_APERTURE, "CSMaxAperture", META_SSHORT );
add( CANON_CS_MACRO_MODE, R, META_SSHORT )492         add( CANON_CS_MACRO_MODE, "CSMacroMode", META_SSHORT );
add( CANON_CS_METERING_MODE, R, META_SSHORT )493         add( CANON_CS_METERING_MODE, "CSMeteringMode", META_SSHORT );
add( CANON_CS_MIN_APERTURE, R, META_SSHORT )494         add( CANON_CS_MIN_APERTURE, "CSMinAperture", META_SSHORT );
add( CANON_CS_QUALITY, R, META_SSHORT )495         add( CANON_CS_QUALITY, "CSQuality", META_SSHORT );
add( CANON_CS_SATURATION, R, META_SSHORT )496         add( CANON_CS_SATURATION, "CSSaturation", META_SSHORT );
add( CANON_CS_SELF_TIMER_DELAY, R, META_SSHORT )497         add( CANON_CS_SELF_TIMER_DELAY, "CSSelfTimerDelay", META_SSHORT );
add( CANON_CS_SHARPNESS, R, META_SSHORT )498         add( CANON_CS_SHARPNESS, "CSSharpness", META_SSHORT );
add( CANON_CS_SHORT_FOCAL_LENGTH, R, META_SSHORT )499         add( CANON_CS_SHORT_FOCAL_LENGTH, "CSShortFocalLength", META_SSHORT );
add( CANON_CS_ZOOMED_RESOLUTION, R, META_SSHORT )500         add( CANON_CS_ZOOMED_RESOLUTION, "CSZoomedResolution", META_SSHORT );
add( CANON_CS_ZOOMED_RESOLUTION_BASE, R, META_SSHORT )501         add( CANON_CS_ZOOMED_RESOLUTION_BASE, "CSZoomedResolutionBase", META_SSHORT );
add( CANON_CUSTOM_FUNCTIONS, R, META_SSHORT )502         add( CANON_CUSTOM_FUNCTIONS, "CustomFunctions", META_SSHORT );
add( CANON_FILE_INFO, R, META_UNDEFINED )503         add( CANON_FILE_INFO, "FileInfo", META_UNDEFINED );
add( CANON_FILE_LENGTH, R, META_ULONG )504         add( CANON_FILE_LENGTH, "FileLength", META_ULONG );
add( CANON_FIRMWARE_VERSION, R, META_STRING )505         add( CANON_FIRMWARE_VERSION, "FirmwareVersion", META_STRING );
add( CANON_FI_FILE_NUMBER, R, META_ULONG )506         add( CANON_FI_FILE_NUMBER, "FIFileNumber", META_ULONG );
add( CANON_FI_SHUTTER_COUNT, R, META_ULONG )507         add( CANON_FI_SHUTTER_COUNT, "FIShutterCount", META_ULONG );
add( CANON_FLASH_INFO, R, META_UNDEFINED )508         add( CANON_FLASH_INFO, "FlashInfo", META_UNDEFINED );
add( CANON_FL_FOCAL_LENGTH, R, META_USHORT )509         add( CANON_FL_FOCAL_LENGTH, "FLFocalLength", META_USHORT );
add( CANON_FL_FOCAL_PLANE_X_SIZE, R, META_USHORT )510         add( CANON_FL_FOCAL_PLANE_X_SIZE, "FLFocalPlaneXSize", META_USHORT );
add( CANON_FL_FOCAL_PLANE_Y_SIZE, R, META_USHORT )511         add( CANON_FL_FOCAL_PLANE_Y_SIZE, "FLFocalPlaneYSize", META_USHORT );
add( CANON_FOCAL_LENGTH, R, META_UNDEFINED )512         add( CANON_FOCAL_LENGTH, "FocalLength", META_UNDEFINED );
add( CANON_IMAGE_NUMBER, R, META_ULONG )513         add( CANON_IMAGE_NUMBER, "ImageNumber", META_ULONG );
add( CANON_IMAGE_TYPE, R, META_STRING )514         add( CANON_IMAGE_TYPE, "ImageType", META_STRING );
add( CANON_LENS_INFO_1D, R, META_UNDEFINED )515         add( CANON_LENS_INFO_1D, "LensInfo1D", META_UNDEFINED );
add( CANON_LI_FOCAL_LENGTH, R, META_USHORT )516         add( CANON_LI_FOCAL_LENGTH, "LIFocalLength", META_USHORT );
add( CANON_LI_LENS_TYPE, R, META_USHORT )517         add( CANON_LI_LENS_TYPE, "LILensType", META_USHORT );
add( CANON_LI_LONG_FOCAL_LENGTH, R, META_USHORT )518         add( CANON_LI_LONG_FOCAL_LENGTH, "LILongFocalLength", META_USHORT );
add( CANON_LI_SHORT_FOCAL_LENGTH, R, META_USHORT )519         add( CANON_LI_SHORT_FOCAL_LENGTH, "LIShortFocalLength", META_USHORT );
add( CANON_MODEL_ID, R, META_ULONG )520         add( CANON_MODEL_ID, "ModelID", META_ULONG );
add( CANON_OWNER_NAME, R, META_STRING )521         add( CANON_OWNER_NAME, "OwnerName", META_STRING );
add( CANON_PI_AF_POINTS_USED, R, META_USHORT )522         add( CANON_PI_AF_POINTS_USED, "PIAFPointsUsed", META_USHORT );
add( CANON_PI_COLOR_TEMPERATURE, R, META_SSHORT )523         add( CANON_PI_COLOR_TEMPERATURE, "PIColorTemperature", META_SSHORT );
add( CANON_PI_DIGITAL_GAIN, R, META_SSHORT )524         add( CANON_PI_DIGITAL_GAIN, "PIDigitalGain", META_SSHORT );
add( CANON_PI_IMAGE_HEIGHT, R, META_USHORT )525         add( CANON_PI_IMAGE_HEIGHT, "PIImageHeight", META_USHORT );
add( CANON_PI_IMAGE_HEIGHT_AS_SHOT, R, META_USHORT )526         add( CANON_PI_IMAGE_HEIGHT_AS_SHOT, "PIImageHeightAsShot", META_USHORT );
add( CANON_PI_IMAGE_WIDTH, R, META_USHORT )527         add( CANON_PI_IMAGE_WIDTH, "PIImageWidth", META_USHORT );
add( CANON_PI_IMAGE_WIDTH_AS_SHOT, R, META_USHORT )528         add( CANON_PI_IMAGE_WIDTH_AS_SHOT, "PIImageWidthAsShot", META_USHORT );
add( CANON_PI_PICTURE_STYLE, R, META_SSHORT )529         add( CANON_PI_PICTURE_STYLE, "PIPictureStyle", META_SSHORT );
add( CANON_PI_SENSOR_BLUE_LEVEL, R, META_SSHORT )530         add( CANON_PI_SENSOR_BLUE_LEVEL, "PISensorBlueLevel", META_SSHORT );
add( CANON_PI_SENSOR_RED_LEVEL, R, META_SSHORT )531         add( CANON_PI_SENSOR_RED_LEVEL, "PISensorRedLevel", META_SSHORT );
add( CANON_PI_TONE_CURVE, R, META_SSHORT )532         add( CANON_PI_TONE_CURVE, "PIToneCurve", META_SSHORT );
add( CANON_PI_WB_SHIFT_AB, R, META_SSHORT )533         add( CANON_PI_WB_SHIFT_AB, "PIWBShiftAB", META_SSHORT );
add( CANON_PI_WB_SHIFT_GM, R, META_SSHORT )534         add( CANON_PI_WB_SHIFT_GM, "PIWBShiftGM", META_SSHORT );
add( CANON_PI_WHITE_BALANCE_BLUE, R, META_SSHORT )535         add( CANON_PI_WHITE_BALANCE_BLUE, "PIWhiteBalanceBlue", META_SSHORT );
add( CANON_PI_WHITE_BALANCE_RED, R, META_SSHORT )536         add( CANON_PI_WHITE_BALANCE_RED, "PIWhiteBalanceRed", META_SSHORT );
add( CANON_PI2_AF_AREA_MODE, R, META_USHORT )537         add( CANON_PI2_AF_AREA_MODE, "PI2AfAreaMode", META_USHORT );
add( CANON_PICTURE_INFO, R, META_UNDEFINED )538         add( CANON_PICTURE_INFO, "PictureInfo", META_UNDEFINED );
add( CANON_PICTURE_INFO2, R, META_UNDEFINED )539         add( CANON_PICTURE_INFO2, "PictureInfo2", META_UNDEFINED );
add( CANON_PII_FOCAL_PLANE_X_RESOLUTION, R, META_SRATIONAL )540         add( CANON_PII_FOCAL_PLANE_X_RESOLUTION, "PIIFocalPlaneXResolution", META_SRATIONAL );
add( CANON_PII_FOCAL_PLANE_Y_RESOLUTION, R, META_SRATIONAL )541         add( CANON_PII_FOCAL_PLANE_Y_RESOLUTION, "PIIFocalPlaneYResolution", META_SRATIONAL );
add( CANON_PII_IMAGE_HEIGHT, R, META_ULONG )542         add( CANON_PII_IMAGE_HEIGHT, "PIIImageHeight", META_ULONG );
add( CANON_PII_IMAGE_LENGTH, R, META_ULONG )543         add( CANON_PII_IMAGE_LENGTH, "PIIImageLength", META_ULONG );
add( CANON_PII_IMAGE_START, R, META_ULONG )544         add( CANON_PII_IMAGE_START, "PIIImageStart", META_ULONG );
add( CANON_PII_IMAGE_WIDTH, R, META_ULONG )545         add( CANON_PII_IMAGE_WIDTH, "PIIImageWidth", META_ULONG );
add( CANON_PREVIEW_IMAGE_INFO, R, META_UNDEFINED )546         add( CANON_PREVIEW_IMAGE_INFO, "PreviewImageInfo", META_UNDEFINED );
add( CANON_PROCESSING_INFO, R, META_UNDEFINED )547         add( CANON_PROCESSING_INFO, "ColorProcessingInfo", META_UNDEFINED );
add( CANON_SENSOR_INFO, R, META_UNDEFINED )548         add( CANON_SENSOR_INFO, "SensorInfo", META_UNDEFINED );
add( CANON_SERIAL_NUMBER, R, META_ULONG )549         add( CANON_SERIAL_NUMBER, "SerialNumber", META_ULONG );
add( CANON_SHOT_INFO, R, META_UNDEFINED )550         add( CANON_SHOT_INFO, "ShotInfo", META_UNDEFINED );
add( CANON_SI_AEB_BRACKET_VALUE, R, META_SSHORT )551         add( CANON_SI_AEB_BRACKET_VALUE, "AEBBracketValue", META_SSHORT );
add( CANON_SI_AF_POINT_USED, R, META_SSHORT )552         add( CANON_SI_AF_POINT_USED, "SIAFPointUsed", META_SSHORT );
add( CANON_SI_AUTO_EXPOSURE_BRACKETING, R, META_SSHORT )553         add( CANON_SI_AUTO_EXPOSURE_BRACKETING, "SIAutoExposureBracketing", META_SSHORT );
add( CANON_SI_AUTO_ROTATE, R, META_SSHORT )554         add( CANON_SI_AUTO_ROTATE, "SIAutoRotate", META_SSHORT );
add( CANON_SI_BULB_DURATION, R, META_SSHORT )555         add( CANON_SI_BULB_DURATION, "SIBulbDuration", META_SSHORT );
add( CANON_SI_EXPOSURE_COMPENSATION, R, META_SSHORT )556         add( CANON_SI_EXPOSURE_COMPENSATION, "SIExposureCompensation", META_SSHORT );
add( CANON_SI_EXPOSURE_TIME, R, META_SSHORT )557         add( CANON_SI_EXPOSURE_TIME, "ExposureTime", META_SSHORT );
add( CANON_SI_FLASH_BIAS, R, META_SSHORT )558         add( CANON_SI_FLASH_BIAS, "SIFlashBias", META_SSHORT );
add( CANON_SI_FNUMBER, R, META_SSHORT )559         add( CANON_SI_FNUMBER, "FNumber", META_SSHORT );
add( CANON_SI_FOCUS_DISTANCE_LOWER, R, META_SSHORT )560         add( CANON_SI_FOCUS_DISTANCE_LOWER, "FocusDistanceLower", META_SSHORT );
add( CANON_SI_FOCUS_DISTANCE_LOWER, R, META_SSHORT )561         add( CANON_SI_FOCUS_DISTANCE_LOWER, "SIFocusDistanceLower", META_SSHORT );
add( CANON_SI_FOCUS_DISTANCE_UPPER, R, META_SSHORT )562         add( CANON_SI_FOCUS_DISTANCE_UPPER, "SIFocusDistanceUpper", META_SSHORT );
add( CANON_SI_ISO, R, META_SSHORT )563         add( CANON_SI_ISO, "SIISO", META_SSHORT );
add( CANON_SI_SENSOR_WIDTH, R, META_SSHORT )564         add( CANON_SI_SENSOR_WIDTH, "SISensorWidth", META_SSHORT );
add( CANON_SI_SENSOR_HEIGHT, R, META_SSHORT )565         add( CANON_SI_SENSOR_HEIGHT, "SISensorHeight", META_SSHORT );
add( CANON_SI_SENSOR_LEFT_BORDER, R, META_SSHORT )566         add( CANON_SI_SENSOR_LEFT_BORDER, "SISensorLeftBorder", META_SSHORT );
add( CANON_SI_SENSOR_TOP_BORDER, R, META_SSHORT )567         add( CANON_SI_SENSOR_TOP_BORDER, "SISensorTopBorder", META_SSHORT );
add( CANON_SI_SENSOR_RIGHT_BORDER, R, META_SSHORT )568         add( CANON_SI_SENSOR_RIGHT_BORDER, "SISensorRightBorder", META_SSHORT );
add( CANON_SI_SENSOR_BOTTOM_BORDER, R, META_SSHORT )569         add( CANON_SI_SENSOR_BOTTOM_BORDER, "SISensorBottomBorder", META_SSHORT );
add( CANON_SI_SEQUENCE_NUMBER, R, META_SSHORT )570         add( CANON_SI_SEQUENCE_NUMBER, "SISequenceNumber", META_SSHORT );
add( CANON_SI_TARGET_APERTURE, R, META_SSHORT )571         add( CANON_SI_TARGET_APERTURE, "TargetAperture", META_SSHORT );
add( CANON_SI_TARGET_EXPOSURE_TIME, R, META_SSHORT )572         add( CANON_SI_TARGET_EXPOSURE_TIME, "TargetExposure", META_SSHORT );
add( CANON_SI_WHITE_BALANCE, R, META_SSHORT )573         add( CANON_SI_WHITE_BALANCE, "SIWhiteBalance", META_SSHORT );
add( CANON_WHITE_BALANCE_TABLE, R, META_SSHORT )574         add( CANON_WHITE_BALANCE_TABLE, "WhiteBalanceTable", META_SSHORT );
575     }
576 }
577 /* vim:set et sw=4 ts=4: */
578