| Eino-Ville Talvala | cab96a4 | 2012-08-24 11:29:22 -0700 | [diff] [blame] | 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 | #define LOG_TAG "CameraMetadata" | 
 | 18 | #include <utils/Log.h> | 
 | 19 | #include <utils/Errors.h> | 
 | 20 |  | 
 | 21 | #include "CameraMetadata.h" | 
 | 22 |  | 
 | 23 | namespace android { | 
 | 24 |  | 
 | 25 | CameraMetadata::CameraMetadata() : | 
 | 26 |         mBuffer(NULL) { | 
 | 27 | } | 
 | 28 |  | 
 | 29 | CameraMetadata::CameraMetadata(size_t entryCapacity, size_t dataCapacity) | 
 | 30 | { | 
 | 31 |     mBuffer = allocate_camera_metadata(entryCapacity, dataCapacity); | 
 | 32 | } | 
 | 33 |  | 
 | 34 | CameraMetadata::CameraMetadata(const CameraMetadata &other) { | 
 | 35 |     mBuffer = clone_camera_metadata(other.mBuffer); | 
 | 36 | } | 
 | 37 |  | 
 | 38 | CameraMetadata &CameraMetadata::operator=(const CameraMetadata &other) { | 
 | 39 |     return operator=(other.mBuffer); | 
 | 40 | } | 
 | 41 |  | 
 | 42 | CameraMetadata &CameraMetadata::operator=(const camera_metadata_t *buffer) { | 
 | 43 |     if (CC_LIKELY(buffer != mBuffer)) { | 
 | 44 |         camera_metadata_t *newBuffer = clone_camera_metadata(buffer); | 
 | 45 |         clear(); | 
 | 46 |         mBuffer = newBuffer; | 
 | 47 |     } | 
 | 48 |     return *this; | 
 | 49 | } | 
 | 50 |  | 
 | 51 | CameraMetadata::~CameraMetadata() { | 
 | 52 |     clear(); | 
 | 53 | } | 
 | 54 |  | 
 | 55 | camera_metadata_t* CameraMetadata::release() { | 
 | 56 |     camera_metadata_t *released = mBuffer; | 
 | 57 |     mBuffer = NULL; | 
 | 58 |     return released; | 
 | 59 | } | 
 | 60 |  | 
 | 61 | void CameraMetadata::clear() { | 
 | 62 |     if (mBuffer) { | 
 | 63 |         free_camera_metadata(mBuffer); | 
 | 64 |         mBuffer = NULL; | 
 | 65 |     } | 
 | 66 | } | 
 | 67 |  | 
 | 68 | void CameraMetadata::acquire(camera_metadata_t *buffer) { | 
 | 69 |     clear(); | 
 | 70 |     mBuffer = buffer; | 
 | 71 | } | 
 | 72 |  | 
 | 73 | void CameraMetadata::acquire(CameraMetadata &other) { | 
 | 74 |     acquire(other.release()); | 
 | 75 | } | 
 | 76 |  | 
 | 77 | status_t CameraMetadata::append(const CameraMetadata &other) { | 
 | 78 |     return append_camera_metadata(mBuffer, other.mBuffer); | 
 | 79 | } | 
 | 80 |  | 
 | 81 | size_t CameraMetadata::entryCount() const { | 
 | 82 |     return (mBuffer == NULL) ? 0 : | 
 | 83 |             get_camera_metadata_entry_count(mBuffer); | 
 | 84 | } | 
 | 85 |  | 
 | 86 | status_t CameraMetadata::sort() { | 
 | 87 |     return sort_camera_metadata(mBuffer); | 
 | 88 | } | 
 | 89 |  | 
 | 90 | status_t CameraMetadata::checkType(uint32_t tag, uint8_t expectedType) { | 
 | 91 |     int tagType = get_camera_metadata_tag_type(tag); | 
 | 92 |     if ( CC_UNLIKELY(tagType == -1)) { | 
 | 93 |         ALOGE("Update metadata entry: Unknown tag %d", tag); | 
 | 94 |         return INVALID_OPERATION; | 
 | 95 |     } | 
 | 96 |     if ( CC_UNLIKELY(tagType != expectedType) ) { | 
 | 97 |         ALOGE("Mismatched tag type when updating entry %s (%d) of type %s; " | 
 | 98 |                 "got type %s data instead ", | 
 | 99 |                 get_camera_metadata_tag_name(tag), tag, | 
 | 100 |                 camera_metadata_type_names[tagType], | 
 | 101 |                 camera_metadata_type_names[expectedType]); | 
 | 102 |         return INVALID_OPERATION; | 
 | 103 |     } | 
 | 104 |     return OK; | 
 | 105 | } | 
 | 106 |  | 
 | 107 | status_t CameraMetadata::update(uint32_t tag, | 
 | 108 |         const int32_t *data, size_t data_count) { | 
 | 109 |     status_t res; | 
 | 110 |     if ( (res = checkType(tag, TYPE_INT32)) != OK) { | 
 | 111 |         return res; | 
 | 112 |     } | 
 | 113 |     return update(tag, (const void*)data, data_count); | 
 | 114 | } | 
 | 115 |  | 
 | 116 | status_t CameraMetadata::update(uint32_t tag, | 
 | 117 |         const uint8_t *data, size_t data_count) { | 
 | 118 |     status_t res; | 
 | 119 |     if ( (res = checkType(tag, TYPE_BYTE)) != OK) { | 
 | 120 |         return res; | 
 | 121 |     } | 
 | 122 |     return update(tag, (const void*)data, data_count); | 
 | 123 | } | 
 | 124 |  | 
 | 125 | status_t CameraMetadata::update(uint32_t tag, | 
 | 126 |         const float *data, size_t data_count) { | 
 | 127 |     status_t res; | 
 | 128 |     if ( (res = checkType(tag, TYPE_FLOAT)) != OK) { | 
 | 129 |         return res; | 
 | 130 |     } | 
 | 131 |     return update(tag, (const void*)data, data_count); | 
 | 132 | } | 
 | 133 |  | 
 | 134 | status_t CameraMetadata::update(uint32_t tag, | 
 | 135 |         const int64_t *data, size_t data_count) { | 
 | 136 |     status_t res; | 
 | 137 |     if ( (res = checkType(tag, TYPE_INT64)) != OK) { | 
 | 138 |         return res; | 
 | 139 |     } | 
 | 140 |     return update(tag, (const void*)data, data_count); | 
 | 141 | } | 
 | 142 |  | 
 | 143 | status_t CameraMetadata::update(uint32_t tag, | 
 | 144 |         const double *data, size_t data_count) { | 
 | 145 |     status_t res; | 
 | 146 |     if ( (res = checkType(tag, TYPE_DOUBLE)) != OK) { | 
 | 147 |         return res; | 
 | 148 |     } | 
 | 149 |     return update(tag, (const void*)data, data_count); | 
 | 150 | } | 
 | 151 |  | 
 | 152 | status_t CameraMetadata::update(uint32_t tag, | 
 | 153 |         const camera_metadata_rational_t *data, size_t data_count) { | 
 | 154 |     status_t res; | 
 | 155 |     if ( (res = checkType(tag, TYPE_RATIONAL)) != OK) { | 
 | 156 |         return res; | 
 | 157 |     } | 
 | 158 |     return update(tag, (const void*)data, data_count); | 
 | 159 | } | 
 | 160 |  | 
 | 161 | status_t CameraMetadata::update(uint32_t tag, | 
 | 162 |         const String8 &string) { | 
 | 163 |     status_t res; | 
 | 164 |     if ( (res = checkType(tag, TYPE_BYTE)) != OK) { | 
 | 165 |         return res; | 
 | 166 |     } | 
 | 167 |     return update(tag, (const void*)string.string(), string.size()); | 
 | 168 | } | 
 | 169 |  | 
 | 170 | status_t CameraMetadata::update(uint32_t tag, const void *data, | 
 | 171 |         size_t data_count) { | 
 | 172 |     status_t res; | 
 | 173 |     int type = get_camera_metadata_tag_type(tag); | 
 | 174 |     if (type == -1) { | 
 | 175 |         ALOGE("%s: Tag %d not found", __FUNCTION__, tag); | 
 | 176 |         return BAD_VALUE; | 
 | 177 |     } | 
 | 178 |     size_t data_size = calculate_camera_metadata_entry_data_size(type, | 
 | 179 |             data_count); | 
 | 180 |  | 
 | 181 |     res = resizeIfNeeded(1, data_size); | 
 | 182 |  | 
 | 183 |     if (res == OK) { | 
 | 184 |         camera_metadata_entry_t entry; | 
 | 185 |         res = find_camera_metadata_entry(mBuffer, tag, &entry); | 
 | 186 |         if (res == NAME_NOT_FOUND) { | 
 | 187 |             res = add_camera_metadata_entry(mBuffer, | 
 | 188 |                     tag, data, data_count); | 
 | 189 |         } else if (res == OK) { | 
 | 190 |             res = update_camera_metadata_entry(mBuffer, | 
 | 191 |                     entry.index, data, data_count, NULL); | 
 | 192 |         } | 
 | 193 |     } | 
 | 194 |  | 
 | 195 |     if (res != OK) { | 
 | 196 |         ALOGE("%s: Unable to update metadata entry %s.%s (%x): %s (%d)", | 
 | 197 |                 __FUNCTION__, get_camera_metadata_section_name(tag), | 
 | 198 |                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); | 
 | 199 |     } | 
 | 200 |     return res; | 
 | 201 | } | 
 | 202 |  | 
 | 203 | camera_metadata_entry_t CameraMetadata::find(uint32_t tag) { | 
 | 204 |     status_t res; | 
 | 205 |     camera_metadata_entry entry; | 
 | 206 |     res = find_camera_metadata_entry(mBuffer, tag, &entry); | 
 | 207 |     if (CC_UNLIKELY( res != OK )) { | 
 | 208 |         entry.count = 0; | 
 | 209 |         entry.data.u8 = NULL; | 
 | 210 |     } | 
 | 211 |     return entry; | 
 | 212 | } | 
 | 213 |  | 
 | 214 | camera_metadata_ro_entry_t CameraMetadata::find(uint32_t tag) const { | 
 | 215 |     status_t res; | 
 | 216 |     camera_metadata_ro_entry entry; | 
 | 217 |     res = find_camera_metadata_ro_entry(mBuffer, tag, &entry); | 
 | 218 |     if (CC_UNLIKELY( res != OK )) { | 
 | 219 |         entry.count = 0; | 
 | 220 |         entry.data.u8 = NULL; | 
 | 221 |     } | 
 | 222 |     return entry; | 
 | 223 | } | 
 | 224 |  | 
 | 225 | status_t CameraMetadata::erase(uint32_t tag) { | 
 | 226 |     camera_metadata_entry_t entry; | 
 | 227 |     status_t res; | 
 | 228 |     res = find_camera_metadata_entry(mBuffer, tag, &entry); | 
 | 229 |     if (res == NAME_NOT_FOUND) { | 
 | 230 |         return OK; | 
 | 231 |     } else if (res != OK) { | 
 | 232 |         ALOGE("%s: Error looking for entry %s.%s (%x): %s %d", | 
 | 233 |                 __FUNCTION__, | 
 | 234 |                 get_camera_metadata_section_name(tag), | 
 | 235 |                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); | 
 | 236 |         return res; | 
 | 237 |     } | 
 | 238 |     res = delete_camera_metadata_entry(mBuffer, entry.index); | 
 | 239 |     if (res != OK) { | 
 | 240 |         ALOGE("%s: Error deleting entry %s.%s (%x): %s %d", | 
 | 241 |                 __FUNCTION__, | 
 | 242 |                 get_camera_metadata_section_name(tag), | 
 | 243 |                 get_camera_metadata_tag_name(tag), tag, strerror(-res), res); | 
 | 244 |     } | 
 | 245 |     return res; | 
 | 246 | } | 
 | 247 |  | 
 | 248 | void CameraMetadata::dump(int fd, int verbosity, int indentation) const { | 
 | 249 |     dump_indented_camera_metadata(mBuffer, fd, verbosity, indentation); | 
 | 250 | } | 
 | 251 |  | 
 | 252 | status_t CameraMetadata::resizeIfNeeded(size_t extraEntries, size_t extraData) { | 
 | 253 |     if (mBuffer == NULL) { | 
 | 254 |         mBuffer = allocate_camera_metadata(extraEntries * 2, extraData * 2); | 
 | 255 |         if (mBuffer == NULL) { | 
 | 256 |             ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); | 
 | 257 |             return NO_MEMORY; | 
 | 258 |         } | 
 | 259 |     } else { | 
 | 260 |         size_t currentEntryCount = get_camera_metadata_entry_count(mBuffer); | 
 | 261 |         size_t currentEntryCap = get_camera_metadata_entry_capacity(mBuffer); | 
 | 262 |         size_t newEntryCount = currentEntryCount + | 
 | 263 |                 extraEntries; | 
 | 264 |         newEntryCount = (newEntryCount > currentEntryCap) ? | 
 | 265 |                 newEntryCount * 2 : currentEntryCap; | 
 | 266 |  | 
 | 267 |         size_t currentDataCount = get_camera_metadata_data_count(mBuffer); | 
 | 268 |         size_t currentDataCap = get_camera_metadata_data_capacity(mBuffer); | 
 | 269 |         size_t newDataCount = currentDataCount + | 
 | 270 |                 extraData; | 
 | 271 |         newDataCount = (newDataCount > currentDataCap) ? | 
 | 272 |                 newDataCount * 2 : currentDataCap; | 
 | 273 |  | 
 | 274 |         if (newEntryCount > currentEntryCap || | 
 | 275 |                 newDataCount > currentDataCap) { | 
 | 276 |             camera_metadata_t *oldBuffer = mBuffer; | 
 | 277 |             mBuffer = allocate_camera_metadata(newEntryCount, | 
 | 278 |                     newDataCount); | 
 | 279 |             if (mBuffer == NULL) { | 
 | 280 |                 ALOGE("%s: Can't allocate larger metadata buffer", __FUNCTION__); | 
 | 281 |                 return NO_MEMORY; | 
 | 282 |             } | 
 | 283 |             append_camera_metadata(mBuffer, oldBuffer); | 
 | 284 |             free_camera_metadata(oldBuffer); | 
 | 285 |         } | 
 | 286 |     } | 
 | 287 |     return OK; | 
 | 288 | } | 
 | 289 |  | 
 | 290 | }; // namespace android |