summaryrefslogtreecommitdiff
path: root/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
diff options
context:
space:
mode:
authorWonguk Jeong <wonguk.jeong@samsung.com>2014-07-06 19:58:47 +0200
committerCedric BAIL <c.bail@partner.samsung.com>2014-07-06 20:12:31 +0200
commit1cc23d4ff26ade2e58b575e295fb1ef4fc937a13 (patch)
treedfdb4510cbd992b6bd8388fe020314441136a91b /src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
parent5eef4351fdfa6ae4811be8fb297d1dca1d1b0c7a (diff)
evas: jpeg loader - support flip, transpose, transverse
Summary: Previously, jpeg image loader support rotation (90°, 180°, 270°) only. this patch is about supporting flip(vertical, horizontal), transpose, transverse @feature Test Plan: I'm going to make tests in src/tests Reviewers: cedric, raster, jpeg CC: seoz, cedric Differential Revision: https://phab.enlightenment.org/D1126 Signed-off-by: Cedric BAIL <c.bail@partner.samsung.com>
Diffstat (limited to '')
-rw-r--r--src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c328
1 files changed, 213 insertions, 115 deletions
diff --git a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
index 0ec2c85c00..c0047a3ea8 100644
--- a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
+++ b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
@@ -37,8 +37,9 @@ static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
37static void _JPEGErrorHandler(j_common_ptr cinfo); 37static void _JPEGErrorHandler(j_common_ptr cinfo);
38static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level); 38static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
39static Eina_Bool _get_next_app0(unsigned char *map, size_t fsize, size_t *position); 39static Eina_Bool _get_next_app0(unsigned char *map, size_t fsize, size_t *position);
40static Eina_Bool _get_orientation_app1(unsigned char *map, size_t fsize, size_t *position, int *orientation); 40static Eina_Bool _get_orientation_app1(unsigned char *map, size_t fsize, size_t *position,
41static int _get_orientation(void *map, size_t length); 41 int *orientation, Eina_Bool *flipped);
42static int _get_orientation(void *map, size_t length, Eina_Bool *flipped);
42 43
43#if 0 /* not used at the moment */ 44#if 0 /* not used at the moment */
44static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2); 45static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
@@ -218,7 +219,8 @@ _get_next_app0(unsigned char *map, size_t fsize, size_t *position)
218 */ 219 */
219 220
220static Eina_Bool 221static Eina_Bool
221_get_orientation_app1(unsigned char *map, size_t fsize, size_t *position, int *orientation_res) 222_get_orientation_app1(unsigned char *map, size_t fsize, size_t *position,
223 int *orientation_res, Eina_Bool *flipped)
222{ 224{
223 unsigned char *app1_head, *buf; 225 unsigned char *app1_head, *buf;
224 unsigned char orientation[2]; 226 unsigned char orientation[2];
@@ -279,20 +281,37 @@ _get_orientation_app1(unsigned char *map, size_t fsize, size_t *position, int *o
279 switch (direction) 281 switch (direction)
280 { 282 {
281 case 3: 283 case 3:
284 *orientation_res = 180;
285 *flipped = EINA_FALSE;
286 return EINA_TRUE;
282 case 4: 287 case 4:
283 *orientation_res = 180; 288 *orientation_res = 180;
284 return EINA_TRUE; 289 *flipped = EINA_TRUE;
290 return EINA_TRUE;
285 case 6: 291 case 6:
292 *orientation_res = 90;
293 *flipped = EINA_FALSE;
294 return EINA_TRUE;
286 case 7: 295 case 7:
287 *orientation_res = 90; 296 *orientation_res = 90;
288 return EINA_TRUE; 297 *flipped = EINA_TRUE;
298 return EINA_TRUE;
289 case 5: 299 case 5:
300 *orientation_res = 270;
301 *flipped = EINA_TRUE;
302 return EINA_TRUE;
290 case 8: 303 case 8:
291 *orientation_res = 270; 304 *orientation_res = 270;
292 return EINA_TRUE; 305 *flipped = EINA_FALSE;
306 return EINA_TRUE;
307 case 2:
308 *orientation_res = 0;
309 *flipped = EINA_TRUE;
310 return EINA_TRUE;
293 default: 311 default:
294 *orientation_res = 0; 312 *orientation_res = 0;
295 return EINA_TRUE; 313 *flipped = EINA_FALSE;
314 return EINA_TRUE;
296 } 315 }
297 } 316 }
298 else 317 else
@@ -302,13 +321,15 @@ _get_orientation_app1(unsigned char *map, size_t fsize, size_t *position, int *o
302} 321}
303 322
304static int 323static int
305_get_orientation(void *map, size_t length) 324_get_orientation(void *map, size_t length, Eina_Bool *flipped)
306{ 325{
307 unsigned char *buf; 326 unsigned char *buf;
308 size_t position = 0; 327 size_t position = 0;
309 int orientation = -1; 328 int orientation = -1;
310 Eina_Bool res = EINA_FALSE; 329 Eina_Bool res = EINA_FALSE;
311 330
331 *flipped = EINA_FALSE;
332
312 /* open file and get 22 byte frome file */ 333 /* open file and get 22 byte frome file */
313 if (!map) return 0; 334 if (!map) return 0;
314 /* 1. read 22byte */ 335 /* 1. read 22byte */
@@ -326,7 +347,7 @@ _get_orientation(void *map, size_t length)
326 } 347 }
327 else if (!memcmp(buf + position, App1, sizeof (App1))) 348 else if (!memcmp(buf + position, App1, sizeof (App1)))
328 { 349 {
329 res = _get_orientation_app1(map, length, &position, &orientation); 350 res = _get_orientation_app1(map, length, &position, &orientation, flipped);
330 if (!res) break; 351 if (!res) break;
331 if (orientation != -1) return orientation; 352 if (orientation != -1) return orientation;
332 } 353 }
@@ -335,10 +356,69 @@ _get_orientation(void *map, size_t length)
335 return 0; 356 return 0;
336} 357}
337 358
359static void
360_rotate_region(unsigned int *r_x, unsigned int *r_y, unsigned int *r_w, unsigned int *r_h,
361 unsigned int x, unsigned int y, unsigned int w, unsigned int h,
362 unsigned int output_w, unsigned int output_h,
363 int degree, Eina_Bool flipped)
364{
365 switch (degree)
366 {
367 case 90:
368 if (flipped)
369 {
370 *r_x = output_w - (y + h);
371 *r_y = output_h - (x + w);
372 *r_w = h;
373 *r_h = w;
374 }
375 else
376 {
377 *r_x = y;
378 *r_y = output_h - (x + y);
379 *r_w = h;
380 *r_h = w;
381 }
382 break;
383 case 180:
384 if (flipped)
385 {
386 *r_y = output_h - (y + h);
387 }
388 else
389 {
390 *r_x = output_w - (x + w);
391 *r_y = output_h - (y + h);
392 }
393 break;
394 case 270:
395 if (flipped)
396 {
397 *r_x = y;
398 *r_y = x;
399 *r_w = h;
400 *r_h = w;
401 }
402 else
403 {
404 *r_x = output_w - (y + h);
405 *r_y = x;
406 *r_w = h;
407 *r_h = w;
408 }
409 break;
410 default:
411 if (flipped)
412 *r_x = output_w - (x + w);
413 break;
414 }
415}
416
338static Eina_Bool 417static Eina_Bool
339evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h, 418evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
340 unsigned char *scale, 419 unsigned char *scale,
341 unsigned char *rotated, 420 unsigned char *rotated,
421 Eina_Bool *flipped,
342 Evas_Image_Load_Opts *opts, 422 Evas_Image_Load_Opts *opts,
343 void *map, size_t length, 423 void *map, size_t length,
344 int *error) 424 int *error)
@@ -388,8 +468,8 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
388 /* rotation decoding */ 468 /* rotation decoding */
389 if (opts->orientation) 469 if (opts->orientation)
390 { 470 {
391 degree = _get_orientation(map, length); 471 degree = _get_orientation(map, length, flipped);
392 if (degree != 0) 472 if (degree != 0 || *flipped)
393 { 473 {
394 opts->degree = degree; 474 opts->degree = degree;
395 *rotated = EINA_TRUE; 475 *rotated = EINA_TRUE;
@@ -522,29 +602,9 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
522 load_region_w = opts->region.w; 602 load_region_w = opts->region.w;
523 load_region_h = opts->region.h; 603 load_region_h = opts->region.h;
524 604
525 switch (degree) 605 _rotate_region(&opts->region.x, &opts->region.y, &opts->region.w, &opts->region.h,
526 { 606 load_region_x, load_region_y, load_region_w, load_region_h,
527 case 90: 607 *w, *h, degree, *flipped);
528 opts->region.x = load_region_y;
529 opts->region.y = *h - (load_region_x + load_region_w);
530 opts->region.w = load_region_h;
531 opts->region.h = load_region_w;
532 break;
533 case 180:
534 opts->region.x = *w - (load_region_x+ load_region_w);
535 opts->region.y = *h - (load_region_y + load_region_h);
536
537 break;
538 case 270:
539 opts->region.x = *w - (load_region_y + load_region_h);
540 opts->region.y = load_region_x;
541 opts->region.w = load_region_h;
542 opts->region.h = load_region_w;
543 break;
544 default:
545 break;
546 }
547
548 } 608 }
549 RECTS_CLIP_TO_RECT(opts->region.x, opts->region.y, 609 RECTS_CLIP_TO_RECT(opts->region.x, opts->region.y,
550 opts->region.w, opts->region.h, 610 opts->region.w, opts->region.h,
@@ -592,6 +652,88 @@ get_time(void)
592} 652}
593*/ 653*/
594 654
655static void
656_rotate_180(DATA32 *data, int w, int h)
657{
658 DATA32 *p1, *p2;
659 DATA32 pt;
660 int x;
661
662 p1 = data;
663 p2 = data + (h * w) - 1;
664 for (x = (w * h) / 2; --x >= 0;)
665 {
666 pt = *p1;
667 *p1 = *p2;
668 *p2 = pt;
669 p1++;
670 p2--;
671 }
672}
673
674static void
675_flip_horizontal(DATA32 *data, int w, int h)
676{
677 DATA32 *p1, *p2;
678 DATA32 pt;
679 int x, y;
680
681 for (y = 0; y < h; y++)
682 {
683 p1 = data + (y * w);
684 p2 = data + ((y + 1) * w) - 1;
685 for (x = 0; x < (w >> 1); x++)
686 {
687 pt = *p1;
688 *p1 = *p2;
689 *p2 = pt;
690 p1++;
691 p2--;
692 }
693 }
694}
695
696static void
697_flip_vertical(DATA32 *data, int w, int h)
698{
699 DATA32 *p1, *p2;
700 DATA32 pt;
701 int x, y;
702
703 for (y = 0; y < (h >> 1); y++)
704 {
705 p1 = data + (y * w);
706 p2 = data + ((h - 1 - y) * w);
707 for (x = 0; x < w; x++)
708 {
709 pt = *p1;
710 *p1 = *p2;
711 *p2 = pt;
712 p1++;
713 p2++;
714 }
715 }
716}
717
718static void
719_rotate_change_wh(DATA32 *to, DATA32 *from,
720 int w, int h,
721 int dx, int dy)
722{
723 int x, y;
724
725 for (x = h; --x >= 0;)
726 {
727 for (y = w; --y >= 0;)
728 {
729 *to = *from;
730 from++;
731 to += dy;
732 }
733 to += dx;
734 }
735}
736
595static Eina_Bool 737static Eina_Bool
596evas_image_load_file_data_jpeg_internal(Evas_Image_Load_Opts *opts, 738evas_image_load_file_data_jpeg_internal(Evas_Image_Load_Opts *opts,
597 Evas_Image_Property *prop, 739 Evas_Image_Property *prop,
@@ -705,29 +847,9 @@ evas_image_load_file_data_jpeg_internal(Evas_Image_Load_Opts *opts,
705 load_region_w = opts->region.w; 847 load_region_w = opts->region.w;
706 load_region_h = opts->region.h; 848 load_region_h = opts->region.h;
707 849
708 switch (degree) 850 _rotate_region(&opts->region.x, &opts->region.y, &opts->region.w, &opts->region.h,
709 { 851 load_region_x, load_region_y, load_region_w, load_region_h,
710 case 90: 852 w, h, degree, prop->flipped);
711 opts->region.x = load_region_y;
712 opts->region.y = h - (load_region_x + load_region_w);
713 opts->region.w = load_region_h;
714 opts->region.h = load_region_w;
715 break;
716 case 180:
717 opts->region.x = w - (load_region_x+ load_region_w);
718 opts->region.y = h - (load_region_y + load_region_h);
719
720 break;
721 case 270:
722 opts->region.x = w - (load_region_y + load_region_h);
723 opts->region.y = load_region_x;
724 opts->region.w = load_region_h;
725 opts->region.h = load_region_w;
726 break;
727 default:
728 break;
729 }
730
731 } 853 }
732#ifdef BUILD_LOADER_JPEG_REGION 854#ifdef BUILD_LOADER_JPEG_REGION
733 cinfo.region_x = opts->region.x; 855 cinfo.region_x = opts->region.x;
@@ -1076,61 +1198,36 @@ done:
1076 1198
1077 if (prop->rotated) 1199 if (prop->rotated)
1078 { 1200 {
1079 DATA32 *data1, *data2, *to, *from; 1201 DATA32 *to;
1080 int lx, ly, lw, lh, hw; 1202 int hw;
1081 1203
1082 lw = w; 1204 hw = w * h;
1083 lh = h; 1205 to = pixels;
1084 hw = lw * lh;
1085 1206
1086 data1 = pixels; 1207 switch (degree)
1087
1088 if (degree == 180)
1089 { 1208 {
1090 DATA32 tmpd; 1209 case 90:
1091 1210 if (prop->flipped)
1092 data2 = data1 + (lh * lw) -1; 1211 _rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h);
1093 for (lx = (lw * lh) / 2; --lx >= 0;) 1212 else
1094 { 1213 _rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h);
1095 tmpd = *data1; 1214 break;
1096 *data1 = *data2; 1215 case 180:
1097 *data2 = tmpd; 1216 if (prop->flipped)
1098 data1++; 1217 _flip_vertical(to, w, h);
1099 data2--; 1218 else
1100 } 1219 _rotate_180(to, w, h);
1101 } 1220 break;
1102 else 1221 case 270:
1103 { 1222 if (prop->flipped)
1104 data2 = NULL; 1223 _rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h);
1105 to = NULL; 1224 else
1106 if (ptr_rotate) data2 = ptr_rotate; 1225 _rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h);
1107 1226 break;
1108 if (degree == 90) 1227 default:
1109 { 1228 if (prop->flipped)
1110 to = data1 + lh - 1; 1229 _flip_horizontal(to, w, h);
1111 hw = -hw - 1; 1230 break;
1112 }
1113 else if (degree == 270)
1114 {
1115 to = data1 + hw - lh;
1116 lh = -lh;
1117 hw = hw + 1;
1118 }
1119
1120 if (to)
1121 {
1122 from = data2;
1123 for (lx = h; --lx >= 0;)
1124 {
1125 for (ly = w; --ly >= 0;)
1126 {
1127 *to = *from;
1128 from++;
1129 to += lh;
1130 }
1131 to += hw;
1132 }
1133 }
1134 } 1231 }
1135 if (ptr_rotate) 1232 if (ptr_rotate)
1136 { 1233 {
@@ -1317,8 +1414,9 @@ evas_image_load_file_head_jpeg(void *loader_data,
1317 } 1414 }
1318 1415
1319 val = evas_image_load_file_head_jpeg_internal(&prop->w, &prop->h, 1416 val = evas_image_load_file_head_jpeg_internal(&prop->w, &prop->h,
1320 &prop->scale, &prop->rotated, 1417 &prop->scale, &prop->rotated,
1321 opts, 1418 &prop->flipped,
1419 opts,
1322 map, eina_file_size_get(f), 1420 map, eina_file_size_get(f),
1323 error); 1421 error);
1324 1422