1 /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include "mm_jpeg_dbg.h"
31 #include "mm_jpeg.h"
32 #include <errno.h>
33 
34 
35 #define LOWER(a)               ((a) & 0xFFFF)
36 #define UPPER(a)               (((a)>>16) & 0xFFFF)
37 #define CHANGE_ENDIAN_16(a)  ((0x00FF & ((a)>>8)) | (0xFF00 & ((a)<<8)))
38 
39 
40 /** addExifEntry:
41  *
42  *  Arguments:
43  *   @exif_info : Exif info struct
44  *   @p_session: job session
45  *   @tagid   : exif tag ID
46  *   @type    : data type
47  *   @count   : number of data in uint of its type
48  *   @data    : input data ptr
49  *
50  *  Retrun     : int32_t type of status
51  *               0  -- success
52  *              none-zero failure code
53  *
54  *  Description:
55  *       Function to add an entry to exif data
56  *
57  **/
addExifEntry(QOMX_EXIF_INFO * p_exif_info,exif_tag_id_t tagid,exif_tag_type_t type,uint32_t count,void * data)58 int32_t addExifEntry(QOMX_EXIF_INFO *p_exif_info, exif_tag_id_t tagid,
59   exif_tag_type_t type, uint32_t count, void *data)
60 {
61     int32_t rc = 0;
62     int32_t numOfEntries = p_exif_info->numOfEntries;
63     QEXIF_INFO_DATA *p_info_data = p_exif_info->exif_data;
64     if(numOfEntries >= MAX_EXIF_TABLE_ENTRIES) {
65         ALOGE("%s: Number of entries exceeded limit", __func__);
66         return -1;
67     }
68 
69     p_info_data[numOfEntries].tag_id = tagid;
70     p_info_data[numOfEntries].tag_entry.type = type;
71     p_info_data[numOfEntries].tag_entry.count = count;
72     p_info_data[numOfEntries].tag_entry.copy = 1;
73     switch (type) {
74     case EXIF_BYTE: {
75       if (count > 1) {
76         uint8_t *values = (uint8_t *)malloc(count);
77         if (values == NULL) {
78           ALOGE("%s: No memory for byte array", __func__);
79           rc = -1;
80         } else {
81           memcpy(values, data, count);
82           p_info_data[numOfEntries].tag_entry.data._bytes = values;
83         }
84       } else {
85         p_info_data[numOfEntries].tag_entry.data._byte = *(uint8_t *)data;
86       }
87     }
88     break;
89     case EXIF_ASCII: {
90       char *str = NULL;
91       str = (char *)malloc(count + 1);
92       if (str == NULL) {
93         ALOGE("%s: No memory for ascii string", __func__);
94         rc = -1;
95       } else {
96         memset(str, 0, count + 1);
97         memcpy(str, data, count);
98         p_info_data[numOfEntries].tag_entry.data._ascii = str;
99       }
100     }
101     break;
102     case EXIF_SHORT: {
103       if (count > 1) {
104         uint16_t *values = (uint16_t *)malloc(count * sizeof(uint16_t));
105         if (values == NULL) {
106           ALOGE("%s: No memory for short array", __func__);
107           rc = -1;
108         } else {
109           memcpy(values, data, count * sizeof(uint16_t));
110           p_info_data[numOfEntries].tag_entry.data._shorts = values;
111         }
112       } else {
113         p_info_data[numOfEntries].tag_entry.data._short = *(uint16_t *)data;
114       }
115     }
116     break;
117     case EXIF_LONG: {
118       if (count > 1) {
119         uint32_t *values = (uint32_t *)malloc(count * sizeof(uint32_t));
120         if (values == NULL) {
121           ALOGE("%s: No memory for long array", __func__);
122           rc = -1;
123         } else {
124           memcpy(values, data, count * sizeof(uint32_t));
125           p_info_data[numOfEntries].tag_entry.data._longs = values;
126         }
127       } else {
128         p_info_data[numOfEntries].tag_entry.data._long = *(uint32_t *)data;
129       }
130     }
131     break;
132     case EXIF_RATIONAL: {
133       if (count > 1) {
134         rat_t *values = (rat_t *)malloc(count * sizeof(rat_t));
135         if (values == NULL) {
136           ALOGE("%s: No memory for rational array", __func__);
137           rc = -1;
138         } else {
139           memcpy(values, data, count * sizeof(rat_t));
140           p_info_data[numOfEntries].tag_entry.data._rats = values;
141         }
142       } else {
143         p_info_data[numOfEntries].tag_entry.data._rat = *(rat_t *)data;
144       }
145     }
146     break;
147     case EXIF_UNDEFINED: {
148       uint8_t *values = (uint8_t *)malloc(count);
149       if (values == NULL) {
150         ALOGE("%s: No memory for undefined array", __func__);
151         rc = -1;
152       } else {
153         memcpy(values, data, count);
154         p_info_data[numOfEntries].tag_entry.data._undefined = values;
155       }
156     }
157     break;
158     case EXIF_SLONG: {
159       if (count > 1) {
160         int32_t *values = (int32_t *)malloc(count * sizeof(int32_t));
161         if (values == NULL) {
162           ALOGE("%s: No memory for signed long array", __func__);
163           rc = -1;
164         } else {
165           memcpy(values, data, count * sizeof(int32_t));
166           p_info_data[numOfEntries].tag_entry.data._slongs = values;
167         }
168       } else {
169         p_info_data[numOfEntries].tag_entry.data._slong = *(int32_t *)data;
170       }
171     }
172     break;
173     case EXIF_SRATIONAL: {
174       if (count > 1) {
175         srat_t *values = (srat_t *)malloc(count * sizeof(srat_t));
176         if (values == NULL) {
177           ALOGE("%s: No memory for signed rational array", __func__);
178           rc = -1;
179         } else {
180           memcpy(values, data, count * sizeof(srat_t));
181           p_info_data[numOfEntries].tag_entry.data._srats = values;
182         }
183       } else {
184         p_info_data[numOfEntries].tag_entry.data._srat = *(srat_t *)data;
185       }
186     }
187     break;
188     }
189 
190     // Increase number of entries
191     p_exif_info->numOfEntries++;
192     return rc;
193 }
194 
195 
releaseExifEntry(QOMX_EXIF_INFO * p_exif_info)196 int32_t releaseExifEntry(QOMX_EXIF_INFO *p_exif_info)
197 {
198   uint32_t i = 0;
199   for (i = 0; i < p_exif_info->numOfEntries; i++) {
200   switch (p_exif_info->exif_data[i].tag_entry.type) {
201   case EXIF_BYTE: {
202     if (p_exif_info->exif_data[i].tag_entry.count > 1 &&
203       p_exif_info->exif_data[i].tag_entry.data._bytes != NULL) {
204       free(p_exif_info->exif_data[i].tag_entry.data._bytes);
205       p_exif_info->exif_data[i].tag_entry.data._bytes = NULL;
206     }
207   }
208   break;
209   case EXIF_ASCII: {
210     if (p_exif_info->exif_data[i].tag_entry.data._ascii != NULL) {
211       free(p_exif_info->exif_data[i].tag_entry.data._ascii);
212       p_exif_info->exif_data[i].tag_entry.data._ascii = NULL;
213     }
214   }
215   break;
216   case EXIF_SHORT: {
217     if (p_exif_info->exif_data[i].tag_entry.count > 1 &&
218       p_exif_info->exif_data[i].tag_entry.data._shorts != NULL) {
219       free(p_exif_info->exif_data[i].tag_entry.data._shorts);
220       p_exif_info->exif_data[i].tag_entry.data._shorts = NULL;
221     }
222   }
223   break;
224   case EXIF_LONG: {
225     if (p_exif_info->exif_data[i].tag_entry.count > 1 &&
226       p_exif_info->exif_data[i].tag_entry.data._longs != NULL) {
227       free(p_exif_info->exif_data[i].tag_entry.data._longs);
228       p_exif_info->exif_data[i].tag_entry.data._longs = NULL;
229     }
230   }
231   break;
232   case EXIF_RATIONAL: {
233     if (p_exif_info->exif_data[i].tag_entry.count > 1 &&
234       p_exif_info->exif_data[i].tag_entry.data._rats != NULL) {
235       free(p_exif_info->exif_data[i].tag_entry.data._rats);
236       p_exif_info->exif_data[i].tag_entry.data._rats = NULL;
237     }
238   }
239   break;
240   case EXIF_UNDEFINED: {
241     if (p_exif_info->exif_data[i].tag_entry.data._undefined != NULL) {
242       free(p_exif_info->exif_data[i].tag_entry.data._undefined);
243       p_exif_info->exif_data[i].tag_entry.data._undefined = NULL;
244     }
245   }
246   break;
247   case EXIF_SLONG: {
248     if (p_exif_info->exif_data[i].tag_entry.count > 1 &&
249       p_exif_info->exif_data[i].tag_entry.data._slongs != NULL) {
250       free(p_exif_info->exif_data[i].tag_entry.data._slongs);
251       p_exif_info->exif_data[i].tag_entry.data._slongs = NULL;
252     }
253   }
254   break;
255   case EXIF_SRATIONAL: {
256     if (p_exif_info->exif_data[i].tag_entry.count > 1 &&
257       p_exif_info->exif_data[i].tag_entry.data._srats != NULL) {
258       free(p_exif_info->exif_data[i].tag_entry.data._srats);
259       p_exif_info->exif_data[i].tag_entry.data._srats = NULL;
260     }
261   }
262   break;
263   }
264 
265   } /*end of switch*/
266 
267   return 0;
268 }
269