summaryrefslogtreecommitdiff
path: root/legacy
diff options
context:
space:
mode:
authorJiyoun Park <jijibe99@gmail.com>2012-08-26 11:22:55 +0000
committerJiyoun Park <jijibe99@gmail.com>2012-08-26 11:22:55 +0000
commit4c7a23d21e27e7e6b6721842b693567b6a876eb9 (patch)
tree3f06c3b5a7c8c1c287352d9627be62263c86623c /legacy
parent77997affdaf1c4147f542cc905a32bce5146cfd4 (diff)
fix jpeg loader to decode JFIF format.
before, if the jpeg format is JFIF, we cannot get orientation. currently jpeg loader get orientation from file SVN revision: 75707
Diffstat (limited to 'legacy')
-rw-r--r--legacy/evas/ChangeLog4
-rw-r--r--legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c102
2 files changed, 85 insertions, 21 deletions
diff --git a/legacy/evas/ChangeLog b/legacy/evas/ChangeLog
index 73986747f5..cd0b83ed6f 100644
--- a/legacy/evas/ChangeLog
+++ b/legacy/evas/ChangeLog
@@ -981,3 +981,7 @@
981 * Textblock: Fixed bug with 1 char word separators at the start of the 981 * Textblock: Fixed bug with 1 char word separators at the start of the
982 text when going to the start of the word (e.g: "=test"). 982 text when going to the start of the word (e.g: "=test").
983 983
9842012-08-26 Jiyoun Park(jypark)
985
986 * Jpeg loader: fix orientation didn't work if jpeg file format is JFIF.
987 Add code deal with JFIF file format.
diff --git a/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c b/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c
index 37efa7f555..a34fba4942 100644
--- a/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c
+++ b/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c
@@ -25,6 +25,9 @@ struct _JPEG_error_mgr
25static void _JPEGFatalErrorHandler(j_common_ptr cinfo); 25static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
26static void _JPEGErrorHandler(j_common_ptr cinfo); 26static void _JPEGErrorHandler(j_common_ptr cinfo);
27static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level); 27static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
28static int _get_orientation_app0(char *app0_head, size_t remain_length);
29static int _get_orientation_app1(char *app1_head, size_t remain_length);
30static int _get_orientation(void *map, size_t length);
28 31
29static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie, 32static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
30 void *map, 33 void *map,
@@ -161,8 +164,11 @@ _evas_jpeg_membuf_src(j_decompress_ptr cinfo,
161 return 0; 164 return 0;
162} 165}
163 166
164/*! Magic number for EXIF header & App1*/ 167/*! Magic number for EXIF header, App0, App1*/
165static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; 168static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
169static const unsigned char JfifHeader[] = {0x4A, 0x46, 0x49, 0x46, 0x00};
170static const unsigned char JfxxHeader[] = {0x4A, 0x46, 0x58, 0x58, 0x00};
171static const unsigned char App0[] = {0xff, 0xe0};
166static const unsigned char App1[] = {0xff, 0xe1}; 172static const unsigned char App1[] = {0xff, 0xe1};
167typedef enum { 173typedef enum {
168 EXIF_BYTE_ALIGN_II, 174 EXIF_BYTE_ALIGN_II,
@@ -170,7 +176,48 @@ typedef enum {
170} ExifByteAlign; 176} ExifByteAlign;
171 177
172static int 178static int
173_get_orientation(void *map, size_t length) 179_get_orientation_app0(char *app0_head, size_t remain_length)
180{
181 unsigned int length = 0;
182 unsigned int w = 0, h = 0;
183 unsigned int format = 0;
184 unsigned int data_size = 0;
185 char *p;
186
187 /* p is appn's start pointer excluding app0 marker */
188 p = app0_head + 2;
189
190
191 length = ((*p << 8) + *(p + 1));
192
193 /* JFIF segment format */
194 if (!memcmp(p + 2, JfifHeader, sizeof (JfifHeader)))
195 {
196 format = 3;
197 w = *(p + 14);
198 h = *(p + 15);
199 }
200 else if (!memcmp(p + 2, JfxxHeader, sizeof (JfxxHeader)))
201 {
202 if (*(p + 7) == 0x11)
203 format = 1;
204 else
205 format = 3;
206 w = *(p + 8);
207 h = *(p + 9);
208 }
209
210 data_size = format * w * h;
211 p += length + data_size;
212
213 if (!memcmp(p, App1, sizeof (App1)))
214 return _get_orientation_app1(p, remain_length - (2 + length + data_size));
215 else
216 return 0;
217}
218
219static int
220_get_orientation_app1(char *app1_head, size_t remain_length)
174{ 221{
175 char *buf; 222 char *buf;
176 char orientation[2]; 223 char orientation[2];
@@ -179,39 +226,33 @@ _get_orientation(void *map, size_t length)
179 unsigned int i, j; 226 unsigned int i, j;
180 int direction; 227 int direction;
181 228
182 /* open file and get 22 byte frome file */ 229 /* start of app1 frame */
183 if (!map) return 0; 230 buf = app1_head;
184 /* 1. read 22byte */
185 if (length < 22) return 0;
186 buf = (char *)map;
187
188 /* 2. check 2,3 bypte with APP1(0xFFE1) */
189 if (memcmp(buf + 2, App1, sizeof (App1))) return 0;
190 231
191 /* 3. check 6~11bype with Exif Header (0x45786966 0000) */ 232 /* 1. check 4~9bype with Exif Header (0x45786966 0000) */
192 if (memcmp(buf + 6, ExifHeader, sizeof (ExifHeader))) return 0; 233 if (memcmp(buf + 4, ExifHeader, sizeof (ExifHeader))) return 0;
193 234
194 /* 4. get 12&13 byte get info of "II(0x4949)" or "MM(0x4d4d)" */ 235 /* 2. get 10&11 byte get info of "II(0x4949)" or "MM(0x4d4d)" */
195 /* 5. get [20]&[21] get directory entry # */ 236 /* 3. get [18]&[19] get directory entry # */
196 if (!strncmp(buf + 12, "MM", 2)) 237 if (!strncmp(buf + 10, "MM", 2))
197 { 238 {
198 byte_align = EXIF_BYTE_ALIGN_MM; 239 byte_align = EXIF_BYTE_ALIGN_MM;
199 num_directory = ((*(buf + 20) << 8) + *(buf + 21)); 240 num_directory = ((*(buf + 18) << 8) + *(buf + 19));
200 orientation[0] = 0x01; 241 orientation[0] = 0x01;
201 orientation[1] = 0x12; 242 orientation[1] = 0x12;
202 } 243 }
203 else if (!strncmp(buf + 12, "II", 2)) 244 else if (!strncmp(buf + 10, "II", 2))
204 { 245 {
205 byte_align = EXIF_BYTE_ALIGN_II; 246 byte_align = EXIF_BYTE_ALIGN_II;
206 num_directory = ((*(buf + 21) << 8) + *(buf + 20)); 247 num_directory = ((*(buf + 19) << 8) + *(buf + 18));
207 orientation[0] = 0x12; 248 orientation[0] = 0x12;
208 orientation[1] = 0x01; 249 orientation[1] = 0x01;
209 } 250 }
210 else return 0; 251 else return 0;
211 252
212 buf = map + 22; 253 buf = app1_head + 20;
213 254
214 if (length < (12 * num_directory + 22)) return 0; 255 if (remain_length < (12 * num_directory + 20)) return 0;
215 256
216 j = 0; 257 j = 0;
217 258
@@ -221,7 +262,7 @@ _get_orientation(void *map, size_t length)
221 { 262 {
222 /*get orientation tag */ 263 /*get orientation tag */
223 if (byte_align == EXIF_BYTE_ALIGN_MM) 264 if (byte_align == EXIF_BYTE_ALIGN_MM)
224 direction = *(buf+ j + 11); 265 direction = *(buf+ j + 9);
225 else direction = *(buf+ j + 8); 266 else direction = *(buf+ j + 8);
226 switch (direction) 267 switch (direction)
227 { 268 {
@@ -244,6 +285,25 @@ _get_orientation(void *map, size_t length)
244 return 0; 285 return 0;
245} 286}
246 287
288static int
289_get_orientation(void *map, size_t length)
290{
291 char *buf;
292
293 /* open file and get 22 byte frome file */
294 if (!map) return 0;
295 /* 1. read 22byte */
296 if (length < 22) return 0;
297 buf = (char *)map;
298
299 /* 2. check 2,3 bypte with APP0(0xFFE0) or APP1(0xFFE1) */
300 if (!memcmp(buf + 2, App0, sizeof (App0)))
301 return _get_orientation_app0(buf + 2, length - 2);
302 if (!memcmp(buf + 2, App1, sizeof (App1)))
303 return _get_orientation_app1(buf + 2, length - 2);
304 return 0;
305}
306
247static Eina_Bool 307static Eina_Bool
248evas_image_load_file_head_jpeg_internal(Image_Entry *ie, 308evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
249 void *map, size_t length, 309 void *map, size_t length,