blob: b8b387201ffef53e1b31b0e4f49a5792c8119ca3 [file] [log] [blame]
Hung-ying Tyan2523f432012-10-19 20:50:50 +08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.gallery3d.exif;
18
Earl Ouff0f96c2012-10-19 16:50:34 +080019import java.nio.charset.Charset;
Hung-ying Tyan2523f432012-10-19 20:50:50 +080020import java.text.SimpleDateFormat;
21import java.util.Arrays;
22import java.util.Date;
23
24/**
Ruben Brunkc274ded2013-03-11 19:00:12 -070025 * This class stores information of an EXIF tag. For more information about
26 * defined EXIF tags, please read the Jeita EXIF 2.2 standard. Tags should be
27 * instantiated using {@link ExifInterface#buildTag}.
28 *
29 * @see ExifInterface
Hung-ying Tyan2523f432012-10-19 20:50:50 +080030 */
31public class ExifTag {
Hung-ying Tyan2523f432012-10-19 20:50:50 +080032 /**
33 * The BYTE type in the EXIF standard. An 8-bit unsigned integer.
34 */
35 public static final short TYPE_UNSIGNED_BYTE = 1;
36 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -070037 * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit
38 * ASCII code. The final byte is terminated with NULL.
Hung-ying Tyan2523f432012-10-19 20:50:50 +080039 */
40 public static final short TYPE_ASCII = 2;
41 /**
42 * The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer
43 */
44 public static final short TYPE_UNSIGNED_SHORT = 3;
45 /**
46 * The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer
47 */
48 public static final short TYPE_UNSIGNED_LONG = 4;
49 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -070050 * The RATIONAL type of EXIF standard. It consists of two LONGs. The first
51 * one is the numerator and the second one expresses the denominator.
Hung-ying Tyan2523f432012-10-19 20:50:50 +080052 */
53 public static final short TYPE_UNSIGNED_RATIONAL = 5;
54 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -070055 * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any
56 * value depending on the field definition.
Hung-ying Tyan2523f432012-10-19 20:50:50 +080057 */
58 public static final short TYPE_UNDEFINED = 7;
59 /**
60 * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer
61 * (2's complement notation).
62 */
63 public static final short TYPE_LONG = 9;
64 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -070065 * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first
66 * one is the numerator and the second one is the denominator.
Hung-ying Tyan2523f432012-10-19 20:50:50 +080067 */
68 public static final short TYPE_RATIONAL = 10;
69
Ruben Brunkc274ded2013-03-11 19:00:12 -070070 private static Charset US_ASCII = Charset.forName("US-ASCII");
Hung-ying Tyan2523f432012-10-19 20:50:50 +080071 private static final int TYPE_TO_SIZE_MAP[] = new int[11];
Ruben Brunkc274ded2013-03-11 19:00:12 -070072 private static final int UNSIGNED_SHORT_MAX = 65535;
73 private static final long UNSIGNED_LONG_MAX = 4294967295L;
74 private static final long LONG_MAX = Integer.MAX_VALUE;
75 private static final long LONG_MIN = Integer.MIN_VALUE;
76
Hung-ying Tyan2523f432012-10-19 20:50:50 +080077 static {
78 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1;
79 TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1;
80 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2;
81 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4;
82 TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8;
83 TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1;
84 TYPE_TO_SIZE_MAP[TYPE_LONG] = 4;
85 TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8;
86 }
87
Ruben Brunkc274ded2013-03-11 19:00:12 -070088 static final int SIZE_UNDEFINED = 0;
89
90 // Exif TagId
91 private final short mTagId;
92 // Exif Tag Type
93 private final short mDataType;
94 // If tag has defined count
95 private boolean mHasDefinedDefaultComponentCount;
96 // Actual data count in tag (should be number of elements in value array)
97 private int mComponentCountActual;
98 // The ifd that this tag should be put in
99 private int mIfd;
100 // The value (array of elements of type Tag Type)
101 private Object mValue;
102 // Value offset in exif header.
103 private int mOffset;
104
105 private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("yyyy:MM:dd kk:mm:ss");
106
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800107 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -0700108 * Returns true if the given IFD is a valid IFD.
109 */
110 public static boolean isValidIfd(int ifdId) {
111 return ifdId == IfdId.TYPE_IFD_0 || ifdId == IfdId.TYPE_IFD_1
112 || ifdId == IfdId.TYPE_IFD_EXIF || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY
113 || ifdId == IfdId.TYPE_IFD_GPS;
114 }
115
116 /**
117 * Returns true if a given type is a valid tag type.
118 */
119 public static boolean isValidType(short type) {
120 return type == TYPE_UNSIGNED_BYTE || type == TYPE_ASCII ||
121 type == TYPE_UNSIGNED_SHORT || type == TYPE_UNSIGNED_LONG ||
122 type == TYPE_UNSIGNED_RATIONAL || type == TYPE_UNDEFINED ||
123 type == TYPE_LONG || type == TYPE_RATIONAL;
124 }
125
126 // Use builtTag in ExifInterface instead of constructor.
127 ExifTag(short tagId, short type, int componentCount, int ifd,
128 boolean hasDefinedComponentCount) {
129 mTagId = tagId;
130 mDataType = type;
131 mComponentCountActual = componentCount;
132 mHasDefinedDefaultComponentCount = hasDefinedComponentCount;
133 mIfd = ifd;
134 mValue = null;
135 }
136
137 /**
138 * Gets the element size of the given data type in bytes.
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800139 *
140 * @see #TYPE_ASCII
141 * @see #TYPE_LONG
142 * @see #TYPE_RATIONAL
143 * @see #TYPE_UNDEFINED
144 * @see #TYPE_UNSIGNED_BYTE
145 * @see #TYPE_UNSIGNED_LONG
146 * @see #TYPE_UNSIGNED_RATIONAL
147 * @see #TYPE_UNSIGNED_SHORT
148 */
149 public static int getElementSize(short type) {
150 return TYPE_TO_SIZE_MAP[type];
151 }
152
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800153 /**
154 * Returns the ID of the IFD this tag belongs to.
155 *
156 * @see IfdId#TYPE_IFD_0
157 * @see IfdId#TYPE_IFD_1
158 * @see IfdId#TYPE_IFD_EXIF
159 * @see IfdId#TYPE_IFD_GPS
160 * @see IfdId#TYPE_IFD_INTEROPERABILITY
161 */
162 public int getIfd() {
163 return mIfd;
164 }
165
Ruben Brunkc274ded2013-03-11 19:00:12 -0700166 protected void setIfd(int ifdId) {
167 mIfd = ifdId;
168 }
169
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800170 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -0700171 * Gets the TID of this tag.
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800172 */
173 public short getTagId() {
174 return mTagId;
175 }
176
177 /**
178 * Gets the data type of this tag
179 *
180 * @see #TYPE_ASCII
181 * @see #TYPE_LONG
182 * @see #TYPE_RATIONAL
183 * @see #TYPE_UNDEFINED
184 * @see #TYPE_UNSIGNED_BYTE
185 * @see #TYPE_UNSIGNED_LONG
186 * @see #TYPE_UNSIGNED_RATIONAL
187 * @see #TYPE_UNSIGNED_SHORT
188 */
189 public short getDataType() {
190 return mDataType;
191 }
192
193 /**
194 * Gets the total data size in bytes of the value of this tag.
195 */
196 public int getDataSize() {
197 return getComponentCount() * getElementSize(getDataType());
198 }
199
200 /**
201 * Gets the component count of this tag.
202 */
Ruben Brunkc274ded2013-03-11 19:00:12 -0700203
204 // TODO: fix integer overflows with this
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800205 public int getComponentCount() {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700206 return mComponentCountActual;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800207 }
208
209 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -0700210 * Sets the component count of this tag. Call this function before
211 * setValue() if the length of value does not match the component count.
Earl Ouff0f96c2012-10-19 16:50:34 +0800212 */
Ruben Brunkc274ded2013-03-11 19:00:12 -0700213 protected void forceSetComponentCount(int count) {
214 mComponentCountActual = count;
Earl Ouff0f96c2012-10-19 16:50:34 +0800215 }
216
217 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -0700218 * Returns true if this ExifTag contains value; otherwise, this tag will
219 * contain an offset value that is determined when the tag is written.
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800220 */
221 public boolean hasValue() {
222 return mValue != null;
223 }
224
225 /**
Ruben Brunkc274ded2013-03-11 19:00:12 -0700226 * Sets integer values into this tag. This method should be used for tags of
227 * type {@link #TYPE_UNSIGNED_SHORT}. This method will fail if:
228 * <ul>
229 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
230 * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
231 * <li>The value overflows.</li>
232 * <li>The value.length does NOT match the component count in the definition
233 * for this tag.</li>
234 * </ul>
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800235 */
Ruben Brunkc274ded2013-03-11 19:00:12 -0700236 public boolean setValue(int[] value) {
237 if (checkBadComponentCount(value.length)) {
238 return false;
239 }
240 if (mDataType != TYPE_UNSIGNED_SHORT && mDataType != TYPE_LONG &&
241 mDataType != TYPE_UNSIGNED_LONG) {
242 return false;
243 }
244 if (mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) {
245 return false;
246 } else if (mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) {
247 return false;
248 }
249
250 long[] data = new long[value.length];
nicolasroard2e472532013-03-14 08:58:24 -0700251 for (int i = 0; i < value.length; i++) {
252 data[i] = value[i];
253 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700254 mValue = data;
255 mComponentCountActual = value.length;
256 return true;
257 }
258
259 /**
260 * Sets integer value into this tag. This method should be used for tags of
261 * type {@link #TYPE_UNSIGNED_SHORT}, or {@link #TYPE_LONG}. This method
262 * will fail if:
263 * <ul>
264 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT},
265 * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.</li>
266 * <li>The value overflows.</li>
267 * <li>The component count in the definition of this tag is not 1.</li>
268 * </ul>
269 */
270 public boolean setValue(int value) {
271 return setValue(new int[] {
272 value
273 });
274 }
275
276 /**
277 * Sets long values into this tag. This method should be used for tags of
278 * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
279 * <ul>
280 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
281 * <li>The value overflows.</li>
282 * <li>The value.length does NOT match the component count in the definition
283 * for this tag.</li>
284 * </ul>
285 */
286 public boolean setValue(long[] value) {
287 if (checkBadComponentCount(value.length) || mDataType != TYPE_UNSIGNED_LONG) {
288 return false;
289 }
290 if (checkOverflowForUnsignedLong(value)) {
291 return false;
292 }
293 mValue = value;
294 mComponentCountActual = value.length;
295 return true;
296 }
297
298 /**
299 * Sets long values into this tag. This method should be used for tags of
300 * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if:
301 * <ul>
302 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li>
303 * <li>The value overflows.</li>
304 * <li>The component count in the definition for this tag is not 1.</li>
305 * </ul>
306 */
307 public boolean setValue(long value) {
308 return setValue(new long[] {
309 value
310 });
311 }
312
313 /**
314 * Sets a string value into this tag. This method should be used for tags of
315 * type {@link #TYPE_ASCII}. The string is converted to an ASCII string.
316 * Characters that cannot be converted are replaced with '?'. The length of
317 * the string must be equal to either (component count -1) or (component
318 * count). The final byte will be set to the string null terminator '\0',
319 * overwriting the last character in the string if the value.length is equal
320 * to the component count. This method will fail if:
321 * <ul>
322 * <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.</li>
323 * <li>The length of the string is not equal to (component count -1) or
324 * (component count) in the definition for this tag.</li>
325 * </ul>
326 */
327 public boolean setValue(String value) {
328 if (mDataType != TYPE_ASCII && mDataType != TYPE_UNDEFINED) {
329 return false;
330 }
331
332 byte[] buf = value.getBytes(US_ASCII);
Ruben Brunk310ef8d2013-04-25 13:10:53 -0700333 byte[] finalBuf = buf;
334 if (buf.length > 0) {
335 finalBuf = (buf[buf.length - 1] == 0 || mDataType == TYPE_UNDEFINED) ? buf : Arrays
Ruben Brunkc274ded2013-03-11 19:00:12 -0700336 .copyOf(buf, buf.length + 1);
Ruben Brunk310ef8d2013-04-25 13:10:53 -0700337 } else if (mDataType == TYPE_ASCII && mComponentCountActual == 1) {
338 finalBuf = new byte[] { 0 };
339 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700340 int count = finalBuf.length;
341 if (checkBadComponentCount(count)) {
342 return false;
343 }
344 mComponentCountActual = count;
345 mValue = finalBuf;
346 return true;
347 }
348
349 /**
350 * Sets Rational values into this tag. This method should be used for tags
351 * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
352 * method will fail if:
353 * <ul>
354 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
355 * or {@link #TYPE_RATIONAL}.</li>
356 * <li>The value overflows.</li>
357 * <li>The value.length does NOT match the component count in the definition
358 * for this tag.</li>
359 * </ul>
360 *
361 * @see Rational
362 */
363 public boolean setValue(Rational[] value) {
364 if (checkBadComponentCount(value.length)) {
365 return false;
366 }
367 if (mDataType != TYPE_UNSIGNED_RATIONAL && mDataType != TYPE_RATIONAL) {
368 return false;
369 }
370 if (mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) {
371 return false;
372 } else if (mDataType == TYPE_RATIONAL && checkOverflowForRational(value)) {
373 return false;
374 }
375
376 mValue = value;
377 mComponentCountActual = value.length;
378 return true;
379 }
380
381 /**
382 * Sets a Rational value into this tag. This method should be used for tags
383 * of type {@link #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This
384 * method will fail if:
385 * <ul>
386 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL}
387 * or {@link #TYPE_RATIONAL}.</li>
388 * <li>The value overflows.</li>
389 * <li>The component count in the definition for this tag is not 1.</li>
390 * </ul>
391 *
392 * @see Rational
393 */
394 public boolean setValue(Rational value) {
395 return setValue(new Rational[] {
396 value
397 });
398 }
399
400 /**
401 * Sets byte values into this tag. This method should be used for tags of
402 * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
403 * will fail if:
404 * <ul>
405 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
406 * {@link #TYPE_UNDEFINED} .</li>
407 * <li>The length does NOT match the component count in the definition for
408 * this tag.</li>
409 * </ul>
410 */
411 public boolean setValue(byte[] value, int offset, int length) {
412 if (checkBadComponentCount(length)) {
413 return false;
414 }
415 if (mDataType != TYPE_UNSIGNED_BYTE && mDataType != TYPE_UNDEFINED) {
416 return false;
417 }
418 mValue = new byte[length];
419 System.arraycopy(value, offset, mValue, 0, length);
420 mComponentCountActual = length;
421 return true;
422 }
423
424 /**
425 * Equivalent to setValue(value, 0, value.length).
426 */
427 public boolean setValue(byte[] value) {
428 return setValue(value, 0, value.length);
429 }
430
431 /**
432 * Sets byte value into this tag. This method should be used for tags of
433 * type {@link #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method
434 * will fail if:
435 * <ul>
436 * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or
437 * {@link #TYPE_UNDEFINED} .</li>
438 * <li>The component count in the definition for this tag is not 1.</li>
439 * </ul>
440 */
441 public boolean setValue(byte value) {
442 return setValue(new byte[] {
443 value
444 });
445 }
446
447 /**
448 * Sets the value for this tag using an appropriate setValue method for the
449 * given object. This method will fail if:
450 * <ul>
451 * <li>The corresponding setValue method for the class of the object passed
452 * in would fail.</li>
453 * <li>There is no obvious way to cast the object passed in into an EXIF tag
454 * type.</li>
455 * </ul>
456 */
457 public boolean setValue(Object obj) {
458 if (obj == null) {
459 return false;
460 } else if (obj instanceof Short) {
461 return setValue(((Short) obj).shortValue() & 0x0ffff);
462 } else if (obj instanceof String) {
463 return setValue((String) obj);
464 } else if (obj instanceof int[]) {
465 return setValue((int[]) obj);
466 } else if (obj instanceof long[]) {
467 return setValue((long[]) obj);
468 } else if (obj instanceof Rational) {
469 return setValue((Rational) obj);
470 } else if (obj instanceof Rational[]) {
471 return setValue((Rational[]) obj);
472 } else if (obj instanceof byte[]) {
473 return setValue((byte[]) obj);
474 } else if (obj instanceof Integer) {
475 return setValue(((Integer) obj).intValue());
476 } else if (obj instanceof Long) {
477 return setValue(((Long) obj).longValue());
478 } else if (obj instanceof Byte) {
479 return setValue(((Byte) obj).byteValue());
480 } else if (obj instanceof Short[]) {
481 // Nulls in this array are treated as zeroes.
482 Short[] arr = (Short[]) obj;
483 int[] fin = new int[arr.length];
484 for (int i = 0; i < arr.length; i++) {
485 fin[i] = (arr[i] == null) ? 0 : arr[i].shortValue() & 0x0ffff;
486 }
487 return setValue(fin);
488 } else if (obj instanceof Integer[]) {
489 // Nulls in this array are treated as zeroes.
490 Integer[] arr = (Integer[]) obj;
491 int[] fin = new int[arr.length];
492 for (int i = 0; i < arr.length; i++) {
493 fin[i] = (arr[i] == null) ? 0 : arr[i].intValue();
494 }
495 return setValue(fin);
496 } else if (obj instanceof Long[]) {
497 // Nulls in this array are treated as zeroes.
498 Long[] arr = (Long[]) obj;
499 long[] fin = new long[arr.length];
500 for (int i = 0; i < arr.length; i++) {
501 fin[i] = (arr[i] == null) ? 0 : arr[i].longValue();
502 }
503 return setValue(fin);
504 } else if (obj instanceof Byte[]) {
505 // Nulls in this array are treated as zeroes.
506 Byte[] arr = (Byte[]) obj;
507 byte[] fin = new byte[arr.length];
508 for (int i = 0; i < arr.length; i++) {
509 fin[i] = (arr[i] == null) ? 0 : arr[i].byteValue();
510 }
511 return setValue(fin);
512 } else {
513 return false;
514 }
515 }
516
517 /**
518 * Sets a timestamp to this tag. The method converts the timestamp with the
519 * format of "yyyy:MM:dd kk:mm:ss" and calls {@link #setValue(String)}. This
520 * method will fail if the data type is not {@link #TYPE_ASCII} or the
521 * component count of this tag is not 20 or undefined.
522 *
523 * @param time the number of milliseconds since Jan. 1, 1970 GMT
524 * @return true on success
525 */
526 public boolean setTimeValue(long time) {
527 // synchronized on TIME_FORMAT as SimpleDateFormat is not thread safe
528 synchronized (TIME_FORMAT) {
529 return setValue(TIME_FORMAT.format(new Date(time)));
530 }
531 }
532
533 /**
534 * Gets the value as a String. This method should be used for tags of type
535 * {@link #TYPE_ASCII}.
536 *
537 * @return the value as a String, or null if the tag's value does not exist
538 * or cannot be converted to a String.
539 */
540 public String getValueAsString() {
541 if (mValue == null) {
542 return null;
543 } else if (mValue instanceof String) {
544 return (String) mValue;
545 } else if (mValue instanceof byte[]) {
546 return new String((byte[]) mValue, US_ASCII);
547 }
548 return null;
549 }
550
551 /**
552 * Gets the value as a String. This method should be used for tags of type
553 * {@link #TYPE_ASCII}.
554 *
555 * @param defaultValue the String to return if the tag's value does not
556 * exist or cannot be converted to a String.
557 * @return the tag's value as a String, or the defaultValue.
558 */
559 public String getValueAsString(String defaultValue) {
560 String s = getValueAsString();
561 if (s == null) {
562 return defaultValue;
563 }
564 return s;
565 }
566
567 /**
568 * Gets the value as a byte array. This method should be used for tags of
569 * type {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
570 *
571 * @return the value as a byte array, or null if the tag's value does not
572 * exist or cannot be converted to a byte array.
573 */
574 public byte[] getValueAsBytes() {
575 if (mValue instanceof byte[]) {
576 return (byte[]) mValue;
577 }
578 return null;
579 }
580
581 /**
582 * Gets the value as a byte. If there are more than 1 bytes in this value,
583 * gets the first byte. This method should be used for tags of type
584 * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
585 *
586 * @param defaultValue the byte to return if tag's value does not exist or
587 * cannot be converted to a byte.
588 * @return the tag's value as a byte, or the defaultValue.
589 */
590 public byte getValueAsByte(byte defaultValue) {
591 byte[] b = getValueAsBytes();
592 if (b == null || b.length < 1) {
593 return defaultValue;
594 }
595 return b[0];
596 }
597
598 /**
599 * Gets the value as an array of Rationals. This method should be used for
600 * tags of type {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
601 *
602 * @return the value as as an array of Rationals, or null if the tag's value
603 * does not exist or cannot be converted to an array of Rationals.
604 */
605 public Rational[] getValueAsRationals() {
606 if (mValue instanceof Rational[]) {
607 return (Rational[]) mValue;
608 }
609 return null;
610 }
611
612 /**
613 * Gets the value as a Rational. If there are more than 1 Rationals in this
614 * value, gets the first one. This method should be used for tags of type
615 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
616 *
617 * @param defaultValue the Rational to return if tag's value does not exist
618 * or cannot be converted to a Rational.
619 * @return the tag's value as a Rational, or the defaultValue.
620 */
621 public Rational getValueAsRational(Rational defaultValue) {
622 Rational[] r = getValueAsRationals();
623 if (r == null || r.length < 1) {
624 return defaultValue;
625 }
626 return r[0];
627 }
628
629 /**
630 * Gets the value as a Rational. If there are more than 1 Rationals in this
631 * value, gets the first one. This method should be used for tags of type
632 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
633 *
634 * @param defaultValue the numerator of the Rational to return if tag's
635 * value does not exist or cannot be converted to a Rational (the
636 * denominator will be 1).
637 * @return the tag's value as a Rational, or the defaultValue.
638 */
639 public Rational getValueAsRational(long defaultValue) {
640 Rational defaultVal = new Rational(defaultValue, 1);
641 return getValueAsRational(defaultVal);
642 }
643
644 /**
645 * Gets the value as an array of ints. This method should be used for tags
646 * of type {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
647 *
648 * @return the value as as an array of ints, or null if the tag's value does
649 * not exist or cannot be converted to an array of ints.
650 */
651 public int[] getValueAsInts() {
652 if (mValue == null) {
653 return null;
654 } else if (mValue instanceof long[]) {
655 long[] val = (long[]) mValue;
656 int[] arr = new int[val.length];
657 for (int i = 0; i < val.length; i++) {
658 arr[i] = (int) val[i]; // Truncates
659 }
660 return arr;
661 }
662 return null;
663 }
664
665 /**
666 * Gets the value as an int. If there are more than 1 ints in this value,
667 * gets the first one. This method should be used for tags of type
668 * {@link #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
669 *
670 * @param defaultValue the int to return if tag's value does not exist or
671 * cannot be converted to an int.
672 * @return the tag's value as a int, or the defaultValue.
673 */
674 public int getValueAsInt(int defaultValue) {
675 int[] i = getValueAsInts();
676 if (i == null || i.length < 1) {
677 return defaultValue;
678 }
679 return i[0];
680 }
681
682 /**
683 * Gets the value as an array of longs. This method should be used for tags
684 * of type {@link #TYPE_UNSIGNED_LONG}.
685 *
686 * @return the value as as an array of longs, or null if the tag's value
687 * does not exist or cannot be converted to an array of longs.
688 */
689 public long[] getValueAsLongs() {
690 if (mValue instanceof long[]) {
691 return (long[]) mValue;
692 }
693 return null;
694 }
695
696 /**
697 * Gets the value or null if none exists. If there are more than 1 longs in
698 * this value, gets the first one. This method should be used for tags of
699 * type {@link #TYPE_UNSIGNED_LONG}.
700 *
701 * @param defaultValue the long to return if tag's value does not exist or
702 * cannot be converted to a long.
703 * @return the tag's value as a long, or the defaultValue.
704 */
705 public long getValueAsLong(long defaultValue) {
706 long[] l = getValueAsLongs();
707 if (l == null || l.length < 1) {
708 return defaultValue;
709 }
710 return l[0];
711 }
712
713 /**
714 * Gets the tag's value or null if none exists.
715 */
716 public Object getValue() {
717 return mValue;
718 }
719
720 /**
721 * Gets a long representation of the value.
722 *
723 * @param defaultValue value to return if there is no value or value is a
724 * rational with a denominator of 0.
725 * @return the tag's value as a long, or defaultValue if no representation
726 * exists.
727 */
728 public long forceGetValueAsLong(long defaultValue) {
729 long[] l = getValueAsLongs();
730 if (l != null && l.length >= 1) {
731 return l[0];
732 }
733 byte[] b = getValueAsBytes();
734 if (b != null && b.length >= 1) {
735 return b[0];
736 }
737 Rational[] r = getValueAsRationals();
738 if (r != null && r.length >= 1 && r[0].getDenominator() != 0) {
739 return (long) r[0].toDouble();
740 }
741 return defaultValue;
742 }
743
744 /**
745 * Gets a string representation of the value.
746 */
747 public String forceGetValueAsString() {
748 if (mValue == null) {
749 return "";
750 } else if (mValue instanceof byte[]) {
751 if (mDataType == TYPE_ASCII) {
752 return new String((byte[]) mValue, US_ASCII);
753 } else {
754 return Arrays.toString((byte[]) mValue);
755 }
756 } else if (mValue instanceof long[]) {
757 if (((long[]) mValue).length == 1) {
758 return String.valueOf(((long[]) mValue)[0]);
759 } else {
760 return Arrays.toString((long[]) mValue);
761 }
762 } else if (mValue instanceof Object[]) {
763 if (((Object[]) mValue).length == 1) {
764 Object val = ((Object[]) mValue)[0];
765 if (val == null) {
766 return "";
767 } else {
768 return val.toString();
769 }
770 } else {
771 return Arrays.toString((Object[]) mValue);
772 }
773 } else {
774 return mValue.toString();
775 }
776 }
777
778 /**
779 * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG},
780 * {@link #TYPE_UNDEFINED}, {@link #TYPE_UNSIGNED_BYTE},
781 * {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}. For
782 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}, call
783 * {@link #getRational(int)} instead.
784 *
785 * @exception IllegalArgumentException if the data type is
786 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
787 */
788 protected long getValueAt(int index) {
789 if (mValue instanceof long[]) {
790 return ((long[]) mValue)[index];
791 } else if (mValue instanceof byte[]) {
792 return ((byte[]) mValue)[index];
793 }
794 throw new IllegalArgumentException("Cannot get integer value from "
795 + convertTypeToString(mDataType));
796 }
797
798 /**
799 * Gets the {@link #TYPE_ASCII} data.
800 *
801 * @exception IllegalArgumentException If the type is NOT
802 * {@link #TYPE_ASCII}.
803 */
804 protected String getString() {
805 if (mDataType != TYPE_ASCII) {
806 throw new IllegalArgumentException("Cannot get ASCII value from "
807 + convertTypeToString(mDataType));
808 }
809 return new String((byte[]) mValue, US_ASCII);
810 }
811
812 /*
813 * Get the converted ascii byte. Used by ExifOutputStream.
814 */
815 protected byte[] getStringByte() {
816 return (byte[]) mValue;
817 }
818
819 /**
820 * Gets the {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL} data.
821 *
822 * @exception IllegalArgumentException If the type is NOT
823 * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}.
824 */
825 protected Rational getRational(int index) {
826 if ((mDataType != TYPE_RATIONAL) && (mDataType != TYPE_UNSIGNED_RATIONAL)) {
827 throw new IllegalArgumentException("Cannot get RATIONAL value from "
828 + convertTypeToString(mDataType));
829 }
830 return ((Rational[]) mValue)[index];
831 }
832
833 /**
834 * Equivalent to getBytes(buffer, 0, buffer.length).
835 */
836 protected void getBytes(byte[] buf) {
837 getBytes(buf, 0, buf.length);
838 }
839
840 /**
841 * Gets the {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE} data.
842 *
843 * @param buf the byte array in which to store the bytes read.
844 * @param offset the initial position in buffer to store the bytes.
845 * @param length the maximum number of bytes to store in buffer. If length >
846 * component count, only the valid bytes will be stored.
847 * @exception IllegalArgumentException If the type is NOT
848 * {@link #TYPE_UNDEFINED} or {@link #TYPE_UNSIGNED_BYTE}.
849 */
850 protected void getBytes(byte[] buf, int offset, int length) {
851 if ((mDataType != TYPE_UNDEFINED) && (mDataType != TYPE_UNSIGNED_BYTE)) {
852 throw new IllegalArgumentException("Cannot get BYTE value from "
853 + convertTypeToString(mDataType));
854 }
855 System.arraycopy(mValue, 0, buf, offset,
856 (length > mComponentCountActual) ? mComponentCountActual : length);
857 }
858
859 /**
860 * Gets the offset of this tag. This is only valid if this data size > 4 and
861 * contains an offset to the location of the actual value.
862 */
863 protected int getOffset() {
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800864 return mOffset;
865 }
866
867 /**
868 * Sets the offset of this tag.
869 */
Ruben Brunkc274ded2013-03-11 19:00:12 -0700870 protected void setOffset(int offset) {
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800871 mOffset = offset;
872 }
873
Ruben Brunkc274ded2013-03-11 19:00:12 -0700874 protected void setHasDefinedCount(boolean d) {
875 mHasDefinedDefaultComponentCount = d;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800876 }
877
Ruben Brunk310ef8d2013-04-25 13:10:53 -0700878 protected boolean hasDefinedCount() {
879 return mHasDefinedDefaultComponentCount;
880 }
881
Ruben Brunkc274ded2013-03-11 19:00:12 -0700882 private boolean checkBadComponentCount(int count) {
883 if (mHasDefinedDefaultComponentCount && (mComponentCountActual != count)) {
884 return true;
885 }
886 return false;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800887 }
888
889 private static String convertTypeToString(short type) {
890 switch (type) {
891 case TYPE_UNSIGNED_BYTE:
892 return "UNSIGNED_BYTE";
893 case TYPE_ASCII:
894 return "ASCII";
895 case TYPE_UNSIGNED_SHORT:
896 return "UNSIGNED_SHORT";
897 case TYPE_UNSIGNED_LONG:
898 return "UNSIGNED_LONG";
899 case TYPE_UNSIGNED_RATIONAL:
900 return "UNSIGNED_RATIONAL";
901 case TYPE_UNDEFINED:
902 return "UNDEFINED";
903 case TYPE_LONG:
904 return "LONG";
905 case TYPE_RATIONAL:
906 return "RATIONAL";
907 default:
908 return "";
909 }
910 }
911
Ruben Brunkc274ded2013-03-11 19:00:12 -0700912 private boolean checkOverflowForUnsignedShort(int[] value) {
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800913 for (int v : value) {
914 if (v > UNSIGNED_SHORT_MAX || v < 0) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700915 return true;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800916 }
917 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700918 return false;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800919 }
920
Ruben Brunkc274ded2013-03-11 19:00:12 -0700921 private boolean checkOverflowForUnsignedLong(long[] value) {
922 for (long v : value) {
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800923 if (v < 0 || v > UNSIGNED_LONG_MAX) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700924 return true;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800925 }
926 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700927 return false;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800928 }
929
Ruben Brunkc274ded2013-03-11 19:00:12 -0700930 private boolean checkOverflowForUnsignedLong(int[] value) {
931 for (int v : value) {
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800932 if (v < 0) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700933 return true;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800934 }
935 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700936 return false;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800937 }
938
Ruben Brunkc274ded2013-03-11 19:00:12 -0700939 private boolean checkOverflowForUnsignedRational(Rational[] value) {
940 for (Rational v : value) {
941 if (v.getNumerator() < 0 || v.getDenominator() < 0
942 || v.getNumerator() > UNSIGNED_LONG_MAX
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800943 || v.getDenominator() > UNSIGNED_LONG_MAX) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700944 return true;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800945 }
946 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700947 return false;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800948 }
949
Ruben Brunkc274ded2013-03-11 19:00:12 -0700950 private boolean checkOverflowForRational(Rational[] value) {
951 for (Rational v : value) {
952 if (v.getNumerator() < LONG_MIN || v.getDenominator() < LONG_MIN
953 || v.getNumerator() > LONG_MAX
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800954 || v.getDenominator() > LONG_MAX) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700955 return true;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800956 }
957 }
Ruben Brunkc274ded2013-03-11 19:00:12 -0700958 return false;
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800959 }
960
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800961 @Override
962 public boolean equals(Object obj) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700963 if (obj == null) {
964 return false;
965 }
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800966 if (obj instanceof ExifTag) {
967 ExifTag tag = (ExifTag) obj;
Ruben Brunkc274ded2013-03-11 19:00:12 -0700968 if (tag.mTagId != this.mTagId
969 || tag.mComponentCountActual != this.mComponentCountActual
970 || tag.mDataType != this.mDataType) {
971 return false;
972 }
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800973 if (mValue != null) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700974 if (tag.mValue == null) {
975 return false;
976 } else if (mValue instanceof long[]) {
977 if (!(tag.mValue instanceof long[])) {
978 return false;
979 }
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800980 return Arrays.equals((long[]) mValue, (long[]) tag.mValue);
981 } else if (mValue instanceof Rational[]) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700982 if (!(tag.mValue instanceof Rational[])) {
983 return false;
984 }
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800985 return Arrays.equals((Rational[]) mValue, (Rational[]) tag.mValue);
986 } else if (mValue instanceof byte[]) {
Ruben Brunkc274ded2013-03-11 19:00:12 -0700987 if (!(tag.mValue instanceof byte[])) {
988 return false;
989 }
Hung-ying Tyan2523f432012-10-19 20:50:50 +0800990 return Arrays.equals((byte[]) mValue, (byte[]) tag.mValue);
991 } else {
992 return mValue.equals(tag.mValue);
993 }
994 } else {
995 return tag.mValue == null;
996 }
997 }
998 return false;
999 }
Ruben Brunkc274ded2013-03-11 19:00:12 -07001000
1001 @Override
1002 public String toString() {
1003 return String.format("tag id: %04X\n", mTagId) + "ifd id: " + mIfd + "\ntype: "
1004 + convertTypeToString(mDataType) + "\ncount: " + mComponentCountActual
1005 + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n";
1006 }
1007
Hung-ying Tyan2523f432012-10-19 20:50:50 +08001008}