1 /*
2  * Copyright (C) 2013 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 <system/camera_metadata.h>
18 
19 //#define LOG_NDEBUG 0
20 #define LOG_TAG "Metadata"
21 #include <cutils/log.h>
22 
23 #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
24 #include <utils/Trace.h>
25 
26 #include "Metadata.h"
27 
28 namespace default_camera_hal {
29 
Metadata()30 Metadata::Metadata():
31     mData(NULL)
32 {
33 }
34 
~Metadata()35 Metadata::~Metadata()
36 {
37     replace(NULL);
38 }
39 
replace(camera_metadata_t * m)40 void Metadata::replace(camera_metadata_t *m)
41 {
42     if (m == mData) {
43         ALOGE("%s: Replacing metadata with itself?!", __func__);
44         return;
45     }
46     if (mData)
47         free_camera_metadata(mData);
48     mData = m;
49 }
50 
init(const camera_metadata_t * metadata)51 int Metadata::init(const camera_metadata_t *metadata)
52 {
53     camera_metadata_t* tmp;
54 
55     if (validate_camera_metadata_structure(metadata, NULL))
56         return -EINVAL;
57 
58     tmp = clone_camera_metadata(metadata);
59     if (tmp == NULL)
60         return -EINVAL;
61 
62     replace(tmp);
63     return 0;
64 }
65 
addUInt8(uint32_t tag,int count,const uint8_t * data)66 int Metadata::addUInt8(uint32_t tag, int count, const uint8_t *data)
67 {
68     if (!validate(tag, TYPE_BYTE, count)) return -EINVAL;
69     return add(tag, count, data);
70 }
71 
add1UInt8(uint32_t tag,const uint8_t data)72 int Metadata::add1UInt8(uint32_t tag, const uint8_t data)
73 {
74     return addUInt8(tag, 1, &data);
75 }
76 
addInt32(uint32_t tag,int count,const int32_t * data)77 int Metadata::addInt32(uint32_t tag, int count, const int32_t *data)
78 {
79     if (!validate(tag, TYPE_INT32, count)) return -EINVAL;
80     return add(tag, count, data);
81 }
82 
addFloat(uint32_t tag,int count,const float * data)83 int Metadata::addFloat(uint32_t tag, int count, const float *data)
84 {
85     if (!validate(tag, TYPE_FLOAT, count)) return -EINVAL;
86     return add(tag, count, data);
87 }
88 
addInt64(uint32_t tag,int count,const int64_t * data)89 int Metadata::addInt64(uint32_t tag, int count, const int64_t *data)
90 {
91     if (!validate(tag, TYPE_INT64, count)) return -EINVAL;
92     return add(tag, count, data);
93 }
94 
addDouble(uint32_t tag,int count,const double * data)95 int Metadata::addDouble(uint32_t tag, int count, const double *data)
96 {
97     if (!validate(tag, TYPE_DOUBLE, count)) return -EINVAL;
98     return add(tag, count, data);
99 }
100 
addRational(uint32_t tag,int count,const camera_metadata_rational_t * data)101 int Metadata::addRational(uint32_t tag, int count,
102         const camera_metadata_rational_t *data)
103 {
104     if (!validate(tag, TYPE_RATIONAL, count)) return -EINVAL;
105     return add(tag, count, data);
106 }
107 
validate(uint32_t tag,int tag_type,int count)108 bool Metadata::validate(uint32_t tag, int tag_type, int count)
109 {
110     if (get_camera_metadata_tag_type(tag) < 0) {
111         ALOGE("%s: Invalid metadata entry tag: %d", __func__, tag);
112         return false;
113     }
114     if (tag_type < 0 || tag_type >= NUM_TYPES) {
115         ALOGE("%s: Invalid metadata entry tag type: %d", __func__, tag_type);
116         return false;
117     }
118     if (tag_type != get_camera_metadata_tag_type(tag)) {
119         ALOGE("%s: Tag %d called with incorrect type: %s(%d)", __func__, tag,
120                 camera_metadata_type_names[tag_type], tag_type);
121         return false;
122     }
123     if (count < 1) {
124         ALOGE("%s: Invalid metadata entry count: %d", __func__, count);
125         return false;
126     }
127     return true;
128 }
129 
add(uint32_t tag,int count,const void * tag_data)130 int Metadata::add(uint32_t tag, int count, const void *tag_data)
131 {
132     int res;
133     size_t entry_capacity = 0;
134     size_t data_capacity = 0;
135     camera_metadata_t* tmp;
136     int tag_type = get_camera_metadata_tag_type(tag);
137     size_t size = calculate_camera_metadata_entry_data_size(tag_type, count);
138 
139     if (NULL == mData) {
140         entry_capacity = 1;
141         data_capacity = size;
142     } else {
143         entry_capacity = get_camera_metadata_entry_count(mData) + 1;
144         data_capacity = get_camera_metadata_data_count(mData) + size;
145     }
146 
147     // Opportunistically attempt to add if metadata exists and has room for it
148     if (mData && !add_camera_metadata_entry(mData, tag, tag_data, count))
149         return 0;
150     // Double new dimensions to minimize future reallocations
151     tmp = allocate_camera_metadata(entry_capacity * 2, data_capacity * 2);
152     if (tmp == NULL) {
153         ALOGE("%s: Failed to allocate new metadata with %zu entries, %zu data",
154                 __func__, entry_capacity, data_capacity);
155         return -ENOMEM;
156     }
157     // Append the current metadata to the new (empty) metadata, if any
158     if (NULL != mData) {
159       res = append_camera_metadata(tmp, mData);
160       if (res) {
161           ALOGE("%s: Failed to append old metadata %p to new %p",
162                   __func__, mData, tmp);
163           return res;
164       }
165     }
166     // Add the remaining new item to tmp and replace mData
167     res = add_camera_metadata_entry(tmp, tag, tag_data, count);
168     if (res) {
169         ALOGE("%s: Failed to add new entry (%d, %p, %d) to metadata %p",
170                 __func__, tag, tag_data, count, tmp);
171         return res;
172     }
173     replace(tmp);
174 
175     return 0;
176 }
177 
get()178 camera_metadata_t* Metadata::get()
179 {
180     return mData;
181 }
182 
183 } // namespace default_camera_hal
184