Home | History | Annotate | Download | only in exif
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dialer.callcomposer.camera.exif;
     18 
     19 import java.nio.charset.Charset;
     20 import java.util.Arrays;
     21 import java.util.Objects;
     22 
     23 /**
     24  * This class stores information of an EXIF tag. For more information about defined EXIF tags,
     25  * please read the Jeita EXIF 2.2 standard. Tags should be instantiated using {@link
     26  * ExifInterface#buildTag}.
     27  *
     28  * @see ExifInterface
     29  */
     30 public class ExifTag {
     31   /** The BYTE type in the EXIF standard. An 8-bit unsigned integer. */
     32   static final short TYPE_UNSIGNED_BYTE = 1;
     33   /**
     34    * The ASCII type in the EXIF standard. An 8-bit byte containing one 7-bit ASCII code. The final
     35    * byte is terminated with NULL.
     36    */
     37   static final short TYPE_ASCII = 2;
     38   /** The SHORT type in the EXIF standard. A 16-bit (2-byte) unsigned integer */
     39   static final short TYPE_UNSIGNED_SHORT = 3;
     40   /** The LONG type in the EXIF standard. A 32-bit (4-byte) unsigned integer */
     41   static final short TYPE_UNSIGNED_LONG = 4;
     42   /**
     43    * The RATIONAL type of EXIF standard. It consists of two LONGs. The first one is the numerator
     44    * and the second one expresses the denominator.
     45    */
     46   static final short TYPE_UNSIGNED_RATIONAL = 5;
     47   /**
     48    * The UNDEFINED type in the EXIF standard. An 8-bit byte that can take any value depending on the
     49    * field definition.
     50    */
     51   static final short TYPE_UNDEFINED = 7;
     52   /**
     53    * The SLONG type in the EXIF standard. A 32-bit (4-byte) signed integer (2's complement
     54    * notation).
     55    */
     56   static final short TYPE_LONG = 9;
     57   /**
     58    * The SRATIONAL type of EXIF standard. It consists of two SLONGs. The first one is the numerator
     59    * and the second one is the denominator.
     60    */
     61   static final short TYPE_RATIONAL = 10;
     62 
     63   private static final Charset US_ASCII = Charset.forName("US-ASCII");
     64   private static final int[] TYPE_TO_SIZE_MAP = new int[11];
     65   private static final int UNSIGNED_SHORT_MAX = 65535;
     66   private static final long UNSIGNED_LONG_MAX = 4294967295L;
     67   private static final long LONG_MAX = Integer.MAX_VALUE;
     68   private static final long LONG_MIN = Integer.MIN_VALUE;
     69 
     70   static {
     71     TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_BYTE] = 1;
     72     TYPE_TO_SIZE_MAP[TYPE_ASCII] = 1;
     73     TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_SHORT] = 2;
     74     TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_LONG] = 4;
     75     TYPE_TO_SIZE_MAP[TYPE_UNSIGNED_RATIONAL] = 8;
     76     TYPE_TO_SIZE_MAP[TYPE_UNDEFINED] = 1;
     77     TYPE_TO_SIZE_MAP[TYPE_LONG] = 4;
     78     TYPE_TO_SIZE_MAP[TYPE_RATIONAL] = 8;
     79   }
     80 
     81   static final int SIZE_UNDEFINED = 0;
     82 
     83   // Exif TagId
     84   private final short tagId;
     85   // Exif Tag Type
     86   private final short dataType;
     87   // If tag has defined count
     88   private boolean hasDefinedDefaultComponentCount;
     89   // Actual data count in tag (should be number of elements in value array)
     90   private int componentCountActual;
     91   // The ifd that this tag should be put in
     92   private int ifd;
     93   // The value (array of elements of type Tag Type)
     94   private Object value;
     95   // Value offset in exif header.
     96   private int offset;
     97 
     98   /** Returns true if the given IFD is a valid IFD. */
     99   static boolean isValidIfd(int ifdId) {
    100     return ifdId == IfdId.TYPE_IFD_0
    101         || ifdId == IfdId.TYPE_IFD_1
    102         || ifdId == IfdId.TYPE_IFD_EXIF
    103         || ifdId == IfdId.TYPE_IFD_INTEROPERABILITY
    104         || ifdId == IfdId.TYPE_IFD_GPS;
    105   }
    106 
    107   /** Returns true if a given type is a valid tag type. */
    108   static boolean isValidType(short type) {
    109     return type == TYPE_UNSIGNED_BYTE
    110         || type == TYPE_ASCII
    111         || type == TYPE_UNSIGNED_SHORT
    112         || type == TYPE_UNSIGNED_LONG
    113         || type == TYPE_UNSIGNED_RATIONAL
    114         || type == TYPE_UNDEFINED
    115         || type == TYPE_LONG
    116         || type == TYPE_RATIONAL;
    117   }
    118 
    119   // Use builtTag in ExifInterface instead of constructor.
    120   ExifTag(short tagId, short type, int componentCount, int ifd, boolean hasDefinedComponentCount) {
    121     this.tagId = tagId;
    122     dataType = type;
    123     componentCountActual = componentCount;
    124     hasDefinedDefaultComponentCount = hasDefinedComponentCount;
    125     this.ifd = ifd;
    126     value = null;
    127   }
    128 
    129   /**
    130    * Gets the element size of the given data type in bytes.
    131    *
    132    * @see #TYPE_ASCII
    133    * @see #TYPE_LONG
    134    * @see #TYPE_RATIONAL
    135    * @see #TYPE_UNDEFINED
    136    * @see #TYPE_UNSIGNED_BYTE
    137    * @see #TYPE_UNSIGNED_LONG
    138    * @see #TYPE_UNSIGNED_RATIONAL
    139    * @see #TYPE_UNSIGNED_SHORT
    140    */
    141   private static int getElementSize(short type) {
    142     return TYPE_TO_SIZE_MAP[type];
    143   }
    144 
    145   /**
    146    * Returns the ID of the IFD this tag belongs to.
    147    *
    148    * @see IfdId#TYPE_IFD_0
    149    * @see IfdId#TYPE_IFD_1
    150    * @see IfdId#TYPE_IFD_EXIF
    151    * @see IfdId#TYPE_IFD_GPS
    152    * @see IfdId#TYPE_IFD_INTEROPERABILITY
    153    */
    154   int getIfd() {
    155     return ifd;
    156   }
    157 
    158   void setIfd(int ifdId) {
    159     ifd = ifdId;
    160   }
    161 
    162   /** Gets the TID of this tag. */
    163   short getTagId() {
    164     return tagId;
    165   }
    166 
    167   /**
    168    * Gets the data type of this tag
    169    *
    170    * @see #TYPE_ASCII
    171    * @see #TYPE_LONG
    172    * @see #TYPE_RATIONAL
    173    * @see #TYPE_UNDEFINED
    174    * @see #TYPE_UNSIGNED_BYTE
    175    * @see #TYPE_UNSIGNED_LONG
    176    * @see #TYPE_UNSIGNED_RATIONAL
    177    * @see #TYPE_UNSIGNED_SHORT
    178    */
    179   short getDataType() {
    180     return dataType;
    181   }
    182 
    183   /** Gets the total data size in bytes of the value of this tag. */
    184   int getDataSize() {
    185     return getComponentCount() * getElementSize(getDataType());
    186   }
    187 
    188   /** Gets the component count of this tag. */
    189 
    190   // TODO(blemmon): fix integer overflows with this
    191   int getComponentCount() {
    192     return componentCountActual;
    193   }
    194 
    195   /**
    196    * Sets the component count of this tag. Call this function before setValue() if the length of
    197    * value does not match the component count.
    198    */
    199   void forceSetComponentCount(int count) {
    200     componentCountActual = count;
    201   }
    202 
    203   /**
    204    * Returns true if this ExifTag contains value; otherwise, this tag will contain an offset value
    205    * that is determined when the tag is written.
    206    */
    207   boolean hasValue() {
    208     return value != null;
    209   }
    210 
    211   /**
    212    * Sets integer values into this tag. This method should be used for tags of type {@link
    213    * #TYPE_UNSIGNED_SHORT}. This method will fail if:
    214    *
    215    * <ul>
    216    *   <li>The component type of this tag is not {@link #TYPE_UNSIGNED_SHORT}, {@link
    217    *       #TYPE_UNSIGNED_LONG}, or {@link #TYPE_LONG}.
    218    *   <li>The value overflows.
    219    *   <li>The value.length does NOT match the component count in the definition for this tag.
    220    * </ul>
    221    */
    222   boolean setValue(int[] value) {
    223     if (checkBadComponentCount(value.length)) {
    224       return false;
    225     }
    226     if (dataType != TYPE_UNSIGNED_SHORT
    227         && dataType != TYPE_LONG
    228         && dataType != TYPE_UNSIGNED_LONG) {
    229       return false;
    230     }
    231     if (dataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort(value)) {
    232       return false;
    233     } else if (dataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong(value)) {
    234       return false;
    235     }
    236 
    237     long[] data = new long[value.length];
    238     for (int i = 0; i < value.length; i++) {
    239       data[i] = value[i];
    240     }
    241     this.value = data;
    242     componentCountActual = value.length;
    243     return true;
    244   }
    245 
    246   /**
    247    * Sets long values into this tag. This method should be used for tags of type {@link
    248    * #TYPE_UNSIGNED_LONG}. This method will fail if:
    249    *
    250    * <ul>
    251    *   <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.
    252    *   <li>The value overflows.
    253    *   <li>The value.length does NOT match the component count in the definition for this tag.
    254    * </ul>
    255    */
    256   boolean setValue(long[] value) {
    257     if (checkBadComponentCount(value.length) || dataType != TYPE_UNSIGNED_LONG) {
    258       return false;
    259     }
    260     if (checkOverflowForUnsignedLong(value)) {
    261       return false;
    262     }
    263     this.value = value;
    264     componentCountActual = value.length;
    265     return true;
    266   }
    267 
    268   /**
    269    * Sets a string value into this tag. This method should be used for tags of type {@link
    270    * #TYPE_ASCII}. The string is converted to an ASCII string. Characters that cannot be converted
    271    * are replaced with '?'. The length of the string must be equal to either (component count -1) or
    272    * (component count). The final byte will be set to the string null terminator '\0', overwriting
    273    * the last character in the string if the value.length is equal to the component count. This
    274    * method will fail if:
    275    *
    276    * <ul>
    277    *   <li>The data type is not {@link #TYPE_ASCII} or {@link #TYPE_UNDEFINED}.
    278    *   <li>The length of the string is not equal to (component count -1) or (component count) in the
    279    *       definition for this tag.
    280    * </ul>
    281    */
    282   boolean setValue(String value) {
    283     if (dataType != TYPE_ASCII && dataType != TYPE_UNDEFINED) {
    284       return false;
    285     }
    286 
    287     byte[] buf = value.getBytes(US_ASCII);
    288     byte[] finalBuf = buf;
    289     if (buf.length > 0) {
    290       finalBuf =
    291           (buf[buf.length - 1] == 0 || dataType == TYPE_UNDEFINED)
    292               ? buf
    293               : Arrays.copyOf(buf, buf.length + 1);
    294     } else if (dataType == TYPE_ASCII && componentCountActual == 1) {
    295       finalBuf = new byte[] {0};
    296     }
    297     int count = finalBuf.length;
    298     if (checkBadComponentCount(count)) {
    299       return false;
    300     }
    301     componentCountActual = count;
    302     this.value = finalBuf;
    303     return true;
    304   }
    305 
    306   /**
    307    * Sets Rational values into this tag. This method should be used for tags of type {@link
    308    * #TYPE_UNSIGNED_RATIONAL}, or {@link #TYPE_RATIONAL}. This method will fail if:
    309    *
    310    * <ul>
    311    *   <li>The component type of this tag is not {@link #TYPE_UNSIGNED_RATIONAL} or {@link
    312    *       #TYPE_RATIONAL}.
    313    *   <li>The value overflows.
    314    *   <li>The value.length does NOT match the component count in the definition for this tag.
    315    * </ul>
    316    *
    317    * @see Rational
    318    */
    319   boolean setValue(Rational[] value) {
    320     if (checkBadComponentCount(value.length)) {
    321       return false;
    322     }
    323     if (dataType != TYPE_UNSIGNED_RATIONAL && dataType != TYPE_RATIONAL) {
    324       return false;
    325     }
    326     if (dataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational(value)) {
    327       return false;
    328     } else if (dataType == TYPE_RATIONAL && checkOverflowForRational(value)) {
    329       return false;
    330     }
    331 
    332     this.value = value;
    333     componentCountActual = value.length;
    334     return true;
    335   }
    336 
    337   /**
    338    * Sets byte values into this tag. This method should be used for tags of type {@link
    339    * #TYPE_UNSIGNED_BYTE} or {@link #TYPE_UNDEFINED}. This method will fail if:
    340    *
    341    * <ul>
    342    *   <li>The component type of this tag is not {@link #TYPE_UNSIGNED_BYTE} or {@link
    343    *       #TYPE_UNDEFINED} .
    344    *   <li>The length does NOT match the component count in the definition for this tag.
    345    * </ul>
    346    */
    347   private boolean setValue(byte[] value, int offset, int length) {
    348     if (checkBadComponentCount(length)) {
    349       return false;
    350     }
    351     if (dataType != TYPE_UNSIGNED_BYTE && dataType != TYPE_UNDEFINED) {
    352       return false;
    353     }
    354     this.value = new byte[length];
    355     System.arraycopy(value, offset, this.value, 0, length);
    356     componentCountActual = length;
    357     return true;
    358   }
    359 
    360   /** Equivalent to setValue(value, 0, value.length). */
    361   boolean setValue(byte[] value) {
    362     return setValue(value, 0, value.length);
    363   }
    364 
    365   /**
    366    * Gets the value as an array of ints. This method should be used for tags of type {@link
    367    * #TYPE_UNSIGNED_SHORT}, {@link #TYPE_UNSIGNED_LONG}.
    368    *
    369    * @return the value as as an array of ints, or null if the tag's value does not exist or cannot
    370    *     be converted to an array of ints.
    371    */
    372   int[] getValueAsInts() {
    373     if (value == null) {
    374       return null;
    375     } else if (value instanceof long[]) {
    376       long[] val = (long[]) value;
    377       int[] arr = new int[val.length];
    378       for (int i = 0; i < val.length; i++) {
    379         arr[i] = (int) val[i]; // Truncates
    380       }
    381       return arr;
    382     }
    383     return null;
    384   }
    385 
    386   /** Gets the tag's value or null if none exists. */
    387   public Object getValue() {
    388     return value;
    389   }
    390 
    391   /** Gets a string representation of the value. */
    392   private String forceGetValueAsString() {
    393     if (value == null) {
    394       return "";
    395     } else if (value instanceof byte[]) {
    396       if (dataType == TYPE_ASCII) {
    397         return new String((byte[]) value, US_ASCII);
    398       } else {
    399         return Arrays.toString((byte[]) value);
    400       }
    401     } else if (value instanceof long[]) {
    402       if (((long[]) value).length == 1) {
    403         return String.valueOf(((long[]) value)[0]);
    404       } else {
    405         return Arrays.toString((long[]) value);
    406       }
    407     } else if (value instanceof Object[]) {
    408       if (((Object[]) value).length == 1) {
    409         Object val = ((Object[]) value)[0];
    410         if (val == null) {
    411           return "";
    412         } else {
    413           return val.toString();
    414         }
    415       } else {
    416         return Arrays.toString((Object[]) value);
    417       }
    418     } else {
    419       return value.toString();
    420     }
    421   }
    422 
    423   /**
    424    * Gets the value for type {@link #TYPE_ASCII}, {@link #TYPE_LONG}, {@link #TYPE_UNDEFINED},
    425    * {@link #TYPE_UNSIGNED_BYTE}, {@link #TYPE_UNSIGNED_LONG}, or {@link #TYPE_UNSIGNED_SHORT}.
    426    *
    427    * @exception IllegalArgumentException if the data type is {@link #TYPE_RATIONAL} or {@link
    428    *     #TYPE_UNSIGNED_RATIONAL}.
    429    */
    430   long getValueAt(int index) {
    431     if (value instanceof long[]) {
    432       return ((long[]) value)[index];
    433     } else if (value instanceof byte[]) {
    434       return ((byte[]) value)[index];
    435     }
    436     throw new IllegalArgumentException(
    437         "Cannot get integer value from " + convertTypeToString(dataType));
    438   }
    439 
    440   /**
    441    * Gets the {@link #TYPE_ASCII} data.
    442    *
    443    * @exception IllegalArgumentException If the type is NOT {@link #TYPE_ASCII}.
    444    */
    445   protected String getString() {
    446     if (dataType != TYPE_ASCII) {
    447       throw new IllegalArgumentException(
    448           "Cannot get ASCII value from " + convertTypeToString(dataType));
    449     }
    450     return new String((byte[]) value, US_ASCII);
    451   }
    452 
    453   /**
    454    * Gets the offset of this tag. This is only valid if this data size > 4 and contains an offset to
    455    * the location of the actual value.
    456    */
    457   protected int getOffset() {
    458     return offset;
    459   }
    460 
    461   /** Sets the offset of this tag. */
    462   protected void setOffset(int offset) {
    463     this.offset = offset;
    464   }
    465 
    466   void setHasDefinedCount(boolean d) {
    467     hasDefinedDefaultComponentCount = d;
    468   }
    469 
    470   boolean hasDefinedCount() {
    471     return hasDefinedDefaultComponentCount;
    472   }
    473 
    474   private boolean checkBadComponentCount(int count) {
    475     return hasDefinedDefaultComponentCount && (componentCountActual != count);
    476   }
    477 
    478   private static String convertTypeToString(short type) {
    479     switch (type) {
    480       case TYPE_UNSIGNED_BYTE:
    481         return "UNSIGNED_BYTE";
    482       case TYPE_ASCII:
    483         return "ASCII";
    484       case TYPE_UNSIGNED_SHORT:
    485         return "UNSIGNED_SHORT";
    486       case TYPE_UNSIGNED_LONG:
    487         return "UNSIGNED_LONG";
    488       case TYPE_UNSIGNED_RATIONAL:
    489         return "UNSIGNED_RATIONAL";
    490       case TYPE_UNDEFINED:
    491         return "UNDEFINED";
    492       case TYPE_LONG:
    493         return "LONG";
    494       case TYPE_RATIONAL:
    495         return "RATIONAL";
    496       default:
    497         return "";
    498     }
    499   }
    500 
    501   private boolean checkOverflowForUnsignedShort(int[] value) {
    502     for (int v : value) {
    503       if (v > UNSIGNED_SHORT_MAX || v < 0) {
    504         return true;
    505       }
    506     }
    507     return false;
    508   }
    509 
    510   private boolean checkOverflowForUnsignedLong(long[] value) {
    511     for (long v : value) {
    512       if (v < 0 || v > UNSIGNED_LONG_MAX) {
    513         return true;
    514       }
    515     }
    516     return false;
    517   }
    518 
    519   private boolean checkOverflowForUnsignedLong(int[] value) {
    520     for (int v : value) {
    521       if (v < 0) {
    522         return true;
    523       }
    524     }
    525     return false;
    526   }
    527 
    528   private boolean checkOverflowForUnsignedRational(Rational[] value) {
    529     for (Rational v : value) {
    530       if (v.getNumerator() < 0
    531           || v.getDenominator() < 0
    532           || v.getNumerator() > UNSIGNED_LONG_MAX
    533           || v.getDenominator() > UNSIGNED_LONG_MAX) {
    534         return true;
    535       }
    536     }
    537     return false;
    538   }
    539 
    540   private boolean checkOverflowForRational(Rational[] value) {
    541     for (Rational v : value) {
    542       if (v.getNumerator() < LONG_MIN
    543           || v.getDenominator() < LONG_MIN
    544           || v.getNumerator() > LONG_MAX
    545           || v.getDenominator() > LONG_MAX) {
    546         return true;
    547       }
    548     }
    549     return false;
    550   }
    551 
    552   @Override
    553   public boolean equals(Object obj) {
    554     if (obj == null) {
    555       return false;
    556     }
    557     if (obj instanceof ExifTag) {
    558       ExifTag tag = (ExifTag) obj;
    559       if (tag.tagId != this.tagId
    560           || tag.componentCountActual != this.componentCountActual
    561           || tag.dataType != this.dataType) {
    562         return false;
    563       }
    564       if (value != null) {
    565         if (tag.value == null) {
    566           return false;
    567         } else if (value instanceof long[]) {
    568           if (!(tag.value instanceof long[])) {
    569             return false;
    570           }
    571           return Arrays.equals((long[]) value, (long[]) tag.value);
    572         } else if (value instanceof Rational[]) {
    573           if (!(tag.value instanceof Rational[])) {
    574             return false;
    575           }
    576           return Arrays.equals((Rational[]) value, (Rational[]) tag.value);
    577         } else if (value instanceof byte[]) {
    578           if (!(tag.value instanceof byte[])) {
    579             return false;
    580           }
    581           return Arrays.equals((byte[]) value, (byte[]) tag.value);
    582         } else {
    583           return value.equals(tag.value);
    584         }
    585       } else {
    586         return tag.value == null;
    587       }
    588     }
    589     return false;
    590   }
    591 
    592   @Override
    593   public int hashCode() {
    594     return Objects.hash(
    595         tagId, dataType, hasDefinedDefaultComponentCount, componentCountActual, ifd, value, offset);
    596   }
    597 
    598   @Override
    599   public String toString() {
    600     return String.format("tag id: %04X\n", tagId)
    601         + "ifd id: "
    602         + ifd
    603         + "\ntype: "
    604         + convertTypeToString(dataType)
    605         + "\ncount: "
    606         + componentCountActual
    607         + "\noffset: "
    608         + offset
    609         + "\nvalue: "
    610         + forceGetValueAsString()
    611         + "\n";
    612   }
    613 }
    614