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