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