Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright 2014 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 #include <img_utils/TiffIfd.h>
     18 #include <img_utils/TiffHelpers.h>
     19 #include <img_utils/TiffEntry.h>
     20 
     21 #include <utils/Errors.h>
     22 #include <utils/StrongPointer.h>
     23 #include <utils/Vector.h>
     24 
     25 namespace android {
     26 namespace img_utils {
     27 
     28 TiffEntry::~TiffEntry() {}
     29 
     30 /**
     31  * Specialize for each valid type, including sub-IFDs.
     32  *
     33  * Values with types other than the ones given here should not compile.
     34  */
     35 
     36 template<>
     37 const sp<TiffIfd>* TiffEntry::forceValidType<sp<TiffIfd> >(TagType type, const sp<TiffIfd>* value) {
     38     if (type == LONG) {
     39         return value;
     40     }
     41     ALOGE("%s: Value of type 'ifd' is not valid for tag with TIFF type %d.",
     42             __FUNCTION__, type);
     43     return NULL;
     44 }
     45 
     46 template<>
     47 const uint8_t* TiffEntry::forceValidType<uint8_t>(TagType type, const uint8_t* value) {
     48     if (type == BYTE || type == ASCII || type == UNDEFINED) {
     49         return value;
     50     }
     51     ALOGE("%s: Value of type 'uint8_t' is not valid for tag with TIFF type %d.",
     52             __FUNCTION__, type);
     53     return NULL;
     54 }
     55 
     56 template<>
     57 const int8_t* TiffEntry::forceValidType<int8_t>(TagType type, const int8_t* value) {
     58     if (type == SBYTE || type == ASCII || type == UNDEFINED) {
     59         return value;
     60     }
     61     ALOGE("%s: Value of type 'int8_t' is not valid for tag with TIFF type %d.",
     62             __FUNCTION__, type);
     63     return NULL;
     64 }
     65 
     66 template<>
     67 const uint16_t* TiffEntry::forceValidType<uint16_t>(TagType type, const uint16_t* value) {
     68     if (type == SHORT) {
     69         return value;
     70     }
     71     ALOGE("%s: Value of type 'uint16_t' is not valid for tag with TIFF type %d.",
     72             __FUNCTION__, type);
     73     return NULL;
     74 }
     75 
     76 template<>
     77 const int16_t* TiffEntry::forceValidType<int16_t>(TagType type, const int16_t* value) {
     78     if (type == SSHORT) {
     79         return value;
     80     }
     81     ALOGE("%s: Value of type 'int16_t' is not valid for tag with TIFF type %d.",
     82             __FUNCTION__, type);
     83     return NULL;
     84 }
     85 
     86 template<>
     87 const uint32_t* TiffEntry::forceValidType<uint32_t>(TagType type, const uint32_t* value) {
     88     if (type == LONG || type == RATIONAL) {
     89         return value;
     90     }
     91     ALOGE("%s: Value of type 'uint32_t' is not valid for tag with TIFF type %d.",
     92             __FUNCTION__, type);
     93     return NULL;
     94 }
     95 
     96 template<>
     97 const int32_t* TiffEntry::forceValidType<int32_t>(TagType type, const int32_t* value) {
     98     if (type == SLONG || type == SRATIONAL) {
     99         return value;
    100     }
    101     ALOGE("%s: Value of type 'int32_t' is not valid for tag with TIFF type %d.",
    102             __FUNCTION__, type);
    103     return NULL;
    104 }
    105 
    106 template<>
    107 const double* TiffEntry::forceValidType<double>(TagType type, const double* value) {
    108     if (type == DOUBLE) {
    109         return value;
    110     }
    111     ALOGE("%s: Value of type 'double' is not valid for tag with TIFF type %d.",
    112             __FUNCTION__, type);
    113     return NULL;
    114 }
    115 
    116 template<>
    117 const float* TiffEntry::forceValidType<float>(TagType type, const float* value) {
    118     if (type == FLOAT) {
    119         return value;
    120     }
    121     ALOGE("%s: Value of type 'float' is not valid for tag with TIFF type %d.",
    122             __FUNCTION__, type);
    123     return NULL;
    124 }
    125 
    126 String8 TiffEntry::toString() const {
    127     String8 output;
    128     uint32_t count = getCount();
    129     output.appendFormat("[id: %x, type: %d, count: %u, value: '", getTag(), getType(), count);
    130 
    131     size_t cappedCount = count;
    132     if (count > MAX_PRINT_STRING_LENGTH) {
    133         cappedCount = MAX_PRINT_STRING_LENGTH;
    134     }
    135 
    136     TagType type = getType();
    137     switch (type) {
    138         case UNDEFINED:
    139         case BYTE: {
    140             const uint8_t* typed_data = getData<uint8_t>();
    141             for (size_t i = 0; i < cappedCount; ++i) {
    142                 output.appendFormat("%u ", typed_data[i]);
    143             }
    144             break;
    145         }
    146         case ASCII: {
    147             const char* typed_data = reinterpret_cast<const char*>(getData<uint8_t>());
    148             size_t len = count;
    149             if (count > MAX_PRINT_STRING_LENGTH) {
    150                  len = MAX_PRINT_STRING_LENGTH;
    151             }
    152             output.append(typed_data, len);
    153             break;
    154         }
    155         case SHORT: {
    156             const uint16_t* typed_data = getData<uint16_t>();
    157             for (size_t i = 0; i < cappedCount; ++i) {
    158                 output.appendFormat("%u ", typed_data[i]);
    159             }
    160             break;
    161         }
    162         case LONG: {
    163             const uint32_t* typed_data = getData<uint32_t>();
    164             for (size_t i = 0; i < cappedCount; ++i) {
    165                 output.appendFormat("%u ", typed_data[i]);
    166             }
    167             break;
    168         }
    169         case RATIONAL: {
    170             const uint32_t* typed_data = getData<uint32_t>();
    171             cappedCount <<= 1;
    172             for (size_t i = 0; i < cappedCount; i+=2) {
    173                 output.appendFormat("%u/%u ", typed_data[i], typed_data[i + 1]);
    174             }
    175             break;
    176         }
    177         case SBYTE: {
    178             const int8_t* typed_data = getData<int8_t>();
    179             for (size_t i = 0; i < cappedCount; ++i) {
    180                 output.appendFormat("%d ", typed_data[i]);
    181             }
    182             break;
    183         }
    184         case SSHORT: {
    185             const int16_t* typed_data = getData<int16_t>();
    186             for (size_t i = 0; i < cappedCount; ++i) {
    187                 output.appendFormat("%d ", typed_data[i]);
    188             }
    189             break;
    190         }
    191         case SLONG: {
    192             const int32_t* typed_data = getData<int32_t>();
    193             for (size_t i = 0; i < cappedCount; ++i) {
    194                 output.appendFormat("%d ", typed_data[i]);
    195             }
    196             break;
    197         }
    198         case SRATIONAL: {
    199             const int32_t* typed_data = getData<int32_t>();
    200             cappedCount <<= 1;
    201             for (size_t i = 0; i < cappedCount; i+=2) {
    202                 output.appendFormat("%d/%d ", typed_data[i], typed_data[i + 1]);
    203             }
    204             break;
    205         }
    206         case FLOAT: {
    207             const float* typed_data = getData<float>();
    208             for (size_t i = 0; i < cappedCount; ++i) {
    209                 output.appendFormat("%f ", typed_data[i]);
    210             }
    211             break;
    212         }
    213         case DOUBLE: {
    214             const double* typed_data = getData<double>();
    215             for (size_t i = 0; i < cappedCount; ++i) {
    216                 output.appendFormat("%f ", typed_data[i]);
    217             }
    218             break;
    219         }
    220         default: {
    221             output.append("unknown type ");
    222             break;
    223         }
    224     }
    225 
    226     if (count > MAX_PRINT_STRING_LENGTH) {
    227         output.append("...");
    228     }
    229     output.append("']");
    230     return output;
    231 }
    232 
    233 } /*namespace img_utils*/
    234 } /*namespace android*/
    235