ExifInterface.java revision ac5fe7c617c66850fff75a9fce9979c6e5674b0f
1/*
2 * Copyright 2018 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
17package androidx.exifinterface.media;
18
19import android.content.res.AssetManager;
20import android.graphics.Bitmap;
21import android.graphics.BitmapFactory;
22import android.location.Location;
23import androidx.annotation.IntDef;
24import androidx.annotation.NonNull;
25import androidx.annotation.Nullable;
26import androidx.annotation.RestrictTo;
27import android.util.Log;
28import android.util.Pair;
29
30import java.io.BufferedInputStream;
31import java.io.ByteArrayInputStream;
32import java.io.Closeable;
33import java.io.DataInput;
34import java.io.DataInputStream;
35import java.io.EOFException;
36import java.io.File;
37import java.io.FileInputStream;
38import java.io.FileNotFoundException;
39import java.io.FileOutputStream;
40import java.io.FilterOutputStream;
41import java.io.IOException;
42import java.io.InputStream;
43import java.io.OutputStream;
44import java.lang.annotation.Retention;
45import java.lang.annotation.RetentionPolicy;
46import java.nio.ByteBuffer;
47import java.nio.ByteOrder;
48import java.nio.charset.Charset;
49import java.text.ParsePosition;
50import java.text.SimpleDateFormat;
51import java.util.Arrays;
52import java.util.Date;
53import java.util.HashMap;
54import java.util.HashSet;
55import java.util.List;
56import java.util.Map;
57import java.util.TimeZone;
58import java.util.concurrent.TimeUnit;
59import java.util.regex.Matcher;
60import java.util.regex.Pattern;
61
62/**
63 * This is a class for reading and writing Exif tags in a JPEG file or a RAW image file.
64 * <p>
65 * Supported formats are: JPEG, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW and RAF.
66 * <p>
67 * Attribute mutation is supported for JPEG image files.
68 */
69public class ExifInterface {
70    private static final String TAG = "ExifInterface";
71    private static final boolean DEBUG = false;
72
73    // The Exif tag names. See JEITA CP-3451C specifications (Exif 2.3) Section 3-8.
74    // A. Tags related to image data structure
75    /**
76     *  <p>The number of columns of image data, equal to the number of pixels per row. In JPEG
77     *  compressed data, this tag shall not be used because a JPEG marker is used instead of it.</p>
78     *
79     *  <ul>
80     *      <li>Tag = 256</li>
81     *      <li>Type = Unsigned short or Unsigned long</li>
82     *      <li>Count = 1</li>
83     *      <li>Default = None</li>
84     *  </ul>
85     */
86    public static final String TAG_IMAGE_WIDTH = "ImageWidth";
87    /**
88     *  <p>The number of rows of image data. In JPEG compressed data, this tag shall not be used
89     *  because a JPEG marker is used instead of it.</p>
90     *
91     *  <ul>
92     *      <li>Tag = 257</li>
93     *      <li>Type = Unsigned short or Unsigned long</li>
94     *      <li>Count = 1</li>
95     *      <li>Default = None</li>
96     *  </ul>
97     */
98    public static final String TAG_IMAGE_LENGTH = "ImageLength";
99    /**
100     *  <p>The number of bits per image component. In this standard each component of the image is
101     *  8 bits, so the value for this tag is 8. See also {@link #TAG_SAMPLES_PER_PIXEL}. In JPEG
102     *  compressed data, this tag shall not be used because a JPEG marker is used instead of it.</p>
103     *
104     *  <ul>
105     *      <li>Tag = 258</li>
106     *      <li>Type = Unsigned short</li>
107     *      <li>Count = 3</li>
108     *      <li>Default = {@link #BITS_PER_SAMPLE_RGB}</li>
109     *  </ul>
110     */
111    public static final String TAG_BITS_PER_SAMPLE = "BitsPerSample";
112    /**
113     *  <p>The compression scheme used for the image data. When a primary image is JPEG compressed,
114     *  this designation is not necessary. So, this tag shall not be recorded. When thumbnails use
115     *  JPEG compression, this tag value is set to 6.</p>
116     *
117     *  <ul>
118     *      <li>Tag = 259</li>
119     *      <li>Type = Unsigned short</li>
120     *      <li>Count = 1</li>
121     *      <li>Default = None</li>
122     *  </ul>
123     *
124     *  @see #DATA_UNCOMPRESSED
125     *  @see #DATA_JPEG
126     */
127    public static final String TAG_COMPRESSION = "Compression";
128    /**
129     *  <p>The pixel composition. In JPEG compressed data, this tag shall not be used because a JPEG
130     *  marker is used instead of it.</p>
131     *
132     *  <ul>
133     *      <li>Tag = 262</li>
134     *      <li>Type = SHORT</li>
135     *      <li>Count = 1</li>
136     *      <li>Default = None</li>
137     *  </ul>
138     *
139     *  @see #PHOTOMETRIC_INTERPRETATION_RGB
140     *  @see #PHOTOMETRIC_INTERPRETATION_YCBCR
141     */
142    public static final String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
143    /**
144     *  <p>The image orientation viewed in terms of rows and columns.</p>
145     *
146     *  <ul>
147     *      <li>Tag = 274</li>
148     *      <li>Type = Unsigned short</li>
149     *      <li>Count = 1</li>
150     *      <li>Default = {@link #ORIENTATION_NORMAL}</li>
151     *  </ul>
152     *
153     *  @see #ORIENTATION_UNDEFINED
154     *  @see #ORIENTATION_NORMAL
155     *  @see #ORIENTATION_FLIP_HORIZONTAL
156     *  @see #ORIENTATION_ROTATE_180
157     *  @see #ORIENTATION_FLIP_VERTICAL
158     *  @see #ORIENTATION_TRANSPOSE
159     *  @see #ORIENTATION_ROTATE_90
160     *  @see #ORIENTATION_TRANSVERSE
161     *  @see #ORIENTATION_ROTATE_270
162     */
163    public static final String TAG_ORIENTATION = "Orientation";
164    /**
165     *  <p>The number of components per pixel. Since this standard applies to RGB and YCbCr images,
166     *  the value set for this tag is 3. In JPEG compressed data, this tag shall not be used because
167     *  a JPEG marker is used instead of it.</p>
168     *
169     *  <ul>
170     *      <li>Tag = 277</li>
171     *      <li>Type = Unsigned short</li>
172     *      <li>Count = 1</li>
173     *      <li>Default = 3</li>
174     *  </ul>
175     */
176    public static final String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
177    /**
178     *  <p>Indicates whether pixel components are recorded in chunky or planar format. In JPEG
179     *  compressed data, this tag shall not be used because a JPEG marker is used instead of it.
180     *  If this field does not exist, the TIFF default, {@link #FORMAT_CHUNKY}, is assumed.</p>
181     *
182     *  <ul>
183     *      <li>Tag = 284</li>
184     *      <li>Type = Unsigned short</li>
185     *      <li>Count = 1</li>
186     *  </ul>
187     *
188     *  @see #FORMAT_CHUNKY
189     *  @see #FORMAT_PLANAR
190     */
191    public static final String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
192    /**
193     *  <p>The sampling ratio of chrominance components in relation to the luminance component.
194     *  In JPEG compressed data a JPEG marker is used instead of this tag. So, this tag shall not
195     *  be recorded.</p>
196     *
197     *  <ul>
198     *      <li>Tag = 530</li>
199     *      <li>Type = Unsigned short</li>
200     *      <li>Count = 2</li>
201     *      <ul>
202     *          <li>[2, 1] = YCbCr4:2:2</li>
203     *          <li>[2, 2] = YCbCr4:2:0</li>
204     *          <li>Other = reserved</li>
205     *      </ul>
206     *  </ul>
207     */
208    public static final String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
209    /**
210     *  <p>The position of chrominance components in relation to the luminance component. This field
211     *  is designated only for JPEG compressed data or uncompressed YCbCr data. The TIFF default is
212     *  {@link #Y_CB_CR_POSITIONING_CENTERED}; but when Y:Cb:Cr = 4:2:2 it is recommended in this
213     *  standard that {@link #Y_CB_CR_POSITIONING_CO_SITED} be used to record data, in order to
214     *  improve the image quality when viewed on TV systems. When this field does not exist,
215     *  the reader shall assume the TIFF default. In the case of Y:Cb:Cr = 4:2:0, the TIFF default
216     *  ({@link #Y_CB_CR_POSITIONING_CENTERED}) is recommended. If the Exif/DCF reader does not
217     *  have the capability of supporting both kinds of positioning, it shall follow the TIFF
218     *  default regardless of the value in this field. It is preferable that readers can support
219     *  both centered and co-sited positioning.</p>
220     *
221     *  <ul>
222     *      <li>Tag = 531</li>
223     *      <li>Type = Unsigned short</li>
224     *      <li>Count = 1</li>
225     *      <li>Default = {@link #Y_CB_CR_POSITIONING_CENTERED}</li>
226     *  </ul>
227     *
228     *  @see #Y_CB_CR_POSITIONING_CENTERED
229     *  @see #Y_CB_CR_POSITIONING_CO_SITED
230     */
231    public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
232    /**
233     *  <p>The number of pixels per {@link #TAG_RESOLUTION_UNIT} in the {@link #TAG_IMAGE_WIDTH}
234     *  direction. When the image resolution is unknown, 72 [dpi] shall be designated.</p>
235     *
236     *  <ul>
237     *      <li>Tag = 282</li>
238     *      <li>Type = Unsigned rational</li>
239     *      <li>Count = 1</li>
240     *      <li>Default = 72</li>
241     *  </ul>
242     *
243     *  @see #TAG_Y_RESOLUTION
244     *  @see #TAG_RESOLUTION_UNIT
245     */
246    public static final String TAG_X_RESOLUTION = "XResolution";
247    /**
248     *  <p>The number of pixels per {@link #TAG_RESOLUTION_UNIT} in the {@link #TAG_IMAGE_WIDTH}
249     *  direction. The same value as {@link #TAG_X_RESOLUTION} shall be designated.</p>
250     *
251     *  <ul>
252     *      <li>Tag = 283</li>
253     *      <li>Type = Unsigned rational</li>
254     *      <li>Count = 1</li>
255     *      <li>Default = 72</li>
256     *  </ul>
257     *
258     *  @see #TAG_X_RESOLUTION
259     *  @see #TAG_RESOLUTION_UNIT
260     */
261    public static final String TAG_Y_RESOLUTION = "YResolution";
262    /**
263     *  <p>The unit for measuring {@link #TAG_X_RESOLUTION} and {@link #TAG_Y_RESOLUTION}. The same
264     *  unit is used for both {@link #TAG_X_RESOLUTION} and {@link #TAG_Y_RESOLUTION}. If the image
265     *  resolution is unknown, {@link #RESOLUTION_UNIT_INCHES} shall be designated.</p>
266     *
267     *  <ul>
268     *      <li>Tag = 296</li>
269     *      <li>Type = Unsigned short</li>
270     *      <li>Count = 1</li>
271     *      <li>Default = {@link #RESOLUTION_UNIT_INCHES}</li>
272     *  </ul>
273     *
274     *  @see #RESOLUTION_UNIT_INCHES
275     *  @see #RESOLUTION_UNIT_CENTIMETERS
276     *  @see #TAG_X_RESOLUTION
277     *  @see #TAG_Y_RESOLUTION
278     */
279    public static final String TAG_RESOLUTION_UNIT = "ResolutionUnit";
280
281    // B. Tags related to recording offset
282    /**
283     *  <p>For each strip, the byte offset of that strip. It is recommended that this be selected
284     *  so the number of strip bytes does not exceed 64 KBytes.In the case of JPEG compressed data,
285     *  this designation is not necessary. So, this tag shall not be recorded.</p>
286     *
287     *  <ul>
288     *      <li>Tag = 273</li>
289     *      <li>Type = Unsigned short or Unsigned long</li>
290     *      <li>Count = StripsPerImage (for {@link #FORMAT_CHUNKY})
291     *               or {@link #TAG_SAMPLES_PER_PIXEL} * StripsPerImage
292     *               (for {@link #FORMAT_PLANAR})</li>
293     *      <li>Default = None</li>
294     *  </ul>
295     *
296     *  <p>StripsPerImage = floor(({@link #TAG_IMAGE_LENGTH} + {@link #TAG_ROWS_PER_STRIP} - 1)
297     *  / {@link #TAG_ROWS_PER_STRIP})</p>
298     *
299     *  @see #TAG_ROWS_PER_STRIP
300     *  @see #TAG_STRIP_BYTE_COUNTS
301     */
302    public static final String TAG_STRIP_OFFSETS = "StripOffsets";
303    /**
304     *  <p>The number of rows per strip. This is the number of rows in the image of one strip when
305     *  an image is divided into strips. In the case of JPEG compressed data, this designation is
306     *  not necessary. So, this tag shall not be recorded.</p>
307     *
308     *  <ul>
309     *      <li>Tag = 278</li>
310     *      <li>Type = Unsigned short or Unsigned long</li>
311     *      <li>Count = 1</li>
312     *      <li>Default = None</li>
313     *  </ul>
314     *
315     *  @see #TAG_STRIP_OFFSETS
316     *  @see #TAG_STRIP_BYTE_COUNTS
317     */
318    public static final String TAG_ROWS_PER_STRIP = "RowsPerStrip";
319    /**
320     *  <p>The total number of bytes in each strip. In the case of JPEG compressed data, this
321     *  designation is not necessary. So, this tag shall not be recorded.</p>
322     *
323     *  <ul>
324     *      <li>Tag = 279</li>
325     *      <li>Type = Unsigned short or Unsigned long</li>
326     *      <li>Count = StripsPerImage (when using {@link #FORMAT_CHUNKY})
327     *               or {@link #TAG_SAMPLES_PER_PIXEL} * StripsPerImage
328     *               (when using {@link #FORMAT_PLANAR})</li>
329     *      <li>Default = None</li>
330     *  </ul>
331     *
332     *  <p>StripsPerImage = floor(({@link #TAG_IMAGE_LENGTH} + {@link #TAG_ROWS_PER_STRIP} - 1)
333     *  / {@link #TAG_ROWS_PER_STRIP})</p>
334     */
335    public static final String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
336    /**
337     *  <p>The offset to the start byte (SOI) of JPEG compressed thumbnail data. This shall not be
338     *  used for primary image JPEG data.</p>
339     *
340     *  <ul>
341     *      <li>Tag = 513</li>
342     *      <li>Type = Unsigned long</li>
343     *      <li>Default = None</li>
344     *  </ul>
345     */
346    public static final String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
347    /**
348     *  <p>The number of bytes of JPEG compressed thumbnail data. This is not used for primary image
349     *  JPEG data. JPEG thumbnails are not divided but are recorded as a continuous JPEG bitstream
350     *  from SOI to EOI. APPn and COM markers should not be recorded. Compressed thumbnails shall be
351     *  recorded in no more than 64 KBytes, including all other data to be recorded in APP1.</p>
352     *
353     *  <ul>
354     *      <li>Tag = 514</li>
355     *      <li>Type = Unsigned long</li>
356     *      <li>Default = None</li>
357     *  </ul>
358     */
359    public static final String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
360
361    // C. Tags related to Image Data Characteristics
362    /**
363     *  <p>A transfer function for the image, described in tabular style. Normally this tag need not
364     *  be used, since color space is specified in {@link #TAG_COLOR_SPACE}.</p>
365     *
366     *  <ul>
367     *      <li>Tag = 301</li>
368     *      <li>Type = Unsigned short</li>
369     *      <li>Count = 3 * 256</li>
370     *      <li>Default = None</li>
371     *  </ul>
372     */
373    public static final String TAG_TRANSFER_FUNCTION = "TransferFunction";
374    /**
375     *  <p>The chromaticity of the white point of the image. Normally this tag need not be used,
376     *  since color space is specified in {@link #TAG_COLOR_SPACE}.</p>
377     *
378     *  <ul>
379     *      <li>Tag = 318</li>
380     *      <li>Type = Unsigned rational</li>
381     *      <li>Count = 2</li>
382     *      <li>Default = None</li>
383     *  </ul>
384     */
385    public static final String TAG_WHITE_POINT = "WhitePoint";
386    /**
387     *  <p>The chromaticity of the three primary colors of the image. Normally this tag need not
388     *  be used, since color space is specified in {@link #TAG_COLOR_SPACE}.</p>
389     *
390     *  <ul>
391     *      <li>Tag = 319</li>
392     *      <li>Type = Unsigned rational</li>
393     *      <li>Count = 6</li>
394     *      <li>Default = None</li>
395     *  </ul>
396     */
397    public static final String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
398    /**
399     *  <p>The matrix coefficients for transformation from RGB to YCbCr image data. About
400     *  the default value, please refer to JEITA CP-3451C Spec, Annex D.</p>
401     *
402     *  <ul>
403     *      <li>Tag = 529</li>
404     *      <li>Type = Unsigned rational</li>
405     *      <li>Count = 3</li>
406     *  </ul>
407     */
408    public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
409    /**
410     *  <p>The reference black point value and reference white point value. No defaults are given
411     *  in TIFF, but the values below are given as defaults here. The color space is declared in
412     *  a color space information tag, with the default being the value that gives the optimal image
413     *  characteristics Interoperability these conditions</p>
414     *
415     *  <ul>
416     *      <li>Tag = 532</li>
417     *      <li>Type = RATIONAL</li>
418     *      <li>Count = 6</li>
419     *      <li>Default = [0, 255, 0, 255, 0, 255] (when {@link #TAG_PHOTOMETRIC_INTERPRETATION}
420     *                 is {@link #PHOTOMETRIC_INTERPRETATION_RGB})
421     *                 or [0, 255, 0, 128, 0, 128] (when {@link #TAG_PHOTOMETRIC_INTERPRETATION}
422     *                 is {@link #PHOTOMETRIC_INTERPRETATION_YCBCR})</li>
423     *  </ul>
424     */
425    public static final String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
426
427    // D. Other tags
428    /**
429     *  <p>The date and time of image creation. In this standard it is the date and time the file
430     *  was changed. The format is "YYYY:MM:DD HH:MM:SS" with time shown in 24-hour format, and
431     *  the date and time separated by one blank character ({@code 0x20}). When the date and time
432     *  are unknown, all the character spaces except colons (":") should be filled with blank
433     *  characters, or else the Interoperability field should be filled with blank characters.
434     *  The character string length is 20 Bytes including NULL for termination. When the field is
435     *  left blank, it is treated as unknown.</p>
436     *
437     *  <ul>
438     *      <li>Tag = 306</li>
439     *      <li>Type = String</li>
440     *      <li>Length = 19</li>
441     *      <li>Default = None</li>
442     *  </ul>
443     */
444    public static final String TAG_DATETIME = "DateTime";
445    /**
446     *  <p>An ASCII string giving the title of the image. It is possible to be added a comment
447     *  such as "1988 company picnic" or the like. Two-byte character codes cannot be used. When
448     *  a 2-byte code is necessary, {@link #TAG_USER_COMMENT} is to be used.</p>
449     *
450     *  <ul>
451     *      <li>Tag = 270</li>
452     *      <li>Type = String</li>
453     *      <li>Default = None</li>
454     *  </ul>
455     */
456    public static final String TAG_IMAGE_DESCRIPTION = "ImageDescription";
457    /**
458     *  <p>The manufacturer of the recording equipment. This is the manufacturer of the DSC,
459     *  scanner, video digitizer or other equipment that generated the image. When the field is left
460     *  blank, it is treated as unknown.</p>
461     *
462     *  <ul>
463     *      <li>Tag = 271</li>
464     *      <li>Type = String</li>
465     *      <li>Default = None</li>
466     *  </ul>
467     */
468    public static final String TAG_MAKE = "Make";
469    /**
470     *  <p>The model name or model number of the equipment. This is the model name of number of
471     *  the DSC, scanner, video digitizer or other equipment that generated the image. When
472     *  the field is left blank, it is treated as unknown.</p>
473     *
474     *  <ul>
475     *      <li>Tag = 272</li>
476     *      <li>Type = String</li>
477     *      <li>Default = None</li>
478     *  </ul>
479     */
480    public static final String TAG_MODEL = "Model";
481    /**
482     *  <p>This tag records the name and version of the software or firmware of the camera or image
483     *  input device used to generate the image. The detailed format is not specified, but it is
484     *  recommended that the example shown below be followed. When the field is left blank, it is
485     *  treated as unknown.</p>
486     *
487     *  <p>Ex.) "Exif Software Version 1.00a".</p>
488     *
489     *  <ul>
490     *      <li>Tag = 305</li>
491     *      <li>Type = String</li>
492     *      <li>Default = None</li>
493     *  </ul>
494     */
495    public static final String TAG_SOFTWARE = "Software";
496    /**
497     *  <p>This tag records the name of the camera owner, photographer or image creator.
498     *  The detailed format is not specified, but it is recommended that the information be written
499     *  as in the example below for ease of Interoperability. When the field is left blank, it is
500     *  treated as unknown.</p>
501     *
502     *  <p>Ex.) "Camera owner, John Smith; Photographer, Michael Brown; Image creator,
503     *  Ken James"</p>
504     *
505     *  <ul>
506     *      <li>Tag = 315</li>
507     *      <li>Type = String</li>
508     *      <li>Default = None</li>
509     *  </ul>
510     */
511    public static final String TAG_ARTIST = "Artist";
512    /**
513     *  <p>Copyright information. In this standard the tag is used to indicate both the photographer
514     *  and editor copyrights. It is the copyright notice of the person or organization claiming
515     *  rights to the image. The Interoperability copyright statement including date and rights
516     *  should be written in this field; e.g., "Copyright, John Smith, 19xx. All rights reserved."
517     *  In this standard the field records both the photographer and editor copyrights, with each
518     *  recorded in a separate part of the statement. When there is a clear distinction between
519     *  the photographer and editor copyrights, these are to be written in the order of photographer
520     *  followed by editor copyright, separated by NULL (in this case, since the statement also ends
521     *  with a NULL, there are two NULL codes) (see example 1). When only the photographer copyright
522     *  is given, it is terminated by one NULL code (see example 2). When only the editor copyright
523     *  is given, the photographer copyright part consists of one space followed by a terminating
524     *  NULL code, then the editor copyright is given (see example 3). When the field is left blank,
525     *  it is treated as unknown.</p>
526     *
527     *  <p>Ex. 1) When both the photographer copyright and editor copyright are given.
528     *  <ul><li>Photographer copyright + NULL + editor copyright + NULL</li></ul></p>
529     *  <p>Ex. 2) When only the photographer copyright is given.
530     *  <ul><li>Photographer copyright + NULL</li></ul></p>
531     *  <p>Ex. 3) When only the editor copyright is given.
532     *  <ul><li>Space ({@code 0x20}) + NULL + editor copyright + NULL</li></ul></p>
533     *
534     *  <ul>
535     *      <li>Tag = 315</li>
536     *      <li>Type = String</li>
537     *      <li>Default = None</li>
538     *  </ul>
539     */
540    public static final String TAG_COPYRIGHT = "Copyright";
541
542    // Exif IFD Attribute Information
543    // A. Tags related to version
544    /**
545     *  <p>The version of this standard supported. Nonexistence of this field is taken to mean
546     *  nonconformance to the standard. In according with conformance to this standard, this tag
547     *  shall be recorded like "0230” as 4-byte ASCII.</p>
548     *
549     *  <ul>
550     *      <li>Tag = 36864</li>
551     *      <li>Type = Undefined</li>
552     *      <li>Length = 4</li>
553     *      <li>Default = "0230"</li>
554     *  </ul>
555     */
556    public static final String TAG_EXIF_VERSION = "ExifVersion";
557    /**
558     *  <p>The Flashpix format version supported by a FPXR file. If the FPXR function supports
559     *  Flashpix format Ver. 1.0, this is indicated similarly to {@link #TAG_EXIF_VERSION} by
560     *  recording "0100" as 4-byte ASCII.</p>
561     *
562     *  <ul>
563     *      <li>Tag = 40960</li>
564     *      <li>Type = Undefined</li>
565     *      <li>Length = 4</li>
566     *      <li>Default = "0100"</li>
567     *  </ul>
568     */
569    public static final String TAG_FLASHPIX_VERSION = "FlashpixVersion";
570
571    // B. Tags related to image data characteristics
572    /**
573     *  <p>The color space information tag is always recorded as the color space specifier.
574     *  Normally {@link #COLOR_SPACE_S_RGB} is used to define the color space based on the PC
575     *  monitor conditions and environment. If a color space other than {@link #COLOR_SPACE_S_RGB}
576     *  is used, {@link #COLOR_SPACE_UNCALIBRATED} is set. Image data recorded as
577     *  {@link #COLOR_SPACE_UNCALIBRATED} may be treated as {@link #COLOR_SPACE_S_RGB} when it is
578     *  converted to Flashpix.</p>
579     *
580     *  <ul>
581     *      <li>Tag = 40961</li>
582     *      <li>Type = Unsigned short</li>
583     *      <li>Count = 1</li>
584     *  </ul>
585     *
586     *  @see #COLOR_SPACE_S_RGB
587     *  @see #COLOR_SPACE_UNCALIBRATED
588     */
589    public static final String TAG_COLOR_SPACE = "ColorSpace";
590    /**
591     *  <p>Indicates the value of coefficient gamma. The formula of transfer function used for image
592     *  reproduction is expressed as follows.</p>
593     *
594     *  <p>(Reproduced value) = (Input value) ^ gamma</p>
595     *
596     *  <p>Both reproduced value and input value indicate normalized value, whose minimum value is
597     *  0 and maximum value is 1.</p>
598     *
599     *  <ul>
600     *      <li>Tag = 42240</li>
601     *      <li>Type = Unsigned rational</li>
602     *      <li>Count = 1</li>
603     *      <li>Default = None</li>
604     *  </ul>
605     */
606    public static final String TAG_GAMMA = "Gamma";
607
608    // C. Tags related to image configuration
609    /**
610     *  <p>Information specific to compressed data. When a compressed file is recorded, the valid
611     *  width of the meaningful image shall be recorded in this tag, whether or not there is padding
612     *  data or a restart marker. This tag shall not exist in an uncompressed file.</p>
613     *
614     *  <ul>
615     *      <li>Tag = 40962</li>
616     *      <li>Type = Unsigned short or Unsigned long</li>
617     *      <li>Count = 1</li>
618     *      <li>Default = None</li>
619     *  </ul>
620     */
621    public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
622    /**
623     *  <p>Information specific to compressed data. When a compressed file is recorded, the valid
624     *  height of the meaningful image shall be recorded in this tag, whether or not there is
625     *  padding data or a restart marker. This tag shall not exist in an uncompressed file.
626     *  Since data padding is unnecessary in the vertical direction, the number of lines recorded
627     *  in this valid image height tag will in fact be the same as that recorded in the SOF.</p>
628     *
629     *  <ul>
630     *      <li>Tag = 40963</li>
631     *      <li>Type = Unsigned short or Unsigned long</li>
632     *      <li>Count = 1</li>
633     *  </ul>
634     */
635    public static final String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
636    /**
637     *  <p>Information specific to compressed data. The channels of each component are arranged
638     *  in order from the 1st component to the 4th. For uncompressed data the data arrangement is
639     *  given in the {@link #TAG_PHOTOMETRIC_INTERPRETATION}. However, since
640     *  {@link #TAG_PHOTOMETRIC_INTERPRETATION} can only express the order of Y, Cb and Cr, this tag
641     *  is provided for cases when compressed data uses components other than Y, Cb, and Cr and to
642     *  enable support of other sequences.</p>
643     *
644     *  <ul>
645     *      <li>Tag = 37121</li>
646     *      <li>Type = Undefined</li>
647     *      <li>Length = 4</li>
648     *      <li>Default = 4 5 6 0 (if RGB uncompressed) or 1 2 3 0 (other cases)</li>
649     *      <ul>
650     *          <li>0 = does not exist</li>
651     *          <li>1 = Y</li>
652     *          <li>2 = Cb</li>
653     *          <li>3 = Cr</li>
654     *          <li>4 = R</li>
655     *          <li>5 = G</li>
656     *          <li>6 = B</li>
657     *          <li>other = reserved</li>
658     *      </ul>
659     *  </ul>
660     */
661    public static final String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
662    /**
663     *  <p>Information specific to compressed data. The compression mode used for a compressed image
664     *  is indicated in unit bits per pixel.</p>
665     *
666     *  <ul>
667     *      <li>Tag = 37122</li>
668     *      <li>Type = Unsigned rational</li>
669     *      <li>Count = 1</li>
670     *      <li>Default = None</li>
671     *  </ul>
672     */
673    public static final String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
674
675    // D. Tags related to user information
676    /**
677     *  <p>A tag for manufacturers of Exif/DCF writers to record any desired information.
678     *  The contents are up to the manufacturer, but this tag shall not be used for any other than
679     *  its intended purpose.</p>
680     *
681     *  <ul>
682     *      <li>Tag = 37500</li>
683     *      <li>Type = Undefined</li>
684     *      <li>Default = None</li>
685     *  </ul>
686     */
687    public static final String TAG_MAKER_NOTE = "MakerNote";
688    /**
689     *  <p>A tag for Exif users to write keywords or comments on the image besides those in
690     *  {@link #TAG_IMAGE_DESCRIPTION}, and without the character code limitations of it.</p>
691     *
692     *  <ul>
693     *      <li>Tag = 37510</li>
694     *      <li>Type = Undefined</li>
695     *      <li>Default = None</li>
696     *  </ul>
697     */
698    public static final String TAG_USER_COMMENT = "UserComment";
699
700    // E. Tags related to related file information
701    /**
702     *  <p>This tag is used to record the name of an audio file related to the image data. The only
703     *  relational information recorded here is the Exif audio file name and extension (an ASCII
704     *  string consisting of 8 characters + '.' + 3 characters). The path is not recorded.</p>
705     *
706     *  <p>When using this tag, audio files shall be recorded in conformance to the Exif audio
707     *  format. Writers can also store the data such as Audio within APP2 as Flashpix extension
708     *  stream data. Audio files shall be recorded in conformance to the Exif audio format.</p>
709     *
710     *  <ul>
711     *      <li>Tag = 40964</li>
712     *      <li>Type = String</li>
713     *      <li>Length = 12</li>
714     *      <li>Default = None</li>
715     *  </ul>
716     */
717    public static final String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
718
719    // F. Tags related to date and time
720    /**
721     *  <p>The date and time when the original image data was generated. For a DSC the date and time
722     *  the picture was taken are recorded. The format is "YYYY:MM:DD HH:MM:SS" with time shown in
723     *  24-hour format, and the date and time separated by one blank character ({@code 0x20}).
724     *  When the date and time are unknown, all the character spaces except colons (":") should be
725     *  filled with blank characters, or else the Interoperability field should be filled with blank
726     *  characters. When the field is left blank, it is treated as unknown.</p>
727     *
728     *  <ul>
729     *      <li>Tag = 36867</li>
730     *      <li>Type = String</li>
731     *      <li>Length = 19</li>
732     *      <li>Default = None</li>
733     *  </ul>
734     */
735    public static final String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
736    /**
737     *  <p>The date and time when the image was stored as digital data. If, for example, an image
738     *  was captured by DSC and at the same time the file was recorded, then
739     *  {@link #TAG_DATETIME_ORIGINAL} and this tag will have the same contents. The format is
740     *  "YYYY:MM:DD HH:MM:SS" with time shown in 24-hour format, and the date and time separated by
741     *  one blank character ({@code 0x20}). When the date and time are unknown, all the character
742     *  spaces except colons (":")should be filled with blank characters, or else
743     *  the Interoperability field should be filled with blank characters. When the field is left
744     *  blank, it is treated as unknown.</p>
745     *
746     *  <ul>
747     *      <li>Tag = 36868</li>
748     *      <li>Type = String</li>
749     *      <li>Length = 19</li>
750     *      <li>Default = None</li>
751     *  </ul>
752     */
753    public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
754    /**
755     *  <p>A tag used to record fractions of seconds for {@link #TAG_DATETIME}.</p>
756     *
757     *  <ul>
758     *      <li>Tag = 37520</li>
759     *      <li>Type = String</li>
760     *      <li>Default = None</li>
761     *  </ul>
762     */
763    public static final String TAG_SUBSEC_TIME = "SubSecTime";
764    /**
765     *  <p>A tag used to record fractions of seconds for {@link #TAG_DATETIME_ORIGINAL}.</p>
766     *
767     *  <ul>
768     *      <li>Tag = 37521</li>
769     *      <li>Type = String</li>
770     *      <li>Default = None</li>
771     *  </ul>
772     */
773    public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
774    /**
775     *  <p>A tag used to record fractions of seconds for {@link #TAG_DATETIME_DIGITIZED}.</p>
776     *
777     *  <ul>
778     *      <li>Tag = 37522</li>
779     *      <li>Type = String</li>
780     *      <li>Default = None</li>
781     *  </ul>
782     */
783    public static final String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
784
785    // G. Tags related to picture-taking condition
786    /**
787     *  <p>Exposure time, given in seconds.</p>
788     *
789     *  <ul>
790     *      <li>Tag = 33434</li>
791     *      <li>Type = Unsigned rational</li>
792     *      <li>Count = 1</li>
793     *      <li>Default = None</li>
794     *  </ul>
795     */
796    public static final String TAG_EXPOSURE_TIME = "ExposureTime";
797    /**
798     *  <p>The F number.</p>
799     *
800     *  <ul>
801     *      <li>Tag = 33437</li>
802     *      <li>Type = Unsigned rational</li>
803     *      <li>Count = 1</li>
804     *      <li>Default = None</li>
805     *  </ul>
806     */
807    public static final String TAG_F_NUMBER = "FNumber";
808    /**
809     *  <p>TThe class of the program used by the camera to set exposure when the picture is taken.
810     *  The tag values are as follows.</p>
811     *
812     *  <ul>
813     *      <li>Tag = 34850</li>
814     *      <li>Type = Unsigned short</li>
815     *      <li>Count = 1</li>
816     *      <li>Default = {@link #EXPOSURE_PROGRAM_NOT_DEFINED}</li>
817     *  </ul>
818     *
819     *  @see #EXPOSURE_PROGRAM_NOT_DEFINED
820     *  @see #EXPOSURE_PROGRAM_MANUAL
821     *  @see #EXPOSURE_PROGRAM_NORMAL
822     *  @see #EXPOSURE_PROGRAM_APERTURE_PRIORITY
823     *  @see #EXPOSURE_PROGRAM_SHUTTER_PRIORITY
824     *  @see #EXPOSURE_PROGRAM_CREATIVE
825     *  @see #EXPOSURE_PROGRAM_ACTION
826     *  @see #EXPOSURE_PROGRAM_PORTRAIT_MODE
827     *  @see #EXPOSURE_PROGRAM_LANDSCAPE_MODE
828     */
829    public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
830    /**
831     *  <p>Indicates the spectral sensitivity of each channel of the camera used. The tag value is
832     *  an ASCII string compatible with the standard developed by the ASTM Technical committee.</p>
833     *
834     *  <ul>
835     *      <li>Tag = 34852</li>
836     *      <li>Type = String</li>
837     *      <li>Default = None</li>
838     *  </ul>
839     */
840    public static final String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
841    /**
842     *  @deprecated Use {@link #TAG_PHOTOGRAPHIC_SENSITIVITY} instead.
843     *  @see #TAG_PHOTOGRAPHIC_SENSITIVITY
844     */
845    @Deprecated public static final String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
846    /**
847     *  <p>This tag indicates the sensitivity of the camera or input device when the image was shot.
848     *  More specifically, it indicates one of the following values that are parameters defined in
849     *  ISO 12232: standard output sensitivity (SOS), recommended exposure index (REI), or ISO
850     *  speed. Accordingly, if a tag corresponding to a parameter that is designated by
851     *  {@link #TAG_SENSITIVITY_TYPE} is recorded, the values of the tag and of this tag are
852     *  the same. However, if the value is 65535 or higher, the value of this tag shall be 65535.
853     *  When recording this tag, {@link #TAG_SENSITIVITY_TYPE} should also be recorded. In addition,
854     *  while “Count = Any”, only 1 count should be used when recording this tag.</p>
855     *
856     *  <ul>
857     *      <li>Tag = 34855</li>
858     *      <li>Type = Unsigned short</li>
859     *      <li>Count = Any</li>
860     *      <li>Default = None</li>
861     *  </ul>
862     */
863    public static final String TAG_PHOTOGRAPHIC_SENSITIVITY = "PhotographicSensitivity";
864    /**
865     *  <p>Indicates the Opto-Electric Conversion Function (OECF) specified in ISO 14524. OECF is
866     *  the relationship between the camera optical input and the image values.</p>
867     *
868     *  <ul>
869     *      <li>Tag = 34856</li>
870     *      <li>Type = Undefined</li>
871     *      <li>Default = None</li>
872     *  </ul>
873     */
874    public static final String TAG_OECF = "OECF";
875    /**
876     *  <p>This tag indicates which one of the parameters of ISO12232 is
877     *  {@link #TAG_PHOTOGRAPHIC_SENSITIVITY}. Although it is an optional tag, it should be recorded
878     *  when {@link #TAG_PHOTOGRAPHIC_SENSITIVITY} is recorded.</p>
879     *
880     *  <ul>
881     *      <li>Tag = 34864</li>
882     *      <li>Type = Unsigned short</li>
883     *      <li>Count = 1</li>
884     *      <li>Default = None</li>
885     *  </ul>
886     *
887     *  @see #SENSITIVITY_TYPE_UNKNOWN
888     *  @see #SENSITIVITY_TYPE_SOS
889     *  @see #SENSITIVITY_TYPE_REI
890     *  @see #SENSITIVITY_TYPE_ISO_SPEED
891     *  @see #SENSITIVITY_TYPE_SOS_AND_REI
892     *  @see #SENSITIVITY_TYPE_SOS_AND_ISO
893     *  @see #SENSITIVITY_TYPE_REI_AND_ISO
894     *  @see #SENSITIVITY_TYPE_SOS_AND_REI_AND_ISO
895     */
896    public static final String TAG_SENSITIVITY_TYPE = "SensitivityType";
897    /**
898     *  <p>This tag indicates the standard output sensitivity value of a camera or input device
899     *  defined in ISO 12232. When recording this tag, {@link #TAG_PHOTOGRAPHIC_SENSITIVITY} and
900     *  {@link #TAG_SENSITIVITY_TYPE} shall also be recorded.</p>
901     *
902     *  <ul>
903     *      <li>Tag = 34865</li>
904     *      <li>Type = Unsigned long</li>
905     *      <li>Count = 1</li>
906     *      <li>Default = None</li>
907     *  </ul>
908     */
909    public static final String TAG_STANDARD_OUTPUT_SENSITIVITY = "StandardOutputSensitivity";
910    /**
911     *  <p>This tag indicates the recommended exposure index value of a camera or input device
912     *  defined in ISO 12232. When recording this tag, {@link #TAG_PHOTOGRAPHIC_SENSITIVITY} and
913     *  {@link #TAG_SENSITIVITY_TYPE} shall also be recorded.</p>
914     *
915     *  <ul>
916     *      <li>Tag = 34866</li>
917     *      <li>Type = Unsigned long</li>
918     *      <li>Count = 1</li>
919     *      <li>Default = None</li>
920     *  </ul>
921     */
922    public static final String TAG_RECOMMENDED_EXPOSURE_INDEX = "RecommendedExposureIndex";
923    /**
924     *  <p>This tag indicates the ISO speed value of a camera or input device that is defined in
925     *  ISO 12232. When recording this tag, {@link #TAG_PHOTOGRAPHIC_SENSITIVITY} and
926     *  {@link #TAG_SENSITIVITY_TYPE} shall also be recorded.</p>
927     *
928     *  <ul>
929     *      <li>Tag = 34867</li>
930     *      <li>Type = Unsigned long</li>
931     *      <li>Count = 1</li>
932     *      <li>Default = None</li>
933     *  </ul>
934     */
935    public static final String TAG_ISO_SPEED = "ISOSpeed";
936    /**
937     *  <p>This tag indicates the ISO speed latitude yyy value of a camera or input device that is
938     *  defined in ISO 12232. However, this tag shall not be recorded without {@link #TAG_ISO_SPEED}
939     *  and {@link #TAG_ISO_SPEED_LATITUDE_ZZZ}.</p>
940     *
941     *  <ul>
942     *      <li>Tag = 34868</li>
943     *      <li>Type = Unsigned long</li>
944     *      <li>Count = 1</li>
945     *      <li>Default = None</li>
946     *  </ul>
947     */
948    public static final String TAG_ISO_SPEED_LATITUDE_YYY = "ISOSpeedLatitudeyyy";
949    /**
950     *  <p>This tag indicates the ISO speed latitude zzz value of a camera or input device that is
951     *  defined in ISO 12232. However, this tag shall not be recorded without {@link #TAG_ISO_SPEED}
952     *  and {@link #TAG_ISO_SPEED_LATITUDE_YYY}.</p>
953     *
954     *  <ul>
955     *      <li>Tag = 34869</li>
956     *      <li>Type = Unsigned long</li>
957     *      <li>Count = 1</li>
958     *      <li>Default = None</li>
959     *  </ul>
960     */
961    public static final String TAG_ISO_SPEED_LATITUDE_ZZZ = "ISOSpeedLatitudezzz";
962    /**
963     *  <p>Shutter speed. The unit is the APEX setting.</p>
964     *
965     *  <ul>
966     *      <li>Tag = 37377</li>
967     *      <li>Type = Signed rational</li>
968     *      <li>Count = 1</li>
969     *      <li>Default = None</li>
970     *  </ul>
971     */
972    public static final String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
973    /**
974     *  <p>The lens aperture. The unit is the APEX value.</p>
975     *
976     *  <ul>
977     *      <li>Tag = 37378</li>
978     *      <li>Type = Unsigned rational</li>
979     *      <li>Count = 1</li>
980     *      <li>Default = None</li>
981     *  </ul>
982     */
983    public static final String TAG_APERTURE_VALUE = "ApertureValue";
984    /**
985     *  <p>The value of brightness. The unit is the APEX value. Ordinarily it is given in the range
986     *  of -99.99 to 99.99. Note that if the numerator of the recorded value is 0xFFFFFFFF,
987     *  Unknown shall be indicated.</p>
988     *
989     *  <ul>
990     *      <li>Tag = 37379</li>
991     *      <li>Type = Signed rational</li>
992     *      <li>Count = 1</li>
993     *      <li>Default = None</li>
994     *  </ul>
995     */
996    public static final String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
997    /**
998     *  <p>The exposure bias. The unit is the APEX value. Ordinarily it is given in the range of
999     *  -99.99 to 99.99.</p>
1000     *
1001     *  <ul>
1002     *      <li>Tag = 37380</li>
1003     *      <li>Type = Signed rational</li>
1004     *      <li>Count = 1</li>
1005     *      <li>Default = None</li>
1006     *  </ul>
1007     */
1008    public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
1009    /**
1010     *  <p>The smallest F number of the lens. The unit is the APEX value. Ordinarily it is given
1011     *  in the range of 00.00 to 99.99, but it is not limited to this range.</p>
1012     *
1013     *  <ul>
1014     *      <li>Tag = 37381</li>
1015     *      <li>Type = Unsigned rational</li>
1016     *      <li>Count = 1</li>
1017     *      <li>Default = None</li>
1018     *  </ul>
1019     */
1020    public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
1021    /**
1022     *  <p>The distance to the subject, given in meters. Note that if the numerator of the recorded
1023     *  value is 0xFFFFFFFF, Infinity shall be indicated; and if the numerator is 0, Distance
1024     *  unknown shall be indicated.</p>
1025     *
1026     *  <ul>
1027     *      <li>Tag = 37382</li>
1028     *      <li>Type = Unsigned rational</li>
1029     *      <li>Count = 1</li>
1030     *      <li>Default = None</li>
1031     *  </ul>
1032     */
1033    public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance";
1034    /**
1035     *  <p>The metering mode.</p>
1036     *
1037     *  <ul>
1038     *      <li>Tag = 37383</li>
1039     *      <li>Type = Unsigned short</li>
1040     *      <li>Count = 1</li>
1041     *      <li>Default = {@link #METERING_MODE_UNKNOWN}</li>
1042     *  </ul>
1043     *
1044     *  @see #METERING_MODE_UNKNOWN
1045     *  @see #METERING_MODE_AVERAGE
1046     *  @see #METERING_MODE_CENTER_WEIGHT_AVERAGE
1047     *  @see #METERING_MODE_SPOT
1048     *  @see #METERING_MODE_MULTI_SPOT
1049     *  @see #METERING_MODE_PATTERN
1050     *  @see #METERING_MODE_PARTIAL
1051     *  @see #METERING_MODE_OTHER
1052     */
1053    public static final String TAG_METERING_MODE = "MeteringMode";
1054    /**
1055     *  <p>The kind of light source.</p>
1056     *
1057     *  <ul>
1058     *      <li>Tag = 37384</li>
1059     *      <li>Type = Unsigned short</li>
1060     *      <li>Count = 1</li>
1061     *      <li>Default = {@link #LIGHT_SOURCE_UNKNOWN}</li>
1062     *  </ul>
1063     *
1064     *  @see #LIGHT_SOURCE_UNKNOWN
1065     *  @see #LIGHT_SOURCE_DAYLIGHT
1066     *  @see #LIGHT_SOURCE_FLUORESCENT
1067     *  @see #LIGHT_SOURCE_TUNGSTEN
1068     *  @see #LIGHT_SOURCE_FLASH
1069     *  @see #LIGHT_SOURCE_FINE_WEATHER
1070     *  @see #LIGHT_SOURCE_CLOUDY_WEATHER
1071     *  @see #LIGHT_SOURCE_SHADE
1072     *  @see #LIGHT_SOURCE_DAYLIGHT_FLUORESCENT
1073     *  @see #LIGHT_SOURCE_DAY_WHITE_FLUORESCENT
1074     *  @see #LIGHT_SOURCE_COOL_WHITE_FLUORESCENT
1075     *  @see #LIGHT_SOURCE_WHITE_FLUORESCENT
1076     *  @see #LIGHT_SOURCE_WARM_WHITE_FLUORESCENT
1077     *  @see #LIGHT_SOURCE_STANDARD_LIGHT_A
1078     *  @see #LIGHT_SOURCE_STANDARD_LIGHT_B
1079     *  @see #LIGHT_SOURCE_STANDARD_LIGHT_C
1080     *  @see #LIGHT_SOURCE_D55
1081     *  @see #LIGHT_SOURCE_D65
1082     *  @see #LIGHT_SOURCE_D75
1083     *  @see #LIGHT_SOURCE_D50
1084     *  @see #LIGHT_SOURCE_ISO_STUDIO_TUNGSTEN
1085     *  @see #LIGHT_SOURCE_OTHER
1086     */
1087    public static final String TAG_LIGHT_SOURCE = "LightSource";
1088    /**
1089     *  <p>This tag indicates the status of flash when the image was shot. Bit 0 indicates the flash
1090     *  firing status, bits 1 and 2 indicate the flash return status, bits 3 and 4 indicate
1091     *  the flash mode, bit 5 indicates whether the flash function is present, and bit 6 indicates
1092     *  "red eye" mode.</p>
1093     *
1094     *  <ul>
1095     *      <li>Tag = 37385</li>
1096     *      <li>Type = Unsigned short</li>
1097     *      <li>Count = 1</li>
1098     *  </ul>
1099     *
1100     *  @see #FLAG_FLASH_FIRED
1101     *  @see #FLAG_FLASH_RETURN_LIGHT_NOT_DETECTED
1102     *  @see #FLAG_FLASH_RETURN_LIGHT_DETECTED
1103     *  @see #FLAG_FLASH_MODE_COMPULSORY_FIRING
1104     *  @see #FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION
1105     *  @see #FLAG_FLASH_MODE_AUTO
1106     *  @see #FLAG_FLASH_NO_FLASH_FUNCTION
1107     *  @see #FLAG_FLASH_RED_EYE_SUPPORTED
1108     */
1109    public static final String TAG_FLASH = "Flash";
1110    /**
1111     *  <p>This tag indicates the location and area of the main subject in the overall scene.</p>
1112     *
1113     *  <ul>
1114     *      <li>Tag = 37396</li>
1115     *      <li>Type = Unsigned short</li>
1116     *      <li>Count = 2 or 3 or 4</li>
1117     *      <li>Default = None</li>
1118     *  </ul>
1119     *
1120     *  <p>The subject location and area are defined by Count values as follows.</p>
1121     *
1122     *  <ul>
1123     *      <li>Count = 2 Indicates the location of the main subject as coordinates. The first value
1124     *                    is the X coordinate and the second is the Y coordinate.</li>
1125     *      <li>Count = 3 The area of the main subject is given as a circle. The circular area is
1126     *                    expressed as center coordinates and diameter. The first value is
1127     *                    the center X coordinate, the second is the center Y coordinate, and
1128     *                    the third is the diameter.</li>
1129     *      <li>Count = 4 The area of the main subject is given as a rectangle. The rectangular
1130     *                    area is expressed as center coordinates and area dimensions. The first
1131     *                    value is the center X coordinate, the second is the center Y coordinate,
1132     *                    the third is the width of the area, and the fourth is the height of
1133     *                    the area.</li>
1134     *  </ul>
1135     *
1136     *  <p>Note that the coordinate values, width, and height are expressed in relation to the upper
1137     *  left as origin, prior to rotation processing as per {@link #TAG_ORIENTATION}.</p>
1138     */
1139    public static final String TAG_SUBJECT_AREA = "SubjectArea";
1140    /**
1141     *  <p>The actual focal length of the lens, in mm. Conversion is not made to the focal length
1142     *  of a 35mm film camera.</p>
1143     *
1144     *  <ul>
1145     *      <li>Tag = 37386</li>
1146     *      <li>Type = Unsigned rational</li>
1147     *      <li>Count = 1</li>
1148     *      <li>Default = None</li>
1149     *  </ul>
1150     */
1151    public static final String TAG_FOCAL_LENGTH = "FocalLength";
1152    /**
1153     *  <p>Indicates the strobe energy at the time the image is captured, as measured in Beam Candle
1154     *  Power Seconds (BCPS).</p>
1155     *
1156     *  <ul>
1157     *      <li>Tag = 41483</li>
1158     *      <li>Type = Unsigned rational</li>
1159     *      <li>Count = 1</li>
1160     *      <li>Default = None</li>
1161     *  </ul>
1162     */
1163    public static final String TAG_FLASH_ENERGY = "FlashEnergy";
1164    /**
1165     *  <p>This tag records the camera or input device spatial frequency table and SFR values in
1166     *  the direction of image width, image height, and diagonal direction, as specified in
1167     *  ISO 12233.</p>
1168     *
1169     *  <ul>
1170     *      <li>Tag = 41484</li>
1171     *      <li>Type = Undefined</li>
1172     *      <li>Default = None</li>
1173     *  </ul>
1174     */
1175    public static final String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
1176    /**
1177     *  <p>Indicates the number of pixels in the image width (X) direction per
1178     *  {@link #TAG_FOCAL_PLANE_RESOLUTION_UNIT} on the camera focal plane.</p>
1179     *
1180     *  <ul>
1181     *      <li>Tag = 41486</li>
1182     *      <li>Type = Unsigned rational</li>
1183     *      <li>Count = 1</li>
1184     *      <li>Default = None</li>
1185     *  </ul>
1186     */
1187    public static final String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
1188    /**
1189     *  <p>Indicates the number of pixels in the image height (Y) direction per
1190     *  {@link #TAG_FOCAL_PLANE_RESOLUTION_UNIT} on the camera focal plane.</p>
1191     *
1192     *  <ul>
1193     *      <li>Tag = 41487</li>
1194     *      <li>Type = Unsigned rational</li>
1195     *      <li>Count = 1</li>
1196     *      <li>Default = None</li>
1197     *  </ul>
1198     */
1199    public static final String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
1200    /**
1201     *  <p>Indicates the unit for measuring {@link #TAG_FOCAL_PLANE_X_RESOLUTION} and
1202     *  {@link #TAG_FOCAL_PLANE_Y_RESOLUTION}. This value is the same as
1203     *  {@link #TAG_RESOLUTION_UNIT}.</p>
1204     *
1205     *  <ul>
1206     *      <li>Tag = 41488</li>
1207     *      <li>Type = Unsigned short</li>
1208     *      <li>Count = 1</li>
1209     *      <li>Default = {@link #RESOLUTION_UNIT_INCHES}</li>
1210     *  </ul>
1211     *
1212     *  @see #TAG_RESOLUTION_UNIT
1213     *  @see #RESOLUTION_UNIT_INCHES
1214     *  @see #RESOLUTION_UNIT_CENTIMETERS
1215     */
1216    public static final String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
1217    /**
1218     *  <p>Indicates the location of the main subject in the scene. The value of this tag represents
1219     *  the pixel at the center of the main subject relative to the left edge, prior to rotation
1220     *  processing as per {@link #TAG_ORIENTATION}. The first value indicates the X column number
1221     *  and second indicates the Y row number. When a camera records the main subject location,
1222     *  it is recommended that {@link #TAG_SUBJECT_AREA} be used instead of this tag.</p>
1223     *
1224     *  <ul>
1225     *      <li>Tag = 41492</li>
1226     *      <li>Type = Unsigned short</li>
1227     *      <li>Count = 2</li>
1228     *      <li>Default = None</li>
1229     *  </ul>
1230     */
1231    public static final String TAG_SUBJECT_LOCATION = "SubjectLocation";
1232    /**
1233     *  <p>Indicates the exposure index selected on the camera or input device at the time the image
1234     *  is captured.</p>
1235     *
1236     *  <ul>
1237     *      <li>Tag = 41493</li>
1238     *      <li>Type = Unsigned rational</li>
1239     *      <li>Count = 1</li>
1240     *      <li>Default = None</li>
1241     *  </ul>
1242     */
1243    public static final String TAG_EXPOSURE_INDEX = "ExposureIndex";
1244    /**
1245     *  <p>Indicates the image sensor type on the camera or input device.</p>
1246     *
1247     *  <ul>
1248     *      <li>Tag = 41495</li>
1249     *      <li>Type = Unsigned short</li>
1250     *      <li>Count = 1</li>
1251     *      <li>Default = None</li>
1252     *  </ul>
1253     *
1254     *  @see #SENSOR_TYPE_NOT_DEFINED
1255     *  @see #SENSOR_TYPE_ONE_CHIP
1256     *  @see #SENSOR_TYPE_TWO_CHIP
1257     *  @see #SENSOR_TYPE_THREE_CHIP
1258     *  @see #SENSOR_TYPE_COLOR_SEQUENTIAL
1259     *  @see #SENSOR_TYPE_TRILINEAR
1260     *  @see #SENSOR_TYPE_COLOR_SEQUENTIAL_LINEAR
1261     */
1262    public static final String TAG_SENSING_METHOD = "SensingMethod";
1263    /**
1264     *  <p>Indicates the image source. If a DSC recorded the image, this tag value always shall
1265     *  be set to {@link #FILE_SOURCE_DSC}.</p>
1266     *
1267     *  <ul>
1268     *      <li>Tag = 41728</li>
1269     *      <li>Type = Undefined</li>
1270     *      <li>Length = 1</li>
1271     *      <li>Default = {@link #FILE_SOURCE_DSC}</li>
1272     *  </ul>
1273     *
1274     *  @see #FILE_SOURCE_OTHER
1275     *  @see #FILE_SOURCE_TRANSPARENT_SCANNER
1276     *  @see #FILE_SOURCE_REFLEX_SCANNER
1277     *  @see #FILE_SOURCE_DSC
1278     */
1279    public static final String TAG_FILE_SOURCE = "FileSource";
1280    /**
1281     *  <p>Indicates the type of scene. If a DSC recorded the image, this tag value shall always
1282     *  be set to {@link #SCENE_TYPE_DIRECTLY_PHOTOGRAPHED}.</p>
1283     *
1284     *  <ul>
1285     *      <li>Tag = 41729</li>
1286     *      <li>Type = Undefined</li>
1287     *      <li>Length = 1</li>
1288     *      <li>Default = 1</li>
1289     *  </ul>
1290     *
1291     *  @see #SCENE_TYPE_DIRECTLY_PHOTOGRAPHED
1292     */
1293    public static final String TAG_SCENE_TYPE = "SceneType";
1294    /**
1295     *  <p>Indicates the color filter array (CFA) geometric pattern of the image sensor when
1296     *  a one-chip color area sensor is used. It does not apply to all sensing methods.</p>
1297     *
1298     *  <ul>
1299     *      <li>Tag = 41730</li>
1300     *      <li>Type = Undefined</li>
1301     *      <li>Default = None</li>
1302     *  </ul>
1303     *
1304     *  @see #TAG_SENSING_METHOD
1305     *  @see #SENSOR_TYPE_ONE_CHIP
1306     */
1307    public static final String TAG_CFA_PATTERN = "CFAPattern";
1308    /**
1309     *  <p>This tag indicates the use of special processing on image data, such as rendering geared
1310     *  to output. When special processing is performed, the Exif/DCF reader is expected to disable
1311     *  or minimize any further processing.</p>
1312     *
1313     *  <ul>
1314     *      <li>Tag = 41985</li>
1315     *      <li>Type = Unsigned short</li>
1316     *      <li>Count = 1</li>
1317     *      <li>Default = {@link #RENDERED_PROCESS_NORMAL}</li>
1318     *  </ul>
1319     *
1320     *  @see #RENDERED_PROCESS_NORMAL
1321     *  @see #RENDERED_PROCESS_CUSTOM
1322     */
1323    public static final String TAG_CUSTOM_RENDERED = "CustomRendered";
1324    /**
1325     *  <p>This tag indicates the exposure mode set when the image was shot.
1326     *  In {@link #EXPOSURE_MODE_AUTO_BRACKET}, the camera shoots a series of frames of the same
1327     *  scene at different exposure settings.</p>
1328     *
1329     *  <ul>
1330     *      <li>Tag = 41986</li>
1331     *      <li>Type = Unsigned short</li>
1332     *      <li>Count = 1</li>
1333     *      <li>Default = None</li>
1334     *  </ul>
1335     *
1336     *  @see #EXPOSURE_MODE_AUTO
1337     *  @see #EXPOSURE_MODE_MANUAL
1338     *  @see #EXPOSURE_MODE_AUTO_BRACKET
1339     */
1340    public static final String TAG_EXPOSURE_MODE = "ExposureMode";
1341    /**
1342     *  <p>This tag indicates the white balance mode set when the image was shot.</p>
1343     *
1344     *  <ul>
1345     *      <li>Tag = 41987</li>
1346     *      <li>Type = Unsigned short</li>
1347     *      <li>Count = 1</li>
1348     *      <li>Default = None</li>
1349     *  </ul>
1350     *
1351     *  @see #WHITEBALANCE_AUTO
1352     *  @see #WHITEBALANCE_MANUAL
1353     */
1354    public static final String TAG_WHITE_BALANCE = "WhiteBalance";
1355    /**
1356     *  <p>This tag indicates the digital zoom ratio when the image was shot. If the numerator of
1357     *  the recorded value is 0, this indicates that digital zoom was not used.</p>
1358     *
1359     *  <ul>
1360     *      <li>Tag = 41988</li>
1361     *      <li>Type = Unsigned rational</li>
1362     *      <li>Count = 1</li>
1363     *      <li>Default = None</li>
1364     *  </ul>
1365     */
1366    public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
1367    /**
1368     *  <p>This tag indicates the equivalent focal length assuming a 35mm film camera, in mm.
1369     *  A value of 0 means the focal length is unknown. Note that this tag differs from
1370     *  {@link #TAG_FOCAL_LENGTH}.</p>
1371     *
1372     *  <ul>
1373     *      <li>Tag = 41989</li>
1374     *      <li>Type = Unsigned short</li>
1375     *      <li>Count = 1</li>
1376     *      <li>Default = None</li>
1377     *  </ul>
1378     */
1379    public static final String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
1380    /**
1381     *  <p>This tag indicates the type of scene that was shot. It may also be used to record
1382     *  the mode in which the image was shot. Note that this differs from
1383     *  {@link #TAG_SCENE_TYPE}.</p>
1384     *
1385     *  <ul>
1386     *      <li>Tag = 41990</li>
1387     *      <li>Type = Unsigned short</li>
1388     *      <li>Count = 1</li>
1389     *      <li>Default = 0</li>
1390     *  </ul>
1391     *
1392     *  @see #SCENE_CAPTURE_TYPE_STANDARD
1393     *  @see #SCENE_CAPTURE_TYPE_LANDSCAPE
1394     *  @see #SCENE_CAPTURE_TYPE_PORTRAIT
1395     *  @see #SCENE_CAPTURE_TYPE_NIGHT
1396     */
1397    public static final String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
1398    /**
1399     *  <p>This tag indicates the degree of overall image gain adjustment.</p>
1400     *
1401     *  <ul>
1402     *      <li>Tag = 41991</li>
1403     *      <li>Type = Unsigned short</li>
1404     *      <li>Count = 1</li>
1405     *      <li>Default = None</li>
1406     *  </ul>
1407     *
1408     *  @see #GAIN_CONTROL_NONE
1409     *  @see #GAIN_CONTROL_LOW_GAIN_UP
1410     *  @see #GAIN_CONTROL_HIGH_GAIN_UP
1411     *  @see #GAIN_CONTROL_LOW_GAIN_DOWN
1412     *  @see #GAIN_CONTROL_HIGH_GAIN_DOWN
1413     */
1414    public static final String TAG_GAIN_CONTROL = "GainControl";
1415    /**
1416     *  <p>This tag indicates the direction of contrast processing applied by the camera when
1417     *  the image was shot.</p>
1418     *
1419     *  <ul>
1420     *      <li>Tag = 41992</li>
1421     *      <li>Type = Unsigned short</li>
1422     *      <li>Count = 1</li>
1423     *      <li>Default = {@link #CONTRAST_NORMAL}</li>
1424     *  </ul>
1425     *
1426     *  @see #CONTRAST_NORMAL
1427     *  @see #CONTRAST_SOFT
1428     *  @see #CONTRAST_HARD
1429     */
1430    public static final String TAG_CONTRAST = "Contrast";
1431    /**
1432     *  <p>This tag indicates the direction of saturation processing applied by the camera when
1433     *  the image was shot.</p>
1434     *
1435     *  <ul>
1436     *      <li>Tag = 41993</li>
1437     *      <li>Type = Unsigned short</li>
1438     *      <li>Count = 1</li>
1439     *      <li>Default = {@link #SATURATION_NORMAL}</li>
1440     *  </ul>
1441     *
1442     *  @see #SATURATION_NORMAL
1443     *  @see #SATURATION_LOW
1444     *  @see #SATURATION_HIGH
1445     */
1446    public static final String TAG_SATURATION = "Saturation";
1447    /**
1448     *  <p>This tag indicates the direction of sharpness processing applied by the camera when
1449     *  the image was shot.</p>
1450     *
1451     *  <ul>
1452     *      <li>Tag = 41994</li>
1453     *      <li>Type = Unsigned short</li>
1454     *      <li>Count = 1</li>
1455     *      <li>Default = {@link #SHARPNESS_NORMAL}</li>
1456     *  </ul>
1457     *
1458     *  @see #SHARPNESS_NORMAL
1459     *  @see #SHARPNESS_SOFT
1460     *  @see #SHARPNESS_HARD
1461     */
1462    public static final String TAG_SHARPNESS = "Sharpness";
1463    /**
1464     *  <p>This tag indicates information on the picture-taking conditions of a particular camera
1465     *  model. The tag is used only to indicate the picture-taking conditions in the Exif/DCF
1466     *  reader.</p>
1467     *
1468     *  <ul>
1469     *      <li>Tag = 41995</li>
1470     *      <li>Type = Undefined</li>
1471     *      <li>Default = None</li>
1472     *  </ul>
1473     */
1474    public static final String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
1475    /**
1476     *  <p>This tag indicates the distance to the subject.</p>
1477     *
1478     *  <ul>
1479     *      <li>Tag = 41996</li>
1480     *      <li>Type = Unsigned short</li>
1481     *      <li>Count = 1</li>
1482     *      <li>Default = None</li>
1483     *  </ul>
1484     *
1485     *  @see #SUBJECT_DISTANCE_RANGE_UNKNOWN
1486     *  @see #SUBJECT_DISTANCE_RANGE_MACRO
1487     *  @see #SUBJECT_DISTANCE_RANGE_CLOSE_VIEW
1488     *  @see #SUBJECT_DISTANCE_RANGE_DISTANT_VIEW
1489     */
1490    public static final String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
1491
1492    // H. Other tags
1493    /**
1494     *  <p>This tag indicates an identifier assigned uniquely to each image. It is recorded as
1495     *  an ASCII string equivalent to hexadecimal notation and 128-bit fixed length.</p>
1496     *
1497     *  <ul>
1498     *      <li>Tag = 42016</li>
1499     *      <li>Type = String</li>
1500     *      <li>Length = 32</li>
1501     *      <li>Default = None</li>
1502     *  </ul>
1503     */
1504    public static final String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
1505    /**
1506     *  <p>This tag records the owner of a camera used in photography as an ASCII string.</p>
1507     *
1508     *  <ul>
1509     *      <li>Tag = 42032</li>
1510     *      <li>Type = String</li>
1511     *      <li>Default = None</li>
1512     *  </ul>
1513     */
1514    public static final String TAG_CAMARA_OWNER_NAME = "CameraOwnerName";
1515    /**
1516     *  <p>This tag records the serial number of the body of the camera that was used in photography
1517     *  as an ASCII string.</p>
1518     *
1519     *  <ul>
1520     *      <li>Tag = 42033</li>
1521     *      <li>Type = String</li>
1522     *      <li>Default = None</li>
1523     *  </ul>
1524     */
1525    public static final String TAG_BODY_SERIAL_NUMBER = "BodySerialNumber";
1526    /**
1527     *  <p>This tag notes minimum focal length, maximum focal length, minimum F number in the
1528     *  minimum focal length, and minimum F number in the maximum focal length, which are
1529     *  specification information for the lens that was used in photography. When the minimum
1530     *  F number is unknown, the notation is 0/0.</p>
1531     *
1532     *  <ul>
1533     *      <li>Tag = 42034</li>
1534     *      <li>Type = Unsigned rational</li>
1535     *      <li>Count = 4</li>
1536     *      <li>Default = None</li>
1537     *      <ul>
1538     *          <li>Value 1 := Minimum focal length (unit: mm)</li>
1539     *          <li>Value 2 : = Maximum focal length (unit: mm)</li>
1540     *          <li>Value 3 : = Minimum F number in the minimum focal length</li>
1541     *          <li>Value 4 : = Minimum F number in the maximum focal length</li>
1542     *      </ul>
1543     *  </ul>
1544     */
1545    public static final String TAG_LENS_SPECIFICATION = "LensSpecification";
1546    /**
1547     *  <p>This tag records the lens manufacturer as an ASCII string.</p>
1548     *
1549     *  <ul>
1550     *      <li>Tag = 42035</li>
1551     *      <li>Type = String</li>
1552     *      <li>Default = None</li>
1553     *  </ul>
1554     */
1555    public static final String TAG_LENS_MAKE = "LensMake";
1556    /**
1557     *  <p>This tag records the lens’s model name and model number as an ASCII string.</p>
1558     *
1559     *  <ul>
1560     *      <li>Tag = 42036</li>
1561     *      <li>Type = String</li>
1562     *      <li>Default = None</li>
1563     *  </ul>
1564     */
1565    public static final String TAG_LENS_MODEL = "LensModel";
1566    /**
1567     *  <p>This tag records the serial number of the interchangeable lens that was used in
1568     *  photography as an ASCII string.</p>
1569     *
1570     *  <ul>
1571     *      <li>Tag = 42037</li>
1572     *      <li>Type = String</li>
1573     *      <li>Default = None</li>
1574     *  </ul>
1575     */
1576    public static final String TAG_LENS_SERIAL_NUMBER = "LensSerialNumber";
1577
1578    // GPS Attribute Information
1579    /**
1580     *  <p>Indicates the version of GPS Info IFD. The version is given as 2.3.0.0. This tag is
1581     *  mandatory when GPS-related tags are present. Note that this tag is written as a different
1582     *  byte than {@link #TAG_EXIF_VERSION}.</p>
1583     *
1584     *  <ul>
1585     *      <li>Tag = 0</li>
1586     *      <li>Type = Byte</li>
1587     *      <li>Count = 4</li>
1588     *      <li>Default = 2.3.0.0</li>
1589     *      <ul>
1590     *          <li>2300 = Version 2.3</li>
1591     *          <li>Other = reserved</li>
1592     *      </ul>
1593     *  </ul>
1594     */
1595    public static final String TAG_GPS_VERSION_ID = "GPSVersionID";
1596    /**
1597     *  <p>Indicates whether the latitude is north or south latitude.</p>
1598     *
1599     *  <ul>
1600     *      <li>Tag = 1</li>
1601     *      <li>Type = String</li>
1602     *      <li>Length = 1</li>
1603     *      <li>Default = None</li>
1604     *  </ul>
1605     *
1606     *  @see #LATITUDE_NORTH
1607     *  @see #LATITUDE_SOUTH
1608     */
1609    public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
1610    /**
1611     *  <p>Indicates the latitude. The latitude is expressed as three RATIONAL values giving
1612     *  the degrees, minutes, and seconds, respectively. If latitude is expressed as degrees,
1613     *  minutes and seconds, a typical format would be dd/1,mm/1,ss/1. When degrees and minutes are
1614     *  used and, for example, fractions of minutes are given up to two decimal places, the format
1615     *  would be dd/1,mmmm/100,0/1.</p>
1616     *
1617     *  <ul>
1618     *      <li>Tag = 2</li>
1619     *      <li>Type = Unsigned rational</li>
1620     *      <li>Count = 3</li>
1621     *      <li>Default = None</li>
1622     *  </ul>
1623     */
1624    public static final String TAG_GPS_LATITUDE = "GPSLatitude";
1625    /**
1626     *  <p>Indicates whether the longitude is east or west longitude.</p>
1627     *
1628     *  <ul>
1629     *      <li>Tag = 3</li>
1630     *      <li>Type = String</li>
1631     *      <li>Length = 1</li>
1632     *      <li>Default = None</li>
1633     *  </ul>
1634     *
1635     *  @see #LONGITUDE_EAST
1636     *  @see #LONGITUDE_WEST
1637     */
1638    public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
1639    /**
1640     *  <p>Indicates the longitude. The longitude is expressed as three RATIONAL values giving
1641     *  the degrees, minutes, and seconds, respectively. If longitude is expressed as degrees,
1642     *  minutes and seconds, a typical format would be ddd/1,mm/1,ss/1. When degrees and minutes
1643     *  are used and, for example, fractions of minutes are given up to two decimal places,
1644     *  the format would be ddd/1,mmmm/100,0/1.</p>
1645     *
1646     *  <ul>
1647     *      <li>Tag = 4</li>
1648     *      <li>Type = Unsigned rational</li>
1649     *      <li>Count = 3</li>
1650     *      <li>Default = None</li>
1651     *  </ul>
1652     */
1653    public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
1654    /**
1655     *  <p>Indicates the altitude used as the reference altitude. If the reference is sea level
1656     *  and the altitude is above sea level, 0 is given. If the altitude is below sea level,
1657     *  a value of 1 is given and the altitude is indicated as an absolute value in
1658     *  {@link #TAG_GPS_ALTITUDE}.</p>
1659     *
1660     *  <ul>
1661     *      <li>Tag = 5</li>
1662     *      <li>Type = Byte</li>
1663     *      <li>Count = 1</li>
1664     *      <li>Default = 0</li>
1665     *  </ul>
1666     *
1667     *  @see #ALTITUDE_ABOVE_SEA_LEVEL
1668     *  @see #ALTITUDE_BELOW_SEA_LEVEL
1669     */
1670    public static final String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
1671    /**
1672     *  <p>Indicates the altitude based on the reference in {@link #TAG_GPS_ALTITUDE_REF}.
1673     *  The reference unit is meters.</p>
1674     *
1675     *  <ul>
1676     *      <li>Tag = 6</li>
1677     *      <li>Type = Unsigned rational</li>
1678     *      <li>Count = 1</li>
1679     *      <li>Default = None</li>
1680     *  </ul>
1681     */
1682    public static final String TAG_GPS_ALTITUDE = "GPSAltitude";
1683    /**
1684     *  <p>Indicates the time as UTC (Coordinated Universal Time). TimeStamp is expressed as three
1685     *  unsigned rational values giving the hour, minute, and second.</p>
1686     *
1687     *  <ul>
1688     *      <li>Tag = 7</li>
1689     *      <li>Type = Unsigned rational</li>
1690     *      <li>Count = 3</li>
1691     *      <li>Default = None</li>
1692     *  </ul>
1693     */
1694    public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
1695    /**
1696     *  <p>Indicates the GPS satellites used for measurements. This tag may be used to describe
1697     *  the number of satellites, their ID number, angle of elevation, azimuth, SNR and other
1698     *  information in ASCII notation. The format is not specified. If the GPS receiver is incapable
1699     *  of taking measurements, value of the tag shall be set to {@code null}.</p>
1700     *
1701     *  <ul>
1702     *      <li>Tag = 8</li>
1703     *      <li>Type = String</li>
1704     *      <li>Default = None</li>
1705     *  </ul>
1706     */
1707    public static final String TAG_GPS_SATELLITES = "GPSSatellites";
1708    /**
1709     *  <p>Indicates the status of the GPS receiver when the image is recorded. 'A' means
1710     *  measurement is in progress, and 'V' means the measurement is interrupted.</p>
1711     *
1712     *  <ul>
1713     *      <li>Tag = 9</li>
1714     *      <li>Type = String</li>
1715     *      <li>Length = 1</li>
1716     *      <li>Default = None</li>
1717     *  </ul>
1718     *
1719     *  @see #GPS_MEASUREMENT_IN_PROGRESS
1720     *  @see #GPS_MEASUREMENT_INTERRUPTED
1721     */
1722    public static final String TAG_GPS_STATUS = "GPSStatus";
1723    /**
1724     *  <p>Indicates the GPS measurement mode. Originally it was defined for GPS, but it may
1725     *  be used for recording a measure mode to record the position information provided from
1726     *  a mobile base station or wireless LAN as well as GPS.</p>
1727     *
1728     *  <ul>
1729     *      <li>Tag = 10</li>
1730     *      <li>Type = String</li>
1731     *      <li>Length = 1</li>
1732     *      <li>Default = None</li>
1733     *  </ul>
1734     *
1735     *  @see #GPS_MEASUREMENT_2D
1736     *  @see #GPS_MEASUREMENT_3D
1737     */
1738    public static final String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
1739    /**
1740     *  <p>Indicates the GPS DOP (data degree of precision). An HDOP value is written during
1741     *  two-dimensional measurement, and PDOP during three-dimensional measurement.</p>
1742     *
1743     *  <ul>
1744     *      <li>Tag = 11</li>
1745     *      <li>Type = Unsigned rational</li>
1746     *      <li>Count = 1</li>
1747     *      <li>Default = None</li>
1748     *  </ul>
1749     */
1750    public static final String TAG_GPS_DOP = "GPSDOP";
1751    /**
1752     *  <p>Indicates the unit used to express the GPS receiver speed of movement.</p>
1753     *
1754     *  <ul>
1755     *      <li>Tag = 12</li>
1756     *      <li>Type = String</li>
1757     *      <li>Length = 1</li>
1758     *      <li>Default = {@link #GPS_SPEED_KILOMETERS_PER_HOUR}</li>
1759     *  </ul>
1760     *
1761     *  @see #GPS_SPEED_KILOMETERS_PER_HOUR
1762     *  @see #GPS_SPEED_MILES_PER_HOUR
1763     *  @see #GPS_SPEED_KNOTS
1764     */
1765    public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef";
1766    /**
1767     *  <p>Indicates the speed of GPS receiver movement.</p>
1768     *
1769     *  <ul>
1770     *      <li>Tag = 13</li>
1771     *      <li>Type = Unsigned rational</li>
1772     *      <li>Count = 1</li>
1773     *      <li>Default = None</li>
1774     *  </ul>
1775     */
1776    public static final String TAG_GPS_SPEED = "GPSSpeed";
1777    /**
1778     *  <p>Indicates the reference for giving the direction of GPS receiver movement.</p>
1779     *
1780     *  <ul>
1781     *      <li>Tag = 14</li>
1782     *      <li>Type = String</li>
1783     *      <li>Length = 1</li>
1784     *      <li>Default = {@link #GPS_DIRECTION_TRUE}</li>
1785     *  </ul>
1786     *
1787     *  @see #GPS_DIRECTION_TRUE
1788     *  @see #GPS_DIRECTION_MAGNETIC
1789     */
1790    public static final String TAG_GPS_TRACK_REF = "GPSTrackRef";
1791    /**
1792     *  <p>Indicates the direction of GPS receiver movement.
1793     *  The range of values is from 0.00 to 359.99.</p>
1794     *
1795     *  <ul>
1796     *      <li>Tag = 15</li>
1797     *      <li>Type = Unsigned rational</li>
1798     *      <li>Count = 1</li>
1799     *      <li>Default = None</li>
1800     *  </ul>
1801     */
1802    public static final String TAG_GPS_TRACK = "GPSTrack";
1803    /**
1804     *  <p>Indicates the reference for giving the direction of the image when it is captured.</p>
1805     *
1806     *  <ul>
1807     *      <li>Tag = 16</li>
1808     *      <li>Type = String</li>
1809     *      <li>Length = 1</li>
1810     *      <li>Default = {@link #GPS_DIRECTION_TRUE}</li>
1811     *  </ul>
1812     *
1813     *  @see #GPS_DIRECTION_TRUE
1814     *  @see #GPS_DIRECTION_MAGNETIC
1815     */
1816    public static final String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
1817    /**
1818     *  <p>ndicates the direction of the image when it was captured.
1819     *  The range of values is from 0.00 to 359.99.</p>
1820     *
1821     *  <ul>
1822     *      <li>Tag = 17</li>
1823     *      <li>Type = Unsigned rational</li>
1824     *      <li>Count = 1</li>
1825     *      <li>Default = None</li>
1826     *  </ul>
1827     */
1828    public static final String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
1829    /**
1830     *  <p>Indicates the geodetic survey data used by the GPS receiver. If the survey data is
1831     *  restricted to Japan,the value of this tag is 'TOKYO' or 'WGS-84'. If a GPS Info tag is
1832     *  recorded, it is strongly recommended that this tag be recorded.</p>
1833     *
1834     *  <ul>
1835     *      <li>Tag = 18</li>
1836     *      <li>Type = String</li>
1837     *      <li>Default = None</li>
1838     *  </ul>
1839     */
1840    public static final String TAG_GPS_MAP_DATUM = "GPSMapDatum";
1841    /**
1842     *  <p>Indicates whether the latitude of the destination point is north or south latitude.</p>
1843     *
1844     *  <ul>
1845     *      <li>Tag = 19</li>
1846     *      <li>Type = String</li>
1847     *      <li>Length = 1</li>
1848     *      <li>Default = None</li>
1849     *  </ul>
1850     *
1851     *  @see #LATITUDE_NORTH
1852     *  @see #LATITUDE_SOUTH
1853     */
1854    public static final String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
1855    /**
1856     *  <p>Indicates the latitude of the destination point. The latitude is expressed as three
1857     *  unsigned rational values giving the degrees, minutes, and seconds, respectively.
1858     *  If latitude is expressed as degrees, minutes and seconds, a typical format would be
1859     *  dd/1,mm/1,ss/1. When degrees and minutes are used and, for example, fractions of minutes
1860     *  are given up to two decimal places, the format would be dd/1, mmmm/100, 0/1.</p>
1861     *
1862     *  <ul>
1863     *      <li>Tag = 20</li>
1864     *      <li>Type = Unsigned rational</li>
1865     *      <li>Count = 3</li>
1866     *      <li>Default = None</li>
1867     *  </ul>
1868     */
1869    public static final String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
1870    /**
1871     *  <p>Indicates whether the longitude of the destination point is east or west longitude.</p>
1872     *
1873     *  <ul>
1874     *      <li>Tag = 21</li>
1875     *      <li>Type = String</li>
1876     *      <li>Length = 1</li>
1877     *      <li>Default = None</li>
1878     *  </ul>
1879     *
1880     *  @see #LONGITUDE_EAST
1881     *  @see #LONGITUDE_WEST
1882     */
1883    public static final String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
1884    /**
1885     *  <p>Indicates the longitude of the destination point. The longitude is expressed as three
1886     *  unsigned rational values giving the degrees, minutes, and seconds, respectively.
1887     *  If longitude is expressed as degrees, minutes and seconds, a typical format would be ddd/1,
1888     *  mm/1, ss/1. When degrees and minutes are used and, for example, fractions of minutes are
1889     *  given up to two decimal places, the format would be ddd/1, mmmm/100, 0/1.</p>
1890     *
1891     *  <ul>
1892     *      <li>Tag = 22</li>
1893     *      <li>Type = Unsigned rational</li>
1894     *      <li>Count = 3</li>
1895     *      <li>Default = None</li>
1896     *  </ul>
1897     */
1898    public static final String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
1899    /**
1900     *  <p>Indicates the reference used for giving the bearing to the destination point.</p>
1901     *
1902     *  <ul>
1903     *      <li>Tag = 23</li>
1904     *      <li>Type = String</li>
1905     *      <li>Length = 1</li>
1906     *      <li>Default = {@link #GPS_DIRECTION_TRUE}</li>
1907     *  </ul>
1908     *
1909     *  @see #GPS_DIRECTION_TRUE
1910     *  @see #GPS_DIRECTION_MAGNETIC
1911     */
1912    public static final String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
1913    /**
1914     *  <p>Indicates the bearing to the destination point.
1915     *  The range of values is from 0.00 to 359.99.</p>
1916     *
1917     *  <ul>
1918     *      <li>Tag = 24</li>
1919     *      <li>Type = Unsigned rational</li>
1920     *      <li>Count = 1</li>
1921     *      <li>Default = None</li>
1922     *  </ul>
1923     */
1924    public static final String TAG_GPS_DEST_BEARING = "GPSDestBearing";
1925    /**
1926     *  <p>Indicates the unit used to express the distance to the destination point.</p>
1927     *
1928     *  <ul>
1929     *      <li>Tag = 25</li>
1930     *      <li>Type = String</li>
1931     *      <li>Length = 1</li>
1932     *      <li>Default = {@link #GPS_DISTANCE_KILOMETERS}</li>
1933     *  </ul>
1934     *
1935     *  @see #GPS_DISTANCE_KILOMETERS
1936     *  @see #GPS_DISTANCE_MILES
1937     *  @see #GPS_DISTANCE_NAUTICAL_MILES
1938     */
1939    public static final String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
1940    /**
1941     *  <p>Indicates the distance to the destination point.</p>
1942     *
1943     *  <ul>
1944     *      <li>Tag = 26</li>
1945     *      <li>Type = Unsigned rational</li>
1946     *      <li>Count = 1</li>
1947     *      <li>Default = None</li>
1948     *  </ul>
1949     */
1950    public static final String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
1951    /**
1952     *  <p>A character string recording the name of the method used for location finding.
1953     *  The first byte indicates the character code used, and this is followed by the name of
1954     *  the method.</p>
1955     *
1956     *  <ul>
1957     *      <li>Tag = 27</li>
1958     *      <li>Type = Undefined</li>
1959     *      <li>Default = None</li>
1960     *  </ul>
1961     */
1962    public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
1963    /**
1964     *  <p>A character string recording the name of the GPS area. The first byte indicates
1965     *  the character code used, and this is followed by the name of the GPS area.</p>
1966     *
1967     *  <ul>
1968     *      <li>Tag = 28</li>
1969     *      <li>Type = Undefined</li>
1970     *      <li>Default = None</li>
1971     *  </ul>
1972     */
1973    public static final String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
1974    /**
1975     *  <p>A character string recording date and time information relative to UTC (Coordinated
1976     *  Universal Time). The format is "YYYY:MM:DD".</p>
1977     *
1978     *  <ul>
1979     *      <li>Tag = 29</li>
1980     *      <li>Type = String</li>
1981     *      <li>Length = 10</li>
1982     *      <li>Default = None</li>
1983     *  </ul>
1984     */
1985    public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";
1986    /**
1987     *  <p>Indicates whether differential correction is applied to the GPS receiver.</p>
1988     *
1989     *  <ul>
1990     *      <li>Tag = 30</li>
1991     *      <li>Type = Unsigned short</li>
1992     *      <li>Count = 1</li>
1993     *      <li>Default = None</li>
1994     *  </ul>
1995     *
1996     *  @see #GPS_MEASUREMENT_NO_DIFFERENTIAL
1997     *  @see #GPS_MEASUREMENT_DIFFERENTIAL_CORRECTED
1998     */
1999    public static final String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
2000    /**
2001     *  <p>This tag indicates horizontal positioning errors in meters.</p>
2002     *
2003     *  <ul>
2004     *      <li>Tag = 31</li>
2005     *      <li>Type = Unsigned rational</li>
2006     *      <li>Count = 1</li>
2007     *      <li>Default = None</li>
2008     *  </ul>
2009     */
2010    public static final String TAG_GPS_H_POSITIONING_ERROR = "GPSHPositioningError";
2011
2012    // Interoperability IFD Attribute Information
2013    /**
2014     *  <p>Indicates the identification of the Interoperability rule.</p>
2015     *
2016     *  <ul>
2017     *      <li>Tag = 1</li>
2018     *      <li>Type = String</li>
2019     *      <li>Length = 4</li>
2020     *      <li>Default = None</li>
2021     *      <ul>
2022     *          <li>"R98" = Indicates a file conforming to R98 file specification of Recommended
2023     *                      Exif Interoperability Rules (Exif R 98) or to DCF basic file stipulated
2024     *                      by Design Rule for Camera File System.</li>
2025     *          <li>"THM" = Indicates a file conforming to DCF thumbnail file stipulated by Design
2026     *                      rule for Camera File System.</li>
2027     *          <li>“R03” = Indicates a file conforming to DCF Option File stipulated by Design rule
2028     *                      for Camera File System.</li>
2029     *      </ul>
2030     *  </ul>
2031     */
2032    public static final String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
2033
2034    /**
2035     * @see #TAG_IMAGE_LENGTH
2036     */
2037    public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
2038    /**
2039     * @see #TAG_IMAGE_WIDTH
2040     */
2041    public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
2042    /** Type is int. DNG Specification 1.4.0.0. Section 4 */
2043    public static final String TAG_DNG_VERSION = "DNGVersion";
2044    /** Type is int. DNG Specification 1.4.0.0. Section 4 */
2045    public static final String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
2046    /** Type is undefined. See Olympus MakerNote tags in http://www.exiv2.org/tags-olympus.html. */
2047    public static final String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
2048    /** Type is int. See Olympus Camera Settings tags in http://www.exiv2.org/tags-olympus.html. */
2049    public static final String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
2050    /** Type is int. See Olympus Camera Settings tags in http://www.exiv2.org/tags-olympus.html. */
2051    public static final String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
2052    /** Type is int. See Olympus Image Processing tags in http://www.exiv2.org/tags-olympus.html. */
2053    public static final String TAG_ORF_ASPECT_FRAME = "AspectFrame";
2054    /**
2055     * Type is int. See PanasonicRaw tags in
2056     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
2057     */
2058    public static final String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
2059    /**
2060     * Type is int. See PanasonicRaw tags in
2061     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
2062     */
2063    public static final String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
2064    /**
2065     * Type is int. See PanasonicRaw tags in
2066     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
2067     */
2068    public static final String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
2069    /**
2070     * Type is int. See PanasonicRaw tags in
2071     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
2072     */
2073    public static final String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
2074    /**
2075     * Type is int. See PanasonicRaw tags in
2076     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
2077     */
2078    public static final String TAG_RW2_ISO = "ISO";
2079    /**
2080     * Type is undefined. See PanasonicRaw tags in
2081     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
2082     */
2083    public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
2084    /** Type is int. See JEITA CP-3451C Spec Section 3: Bilevel Images. */
2085    public static final String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
2086    /** Type is int. See JEITA CP-3451C Spec Section 3: Bilevel Images. */
2087    public static final String TAG_SUBFILE_TYPE = "SubfileType";
2088
2089    /**
2090     * Private tags used for pointing the other IFD offsets.
2091     * The types of the following tags are int.
2092     * See JEITA CP-3451C Section 4.6.3: Exif-specific IFD.
2093     * For SubIFD, see Note 1 of Adobe PageMaker® 6.0 TIFF Technical Notes.
2094     */
2095    private static final String TAG_EXIF_IFD_POINTER = "ExifIFDPointer";
2096    private static final String TAG_GPS_INFO_IFD_POINTER = "GPSInfoIFDPointer";
2097    private static final String TAG_INTEROPERABILITY_IFD_POINTER = "InteroperabilityIFDPointer";
2098    private static final String TAG_SUB_IFD_POINTER = "SubIFDPointer";
2099    // Proprietary pointer tags used for ORF files.
2100    // See http://www.exiv2.org/tags-olympus.html
2101    private static final String TAG_ORF_CAMERA_SETTINGS_IFD_POINTER = "CameraSettingsIFDPointer";
2102    private static final String TAG_ORF_IMAGE_PROCESSING_IFD_POINTER = "ImageProcessingIFDPointer";
2103
2104    // Private tags used for thumbnail information.
2105    private static final String TAG_HAS_THUMBNAIL = "HasThumbnail";
2106    private static final String TAG_THUMBNAIL_OFFSET = "ThumbnailOffset";
2107    private static final String TAG_THUMBNAIL_LENGTH = "ThumbnailLength";
2108    private static final String TAG_THUMBNAIL_DATA = "ThumbnailData";
2109    private static final int MAX_THUMBNAIL_SIZE = 512;
2110
2111    // Constants used for the Orientation Exif tag.
2112    public static final int ORIENTATION_UNDEFINED = 0;
2113    public static final int ORIENTATION_NORMAL = 1;
2114    /**
2115     * Indicates the image is left right reversed mirror.
2116     */
2117    public static final int ORIENTATION_FLIP_HORIZONTAL = 2;
2118    /**
2119     * Indicates the image is rotated by 180 degree clockwise.
2120     */
2121    public static final int ORIENTATION_ROTATE_180 = 3;
2122    /**
2123     * Indicates the image is upside down mirror, it can also be represented by flip
2124     * horizontally firstly and rotate 180 degree clockwise.
2125     */
2126    public static final int ORIENTATION_FLIP_VERTICAL = 4;
2127    /**
2128     * Indicates the image is flipped about top-left <--> bottom-right axis, it can also be
2129     * represented by flip horizontally firstly and rotate 270 degree clockwise.
2130     */
2131    public static final int ORIENTATION_TRANSPOSE = 5;
2132    /**
2133     * Indicates the image is rotated by 90 degree clockwise.
2134     */
2135    public static final int ORIENTATION_ROTATE_90 = 6;
2136    /**
2137     * Indicates the image is flipped about top-right <--> bottom-left axis, it can also be
2138     * represented by flip horizontally firstly and rotate 90 degree clockwise.
2139     */
2140    public static final int ORIENTATION_TRANSVERSE = 7;
2141    /**
2142     * Indicates the image is rotated by 270 degree clockwise.
2143     */
2144    public static final int ORIENTATION_ROTATE_270 = 8;
2145    private static final List<Integer> ROTATION_ORDER = Arrays.asList(ORIENTATION_NORMAL,
2146            ORIENTATION_ROTATE_90, ORIENTATION_ROTATE_180, ORIENTATION_ROTATE_270);
2147    private static final List<Integer> FLIPPED_ROTATION_ORDER = Arrays.asList(
2148            ORIENTATION_FLIP_HORIZONTAL, ORIENTATION_TRANSVERSE, ORIENTATION_FLIP_VERTICAL,
2149            ORIENTATION_TRANSPOSE);
2150
2151    /**
2152     * The contant used by {@link #TAG_PLANAR_CONFIGURATION} to denote Chunky format.
2153     */
2154    public static final short FORMAT_CHUNKY = 1;
2155    /**
2156     * The contant used by {@link #TAG_PLANAR_CONFIGURATION} to denote Planar format.
2157     */
2158    public static final short FORMAT_PLANAR = 2;
2159
2160    /**
2161     * The contant used by {@link #TAG_Y_CB_CR_POSITIONING} to denote Centered positioning.
2162     */
2163    public static final short Y_CB_CR_POSITIONING_CENTERED = 1;
2164    /**
2165     * The contant used by {@link #TAG_Y_CB_CR_POSITIONING} to denote Co-sited positioning.
2166     */
2167    public static final short Y_CB_CR_POSITIONING_CO_SITED = 2;
2168
2169    /**
2170     * The contant used to denote resolution unit as inches.
2171     */
2172    public static final short RESOLUTION_UNIT_INCHES = 2;
2173    /**
2174     * The contant used to denote resolution unit as centimeters.
2175     */
2176    public static final short RESOLUTION_UNIT_CENTIMETERS = 3;
2177
2178    /**
2179     * The contant used by {@link #TAG_COLOR_SPACE} to denote sRGB color space.
2180     */
2181    public static final int COLOR_SPACE_S_RGB = 1;
2182    /**
2183     * The contant used by {@link #TAG_COLOR_SPACE} to denote Uncalibrated.
2184     */
2185    public static final int COLOR_SPACE_UNCALIBRATED = 65535;
2186
2187    /**
2188     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is not defined.
2189     */
2190    public static final short EXPOSURE_PROGRAM_NOT_DEFINED = 0;
2191    /**
2192     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is Manual.
2193     */
2194    public static final short EXPOSURE_PROGRAM_MANUAL = 1;
2195    /**
2196     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is Normal.
2197     */
2198    public static final short EXPOSURE_PROGRAM_NORMAL = 2;
2199    /**
2200     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is
2201     * Aperture priority.
2202     */
2203    public static final short EXPOSURE_PROGRAM_APERTURE_PRIORITY = 3;
2204    /**
2205     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is
2206     * Shutter priority.
2207     */
2208    public static final short EXPOSURE_PROGRAM_SHUTTER_PRIORITY = 4;
2209    /**
2210     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is Creative
2211     * program (biased toward depth of field).
2212     */
2213    public static final short EXPOSURE_PROGRAM_CREATIVE = 5;
2214    /**
2215     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is Action
2216     * program (biased toward fast shutter speed).
2217     */
2218    public static final short EXPOSURE_PROGRAM_ACTION = 6;
2219    /**
2220     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is Portrait mode
2221     * (for closeup photos with the background out of focus).
2222     */
2223    public static final short EXPOSURE_PROGRAM_PORTRAIT_MODE = 7;
2224    /**
2225     * The contant used by {@link #TAG_EXPOSURE_PROGRAM} to denote exposure program is Landscape
2226     * mode (for landscape photos with the background in focus).
2227     */
2228    public static final short EXPOSURE_PROGRAM_LANDSCAPE_MODE = 8;
2229
2230    /**
2231     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is unknown.
2232     */
2233    public static final short SENSITIVITY_TYPE_UNKNOWN = 0;
2234    /**
2235     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is Standard
2236     * output sensitivity (SOS).
2237     */
2238    public static final short SENSITIVITY_TYPE_SOS = 1;
2239    /**
2240     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is Recommended
2241     * exposure index (REI).
2242     */
2243    public static final short SENSITIVITY_TYPE_REI = 2;
2244    /**
2245     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is ISO speed.
2246     */
2247    public static final short SENSITIVITY_TYPE_ISO_SPEED = 3;
2248    /**
2249     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is Standard
2250     * output sensitivity (SOS) and recommended exposure index (REI).
2251     */
2252    public static final short SENSITIVITY_TYPE_SOS_AND_REI = 4;
2253    /**
2254     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is Standard
2255     * output sensitivity (SOS) and ISO speed.
2256     */
2257    public static final short SENSITIVITY_TYPE_SOS_AND_ISO = 5;
2258    /**
2259     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is Recommended
2260     * exposure index (REI) and ISO speed.
2261     */
2262    public static final short SENSITIVITY_TYPE_REI_AND_ISO = 6;
2263    /**
2264     * The contant used by {@link #TAG_SENSITIVITY_TYPE} to denote sensitivity type is Standard
2265     * output sensitivity (SOS) and recommended exposure index (REI) and ISO speed.
2266     */
2267    public static final short SENSITIVITY_TYPE_SOS_AND_REI_AND_ISO = 7;
2268
2269    /**
2270     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is unknown.
2271     */
2272    public static final short METERING_MODE_UNKNOWN = 0;
2273    /**
2274     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is Average.
2275     */
2276    public static final short METERING_MODE_AVERAGE = 1;
2277    /**
2278     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is
2279     * CenterWeightedAverage.
2280     */
2281    public static final short METERING_MODE_CENTER_WEIGHT_AVERAGE = 2;
2282    /**
2283     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is Spot.
2284     */
2285    public static final short METERING_MODE_SPOT = 3;
2286    /**
2287     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is MultiSpot.
2288     */
2289    public static final short METERING_MODE_MULTI_SPOT = 4;
2290    /**
2291     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is Pattern.
2292     */
2293    public static final short METERING_MODE_PATTERN = 5;
2294    /**
2295     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is Partial.
2296     */
2297    public static final short METERING_MODE_PARTIAL = 6;
2298    /**
2299     * The contant used by {@link #TAG_METERING_MODE} to denote metering mode is other.
2300     */
2301    public static final short METERING_MODE_OTHER = 255;
2302
2303    /**
2304     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is unknown.
2305     */
2306    public static final short LIGHT_SOURCE_UNKNOWN = 0;
2307    /**
2308     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Daylight.
2309     */
2310    public static final short LIGHT_SOURCE_DAYLIGHT = 1;
2311    /**
2312     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Fluorescent.
2313     */
2314    public static final short LIGHT_SOURCE_FLUORESCENT = 2;
2315    /**
2316     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Tungsten
2317     * (incandescent light).
2318     */
2319    public static final short LIGHT_SOURCE_TUNGSTEN = 3;
2320    /**
2321     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Flash.
2322     */
2323    public static final short LIGHT_SOURCE_FLASH = 4;
2324    /**
2325     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Fine weather.
2326     */
2327    public static final short LIGHT_SOURCE_FINE_WEATHER = 9;
2328    /**
2329     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Cloudy weather.
2330     */
2331    public static final short LIGHT_SOURCE_CLOUDY_WEATHER = 10;
2332    /**
2333     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Shade.
2334     */
2335    public static final short LIGHT_SOURCE_SHADE = 11;
2336    /**
2337     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Daylight fluorescent
2338     * (D 5700 - 7100K).
2339     */
2340    public static final short LIGHT_SOURCE_DAYLIGHT_FLUORESCENT = 12;
2341    /**
2342     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Day white fluorescent
2343     * (N 4600 - 5500K).
2344     */
2345    public static final short LIGHT_SOURCE_DAY_WHITE_FLUORESCENT = 13;
2346    /**
2347     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Cool white
2348     * fluorescent (W 3800 - 4500K).
2349     */
2350    public static final short LIGHT_SOURCE_COOL_WHITE_FLUORESCENT = 14;
2351    /**
2352     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is White fluorescent
2353     * (WW 3250 - 3800K).
2354     */
2355    public static final short LIGHT_SOURCE_WHITE_FLUORESCENT = 15;
2356    /**
2357     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Warm white
2358     * fluorescent (L 2600 - 3250K).
2359     */
2360    public static final short LIGHT_SOURCE_WARM_WHITE_FLUORESCENT = 16;
2361    /**
2362     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Standard light A.
2363     */
2364    public static final short LIGHT_SOURCE_STANDARD_LIGHT_A = 17;
2365    /**
2366     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Standard light B.
2367     */
2368    public static final short LIGHT_SOURCE_STANDARD_LIGHT_B = 18;
2369    /**
2370     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is Standard light C.
2371     */
2372    public static final short LIGHT_SOURCE_STANDARD_LIGHT_C = 19;
2373    /**
2374     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is D55.
2375     */
2376    public static final short LIGHT_SOURCE_D55 = 20;
2377    /**
2378     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is D65.
2379     */
2380    public static final short LIGHT_SOURCE_D65 = 21;
2381    /**
2382     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is D75.
2383     */
2384    public static final short LIGHT_SOURCE_D75 = 22;
2385    /**
2386     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is D50.
2387     */
2388    public static final short LIGHT_SOURCE_D50 = 23;
2389    /**
2390     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is ISO studio tungsten.
2391     */
2392    public static final short LIGHT_SOURCE_ISO_STUDIO_TUNGSTEN = 24;
2393    /**
2394     * The contant used by {@link #TAG_LIGHT_SOURCE} to denote light source is other.
2395     */
2396    public static final short LIGHT_SOURCE_OTHER = 255;
2397
2398    /**
2399     * The flag used by {@link #TAG_FLASH} to indicate whether the flash is fired.
2400     */
2401    public static final short FLAG_FLASH_FIRED = 0b0000_0001;
2402    /**
2403     * The flag used by {@link #TAG_FLASH} to indicate strobe return light is not detected.
2404     */
2405    public static final short FLAG_FLASH_RETURN_LIGHT_NOT_DETECTED = 0b0000_0100;
2406    /**
2407     * The flag used by {@link #TAG_FLASH} to indicate strobe return light is detected.
2408     */
2409    public static final short FLAG_FLASH_RETURN_LIGHT_DETECTED = 0b0000_0110;
2410    /**
2411     * The flag used by {@link #TAG_FLASH} to indicate the camera's flash mode is Compulsory flash
2412     * firing.
2413     *
2414     * @see #FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION
2415     * @see #FLAG_FLASH_MODE_AUTO
2416     */
2417    public static final short FLAG_FLASH_MODE_COMPULSORY_FIRING = 0b0000_1000;
2418    /**
2419     * The flag used by {@link #TAG_FLASH} to indicate the camera's flash mode is Compulsory flash
2420     * suppression.
2421     *
2422     * @see #FLAG_FLASH_MODE_COMPULSORY_FIRING
2423     * @see #FLAG_FLASH_MODE_AUTO
2424     */
2425    public static final short FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION = 0b0001_0000;
2426    /**
2427     * The flag used by {@link #TAG_FLASH} to indicate the camera's flash mode is Auto.
2428     *
2429     * @see #FLAG_FLASH_MODE_COMPULSORY_FIRING
2430     * @see #FLAG_FLASH_MODE_COMPULSORY_SUPPRESSION
2431     */
2432    public static final short FLAG_FLASH_MODE_AUTO = 0b0001_1000;
2433    /**
2434     * The flag used by {@link #TAG_FLASH} to indicate no flash function is present.
2435     */
2436    public static final short FLAG_FLASH_NO_FLASH_FUNCTION = 0b0010_0000;
2437    /**
2438     * The flag used by {@link #TAG_FLASH} to indicate red-eye reduction is supported.
2439     */
2440    public static final short FLAG_FLASH_RED_EYE_SUPPORTED = 0b0100_0000;
2441
2442    /**
2443     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is not
2444     * defined.
2445     */
2446    public static final short SENSOR_TYPE_NOT_DEFINED = 1;
2447    /**
2448     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is One-chip
2449     * color area sensor.
2450     */
2451    public static final short SENSOR_TYPE_ONE_CHIP = 2;
2452    /**
2453     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is Two-chip
2454     * color area sensor.
2455     */
2456    public static final short SENSOR_TYPE_TWO_CHIP = 3;
2457    /**
2458     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is Three-chip
2459     * color area sensor.
2460     */
2461    public static final short SENSOR_TYPE_THREE_CHIP = 4;
2462    /**
2463     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is Color
2464     * sequential area sensor.
2465     */
2466    public static final short SENSOR_TYPE_COLOR_SEQUENTIAL = 5;
2467    /**
2468     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is Trilinear
2469     * sensor.
2470     */
2471    public static final short SENSOR_TYPE_TRILINEAR = 7;
2472    /**
2473     * The contant used by {@link #TAG_SENSING_METHOD} to denote the image sensor type is Color
2474     * sequential linear sensor.
2475     */
2476    public static final short SENSOR_TYPE_COLOR_SEQUENTIAL_LINEAR = 8;
2477
2478    /**
2479     * The contant used by {@link #TAG_FILE_SOURCE} to denote the source is other.
2480     */
2481    public static final short FILE_SOURCE_OTHER = 0;
2482    /**
2483     * The contant used by {@link #TAG_FILE_SOURCE} to denote the source is scanner of transparent
2484     * type.
2485     */
2486    public static final short FILE_SOURCE_TRANSPARENT_SCANNER = 1;
2487    /**
2488     * The contant used by {@link #TAG_FILE_SOURCE} to denote the source is scanner of reflex type.
2489     */
2490    public static final short FILE_SOURCE_REFLEX_SCANNER = 2;
2491    /**
2492     * The contant used by {@link #TAG_FILE_SOURCE} to denote the source is DSC.
2493     */
2494    public static final short FILE_SOURCE_DSC = 3;
2495
2496    /**
2497     * The contant used by {@link #TAG_SCENE_TYPE} to denote the scene is directly photographed.
2498     */
2499    public static final short SCENE_TYPE_DIRECTLY_PHOTOGRAPHED = 1;
2500
2501    /**
2502     * The contant used by {@link #TAG_CUSTOM_RENDERED} to denote no special processing is used.
2503     */
2504    public static final short RENDERED_PROCESS_NORMAL = 0;
2505    /**
2506     * The contant used by {@link #TAG_CUSTOM_RENDERED} to denote special processing is used.
2507     */
2508    public static final short RENDERED_PROCESS_CUSTOM = 1;
2509
2510    /**
2511     * The contant used by {@link #TAG_EXPOSURE_MODE} to denote the exposure mode is Auto.
2512     */
2513    public static final short EXPOSURE_MODE_AUTO = 0;
2514    /**
2515     * The contant used by {@link #TAG_EXPOSURE_MODE} to denote the exposure mode is Manual.
2516     */
2517    public static final short EXPOSURE_MODE_MANUAL = 1;
2518    /**
2519     * The contant used by {@link #TAG_EXPOSURE_MODE} to denote the exposure mode is Auto bracket.
2520     */
2521    public static final short EXPOSURE_MODE_AUTO_BRACKET = 2;
2522
2523    /**
2524     * The contant used by {@link #TAG_WHITE_BALANCE} to denote the white balance is Auto.
2525     *
2526     * @deprecated Use {@link #WHITE_BALANCE_AUTO} instead.
2527     */
2528    @Deprecated public static final int WHITEBALANCE_AUTO = 0;
2529    /**
2530     * The contant used by {@link #TAG_WHITE_BALANCE} to denote the white balance is Manual.
2531     *
2532     * @deprecated Use {@link #WHITE_BALANCE_MANUAL} instead.
2533     */
2534    @Deprecated public static final int WHITEBALANCE_MANUAL = 1;
2535    /**
2536     * The contant used by {@link #TAG_WHITE_BALANCE} to denote the white balance is Auto.
2537     */
2538    public static final short WHITE_BALANCE_AUTO = 0;
2539    /**
2540     * The contant used by {@link #TAG_WHITE_BALANCE} to denote the white balance is Manual.
2541     */
2542    public static final short WHITE_BALANCE_MANUAL = 1;
2543
2544    /**
2545     * The contant used by {@link #TAG_SCENE_CAPTURE_TYPE} to denote the scene capture type is
2546     * Standard.
2547     */
2548    public static final short SCENE_CAPTURE_TYPE_STANDARD = 0;
2549    /**
2550     * The contant used by {@link #TAG_SCENE_CAPTURE_TYPE} to denote the scene capture type is
2551     * Landscape.
2552     */
2553    public static final short SCENE_CAPTURE_TYPE_LANDSCAPE = 1;
2554    /**
2555     * The contant used by {@link #TAG_SCENE_CAPTURE_TYPE} to denote the scene capture type is
2556     * Portrait.
2557     */
2558    public static final short SCENE_CAPTURE_TYPE_PORTRAIT = 2;
2559    /**
2560     * The contant used by {@link #TAG_SCENE_CAPTURE_TYPE} to denote the scene capture type is Night
2561     * scene.
2562     */
2563    public static final short SCENE_CAPTURE_TYPE_NIGHT = 3;
2564
2565    /**
2566     * The contant used by {@link #TAG_GAIN_CONTROL} to denote none gain adjustment.
2567     */
2568    public static final short GAIN_CONTROL_NONE = 0;
2569    /**
2570     * The contant used by {@link #TAG_GAIN_CONTROL} to denote low gain up.
2571     */
2572    public static final short GAIN_CONTROL_LOW_GAIN_UP = 1;
2573    /**
2574     * The contant used by {@link #TAG_GAIN_CONTROL} to denote high gain up.
2575     */
2576    public static final short GAIN_CONTROL_HIGH_GAIN_UP = 2;
2577    /**
2578     * The contant used by {@link #TAG_GAIN_CONTROL} to denote low gain down.
2579     */
2580    public static final short GAIN_CONTROL_LOW_GAIN_DOWN = 3;
2581    /**
2582     * The contant used by {@link #TAG_GAIN_CONTROL} to denote high gain down.
2583     */
2584    public static final short GAIN_CONTROL_HIGH_GAIN_DOWN = 4;
2585
2586    /**
2587     * The contant used by {@link #TAG_CONTRAST} to denote normal contrast.
2588     */
2589    public static final short CONTRAST_NORMAL = 0;
2590    /**
2591     * The contant used by {@link #TAG_CONTRAST} to denote soft contrast.
2592     */
2593    public static final short CONTRAST_SOFT = 1;
2594    /**
2595     * The contant used by {@link #TAG_CONTRAST} to denote hard contrast.
2596     */
2597    public static final short CONTRAST_HARD = 2;
2598
2599    /**
2600     * The contant used by {@link #TAG_SATURATION} to denote normal saturation.
2601     */
2602    public static final short SATURATION_NORMAL = 0;
2603    /**
2604     * The contant used by {@link #TAG_SATURATION} to denote low saturation.
2605     */
2606    public static final short SATURATION_LOW = 0;
2607    /**
2608     * The contant used by {@link #TAG_SHARPNESS} to denote high saturation.
2609     */
2610    public static final short SATURATION_HIGH = 0;
2611
2612    /**
2613     * The contant used by {@link #TAG_SHARPNESS} to denote normal sharpness.
2614     */
2615    public static final short SHARPNESS_NORMAL = 0;
2616    /**
2617     * The contant used by {@link #TAG_SHARPNESS} to denote soft sharpness.
2618     */
2619    public static final short SHARPNESS_SOFT = 1;
2620    /**
2621     * The contant used by {@link #TAG_SHARPNESS} to denote hard sharpness.
2622     */
2623    public static final short SHARPNESS_HARD = 2;
2624
2625    /**
2626     * The contant used by {@link #TAG_SUBJECT_DISTANCE_RANGE} to denote the subject distance range
2627     * is unknown.
2628     */
2629    public static final short SUBJECT_DISTANCE_RANGE_UNKNOWN = 0;
2630    /**
2631     * The contant used by {@link #TAG_SUBJECT_DISTANCE_RANGE} to denote the subject distance range
2632     * is Macro.
2633     */
2634    public static final short SUBJECT_DISTANCE_RANGE_MACRO = 1;
2635    /**
2636     * The contant used by {@link #TAG_SUBJECT_DISTANCE_RANGE} to denote the subject distance range
2637     * is Close view.
2638     */
2639    public static final short SUBJECT_DISTANCE_RANGE_CLOSE_VIEW = 2;
2640    /**
2641     * The contant used by {@link #TAG_SUBJECT_DISTANCE_RANGE} to denote the subject distance range
2642     * is Distant view.
2643     */
2644    public static final short SUBJECT_DISTANCE_RANGE_DISTANT_VIEW = 3;
2645
2646    /**
2647     * The contant used by GPS latitude-related tags to denote the latitude is North latitude.
2648     *
2649     * @see #TAG_GPS_LATITUDE_REF
2650     * @see #TAG_GPS_DEST_LATITUDE_REF
2651     */
2652    public static final String LATITUDE_NORTH = "N";
2653    /**
2654     * The contant used by GPS latitude-related tags to denote the latitude is South latitude.
2655     *
2656     * @see #TAG_GPS_LATITUDE_REF
2657     * @see #TAG_GPS_DEST_LATITUDE_REF
2658     */
2659    public static final String LATITUDE_SOUTH = "S";
2660
2661    /**
2662     * The contant used by GPS longitude-related tags to denote the longitude is East longitude.
2663     *
2664     * @see #TAG_GPS_LONGITUDE_REF
2665     * @see #TAG_GPS_DEST_LONGITUDE_REF
2666     */
2667    public static final String LONGITUDE_EAST = "E";
2668    /**
2669     * The contant used by GPS longitude-related tags to denote the longitude is West longitude.
2670     *
2671     * @see #TAG_GPS_LONGITUDE_REF
2672     * @see #TAG_GPS_DEST_LONGITUDE_REF
2673     */
2674    public static final String LONGITUDE_WEST = "W";
2675
2676    /**
2677     * The contant used by {@link #TAG_GPS_ALTITUDE_REF} to denote the altitude is above sea level.
2678     */
2679    public static final short ALTITUDE_ABOVE_SEA_LEVEL = 0;
2680    /**
2681     * The contant used by {@link #TAG_GPS_ALTITUDE_REF} to denote the altitude is below sea level.
2682     */
2683    public static final short ALTITUDE_BELOW_SEA_LEVEL = 1;
2684
2685    /**
2686     * The contant used by {@link #TAG_GPS_STATUS} to denote GPS measurement is in progress.
2687     */
2688    public static final String GPS_MEASUREMENT_IN_PROGRESS = "A";
2689    /**
2690     * The contant used by {@link #TAG_GPS_STATUS} to denote GPS measurement is interrupted.
2691     */
2692    public static final String GPS_MEASUREMENT_INTERRUPTED = "V";
2693
2694    /**
2695     * The contant used by {@link #TAG_GPS_MEASURE_MODE} to denote GPS measurement is 2-dimensional.
2696     */
2697    public static final String GPS_MEASUREMENT_2D = "2";
2698    /**
2699     * The contant used by {@link #TAG_GPS_MEASURE_MODE} to denote GPS measurement is 3-dimensional.
2700     */
2701    public static final String GPS_MEASUREMENT_3D = "3";
2702
2703    /**
2704     * The contant used by {@link #TAG_GPS_SPEED_REF} to denote the speed unit is kilometers per
2705     * hour.
2706     */
2707    public static final String GPS_SPEED_KILOMETERS_PER_HOUR = "K";
2708    /**
2709     * The contant used by {@link #TAG_GPS_SPEED_REF} to denote the speed unit is miles per hour.
2710     */
2711    public static final String GPS_SPEED_MILES_PER_HOUR = "M";
2712    /**
2713     * The contant used by {@link #TAG_GPS_SPEED_REF} to denote the speed unit is knots.
2714     */
2715    public static final String GPS_SPEED_KNOTS = "N";
2716
2717    /**
2718     * The contant used by GPS attributes to denote the direction is true direction.
2719     */
2720    public static final String GPS_DIRECTION_TRUE = "T";
2721    /**
2722     * The contant used by GPS attributes to denote the direction is magnetic direction.
2723     */
2724    public static final String GPS_DIRECTION_MAGNETIC = "M";
2725
2726    /**
2727     * The contant used by {@link #TAG_GPS_DEST_DISTANCE_REF} to denote the distance unit is
2728     * kilometers.
2729     */
2730    public static final String GPS_DISTANCE_KILOMETERS = "K";
2731    /**
2732     * The contant used by {@link #TAG_GPS_DEST_DISTANCE_REF} to denote the distance unit is miles.
2733     */
2734    public static final String GPS_DISTANCE_MILES = "M";
2735    /**
2736     * The contant used by {@link #TAG_GPS_DEST_DISTANCE_REF} to denote the distance unit is
2737     * nautical miles.
2738     */
2739    public static final String GPS_DISTANCE_NAUTICAL_MILES = "N";
2740
2741    /**
2742     * The contant used by {@link #TAG_GPS_DIFFERENTIAL} to denote no differential correction is
2743     * applied.
2744     */
2745    public static final short GPS_MEASUREMENT_NO_DIFFERENTIAL = 0;
2746    /**
2747     * The contant used by {@link #TAG_GPS_DIFFERENTIAL} to denote differential correction is
2748     * applied.
2749     */
2750    public static final short GPS_MEASUREMENT_DIFFERENTIAL_CORRECTED = 1;
2751
2752    /**
2753     * The constant used by {@link #TAG_COMPRESSION} to denote the image is not compressed.
2754     */
2755    public static final int DATA_UNCOMPRESSED = 1;
2756    /**
2757     * The constant used by {@link #TAG_COMPRESSION} to denote the image is huffman compressed.
2758     */
2759    public static final int DATA_HUFFMAN_COMPRESSED = 2;
2760    /**
2761     * The constant used by {@link #TAG_COMPRESSION} to denote the image is JPEG.
2762     */
2763    public static final int DATA_JPEG = 6;
2764    /**
2765     * The constant used by {@link #TAG_COMPRESSION}, see DNG Specification 1.4.0.0.
2766     * Section 3, Compression
2767     */
2768    public static final int DATA_JPEG_COMPRESSED = 7;
2769    /**
2770     * The constant used by {@link #TAG_COMPRESSION}, see DNG Specification 1.4.0.0.
2771     * Section 3, Compression
2772     */
2773    public static final int DATA_DEFLATE_ZIP = 8;
2774    /**
2775     * The constant used by {@link #TAG_COMPRESSION} to denote the image is pack-bits compressed.
2776     */
2777    public static final int DATA_PACK_BITS_COMPRESSED = 32773;
2778    /**
2779     * The constant used by {@link #TAG_COMPRESSION}, see DNG Specification 1.4.0.0.
2780     * Section 3, Compression
2781     */
2782    public static final int DATA_LOSSY_JPEG = 34892;
2783
2784    /**
2785     * The constant used by {@link #TAG_BITS_PER_SAMPLE}.
2786     * See JEITA CP-3451C Spec Section 6, Differences from Palette Color Images
2787     */
2788    public static final int[] BITS_PER_SAMPLE_RGB = new int[] { 8, 8, 8 };
2789    /**
2790     * The constant used by {@link #TAG_BITS_PER_SAMPLE}.
2791     * See JEITA CP-3451C Spec Section 4, Differences from Bilevel Images
2792     */
2793    public static final int[] BITS_PER_SAMPLE_GREYSCALE_1 = new int[] { 4 };
2794    /**
2795     * The constant used by {@link #TAG_BITS_PER_SAMPLE}.
2796     * See JEITA CP-3451C Spec Section 4, Differences from Bilevel Images
2797     */
2798    public static final int[] BITS_PER_SAMPLE_GREYSCALE_2 = new int[] { 8 };
2799
2800    /**
2801     * The constant used by {@link #TAG_PHOTOMETRIC_INTERPRETATION}.
2802     */
2803    public static final int PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0;
2804    /**
2805     * The constant used by {@link #TAG_PHOTOMETRIC_INTERPRETATION}.
2806     */
2807    public static final int PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 1;
2808    /**
2809     * The constant used by {@link #TAG_PHOTOMETRIC_INTERPRETATION}.
2810     */
2811    public static final int PHOTOMETRIC_INTERPRETATION_RGB = 2;
2812    /**
2813     * The constant used by {@link #TAG_PHOTOMETRIC_INTERPRETATION}.
2814     */
2815    public static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6;
2816
2817    /**
2818     * The constant used by {@link #TAG_NEW_SUBFILE_TYPE}. See JEITA CP-3451C Spec Section 8.
2819     */
2820    public static final int ORIGINAL_RESOLUTION_IMAGE = 0;
2821    /**
2822     * The constant used by {@link #TAG_NEW_SUBFILE_TYPE}. See JEITA CP-3451C Spec Section 8.
2823     */
2824    public static final int REDUCED_RESOLUTION_IMAGE = 1;
2825
2826    // Maximum size for checking file type signature (see image_type_recognition_lite.cc)
2827    private static final int SIGNATURE_CHECK_SIZE = 5000;
2828
2829    static final byte[] JPEG_SIGNATURE = new byte[] {(byte) 0xff, (byte) 0xd8, (byte) 0xff};
2830    private static final String RAF_SIGNATURE = "FUJIFILMCCD-RAW";
2831    private static final int RAF_OFFSET_TO_JPEG_IMAGE_OFFSET = 84;
2832    private static final int RAF_INFO_SIZE = 160;
2833    private static final int RAF_JPEG_LENGTH_VALUE_SIZE = 4;
2834
2835    // See http://fileformats.archiveteam.org/wiki/Olympus_ORF
2836    private static final short ORF_SIGNATURE_1 = 0x4f52;
2837    private static final short ORF_SIGNATURE_2 = 0x5352;
2838    // There are two formats for Olympus Makernote Headers. Each has different identifiers and
2839    // offsets to the actual data.
2840    // See http://www.exiv2.org/makernote.html#R1
2841    private static final byte[] ORF_MAKER_NOTE_HEADER_1 = new byte[] {(byte) 0x4f, (byte) 0x4c,
2842            (byte) 0x59, (byte) 0x4d, (byte) 0x50, (byte) 0x00}; // "OLYMP\0"
2843    private static final byte[] ORF_MAKER_NOTE_HEADER_2 = new byte[] {(byte) 0x4f, (byte) 0x4c,
2844            (byte) 0x59, (byte) 0x4d, (byte) 0x50, (byte) 0x55, (byte) 0x53, (byte) 0x00,
2845            (byte) 0x49, (byte) 0x49}; // "OLYMPUS\0II"
2846    private static final int ORF_MAKER_NOTE_HEADER_1_SIZE = 8;
2847    private static final int ORF_MAKER_NOTE_HEADER_2_SIZE = 12;
2848
2849    // See http://fileformats.archiveteam.org/wiki/RW2
2850    private static final short RW2_SIGNATURE = 0x0055;
2851
2852    // See http://fileformats.archiveteam.org/wiki/Pentax_PEF
2853    private static final String PEF_SIGNATURE = "PENTAX";
2854    // See http://www.exiv2.org/makernote.html#R11
2855    private static final int PEF_MAKER_NOTE_SKIP_SIZE = 6;
2856
2857    private static SimpleDateFormat sFormatter;
2858
2859    // See Exchangeable image file format for digital still cameras: Exif version 2.2.
2860    // The following values are for parsing EXIF data area. There are tag groups in EXIF data area.
2861    // They are called "Image File Directory". They have multiple data formats to cover various
2862    // image metadata from GPS longitude to camera model name.
2863
2864    // Types of Exif byte alignments (see JEITA CP-3451C Section 4.5.2)
2865    static final short BYTE_ALIGN_II = 0x4949;  // II: Intel order
2866    static final short BYTE_ALIGN_MM = 0x4d4d;  // MM: Motorola order
2867
2868    // TIFF Header Fixed Constant (see JEITA CP-3451C Section 4.5.2)
2869    static final byte START_CODE = 0x2a; // 42
2870    private static final int IFD_OFFSET = 8;
2871
2872    // Formats for the value in IFD entry (See TIFF 6.0 Section 2, "Image File Directory".)
2873    private static final int IFD_FORMAT_BYTE = 1;
2874    private static final int IFD_FORMAT_STRING = 2;
2875    private static final int IFD_FORMAT_USHORT = 3;
2876    private static final int IFD_FORMAT_ULONG = 4;
2877    private static final int IFD_FORMAT_URATIONAL = 5;
2878    private static final int IFD_FORMAT_SBYTE = 6;
2879    private static final int IFD_FORMAT_UNDEFINED = 7;
2880    private static final int IFD_FORMAT_SSHORT = 8;
2881    private static final int IFD_FORMAT_SLONG = 9;
2882    private static final int IFD_FORMAT_SRATIONAL = 10;
2883    private static final int IFD_FORMAT_SINGLE = 11;
2884    private static final int IFD_FORMAT_DOUBLE = 12;
2885    // Format indicating a new IFD entry (See Adobe PageMaker® 6.0 TIFF Technical Notes, "New Tag")
2886    private static final int IFD_FORMAT_IFD = 13;
2887    // Names for the data formats for debugging purpose.
2888    static final String[] IFD_FORMAT_NAMES = new String[] {
2889            "", "BYTE", "STRING", "USHORT", "ULONG", "URATIONAL", "SBYTE", "UNDEFINED", "SSHORT",
2890            "SLONG", "SRATIONAL", "SINGLE", "DOUBLE"
2891    };
2892    // Sizes of the components of each IFD value format
2893    static final int[] IFD_FORMAT_BYTES_PER_FORMAT = new int[] {
2894            0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1
2895    };
2896    private static final byte[] EXIF_ASCII_PREFIX = new byte[] {
2897            0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0
2898    };
2899
2900    // A class for indicating EXIF rational type.
2901    private static class Rational {
2902        public final long numerator;
2903        public final long denominator;
2904
2905        private Rational(double value) {
2906            this((long) (value * 10000), 10000);
2907        }
2908
2909        private Rational(long numerator, long denominator) {
2910            // Handle erroneous case
2911            if (denominator == 0) {
2912                this.numerator = 0;
2913                this.denominator = 1;
2914                return;
2915            }
2916            this.numerator = numerator;
2917            this.denominator = denominator;
2918        }
2919
2920        @Override
2921        public String toString() {
2922            return numerator + "/" + denominator;
2923        }
2924
2925        public double calculate() {
2926            return (double) numerator / denominator;
2927        }
2928    }
2929
2930    // A class for indicating EXIF attribute.
2931    private static class ExifAttribute {
2932        public final int format;
2933        public final int numberOfComponents;
2934        public final byte[] bytes;
2935
2936        private ExifAttribute(int format, int numberOfComponents, byte[] bytes) {
2937            this.format = format;
2938            this.numberOfComponents = numberOfComponents;
2939            this.bytes = bytes;
2940        }
2941
2942        public static ExifAttribute createUShort(int[] values, ByteOrder byteOrder) {
2943            final ByteBuffer buffer = ByteBuffer.wrap(
2944                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_USHORT] * values.length]);
2945            buffer.order(byteOrder);
2946            for (int value : values) {
2947                buffer.putShort((short) value);
2948            }
2949            return new ExifAttribute(IFD_FORMAT_USHORT, values.length, buffer.array());
2950        }
2951
2952        public static ExifAttribute createUShort(int value, ByteOrder byteOrder) {
2953            return createUShort(new int[] {value}, byteOrder);
2954        }
2955
2956        public static ExifAttribute createULong(long[] values, ByteOrder byteOrder) {
2957            final ByteBuffer buffer = ByteBuffer.wrap(
2958                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_ULONG] * values.length]);
2959            buffer.order(byteOrder);
2960            for (long value : values) {
2961                buffer.putInt((int) value);
2962            }
2963            return new ExifAttribute(IFD_FORMAT_ULONG, values.length, buffer.array());
2964        }
2965
2966        public static ExifAttribute createULong(long value, ByteOrder byteOrder) {
2967            return createULong(new long[] {value}, byteOrder);
2968        }
2969
2970        public static ExifAttribute createSLong(int[] values, ByteOrder byteOrder) {
2971            final ByteBuffer buffer = ByteBuffer.wrap(
2972                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_SLONG] * values.length]);
2973            buffer.order(byteOrder);
2974            for (int value : values) {
2975                buffer.putInt(value);
2976            }
2977            return new ExifAttribute(IFD_FORMAT_SLONG, values.length, buffer.array());
2978        }
2979
2980        public static ExifAttribute createSLong(int value, ByteOrder byteOrder) {
2981            return createSLong(new int[] {value}, byteOrder);
2982        }
2983
2984        public static ExifAttribute createByte(String value) {
2985            // Exception for GPSAltitudeRef tag
2986            if (value.length() == 1 && value.charAt(0) >= '0' && value.charAt(0) <= '1') {
2987                final byte[] bytes = new byte[] { (byte) (value.charAt(0) - '0') };
2988                return new ExifAttribute(IFD_FORMAT_BYTE, bytes.length, bytes);
2989            }
2990            final byte[] ascii = value.getBytes(ASCII);
2991            return new ExifAttribute(IFD_FORMAT_BYTE, ascii.length, ascii);
2992        }
2993
2994        public static ExifAttribute createString(String value) {
2995            final byte[] ascii = (value + '\0').getBytes(ASCII);
2996            return new ExifAttribute(IFD_FORMAT_STRING, ascii.length, ascii);
2997        }
2998
2999        public static ExifAttribute createURational(Rational[] values, ByteOrder byteOrder) {
3000            final ByteBuffer buffer = ByteBuffer.wrap(
3001                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_URATIONAL] * values.length]);
3002            buffer.order(byteOrder);
3003            for (Rational value : values) {
3004                buffer.putInt((int) value.numerator);
3005                buffer.putInt((int) value.denominator);
3006            }
3007            return new ExifAttribute(IFD_FORMAT_URATIONAL, values.length, buffer.array());
3008        }
3009
3010        public static ExifAttribute createURational(Rational value, ByteOrder byteOrder) {
3011            return createURational(new Rational[] {value}, byteOrder);
3012        }
3013
3014        public static ExifAttribute createSRational(Rational[] values, ByteOrder byteOrder) {
3015            final ByteBuffer buffer = ByteBuffer.wrap(
3016                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_SRATIONAL] * values.length]);
3017            buffer.order(byteOrder);
3018            for (Rational value : values) {
3019                buffer.putInt((int) value.numerator);
3020                buffer.putInt((int) value.denominator);
3021            }
3022            return new ExifAttribute(IFD_FORMAT_SRATIONAL, values.length, buffer.array());
3023        }
3024
3025        public static ExifAttribute createSRational(Rational value, ByteOrder byteOrder) {
3026            return createSRational(new Rational[] {value}, byteOrder);
3027        }
3028
3029        public static ExifAttribute createDouble(double[] values, ByteOrder byteOrder) {
3030            final ByteBuffer buffer = ByteBuffer.wrap(
3031                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_DOUBLE] * values.length]);
3032            buffer.order(byteOrder);
3033            for (double value : values) {
3034                buffer.putDouble(value);
3035            }
3036            return new ExifAttribute(IFD_FORMAT_DOUBLE, values.length, buffer.array());
3037        }
3038
3039        public static ExifAttribute createDouble(double value, ByteOrder byteOrder) {
3040            return createDouble(new double[] {value}, byteOrder);
3041        }
3042
3043        @Override
3044        public String toString() {
3045            return "(" + IFD_FORMAT_NAMES[format] + ", data length:" + bytes.length + ")";
3046        }
3047
3048        private Object getValue(ByteOrder byteOrder) {
3049            ByteOrderedDataInputStream inputStream = null;
3050            try {
3051                inputStream = new ByteOrderedDataInputStream(bytes);
3052                inputStream.setByteOrder(byteOrder);
3053                switch (format) {
3054                    case IFD_FORMAT_BYTE:
3055                    case IFD_FORMAT_SBYTE: {
3056                        // Exception for GPSAltitudeRef tag
3057                        if (bytes.length == 1 && bytes[0] >= 0 && bytes[0] <= 1) {
3058                            return new String(new char[] { (char) (bytes[0] + '0') });
3059                        }
3060                        return new String(bytes, ASCII);
3061                    }
3062                    case IFD_FORMAT_UNDEFINED:
3063                    case IFD_FORMAT_STRING: {
3064                        int index = 0;
3065                        if (numberOfComponents >= EXIF_ASCII_PREFIX.length) {
3066                            boolean same = true;
3067                            for (int i = 0; i < EXIF_ASCII_PREFIX.length; ++i) {
3068                                if (bytes[i] != EXIF_ASCII_PREFIX[i]) {
3069                                    same = false;
3070                                    break;
3071                                }
3072                            }
3073                            if (same) {
3074                                index = EXIF_ASCII_PREFIX.length;
3075                            }
3076                        }
3077
3078                        StringBuilder stringBuilder = new StringBuilder();
3079                        while (index < numberOfComponents) {
3080                            int ch = bytes[index];
3081                            if (ch == 0) {
3082                                break;
3083                            }
3084                            if (ch >= 32) {
3085                                stringBuilder.append((char) ch);
3086                            } else {
3087                                stringBuilder.append('?');
3088                            }
3089                            ++index;
3090                        }
3091                        return stringBuilder.toString();
3092                    }
3093                    case IFD_FORMAT_USHORT: {
3094                        final int[] values = new int[numberOfComponents];
3095                        for (int i = 0; i < numberOfComponents; ++i) {
3096                            values[i] = inputStream.readUnsignedShort();
3097                        }
3098                        return values;
3099                    }
3100                    case IFD_FORMAT_ULONG: {
3101                        final long[] values = new long[numberOfComponents];
3102                        for (int i = 0; i < numberOfComponents; ++i) {
3103                            values[i] = inputStream.readUnsignedInt();
3104                        }
3105                        return values;
3106                    }
3107                    case IFD_FORMAT_URATIONAL: {
3108                        final Rational[] values = new Rational[numberOfComponents];
3109                        for (int i = 0; i < numberOfComponents; ++i) {
3110                            final long numerator = inputStream.readUnsignedInt();
3111                            final long denominator = inputStream.readUnsignedInt();
3112                            values[i] = new Rational(numerator, denominator);
3113                        }
3114                        return values;
3115                    }
3116                    case IFD_FORMAT_SSHORT: {
3117                        final int[] values = new int[numberOfComponents];
3118                        for (int i = 0; i < numberOfComponents; ++i) {
3119                            values[i] = inputStream.readShort();
3120                        }
3121                        return values;
3122                    }
3123                    case IFD_FORMAT_SLONG: {
3124                        final int[] values = new int[numberOfComponents];
3125                        for (int i = 0; i < numberOfComponents; ++i) {
3126                            values[i] = inputStream.readInt();
3127                        }
3128                        return values;
3129                    }
3130                    case IFD_FORMAT_SRATIONAL: {
3131                        final Rational[] values = new Rational[numberOfComponents];
3132                        for (int i = 0; i < numberOfComponents; ++i) {
3133                            final long numerator = inputStream.readInt();
3134                            final long denominator = inputStream.readInt();
3135                            values[i] = new Rational(numerator, denominator);
3136                        }
3137                        return values;
3138                    }
3139                    case IFD_FORMAT_SINGLE: {
3140                        final double[] values = new double[numberOfComponents];
3141                        for (int i = 0; i < numberOfComponents; ++i) {
3142                            values[i] = inputStream.readFloat();
3143                        }
3144                        return values;
3145                    }
3146                    case IFD_FORMAT_DOUBLE: {
3147                        final double[] values = new double[numberOfComponents];
3148                        for (int i = 0; i < numberOfComponents; ++i) {
3149                            values[i] = inputStream.readDouble();
3150                        }
3151                        return values;
3152                    }
3153                    default:
3154                        return null;
3155                }
3156            } catch (IOException e) {
3157                Log.w(TAG, "IOException occurred during reading a value", e);
3158                return null;
3159            } finally {
3160                if (inputStream != null) {
3161                    try {
3162                        inputStream.close();
3163                    } catch (IOException e) {
3164                        Log.e(TAG, "IOException occurred while closing InputStream", e);
3165                    }
3166                }
3167            }
3168        }
3169
3170        public double getDoubleValue(ByteOrder byteOrder) {
3171            Object value = getValue(byteOrder);
3172            if (value == null) {
3173                throw new NumberFormatException("NULL can't be converted to a double value");
3174            }
3175            if (value instanceof String) {
3176                return Double.parseDouble((String) value);
3177            }
3178            if (value instanceof long[]) {
3179                long[] array = (long[]) value;
3180                if (array.length == 1) {
3181                    return array[0];
3182                }
3183                throw new NumberFormatException("There are more than one component");
3184            }
3185            if (value instanceof int[]) {
3186                int[] array = (int[]) value;
3187                if (array.length == 1) {
3188                    return array[0];
3189                }
3190                throw new NumberFormatException("There are more than one component");
3191            }
3192            if (value instanceof double[]) {
3193                double[] array = (double[]) value;
3194                if (array.length == 1) {
3195                    return array[0];
3196                }
3197                throw new NumberFormatException("There are more than one component");
3198            }
3199            if (value instanceof Rational[]) {
3200                Rational[] array = (Rational[]) value;
3201                if (array.length == 1) {
3202                    return array[0].calculate();
3203                }
3204                throw new NumberFormatException("There are more than one component");
3205            }
3206            throw new NumberFormatException("Couldn't find a double value");
3207        }
3208
3209        public int getIntValue(ByteOrder byteOrder) {
3210            Object value = getValue(byteOrder);
3211            if (value == null) {
3212                throw new NumberFormatException("NULL can't be converted to a integer value");
3213            }
3214            if (value instanceof String) {
3215                return Integer.parseInt((String) value);
3216            }
3217            if (value instanceof long[]) {
3218                long[] array = (long[]) value;
3219                if (array.length == 1) {
3220                    return (int) array[0];
3221                }
3222                throw new NumberFormatException("There are more than one component");
3223            }
3224            if (value instanceof int[]) {
3225                int[] array = (int[]) value;
3226                if (array.length == 1) {
3227                    return array[0];
3228                }
3229                throw new NumberFormatException("There are more than one component");
3230            }
3231            throw new NumberFormatException("Couldn't find a integer value");
3232        }
3233
3234        public String getStringValue(ByteOrder byteOrder) {
3235            Object value = getValue(byteOrder);
3236            if (value == null) {
3237                return null;
3238            }
3239            if (value instanceof String) {
3240                return (String) value;
3241            }
3242
3243            final StringBuilder stringBuilder = new StringBuilder();
3244            if (value instanceof long[]) {
3245                long[] array = (long[]) value;
3246                for (int i = 0; i < array.length; ++i) {
3247                    stringBuilder.append(array[i]);
3248                    if (i + 1 != array.length) {
3249                        stringBuilder.append(",");
3250                    }
3251                }
3252                return stringBuilder.toString();
3253            }
3254            if (value instanceof int[]) {
3255                int[] array = (int[]) value;
3256                for (int i = 0; i < array.length; ++i) {
3257                    stringBuilder.append(array[i]);
3258                    if (i + 1 != array.length) {
3259                        stringBuilder.append(",");
3260                    }
3261                }
3262                return stringBuilder.toString();
3263            }
3264            if (value instanceof double[]) {
3265                double[] array = (double[]) value;
3266                for (int i = 0; i < array.length; ++i) {
3267                    stringBuilder.append(array[i]);
3268                    if (i + 1 != array.length) {
3269                        stringBuilder.append(",");
3270                    }
3271                }
3272                return stringBuilder.toString();
3273            }
3274            if (value instanceof Rational[]) {
3275                Rational[] array = (Rational[]) value;
3276                for (int i = 0; i < array.length; ++i) {
3277                    stringBuilder.append(array[i].numerator);
3278                    stringBuilder.append('/');
3279                    stringBuilder.append(array[i].denominator);
3280                    if (i + 1 != array.length) {
3281                        stringBuilder.append(",");
3282                    }
3283                }
3284                return stringBuilder.toString();
3285            }
3286            return null;
3287        }
3288
3289        public int size() {
3290            return IFD_FORMAT_BYTES_PER_FORMAT[format] * numberOfComponents;
3291        }
3292    }
3293
3294    // A class for indicating EXIF tag.
3295    static class ExifTag {
3296        public final int number;
3297        public final String name;
3298        public final int primaryFormat;
3299        public final int secondaryFormat;
3300
3301        private ExifTag(String name, int number, int format) {
3302            this.name = name;
3303            this.number = number;
3304            this.primaryFormat = format;
3305            this.secondaryFormat = -1;
3306        }
3307
3308        private ExifTag(String name, int number, int primaryFormat, int secondaryFormat) {
3309            this.name = name;
3310            this.number = number;
3311            this.primaryFormat = primaryFormat;
3312            this.secondaryFormat = secondaryFormat;
3313        }
3314
3315        private boolean isFormatCompatible(int format) {
3316            if (primaryFormat == IFD_FORMAT_UNDEFINED || format == IFD_FORMAT_UNDEFINED) {
3317                return true;
3318            } else if (primaryFormat == format || secondaryFormat == format) {
3319                return true;
3320            } else if ((primaryFormat == IFD_FORMAT_ULONG || secondaryFormat == IFD_FORMAT_ULONG)
3321                    && format == IFD_FORMAT_USHORT) {
3322                return true;
3323            } else if ((primaryFormat == IFD_FORMAT_SLONG || secondaryFormat == IFD_FORMAT_SLONG)
3324                    && format == IFD_FORMAT_SSHORT) {
3325                return true;
3326            } else if ((primaryFormat == IFD_FORMAT_DOUBLE || secondaryFormat == IFD_FORMAT_DOUBLE)
3327                    && format == IFD_FORMAT_SINGLE) {
3328                return true;
3329            }
3330            return false;
3331        }
3332    }
3333
3334    // Primary image IFD TIFF tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
3335    private static final ExifTag[] IFD_TIFF_TAGS = new ExifTag[] {
3336            // For below two, see TIFF 6.0 Spec Section 3: Bilevel Images.
3337            new ExifTag(TAG_NEW_SUBFILE_TYPE, 254, IFD_FORMAT_ULONG),
3338            new ExifTag(TAG_SUBFILE_TYPE, 255, IFD_FORMAT_ULONG),
3339            new ExifTag(TAG_IMAGE_WIDTH, 256, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3340            new ExifTag(TAG_IMAGE_LENGTH, 257, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3341            new ExifTag(TAG_BITS_PER_SAMPLE, 258, IFD_FORMAT_USHORT),
3342            new ExifTag(TAG_COMPRESSION, 259, IFD_FORMAT_USHORT),
3343            new ExifTag(TAG_PHOTOMETRIC_INTERPRETATION, 262, IFD_FORMAT_USHORT),
3344            new ExifTag(TAG_IMAGE_DESCRIPTION, 270, IFD_FORMAT_STRING),
3345            new ExifTag(TAG_MAKE, 271, IFD_FORMAT_STRING),
3346            new ExifTag(TAG_MODEL, 272, IFD_FORMAT_STRING),
3347            new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3348            new ExifTag(TAG_ORIENTATION, 274, IFD_FORMAT_USHORT),
3349            new ExifTag(TAG_SAMPLES_PER_PIXEL, 277, IFD_FORMAT_USHORT),
3350            new ExifTag(TAG_ROWS_PER_STRIP, 278, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3351            new ExifTag(TAG_STRIP_BYTE_COUNTS, 279, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3352            new ExifTag(TAG_X_RESOLUTION, 282, IFD_FORMAT_URATIONAL),
3353            new ExifTag(TAG_Y_RESOLUTION, 283, IFD_FORMAT_URATIONAL),
3354            new ExifTag(TAG_PLANAR_CONFIGURATION, 284, IFD_FORMAT_USHORT),
3355            new ExifTag(TAG_RESOLUTION_UNIT, 296, IFD_FORMAT_USHORT),
3356            new ExifTag(TAG_TRANSFER_FUNCTION, 301, IFD_FORMAT_USHORT),
3357            new ExifTag(TAG_SOFTWARE, 305, IFD_FORMAT_STRING),
3358            new ExifTag(TAG_DATETIME, 306, IFD_FORMAT_STRING),
3359            new ExifTag(TAG_ARTIST, 315, IFD_FORMAT_STRING),
3360            new ExifTag(TAG_WHITE_POINT, 318, IFD_FORMAT_URATIONAL),
3361            new ExifTag(TAG_PRIMARY_CHROMATICITIES, 319, IFD_FORMAT_URATIONAL),
3362            // See Adobe PageMaker® 6.0 TIFF Technical Notes, Note 1.
3363            new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG),
3364            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513, IFD_FORMAT_ULONG),
3365            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG),
3366            new ExifTag(TAG_Y_CB_CR_COEFFICIENTS, 529, IFD_FORMAT_URATIONAL),
3367            new ExifTag(TAG_Y_CB_CR_SUB_SAMPLING, 530, IFD_FORMAT_USHORT),
3368            new ExifTag(TAG_Y_CB_CR_POSITIONING, 531, IFD_FORMAT_USHORT),
3369            new ExifTag(TAG_REFERENCE_BLACK_WHITE, 532, IFD_FORMAT_URATIONAL),
3370            new ExifTag(TAG_COPYRIGHT, 33432, IFD_FORMAT_STRING),
3371            new ExifTag(TAG_EXIF_IFD_POINTER, 34665, IFD_FORMAT_ULONG),
3372            new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853, IFD_FORMAT_ULONG),
3373            // RW2 file tags
3374            // See http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html)
3375            new ExifTag(TAG_RW2_SENSOR_TOP_BORDER, 4, IFD_FORMAT_ULONG),
3376            new ExifTag(TAG_RW2_SENSOR_LEFT_BORDER, 5, IFD_FORMAT_ULONG),
3377            new ExifTag(TAG_RW2_SENSOR_BOTTOM_BORDER, 6, IFD_FORMAT_ULONG),
3378            new ExifTag(TAG_RW2_SENSOR_RIGHT_BORDER, 7, IFD_FORMAT_ULONG),
3379            new ExifTag(TAG_RW2_ISO, 23, IFD_FORMAT_USHORT),
3380            new ExifTag(TAG_RW2_JPG_FROM_RAW, 46, IFD_FORMAT_UNDEFINED)
3381    };
3382
3383    // Primary image IFD Exif Private tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
3384    private static final ExifTag[] IFD_EXIF_TAGS = new ExifTag[] {
3385            new ExifTag(TAG_EXPOSURE_TIME, 33434, IFD_FORMAT_URATIONAL),
3386            new ExifTag(TAG_F_NUMBER, 33437, IFD_FORMAT_URATIONAL),
3387            new ExifTag(TAG_EXPOSURE_PROGRAM, 34850, IFD_FORMAT_USHORT),
3388            new ExifTag(TAG_SPECTRAL_SENSITIVITY, 34852, IFD_FORMAT_STRING),
3389            new ExifTag(TAG_PHOTOGRAPHIC_SENSITIVITY, 34855, IFD_FORMAT_USHORT),
3390            new ExifTag(TAG_OECF, 34856, IFD_FORMAT_UNDEFINED),
3391            new ExifTag(TAG_EXIF_VERSION, 36864, IFD_FORMAT_STRING),
3392            new ExifTag(TAG_DATETIME_ORIGINAL, 36867, IFD_FORMAT_STRING),
3393            new ExifTag(TAG_DATETIME_DIGITIZED, 36868, IFD_FORMAT_STRING),
3394            new ExifTag(TAG_COMPONENTS_CONFIGURATION, 37121, IFD_FORMAT_UNDEFINED),
3395            new ExifTag(TAG_COMPRESSED_BITS_PER_PIXEL, 37122, IFD_FORMAT_URATIONAL),
3396            new ExifTag(TAG_SHUTTER_SPEED_VALUE, 37377, IFD_FORMAT_SRATIONAL),
3397            new ExifTag(TAG_APERTURE_VALUE, 37378, IFD_FORMAT_URATIONAL),
3398            new ExifTag(TAG_BRIGHTNESS_VALUE, 37379, IFD_FORMAT_SRATIONAL),
3399            new ExifTag(TAG_EXPOSURE_BIAS_VALUE, 37380, IFD_FORMAT_SRATIONAL),
3400            new ExifTag(TAG_MAX_APERTURE_VALUE, 37381, IFD_FORMAT_URATIONAL),
3401            new ExifTag(TAG_SUBJECT_DISTANCE, 37382, IFD_FORMAT_URATIONAL),
3402            new ExifTag(TAG_METERING_MODE, 37383, IFD_FORMAT_USHORT),
3403            new ExifTag(TAG_LIGHT_SOURCE, 37384, IFD_FORMAT_USHORT),
3404            new ExifTag(TAG_FLASH, 37385, IFD_FORMAT_USHORT),
3405            new ExifTag(TAG_FOCAL_LENGTH, 37386, IFD_FORMAT_URATIONAL),
3406            new ExifTag(TAG_SUBJECT_AREA, 37396, IFD_FORMAT_USHORT),
3407            new ExifTag(TAG_MAKER_NOTE, 37500, IFD_FORMAT_UNDEFINED),
3408            new ExifTag(TAG_USER_COMMENT, 37510, IFD_FORMAT_UNDEFINED),
3409            new ExifTag(TAG_SUBSEC_TIME, 37520, IFD_FORMAT_STRING),
3410            new ExifTag(TAG_SUBSEC_TIME_ORIGINAL, 37521, IFD_FORMAT_STRING),
3411            new ExifTag(TAG_SUBSEC_TIME_DIGITIZED, 37522, IFD_FORMAT_STRING),
3412            new ExifTag(TAG_FLASHPIX_VERSION, 40960, IFD_FORMAT_UNDEFINED),
3413            new ExifTag(TAG_COLOR_SPACE, 40961, IFD_FORMAT_USHORT),
3414            new ExifTag(TAG_PIXEL_X_DIMENSION, 40962, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3415            new ExifTag(TAG_PIXEL_Y_DIMENSION, 40963, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3416            new ExifTag(TAG_RELATED_SOUND_FILE, 40964, IFD_FORMAT_STRING),
3417            new ExifTag(TAG_INTEROPERABILITY_IFD_POINTER, 40965, IFD_FORMAT_ULONG),
3418            new ExifTag(TAG_FLASH_ENERGY, 41483, IFD_FORMAT_URATIONAL),
3419            new ExifTag(TAG_SPATIAL_FREQUENCY_RESPONSE, 41484, IFD_FORMAT_UNDEFINED),
3420            new ExifTag(TAG_FOCAL_PLANE_X_RESOLUTION, 41486, IFD_FORMAT_URATIONAL),
3421            new ExifTag(TAG_FOCAL_PLANE_Y_RESOLUTION, 41487, IFD_FORMAT_URATIONAL),
3422            new ExifTag(TAG_FOCAL_PLANE_RESOLUTION_UNIT, 41488, IFD_FORMAT_USHORT),
3423            new ExifTag(TAG_SUBJECT_LOCATION, 41492, IFD_FORMAT_USHORT),
3424            new ExifTag(TAG_EXPOSURE_INDEX, 41493, IFD_FORMAT_URATIONAL),
3425            new ExifTag(TAG_SENSING_METHOD, 41495, IFD_FORMAT_USHORT),
3426            new ExifTag(TAG_FILE_SOURCE, 41728, IFD_FORMAT_UNDEFINED),
3427            new ExifTag(TAG_SCENE_TYPE, 41729, IFD_FORMAT_UNDEFINED),
3428            new ExifTag(TAG_CFA_PATTERN, 41730, IFD_FORMAT_UNDEFINED),
3429            new ExifTag(TAG_CUSTOM_RENDERED, 41985, IFD_FORMAT_USHORT),
3430            new ExifTag(TAG_EXPOSURE_MODE, 41986, IFD_FORMAT_USHORT),
3431            new ExifTag(TAG_WHITE_BALANCE, 41987, IFD_FORMAT_USHORT),
3432            new ExifTag(TAG_DIGITAL_ZOOM_RATIO, 41988, IFD_FORMAT_URATIONAL),
3433            new ExifTag(TAG_FOCAL_LENGTH_IN_35MM_FILM, 41989, IFD_FORMAT_USHORT),
3434            new ExifTag(TAG_SCENE_CAPTURE_TYPE, 41990, IFD_FORMAT_USHORT),
3435            new ExifTag(TAG_GAIN_CONTROL, 41991, IFD_FORMAT_USHORT),
3436            new ExifTag(TAG_CONTRAST, 41992, IFD_FORMAT_USHORT),
3437            new ExifTag(TAG_SATURATION, 41993, IFD_FORMAT_USHORT),
3438            new ExifTag(TAG_SHARPNESS, 41994, IFD_FORMAT_USHORT),
3439            new ExifTag(TAG_DEVICE_SETTING_DESCRIPTION, 41995, IFD_FORMAT_UNDEFINED),
3440            new ExifTag(TAG_SUBJECT_DISTANCE_RANGE, 41996, IFD_FORMAT_USHORT),
3441            new ExifTag(TAG_IMAGE_UNIQUE_ID, 42016, IFD_FORMAT_STRING),
3442            new ExifTag(TAG_DNG_VERSION, 50706, IFD_FORMAT_BYTE),
3443            new ExifTag(TAG_DEFAULT_CROP_SIZE, 50720, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG)
3444    };
3445
3446    // Primary image IFD GPS Info tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
3447    private static final ExifTag[] IFD_GPS_TAGS = new ExifTag[] {
3448            new ExifTag(TAG_GPS_VERSION_ID, 0, IFD_FORMAT_BYTE),
3449            new ExifTag(TAG_GPS_LATITUDE_REF, 1, IFD_FORMAT_STRING),
3450            new ExifTag(TAG_GPS_LATITUDE, 2, IFD_FORMAT_URATIONAL),
3451            new ExifTag(TAG_GPS_LONGITUDE_REF, 3, IFD_FORMAT_STRING),
3452            new ExifTag(TAG_GPS_LONGITUDE, 4, IFD_FORMAT_URATIONAL),
3453            new ExifTag(TAG_GPS_ALTITUDE_REF, 5, IFD_FORMAT_BYTE),
3454            new ExifTag(TAG_GPS_ALTITUDE, 6, IFD_FORMAT_URATIONAL),
3455            new ExifTag(TAG_GPS_TIMESTAMP, 7, IFD_FORMAT_URATIONAL),
3456            new ExifTag(TAG_GPS_SATELLITES, 8, IFD_FORMAT_STRING),
3457            new ExifTag(TAG_GPS_STATUS, 9, IFD_FORMAT_STRING),
3458            new ExifTag(TAG_GPS_MEASURE_MODE, 10, IFD_FORMAT_STRING),
3459            new ExifTag(TAG_GPS_DOP, 11, IFD_FORMAT_URATIONAL),
3460            new ExifTag(TAG_GPS_SPEED_REF, 12, IFD_FORMAT_STRING),
3461            new ExifTag(TAG_GPS_SPEED, 13, IFD_FORMAT_URATIONAL),
3462            new ExifTag(TAG_GPS_TRACK_REF, 14, IFD_FORMAT_STRING),
3463            new ExifTag(TAG_GPS_TRACK, 15, IFD_FORMAT_URATIONAL),
3464            new ExifTag(TAG_GPS_IMG_DIRECTION_REF, 16, IFD_FORMAT_STRING),
3465            new ExifTag(TAG_GPS_IMG_DIRECTION, 17, IFD_FORMAT_URATIONAL),
3466            new ExifTag(TAG_GPS_MAP_DATUM, 18, IFD_FORMAT_STRING),
3467            new ExifTag(TAG_GPS_DEST_LATITUDE_REF, 19, IFD_FORMAT_STRING),
3468            new ExifTag(TAG_GPS_DEST_LATITUDE, 20, IFD_FORMAT_URATIONAL),
3469            new ExifTag(TAG_GPS_DEST_LONGITUDE_REF, 21, IFD_FORMAT_STRING),
3470            new ExifTag(TAG_GPS_DEST_LONGITUDE, 22, IFD_FORMAT_URATIONAL),
3471            new ExifTag(TAG_GPS_DEST_BEARING_REF, 23, IFD_FORMAT_STRING),
3472            new ExifTag(TAG_GPS_DEST_BEARING, 24, IFD_FORMAT_URATIONAL),
3473            new ExifTag(TAG_GPS_DEST_DISTANCE_REF, 25, IFD_FORMAT_STRING),
3474            new ExifTag(TAG_GPS_DEST_DISTANCE, 26, IFD_FORMAT_URATIONAL),
3475            new ExifTag(TAG_GPS_PROCESSING_METHOD, 27, IFD_FORMAT_UNDEFINED),
3476            new ExifTag(TAG_GPS_AREA_INFORMATION, 28, IFD_FORMAT_UNDEFINED),
3477            new ExifTag(TAG_GPS_DATESTAMP, 29, IFD_FORMAT_STRING),
3478            new ExifTag(TAG_GPS_DIFFERENTIAL, 30, IFD_FORMAT_USHORT)
3479    };
3480    // Primary image IFD Interoperability tag (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
3481    private static final ExifTag[] IFD_INTEROPERABILITY_TAGS = new ExifTag[] {
3482            new ExifTag(TAG_INTEROPERABILITY_INDEX, 1, IFD_FORMAT_STRING)
3483    };
3484    // IFD Thumbnail tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
3485    private static final ExifTag[] IFD_THUMBNAIL_TAGS = new ExifTag[] {
3486            // For below two, see TIFF 6.0 Spec Section 3: Bilevel Images.
3487            new ExifTag(TAG_NEW_SUBFILE_TYPE, 254, IFD_FORMAT_ULONG),
3488            new ExifTag(TAG_SUBFILE_TYPE, 255, IFD_FORMAT_ULONG),
3489            new ExifTag(TAG_THUMBNAIL_IMAGE_WIDTH, 256, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3490            new ExifTag(TAG_THUMBNAIL_IMAGE_LENGTH, 257, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3491            new ExifTag(TAG_BITS_PER_SAMPLE, 258, IFD_FORMAT_USHORT),
3492            new ExifTag(TAG_COMPRESSION, 259, IFD_FORMAT_USHORT),
3493            new ExifTag(TAG_PHOTOMETRIC_INTERPRETATION, 262, IFD_FORMAT_USHORT),
3494            new ExifTag(TAG_IMAGE_DESCRIPTION, 270, IFD_FORMAT_STRING),
3495            new ExifTag(TAG_MAKE, 271, IFD_FORMAT_STRING),
3496            new ExifTag(TAG_MODEL, 272, IFD_FORMAT_STRING),
3497            new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3498            new ExifTag(TAG_ORIENTATION, 274, IFD_FORMAT_USHORT),
3499            new ExifTag(TAG_SAMPLES_PER_PIXEL, 277, IFD_FORMAT_USHORT),
3500            new ExifTag(TAG_ROWS_PER_STRIP, 278, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3501            new ExifTag(TAG_STRIP_BYTE_COUNTS, 279, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
3502            new ExifTag(TAG_X_RESOLUTION, 282, IFD_FORMAT_URATIONAL),
3503            new ExifTag(TAG_Y_RESOLUTION, 283, IFD_FORMAT_URATIONAL),
3504            new ExifTag(TAG_PLANAR_CONFIGURATION, 284, IFD_FORMAT_USHORT),
3505            new ExifTag(TAG_RESOLUTION_UNIT, 296, IFD_FORMAT_USHORT),
3506            new ExifTag(TAG_TRANSFER_FUNCTION, 301, IFD_FORMAT_USHORT),
3507            new ExifTag(TAG_SOFTWARE, 305, IFD_FORMAT_STRING),
3508            new ExifTag(TAG_DATETIME, 306, IFD_FORMAT_STRING),
3509            new ExifTag(TAG_ARTIST, 315, IFD_FORMAT_STRING),
3510            new ExifTag(TAG_WHITE_POINT, 318, IFD_FORMAT_URATIONAL),
3511            new ExifTag(TAG_PRIMARY_CHROMATICITIES, 319, IFD_FORMAT_URATIONAL),
3512            // See Adobe PageMaker® 6.0 TIFF Technical Notes, Note 1.
3513            new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG),
3514            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513, IFD_FORMAT_ULONG),
3515            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG),
3516            new ExifTag(TAG_Y_CB_CR_COEFFICIENTS, 529, IFD_FORMAT_URATIONAL),
3517            new ExifTag(TAG_Y_CB_CR_SUB_SAMPLING, 530, IFD_FORMAT_USHORT),
3518            new ExifTag(TAG_Y_CB_CR_POSITIONING, 531, IFD_FORMAT_USHORT),
3519            new ExifTag(TAG_REFERENCE_BLACK_WHITE, 532, IFD_FORMAT_URATIONAL),
3520            new ExifTag(TAG_COPYRIGHT, 33432, IFD_FORMAT_STRING),
3521            new ExifTag(TAG_EXIF_IFD_POINTER, 34665, IFD_FORMAT_ULONG),
3522            new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853, IFD_FORMAT_ULONG),
3523            new ExifTag(TAG_DNG_VERSION, 50706, IFD_FORMAT_BYTE),
3524            new ExifTag(TAG_DEFAULT_CROP_SIZE, 50720, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG)
3525    };
3526
3527    // RAF file tag (See piex.cc line 372)
3528    private static final ExifTag TAG_RAF_IMAGE_SIZE =
3529            new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT);
3530
3531    // ORF file tags (See http://www.exiv2.org/tags-olympus.html)
3532    private static final ExifTag[] ORF_MAKER_NOTE_TAGS = new ExifTag[] {
3533            new ExifTag(TAG_ORF_THUMBNAIL_IMAGE, 256, IFD_FORMAT_UNDEFINED),
3534            new ExifTag(TAG_ORF_CAMERA_SETTINGS_IFD_POINTER, 8224, IFD_FORMAT_ULONG),
3535            new ExifTag(TAG_ORF_IMAGE_PROCESSING_IFD_POINTER, 8256, IFD_FORMAT_ULONG)
3536    };
3537    private static final ExifTag[] ORF_CAMERA_SETTINGS_TAGS = new ExifTag[] {
3538            new ExifTag(TAG_ORF_PREVIEW_IMAGE_START, 257, IFD_FORMAT_ULONG),
3539            new ExifTag(TAG_ORF_PREVIEW_IMAGE_LENGTH, 258, IFD_FORMAT_ULONG)
3540    };
3541    private static final ExifTag[] ORF_IMAGE_PROCESSING_TAGS = new ExifTag[] {
3542            new ExifTag(TAG_ORF_ASPECT_FRAME, 4371, IFD_FORMAT_USHORT)
3543    };
3544    // PEF file tag (See http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html)
3545    private static final ExifTag[] PEF_TAGS = new ExifTag[] {
3546            new ExifTag(TAG_COLOR_SPACE, 55, IFD_FORMAT_USHORT)
3547    };
3548
3549    // See JEITA CP-3451C Section 4.6.3: Exif-specific IFD.
3550    // The following values are used for indicating pointers to the other Image File Directories.
3551
3552    // Indices of Exif Ifd tag groups
3553    /** @hide */
3554    @RestrictTo(RestrictTo.Scope.LIBRARY)
3555    @Retention(RetentionPolicy.SOURCE)
3556    @IntDef({IFD_TYPE_PRIMARY, IFD_TYPE_EXIF, IFD_TYPE_GPS, IFD_TYPE_INTEROPERABILITY,
3557            IFD_TYPE_THUMBNAIL, IFD_TYPE_PREVIEW, IFD_TYPE_ORF_MAKER_NOTE,
3558            IFD_TYPE_ORF_CAMERA_SETTINGS, IFD_TYPE_ORF_IMAGE_PROCESSING, IFD_TYPE_PEF})
3559    public @interface IfdType {}
3560
3561    static final int IFD_TYPE_PRIMARY = 0;
3562    private static final int IFD_TYPE_EXIF = 1;
3563    private static final int IFD_TYPE_GPS = 2;
3564    private static final int IFD_TYPE_INTEROPERABILITY = 3;
3565    static final int IFD_TYPE_THUMBNAIL = 4;
3566    static final int IFD_TYPE_PREVIEW = 5;
3567    private static final int IFD_TYPE_ORF_MAKER_NOTE = 6;
3568    private static final int IFD_TYPE_ORF_CAMERA_SETTINGS = 7;
3569    private static final int IFD_TYPE_ORF_IMAGE_PROCESSING = 8;
3570    private static final int IFD_TYPE_PEF = 9;
3571
3572    // List of Exif tag groups
3573    static final ExifTag[][] EXIF_TAGS = new ExifTag[][] {
3574            IFD_TIFF_TAGS, IFD_EXIF_TAGS, IFD_GPS_TAGS, IFD_INTEROPERABILITY_TAGS,
3575            IFD_THUMBNAIL_TAGS, IFD_TIFF_TAGS, ORF_MAKER_NOTE_TAGS, ORF_CAMERA_SETTINGS_TAGS,
3576            ORF_IMAGE_PROCESSING_TAGS, PEF_TAGS
3577    };
3578    // List of tags for pointing to the other image file directory offset.
3579    private static final ExifTag[] EXIF_POINTER_TAGS = new ExifTag[] {
3580            new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG),
3581            new ExifTag(TAG_EXIF_IFD_POINTER, 34665, IFD_FORMAT_ULONG),
3582            new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853, IFD_FORMAT_ULONG),
3583            new ExifTag(TAG_INTEROPERABILITY_IFD_POINTER, 40965, IFD_FORMAT_ULONG),
3584            new ExifTag(TAG_ORF_CAMERA_SETTINGS_IFD_POINTER, 8224, IFD_FORMAT_BYTE),
3585            new ExifTag(TAG_ORF_IMAGE_PROCESSING_IFD_POINTER, 8256, IFD_FORMAT_BYTE)
3586    };
3587
3588    // Tags for indicating the thumbnail offset and length
3589    private static final ExifTag JPEG_INTERCHANGE_FORMAT_TAG =
3590            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513, IFD_FORMAT_ULONG);
3591    private static final ExifTag JPEG_INTERCHANGE_FORMAT_LENGTH_TAG =
3592            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG);
3593
3594    // Mappings from tag number to tag name and each item represents one IFD tag group.
3595    @SuppressWarnings("unchecked")
3596    private static final HashMap<Integer, ExifTag>[] sExifTagMapsForReading =
3597            new HashMap[EXIF_TAGS.length];
3598    // Mappings from tag name to tag number and each item represents one IFD tag group.
3599    @SuppressWarnings("unchecked")
3600    private static final HashMap<String, ExifTag>[] sExifTagMapsForWriting =
3601            new HashMap[EXIF_TAGS.length];
3602    private static final HashSet<String> sTagSetForCompatibility = new HashSet<>(Arrays.asList(
3603            TAG_F_NUMBER, TAG_DIGITAL_ZOOM_RATIO, TAG_EXPOSURE_TIME, TAG_SUBJECT_DISTANCE,
3604            TAG_GPS_TIMESTAMP));
3605    // Mappings from tag number to IFD type for pointer tags.
3606    @SuppressWarnings("unchecked")
3607    private static final HashMap<Integer, Integer> sExifPointerTagMap = new HashMap();
3608
3609    // See JPEG File Interchange Format Version 1.02.
3610    // The following values are defined for handling JPEG streams. In this implementation, we are
3611    // not only getting information from EXIF but also from some JPEG special segments such as
3612    // MARKER_COM for user comment and MARKER_SOFx for image width and height.
3613
3614    private static final Charset ASCII = Charset.forName("US-ASCII");
3615    // Identifier for EXIF APP1 segment in JPEG
3616    static final byte[] IDENTIFIER_EXIF_APP1 = "Exif\0\0".getBytes(ASCII);
3617    // JPEG segment markers, that each marker consumes two bytes beginning with 0xff and ending with
3618    // the indicator. There is no SOF4, SOF8, SOF16 markers in JPEG and SOFx markers indicates start
3619    // of frame(baseline DCT) and the image size info exists in its beginning part.
3620    static final byte MARKER = (byte) 0xff;
3621    private static final byte MARKER_SOI = (byte) 0xd8;
3622    private static final byte MARKER_SOF0 = (byte) 0xc0;
3623    private static final byte MARKER_SOF1 = (byte) 0xc1;
3624    private static final byte MARKER_SOF2 = (byte) 0xc2;
3625    private static final byte MARKER_SOF3 = (byte) 0xc3;
3626    private static final byte MARKER_SOF5 = (byte) 0xc5;
3627    private static final byte MARKER_SOF6 = (byte) 0xc6;
3628    private static final byte MARKER_SOF7 = (byte) 0xc7;
3629    private static final byte MARKER_SOF9 = (byte) 0xc9;
3630    private static final byte MARKER_SOF10 = (byte) 0xca;
3631    private static final byte MARKER_SOF11 = (byte) 0xcb;
3632    private static final byte MARKER_SOF13 = (byte) 0xcd;
3633    private static final byte MARKER_SOF14 = (byte) 0xce;
3634    private static final byte MARKER_SOF15 = (byte) 0xcf;
3635    private static final byte MARKER_SOS = (byte) 0xda;
3636    static final byte MARKER_APP1 = (byte) 0xe1;
3637    private static final byte MARKER_COM = (byte) 0xfe;
3638    static final byte MARKER_EOI = (byte) 0xd9;
3639
3640    // Supported Image File Types
3641    private static final int IMAGE_TYPE_UNKNOWN = 0;
3642    private static final int IMAGE_TYPE_ARW = 1;
3643    private static final int IMAGE_TYPE_CR2 = 2;
3644    private static final int IMAGE_TYPE_DNG = 3;
3645    private static final int IMAGE_TYPE_JPEG = 4;
3646    private static final int IMAGE_TYPE_NEF = 5;
3647    private static final int IMAGE_TYPE_NRW = 6;
3648    private static final int IMAGE_TYPE_ORF = 7;
3649    private static final int IMAGE_TYPE_PEF = 8;
3650    private static final int IMAGE_TYPE_RAF = 9;
3651    private static final int IMAGE_TYPE_RW2 = 10;
3652    private static final int IMAGE_TYPE_SRW = 11;
3653
3654    static {
3655        sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
3656        sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
3657
3658        // Build up the hash tables to look up Exif tags for reading Exif tags.
3659        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
3660            sExifTagMapsForReading[ifdType] = new HashMap<>();
3661            sExifTagMapsForWriting[ifdType] = new HashMap<>();
3662            for (ExifTag tag : EXIF_TAGS[ifdType]) {
3663                sExifTagMapsForReading[ifdType].put(tag.number, tag);
3664                sExifTagMapsForWriting[ifdType].put(tag.name, tag);
3665            }
3666        }
3667
3668        // Build up the hash table to look up Exif pointer tags.
3669        sExifPointerTagMap.put(EXIF_POINTER_TAGS[0].number, IFD_TYPE_PREVIEW); // 330
3670        sExifPointerTagMap.put(EXIF_POINTER_TAGS[1].number, IFD_TYPE_EXIF); // 34665
3671        sExifPointerTagMap.put(EXIF_POINTER_TAGS[2].number, IFD_TYPE_GPS); // 34853
3672        sExifPointerTagMap.put(EXIF_POINTER_TAGS[3].number, IFD_TYPE_INTEROPERABILITY); // 40965
3673        sExifPointerTagMap.put(EXIF_POINTER_TAGS[4].number, IFD_TYPE_ORF_CAMERA_SETTINGS); // 8224
3674        sExifPointerTagMap.put(EXIF_POINTER_TAGS[5].number, IFD_TYPE_ORF_IMAGE_PROCESSING); // 8256
3675    }
3676
3677    private final String mFilename;
3678    private final AssetManager.AssetInputStream mAssetInputStream;
3679    private int mMimeType;
3680    @SuppressWarnings("unchecked")
3681    private final HashMap<String, ExifAttribute>[] mAttributes = new HashMap[EXIF_TAGS.length];
3682    private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN;
3683    private boolean mHasThumbnail;
3684    // The following values used for indicating a thumbnail position.
3685    private int mThumbnailOffset;
3686    private int mThumbnailLength;
3687    private byte[] mThumbnailBytes;
3688    private int mThumbnailCompression;
3689    private int mExifOffset;
3690    private int mOrfMakerNoteOffset;
3691    private int mOrfThumbnailOffset;
3692    private int mOrfThumbnailLength;
3693    private int mRw2JpgFromRawOffset;
3694    private boolean mIsSupportedFile;
3695
3696    // Pattern to check non zero timestamp
3697    private static final Pattern sNonZeroTimePattern = Pattern.compile(".*[1-9].*");
3698    // Pattern to check gps timestamp
3699    private static final Pattern sGpsTimestampPattern =
3700            Pattern.compile("^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$");
3701
3702    /**
3703     * Reads Exif tags from the specified image file.
3704     */
3705    public ExifInterface(@NonNull String filename) throws IOException {
3706        if (filename == null) {
3707            throw new IllegalArgumentException("filename cannot be null");
3708        }
3709        FileInputStream in = null;
3710        mAssetInputStream = null;
3711        mFilename = filename;
3712        try {
3713            in = new FileInputStream(filename);
3714            loadAttributes(in);
3715        } finally {
3716            closeQuietly(in);
3717        }
3718    }
3719
3720    /**
3721     * Reads Exif tags from the specified image input stream. Attribute mutation is not supported
3722     * for input streams. The given input stream will proceed its current position. Developers
3723     * should close the input stream after use. This constructor is not intended to be used with
3724     * an input stream that performs any networking operations.
3725     */
3726    public ExifInterface(@NonNull InputStream inputStream) throws IOException {
3727        if (inputStream == null) {
3728            throw new IllegalArgumentException("inputStream cannot be null");
3729        }
3730        mFilename = null;
3731        if (inputStream instanceof AssetManager.AssetInputStream) {
3732            mAssetInputStream = (AssetManager.AssetInputStream) inputStream;
3733        } else {
3734            mAssetInputStream = null;
3735        }
3736        loadAttributes(inputStream);
3737    }
3738
3739    /**
3740     * Returns the EXIF attribute of the specified tag or {@code null} if there is no such tag in
3741     * the image file.
3742     *
3743     * @param tag the name of the tag.
3744     */
3745    @Nullable
3746    private ExifAttribute getExifAttribute(@NonNull String tag) {
3747        if (TAG_ISO_SPEED_RATINGS.equals(tag)) {
3748            if (DEBUG) {
3749                Log.d(TAG, "getExifAttribute: Replacing TAG_ISO_SPEED_RATINGS with "
3750                        + "TAG_PHOTOGRAPHIC_SENSITIVITY.");
3751            }
3752            tag = TAG_PHOTOGRAPHIC_SENSITIVITY;
3753        }
3754        // Retrieves all tag groups. The value from primary image tag group has a higher priority
3755        // than the value from the thumbnail tag group if there are more than one candidates.
3756        for (int i = 0; i < EXIF_TAGS.length; ++i) {
3757            ExifAttribute value = mAttributes[i].get(tag);
3758            if (value != null) {
3759                return value;
3760            }
3761        }
3762        return null;
3763    }
3764
3765    /**
3766     * Returns the value of the specified tag or {@code null} if there
3767     * is no such tag in the image file.
3768     *
3769     * @param tag the name of the tag.
3770     */
3771    @Nullable
3772    public String getAttribute(@NonNull String tag) {
3773        ExifAttribute attribute = getExifAttribute(tag);
3774        if (attribute != null) {
3775            if (!sTagSetForCompatibility.contains(tag)) {
3776                return attribute.getStringValue(mExifByteOrder);
3777            }
3778            if (tag.equals(TAG_GPS_TIMESTAMP)) {
3779                // Convert the rational values to the custom formats for backwards compatibility.
3780                if (attribute.format != IFD_FORMAT_URATIONAL
3781                        && attribute.format != IFD_FORMAT_SRATIONAL) {
3782                    Log.w(TAG, "GPS Timestamp format is not rational. format=" + attribute.format);
3783                    return null;
3784                }
3785                Rational[] array = (Rational[]) attribute.getValue(mExifByteOrder);
3786                if (array == null || array.length != 3) {
3787                    Log.w(TAG, "Invalid GPS Timestamp array. array=" + Arrays.toString(array));
3788                    return null;
3789                }
3790                return String.format("%02d:%02d:%02d",
3791                        (int) ((float) array[0].numerator / array[0].denominator),
3792                        (int) ((float) array[1].numerator / array[1].denominator),
3793                        (int) ((float) array[2].numerator / array[2].denominator));
3794            }
3795            try {
3796                return Double.toString(attribute.getDoubleValue(mExifByteOrder));
3797            } catch (NumberFormatException e) {
3798                return null;
3799            }
3800        }
3801        return null;
3802    }
3803
3804    /**
3805     * Returns the integer value of the specified tag. If there is no such tag
3806     * in the image file or the value cannot be parsed as integer, return
3807     * <var>defaultValue</var>.
3808     *
3809     * @param tag the name of the tag.
3810     * @param defaultValue the value to return if the tag is not available.
3811     */
3812    public int getAttributeInt(@NonNull String tag, int defaultValue) {
3813        ExifAttribute exifAttribute = getExifAttribute(tag);
3814        if (exifAttribute == null) {
3815            return defaultValue;
3816        }
3817
3818        try {
3819            return exifAttribute.getIntValue(mExifByteOrder);
3820        } catch (NumberFormatException e) {
3821            return defaultValue;
3822        }
3823    }
3824
3825    /**
3826     * Returns the double value of the tag that is specified as rational or contains a
3827     * double-formatted value. If there is no such tag in the image file or the value cannot be
3828     * parsed as double, return <var>defaultValue</var>.
3829     *
3830     * @param tag the name of the tag.
3831     * @param defaultValue the value to return if the tag is not available.
3832     */
3833    public double getAttributeDouble(@NonNull String tag, double defaultValue) {
3834        ExifAttribute exifAttribute = getExifAttribute(tag);
3835        if (exifAttribute == null) {
3836            return defaultValue;
3837        }
3838
3839        try {
3840            return exifAttribute.getDoubleValue(mExifByteOrder);
3841        } catch (NumberFormatException e) {
3842            return defaultValue;
3843        }
3844    }
3845
3846    /**
3847     * Sets the value of the specified tag.
3848     *
3849     * @param tag the name of the tag.
3850     * @param value the value of the tag.
3851     */
3852    public void setAttribute(@NonNull String tag, @Nullable String value) {
3853        if (TAG_ISO_SPEED_RATINGS.equals(tag)) {
3854            if (DEBUG) {
3855                Log.d(TAG, "setAttribute: Replacing TAG_ISO_SPEED_RATINGS with "
3856                        + "TAG_PHOTOGRAPHIC_SENSITIVITY.");
3857            }
3858            tag = TAG_PHOTOGRAPHIC_SENSITIVITY;
3859        }
3860        // Convert the given value to rational values for backwards compatibility.
3861        if (value != null && sTagSetForCompatibility.contains(tag)) {
3862            if (tag.equals(TAG_GPS_TIMESTAMP)) {
3863                Matcher m = sGpsTimestampPattern.matcher(value);
3864                if (!m.find()) {
3865                    Log.w(TAG, "Invalid value for " + tag + " : " + value);
3866                    return;
3867                }
3868                value = Integer.parseInt(m.group(1)) + "/1," + Integer.parseInt(m.group(2)) + "/1,"
3869                        + Integer.parseInt(m.group(3)) + "/1";
3870            } else {
3871                try {
3872                    double doubleValue = Double.parseDouble(value);
3873                    value = new Rational(doubleValue).toString();
3874                } catch (NumberFormatException e) {
3875                    Log.w(TAG, "Invalid value for " + tag + " : " + value);
3876                    return;
3877                }
3878            }
3879        }
3880
3881        for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
3882            if (i == IFD_TYPE_THUMBNAIL && !mHasThumbnail) {
3883                continue;
3884            }
3885            final ExifTag exifTag = sExifTagMapsForWriting[i].get(tag);
3886            if (exifTag != null) {
3887                if (value == null) {
3888                    mAttributes[i].remove(tag);
3889                    continue;
3890                }
3891                Pair<Integer, Integer> guess = guessDataFormat(value);
3892                int dataFormat;
3893                if (exifTag.primaryFormat == guess.first || exifTag.primaryFormat == guess.second) {
3894                    dataFormat = exifTag.primaryFormat;
3895                } else if (exifTag.secondaryFormat != -1 && (exifTag.secondaryFormat == guess.first
3896                        || exifTag.secondaryFormat == guess.second)) {
3897                    dataFormat = exifTag.secondaryFormat;
3898                } else if (exifTag.primaryFormat == IFD_FORMAT_BYTE
3899                        || exifTag.primaryFormat == IFD_FORMAT_UNDEFINED
3900                        || exifTag.primaryFormat == IFD_FORMAT_STRING) {
3901                    dataFormat = exifTag.primaryFormat;
3902                } else {
3903                    Log.w(TAG, "Given tag (" + tag + ") value didn't match with one of expected "
3904                            + "formats: " + IFD_FORMAT_NAMES[exifTag.primaryFormat]
3905                            + (exifTag.secondaryFormat == -1 ? "" : ", "
3906                            + IFD_FORMAT_NAMES[exifTag.secondaryFormat]) + " (guess: "
3907                            + IFD_FORMAT_NAMES[guess.first] + (guess.second == -1 ? "" : ", "
3908                            + IFD_FORMAT_NAMES[guess.second]) + ")");
3909                    continue;
3910                }
3911                switch (dataFormat) {
3912                    case IFD_FORMAT_BYTE: {
3913                        mAttributes[i].put(tag, ExifAttribute.createByte(value));
3914                        break;
3915                    }
3916                    case IFD_FORMAT_UNDEFINED:
3917                    case IFD_FORMAT_STRING: {
3918                        mAttributes[i].put(tag, ExifAttribute.createString(value));
3919                        break;
3920                    }
3921                    case IFD_FORMAT_USHORT: {
3922                        final String[] values = value.split(",");
3923                        final int[] intArray = new int[values.length];
3924                        for (int j = 0; j < values.length; ++j) {
3925                            intArray[j] = Integer.parseInt(values[j]);
3926                        }
3927                        mAttributes[i].put(tag,
3928                                ExifAttribute.createUShort(intArray, mExifByteOrder));
3929                        break;
3930                    }
3931                    case IFD_FORMAT_SLONG: {
3932                        final String[] values = value.split(",");
3933                        final int[] intArray = new int[values.length];
3934                        for (int j = 0; j < values.length; ++j) {
3935                            intArray[j] = Integer.parseInt(values[j]);
3936                        }
3937                        mAttributes[i].put(tag,
3938                                ExifAttribute.createSLong(intArray, mExifByteOrder));
3939                        break;
3940                    }
3941                    case IFD_FORMAT_ULONG: {
3942                        final String[] values = value.split(",");
3943                        final long[] longArray = new long[values.length];
3944                        for (int j = 0; j < values.length; ++j) {
3945                            longArray[j] = Long.parseLong(values[j]);
3946                        }
3947                        mAttributes[i].put(tag,
3948                                ExifAttribute.createULong(longArray, mExifByteOrder));
3949                        break;
3950                    }
3951                    case IFD_FORMAT_URATIONAL: {
3952                        final String[] values = value.split(",");
3953                        final Rational[] rationalArray = new Rational[values.length];
3954                        for (int j = 0; j < values.length; ++j) {
3955                            final String[] numbers = values[j].split("/");
3956                            rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
3957                                    (long) Double.parseDouble(numbers[1]));
3958                        }
3959                        mAttributes[i].put(tag,
3960                                ExifAttribute.createURational(rationalArray, mExifByteOrder));
3961                        break;
3962                    }
3963                    case IFD_FORMAT_SRATIONAL: {
3964                        final String[] values = value.split(",");
3965                        final Rational[] rationalArray = new Rational[values.length];
3966                        for (int j = 0; j < values.length; ++j) {
3967                            final String[] numbers = values[j].split("/");
3968                            rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
3969                                    (long) Double.parseDouble(numbers[1]));
3970                        }
3971                        mAttributes[i].put(tag,
3972                                ExifAttribute.createSRational(rationalArray, mExifByteOrder));
3973                        break;
3974                    }
3975                    case IFD_FORMAT_DOUBLE: {
3976                        final String[] values = value.split(",");
3977                        final double[] doubleArray = new double[values.length];
3978                        for (int j = 0; j < values.length; ++j) {
3979                            doubleArray[j] = Double.parseDouble(values[j]);
3980                        }
3981                        mAttributes[i].put(tag,
3982                                ExifAttribute.createDouble(doubleArray, mExifByteOrder));
3983                        break;
3984                    }
3985                    default:
3986                        Log.w(TAG, "Data format isn't one of expected formats: " + dataFormat);
3987                        continue;
3988                }
3989            }
3990        }
3991    }
3992
3993    /**
3994     * Resets the {@link #TAG_ORIENTATION} of the image to be {@link #ORIENTATION_NORMAL}.
3995     */
3996    public void resetOrientation() {
3997        setAttribute(TAG_ORIENTATION, Integer.toString(ORIENTATION_NORMAL));
3998    }
3999
4000    /**
4001     * Rotates the image by the given degree clockwise. The degree should be a multiple of
4002     * 90 (e.g, 90, 180, -90, etc.).
4003     *
4004     * @param degree The degree of rotation.
4005     */
4006    public void rotate(int degree) {
4007        if (degree % 90 !=0) {
4008            throw new IllegalArgumentException("degree should be a multiple of 90");
4009        }
4010
4011        int currentOrientation = getAttributeInt(TAG_ORIENTATION, ORIENTATION_NORMAL);
4012        int currentIndex, newIndex;
4013        int resultOrientation;
4014        if (ROTATION_ORDER.contains(currentOrientation)) {
4015            currentIndex = ROTATION_ORDER.indexOf(currentOrientation);
4016            newIndex = (currentIndex + degree / 90) % 4;
4017            newIndex += newIndex < 0 ? 4 : 0;
4018            resultOrientation = ROTATION_ORDER.get(newIndex);
4019        } else if (FLIPPED_ROTATION_ORDER.contains(currentOrientation)) {
4020            currentIndex = FLIPPED_ROTATION_ORDER.indexOf(currentOrientation);
4021            newIndex = (currentIndex + degree / 90) % 4;
4022            newIndex += newIndex < 0 ? 4 : 0;
4023            resultOrientation = FLIPPED_ROTATION_ORDER.get(newIndex);
4024        } else {
4025            resultOrientation = ORIENTATION_UNDEFINED;
4026        }
4027
4028        setAttribute(TAG_ORIENTATION, Integer.toString(resultOrientation));
4029    }
4030
4031    /**
4032     * Flips the image vertically.
4033     */
4034    public void flipVertically() {
4035        int currentOrientation = getAttributeInt(TAG_ORIENTATION, ORIENTATION_NORMAL);
4036        int resultOrientation;
4037        switch (currentOrientation) {
4038            case ORIENTATION_FLIP_HORIZONTAL:
4039                resultOrientation = ORIENTATION_ROTATE_180;
4040                break;
4041            case ORIENTATION_ROTATE_180:
4042                resultOrientation = ORIENTATION_FLIP_HORIZONTAL;
4043                break;
4044            case ORIENTATION_FLIP_VERTICAL:
4045                resultOrientation = ORIENTATION_NORMAL;
4046                break;
4047            case ORIENTATION_TRANSPOSE:
4048                resultOrientation = ORIENTATION_ROTATE_270;
4049                break;
4050            case ORIENTATION_ROTATE_90:
4051                resultOrientation = ORIENTATION_TRANSVERSE;
4052                break;
4053            case ORIENTATION_TRANSVERSE:
4054                resultOrientation = ORIENTATION_ROTATE_90;
4055                break;
4056            case ORIENTATION_ROTATE_270:
4057                resultOrientation = ORIENTATION_TRANSPOSE;
4058                break;
4059            case ORIENTATION_NORMAL:
4060                resultOrientation = ORIENTATION_FLIP_VERTICAL;
4061                break;
4062            case ORIENTATION_UNDEFINED:
4063            default:
4064                resultOrientation = ORIENTATION_UNDEFINED;
4065                break;
4066        }
4067        setAttribute(TAG_ORIENTATION, Integer.toString(resultOrientation));
4068    }
4069
4070    /**
4071     * Flips the image horizontally.
4072     */
4073    public void flipHorizontally() {
4074        int currentOrientation = getAttributeInt(TAG_ORIENTATION, ORIENTATION_NORMAL);
4075        int resultOrientation;
4076        switch (currentOrientation) {
4077            case ORIENTATION_FLIP_HORIZONTAL:
4078                resultOrientation = ORIENTATION_NORMAL;
4079                break;
4080            case ORIENTATION_ROTATE_180:
4081                resultOrientation = ORIENTATION_FLIP_VERTICAL;
4082                break;
4083            case ORIENTATION_FLIP_VERTICAL:
4084                resultOrientation = ORIENTATION_ROTATE_180;
4085                break;
4086            case ORIENTATION_TRANSPOSE:
4087                resultOrientation = ORIENTATION_ROTATE_90;
4088                break;
4089            case ORIENTATION_ROTATE_90:
4090                resultOrientation = ORIENTATION_TRANSPOSE;
4091                break;
4092            case ORIENTATION_TRANSVERSE:
4093                resultOrientation = ORIENTATION_ROTATE_270;
4094                break;
4095            case ORIENTATION_ROTATE_270:
4096                resultOrientation = ORIENTATION_TRANSVERSE;
4097                break;
4098            case ORIENTATION_NORMAL:
4099                resultOrientation = ORIENTATION_FLIP_HORIZONTAL;
4100                break;
4101            case ORIENTATION_UNDEFINED:
4102            default:
4103                resultOrientation = ORIENTATION_UNDEFINED;
4104                break;
4105        }
4106        setAttribute(TAG_ORIENTATION, Integer.toString(resultOrientation));
4107    }
4108
4109    /**
4110     * Returns if the current image orientation is flipped.
4111     *
4112     * @see #getRotationDegrees()
4113     */
4114    public boolean isFlipped() {
4115        int orientation = getAttributeInt(TAG_ORIENTATION, ORIENTATION_NORMAL);
4116        switch (orientation) {
4117            case ORIENTATION_FLIP_HORIZONTAL:
4118            case ORIENTATION_TRANSVERSE:
4119            case ORIENTATION_FLIP_VERTICAL:
4120            case ORIENTATION_TRANSPOSE:
4121                return true;
4122            default:
4123                return false;
4124        }
4125    }
4126
4127    /**
4128     * Returns the rotation degrees for the current image orientation. If the image is flipped,
4129     * i.e., {@link #isFlipped()} returns {@code true}, the rotation degrees will be base on
4130     * the assumption that the image is first flipped horizontally (along Y-axis), and then do
4131     * the rotation. For example, {@link #ORIENTATION_TRANSPOSE} will be interpreted as flipped
4132     * horizontally first, and then rotate 270 degrees clockwise.
4133     *
4134     * @return The rotation degrees of the image after the horizontal flipping is applied, if any.
4135     *
4136     * @see #isFlipped()
4137     */
4138    public int getRotationDegrees() {
4139        int orientation = getAttributeInt(TAG_ORIENTATION, ORIENTATION_NORMAL);
4140        switch (orientation) {
4141            case ORIENTATION_ROTATE_90:
4142            case ORIENTATION_TRANSVERSE:
4143                return 90;
4144            case ORIENTATION_ROTATE_180:
4145            case ORIENTATION_FLIP_VERTICAL:
4146                return 180;
4147            case ORIENTATION_ROTATE_270:
4148            case ORIENTATION_TRANSPOSE:
4149                return 270;
4150            case ORIENTATION_UNDEFINED:
4151            case ORIENTATION_NORMAL:
4152            case ORIENTATION_FLIP_HORIZONTAL:
4153            default:
4154                return 0;
4155        }
4156    }
4157
4158    /**
4159     * Update the values of the tags in the tag groups if any value for the tag already was stored.
4160     *
4161     * @param tag the name of the tag.
4162     * @param value the value of the tag in a form of {@link ExifAttribute}.
4163     * @return Returns {@code true} if updating is placed.
4164     */
4165    private boolean updateAttribute(String tag, ExifAttribute value) {
4166        boolean updated = false;
4167        for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
4168            if (mAttributes[i].containsKey(tag)) {
4169                mAttributes[i].put(tag, value);
4170                updated = true;
4171            }
4172        }
4173        return updated;
4174    }
4175
4176    /**
4177     * Remove any values of the specified tag.
4178     *
4179     * @param tag the name of the tag.
4180     */
4181    private void removeAttribute(String tag) {
4182        for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
4183            mAttributes[i].remove(tag);
4184        }
4185    }
4186
4187    /**
4188     * This function decides which parser to read the image data according to the given input stream
4189     * type and the content of the input stream. In each case, it reads the first three bytes to
4190     * determine whether the image data format is JPEG or not.
4191     */
4192    private void loadAttributes(@NonNull InputStream in) throws IOException {
4193        try {
4194            // Initialize mAttributes.
4195            for (int i = 0; i < EXIF_TAGS.length; ++i) {
4196                mAttributes[i] = new HashMap<>();
4197            }
4198
4199            // Check file type
4200            in = new BufferedInputStream(in, SIGNATURE_CHECK_SIZE);
4201            mMimeType = getMimeType((BufferedInputStream) in);
4202
4203            // Create byte-ordered input stream
4204            ByteOrderedDataInputStream inputStream = new ByteOrderedDataInputStream(in);
4205
4206            switch (mMimeType) {
4207                case IMAGE_TYPE_JPEG: {
4208                    getJpegAttributes(inputStream, 0, IFD_TYPE_PRIMARY); // 0 is offset
4209                    break;
4210                }
4211                case IMAGE_TYPE_RAF: {
4212                    getRafAttributes(inputStream);
4213                    break;
4214                }
4215                case IMAGE_TYPE_ORF: {
4216                    getOrfAttributes(inputStream);
4217                    break;
4218                }
4219                case IMAGE_TYPE_RW2: {
4220                    getRw2Attributes(inputStream);
4221                    break;
4222                }
4223                case IMAGE_TYPE_ARW:
4224                case IMAGE_TYPE_CR2:
4225                case IMAGE_TYPE_DNG:
4226                case IMAGE_TYPE_NEF:
4227                case IMAGE_TYPE_NRW:
4228                case IMAGE_TYPE_PEF:
4229                case IMAGE_TYPE_SRW:
4230                case IMAGE_TYPE_UNKNOWN: {
4231                    getRawAttributes(inputStream);
4232                    break;
4233                }
4234                default: {
4235                    break;
4236                }
4237            }
4238            // Set thumbnail image offset and length
4239            setThumbnailData(inputStream);
4240            mIsSupportedFile = true;
4241        } catch (IOException e) {
4242            // Ignore exceptions in order to keep the compatibility with the old versions of
4243            // ExifInterface.
4244            mIsSupportedFile = false;
4245            if (DEBUG) {
4246                Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file"
4247                        + "(ExifInterface supports JPEG and some RAW image formats only) "
4248                        + "or a corrupted JPEG file to ExifInterface.", e);
4249            }
4250        } finally {
4251            addDefaultValuesForCompatibility();
4252
4253            if (DEBUG) {
4254                printAttributes();
4255            }
4256        }
4257    }
4258
4259    // Prints out attributes for debugging.
4260    private void printAttributes() {
4261        for (int i = 0; i < mAttributes.length; ++i) {
4262            Log.d(TAG, "The size of tag group[" + i + "]: " + mAttributes[i].size());
4263            for (Map.Entry<String, ExifAttribute> entry : mAttributes[i].entrySet()) {
4264                final ExifAttribute tagValue = entry.getValue();
4265                Log.d(TAG, "tagName: " + entry.getKey() + ", tagType: " + tagValue.toString()
4266                        + ", tagValue: '" + tagValue.getStringValue(mExifByteOrder) + "'");
4267            }
4268        }
4269    }
4270
4271    /**
4272     * Save the tag data into the original image file. This is expensive because it involves
4273     * copying all the data from one file to another and deleting the old file and renaming the
4274     * other. It's best to use {@link #setAttribute(String,String)} to set all attributes to write
4275     * and make a single call rather than multiple calls for each attribute.
4276     * <p>
4277     * This method is only supported for JPEG files.
4278     * </p>
4279     */
4280    public void saveAttributes() throws IOException {
4281        if (!mIsSupportedFile || mMimeType != IMAGE_TYPE_JPEG) {
4282            throw new IOException("ExifInterface only supports saving attributes on JPEG formats.");
4283        }
4284        if (mFilename == null) {
4285            throw new IOException(
4286                    "ExifInterface does not support saving attributes for the current input.");
4287        }
4288
4289        // Keep the thumbnail in memory
4290        mThumbnailBytes = getThumbnail();
4291
4292        File tempFile = new File(mFilename + ".tmp");
4293        File originalFile = new File(mFilename);
4294        if (!originalFile.renameTo(tempFile)) {
4295            throw new IOException("Could not rename to " + tempFile.getAbsolutePath());
4296        }
4297
4298        FileInputStream in = null;
4299        FileOutputStream out = null;
4300        try {
4301            // Save the new file.
4302            in = new FileInputStream(tempFile);
4303            out = new FileOutputStream(mFilename);
4304            saveJpegAttributes(in, out);
4305        } finally {
4306            closeQuietly(in);
4307            closeQuietly(out);
4308            tempFile.delete();
4309        }
4310
4311        // Discard the thumbnail in memory
4312        mThumbnailBytes = null;
4313    }
4314
4315    /**
4316     * Returns true if the image file has a thumbnail.
4317     */
4318    public boolean hasThumbnail() {
4319        return mHasThumbnail;
4320    }
4321
4322    /**
4323     * Returns the JPEG compressed thumbnail inside the image file, or {@code null} if there is no
4324     * JPEG compressed thumbnail.
4325     * The returned data can be decoded using
4326     * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
4327     */
4328    @Nullable
4329    public byte[] getThumbnail() {
4330        if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) {
4331            return getThumbnailBytes();
4332        }
4333        return null;
4334    }
4335
4336    /**
4337     * Returns the thumbnail bytes inside the image file, regardless of the compression type of the
4338     * thumbnail image.
4339     */
4340    @Nullable
4341    public byte[] getThumbnailBytes() {
4342        if (!mHasThumbnail) {
4343            return null;
4344        }
4345        if (mThumbnailBytes != null) {
4346            return mThumbnailBytes;
4347        }
4348
4349        // Read the thumbnail.
4350        InputStream in = null;
4351        try {
4352            if (mAssetInputStream != null) {
4353                in = mAssetInputStream;
4354                if (in.markSupported()) {
4355                    in.reset();
4356                } else {
4357                    Log.d(TAG, "Cannot read thumbnail from inputstream without mark/reset support");
4358                    return null;
4359                }
4360            } else if (mFilename != null) {
4361                in = new FileInputStream(mFilename);
4362            }
4363            if (in == null) {
4364                // Should not be reached this.
4365                throw new FileNotFoundException();
4366            }
4367            if (in.skip(mThumbnailOffset) != mThumbnailOffset) {
4368                throw new IOException("Corrupted image");
4369            }
4370            byte[] buffer = new byte[mThumbnailLength];
4371            if (in.read(buffer) != mThumbnailLength) {
4372                throw new IOException("Corrupted image");
4373            }
4374            mThumbnailBytes = buffer;
4375            return buffer;
4376        } catch (IOException e) {
4377            // Couldn't get a thumbnail image.
4378            Log.d(TAG, "Encountered exception while getting thumbnail", e);
4379        } finally {
4380            closeQuietly(in);
4381        }
4382        return null;
4383    }
4384
4385    /**
4386     * Creates and returns a Bitmap object of the thumbnail image based on the byte array and the
4387     * thumbnail compression value, or {@code null} if the compression type is unsupported.
4388     */
4389    @Nullable
4390    public Bitmap getThumbnailBitmap() {
4391        if (!mHasThumbnail) {
4392            return null;
4393        } else if (mThumbnailBytes == null) {
4394            mThumbnailBytes = getThumbnailBytes();
4395        }
4396
4397        if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) {
4398            return BitmapFactory.decodeByteArray(mThumbnailBytes, 0, mThumbnailLength);
4399        } else if (mThumbnailCompression == DATA_UNCOMPRESSED) {
4400            int[] rgbValues = new int[mThumbnailBytes.length / 3];
4401            byte alpha = (byte) 0xff000000;
4402            for (int i = 0; i < rgbValues.length; i++) {
4403                rgbValues[i] = alpha + (mThumbnailBytes[3 * i] << 16)
4404                        + (mThumbnailBytes[3 * i + 1] << 8) + mThumbnailBytes[3 * i + 2];
4405            }
4406
4407            ExifAttribute imageLengthAttribute =
4408                    (ExifAttribute) mAttributes[IFD_TYPE_THUMBNAIL].get(TAG_IMAGE_LENGTH);
4409            ExifAttribute imageWidthAttribute =
4410                    (ExifAttribute) mAttributes[IFD_TYPE_THUMBNAIL].get(TAG_IMAGE_WIDTH);
4411            if (imageLengthAttribute != null && imageWidthAttribute != null) {
4412                int imageLength = imageLengthAttribute.getIntValue(mExifByteOrder);
4413                int imageWidth = imageWidthAttribute.getIntValue(mExifByteOrder);
4414                return Bitmap.createBitmap(
4415                        rgbValues, imageWidth, imageLength, Bitmap.Config.ARGB_8888);
4416            }
4417        }
4418        return null;
4419    }
4420
4421    /**
4422     * Returns true if thumbnail image is JPEG Compressed, or false if either thumbnail image does
4423     * not exist or thumbnail image is uncompressed.
4424     */
4425    public boolean isThumbnailCompressed() {
4426        return mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED;
4427    }
4428
4429    /**
4430     * Returns the offset and length of thumbnail inside the image file, or
4431     * {@code null} if there is no thumbnail.
4432     *
4433     * @return two-element array, the offset in the first value, and length in
4434     *         the second, or {@code null} if no thumbnail was found.
4435     */
4436    @Nullable
4437    public long[] getThumbnailRange() {
4438        if (!mHasThumbnail) {
4439            return null;
4440        }
4441
4442        long[] range = new long[2];
4443        range[0] = mThumbnailOffset;
4444        range[1] = mThumbnailLength;
4445
4446        return range;
4447    }
4448
4449    /**
4450     * Stores the latitude and longitude value in a float array. The first element is the latitude,
4451     * and the second element is the longitude. Returns false if the Exif tags are not available.
4452     *
4453     * @deprecated Use {@link #getLatLong()} instead.
4454     */
4455    @Deprecated
4456    public boolean getLatLong(float output[]) {
4457        double[] latLong = getLatLong();
4458        if (latLong == null) {
4459            return false;
4460        }
4461
4462        output[0] = (float) latLong[0];
4463        output[1] = (float) latLong[1];
4464        return true;
4465    }
4466
4467    /**
4468     * Gets the latitude and longitude values.
4469     * <p>
4470     * If there are valid latitude and longitude values in the image, this method returns a double
4471     * array where the first element is the latitude and the second element is the longitude.
4472     * Otherwise, it returns null.
4473     */
4474    @Nullable
4475    public double[] getLatLong() {
4476        String latValue = getAttribute(TAG_GPS_LATITUDE);
4477        String latRef = getAttribute(TAG_GPS_LATITUDE_REF);
4478        String lngValue = getAttribute(TAG_GPS_LONGITUDE);
4479        String lngRef = getAttribute(TAG_GPS_LONGITUDE_REF);
4480
4481        if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
4482            try {
4483                double latitude = convertRationalLatLonToDouble(latValue, latRef);
4484                double longitude = convertRationalLatLonToDouble(lngValue, lngRef);
4485                return new double[] {latitude, longitude};
4486            } catch (IllegalArgumentException e) {
4487                Log.w(TAG, "Latitude/longitude values are not parseable. " +
4488                        String.format("latValue=%s, latRef=%s, lngValue=%s, lngRef=%s",
4489                                latValue, latRef, lngValue, lngRef));
4490            }
4491        }
4492        return null;
4493    }
4494
4495    /**
4496     * Sets the GPS-related information. It will set GPS processing method, latitude and longitude
4497     * values, GPS timestamp, and speed information at the same time.
4498     *
4499     * @param location the {@link Location} object returned by GPS service.
4500     */
4501    public void setGpsInfo(Location location) {
4502        if (location == null) {
4503            return;
4504        }
4505        setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD, location.getProvider());
4506        setLatLong(location.getLatitude(), location.getLongitude());
4507        setAltitude(location.getAltitude());
4508        // Location objects store speeds in m/sec. Translates it to km/hr here.
4509        setAttribute(TAG_GPS_SPEED_REF, "K");
4510        setAttribute(TAG_GPS_SPEED, new Rational(location.getSpeed()
4511                * TimeUnit.HOURS.toSeconds(1) / 1000).toString());
4512        String[] dateTime = sFormatter.format(new Date(location.getTime())).split("\\s+");
4513        setAttribute(ExifInterface.TAG_GPS_DATESTAMP, dateTime[0]);
4514        setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, dateTime[1]);
4515    }
4516
4517    /**
4518     * Sets the latitude and longitude values.
4519     *
4520     * @param latitude the decimal value of latitude. Must be a valid double value between -90.0 and
4521     *                 90.0.
4522     * @param longitude the decimal value of longitude. Must be a valid double value between -180.0
4523     *                  and 180.0.
4524     * @throws IllegalArgumentException If {@code latitude} or {@code longitude} is outside the
4525     *                                  specified range.
4526     */
4527    public void setLatLong(double latitude, double longitude) {
4528        if (latitude < -90.0 || latitude > 90.0 || Double.isNaN(latitude)) {
4529            throw new IllegalArgumentException("Latitude value " + latitude + " is not valid.");
4530        }
4531        if (longitude < -180.0 || longitude > 180.0 || Double.isNaN(longitude)) {
4532            throw new IllegalArgumentException("Longitude value " + longitude + " is not valid.");
4533        }
4534        setAttribute(TAG_GPS_LATITUDE_REF, latitude >= 0 ? "N" : "S");
4535        setAttribute(TAG_GPS_LATITUDE, convertDecimalDegree(Math.abs(latitude)));
4536        setAttribute(TAG_GPS_LONGITUDE_REF, longitude >= 0 ? "E" : "W");
4537        setAttribute(TAG_GPS_LONGITUDE, convertDecimalDegree(Math.abs(longitude)));
4538    }
4539
4540    /**
4541     * Return the altitude in meters. If the exif tag does not exist, return
4542     * <var>defaultValue</var>.
4543     *
4544     * @param defaultValue the value to return if the tag is not available.
4545     */
4546    public double getAltitude(double defaultValue) {
4547        double altitude = getAttributeDouble(TAG_GPS_ALTITUDE, -1);
4548        int ref = getAttributeInt(TAG_GPS_ALTITUDE_REF, -1);
4549
4550        if (altitude >= 0 && ref >= 0) {
4551            return (altitude * ((ref == 1) ? -1 : 1));
4552        } else {
4553            return defaultValue;
4554        }
4555    }
4556
4557    /**
4558     * Sets the altitude in meters.
4559     */
4560    public void setAltitude(double altitude) {
4561        String ref = altitude >= 0 ? "0" : "1";
4562        setAttribute(TAG_GPS_ALTITUDE, new Rational(Math.abs(altitude)).toString());
4563        setAttribute(TAG_GPS_ALTITUDE_REF, ref);
4564    }
4565
4566    /**
4567     * Set the date time value.
4568     *
4569     * @param timeStamp number of milliseconds since Jan. 1, 1970, midnight local time.
4570     * @hide
4571     */
4572    @RestrictTo(RestrictTo.Scope.LIBRARY)
4573    public void setDateTime(long timeStamp) {
4574        long sub = timeStamp % 1000;
4575        setAttribute(TAG_DATETIME, sFormatter.format(new Date(timeStamp)));
4576        setAttribute(TAG_SUBSEC_TIME, Long.toString(sub));
4577    }
4578
4579    /**
4580     * Returns number of milliseconds since Jan. 1, 1970, midnight local time.
4581     * Returns -1 if the date time information if not available.
4582     * @hide
4583     */
4584    @RestrictTo(RestrictTo.Scope.LIBRARY)
4585    public long getDateTime() {
4586        String dateTimeString = getAttribute(TAG_DATETIME);
4587        if (dateTimeString == null
4588                || !sNonZeroTimePattern.matcher(dateTimeString).matches()) return -1;
4589
4590        ParsePosition pos = new ParsePosition(0);
4591        try {
4592            // The exif field is in local time. Parsing it as if it is UTC will yield time
4593            // since 1/1/1970 local time
4594            Date datetime = sFormatter.parse(dateTimeString, pos);
4595            if (datetime == null) return -1;
4596            long msecs = datetime.getTime();
4597
4598            String subSecs = getAttribute(TAG_SUBSEC_TIME);
4599            if (subSecs != null) {
4600                try {
4601                    long sub = Long.parseLong(subSecs);
4602                    while (sub > 1000) {
4603                        sub /= 10;
4604                    }
4605                    msecs += sub;
4606                } catch (NumberFormatException e) {
4607                    // Ignored
4608                }
4609            }
4610            return msecs;
4611        } catch (IllegalArgumentException e) {
4612            return -1;
4613        }
4614    }
4615
4616    /**
4617     * Returns number of milliseconds since Jan. 1, 1970, midnight UTC.
4618     * Returns -1 if the date time information if not available.
4619     * @hide
4620     */
4621    @RestrictTo(RestrictTo.Scope.LIBRARY)
4622    public long getGpsDateTime() {
4623        String date = getAttribute(TAG_GPS_DATESTAMP);
4624        String time = getAttribute(TAG_GPS_TIMESTAMP);
4625        if (date == null || time == null
4626                || (!sNonZeroTimePattern.matcher(date).matches()
4627                && !sNonZeroTimePattern.matcher(time).matches())) {
4628            return -1;
4629        }
4630
4631        String dateTimeString = date + ' ' + time;
4632
4633        ParsePosition pos = new ParsePosition(0);
4634        try {
4635            Date datetime = sFormatter.parse(dateTimeString, pos);
4636            if (datetime == null) return -1;
4637            return datetime.getTime();
4638        } catch (IllegalArgumentException e) {
4639            return -1;
4640        }
4641    }
4642
4643    private static double convertRationalLatLonToDouble(String rationalString, String ref) {
4644        try {
4645            String [] parts = rationalString.split(",");
4646
4647            String [] pair;
4648            pair = parts[0].split("/");
4649            double degrees = Double.parseDouble(pair[0].trim())
4650                    / Double.parseDouble(pair[1].trim());
4651
4652            pair = parts[1].split("/");
4653            double minutes = Double.parseDouble(pair[0].trim())
4654                    / Double.parseDouble(pair[1].trim());
4655
4656            pair = parts[2].split("/");
4657            double seconds = Double.parseDouble(pair[0].trim())
4658                    / Double.parseDouble(pair[1].trim());
4659
4660            double result = degrees + (minutes / 60.0) + (seconds / 3600.0);
4661            if ((ref.equals("S") || ref.equals("W"))) {
4662                return -result;
4663            } else if (ref.equals("N") || ref.equals("E")) {
4664                return result;
4665            } else {
4666                // Not valid
4667                throw new IllegalArgumentException();
4668            }
4669        } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
4670            // Not valid
4671            throw new IllegalArgumentException();
4672        }
4673    }
4674
4675    private String convertDecimalDegree(double decimalDegree) {
4676        long degrees = (long) decimalDegree;
4677        long minutes = (long) ((decimalDegree - degrees) * 60.0);
4678        long seconds = Math.round((decimalDegree - degrees - minutes / 60.0) * 3600.0 * 1e7);
4679        return degrees + "/1," + minutes + "/1," + seconds + "/10000000";
4680    }
4681
4682    // Checks the type of image file
4683    private int getMimeType(BufferedInputStream in) throws IOException {
4684        in.mark(SIGNATURE_CHECK_SIZE);
4685        byte[] signatureCheckBytes = new byte[SIGNATURE_CHECK_SIZE];
4686        in.read(signatureCheckBytes);
4687        in.reset();
4688        if (isJpegFormat(signatureCheckBytes)) {
4689            return IMAGE_TYPE_JPEG;
4690        } else if (isRafFormat(signatureCheckBytes)) {
4691            return IMAGE_TYPE_RAF;
4692        } else if (isOrfFormat(signatureCheckBytes)) {
4693            return IMAGE_TYPE_ORF;
4694        } else if (isRw2Format(signatureCheckBytes)) {
4695            return IMAGE_TYPE_RW2;
4696        }
4697        // Certain file formats (PEF) are identified in readImageFileDirectory()
4698        return IMAGE_TYPE_UNKNOWN;
4699    }
4700
4701    /**
4702     * This method looks at the first 3 bytes to determine if this file is a JPEG file.
4703     * See http://www.media.mit.edu/pia/Research/deepview/exif.html, "JPEG format and Marker"
4704     */
4705    private static boolean isJpegFormat(byte[] signatureCheckBytes) throws IOException {
4706        for (int i = 0; i < JPEG_SIGNATURE.length; i++) {
4707            if (signatureCheckBytes[i] != JPEG_SIGNATURE[i]) {
4708                return false;
4709            }
4710        }
4711        return true;
4712    }
4713
4714    /**
4715     * This method looks at the first 15 bytes to determine if this file is a RAF file.
4716     * There is no official specification for RAF files from Fuji, but there is an online archive of
4717     * image file specifications:
4718     * http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
4719     */
4720    private boolean isRafFormat(byte[] signatureCheckBytes) throws IOException {
4721        byte[] rafSignatureBytes = RAF_SIGNATURE.getBytes(Charset.defaultCharset());
4722        for (int i = 0; i < rafSignatureBytes.length; i++) {
4723            if (signatureCheckBytes[i] != rafSignatureBytes[i]) {
4724                return false;
4725            }
4726        }
4727        return true;
4728    }
4729
4730    /**
4731     * ORF has a similar structure to TIFF but it contains a different signature at the TIFF Header.
4732     * This method looks at the 2 bytes following the Byte Order bytes to determine if this file is
4733     * an ORF file.
4734     * There is no official specification for ORF files from Olympus, but there is an online archive
4735     * of image file specifications:
4736     * http://fileformats.archiveteam.org/wiki/Olympus_ORF
4737     */
4738    private boolean isOrfFormat(byte[] signatureCheckBytes) throws IOException {
4739        ByteOrderedDataInputStream signatureInputStream =
4740                new ByteOrderedDataInputStream(signatureCheckBytes);
4741        // Read byte order
4742        mExifByteOrder = readByteOrder(signatureInputStream);
4743        // Set byte order
4744        signatureInputStream.setByteOrder(mExifByteOrder);
4745
4746        short orfSignature = signatureInputStream.readShort();
4747        signatureInputStream.close();
4748        return orfSignature == ORF_SIGNATURE_1 || orfSignature == ORF_SIGNATURE_2;
4749    }
4750
4751    /**
4752     * RW2 is TIFF-based, but stores 0x55 signature byte instead of 0x42 at the header
4753     * See http://lclevy.free.fr/raw/
4754     */
4755    private boolean isRw2Format(byte[] signatureCheckBytes) throws IOException {
4756        ByteOrderedDataInputStream signatureInputStream =
4757                new ByteOrderedDataInputStream(signatureCheckBytes);
4758        // Read byte order
4759        mExifByteOrder = readByteOrder(signatureInputStream);
4760        // Set byte order
4761        signatureInputStream.setByteOrder(mExifByteOrder);
4762
4763        short signatureByte = signatureInputStream.readShort();
4764        signatureInputStream.close();
4765        return signatureByte == RW2_SIGNATURE;
4766    }
4767
4768    /**
4769     * Loads EXIF attributes from a JPEG input stream.
4770     *
4771     * @param in The input stream that starts with the JPEG data.
4772     * @param jpegOffset The offset value in input stream for JPEG data.
4773     * @param imageType The image type from which to retrieve metadata. Use IFD_TYPE_PRIMARY for
4774     *                   primary image, IFD_TYPE_PREVIEW for preview image, and
4775     *                   IFD_TYPE_THUMBNAIL for thumbnail image.
4776     * @throws IOException If the data contains invalid JPEG markers, offsets, or length values.
4777     */
4778    private void getJpegAttributes(ByteOrderedDataInputStream in, int jpegOffset, int imageType)
4779            throws IOException {
4780        // See JPEG File Interchange Format Specification, "JFIF Specification"
4781        if (DEBUG) {
4782            Log.d(TAG, "getJpegAttributes starting with: " + in);
4783        }
4784
4785        // JPEG uses Big Endian by default. See https://people.cs.umass.edu/~verts/cs32/endian.html
4786        in.setByteOrder(ByteOrder.BIG_ENDIAN);
4787
4788        // Skip to JPEG data
4789        in.seek(jpegOffset);
4790        int bytesRead = jpegOffset;
4791
4792        byte marker;
4793        if ((marker = in.readByte()) != MARKER) {
4794            throw new IOException("Invalid marker: " + Integer.toHexString(marker & 0xff));
4795        }
4796        ++bytesRead;
4797        if (in.readByte() != MARKER_SOI) {
4798            throw new IOException("Invalid marker: " + Integer.toHexString(marker & 0xff));
4799        }
4800        ++bytesRead;
4801        while (true) {
4802            marker = in.readByte();
4803            if (marker != MARKER) {
4804                throw new IOException("Invalid marker:" + Integer.toHexString(marker & 0xff));
4805            }
4806            ++bytesRead;
4807            marker = in.readByte();
4808            if (DEBUG) {
4809                Log.d(TAG, "Found JPEG segment indicator: " + Integer.toHexString(marker & 0xff));
4810            }
4811            ++bytesRead;
4812
4813            // EOI indicates the end of an image and in case of SOS, JPEG image stream starts and
4814            // the image data will terminate right after.
4815            if (marker == MARKER_EOI || marker == MARKER_SOS) {
4816                break;
4817            }
4818            int length = in.readUnsignedShort() - 2;
4819            bytesRead += 2;
4820            if (DEBUG) {
4821                Log.d(TAG, "JPEG segment: " + Integer.toHexString(marker & 0xff) + " (length: "
4822                        + (length + 2) + ")");
4823            }
4824            if (length < 0) {
4825                throw new IOException("Invalid length");
4826            }
4827            switch (marker) {
4828                case MARKER_APP1: {
4829                    if (DEBUG) {
4830                        Log.d(TAG, "MARKER_APP1");
4831                    }
4832                    if (length < 6) {
4833                        // Skip if it's not an EXIF APP1 segment.
4834                        break;
4835                    }
4836                    byte[] identifier = new byte[6];
4837                    if (in.read(identifier) != 6) {
4838                        throw new IOException("Invalid exif");
4839                    }
4840                    bytesRead += 6;
4841                    length -= 6;
4842                    if (!Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) {
4843                        // Skip if it's not an EXIF APP1 segment.
4844                        break;
4845                    }
4846                    if (length <= 0) {
4847                        throw new IOException("Invalid exif");
4848                    }
4849                    if (DEBUG) {
4850                        Log.d(TAG, "readExifSegment with a byte array (length: " + length + ")");
4851                    }
4852                    // Save offset values for createJpegThumbnailBitmap() function
4853                    mExifOffset = bytesRead;
4854
4855                    byte[] bytes = new byte[length];
4856                    if (in.read(bytes) != length) {
4857                        throw new IOException("Invalid exif");
4858                    }
4859                    bytesRead += length;
4860                    length = 0;
4861
4862                    readExifSegment(bytes, imageType);
4863                    break;
4864                }
4865
4866                case MARKER_COM: {
4867                    byte[] bytes = new byte[length];
4868                    if (in.read(bytes) != length) {
4869                        throw new IOException("Invalid exif");
4870                    }
4871                    length = 0;
4872                    if (getAttribute(TAG_USER_COMMENT) == null) {
4873                        mAttributes[IFD_TYPE_EXIF].put(TAG_USER_COMMENT, ExifAttribute.createString(
4874                                new String(bytes, ASCII)));
4875                    }
4876                    break;
4877                }
4878
4879                case MARKER_SOF0:
4880                case MARKER_SOF1:
4881                case MARKER_SOF2:
4882                case MARKER_SOF3:
4883                case MARKER_SOF5:
4884                case MARKER_SOF6:
4885                case MARKER_SOF7:
4886                case MARKER_SOF9:
4887                case MARKER_SOF10:
4888                case MARKER_SOF11:
4889                case MARKER_SOF13:
4890                case MARKER_SOF14:
4891                case MARKER_SOF15: {
4892                    if (in.skipBytes(1) != 1) {
4893                        throw new IOException("Invalid SOFx");
4894                    }
4895                    mAttributes[imageType].put(TAG_IMAGE_LENGTH, ExifAttribute.createULong(
4896                            in.readUnsignedShort(), mExifByteOrder));
4897                    mAttributes[imageType].put(TAG_IMAGE_WIDTH, ExifAttribute.createULong(
4898                            in.readUnsignedShort(), mExifByteOrder));
4899                    length -= 5;
4900                    break;
4901                }
4902
4903                default: {
4904                    break;
4905                }
4906            }
4907            if (length < 0) {
4908                throw new IOException("Invalid length");
4909            }
4910            if (in.skipBytes(length) != length) {
4911                throw new IOException("Invalid JPEG segment");
4912            }
4913            bytesRead += length;
4914        }
4915        // Restore original byte order
4916        in.setByteOrder(mExifByteOrder);
4917    }
4918
4919    private void getRawAttributes(ByteOrderedDataInputStream in) throws IOException {
4920        // Parse TIFF Headers. See JEITA CP-3451C Section 4.5.2. Table 1.
4921        parseTiffHeaders(in, in.available());
4922
4923        // Read TIFF image file directories. See JEITA CP-3451C Section 4.5.2. Figure 6.
4924        readImageFileDirectory(in, IFD_TYPE_PRIMARY);
4925
4926        // Update ImageLength/Width tags for all image data.
4927        updateImageSizeValues(in, IFD_TYPE_PRIMARY);
4928        updateImageSizeValues(in, IFD_TYPE_PREVIEW);
4929        updateImageSizeValues(in, IFD_TYPE_THUMBNAIL);
4930
4931        // Check if each image data is in valid position.
4932        validateImages(in);
4933
4934        if (mMimeType == IMAGE_TYPE_PEF) {
4935            // PEF files contain a MakerNote data, which contains the data for ColorSpace tag.
4936            // See http://lclevy.free.fr/raw/ and piex.cc PefGetPreviewData()
4937            ExifAttribute makerNoteAttribute =
4938                    (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_MAKER_NOTE);
4939            if (makerNoteAttribute != null) {
4940                // Create an ordered DataInputStream for MakerNote
4941                ByteOrderedDataInputStream makerNoteDataInputStream =
4942                        new ByteOrderedDataInputStream(makerNoteAttribute.bytes);
4943                makerNoteDataInputStream.setByteOrder(mExifByteOrder);
4944
4945                // Seek to MakerNote data
4946                makerNoteDataInputStream.seek(PEF_MAKER_NOTE_SKIP_SIZE);
4947
4948                // Read IFD data from MakerNote
4949                readImageFileDirectory(makerNoteDataInputStream, IFD_TYPE_PEF);
4950
4951                // Update ColorSpace tag
4952                ExifAttribute colorSpaceAttribute =
4953                        (ExifAttribute) mAttributes[IFD_TYPE_PEF].get(TAG_COLOR_SPACE);
4954                if (colorSpaceAttribute != null) {
4955                    mAttributes[IFD_TYPE_EXIF].put(TAG_COLOR_SPACE, colorSpaceAttribute);
4956                }
4957            }
4958        }
4959    }
4960
4961    /**
4962     * RAF files contains a JPEG and a CFA data.
4963     * The JPEG contains two images, a preview and a thumbnail, while the CFA contains a RAW image.
4964     * This method looks at the first 160 bytes of a RAF file to retrieve the offset and length
4965     * values for the JPEG and CFA data.
4966     * Using that data, it parses the JPEG data to retrieve the preview and thumbnail image data,
4967     * then parses the CFA metadata to retrieve the primary image length/width values.
4968     * For data format details, see http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
4969     */
4970    private void getRafAttributes(ByteOrderedDataInputStream in) throws IOException {
4971        // Retrieve offset & length values
4972        in.skipBytes(RAF_OFFSET_TO_JPEG_IMAGE_OFFSET);
4973        byte[] jpegOffsetBytes = new byte[4];
4974        byte[] cfaHeaderOffsetBytes = new byte[4];
4975        in.read(jpegOffsetBytes);
4976        // Skip JPEG length value since it is not needed
4977        in.skipBytes(RAF_JPEG_LENGTH_VALUE_SIZE);
4978        in.read(cfaHeaderOffsetBytes);
4979        int rafJpegOffset = ByteBuffer.wrap(jpegOffsetBytes).getInt();
4980        int rafCfaHeaderOffset = ByteBuffer.wrap(cfaHeaderOffsetBytes).getInt();
4981
4982        // Retrieve JPEG image metadata
4983        getJpegAttributes(in, rafJpegOffset, IFD_TYPE_PREVIEW);
4984
4985        // Skip to CFA header offset.
4986        in.seek(rafCfaHeaderOffset);
4987
4988        // Retrieve primary image length/width values, if TAG_RAF_IMAGE_SIZE exists
4989        in.setByteOrder(ByteOrder.BIG_ENDIAN);
4990        int numberOfDirectoryEntry = in.readInt();
4991        if (DEBUG) {
4992            Log.d(TAG, "numberOfDirectoryEntry: " + numberOfDirectoryEntry);
4993        }
4994        // CFA stores some metadata about the RAW image. Since CFA uses proprietary tags, can only
4995        // find and retrieve image size information tags, while skipping others.
4996        // See piex.cc RafGetDimension()
4997        for (int i = 0; i < numberOfDirectoryEntry; ++i) {
4998            int tagNumber = in.readUnsignedShort();
4999            int numberOfBytes = in.readUnsignedShort();
5000            if (tagNumber == TAG_RAF_IMAGE_SIZE.number) {
5001                int imageLength = in.readShort();
5002                int imageWidth = in.readShort();
5003                ExifAttribute imageLengthAttribute =
5004                        ExifAttribute.createUShort(imageLength, mExifByteOrder);
5005                ExifAttribute imageWidthAttribute =
5006                        ExifAttribute.createUShort(imageWidth, mExifByteOrder);
5007                mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH, imageLengthAttribute);
5008                mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH, imageWidthAttribute);
5009                if (DEBUG) {
5010                    Log.d(TAG, "Updated to length: " + imageLength + ", width: " + imageWidth);
5011                }
5012                return;
5013            }
5014            in.skipBytes(numberOfBytes);
5015        }
5016    }
5017
5018    /**
5019     * ORF files contains a primary image data and a MakerNote data that contains preview/thumbnail
5020     * images. Both data takes the form of IFDs and can therefore be read with the
5021     * readImageFileDirectory() method.
5022     * This method reads all the necessary data and updates the primary/preview/thumbnail image
5023     * information according to the GetOlympusPreviewImage() method in piex.cc.
5024     * For data format details, see the following:
5025     * http://fileformats.archiveteam.org/wiki/Olympus_ORF
5026     * https://libopenraw.freedesktop.org/wiki/Olympus_ORF
5027     */
5028    private void getOrfAttributes(ByteOrderedDataInputStream in) throws IOException {
5029        // Retrieve primary image data
5030        // Other Exif data will be located in the Makernote.
5031        getRawAttributes(in);
5032
5033        // Additionally retrieve preview/thumbnail information from MakerNote tag, which contains
5034        // proprietary tags and therefore does not have offical documentation
5035        // See GetOlympusPreviewImage() in piex.cc & http://www.exiv2.org/tags-olympus.html
5036        ExifAttribute makerNoteAttribute =
5037                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_MAKER_NOTE);
5038        if (makerNoteAttribute != null) {
5039            // Create an ordered DataInputStream for MakerNote
5040            ByteOrderedDataInputStream makerNoteDataInputStream =
5041                    new ByteOrderedDataInputStream(makerNoteAttribute.bytes);
5042            makerNoteDataInputStream.setByteOrder(mExifByteOrder);
5043
5044            // There are two types of headers for Olympus MakerNotes
5045            // See http://www.exiv2.org/makernote.html#R1
5046            byte[] makerNoteHeader1Bytes = new byte[ORF_MAKER_NOTE_HEADER_1.length];
5047            makerNoteDataInputStream.readFully(makerNoteHeader1Bytes);
5048            makerNoteDataInputStream.seek(0);
5049            byte[] makerNoteHeader2Bytes = new byte[ORF_MAKER_NOTE_HEADER_2.length];
5050            makerNoteDataInputStream.readFully(makerNoteHeader2Bytes);
5051            // Skip the corresponding amount of bytes for each header type
5052            if (Arrays.equals(makerNoteHeader1Bytes, ORF_MAKER_NOTE_HEADER_1)) {
5053                makerNoteDataInputStream.seek(ORF_MAKER_NOTE_HEADER_1_SIZE);
5054            } else if (Arrays.equals(makerNoteHeader2Bytes, ORF_MAKER_NOTE_HEADER_2)) {
5055                makerNoteDataInputStream.seek(ORF_MAKER_NOTE_HEADER_2_SIZE);
5056            }
5057
5058            // Read IFD data from MakerNote
5059            readImageFileDirectory(makerNoteDataInputStream, IFD_TYPE_ORF_MAKER_NOTE);
5060
5061            // Retrieve & update preview image offset & length values
5062            ExifAttribute imageStartAttribute = (ExifAttribute)
5063                    mAttributes[IFD_TYPE_ORF_CAMERA_SETTINGS].get(TAG_ORF_PREVIEW_IMAGE_START);
5064            ExifAttribute imageLengthAttribute = (ExifAttribute)
5065                    mAttributes[IFD_TYPE_ORF_CAMERA_SETTINGS].get(TAG_ORF_PREVIEW_IMAGE_LENGTH);
5066
5067            if (imageStartAttribute != null && imageLengthAttribute != null) {
5068                mAttributes[IFD_TYPE_PREVIEW].put(TAG_JPEG_INTERCHANGE_FORMAT,
5069                        imageStartAttribute);
5070                mAttributes[IFD_TYPE_PREVIEW].put(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
5071                        imageLengthAttribute);
5072            }
5073
5074            // TODO: Check this behavior in other ORF files
5075            // Retrieve primary image length & width values
5076            // See piex.cc GetOlympusPreviewImage()
5077            ExifAttribute aspectFrameAttribute = (ExifAttribute)
5078                    mAttributes[IFD_TYPE_ORF_IMAGE_PROCESSING].get(TAG_ORF_ASPECT_FRAME);
5079            if (aspectFrameAttribute != null) {
5080                int[] aspectFrameValues = (int[]) aspectFrameAttribute.getValue(mExifByteOrder);
5081                if (aspectFrameValues == null || aspectFrameValues.length != 4) {
5082                    Log.w(TAG, "Invalid aspect frame values. frame="
5083                            + Arrays.toString(aspectFrameValues));
5084                    return;
5085                }
5086                if (aspectFrameValues[2] > aspectFrameValues[0] &&
5087                        aspectFrameValues[3] > aspectFrameValues[1]) {
5088                    int primaryImageWidth = aspectFrameValues[2] - aspectFrameValues[0] + 1;
5089                    int primaryImageLength = aspectFrameValues[3] - aspectFrameValues[1] + 1;
5090                    // Swap width & length values
5091                    if (primaryImageWidth < primaryImageLength) {
5092                        primaryImageWidth += primaryImageLength;
5093                        primaryImageLength = primaryImageWidth - primaryImageLength;
5094                        primaryImageWidth -= primaryImageLength;
5095                    }
5096                    ExifAttribute primaryImageWidthAttribute =
5097                            ExifAttribute.createUShort(primaryImageWidth, mExifByteOrder);
5098                    ExifAttribute primaryImageLengthAttribute =
5099                            ExifAttribute.createUShort(primaryImageLength, mExifByteOrder);
5100
5101                    mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH, primaryImageWidthAttribute);
5102                    mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH, primaryImageLengthAttribute);
5103                }
5104            }
5105        }
5106    }
5107
5108    // RW2 contains the primary image data in IFD0 and the preview and/or thumbnail image data in
5109    // the JpgFromRaw tag
5110    // See https://libopenraw.freedesktop.org/wiki/Panasonic_RAW/ and piex.cc Rw2GetPreviewData()
5111    private void getRw2Attributes(ByteOrderedDataInputStream in) throws IOException {
5112        // Retrieve primary image data
5113        getRawAttributes(in);
5114
5115        // Retrieve preview and/or thumbnail image data
5116        ExifAttribute jpgFromRawAttribute =
5117                (ExifAttribute) mAttributes[IFD_TYPE_PRIMARY].get(TAG_RW2_JPG_FROM_RAW);
5118        if (jpgFromRawAttribute != null) {
5119            getJpegAttributes(in, mRw2JpgFromRawOffset, IFD_TYPE_PREVIEW);
5120        }
5121
5122        // Set ISO tag value if necessary
5123        ExifAttribute rw2IsoAttribute =
5124                (ExifAttribute) mAttributes[IFD_TYPE_PRIMARY].get(TAG_RW2_ISO);
5125        ExifAttribute exifIsoAttribute =
5126                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_PHOTOGRAPHIC_SENSITIVITY);
5127        if (rw2IsoAttribute != null && exifIsoAttribute == null) {
5128            // Place this attribute only if it doesn't exist
5129            mAttributes[IFD_TYPE_EXIF].put(TAG_PHOTOGRAPHIC_SENSITIVITY, rw2IsoAttribute);
5130        }
5131    }
5132
5133    // Stores a new JPEG image with EXIF attributes into a given output stream.
5134    private void saveJpegAttributes(InputStream inputStream, OutputStream outputStream)
5135            throws IOException {
5136        // See JPEG File Interchange Format Specification, "JFIF Specification"
5137        if (DEBUG) {
5138            Log.d(TAG, "saveJpegAttributes starting with (inputStream: " + inputStream
5139                    + ", outputStream: " + outputStream + ")");
5140        }
5141        DataInputStream dataInputStream = new DataInputStream(inputStream);
5142        ByteOrderedDataOutputStream dataOutputStream =
5143                new ByteOrderedDataOutputStream(outputStream, ByteOrder.BIG_ENDIAN);
5144        if (dataInputStream.readByte() != MARKER) {
5145            throw new IOException("Invalid marker");
5146        }
5147        dataOutputStream.writeByte(MARKER);
5148        if (dataInputStream.readByte() != MARKER_SOI) {
5149            throw new IOException("Invalid marker");
5150        }
5151        dataOutputStream.writeByte(MARKER_SOI);
5152
5153        // Write EXIF APP1 segment
5154        dataOutputStream.writeByte(MARKER);
5155        dataOutputStream.writeByte(MARKER_APP1);
5156        writeExifSegment(dataOutputStream, 6);
5157
5158        byte[] bytes = new byte[4096];
5159
5160        while (true) {
5161            byte marker = dataInputStream.readByte();
5162            if (marker != MARKER) {
5163                throw new IOException("Invalid marker");
5164            }
5165            marker = dataInputStream.readByte();
5166            switch (marker) {
5167                case MARKER_APP1: {
5168                    int length = dataInputStream.readUnsignedShort() - 2;
5169                    if (length < 0) {
5170                        throw new IOException("Invalid length");
5171                    }
5172                    byte[] identifier = new byte[6];
5173                    if (length >= 6) {
5174                        if (dataInputStream.read(identifier) != 6) {
5175                            throw new IOException("Invalid exif");
5176                        }
5177                        if (Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) {
5178                            // Skip the original EXIF APP1 segment.
5179                            if (dataInputStream.skipBytes(length - 6) != length - 6) {
5180                                throw new IOException("Invalid length");
5181                            }
5182                            break;
5183                        }
5184                    }
5185                    // Copy non-EXIF APP1 segment.
5186                    dataOutputStream.writeByte(MARKER);
5187                    dataOutputStream.writeByte(marker);
5188                    dataOutputStream.writeUnsignedShort(length + 2);
5189                    if (length >= 6) {
5190                        length -= 6;
5191                        dataOutputStream.write(identifier);
5192                    }
5193                    int read;
5194                    while (length > 0 && (read = dataInputStream.read(
5195                            bytes, 0, Math.min(length, bytes.length))) >= 0) {
5196                        dataOutputStream.write(bytes, 0, read);
5197                        length -= read;
5198                    }
5199                    break;
5200                }
5201                case MARKER_EOI:
5202                case MARKER_SOS: {
5203                    dataOutputStream.writeByte(MARKER);
5204                    dataOutputStream.writeByte(marker);
5205                    // Copy all the remaining data
5206                    copy(dataInputStream, dataOutputStream);
5207                    return;
5208                }
5209                default: {
5210                    // Copy JPEG segment
5211                    dataOutputStream.writeByte(MARKER);
5212                    dataOutputStream.writeByte(marker);
5213                    int length = dataInputStream.readUnsignedShort();
5214                    dataOutputStream.writeUnsignedShort(length);
5215                    length -= 2;
5216                    if (length < 0) {
5217                        throw new IOException("Invalid length");
5218                    }
5219                    int read;
5220                    while (length > 0 && (read = dataInputStream.read(
5221                            bytes, 0, Math.min(length, bytes.length))) >= 0) {
5222                        dataOutputStream.write(bytes, 0, read);
5223                        length -= read;
5224                    }
5225                    break;
5226                }
5227            }
5228        }
5229    }
5230
5231    // Reads the given EXIF byte area and save its tag data into attributes.
5232    private void readExifSegment(byte[] exifBytes, int imageType) throws IOException {
5233        ByteOrderedDataInputStream dataInputStream =
5234                new ByteOrderedDataInputStream(exifBytes);
5235
5236        // Parse TIFF Headers. See JEITA CP-3451C Section 4.5.2. Table 1.
5237        parseTiffHeaders(dataInputStream, exifBytes.length);
5238
5239        // Read TIFF image file directories. See JEITA CP-3451C Section 4.5.2. Figure 6.
5240        readImageFileDirectory(dataInputStream, imageType);
5241    }
5242
5243    private void addDefaultValuesForCompatibility() {
5244        // If DATETIME tag has no value, then set the value to DATETIME_ORIGINAL tag's.
5245        String valueOfDateTimeOriginal = getAttribute(TAG_DATETIME_ORIGINAL);
5246        if (valueOfDateTimeOriginal != null && getAttribute(TAG_DATETIME) == null) {
5247            mAttributes[IFD_TYPE_PRIMARY].put(TAG_DATETIME,
5248                    ExifAttribute.createString(valueOfDateTimeOriginal));
5249        }
5250
5251        // Add the default value.
5252        if (getAttribute(TAG_IMAGE_WIDTH) == null) {
5253            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH,
5254                    ExifAttribute.createULong(0, mExifByteOrder));
5255        }
5256        if (getAttribute(TAG_IMAGE_LENGTH) == null) {
5257            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH,
5258                    ExifAttribute.createULong(0, mExifByteOrder));
5259        }
5260        if (getAttribute(TAG_ORIENTATION) == null) {
5261            mAttributes[IFD_TYPE_PRIMARY].put(TAG_ORIENTATION,
5262                    ExifAttribute.createULong(0, mExifByteOrder));
5263        }
5264        if (getAttribute(TAG_LIGHT_SOURCE) == null) {
5265            mAttributes[IFD_TYPE_EXIF].put(TAG_LIGHT_SOURCE,
5266                    ExifAttribute.createULong(0, mExifByteOrder));
5267        }
5268    }
5269
5270    private ByteOrder readByteOrder(ByteOrderedDataInputStream dataInputStream)
5271            throws IOException {
5272        // Read byte order.
5273        short byteOrder = dataInputStream.readShort();
5274        switch (byteOrder) {
5275            case BYTE_ALIGN_II:
5276                if (DEBUG) {
5277                    Log.d(TAG, "readExifSegment: Byte Align II");
5278                }
5279                return ByteOrder.LITTLE_ENDIAN;
5280            case BYTE_ALIGN_MM:
5281                if (DEBUG) {
5282                    Log.d(TAG, "readExifSegment: Byte Align MM");
5283                }
5284                return ByteOrder.BIG_ENDIAN;
5285            default:
5286                throw new IOException("Invalid byte order: " + Integer.toHexString(byteOrder));
5287        }
5288    }
5289
5290    private void parseTiffHeaders(ByteOrderedDataInputStream dataInputStream,
5291            int exifBytesLength) throws IOException {
5292        // Read byte order
5293        mExifByteOrder = readByteOrder(dataInputStream);
5294        // Set byte order
5295        dataInputStream.setByteOrder(mExifByteOrder);
5296
5297        // Check start code
5298        int startCode = dataInputStream.readUnsignedShort();
5299        if (mMimeType != IMAGE_TYPE_ORF && mMimeType != IMAGE_TYPE_RW2 && startCode != START_CODE) {
5300            throw new IOException("Invalid start code: " + Integer.toHexString(startCode));
5301        }
5302
5303        // Read and skip to first ifd offset
5304        int firstIfdOffset = dataInputStream.readInt();
5305        if (firstIfdOffset < 8 || firstIfdOffset >= exifBytesLength) {
5306            throw new IOException("Invalid first Ifd offset: " + firstIfdOffset);
5307        }
5308        firstIfdOffset -= 8;
5309        if (firstIfdOffset > 0) {
5310            if (dataInputStream.skipBytes(firstIfdOffset) != firstIfdOffset) {
5311                throw new IOException("Couldn't jump to first Ifd: " + firstIfdOffset);
5312            }
5313        }
5314    }
5315
5316    // Reads image file directory, which is a tag group in EXIF.
5317    private void readImageFileDirectory(ByteOrderedDataInputStream dataInputStream,
5318            @IfdType int ifdType) throws IOException {
5319        if (dataInputStream.mPosition + 2 > dataInputStream.mLength) {
5320            // Return if there is no data from the offset.
5321            return;
5322        }
5323        // See TIFF 6.0 Section 2: TIFF Structure, Figure 1.
5324        short numberOfDirectoryEntry = dataInputStream.readShort();
5325        if (DEBUG) {
5326            Log.d(TAG, "numberOfDirectoryEntry: " + numberOfDirectoryEntry);
5327        }
5328        if (dataInputStream.mPosition + 12 * numberOfDirectoryEntry > dataInputStream.mLength) {
5329            // Return if the size of entries is too big.
5330            return;
5331        }
5332
5333        // See TIFF 6.0 Section 2: TIFF Structure, "Image File Directory".
5334        for (short i = 0; i < numberOfDirectoryEntry; ++i) {
5335            int tagNumber = dataInputStream.readUnsignedShort();
5336            int dataFormat = dataInputStream.readUnsignedShort();
5337            int numberOfComponents = dataInputStream.readInt();
5338            // Next four bytes is for data offset or value.
5339            long nextEntryOffset = dataInputStream.peek() + 4L;
5340
5341            // Look up a corresponding tag from tag number
5342            ExifTag tag = (ExifTag) sExifTagMapsForReading[ifdType].get(tagNumber);
5343
5344            if (DEBUG) {
5345                Log.d(TAG, String.format("ifdType: %d, tagNumber: %d, tagName: %s, dataFormat: %d, "
5346                        + "numberOfComponents: %d", ifdType, tagNumber,
5347                        tag != null ? tag.name : null, dataFormat, numberOfComponents));
5348            }
5349
5350            long byteCount = 0;
5351            boolean valid = false;
5352            if (tag == null) {
5353                Log.w(TAG, "Skip the tag entry since tag number is not defined: " + tagNumber);
5354            } else if (dataFormat <= 0 || dataFormat >= IFD_FORMAT_BYTES_PER_FORMAT.length) {
5355                Log.w(TAG, "Skip the tag entry since data format is invalid: " + dataFormat);
5356            } else if (!tag.isFormatCompatible(dataFormat)) {
5357                Log.w(TAG, "Skip the tag entry since data format (" + IFD_FORMAT_NAMES[dataFormat]
5358                        + ") is unexpected for tag: " + tag.name);
5359            } else {
5360                if (dataFormat == IFD_FORMAT_UNDEFINED) {
5361                    dataFormat = tag.primaryFormat;
5362                }
5363                byteCount = (long) numberOfComponents * IFD_FORMAT_BYTES_PER_FORMAT[dataFormat];
5364                if (byteCount < 0 || byteCount > Integer.MAX_VALUE) {
5365                    Log.w(TAG, "Skip the tag entry since the number of components is invalid: "
5366                            + numberOfComponents);
5367                } else {
5368                    valid = true;
5369                }
5370            }
5371            if (!valid) {
5372                dataInputStream.seek(nextEntryOffset);
5373                continue;
5374            }
5375
5376            // Read a value from data field or seek to the value offset which is stored in data
5377            // field if the size of the entry value is bigger than 4.
5378            if (byteCount > 4) {
5379                int offset = dataInputStream.readInt();
5380                if (DEBUG) {
5381                    Log.d(TAG, "seek to data offset: " + offset);
5382                }
5383                if (mMimeType == IMAGE_TYPE_ORF) {
5384                    if (TAG_MAKER_NOTE.equals(tag.name)) {
5385                        // Save offset value for reading thumbnail
5386                        mOrfMakerNoteOffset = offset;
5387                    } else if (ifdType == IFD_TYPE_ORF_MAKER_NOTE
5388                            && TAG_ORF_THUMBNAIL_IMAGE.equals(tag.name)) {
5389                        // Retrieve & update values for thumbnail offset and length values for ORF
5390                        mOrfThumbnailOffset = offset;
5391                        mOrfThumbnailLength = numberOfComponents;
5392
5393                        ExifAttribute compressionAttribute =
5394                                ExifAttribute.createUShort(DATA_JPEG, mExifByteOrder);
5395                        ExifAttribute jpegInterchangeFormatAttribute =
5396                                ExifAttribute.createULong(mOrfThumbnailOffset, mExifByteOrder);
5397                        ExifAttribute jpegInterchangeFormatLengthAttribute =
5398                                ExifAttribute.createULong(mOrfThumbnailLength, mExifByteOrder);
5399
5400                        mAttributes[IFD_TYPE_THUMBNAIL].put(TAG_COMPRESSION, compressionAttribute);
5401                        mAttributes[IFD_TYPE_THUMBNAIL].put(TAG_JPEG_INTERCHANGE_FORMAT,
5402                                jpegInterchangeFormatAttribute);
5403                        mAttributes[IFD_TYPE_THUMBNAIL].put(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
5404                                jpegInterchangeFormatLengthAttribute);
5405                    }
5406                } else if (mMimeType == IMAGE_TYPE_RW2) {
5407                    if (TAG_RW2_JPG_FROM_RAW.equals(tag.name)) {
5408                        mRw2JpgFromRawOffset = offset;
5409                    }
5410                }
5411                if (offset + byteCount <= dataInputStream.mLength) {
5412                    dataInputStream.seek(offset);
5413                } else {
5414                    // Skip if invalid data offset.
5415                    Log.w(TAG, "Skip the tag entry since data offset is invalid: " + offset);
5416                    dataInputStream.seek(nextEntryOffset);
5417                    continue;
5418                }
5419            }
5420
5421            // Recursively parse IFD when a IFD pointer tag appears.
5422            Integer nextIfdType = sExifPointerTagMap.get(tagNumber);
5423            if (DEBUG) {
5424                Log.d(TAG, "nextIfdType: " + nextIfdType + " byteCount: " + byteCount);
5425            }
5426
5427            if (nextIfdType != null) {
5428                long offset = -1L;
5429                // Get offset from data field
5430                switch (dataFormat) {
5431                    case IFD_FORMAT_USHORT: {
5432                        offset = dataInputStream.readUnsignedShort();
5433                        break;
5434                    }
5435                    case IFD_FORMAT_SSHORT: {
5436                        offset = dataInputStream.readShort();
5437                        break;
5438                    }
5439                    case IFD_FORMAT_ULONG: {
5440                        offset = dataInputStream.readUnsignedInt();
5441                        break;
5442                    }
5443                    case IFD_FORMAT_SLONG:
5444                    case IFD_FORMAT_IFD: {
5445                        offset = dataInputStream.readInt();
5446                        break;
5447                    }
5448                    default: {
5449                        // Nothing to do
5450                        break;
5451                    }
5452                }
5453                if (DEBUG) {
5454                    Log.d(TAG, String.format("Offset: %d, tagName: %s", offset, tag.name));
5455                }
5456                if (offset > 0L && offset < dataInputStream.mLength) {
5457                    dataInputStream.seek(offset);
5458                    readImageFileDirectory(dataInputStream, nextIfdType);
5459                } else {
5460                    Log.w(TAG, "Skip jump into the IFD since its offset is invalid: " + offset);
5461                }
5462
5463                dataInputStream.seek(nextEntryOffset);
5464                continue;
5465            }
5466
5467            byte[] bytes = new byte[(int) byteCount];
5468            dataInputStream.readFully(bytes);
5469            ExifAttribute attribute = new ExifAttribute(dataFormat, numberOfComponents, bytes);
5470            mAttributes[ifdType].put(tag.name, attribute);
5471
5472            // DNG files have a DNG Version tag specifying the version of specifications that the
5473            // image file is following.
5474            // See http://fileformats.archiveteam.org/wiki/DNG
5475            if (TAG_DNG_VERSION.equals(tag.name)) {
5476                mMimeType = IMAGE_TYPE_DNG;
5477            }
5478
5479            // PEF files have a Make or Model tag that begins with "PENTAX" or a compression tag
5480            // that is 65535.
5481            // See http://fileformats.archiveteam.org/wiki/Pentax_PEF
5482            if (((TAG_MAKE.equals(tag.name) || TAG_MODEL.equals(tag.name))
5483                    && attribute.getStringValue(mExifByteOrder).contains(PEF_SIGNATURE))
5484                    || (TAG_COMPRESSION.equals(tag.name)
5485                    && attribute.getIntValue(mExifByteOrder) == 65535)) {
5486                mMimeType = IMAGE_TYPE_PEF;
5487            }
5488
5489            // Seek to next tag offset
5490            if (dataInputStream.peek() != nextEntryOffset) {
5491                dataInputStream.seek(nextEntryOffset);
5492            }
5493        }
5494
5495        if (dataInputStream.peek() + 4 <= dataInputStream.mLength) {
5496            int nextIfdOffset = dataInputStream.readInt();
5497            if (DEBUG) {
5498                Log.d(TAG, String.format("nextIfdOffset: %d", nextIfdOffset));
5499            }
5500            // The next IFD offset needs to be bigger than 8
5501            // since the first IFD offset is at least 8.
5502            if (nextIfdOffset > 8 && nextIfdOffset < dataInputStream.mLength) {
5503                dataInputStream.seek(nextIfdOffset);
5504                if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
5505                    // Do not overwrite thumbnail IFD data if it alreay exists.
5506                    readImageFileDirectory(dataInputStream, IFD_TYPE_THUMBNAIL);
5507                } else if (mAttributes[IFD_TYPE_PREVIEW].isEmpty()) {
5508                    readImageFileDirectory(dataInputStream, IFD_TYPE_PREVIEW);
5509                }
5510            }
5511        }
5512    }
5513
5514    /**
5515     * JPEG compressed images do not contain IMAGE_LENGTH & IMAGE_WIDTH tags.
5516     * This value uses JpegInterchangeFormat(JPEG data offset) value, and calls getJpegAttributes()
5517     * to locate SOF(Start of Frame) marker and update the image length & width values.
5518     * See JEITA CP-3451C Table 5 and Section 4.8.1. B.
5519     */
5520    private void retrieveJpegImageSize(ByteOrderedDataInputStream in, int imageType)
5521            throws IOException {
5522        // Check if image already has IMAGE_LENGTH & IMAGE_WIDTH values
5523        ExifAttribute imageLengthAttribute =
5524                (ExifAttribute) mAttributes[imageType].get(TAG_IMAGE_LENGTH);
5525        ExifAttribute imageWidthAttribute =
5526                (ExifAttribute) mAttributes[imageType].get(TAG_IMAGE_WIDTH);
5527
5528        if (imageLengthAttribute == null || imageWidthAttribute == null) {
5529            // Find if offset for JPEG data exists
5530            ExifAttribute jpegInterchangeFormatAttribute =
5531                    (ExifAttribute) mAttributes[imageType].get(TAG_JPEG_INTERCHANGE_FORMAT);
5532            if (jpegInterchangeFormatAttribute != null) {
5533                int jpegInterchangeFormat =
5534                        jpegInterchangeFormatAttribute.getIntValue(mExifByteOrder);
5535
5536                // Searches for SOF marker in JPEG data and updates IMAGE_LENGTH & IMAGE_WIDTH tags
5537                getJpegAttributes(in, jpegInterchangeFormat, imageType);
5538            }
5539        }
5540    }
5541
5542    // Sets thumbnail offset & length attributes based on JpegInterchangeFormat or StripOffsets tags
5543    private void setThumbnailData(ByteOrderedDataInputStream in) throws IOException {
5544        HashMap thumbnailData = mAttributes[IFD_TYPE_THUMBNAIL];
5545
5546        ExifAttribute compressionAttribute =
5547                (ExifAttribute) thumbnailData.get(TAG_COMPRESSION);
5548        if (compressionAttribute != null) {
5549            mThumbnailCompression = compressionAttribute.getIntValue(mExifByteOrder);
5550            switch (mThumbnailCompression) {
5551                case DATA_JPEG: {
5552                    handleThumbnailFromJfif(in, thumbnailData);
5553                    break;
5554                }
5555                case DATA_UNCOMPRESSED:
5556                case DATA_JPEG_COMPRESSED: {
5557                    if (isSupportedDataType(thumbnailData)) {
5558                        handleThumbnailFromStrips(in, thumbnailData);
5559                    }
5560                    break;
5561                }
5562            }
5563        } else {
5564            // Thumbnail data may not contain Compression tag value
5565            mThumbnailCompression = DATA_JPEG;
5566            handleThumbnailFromJfif(in, thumbnailData);
5567        }
5568    }
5569
5570    // Check JpegInterchangeFormat(JFIF) tags to retrieve thumbnail offset & length values
5571    // and reads the corresponding bytes if stream does not support seek function
5572    private void handleThumbnailFromJfif(ByteOrderedDataInputStream in, HashMap thumbnailData)
5573            throws IOException {
5574        ExifAttribute jpegInterchangeFormatAttribute =
5575                (ExifAttribute) thumbnailData.get(TAG_JPEG_INTERCHANGE_FORMAT);
5576        ExifAttribute jpegInterchangeFormatLengthAttribute =
5577                (ExifAttribute) thumbnailData.get(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
5578        if (jpegInterchangeFormatAttribute != null
5579                && jpegInterchangeFormatLengthAttribute != null) {
5580            int thumbnailOffset = jpegInterchangeFormatAttribute.getIntValue(mExifByteOrder);
5581            int thumbnailLength = jpegInterchangeFormatLengthAttribute.getIntValue(mExifByteOrder);
5582
5583            // The following code limits the size of thumbnail size not to overflow EXIF data area.
5584            thumbnailLength = Math.min(thumbnailLength, in.available() - thumbnailOffset);
5585            if (mMimeType == IMAGE_TYPE_JPEG || mMimeType == IMAGE_TYPE_RAF
5586                    || mMimeType == IMAGE_TYPE_RW2) {
5587                thumbnailOffset += mExifOffset;
5588            } else if (mMimeType == IMAGE_TYPE_ORF) {
5589                // Update offset value since RAF files have IFD data preceding MakerNote data.
5590                thumbnailOffset += mOrfMakerNoteOffset;
5591            }
5592            if (DEBUG) {
5593                Log.d(TAG, "Setting thumbnail attributes with offset: " + thumbnailOffset
5594                        + ", length: " + thumbnailLength);
5595            }
5596            if (thumbnailOffset > 0 && thumbnailLength > 0) {
5597                mHasThumbnail = true;
5598                mThumbnailOffset = thumbnailOffset;
5599                mThumbnailLength = thumbnailLength;
5600                if (mFilename == null && mAssetInputStream == null) {
5601                    // Save the thumbnail in memory if the input doesn't support reading again.
5602                    byte[] thumbnailBytes = new byte[thumbnailLength];
5603                    in.seek(thumbnailOffset);
5604                    in.readFully(thumbnailBytes);
5605                    mThumbnailBytes = thumbnailBytes;
5606                }
5607            }
5608        }
5609    }
5610
5611    // Check StripOffsets & StripByteCounts tags to retrieve thumbnail offset & length values
5612    private void handleThumbnailFromStrips(ByteOrderedDataInputStream in, HashMap thumbnailData)
5613            throws IOException {
5614        ExifAttribute stripOffsetsAttribute =
5615                (ExifAttribute) thumbnailData.get(TAG_STRIP_OFFSETS);
5616        ExifAttribute stripByteCountsAttribute =
5617                (ExifAttribute) thumbnailData.get(TAG_STRIP_BYTE_COUNTS);
5618
5619        if (stripOffsetsAttribute != null && stripByteCountsAttribute != null) {
5620            long[] stripOffsets =
5621                    convertToLongArray(stripOffsetsAttribute.getValue(mExifByteOrder));
5622            long[] stripByteCounts =
5623                    convertToLongArray(stripByteCountsAttribute.getValue(mExifByteOrder));
5624
5625            if (stripOffsets == null) {
5626                Log.w(TAG, "stripOffsets should not be null.");
5627                return;
5628            }
5629            if (stripByteCounts == null) {
5630                Log.w(TAG, "stripByteCounts should not be null.");
5631                return;
5632            }
5633
5634            long totalStripByteCount = 0;
5635            for (long byteCount : stripByteCounts) {
5636                totalStripByteCount += byteCount;
5637            }
5638
5639            // Set thumbnail byte array data for non-consecutive strip bytes
5640            byte[] totalStripBytes = new byte[(int) totalStripByteCount];
5641
5642            int bytesRead = 0;
5643            int bytesAdded = 0;
5644            for (int i = 0; i < stripOffsets.length; i++) {
5645                int stripOffset = (int) stripOffsets[i];
5646                int stripByteCount = (int) stripByteCounts[i];
5647
5648                // Skip to offset
5649                int skipBytes = stripOffset - bytesRead;
5650                if (skipBytes < 0) {
5651                    Log.d(TAG, "Invalid strip offset value");
5652                }
5653                in.seek(skipBytes);
5654                bytesRead += skipBytes;
5655
5656                // Read strip bytes
5657                byte[] stripBytes = new byte[stripByteCount];
5658                in.read(stripBytes);
5659                bytesRead += stripByteCount;
5660
5661                // Add bytes to array
5662                System.arraycopy(stripBytes, 0, totalStripBytes, bytesAdded,
5663                        stripBytes.length);
5664                bytesAdded += stripBytes.length;
5665            }
5666
5667            mHasThumbnail = true;
5668            mThumbnailBytes = totalStripBytes;
5669            mThumbnailLength = totalStripBytes.length;
5670        }
5671    }
5672
5673    // Check if thumbnail data type is currently supported or not
5674    private boolean isSupportedDataType(HashMap thumbnailData) throws IOException {
5675        ExifAttribute bitsPerSampleAttribute =
5676                (ExifAttribute) thumbnailData.get(TAG_BITS_PER_SAMPLE);
5677        if (bitsPerSampleAttribute != null) {
5678            int[] bitsPerSampleValue = (int[]) bitsPerSampleAttribute.getValue(mExifByteOrder);
5679
5680            if (Arrays.equals(BITS_PER_SAMPLE_RGB, bitsPerSampleValue)) {
5681                return true;
5682            }
5683
5684            // See DNG Specification 1.4.0.0. Section 3, Compression.
5685            if (mMimeType == IMAGE_TYPE_DNG) {
5686                ExifAttribute photometricInterpretationAttribute =
5687                        (ExifAttribute) thumbnailData.get(TAG_PHOTOMETRIC_INTERPRETATION);
5688                if (photometricInterpretationAttribute != null) {
5689                    int photometricInterpretationValue
5690                            = photometricInterpretationAttribute.getIntValue(mExifByteOrder);
5691                    if ((photometricInterpretationValue == PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO
5692                            && Arrays.equals(bitsPerSampleValue, BITS_PER_SAMPLE_GREYSCALE_2))
5693                            || ((photometricInterpretationValue == PHOTOMETRIC_INTERPRETATION_YCBCR)
5694                            && (Arrays.equals(bitsPerSampleValue, BITS_PER_SAMPLE_RGB)))) {
5695                        return true;
5696                    } else {
5697                        // TODO: Add support for lossless Huffman JPEG data
5698                    }
5699                }
5700            }
5701        }
5702        if (DEBUG) {
5703            Log.d(TAG, "Unsupported data type value");
5704        }
5705        return false;
5706    }
5707
5708    // Returns true if the image length and width values are <= 512.
5709    // See Section 4.8 of http://standardsproposals.bsigroup.com/Home/getPDF/567
5710    private boolean isThumbnail(HashMap map) throws IOException {
5711        ExifAttribute imageLengthAttribute = (ExifAttribute) map.get(TAG_IMAGE_LENGTH);
5712        ExifAttribute imageWidthAttribute = (ExifAttribute) map.get(TAG_IMAGE_WIDTH);
5713
5714        if (imageLengthAttribute != null && imageWidthAttribute != null) {
5715            int imageLengthValue = imageLengthAttribute.getIntValue(mExifByteOrder);
5716            int imageWidthValue = imageWidthAttribute.getIntValue(mExifByteOrder);
5717            if (imageLengthValue <= MAX_THUMBNAIL_SIZE && imageWidthValue <= MAX_THUMBNAIL_SIZE) {
5718                return true;
5719            }
5720        }
5721        return false;
5722    }
5723
5724    // Validate primary, preview, thumbnail image data by comparing image size
5725    private void validateImages(InputStream in) throws IOException {
5726        // Swap images based on size (primary > preview > thumbnail)
5727        swapBasedOnImageSize(IFD_TYPE_PRIMARY, IFD_TYPE_PREVIEW);
5728        swapBasedOnImageSize(IFD_TYPE_PRIMARY, IFD_TYPE_THUMBNAIL);
5729        swapBasedOnImageSize(IFD_TYPE_PREVIEW, IFD_TYPE_THUMBNAIL);
5730
5731        // Check if image has PixelXDimension/PixelYDimension tags, which contain valid image
5732        // sizes, excluding padding at the right end or bottom end of the image to make sure that
5733        // the values are multiples of 64. See JEITA CP-3451C Table 5 and Section 4.8.1. B.
5734        ExifAttribute pixelXDimAttribute =
5735                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_PIXEL_X_DIMENSION);
5736        ExifAttribute pixelYDimAttribute =
5737                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_PIXEL_Y_DIMENSION);
5738        if (pixelXDimAttribute != null && pixelYDimAttribute != null) {
5739            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH, pixelXDimAttribute);
5740            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH, pixelYDimAttribute);
5741        }
5742
5743        // Check whether thumbnail image exists and whether preview image satisfies the thumbnail
5744        // image requirements
5745        if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
5746            if (isThumbnail(mAttributes[IFD_TYPE_PREVIEW])) {
5747                mAttributes[IFD_TYPE_THUMBNAIL] = mAttributes[IFD_TYPE_PREVIEW];
5748                mAttributes[IFD_TYPE_PREVIEW] = new HashMap<>();
5749            }
5750        }
5751
5752        // Check if the thumbnail image satisfies the thumbnail size requirements
5753        if (!isThumbnail(mAttributes[IFD_TYPE_THUMBNAIL])) {
5754            Log.d(TAG, "No image meets the size requirements of a thumbnail image.");
5755        }
5756    }
5757
5758    /**
5759     * If image is uncompressed, ImageWidth/Length tags are used to store size info.
5760     * However, uncompressed images often store extra pixels around the edges of the final image,
5761     * which results in larger values for TAG_IMAGE_WIDTH and TAG_IMAGE_LENGTH tags.
5762     * This method corrects those tag values by checking first the values of TAG_DEFAULT_CROP_SIZE
5763     * See DNG Specification 1.4.0.0. Section 4. (DefaultCropSize)
5764     *
5765     * If image is a RW2 file, valid image sizes are stored in SensorBorder tags.
5766     * See tiff_parser.cc GetFullDimension32()
5767     * */
5768    private void updateImageSizeValues(ByteOrderedDataInputStream in, int imageType)
5769            throws IOException {
5770        // Uncompressed image valid image size values
5771        ExifAttribute defaultCropSizeAttribute =
5772                (ExifAttribute) mAttributes[imageType].get(TAG_DEFAULT_CROP_SIZE);
5773        // RW2 image valid image size values
5774        ExifAttribute topBorderAttribute =
5775                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_TOP_BORDER);
5776        ExifAttribute leftBorderAttribute =
5777                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_LEFT_BORDER);
5778        ExifAttribute bottomBorderAttribute =
5779                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_BOTTOM_BORDER);
5780        ExifAttribute rightBorderAttribute =
5781                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_RIGHT_BORDER);
5782
5783        if (defaultCropSizeAttribute != null) {
5784            // Update for uncompressed image
5785            ExifAttribute defaultCropSizeXAttribute, defaultCropSizeYAttribute;
5786            if (defaultCropSizeAttribute.format == IFD_FORMAT_URATIONAL) {
5787                Rational[] defaultCropSizeValue =
5788                        (Rational[]) defaultCropSizeAttribute.getValue(mExifByteOrder);
5789                if (defaultCropSizeValue == null || defaultCropSizeValue.length != 2) {
5790                    Log.w(TAG, "Invalid crop size values. cropSize="
5791                            + Arrays.toString(defaultCropSizeValue));
5792                    return;
5793                }
5794                defaultCropSizeXAttribute =
5795                        ExifAttribute.createURational(defaultCropSizeValue[0], mExifByteOrder);
5796                defaultCropSizeYAttribute =
5797                        ExifAttribute.createURational(defaultCropSizeValue[1], mExifByteOrder);
5798            } else {
5799                int[] defaultCropSizeValue =
5800                        (int[]) defaultCropSizeAttribute.getValue(mExifByteOrder);
5801                if (defaultCropSizeValue == null || defaultCropSizeValue.length != 2) {
5802                    Log.w(TAG, "Invalid crop size values. cropSize="
5803                            + Arrays.toString(defaultCropSizeValue));
5804                    return;
5805                }
5806                defaultCropSizeXAttribute =
5807                        ExifAttribute.createUShort(defaultCropSizeValue[0], mExifByteOrder);
5808                defaultCropSizeYAttribute =
5809                        ExifAttribute.createUShort(defaultCropSizeValue[1], mExifByteOrder);
5810            }
5811            mAttributes[imageType].put(TAG_IMAGE_WIDTH, defaultCropSizeXAttribute);
5812            mAttributes[imageType].put(TAG_IMAGE_LENGTH, defaultCropSizeYAttribute);
5813        } else if (topBorderAttribute != null && leftBorderAttribute != null &&
5814                bottomBorderAttribute != null && rightBorderAttribute != null) {
5815            // Update for RW2 image
5816            int topBorderValue = topBorderAttribute.getIntValue(mExifByteOrder);
5817            int bottomBorderValue = bottomBorderAttribute.getIntValue(mExifByteOrder);
5818            int rightBorderValue = rightBorderAttribute.getIntValue(mExifByteOrder);
5819            int leftBorderValue = leftBorderAttribute.getIntValue(mExifByteOrder);
5820            if (bottomBorderValue > topBorderValue && rightBorderValue > leftBorderValue) {
5821                int length = bottomBorderValue - topBorderValue;
5822                int width = rightBorderValue - leftBorderValue;
5823                ExifAttribute imageLengthAttribute =
5824                        ExifAttribute.createUShort(length, mExifByteOrder);
5825                ExifAttribute imageWidthAttribute =
5826                        ExifAttribute.createUShort(width, mExifByteOrder);
5827                mAttributes[imageType].put(TAG_IMAGE_LENGTH, imageLengthAttribute);
5828                mAttributes[imageType].put(TAG_IMAGE_WIDTH, imageWidthAttribute);
5829            }
5830        } else {
5831            retrieveJpegImageSize(in, imageType);
5832        }
5833    }
5834
5835    // Writes an Exif segment into the given output stream.
5836    private int writeExifSegment(ByteOrderedDataOutputStream dataOutputStream,
5837            int exifOffsetFromBeginning) throws IOException {
5838        // The following variables are for calculating each IFD tag group size in bytes.
5839        int[] ifdOffsets = new int[EXIF_TAGS.length];
5840        int[] ifdDataSizes = new int[EXIF_TAGS.length];
5841
5842        // Remove IFD pointer tags (we'll re-add it later.)
5843        for (ExifTag tag : EXIF_POINTER_TAGS) {
5844            removeAttribute(tag.name);
5845        }
5846        // Remove old thumbnail data
5847        removeAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name);
5848        removeAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name);
5849
5850        // Remove null value tags.
5851        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
5852            for (Object obj : mAttributes[ifdType].entrySet().toArray()) {
5853                final Map.Entry entry = (Map.Entry) obj;
5854                if (entry.getValue() == null) {
5855                    mAttributes[ifdType].remove(entry.getKey());
5856                }
5857            }
5858        }
5859
5860        // Add IFD pointer tags. The next offset of primary image TIFF IFD will have thumbnail IFD
5861        // offset when there is one or more tags in the thumbnail IFD.
5862        if (!mAttributes[IFD_TYPE_EXIF].isEmpty()) {
5863            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[1].name,
5864                    ExifAttribute.createULong(0, mExifByteOrder));
5865        }
5866        if (!mAttributes[IFD_TYPE_GPS].isEmpty()) {
5867            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[2].name,
5868                    ExifAttribute.createULong(0, mExifByteOrder));
5869        }
5870        if (!mAttributes[IFD_TYPE_INTEROPERABILITY].isEmpty()) {
5871            mAttributes[IFD_TYPE_EXIF].put(EXIF_POINTER_TAGS[3].name,
5872                    ExifAttribute.createULong(0, mExifByteOrder));
5873        }
5874        if (mHasThumbnail) {
5875            mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_TAG.name,
5876                    ExifAttribute.createULong(0, mExifByteOrder));
5877            mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name,
5878                    ExifAttribute.createULong(mThumbnailLength, mExifByteOrder));
5879        }
5880
5881        // Calculate IFD group data area sizes. IFD group data area is assigned to save the entry
5882        // value which has a bigger size than 4 bytes.
5883        for (int i = 0; i < EXIF_TAGS.length; ++i) {
5884            int sum = 0;
5885            for (Map.Entry<String, ExifAttribute> entry : mAttributes[i].entrySet()) {
5886                final ExifAttribute exifAttribute = entry.getValue();
5887                final int size = exifAttribute.size();
5888                if (size > 4) {
5889                    sum += size;
5890                }
5891            }
5892            ifdDataSizes[i] += sum;
5893        }
5894
5895        // Calculate IFD offsets.
5896        int position = 8;
5897        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
5898            if (!mAttributes[ifdType].isEmpty()) {
5899                ifdOffsets[ifdType] = position;
5900                position += 2 + mAttributes[ifdType].size() * 12 + 4 + ifdDataSizes[ifdType];
5901            }
5902        }
5903        if (mHasThumbnail) {
5904            int thumbnailOffset = position;
5905            mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_TAG.name,
5906                    ExifAttribute.createULong(thumbnailOffset, mExifByteOrder));
5907            mThumbnailOffset = exifOffsetFromBeginning + thumbnailOffset;
5908            position += mThumbnailLength;
5909        }
5910
5911        // Calculate the total size
5912        int totalSize = position + 8;  // eight bytes is for header part.
5913        if (DEBUG) {
5914            Log.d(TAG, "totalSize length: " + totalSize);
5915            for (int i = 0; i < EXIF_TAGS.length; ++i) {
5916                Log.d(TAG, String.format("index: %d, offsets: %d, tag count: %d, data sizes: %d",
5917                        i, ifdOffsets[i], mAttributes[i].size(), ifdDataSizes[i]));
5918            }
5919        }
5920
5921        // Update IFD pointer tags with the calculated offsets.
5922        if (!mAttributes[IFD_TYPE_EXIF].isEmpty()) {
5923            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[1].name,
5924                    ExifAttribute.createULong(ifdOffsets[IFD_TYPE_EXIF], mExifByteOrder));
5925        }
5926        if (!mAttributes[IFD_TYPE_GPS].isEmpty()) {
5927            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[2].name,
5928                    ExifAttribute.createULong(ifdOffsets[IFD_TYPE_GPS], mExifByteOrder));
5929        }
5930        if (!mAttributes[IFD_TYPE_INTEROPERABILITY].isEmpty()) {
5931            mAttributes[IFD_TYPE_EXIF].put(EXIF_POINTER_TAGS[3].name, ExifAttribute.createULong(
5932                    ifdOffsets[IFD_TYPE_INTEROPERABILITY], mExifByteOrder));
5933        }
5934
5935        // Write TIFF Headers. See JEITA CP-3451C Section 4.5.2. Table 1.
5936        dataOutputStream.writeUnsignedShort(totalSize);
5937        dataOutputStream.write(IDENTIFIER_EXIF_APP1);
5938        dataOutputStream.writeShort(mExifByteOrder == ByteOrder.BIG_ENDIAN
5939                ? BYTE_ALIGN_MM : BYTE_ALIGN_II);
5940        dataOutputStream.setByteOrder(mExifByteOrder);
5941        dataOutputStream.writeUnsignedShort(START_CODE);
5942        dataOutputStream.writeUnsignedInt(IFD_OFFSET);
5943
5944        // Write IFD groups. See JEITA CP-3451C Section 4.5.8. Figure 9.
5945        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
5946            if (!mAttributes[ifdType].isEmpty()) {
5947                // See JEITA CP-3451C Section 4.6.2: IFD structure.
5948                // Write entry count
5949                dataOutputStream.writeUnsignedShort(mAttributes[ifdType].size());
5950
5951                // Write entry info
5952                int dataOffset = ifdOffsets[ifdType] + 2 + mAttributes[ifdType].size() * 12 + 4;
5953                for (Map.Entry<String, ExifAttribute> entry : mAttributes[ifdType].entrySet()) {
5954                    // Convert tag name to tag number.
5955                    final ExifTag tag = sExifTagMapsForWriting[ifdType].get(entry.getKey());
5956                    final int tagNumber = tag.number;
5957                    final ExifAttribute attribute = entry.getValue();
5958                    final int size = attribute.size();
5959
5960                    dataOutputStream.writeUnsignedShort(tagNumber);
5961                    dataOutputStream.writeUnsignedShort(attribute.format);
5962                    dataOutputStream.writeInt(attribute.numberOfComponents);
5963                    if (size > 4) {
5964                        dataOutputStream.writeUnsignedInt(dataOffset);
5965                        dataOffset += size;
5966                    } else {
5967                        dataOutputStream.write(attribute.bytes);
5968                        // Fill zero up to 4 bytes
5969                        if (size < 4) {
5970                            for (int i = size; i < 4; ++i) {
5971                                dataOutputStream.writeByte(0);
5972                            }
5973                        }
5974                    }
5975                }
5976
5977                // Write the next offset. It writes the offset of thumbnail IFD if there is one or
5978                // more tags in the thumbnail IFD when the current IFD is the primary image TIFF
5979                // IFD; Otherwise 0.
5980                if (ifdType == 0 && !mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
5981                    dataOutputStream.writeUnsignedInt(ifdOffsets[IFD_TYPE_THUMBNAIL]);
5982                } else {
5983                    dataOutputStream.writeUnsignedInt(0);
5984                }
5985
5986                // Write values of data field exceeding 4 bytes after the next offset.
5987                for (Map.Entry<String, ExifAttribute> entry : mAttributes[ifdType].entrySet()) {
5988                    ExifAttribute attribute = entry.getValue();
5989
5990                    if (attribute.bytes.length > 4) {
5991                        dataOutputStream.write(attribute.bytes, 0, attribute.bytes.length);
5992                    }
5993                }
5994            }
5995        }
5996
5997        // Write thumbnail
5998        if (mHasThumbnail) {
5999            dataOutputStream.write(getThumbnailBytes());
6000        }
6001
6002        // Reset the byte order to big endian in order to write remaining parts of the JPEG file.
6003        dataOutputStream.setByteOrder(ByteOrder.BIG_ENDIAN);
6004
6005        return totalSize;
6006    }
6007
6008    /**
6009     * Determines the data format of EXIF entry value.
6010     *
6011     * @param entryValue The value to be determined.
6012     * @return Returns two data formats gussed as a pair in integer. If there is no two candidate
6013               data formats for the given entry value, returns {@code -1} in the second of the pair.
6014     */
6015    private static Pair<Integer, Integer> guessDataFormat(String entryValue) {
6016        // See TIFF 6.0 Section 2, "Image File Directory".
6017        // Take the first component if there are more than one component.
6018        if (entryValue.contains(",")) {
6019            String[] entryValues = entryValue.split(",");
6020            Pair<Integer, Integer> dataFormat = guessDataFormat(entryValues[0]);
6021            if (dataFormat.first == IFD_FORMAT_STRING) {
6022                return dataFormat;
6023            }
6024            for (int i = 1; i < entryValues.length; ++i) {
6025                final Pair<Integer, Integer> guessDataFormat = guessDataFormat(entryValues[i]);
6026                int first = -1, second = -1;
6027                if (guessDataFormat.first.equals(dataFormat.first)
6028                        || guessDataFormat.second.equals(dataFormat.first)) {
6029                    first = dataFormat.first;
6030                }
6031                if (dataFormat.second != -1 && (guessDataFormat.first.equals(dataFormat.second)
6032                        || guessDataFormat.second.equals(dataFormat.second))) {
6033                    second = dataFormat.second;
6034                }
6035                if (first == -1 && second == -1) {
6036                    return new Pair<>(IFD_FORMAT_STRING, -1);
6037                }
6038                if (first == -1) {
6039                    dataFormat = new Pair<>(second, -1);
6040                    continue;
6041                }
6042                if (second == -1) {
6043                    dataFormat = new Pair<>(first, -1);
6044                    continue;
6045                }
6046            }
6047            return dataFormat;
6048        }
6049
6050        if (entryValue.contains("/")) {
6051            String[] rationalNumber = entryValue.split("/");
6052            if (rationalNumber.length == 2) {
6053                try {
6054                    long numerator = (long) Double.parseDouble(rationalNumber[0]);
6055                    long denominator = (long) Double.parseDouble(rationalNumber[1]);
6056                    if (numerator < 0L || denominator < 0L) {
6057                        return new Pair<>(IFD_FORMAT_SRATIONAL, -1);
6058                    }
6059                    if (numerator > Integer.MAX_VALUE || denominator > Integer.MAX_VALUE) {
6060                        return new Pair<>(IFD_FORMAT_URATIONAL, -1);
6061                    }
6062                    return new Pair<>(IFD_FORMAT_SRATIONAL, IFD_FORMAT_URATIONAL);
6063                } catch (NumberFormatException e)  {
6064                    // Ignored
6065                }
6066            }
6067            return new Pair<>(IFD_FORMAT_STRING, -1);
6068        }
6069        try {
6070            Long longValue = Long.parseLong(entryValue);
6071            if (longValue >= 0 && longValue <= 65535) {
6072                return new Pair<>(IFD_FORMAT_USHORT, IFD_FORMAT_ULONG);
6073            }
6074            if (longValue < 0) {
6075                return new Pair<>(IFD_FORMAT_SLONG, -1);
6076            }
6077            return new Pair<>(IFD_FORMAT_ULONG, -1);
6078        } catch (NumberFormatException e) {
6079            // Ignored
6080        }
6081        try {
6082            Double.parseDouble(entryValue);
6083            return new Pair<>(IFD_FORMAT_DOUBLE, -1);
6084        } catch (NumberFormatException e) {
6085            // Ignored
6086        }
6087        return new Pair<>(IFD_FORMAT_STRING, -1);
6088    }
6089
6090    // An input stream to parse EXIF data area, which can be written in either little or big endian
6091    // order.
6092    private static class ByteOrderedDataInputStream extends InputStream implements DataInput {
6093        private static final ByteOrder LITTLE_ENDIAN = ByteOrder.LITTLE_ENDIAN;
6094        private static final ByteOrder BIG_ENDIAN = ByteOrder.BIG_ENDIAN;
6095
6096        private DataInputStream mDataInputStream;
6097        private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
6098        private final int mLength;
6099        private int mPosition;
6100
6101        public ByteOrderedDataInputStream(InputStream in) throws IOException {
6102            mDataInputStream = new DataInputStream(in);
6103            mLength = mDataInputStream.available();
6104            mPosition = 0;
6105            mDataInputStream.mark(mLength);
6106        }
6107
6108        public ByteOrderedDataInputStream(byte[] bytes) throws IOException {
6109            this(new ByteArrayInputStream(bytes));
6110        }
6111
6112        public void setByteOrder(ByteOrder byteOrder) {
6113            mByteOrder = byteOrder;
6114        }
6115
6116        public void seek(long byteCount) throws IOException {
6117            if (mPosition > byteCount) {
6118                mPosition = 0;
6119                mDataInputStream.reset();
6120                mDataInputStream.mark(mLength);
6121            } else {
6122                byteCount -= mPosition;
6123            }
6124
6125            if (skipBytes((int) byteCount) != (int) byteCount) {
6126                throw new IOException("Couldn't seek up to the byteCount");
6127            }
6128        }
6129
6130        public int peek() {
6131            return mPosition;
6132        }
6133
6134        @Override
6135        public int available() throws IOException {
6136            return mDataInputStream.available();
6137        }
6138
6139        @Override
6140        public int read() throws IOException {
6141            ++mPosition;
6142            return mDataInputStream.read();
6143        }
6144
6145        @Override
6146        public int read(byte[] b, int off, int len) throws IOException {
6147            int bytesRead = mDataInputStream.read(b, off, len);
6148            mPosition += bytesRead;
6149            return bytesRead;
6150        }
6151
6152        @Override
6153        public int readUnsignedByte() throws IOException {
6154            ++mPosition;
6155            return mDataInputStream.readUnsignedByte();
6156        }
6157
6158        @Override
6159        public String readLine() throws IOException {
6160            Log.d(TAG, "Currently unsupported");
6161            return null;
6162        }
6163
6164        @Override
6165        public boolean readBoolean() throws IOException {
6166            ++mPosition;
6167            return mDataInputStream.readBoolean();
6168        }
6169
6170        @Override
6171        public char readChar() throws IOException {
6172            mPosition += 2;
6173            return mDataInputStream.readChar();
6174        }
6175
6176        @Override
6177        public String readUTF() throws IOException {
6178            mPosition += 2;
6179            return mDataInputStream.readUTF();
6180        }
6181
6182        @Override
6183        public void readFully(byte[] buffer, int offset, int length) throws IOException {
6184            mPosition += length;
6185            if (mPosition > mLength) {
6186                throw new EOFException();
6187            }
6188            if (mDataInputStream.read(buffer, offset, length) != length) {
6189                throw new IOException("Couldn't read up to the length of buffer");
6190            }
6191        }
6192
6193        @Override
6194        public void readFully(byte[] buffer) throws IOException {
6195            mPosition += buffer.length;
6196            if (mPosition > mLength) {
6197                throw new EOFException();
6198            }
6199            if (mDataInputStream.read(buffer, 0, buffer.length) != buffer.length) {
6200                throw new IOException("Couldn't read up to the length of buffer");
6201            }
6202        }
6203
6204        @Override
6205        public byte readByte() throws IOException {
6206            ++mPosition;
6207            if (mPosition > mLength) {
6208                throw new EOFException();
6209            }
6210            int ch = mDataInputStream.read();
6211            if (ch < 0) {
6212                throw new EOFException();
6213            }
6214            return (byte) ch;
6215        }
6216
6217        @Override
6218        public short readShort() throws IOException {
6219            mPosition += 2;
6220            if (mPosition > mLength) {
6221                throw new EOFException();
6222            }
6223            int ch1 = mDataInputStream.read();
6224            int ch2 = mDataInputStream.read();
6225            if ((ch1 | ch2) < 0) {
6226                throw new EOFException();
6227            }
6228            if (mByteOrder == LITTLE_ENDIAN) {
6229                return (short) ((ch2 << 8) + (ch1));
6230            } else if (mByteOrder == BIG_ENDIAN) {
6231                return (short) ((ch1 << 8) + (ch2));
6232            }
6233            throw new IOException("Invalid byte order: " + mByteOrder);
6234        }
6235
6236        @Override
6237        public int readInt() throws IOException {
6238            mPosition += 4;
6239            if (mPosition > mLength) {
6240                throw new EOFException();
6241            }
6242            int ch1 = mDataInputStream.read();
6243            int ch2 = mDataInputStream.read();
6244            int ch3 = mDataInputStream.read();
6245            int ch4 = mDataInputStream.read();
6246            if ((ch1 | ch2 | ch3 | ch4) < 0) {
6247                throw new EOFException();
6248            }
6249            if (mByteOrder == LITTLE_ENDIAN) {
6250                return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + ch1);
6251            } else if (mByteOrder == BIG_ENDIAN) {
6252                return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
6253            }
6254            throw new IOException("Invalid byte order: " + mByteOrder);
6255        }
6256
6257        @Override
6258        public int skipBytes(int byteCount) throws IOException {
6259            int totalSkip = Math.min(byteCount, mLength - mPosition);
6260            int skipped = 0;
6261            while (skipped < totalSkip) {
6262                skipped += mDataInputStream.skipBytes(totalSkip - skipped);
6263            }
6264            mPosition += skipped;
6265            return skipped;
6266        }
6267
6268        @Override
6269        public int readUnsignedShort() throws IOException {
6270            mPosition += 2;
6271            if (mPosition > mLength) {
6272                throw new EOFException();
6273            }
6274            int ch1 = mDataInputStream.read();
6275            int ch2 = mDataInputStream.read();
6276            if ((ch1 | ch2) < 0) {
6277                throw new EOFException();
6278            }
6279            if (mByteOrder == LITTLE_ENDIAN) {
6280                return ((ch2 << 8) + (ch1));
6281            } else if (mByteOrder == BIG_ENDIAN) {
6282                return ((ch1 << 8) + (ch2));
6283            }
6284            throw new IOException("Invalid byte order: " + mByteOrder);
6285        }
6286
6287        public long readUnsignedInt() throws IOException {
6288            return readInt() & 0xffffffffL;
6289        }
6290
6291        @Override
6292        public long readLong() throws IOException {
6293            mPosition += 8;
6294            if (mPosition > mLength) {
6295                throw new EOFException();
6296            }
6297            int ch1 = mDataInputStream.read();
6298            int ch2 = mDataInputStream.read();
6299            int ch3 = mDataInputStream.read();
6300            int ch4 = mDataInputStream.read();
6301            int ch5 = mDataInputStream.read();
6302            int ch6 = mDataInputStream.read();
6303            int ch7 = mDataInputStream.read();
6304            int ch8 = mDataInputStream.read();
6305            if ((ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8) < 0) {
6306                throw new EOFException();
6307            }
6308            if (mByteOrder == LITTLE_ENDIAN) {
6309                return (((long) ch8 << 56) + ((long) ch7 << 48) + ((long) ch6 << 40)
6310                        + ((long) ch5 << 32) + ((long) ch4 << 24) + ((long) ch3 << 16)
6311                        + ((long) ch2 << 8) + (long) ch1);
6312            } else if (mByteOrder == BIG_ENDIAN) {
6313                return (((long) ch1 << 56) + ((long) ch2 << 48) + ((long) ch3 << 40)
6314                        + ((long) ch4 << 32) + ((long) ch5 << 24) + ((long) ch6 << 16)
6315                        + ((long) ch7 << 8) + (long) ch8);
6316            }
6317            throw new IOException("Invalid byte order: " + mByteOrder);
6318        }
6319
6320        @Override
6321        public float readFloat() throws IOException {
6322            return Float.intBitsToFloat(readInt());
6323        }
6324
6325        @Override
6326        public double readDouble() throws IOException {
6327            return Double.longBitsToDouble(readLong());
6328        }
6329    }
6330
6331    // An output stream to write EXIF data area, which can be written in either little or big endian
6332    // order.
6333    private static class ByteOrderedDataOutputStream extends FilterOutputStream {
6334        private final OutputStream mOutputStream;
6335        private ByteOrder mByteOrder;
6336
6337        public ByteOrderedDataOutputStream(OutputStream out, ByteOrder byteOrder) {
6338            super(out);
6339            mOutputStream = out;
6340            mByteOrder = byteOrder;
6341        }
6342
6343        public void setByteOrder(ByteOrder byteOrder) {
6344            mByteOrder = byteOrder;
6345        }
6346
6347        @Override
6348        public void write(byte[] bytes) throws IOException {
6349            mOutputStream.write(bytes);
6350        }
6351
6352        @Override
6353        public void write(byte[] bytes, int offset, int length) throws IOException {
6354            mOutputStream.write(bytes, offset, length);
6355        }
6356
6357        public void writeByte(int val) throws IOException {
6358            mOutputStream.write(val);
6359        }
6360
6361        public void writeShort(short val) throws IOException {
6362            if (mByteOrder == ByteOrder.LITTLE_ENDIAN) {
6363                mOutputStream.write((val >>> 0) & 0xFF);
6364                mOutputStream.write((val >>> 8) & 0xFF);
6365            } else if (mByteOrder == ByteOrder.BIG_ENDIAN) {
6366                mOutputStream.write((val >>> 8) & 0xFF);
6367                mOutputStream.write((val >>> 0) & 0xFF);
6368            }
6369        }
6370
6371        public void writeInt(int val) throws IOException {
6372            if (mByteOrder == ByteOrder.LITTLE_ENDIAN) {
6373                mOutputStream.write((val >>> 0) & 0xFF);
6374                mOutputStream.write((val >>> 8) & 0xFF);
6375                mOutputStream.write((val >>> 16) & 0xFF);
6376                mOutputStream.write((val >>> 24) & 0xFF);
6377            } else if (mByteOrder == ByteOrder.BIG_ENDIAN) {
6378                mOutputStream.write((val >>> 24) & 0xFF);
6379                mOutputStream.write((val >>> 16) & 0xFF);
6380                mOutputStream.write((val >>> 8) & 0xFF);
6381                mOutputStream.write((val >>> 0) & 0xFF);
6382            }
6383        }
6384
6385        public void writeUnsignedShort(int val) throws IOException {
6386            writeShort((short) val);
6387        }
6388
6389        public void writeUnsignedInt(long val) throws IOException {
6390            writeInt((int) val);
6391        }
6392    }
6393
6394    // Swaps image data based on image size
6395    private void swapBasedOnImageSize(@IfdType int firstIfdType, @IfdType int secondIfdType)
6396            throws IOException {
6397        if (mAttributes[firstIfdType].isEmpty() || mAttributes[secondIfdType].isEmpty()) {
6398            if (DEBUG) {
6399                Log.d(TAG, "Cannot perform swap since only one image data exists");
6400            }
6401            return;
6402        }
6403
6404        ExifAttribute firstImageLengthAttribute =
6405                (ExifAttribute) mAttributes[firstIfdType].get(TAG_IMAGE_LENGTH);
6406        ExifAttribute firstImageWidthAttribute =
6407                (ExifAttribute) mAttributes[firstIfdType].get(TAG_IMAGE_WIDTH);
6408        ExifAttribute secondImageLengthAttribute =
6409                (ExifAttribute) mAttributes[secondIfdType].get(TAG_IMAGE_LENGTH);
6410        ExifAttribute secondImageWidthAttribute =
6411                (ExifAttribute) mAttributes[secondIfdType].get(TAG_IMAGE_WIDTH);
6412
6413        if (firstImageLengthAttribute == null || firstImageWidthAttribute == null) {
6414            if (DEBUG) {
6415                Log.d(TAG, "First image does not contain valid size information");
6416            }
6417        } else if (secondImageLengthAttribute == null || secondImageWidthAttribute == null) {
6418            if (DEBUG) {
6419                Log.d(TAG, "Second image does not contain valid size information");
6420            }
6421        } else {
6422            int firstImageLengthValue = firstImageLengthAttribute.getIntValue(mExifByteOrder);
6423            int firstImageWidthValue = firstImageWidthAttribute.getIntValue(mExifByteOrder);
6424            int secondImageLengthValue = secondImageLengthAttribute.getIntValue(mExifByteOrder);
6425            int secondImageWidthValue = secondImageWidthAttribute.getIntValue(mExifByteOrder);
6426
6427            if (firstImageLengthValue < secondImageLengthValue &&
6428                    firstImageWidthValue < secondImageWidthValue) {
6429                HashMap<String, ExifAttribute> tempMap = mAttributes[firstIfdType];
6430                mAttributes[firstIfdType] = mAttributes[secondIfdType];
6431                mAttributes[secondIfdType] = tempMap;
6432            }
6433        }
6434    }
6435
6436    /**
6437     * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
6438     */
6439    private static void closeQuietly(Closeable closeable) {
6440        if (closeable != null) {
6441            try {
6442                closeable.close();
6443            } catch (RuntimeException rethrown) {
6444                throw rethrown;
6445            } catch (Exception ignored) {
6446            }
6447        }
6448    }
6449
6450    /**
6451     * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
6452     * Returns the total number of bytes transferred.
6453     */
6454    private static int copy(InputStream in, OutputStream out) throws IOException {
6455        int total = 0;
6456        byte[] buffer = new byte[8192];
6457        int c;
6458        while ((c = in.read(buffer)) != -1) {
6459            total += c;
6460            out.write(buffer, 0, c);
6461        }
6462        return total;
6463    }
6464
6465    /**
6466     * Convert given int[] to long[]. If long[] is given, just return it.
6467     * Return null for other types of input.
6468     */
6469    private static long[] convertToLongArray(Object inputObj) {
6470        if (inputObj instanceof int[]) {
6471            int[] input = (int[]) inputObj;
6472            long[] result = new long[input.length];
6473            for (int i = 0; i < input.length; i++) {
6474                result[i] = input[i];
6475            }
6476            return result;
6477        } else if (inputObj instanceof long[]) {
6478            return (long[]) inputObj;
6479        }
6480        return null;
6481    }
6482}
6483