Update change log and spec for wrt-plugins-tizen_0.4.11
[framework/web/wrt-plugins-tizen.git] / src / Content / ContentExif.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "ContentExif.h"
19 #include <Logger.h>
20
21
22 namespace DeviceAPI {
23 namespace Content {
24
25 ContentExif::ContentExif(std::string path)
26 {
27         fp = fopen(path.c_str(), "rb+");
28         m_exifBuf = NULL;
29 }
30
31 ContentExif::~ContentExif()
32 {
33         if(fp)
34         {
35                 fclose(fp);
36         }
37         if(!m_exifBuf)
38         {
39                 free(m_exifBuf);
40         }
41 }
42
43 unsigned char ContentExif::nextByte()
44 {
45         return getc(fp);
46 }
47
48 int ContentExif::read_1_byte (void)
49 {
50         int c;
51
52         //todo. check EOF
53         c = nextByte();
54
55         return c;
56 }
57
58 /* Read 2 bytes, convert to unsigned int */
59 /* All 2-byte quantities in JPEG markers are MSB first */
60 unsigned int ContentExif::read_2_bytes (void)
61 {
62         int c1, c2;
63
64         //todo. check EOF
65         c1 = nextByte();
66         c2 = nextByte();
67         return (((unsigned int) c1) << 8) + ((unsigned int) c2);
68 }
69
70 int ContentExif::LodExif()
71 {
72         unsigned char soi[2];
73
74         if(fp == NULL) return 0;
75
76         for (int i = 0; i < sizeof(soi); i++)
77           soi[i] = (unsigned char) read_1_byte();
78
79         //check soi tag for jpeg
80         if (soi[0]!=0xFF || soi[1]!=0xD8)
81         {
82                 LogDebug("can not find SOI tag");
83                 return -1;
84         }
85
86         //App marker
87         for(;;)
88         {
89                 unsigned char app[2];
90                 for( int i = 0; i < sizeof(app); i++)
91                         app[i] = (unsigned char) read_1_byte();
92
93                 printf("marker:%02x %02x \n",app[0],app[1]);
94                 if(app[0] == 0xFF && app[1] == 0xE1)
95                         break;
96                 else if(app[0] != 0xFF || !(app[1]==0xEE ||app[1]==0xE0))
97                 {
98                         LogDebug("Not supported image type.");
99                         return -1;
100                 }
101
102                 unsigned int marker_size = read_2_bytes();
103
104                 for( int i =0 ; i < marker_size - 2; i++)
105                         read_1_byte();
106         }
107
108         unsigned int len = read_2_bytes() - 8;
109         if (len < 0)
110         {
111                 LogDebug("Wrong Image");
112                 return -2;
113         }
114
115         //check exif header
116         unsigned char exif[6];
117         for (int i = 0; i < 6; i++)
118           exif[i] = (unsigned char) read_1_byte();
119
120         if (exif[0] != 0x45 || exif[1] != 0x78 || exif[2] != 0x69 ||exif[3] != 0x66)
121         {
122                 LogDebug("can not find EXIF tag");
123                 return -1;
124         }
125
126         m_exifBuf = (unsigned char*)calloc(len,sizeof(unsigned char));
127
128         fread(m_exifBuf, 1, len,fp);
129
130         /* check endian type */
131         if (m_exifBuf[0] == 0x49 && m_exifBuf[1] == 0x49)
132         {
133                 m_endianType = false;
134         }
135         else if (m_exifBuf[0] == 0x4D && m_exifBuf[1] == 0x4D)
136         {
137                 m_endianType = true;
138         }
139         else
140         {
141                 LogDebug("can not find endian tag");
142                 return -1;
143         }
144
145         /* Get first IFD offset (offset to IFD0) */
146         if (m_endianType)
147         {
148                 if (m_exifBuf[4] != 0) return 0;
149                 if (m_exifBuf[5] != 0) return 0;
150                 m_offset = m_exifBuf[6];
151                 m_offset <<= 8;
152                 m_offset += m_exifBuf[7];
153         }
154         else
155         {
156                 if (m_exifBuf[7] != 0) return 0;
157                 if (m_exifBuf[6] != 0) return 0;
158                 m_offset = m_exifBuf[5];
159                 m_offset <<= 8;
160                 m_offset += m_exifBuf[4];
161         }
162
163         if (m_offset > len - 2) return 0; /* check end of data segment */
164
165         /* Get the number of directory entries contained in this IFD */
166         if (m_endianType)
167         {
168                 m_tagCount = m_exifBuf[m_offset];
169                 m_tagCount <<= 8;
170                 m_tagCount += m_exifBuf[m_offset+1];
171         }
172         else
173         {
174                 m_tagCount = m_exifBuf[m_offset+1];
175                 m_tagCount <<= 8;
176                 m_tagCount += m_exifBuf[m_offset];
177         }
178         if (m_tagCount == 0) return 0;
179         m_offset += 2;
180
181         return 1;
182 }
183
184 bool ContentExif::SetExifChar(unsigned int tag, unsigned char value)
185 {
186         unsigned int _tag;
187         bool isfound = false;
188         for(unsigned int i = 0; i < m_tagCount; i++)
189         {
190                 if(m_endianType)
191                 {
192                         _tag = m_exifBuf[m_offset];
193                         _tag <<= 8;
194                         _tag += m_exifBuf[m_offset+1];
195                 }
196                 else
197                 {
198                         _tag = m_exifBuf[m_offset+1];
199                         _tag <<= 8;
200                         _tag += m_exifBuf[m_offset];
201                 }
202                 if(_tag == tag)
203                 {
204                         isfound = true;
205                         break;
206                 }
207
208             m_offset += 12;
209         }
210
211         if(isfound)
212         {
213                 if (m_endianType) {
214                         m_exifBuf[m_offset+2] = 0; /* Format = unsigned short (2 octets) */
215                         m_exifBuf[m_offset+3] = 3;
216                         m_exifBuf[m_offset+4] = 0; /* Number Of Components = 1 */
217                         m_exifBuf[m_offset+5] = 0;
218                         m_exifBuf[m_offset+6] = 0;
219                         m_exifBuf[m_offset+7] = 1;
220                         m_exifBuf[m_offset+8] = 0;
221                         m_exifBuf[m_offset+9] = value;
222                         m_exifBuf[m_offset+10] = 0;
223                         m_exifBuf[m_offset+11] = 0;
224                 } else {
225                         m_exifBuf[m_offset+2] = 3; /* Format = unsigned short (2 octets) */
226                         m_exifBuf[m_offset+3] = 0;
227                         m_exifBuf[m_offset+4] = 1; /* Number Of Components = 1 */
228                         m_exifBuf[m_offset+5] = 0;
229                         m_exifBuf[m_offset+6] = 0;
230                         m_exifBuf[m_offset+7] = 0;
231                         m_exifBuf[m_offset+8] = value;
232                         m_exifBuf[m_offset+9] = 0;
233                         m_exifBuf[m_offset+10] = 0;
234                         m_exifBuf[m_offset+11] = 0;
235                 }
236
237                 fseek(fp, (4 + 2 + 6 + 2) + m_offset, SEEK_SET);
238                 fwrite(m_exifBuf + 2 + m_offset, 1, 10, fp);
239         }
240         return isfound;
241 }
242
243
244 } // Content
245 } // DeviceAPI