OSDN Git Service

Merge "Parse the layer of exiftool output" into gb-ub-photos-bryce
[android-x86/packages-apps-Gallery2.git] / gallerycommon / src / com / android / gallery3d / exif / ExifTag.java
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.android.gallery3d.exif;
18
19 import android.util.SparseArray;
20
21 import java.nio.charset.Charset;
22 import java.text.SimpleDateFormat;
23 import java.util.Arrays;
24 import java.util.Date;
25
26 /**
27  * This class stores information of an EXIF tag.
28  * @see ExifParser
29  * @see ExifReader
30  * @see IfdData
31  * @see ExifData
32  */
33 public class ExifTag {
34     // Tiff Tags
35     public static final short TAG_IMAGE_WIDTH = 0x100;
36     /*
37      * The height of the image.
38      */
39     public static final short TAG_IMAGE_LENGTH = 0x101;
40     public static final short TAG_BITS_PER_SAMPLE = 0x102;
41     public static final short TAG_COMPRESSION = 0x103;
42     public static final short TAG_PHOTOMETRIC_INTERPRETATION = 0x106;
43     public static final short TAG_IMAGE_DESCRIPTION = 0x10E;
44     public static final short TAG_MAKE = 0x10F;
45     public static final short TAG_MODEL = 0x110;
46     public static final short TAG_STRIP_OFFSETS = 0x111;
47     public static final short TAG_ORIENTATION = 0x112;
48     public static final short TAG_SAMPLES_PER_PIXEL = 0x115;
49     public static final short TAG_ROWS_PER_STRIP = 0x116;
50     public static final short TAG_STRIP_BYTE_COUNTS = 0x117;
51     public static final short TAG_X_RESOLUTION = 0x11A;
52     public static final short TAG_Y_RESOLUTION = 0x11B;
53     public static final short TAG_PLANAR_CONFIGURATION = 0x11C;
54     public static final short TAG_RESOLUTION_UNIT = 0x128;
55     public static final short TAG_TRANSFER_FUNCTION = 0x12D;
56     public static final short TAG_SOFTWARE = 0x131;
57     public static final short TAG_DATE_TIME = 0x132;
58     public static final short TAG_ARTIST = 0x13B;
59     public static final short TAG_WHITE_POINT = 0x13E;
60     public static final short TAG_PRIMARY_CHROMATICITIES = 0x13F;
61     public static final short TAG_JPEG_INTERCHANGE_FORMAT = 0x201;
62     public static final short TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = 0x202;
63     public static final short TAG_Y_CB_CR_COEFFICIENTS = 0x211;
64     public static final short TAG_Y_CB_CR_SUB_SAMPLING = 0x212;
65     public static final short TAG_Y_CB_CR_POSITIONING = 0x213;
66     public static final short TAG_REFERENCE_BLACK_WHITE = 0x214;
67     public static final short TAG_COPYRIGHT = (short) 0x8298;
68     public static final short TAG_EXIF_IFD = (short) 0x8769;
69     public static final short TAG_GPS_IFD = (short) 0x8825;
70
71     // Exif Tags
72     public static final short TAG_EXPOSURE_TIME = (short) 0x829A;
73     public static final short TAG_F_NUMBER = (short) 0x829D;
74     public static final short TAG_EXPOSURE_PROGRAM = (short) 0x8822;
75     public static final short TAG_SPECTRAL_SENSITIVITY = (short) 0x8824;
76     public static final short TAG_ISO_SPEED_RATINGS = (short) 0x8827;
77     public static final short TAG_OECF = (short) 0x8828;
78     public static final short TAG_EXIF_VERSION = (short) 0x9000;
79     public static final short TAG_DATE_TIME_ORIGINAL = (short) 0x9003;
80     public static final short TAG_DATE_TIME_DIGITIZED = (short) 0x9004;
81     public static final short TAG_COMPONENTS_CONFIGURATION = (short) 0x9101;
82     public static final short TAG_COMPRESSED_BITS_PER_PIXEL = (short) 0x9102;
83     public static final short TAG_SHUTTER_SPEED_VALUE = (short) 0x9201;
84     public static final short TAG_APERTURE_VALUE = (short) 0x9202;
85     public static final short TAG_BRIGHTNESS_VALUE = (short) 0x9203;
86     public static final short TAG_EXPOSURE_BIAS_VALUE = (short) 0x9204;
87     public static final short TAG_MAX_APERTURE_VALUE = (short) 0x9205;
88     public static final short TAG_SUBJECT_DISTANCE = (short) 0x9206;
89     public static final short TAG_METERING_MODE = (short) 0x9207;
90     public static final short TAG_LIGHT_SOURCE = (short) 0x9208;
91     public static final short TAG_FLASH = (short) 0x9209;
92     public static final short TAG_FOCAL_LENGTH = (short) 0x920A;
93     public static final short TAG_SUBJECT_AREA = (short) 0x9214;
94     public static final short TAG_MAKER_NOTE = (short) 0x927C;
95     public static final short TAG_USER_COMMENT = (short) 0x9286;
96     public static final short TAG_SUB_SEC_TIME = (short) 0x9290;
97     public static final short TAG_SUB_SEC_TIME_ORIGINAL = (short) 0x9291;
98     public static final short TAG_SUB_SEC_TIME_DIGITIZED = (short) 0x9292;
99     public static final short TAG_FLASHPIX_VERSION = (short) 0xA000;
100     public static final short TAG_COLOR_SPACE = (short) 0xA001;
101     public static final short TAG_PIXEL_X_DIMENSION = (short) 0xA002;
102     public static final short TAG_PIXEL_Y_DIMENSION = (short) 0xA003;
103     public static final short TAG_RELATED_SOUND_FILE = (short) 0xA004;
104     public static final short TAG_INTEROPERABILITY_IFD = (short) 0xA005;
105     public static final short TAG_FLASH_ENERGY = (short) 0xA20B;
106     public static final short TAG_SPATIAL_FREQUENCY_RESPONSE = (short) 0xA20C;
107     public static final short TAG_FOCAL_PLANE_X_RESOLUTION = (short) 0xA20E;
108     public static final short TAG_FOCAL_PLANE_Y_RESOLUTION = (short) 0xA20F;
109     public static final short TAG_FOCAL_PLANE_RESOLUTION_UNIT = (short) 0xA210;
110     public static final short TAG_SUBJECT_LOCATION = (short) 0xA214;
111     public static final short TAG_EXPOSURE_INDEX = (short) 0xA215;
112     public static final short TAG_SENSING_METHOD = (short) 0xA217;
113     public static final short TAG_FILE_SOURCE = (short) 0xA300;
114     public static final short TAG_SCENE_TYPE = (short) 0xA301;
115     public static final short TAG_CFA_PATTERN = (short) 0xA302;
116     public static final short TAG_CUSTOM_RENDERED = (short) 0xA401;
117     public static final short TAG_EXPOSURE_MODE = (short) 0xA402;
118     public static final short TAG_WHITE_BALANCE = (short) 0xA403;
119     public static final short TAG_DIGITAL_ZOOM_RATIO = (short) 0xA404;
120     public static final short TAG_FOCAL_LENGTH_IN_35_MM_FILE = (short) 0xA405;
121     public static final short TAG_SCENE_CAPTURE_TYPE = (short) 0xA406;
122     public static final short TAG_GAIN_CONTROL = (short) 0xA407;
123     public static final short TAG_CONTRAST = (short) 0xA408;
124     public static final short TAG_SATURATION = (short) 0xA409;
125     public static final short TAG_SHARPNESS = (short) 0xA40A;
126     public static final short TAG_DEVICE_SETTING_DESCRIPTION = (short) 0xA40B;
127     public static final short TAG_SUBJECT_DISTANCE_RANGE = (short) 0xA40C;
128     public static final short TAG_IMAGE_UNIQUE_ID = (short) 0xA420;
129
130     // GPS tags
131     public static final short TAG_GPS_VERSION_ID = 0;
132     public static final short TAG_GPS_LATITUDE_REF = 1;
133     public static final short TAG_GPS_LATITUDE = 2;
134     public static final short TAG_GPS_LONGITUDE_REF = 3;
135     public static final short TAG_GPS_LONGITUDE = 4;
136     public static final short TAG_GPS_ALTITUDE_REF = 5;
137     public static final short TAG_GPS_ALTITUDE = 6;
138     public static final short TAG_GPS_TIME_STAMP = 7;
139     public static final short TAG_GPS_SATTELLITES = 8;
140     public static final short TAG_GPS_STATUS = 9;
141     public static final short TAG_GPS_MEASURE_MODE = 10;
142     public static final short TAG_GPS_DOP = 11;
143     public static final short TAG_GPS_SPEED_REF = 12;
144     public static final short TAG_GPS_SPEED = 13;
145     public static final short TAG_GPS_TRACK_REF = 14;
146     public static final short TAG_GPS_TRACK = 15;
147     public static final short TAG_GPS_IMG_DIRECTION_REF = 16;
148     public static final short TAG_GPS_IMG_DIRECTION = 17;
149     public static final short TAG_GPS_MAP_DATUM = 18;
150     public static final short TAG_GPS_DEST_LATITUDE_REF = 19;
151     public static final short TAG_GPS_DEST_LATITUDE = 20;
152     public static final short TAG_GPS_DEST_LONGITUDE_REF = 21;
153     public static final short TAG_GPS_DEST_LONGITUDE = 22;
154     public static final short TAG_GPS_DEST_BEARING_REF = 23;
155     public static final short TAG_GPS_DEST_BEARING = 24;
156     public static final short TAG_GPS_DEST_DISTANCE_REF = 25;
157     public static final short TAG_GPS_DEST_DISTANCE = 26;
158     public static final short TAG_GPS_PROCESSING_METHOD = 27;
159     public static final short TAG_GPS_AREA_INFORMATION = 28;
160     public static final short TAG_GPS_DATE_STAMP = 29;
161     public static final short TAG_GPS_DIFFERENTIAL = 30;
162
163     // Interoperability tag
164     public static final short TAG_INTEROPERABILITY_INDEX = 1;
165
166     /**
167      * Constants for {@link #TAG_ORIENTATION}
168      */
169     public static interface Orientation {
170         public static final short TOP_LEFT = 1;
171         public static final short TOP_RIGHT = 2;
172         public static final short BOTTOM_LEFT = 3;
173         public static final short BOTTOM_RIGHT = 4;
174         public static final short LEFT_TOP = 5;
175         public static final short RIGHT_TOP = 6;
176         public static final short LEFT_BOTTOM = 7;
177         public static final short RIGHT_BOTTOM = 8;
178     }
179
180     /**
181      * Constants for {@link #TAG_Y_CB_CR_POSITIONING}
182      */
183     public static interface YCbCrPositioning {
184         public static final short CENTERED = 1;
185         public static final short CO_SITED = 2;
186     }
187
188     /**
189      * Constants for {@link #TAG_COMPRESSION}
190      */
191     public static interface Compression {
192         public static final short UNCOMPRESSION = 1;
193         public static final short JPEG = 6;
194     }
195
196     /**
197      * Constants for {@link #TAG_RESOLUTION_UNIT}
198      */
199     public static interface ResolutionUnit {
200         public static final short INCHES = 2;
201         public static final short CENTIMETERS = 3;
202     }
203
204     /**
205      * Constants for {@link #TAG_PHOTOMETRIC_INTERPRETATION}
206      */
207     public static interface PhotometricInterpretation {
208         public static final short RGB = 2;
209         public static final short YCBCR = 6;
210     }
211
212     /**
213      * Constants for {@link #TAG_PLANAR_CONFIGURATION}
214      */
215     public static interface PlanarConfiguration {
216         public static final short CHUNKY = 1;
217         public static final short PLANAR = 2;
218     }
219
220     /**
221      * Constants for {@link #TAG_EXPOSURE_PROGRAM}
222      */
223     public static interface ExposureProgram {
224         public static final short NOT_DEFINED = 0;
225         public static final short MANUAL = 1;
226         public static final short NORMAL_PROGRAM = 2;
227         public static final short APERTURE_PRIORITY = 3;
228         public static final short SHUTTER_PRIORITY = 4;
229         public static final short CREATIVE_PROGRAM = 5;
230         public static final short ACTION_PROGRAM = 6;
231         public static final short PROTRAIT_MODE = 7;
232         public static final short LANDSCAPE_MODE = 8;
233     }
234
235     /**
236      * Constants for {@link #TAG_METERING_MODE}
237      */
238     public static interface MeteringMode {
239         public static final short UNKNOWN = 0;
240         public static final short AVERAGE = 1;
241         public static final short CENTER_WEIGHTED_AVERAGE = 2;
242         public static final short SPOT = 3;
243         public static final short MULTISPOT = 4;
244         public static final short PATTERN = 5;
245         public static final short PARTAIL = 6;
246         public static final short OTHER = 255;
247     }
248
249     /**
250      * Constants for {@link #TAG_FLASH} As the definition in Jeita EXIF 2.2 standard, we can
251      * treat this constant as bitwise flag.
252      * <p>
253      * e.g.
254      * <p>
255      * short flash = FIRED | RETURN_STROBE_RETURN_LIGHT_DETECTED | MODE_AUTO_MODE
256      */
257     public static interface Flash {
258         // LSB
259         public static final short DID_NOT_FIRED = 0;
260         public static final short FIRED = 1;
261         // 1st~2nd bits
262         public static final short RETURN_NO_STROBE_RETURN_DETECTION_FUNCTION = 0 << 1;
263         public static final short RETURN_STROBE_RETURN_LIGHT_NOT_DETECTED = 2 << 1;
264         public static final short RETURN_STROBE_RETURN_LIGHT_DETECTED = 3 << 1;
265         // 3rd~4th bits
266         public static final short MODE_UNKNOWN = 0 << 3;
267         public static final short MODE_COMPULSORY_FLASH_FIRING = 1 << 3;
268         public static final short MODE_COMPULSORY_FLASH_SUPPRESSION = 2 << 3;
269         public static final short MODE_AUTO_MODE = 3 << 3;
270         // 5th bit
271         public static final short FUNCTION_PRESENT = 0 << 5;
272         public static final short FUNCTION_NO_FUNCTION = 1 << 5;
273         // 6th bit
274         public static final short RED_EYE_REDUCTION_NO_OR_UNKNOWN = 0 << 6;
275         public static final short RED_EYE_REDUCTION_SUPPORT = 1 << 6;
276     }
277
278     /**
279      * Constants for {@link #TAG_COLOR_SPACE}
280      */
281     public static interface ColorSpace {
282         public static final short SRGB = 1;
283         public static final short UNCALIBRATED = (short) 0xFFFF;
284     }
285
286     /**
287      * Constants for {@link #TAG_EXPOSURE_MODE}
288      */
289     public static interface ExposureMode {
290         public static final short AUTO_EXPOSURE = 0;
291         public static final short MANUAL_EXPOSURE = 1;
292         public static final short AUTO_BRACKET = 2;
293     }
294
295     /**
296      * Constants for {@link #TAG_WHITE_BALANCE}
297      */
298     public static interface WhiteBalance {
299         public static final short AUTO = 0;
300         public static final short MANUAL = 1;
301     }
302
303     /**
304      * Constants for {@link #TAG_SCENE_CAPTURE_TYPE}
305      */
306     public static interface SceneCapture {
307         public static final short STANDARD = 0;
308         public static final short LANDSCAPE = 1;
309         public static final short PROTRAIT = 2;
310         public static final short NIGHT_SCENE = 3;
311     }
312
313     /**
314      * Constants for {@link #TAG_COMPONENTS_CONFIGURATION}
315      */
316     public static interface ComponentsConfiguration {
317         public static final short NOT_EXIST = 0;
318         public static final short Y = 1;
319         public static final short CB = 2;
320         public static final short CR = 3;
321         public static final short R = 4;
322         public static final short G = 5;
323         public static final short B = 6;
324     }
325
326     /**
327      * Constants for {@link #TAG_LIGHT_SOURCE}
328      */
329     public static interface LightSource {
330         public static final short UNKNOWN = 0;
331         public static final short DAYLIGHT = 1;
332         public static final short FLUORESCENT = 2;
333         public static final short TUNGSTEN = 3;
334         public static final short FLASH = 4;
335         public static final short FINE_WEATHER = 9;
336         public static final short CLOUDY_WEATHER = 10;
337         public static final short SHADE = 11;
338         public static final short DAYLIGHT_FLUORESCENT = 12;
339         public static final short DAY_WHITE_FLUORESCENT = 13;
340         public static final short COOL_WHITE_FLUORESCENT = 14;
341         public static final short WHITE_FLUORESCENT = 15;
342         public static final short STANDARD_LIGHT_A = 17;
343         public static final short STANDARD_LIGHT_B = 18;
344         public static final short STANDARD_LIGHT_C = 19;
345         public static final short D55 = 20;
346         public static final short D65 = 21;
347         public static final short D75 = 22;
348         public static final short D50 = 23;
349         public static final short ISO_STUDIO_TUNGSTEN = 24;
350         public static final short OTHER = 255;
351     }
352
353     /**
354      * Constants for {@link #TAG_SENSING_METHOD}
355      */
356     public static interface SensingMethod {
357         public static final short NOT_DEFINED = 1;
358         public static final short ONE_CHIP_COLOR = 2;
359         public static final short TWO_CHIP_COLOR = 3;
360         public static final short THREE_CHIP_COLOR = 4;
361         public static final short COLOR_SEQUENTIAL_AREA = 5;
362         public static final short TRILINEAR = 7;
363         public static final short COLOR_SEQUENTIAL_LINEAR = 8;
364     }
365
366     /**
367      * Constants for {@link #TAG_FILE_SOURCE}
368      */
369     public static interface FileSource {
370         public static final short DSC = 3;
371     }
372
373     /**
374      * Constants for {@link #TAG_SCENE_TYPE}
375      */
376     public static interface SceneType {
377         public static final short DIRECT_PHOTOGRAPHED = 1;
378     }
379
380     /**
381      * Constants for {@link #TAG_GAIN_CONTROL}
382      */
383     public static interface GainControl {
384         public static final short NONE = 0;
385         public static final short LOW_UP = 1;
386         public static final short HIGH_UP = 2;
387         public static final short LOW_DOWN = 3;
388         public static final short HIGH_DOWN = 4;
389     }
390
391     /**
392      * Constants for {@link #TAG_CONTRAST}
393      */
394     public static interface Contrast {
395         public static final short NORMAL = 0;
396         public static final short SOFT = 1;
397         public static final short HARD = 2;
398     }
399
400     /**
401      * Constants for {@link #TAG_SATURATION}
402      */
403     public static interface Saturation {
404         public static final short NORMAL = 0;
405         public static final short LOW = 1;
406         public static final short HIGH = 2;
407     }
408
409     /**
410      * Constants for {@link #TAG_SHARPNESS}
411      */
412     public static interface Sharpness {
413         public static final short NORMAL = 0;
414         public static final short SOFT = 1;
415         public static final short HARD = 2;
416     }
417
418     /**
419      * Constants for {@link #TAG_SUBJECT_DISTANCE}
420      */
421     public static interface SubjectDistance {
422         public static final short UNKNOWN = 0;
423         public static final short MACRO = 1;
424         public static final short CLOSE_VIEW = 2;
425         public static final short DISTANT_VIEW = 3;
426     }
427
428     /**
429      * Constants for {@link #TAG_GPS_LATITUDE_REF}, {@link #TAG_GPS_DEST_LATITUDE_REF}
430      */
431     public static interface GpsLatitudeRef {
432         public static final String NORTH = "N";
433         public static final String SOUTH = "S";
434     }
435
436     /**
437      * Constants for {@link #TAG_GPS_LONGITUDE_REF}, {@link #TAG_GPS_DEST_LONGITUDE_REF}
438      */
439     public static interface GpsLongitudeRef {
440         public static final String EAST = "E";
441         public static final String WEST = "W";
442     }
443
444     /**
445      * Constants for {@link #TAG_GPS_ALTITUDE_REF}
446      */
447     public static interface GpsAltitudeRef {
448         public static final short SEA_LEVEL = 0;
449         public static final short SEA_LEVEL_NEGATIVE = 1;
450     }
451
452     /**
453      * Constants for {@link #TAG_GPS_STATUS}
454      */
455     public static interface GpsStatus {
456         public static final String IN_PROGRESS = "A";
457         public static final String INTEROPERABILITY = "V";
458     }
459
460     /**
461      * Constants for {@link #TAG_GPS_MEASURE_MODE}
462      */
463     public static interface GpsMeasureMode {
464         public static final String MODE_2_DIMENSIONAL = "2";
465         public static final String MODE_3_DIMENSIONAL = "3";
466     }
467
468     /**
469      * Constants for {@link #TAG_GPS_SPEED_REF}, {@link #TAG_GPS_DEST_DISTANCE_REF}
470      */
471     public static interface GpsSpeedRef {
472         public static final String KILOMETERS = "K";
473         public static final String MILES = "M";
474         public static final String KNOTS = "N";
475     }
476
477     /**
478      * Constants for {@link #TAG_GPS_TRACK_REF}, {@link #TAG_GPS_IMG_DIRECTION_REF},
479      * {@link #TAG_GPS_DEST_BEARING_REF}
480      */
481     public static interface GpsTrackRef {
482         public static final String TRUE_DIRECTION = "T";
483         public static final String MAGNETIC_DIRECTION = "M";
484     }
485
486     /**
487      * Constants for {@link #TAG_GPS_DIFFERENTIAL}
488      */
489     public static interface GpsDifferential {
490         public static final short WITHOUT_DIFFERENTIAL_CORRECTION = 0;
491         public static final short DIFFERENTIAL_CORRECTION_APPLIED = 1;
492     }
493
494     /**
495      * The BYTE type in the EXIF standard. An 8-bit unsigned integer.
496      */
497     public static final short TYPE_UNSIGNED_BYTE = 1;
498     /**
499      * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit ASCII code.
500      * The final byte is terminated with NULL.
501      */
502     public static final short TYPE_ASCII = 2;
503     /**
504      * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer
505      */
506     public static final short TYPE_UNSIGNED_SHORT = 3;
507     /**
508      * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer
509      */
510     public static final short TYPE_UNSIGNED_LONG = 4;
511     /**
512      * The RATIONAL type of EXIF standard. It consists of two LONGs. The first one is the numerator
513      * and the second one expresses the denominator.
514      */
515     public static final short TYPE_UNSIGNED_RATIONAL = 5;
516     /**
517      * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any value
518      * depending on the field definition.
519      */
520     public static final short TYPE_UNDEFINED = 7;
521     /**
522      * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer
523      * (2's complement notation).
524      */
525     public static final short TYPE_LONG = 9;
526     /**
527      * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first one is the
528      * numerator and the second one is the denominator.
529      */
530     public static final short TYPE_RATIONAL = 10;
531
532     private static final int TYPE_TO_SIZE_MAP[] = new int[11];
533     static {
534         TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1;
535         TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1;
536         TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2;
537         TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4;
538         TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8;
539         TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1;
540         TYPE_TO_SIZE_MAP[TYPE_LONG] = 4;
541         TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8;
542     }
543
544     /**
545      * Gets the element size of the given data type.
546      *
547      * @see #TYPE_ASCII
548      * @see #TYPE_LONG
549      * @see #TYPE_RATIONAL
550      * @see #TYPE_UNDEFINED
551      * @see #TYPE_UNSIGNED_BYTE
552      * @see #TYPE_UNSIGNED_LONG
553      * @see #TYPE_UNSIGNED_RATIONAL
554      * @see #TYPE_UNSIGNED_SHORT
555      */
556     public static int getElementSize(short type) {
557         return TYPE_TO_SIZE_MAP[type];
558     }
559
560     private static volatile SparseArray<Integer> sTagInfo = null;
561     private static volatile SparseArray<Integer> sInteroperTagInfo = null;
562     private static final int SIZE_UNDEFINED = 0;
563
564     private static SparseArray<Integer> getTagInfo() {
565         if (sTagInfo == null) {
566             synchronized(ExifTag.class) {
567                 if (sTagInfo == null) {
568                     sTagInfo = new SparseArray<Integer>();
569                     initTagInfo();
570                 }
571             }
572         }
573         return sTagInfo;
574     }
575
576     private static SparseArray<Integer> getInteroperTagInfo() {
577         if (sInteroperTagInfo == null) {
578             synchronized(ExifTag.class) {
579                 if (sInteroperTagInfo == null) {
580                     sInteroperTagInfo = new SparseArray<Integer>();
581                     sInteroperTagInfo.put(TAG_INTEROPERABILITY_INDEX,
582                             (IfdId.TYPE_IFD_INTEROPERABILITY << 24)
583                             | TYPE_ASCII << 16 | SIZE_UNDEFINED);
584                 }
585             }
586         }
587         return sInteroperTagInfo;
588     }
589
590     private static void initTagInfo() {
591         /**
592          * We put tag information in a 4-bytes integer. The first byte is the
593          * IFD of the tag, and the second byte is the default data type. The
594          * last two byte are a short value indicating the component count of this
595          * tag.
596          */
597         sTagInfo.put(TAG_MAKE,
598                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
599         sTagInfo.put(TAG_IMAGE_WIDTH,
600                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
601         sTagInfo.put(TAG_IMAGE_LENGTH,
602                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
603         sTagInfo.put(TAG_BITS_PER_SAMPLE,
604                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 3);
605         sTagInfo.put(TAG_COMPRESSION,
606                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
607         sTagInfo.put(TAG_PHOTOMETRIC_INTERPRETATION,
608                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
609         sTagInfo.put(TAG_ORIENTATION, (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
610         sTagInfo.put(TAG_SAMPLES_PER_PIXEL,
611                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
612         sTagInfo.put(TAG_PLANAR_CONFIGURATION,
613                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
614         sTagInfo.put(TAG_Y_CB_CR_SUB_SAMPLING,
615                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 2);
616         sTagInfo.put(TAG_Y_CB_CR_POSITIONING,
617                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
618         sTagInfo.put(TAG_X_RESOLUTION,
619                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
620         sTagInfo.put(TAG_Y_RESOLUTION,
621                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
622         sTagInfo.put(TAG_RESOLUTION_UNIT,
623                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
624         sTagInfo.put(TAG_STRIP_OFFSETS,
625                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | SIZE_UNDEFINED);
626         sTagInfo.put(TAG_ROWS_PER_STRIP,
627                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
628         sTagInfo.put(TAG_STRIP_BYTE_COUNTS,
629                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | SIZE_UNDEFINED);
630         sTagInfo.put(TAG_JPEG_INTERCHANGE_FORMAT,
631                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
632         sTagInfo.put(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
633                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
634         sTagInfo.put(TAG_TRANSFER_FUNCTION,
635                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_SHORT << 16 | 3 * 256);
636         sTagInfo.put(TAG_WHITE_POINT,
637                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 2);
638         sTagInfo.put(TAG_PRIMARY_CHROMATICITIES,
639                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 6);
640         sTagInfo.put(TAG_Y_CB_CR_COEFFICIENTS,
641                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 3);
642         sTagInfo.put(TAG_REFERENCE_BLACK_WHITE,
643                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 6);
644         sTagInfo.put(TAG_DATE_TIME,
645                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | 20);
646         sTagInfo.put(TAG_IMAGE_DESCRIPTION,
647                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
648         sTagInfo.put(TAG_MAKE,
649                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
650         sTagInfo.put(TAG_MODEL,
651                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
652         sTagInfo.put(TAG_SOFTWARE,
653                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
654         sTagInfo.put(TAG_ARTIST,
655                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
656         sTagInfo.put(TAG_COPYRIGHT,
657                 (IfdId.TYPE_IFD_0 << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
658         sTagInfo.put(TAG_EXIF_IFD,
659                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
660         sTagInfo.put(TAG_GPS_IFD,
661                 (IfdId.TYPE_IFD_0 << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
662
663         // EXIF TAG
664         sTagInfo.put(TAG_EXIF_VERSION,
665                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | 4);
666         sTagInfo.put(TAG_FLASHPIX_VERSION,
667                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | 4);
668         sTagInfo.put(TAG_COLOR_SPACE,
669                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
670         sTagInfo.put(TAG_COMPONENTS_CONFIGURATION,
671                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | 4);
672         sTagInfo.put(TAG_COMPRESSED_BITS_PER_PIXEL,
673                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
674         sTagInfo.put(TAG_PIXEL_X_DIMENSION,
675                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
676         sTagInfo.put(TAG_PIXEL_Y_DIMENSION,
677                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_LONG << 16 | 1);
678         sTagInfo.put(TAG_MAKER_NOTE,
679                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
680         sTagInfo.put(TAG_USER_COMMENT,
681                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
682         sTagInfo.put(TAG_RELATED_SOUND_FILE,
683                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | 13);
684         sTagInfo.put(TAG_DATE_TIME_ORIGINAL,
685                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | 20);
686         sTagInfo.put(TAG_DATE_TIME_DIGITIZED,
687                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | 20);
688         sTagInfo.put(TAG_SUB_SEC_TIME,
689                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
690         sTagInfo.put(TAG_SUB_SEC_TIME_ORIGINAL,
691                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
692         sTagInfo.put(TAG_SUB_SEC_TIME_DIGITIZED,
693                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
694         sTagInfo.put(TAG_IMAGE_UNIQUE_ID,
695                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | 33);
696         sTagInfo.put(TAG_EXPOSURE_TIME,
697                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
698         sTagInfo.put(TAG_F_NUMBER,
699                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
700         sTagInfo.put(TAG_EXPOSURE_PROGRAM,
701                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
702         sTagInfo.put(TAG_SPECTRAL_SENSITIVITY,
703                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
704         sTagInfo.put(TAG_ISO_SPEED_RATINGS,
705                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | SIZE_UNDEFINED);
706         sTagInfo.put(TAG_OECF,
707                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
708         sTagInfo.put(TAG_SHUTTER_SPEED_VALUE,
709                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_RATIONAL << 16 | 1);
710         sTagInfo.put(TAG_APERTURE_VALUE,
711                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
712         sTagInfo.put(TAG_BRIGHTNESS_VALUE,
713                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_RATIONAL << 16 | 1);
714         sTagInfo.put(TAG_EXPOSURE_BIAS_VALUE,
715                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_RATIONAL << 16 | 1);
716         sTagInfo.put(TAG_MAX_APERTURE_VALUE,
717                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
718         sTagInfo.put(TAG_SUBJECT_DISTANCE,
719                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
720         sTagInfo.put(TAG_METERING_MODE,
721                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
722         sTagInfo.put(TAG_LIGHT_SOURCE,
723                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
724         sTagInfo.put(TAG_FLASH,
725                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
726         sTagInfo.put(TAG_FOCAL_LENGTH,
727                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
728         sTagInfo.put(TAG_SUBJECT_AREA,
729                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | SIZE_UNDEFINED);
730         sTagInfo.put(TAG_FLASH_ENERGY,
731                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
732         sTagInfo.put(TAG_SPATIAL_FREQUENCY_RESPONSE,
733                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
734         sTagInfo.put(TAG_FOCAL_PLANE_X_RESOLUTION,
735                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
736         sTagInfo.put(TAG_FOCAL_PLANE_Y_RESOLUTION,
737                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
738         sTagInfo.put(TAG_FOCAL_PLANE_RESOLUTION_UNIT,
739                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
740         sTagInfo.put(TAG_SUBJECT_LOCATION,
741                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 2);
742         sTagInfo.put(TAG_EXPOSURE_INDEX,
743                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
744         sTagInfo.put(TAG_SENSING_METHOD,
745                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
746         sTagInfo.put(TAG_FILE_SOURCE,
747                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | 1);
748         sTagInfo.put(TAG_SCENE_TYPE,
749                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | 1);
750         sTagInfo.put(TAG_CFA_PATTERN,
751                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
752         sTagInfo.put(TAG_CUSTOM_RENDERED,
753                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
754         sTagInfo.put(TAG_EXPOSURE_MODE,
755                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
756         sTagInfo.put(TAG_WHITE_BALANCE,
757                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
758         sTagInfo.put(TAG_DIGITAL_ZOOM_RATIO,
759                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
760         sTagInfo.put(TAG_FOCAL_LENGTH_IN_35_MM_FILE,
761                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
762         sTagInfo.put(TAG_SCENE_CAPTURE_TYPE,
763                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
764         sTagInfo.put(TAG_GAIN_CONTROL,
765                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
766         sTagInfo.put(TAG_CONTRAST,
767                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
768         sTagInfo.put(TAG_SATURATION,
769                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
770         sTagInfo.put(TAG_SHARPNESS,
771                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
772         sTagInfo.put(TAG_DEVICE_SETTING_DESCRIPTION,
773                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
774         sTagInfo.put(TAG_SUBJECT_DISTANCE_RANGE,
775                 (IfdId.TYPE_IFD_EXIF << 24) | TYPE_UNSIGNED_SHORT << 16 | 1);
776         // GPS tag
777         sTagInfo.put(TAG_GPS_VERSION_ID,
778                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_BYTE << 16 | 4);
779         sTagInfo.put(TAG_GPS_LATITUDE_REF,
780                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
781         sTagInfo.put(TAG_GPS_LONGITUDE_REF,
782                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
783         sTagInfo.put(TAG_GPS_LATITUDE,
784                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_RATIONAL << 16 | 3);
785         sTagInfo.put(TAG_GPS_LONGITUDE,
786                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_RATIONAL << 16 | 3);
787         sTagInfo.put(TAG_GPS_ALTITUDE_REF,
788                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_BYTE << 16 | 1);
789         sTagInfo.put(TAG_GPS_ALTITUDE,
790                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
791         sTagInfo.put(TAG_GPS_TIME_STAMP,
792                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 3);
793         sTagInfo.put(TAG_GPS_SATTELLITES,
794                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
795         sTagInfo.put(TAG_GPS_STATUS,
796                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
797         sTagInfo.put(TAG_GPS_MEASURE_MODE,
798                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
799         sTagInfo.put(TAG_GPS_DOP,
800                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
801         sTagInfo.put(TAG_GPS_SPEED_REF,
802                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
803         sTagInfo.put(TAG_GPS_SPEED,
804                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
805         sTagInfo.put(TAG_GPS_TRACK_REF,
806                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
807         sTagInfo.put(TAG_GPS_TRACK,
808                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
809         sTagInfo.put(TAG_GPS_IMG_DIRECTION_REF,
810                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
811         sTagInfo.put(TAG_GPS_IMG_DIRECTION,
812                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
813         sTagInfo.put(TAG_GPS_MAP_DATUM,
814                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | SIZE_UNDEFINED);
815         sTagInfo.put(TAG_GPS_DEST_LATITUDE_REF,
816                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
817         sTagInfo.put(TAG_GPS_DEST_LATITUDE,
818                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
819         sTagInfo.put(TAG_GPS_DEST_BEARING_REF,
820                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
821         sTagInfo.put(TAG_GPS_DEST_BEARING,
822                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
823         sTagInfo.put(TAG_GPS_DEST_DISTANCE_REF,
824                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 2);
825         sTagInfo.put(TAG_GPS_DEST_DISTANCE,
826                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_RATIONAL << 16 | 1);
827         sTagInfo.put(TAG_GPS_PROCESSING_METHOD,
828                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
829         sTagInfo.put(TAG_GPS_AREA_INFORMATION,
830                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNDEFINED << 16 | SIZE_UNDEFINED);
831         sTagInfo.put(TAG_GPS_DATE_STAMP,
832                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_ASCII << 16 | 11);
833         sTagInfo.put(TAG_GPS_DIFFERENTIAL,
834                 (IfdId.TYPE_IFD_GPS << 24) | TYPE_UNSIGNED_SHORT << 16 | 11);
835     }
836
837     private static Charset US_ASCII = Charset.forName("US-ASCII");
838     private final short mTagId;
839     private final short mDataType;
840     private final int mIfd;
841     private final boolean mComponentCountDefined;
842     private int mComponentCount;
843     private Object mValue;
844     private int mOffset;
845
846     static private short getTypeFromInfo(int info) {
847         return (short) ((info >> 16) & 0xff);
848     }
849
850     static private int getComponentCountFromInfo(int info) {
851         return info & 0xffff;
852     }
853
854     static private int getIfdIdFromInfo(int info) {
855         return (info >> 24) & 0xff;
856     }
857
858     static private boolean getComponentCountDefined(short tagId, int ifd) {
859         Integer info = (ifd == IfdId.TYPE_IFD_INTEROPERABILITY) ?
860                 getInteroperTagInfo().get(tagId) : getTagInfo().get(tagId);
861         if (info == null) return false;
862         return getComponentCountFromInfo(info) != SIZE_UNDEFINED;
863     }
864
865     static int getIfdIdFromTagId(short tagId) {
866         Integer info = getTagInfo().get(tagId);
867         if (info == null) {
868             throw new IllegalArgumentException("Unknown Tag ID: " + tagId);
869         }
870         return getIfdIdFromInfo(info);
871     }
872
873     /**
874      * Create a tag with given ID. For tags related to interoperability and thumbnail, call
875      * {@link #buildInteroperabilityTag(short)} and {@link #buildThumbnailTag(short)} respectively.
876      * @exception IllegalArgumentException If the ID is invalid.
877      */
878     static public ExifTag buildTag(short tagId) {
879         Integer info = getTagInfo().get(tagId);
880         if (info == null) {
881             throw new IllegalArgumentException("Unknown Tag ID: " + tagId);
882         }
883         return new ExifTag(tagId, getTypeFromInfo(info),
884                 getComponentCountFromInfo(info),
885                 getIfdIdFromInfo(info));
886     }
887
888     /**
889      * Create a tag related to thumbnail with given ID.
890      * @exception IllegalArgumentException If the ID is invalid.
891      */
892     static public ExifTag buildThumbnailTag(short tagId) {
893         Integer info = getTagInfo().get(tagId);
894         if (info == null || getIfdIdFromInfo(info) != IfdId.TYPE_IFD_0) {
895             throw new IllegalArgumentException("Unknown Thumnail Tag ID: " + tagId);
896         }
897         return new ExifTag(tagId, getTypeFromInfo(info),
898                 getComponentCountFromInfo(info),
899                 IfdId.TYPE_IFD_1);
900     }
901
902     /**
903      * Create a tag related to interoperability with given ID.
904      * @exception IllegalArgumentException If the ID is invalid.
905      */
906     static public ExifTag buildInteroperabilityTag(short tagId) {
907         Integer info = getInteroperTagInfo().get(tagId);
908         if (info == null || getIfdIdFromInfo(info) != IfdId.TYPE_IFD_INTEROPERABILITY) {
909             throw new RuntimeException("Unknown Interoperability Tag ID: " + tagId);
910         }
911         return new ExifTag(tagId, getTypeFromInfo(info),
912                 getComponentCountFromInfo(info),
913                 IfdId.TYPE_IFD_INTEROPERABILITY);
914     }
915
916     static boolean isValidType(short type) {
917         return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII ||
918                type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG ||
919                type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED ||
920                type == TYPE_LONG || type == TYPE_RATIONAL;
921     }
922
923     ExifTag(short tagId, short type, int componentCount, int ifd) {
924         mTagId = tagId;
925         mDataType = type;
926         mComponentCount = componentCount;
927         mComponentCountDefined = getComponentCountDefined(tagId, ifd);
928         mIfd = ifd;
929     }
930
931     /**
932      * Returns the ID of the IFD this tag belongs to.
933      *
934      * @see IfdId#TYPE_IFD_0
935      * @see IfdId#TYPE_IFD_1
936      * @see IfdId#TYPE_IFD_EXIF
937      * @see IfdId#TYPE_IFD_GPS
938      * @see IfdId#TYPE_IFD_INTEROPERABILITY
939      */
940     public int getIfd() {
941         return mIfd;
942     }
943
944     /**
945      * Gets the ID of this tag.
946      */
947     public short getTagId() {
948         return mTagId;
949     }
950
951     /**
952      * Gets the data type of this tag
953      *
954      * @see #TYPE_ASCII
955      * @see #TYPE_LONG
956      * @see #TYPE_RATIONAL
957      * @see #TYPE_UNDEFINED
958      * @see #TYPE_UNSIGNED_BYTE
959      * @see #TYPE_UNSIGNED_LONG
960      * @see #TYPE_UNSIGNED_RATIONAL
961      * @see #TYPE_UNSIGNED_SHORT
962      */
963     public short getDataType() {
964         return mDataType;
965     }
966
967     /**
968      * Gets the total data size in bytes of the value of this tag.
969      */
970     public int getDataSize() {
971         return getComponentCount() * getElementSize(getDataType());
972     }
973
974     /**
975      * Gets the component count of this tag.
976      */
977     public int getComponentCount() {
978         return mComponentCount;
979     }
980
981     /**
982      * Sets the component count of this tag.
983      * Call this function before setValue() if the length of value does not
984      * match the component count.
985      */
986     public void setComponentCount(int count) {
987         mComponentCount = count;
988     }
989
990     /**
991      * Returns true if this ExifTag contains value; otherwise, this tag will contain an offset value
992      * that links to the area where the actual value is located.
993      *
994      * @see #getOffset()
995      */
996     public boolean hasValue() {
997         return mValue != null;
998     }
999
1000     /**
1001      * Gets the offset of this tag. This is only valid if this data size > 4 and contains an offset
1002      * to the location of the actual value.
1003      */
1004     public int getOffset() {
1005         return mOffset;
1006     }
1007
1008     /**
1009      * Sets the offset of this tag.
1010      */
1011     void setOffset(int offset) {
1012         mOffset = offset;
1013     }
1014
1015     private void checkComponentCountOrThrow(int count)
1016             throws IllegalArgumentException {
1017         if (mComponentCountDefined && (mComponentCount != count)) {
1018             throw new IllegalArgumentException("Tag " + mTagId + ": Required "
1019                     + mComponentCount + " components but was given " + count
1020                     + " component(s)");
1021         }
1022     }
1023
1024     private void throwTypeNotMatchedException(String className)
1025             throws IllegalArgumentException {
1026         throw new IllegalArgumentException("Tag " + mTagId + ": expect type " +
1027                 convertTypeToString(mDataType) + " but got " + className);
1028     }
1029
1030     private static String convertTypeToString(short type) {
1031         switch (type) {
1032             case TYPE_UNSIGNED_BYTE:
1033                 return "UNSIGNED_BYTE";
1034             case TYPE_ASCII:
1035                 return "ASCII";
1036             case TYPE_UNSIGNED_SHORT:
1037                 return "UNSIGNED_SHORT";
1038             case TYPE_UNSIGNED_LONG:
1039                 return "UNSIGNED_LONG";
1040             case TYPE_UNSIGNED_RATIONAL:
1041                 return "UNSIGNED_RATIONAL";
1042             case TYPE_UNDEFINED:
1043                 return "UNDEFINED";
1044             case TYPE_LONG:
1045                 return "LONG";
1046             case TYPE_RATIONAL:
1047                 return "RATIONAL";
1048             default:
1049                 return "";
1050         }
1051     }
1052
1053     private static final int UNSIGNED_SHORT_MAX = 65535;
1054     private static final long UNSIGNED_LONG_MAX = 4294967295L;
1055     private static final long LONG_MAX = Integer.MAX_VALUE;
1056     private static final long LONG_MIN = Integer.MIN_VALUE;
1057
1058     private void checkOverflowForUnsignedShort(int[] value) {
1059         for (int v : value) {
1060             if (v > UNSIGNED_SHORT_MAX || v < 0) {
1061                 throw new IllegalArgumentException(
1062                         "Tag " + mTagId+ ": Value" + v +
1063                         " is illegal for type UNSIGNED_SHORT");
1064             }
1065         }
1066     }
1067
1068     private void checkOverflowForUnsignedLong(long[] value) {
1069         for (long v: value) {
1070             if (v < 0 || v > UNSIGNED_LONG_MAX) {
1071                 throw new IllegalArgumentException(
1072                         "Tag " + mTagId+ ": Value" + v +
1073                         " is illegal for type UNSIGNED_LONG");
1074             }
1075         }
1076     }
1077
1078     private void checkOverflowForUnsignedLong(int[] value) {
1079         for (int v: value) {
1080             if (v < 0) {
1081                 throw new IllegalArgumentException(
1082                         "Tag " + mTagId+ ": Value" + v +
1083                         " is illegal for type UNSIGNED_LONG");
1084             }
1085         }
1086     }
1087
1088     private void checkOverflowForUnsignedRational(Rational[] value) {
1089         for (Rational v: value) {
1090             if (v.getNominator() < 0 || v.getDenominator() < 0
1091                     || v.getNominator() > UNSIGNED_LONG_MAX
1092                     || v.getDenominator() > UNSIGNED_LONG_MAX) {
1093                 throw new IllegalArgumentException(
1094                         "Tag " + mTagId+ ": Value" + v +
1095                         " is illegal for type UNSIGNED_RATIONAL");
1096             }
1097         }
1098     }
1099
1100     private void checkOverflowForRational(Rational[] value) {
1101         for (Rational v: value) {
1102             if (v.getNominator() < LONG_MIN || v.getDenominator() < LONG_MIN
1103                     || v.getNominator() > LONG_MAX
1104                     || v.getDenominator() > LONG_MAX) {
1105                 throw new IllegalArgumentException(
1106                         "Tag " + mTagId+ ": Value" + v +
1107                         " is illegal for type RATIONAL");
1108             }
1109         }
1110     }
1111
1112     /**
1113      * Sets integer values into this tag.
1114      * @exception IllegalArgumentException for the following situation:
1115      * <ul>
1116      *     <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
1117      *      {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
1118      *     <li>The value overflows. </li>
1119      *     <li>The value.length does NOT match the definition of component count in
1120      *      EXIF standard.</li>
1121      * </ul>
1122      */
1123     public void setValue(int[] value) {
1124         checkComponentCountOrThrow(value.length);
1125         if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG &&
1126                 mDataType != TYPE_UNSIGNED_LONG) {
1127             throwTypeNotMatchedException("int");
1128         }
1129         if (mDataType == TYPE_UNSIGNED_SHORT) {
1130             checkOverflowForUnsignedShort(value);
1131         } else if (mDataType == TYPE_UNSIGNED_LONG) {
1132             checkOverflowForUnsignedLong(value);
1133         }
1134
1135         long[] data = new long[value.length];
1136         for (int i = 0; i < value.length; i++) {
1137             data[i] = value[i];
1138         }
1139         mValue = data;
1140         mComponentCount = value.length;
1141     }
1142
1143     /**
1144      * Sets integer values into this tag.
1145      * @exception IllegalArgumentException For the following situation:
1146      * <ul>
1147      *     <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
1148      *      {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
1149      *     <li>The value overflows.</li>
1150      *     <li>The component count in the definition of EXIF standard is not 1.</li>
1151      * </ul>
1152      */
1153     public void setValue(int value) {
1154         checkComponentCountOrThrow(1);
1155         setValue(new int[] {value});
1156     }
1157
1158     /**
1159      * Sets long values into this tag.
1160      * @exception IllegalArgumentException For the following situation:
1161      * <ul>
1162      *      <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
1163      *      <li>The value overflows. </li>
1164      *      <li>The value.length does NOT match the definition of component count in
1165      *       EXIF standard.</li>
1166      * </ul>
1167      */
1168     public void setValue(long[] value) {
1169         checkComponentCountOrThrow(value.length);
1170         if (mDataType != TYPE_UNSIGNED_LONG) {
1171             throwTypeNotMatchedException("long");
1172         }
1173         checkOverflowForUnsignedLong(value);
1174         mValue = value;
1175         mComponentCount = value.length;
1176     }
1177
1178     /**
1179      * Sets long values into this tag.
1180      * @exception IllegalArgumentException For the following situation:
1181      * <ul>
1182      *     <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
1183      *     <li>The value overflows. </li>
1184      *     <li>The component count in the definition of EXIF standard is not 1.</li>
1185      * </ul>
1186      */
1187     public void setValue(long value) {
1188         setValue(new long[] {value});
1189     }
1190
1191     /**
1192      * Sets a string value into this tag. The value is treated as an ASCII string where we only
1193      * preserve the lower byte of each character. The length of the string should be equal
1194      * to either (component count -1) or (component count). A "0" byte will be appeneded while
1195      * written to the EXIF file. If the length equals (component count), the final byte will be
1196      * replaced by a "0" byte.
1197      *
1198      * @exception IllegalArgumentException If the data type is not {@link #TYPE_ASCII}
1199      * or the length of the string is not equal to (component count -1) and (component count)
1200      */
1201     public void setValue(String value) {
1202         if (mDataType != TYPE_ASCII) {
1203             throwTypeNotMatchedException("String");
1204         }
1205
1206         byte[] buf = new byte[value.length()];
1207         for (int i = 0, n = value.length(); i < n; i++) {
1208             buf[i] = (byte) value.charAt(i);
1209         }
1210
1211         int count = buf.length;
1212         if (mComponentCountDefined) {
1213             if (mComponentCount != count && mComponentCount != count + 1) {
1214                 throw new IllegalArgumentException("Tag " + mTagId + ": Required "
1215                         + mComponentCount + " or " + (mComponentCount + 1)
1216                         + " components but was given " + count
1217                         + " component(s)");
1218             }
1219         } else {
1220             mComponentCount = buf[count - 1] == 0 ? count : count + 1;
1221         }
1222         mValue = buf;
1223     }
1224
1225     /**
1226      * Sets Rational values into this tag.
1227      * @exception IllegalArgumentException For the following situation:
1228      * <ul>
1229      *      <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} or
1230      *       {@link #TYPE_RATIONAL} .</li>
1231      *      <li>The value overflows. </li>
1232      *      <li>The value.length does NOT match the definition of component count in
1233      *       EXIF standard.</li>
1234      * </ul>
1235      */
1236     public void setValue(Rational[] value) {
1237         if (mDataType == TYPE_UNSIGNED_RATIONAL) {
1238             checkOverflowForUnsignedRational(value);
1239         } else if (mDataType == TYPE_RATIONAL) {
1240             checkOverflowForRational(value);
1241         } else {
1242             throwTypeNotMatchedException("Rational");
1243         }
1244         checkComponentCountOrThrow(value.length);
1245         mValue = value;
1246         mComponentCount = value.length;
1247     }
1248
1249     /**
1250      * Sets Rational values into this tag.
1251      * @exception IllegalArgumentException For the following situation:
1252      * <ul>
1253      *      <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} or
1254      *       {@link #TYPE_RATIONAL} .</li>
1255      *      <li>The value overflows. </li>
1256      *      <li>The component count in the definition of EXIF standard is not 1.</li>
1257      * </ul>
1258      * */
1259     public void setValue(Rational value) {
1260         setValue(new Rational[] {value});
1261     }
1262
1263     /**
1264      * Sets byte values into this tag.
1265      * @exception IllegalArgumentException For the following situation:
1266      * <ul>
1267      *      <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
1268      *       {@link #TYPE_UNDEFINED} .</li>
1269      *      <li>The length does NOT match the definition of component count in EXIF standard.</li>
1270      * </ul>
1271      * */
1272     public void setValue(byte[] value, int offset, int length) {
1273         checkComponentCountOrThrow(length);
1274         if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) {
1275             throwTypeNotMatchedException("byte");
1276         }
1277         mValue = new byte[length];
1278         System.arraycopy(value, offset, mValue, 0, length);
1279         mComponentCount = length;
1280     }
1281
1282     /**
1283      * Equivalent to setValue(value, 0, value.length).
1284      */
1285     public void setValue(byte[] value) {
1286         setValue(value, 0, value.length);
1287     }
1288
1289     private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
1290
1291     /**
1292      * Sets a timestamp to this tag. The method converts the timestamp with the format of
1293      * "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}.
1294      *
1295      * @param time the number of milliseconds since Jan. 1, 1970 GMT
1296      * @exception IllegalArgumentException If the data type is not {@link #TYPE_ASCII}
1297      * or the component count of this tag is not 20 or undefined
1298      */
1299     public void setTimeValue(long time) {
1300         // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe
1301         synchronized (TIME_FORMAT) {
1302             setValue(TIME_FORMAT.format(new Date(time)));
1303         }
1304     }
1305
1306     /**
1307      * Gets the {@link #TYPE_UNSIGNED_SHORT} data.
1308      * @exception IllegalArgumentException If the type is NOT {@link #TYPE_UNSIGNED_SHORT}.
1309      */
1310     public int getUnsignedShort(int index) {
1311         if (mDataType != TYPE_UNSIGNED_SHORT) {
1312             throw new IllegalArgumentException("Cannot get UNSIGNED_SHORT value from "
1313                     + convertTypeToString(mDataType));
1314         }
1315         return (int) (((long[]) mValue) [index]);
1316     }
1317
1318     /**
1319      * Gets the {@link #TYPE_LONG} data.
1320      * @exception IllegalArgumentException If the type is NOT {@link #TYPE_LONG}.
1321      */
1322     public int getLong(int index) {
1323         if (mDataType != TYPE_LONG) {
1324             throw new IllegalArgumentException("Cannot get LONG value from "
1325                     + convertTypeToString(mDataType));
1326         }
1327         return (int) (((long[]) mValue) [index]);
1328     }
1329
1330     /**
1331      * Gets the {@link #TYPE_UNSIGNED_LONG} data.
1332      * @exception IllegalArgumentException If the type is NOT {@link #TYPE_UNSIGNED_LONG}.
1333      */
1334     public long getUnsignedLong(int index) {
1335         if (mDataType != TYPE_UNSIGNED_LONG) {
1336             throw new IllegalArgumentException("Cannot get UNSIGNED LONG value from "
1337                     + convertTypeToString(mDataType));
1338         }
1339         return ((long[]) mValue) [index];
1340     }
1341
1342     /**
1343      * Gets the {@link #TYPE_ASCII} data.
1344      * @exception IllegalArgumentException If the type is NOT {@link #TYPE_ASCII}.
1345      */
1346     public String getString() {
1347         if (mDataType != TYPE_ASCII) {
1348             throw new IllegalArgumentException("Cannot get ASCII value from "
1349                     + convertTypeToString(mDataType));
1350         }
1351         return new String((byte[]) mValue, US_ASCII);
1352     }
1353
1354     /*
1355      * Get the converted ascii byte. Used by ExifOutputStream.
1356      */
1357     byte[] getStringByte() {
1358         return (byte[]) mValue;
1359     }
1360
1361     /**
1362      * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data.
1363      * @exception IllegalArgumentException If the type is NOT {@link #TYPE_RATIONAL} or
1364      * {@link #TYPE_UNSIGNED_RATIONAL}.
1365      */
1366     public Rational getRational(int index) {
1367         if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) {
1368             throw new IllegalArgumentException("Cannot get RATIONAL value from "
1369                     + convertTypeToString(mDataType));
1370         }
1371         return ((Rational[]) mValue) [index];
1372     }
1373
1374     /**
1375      * Equivalent to getBytes(buffer, 0, buffer.length).
1376      */
1377     public void getBytes(byte[] buf) {
1378         getBytes(buf, 0, buf.length);
1379     }
1380
1381     /**
1382      * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data.
1383      *
1384      * @param buf the byte array in which to store the bytes read.
1385      * @param offset the initial position in buffer to store the bytes.
1386      * @param length the maximum number of bytes to store in buffer. If length > component count,
1387      * only the valid bytes will be stored.
1388      *
1389      * @exception IllegalArgumentException If the type is NOT {@link #TYPE_UNDEFINED} or
1390      * {@link #TYPE_UNSIGNED_BYTE}.
1391      */
1392     public void getBytes(byte[] buf, int offset, int length) {
1393         if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) {
1394             throw new IllegalArgumentException("Cannot get BYTE value from "
1395                     + convertTypeToString(mDataType));
1396         }
1397         System.arraycopy(mValue, 0, buf, offset,
1398                 (length > mComponentCount) ? mComponentCount : length);
1399     }
1400
1401     /**
1402      * Returns true if the ID is one of the following: {@link #TAG_EXIF_IFD},
1403      * {@link #TAG_GPS_IFD}, {@link #TAG_JPEG_INTERCHANGE_FORMAT},
1404      * {@link #TAG_STRIP_OFFSETS}, {@link #TAG_INTEROPERABILITY_IFD}
1405      */
1406     static boolean isOffsetTag(short tagId) {
1407         return tagId == TAG_EXIF_IFD
1408                 || tagId == TAG_GPS_IFD
1409                 || tagId == TAG_JPEG_INTERCHANGE_FORMAT
1410                 || tagId == TAG_STRIP_OFFSETS
1411                 || tagId == TAG_INTEROPERABILITY_IFD;
1412     }
1413
1414     /**
1415      * Returns true if the ID is one of the following: {@link #TAG_EXIF_IFD},
1416      * {@link #TAG_GPS_IFD}, {@link #TAG_INTEROPERABILITY_IFD}
1417      */
1418     static boolean isSubIfdOffsetTag(short tagId) {
1419         return tagId == TAG_EXIF_IFD
1420                 || tagId == TAG_GPS_IFD
1421                 || tagId == TAG_INTEROPERABILITY_IFD;
1422     }
1423     @Override
1424     public boolean equals(Object obj) {
1425         if (obj instanceof ExifTag) {
1426             ExifTag tag = (ExifTag) obj;
1427             if (mValue != null) {
1428                 if (mValue instanceof long[]) {
1429                     if (!(tag.mValue instanceof long[])) return false;
1430                     return Arrays.equals((long[]) mValue, (long[]) tag.mValue);
1431                 } else if (mValue instanceof Rational[]) {
1432                     if (!(tag.mValue instanceof Rational[])) return false;
1433                     return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue);
1434                 } else if (mValue instanceof byte[]) {
1435                     if (!(tag.mValue instanceof byte[])) return false;
1436                     return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue);
1437                 } else {
1438                     return mValue.equals(tag.mValue);
1439                 }
1440             } else {
1441                 return tag.mValue == null;
1442             }
1443         }
1444         return false;
1445     }
1446 }