summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-04-27 19:15:58 +0200
committerCedric BAIL <cedric@osg.samsung.com>2015-04-27 19:18:04 +0200
commitf93cc6fe3b0b3022955f528a154918b6f34be635 (patch)
tree114abdbe3bb6ba543ecf166132d9fc35e38bc227 /src/modules
parent1361775ddffeeadfeba1a7cd399e60ac449cc076 (diff)
evas: fix issue of using two times the same image with different orient in software.
Fixing T2338
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/evas/engines/software_generic/evas_engine.c393
1 files changed, 216 insertions, 177 deletions
diff --git a/src/modules/evas/engines/software_generic/evas_engine.c b/src/modules/evas/engines/software_generic/evas_engine.c
index fa41a5a..dfdcb5c 100644
--- a/src/modules/evas/engines/software_generic/evas_engine.c
+++ b/src/modules/evas/engines/software_generic/evas_engine.c
@@ -1319,128 +1319,80 @@ eng_image_data_put(void *data, void *image, DATA32 *image_data)
1319 return im; 1319 return im;
1320} 1320}
1321 1321
1322static void * 1322static void
1323_image_flip_horizontal(void *data, Image_Entry *im) 1323_image_flip_horizontal(DATA32 *pixels_out, const DATA32 *pixels_in,
1324 int iw, int ih)
1324{ 1325{
1325 unsigned int *p1, *p2, tmp; 1326 const unsigned int *pi1, *pi2;
1326 DATA32 *image_data; 1327 unsigned int *po1, *po2;
1327 int x, y, iw, ih; 1328 int x, y;
1328 Image_Entry *im2;
1329 1329
1330 eng_image_size_get(data, im, &iw, &ih);
1331 im = eng_image_data_get(data, im , 1, &image_data, NULL);
1332 for (y = 0; y < ih; y++) 1330 for (y = 0; y < ih; y++)
1333 { 1331 {
1334 p1 = image_data + (y * iw); 1332 pi1 = pixels_in + (y * iw);
1335 p2 = image_data + ((y + 1) * iw) - 1; 1333 pi2 = pixels_in + ((y + 1) * iw) - 1;
1334 po1 = pixels_out + (y * iw);
1335 po2 = pixels_out + ((y + 1) * iw) - 1;
1336 for (x = 0; x < (iw >> 1); x++) 1336 for (x = 0; x < (iw >> 1); x++)
1337 { 1337 {
1338 tmp = *p1; 1338 *po2 = *pi1;
1339 *p1 = *p2; 1339 *po1 = *pi2;
1340 *p2 = tmp; 1340 pi1++; po1++;
1341 p1++; 1341 pi2--; po2--;
1342 p2--;
1343 } 1342 }
1344 } 1343 }
1345 im2 = eng_image_new_from_data(data, iw, ih, image_data,
1346 eng_image_alpha_get(data, im),
1347 eng_image_colorspace_get(data, im));
1348 im = im2;
1349 return im;
1350} 1344}
1351 1345
1352static void * 1346static void
1353_image_flip_vertical(void *data, Image_Entry *im) 1347_image_flip_vertical(DATA32 *pixels_out, const DATA32 *pixels_in,
1348 int iw, int ih)
1354{ 1349{
1355 unsigned int *p1, *p2, tmp; 1350 const unsigned int *pi1, *pi2;
1356 DATA32 *image_data; 1351 unsigned int *po1, *po2;
1357 int x, y, iw, ih; 1352 int x, y;
1358 Image_Entry *im2;
1359 1353
1360 eng_image_size_get(data, im, &iw, &ih);
1361 im = eng_image_data_get(data, im , 1, &image_data, NULL);
1362 for (y = 0; y < (ih >> 1); y++) 1354 for (y = 0; y < (ih >> 1); y++)
1363 { 1355 {
1364 p1 = image_data + (y * iw); 1356 pi1 = pixels_in + (y * iw);
1365 p2 = image_data + ((ih - 1 - y) * iw); 1357 pi2 = pixels_in + ((ih - 1 - y) * iw);
1358 po1 = pixels_out + (y * iw);
1359 po2 = pixels_out + ((ih - 1 - y) * iw);
1366 for (x = 0; x < iw; x++) 1360 for (x = 0; x < iw; x++)
1367 { 1361 {
1368 tmp = *p1; 1362 *po2 = *pi1;
1369 *p1 = *p2; 1363 *po1 = *pi2;
1370 *p2 = tmp; 1364 pi1++; po1++;
1371 p1++; 1365 pi2++; po2++;
1372 p2++;
1373 } 1366 }
1374 } 1367 }
1375 im2 = eng_image_new_from_data(data, iw, ih, image_data,
1376 eng_image_alpha_get(data, im),
1377 eng_image_colorspace_get(data, im));
1378 im = im2;
1379 return im;
1380} 1368}
1381 1369
1382static void * 1370static void
1383_image_rotate_180(void *data, Image_Entry *im) 1371_image_rotate_180(DATA32 *pixels_out, const DATA32 *pixels_in,
1372 int iw, int ih)
1384{ 1373{
1385 unsigned int *p1, *p2, tmp; 1374 const unsigned int *pi1, *pi2;
1386 DATA32 *image_data; 1375 unsigned int *po1, *po2;
1387 int hw, iw, ih; 1376 int hw;
1388 Image_Entry *im2;
1389 1377
1390 eng_image_size_get(data, im, &iw, &ih);
1391 im = eng_image_data_get(data, im , 1, &image_data, NULL);
1392 if(!image_data) return im;
1393 hw = iw * ih; 1378 hw = iw * ih;
1394 p1 = image_data; 1379 pi1 = pixels_in;
1395 p2 = image_data + hw - 1; 1380 pi2 = pixels_in + hw - 1;
1396 for (; p1 < p2; ) 1381 po1 = pixels_out;
1382 po2 = pixels_out + hw - 1;
1383 for (; pi1 < pi2; )
1397 { 1384 {
1398 tmp = *p1; 1385 *po2 = *pi1;
1399 *p1 = *p2; 1386 *po1 = *pi2;
1400 *p2 = tmp; 1387 pi1++; po1++;
1401 p1++; 1388 pi2--; po2--;
1402 p2--;
1403 } 1389 }
1404 im2 = eng_image_new_from_data(data, iw, ih, image_data,
1405 eng_image_alpha_get(data, im),
1406 eng_image_colorspace_get(data, im));
1407 im = im2;
1408 return im;
1409} 1390}
1410 1391
1411# define GETDAT(neww, newh) \ 1392static void
1412 DATA32 *image_data, *image_data2; \ 1393_image_rotate_90(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih)
1413 int iw, ih, w, h; \
1414 Image_Entry *im2; \
1415 eng_image_size_get(data, im, &iw, &ih); \
1416 im = eng_image_data_get(data, im , 0, &image_data, NULL); \
1417 if (!image_data) return im; \
1418 image_data2 = malloc(iw * ih * sizeof(DATA32) + 1); \
1419 if (!image_data2) { \
1420 return im; \
1421 } \
1422 memcpy(image_data2, image_data, iw * ih * sizeof(DATA32)); \
1423 im = eng_image_new_from_data(data, iw, ih, image_data, \
1424 eng_image_alpha_get(data, im), \
1425 eng_image_colorspace_get(data, im)); \
1426 w = neww; h = newh; \
1427 im = eng_image_data_get(data, im , 1, &image_data, NULL); \
1428
1429# define PUTDAT \
1430 im2 = eng_image_new_from_data(data, w, h, image_data, \
1431 eng_image_alpha_get(data, im), \
1432 eng_image_colorspace_get(data, im)); \
1433 im2 = eng_image_size_set(data, im2, w, h); \
1434 im = im2; \
1435 free(image_data2); \
1436 return im; \
1437
1438static void *
1439_image_rotate_90(void *data, Image_Entry *im)
1440{ 1394{
1441 GETDAT(ih, iw);
1442 int x, y, xx, yy, xx2, yy2; 1395 int x, y, xx, yy, xx2, yy2;
1443 unsigned int *src, *dst;
1444 1396
1445 for (y = 0; y < ih; y += TILE) 1397 for (y = 0; y < ih; y += TILE)
1446 { 1398 {
@@ -1452,26 +1404,26 @@ _image_rotate_90(void *data, Image_Entry *im)
1452 if (xx2 > iw) xx2 = iw; 1404 if (xx2 > iw) xx2 = iw;
1453 for (yy = y; yy < yy2; yy++) 1405 for (yy = y; yy < yy2; yy++)
1454 { 1406 {
1455 src = image_data2 + (yy * iw) + x; 1407 const unsigned int *src;
1456 dst = image_data + (x * w) + (w - yy - 1); 1408 unsigned int *dst;
1409
1410 src = pixels_in + (yy * iw) + x;
1411 dst = pixels_out + (x * ih) + (ih - yy - 1);
1457 for (xx = x; xx < xx2; xx++) 1412 for (xx = x; xx < xx2; xx++)
1458 { 1413 {
1459 *dst = *src; 1414 *dst = *src;
1460 src++; 1415 src++;
1461 dst += w; 1416 dst += ih;
1462 } 1417 }
1463 } 1418 }
1464 } 1419 }
1465 } 1420 }
1466 PUTDAT;
1467} 1421}
1468 1422
1469static void * 1423static void
1470_image_rotate_270(void *data, Image_Entry *im) 1424_image_rotate_270(DATA32 *pixels_out, const DATA32 *pixels_in, int iw, int ih)
1471{ 1425{
1472 GETDAT(ih, iw);
1473 int x, y, xx, yy, xx2, yy2; 1426 int x, y, xx, yy, xx2, yy2;
1474 unsigned int *src, *dst;
1475 1427
1476 for (y = 0; y < ih; y += TILE) 1428 for (y = 0; y < ih; y += TILE)
1477 { 1429 {
@@ -1483,74 +1435,126 @@ _image_rotate_270(void *data, Image_Entry *im)
1483 if (xx2 > iw) xx2 = iw; 1435 if (xx2 > iw) xx2 = iw;
1484 for (yy = y; yy < yy2; yy++) 1436 for (yy = y; yy < yy2; yy++)
1485 { 1437 {
1486 src = image_data2 + (yy * iw) + x; 1438 const unsigned int *src;
1487 dst = image_data + ((h - x - 1) * w) + yy; 1439 unsigned int *dst;
1440
1441 src = pixels_in + (yy * iw) + x;
1442 dst = pixels_out + ((iw - x - 1) * ih) + yy;
1488 for (xx = x; xx < xx2; xx++) 1443 for (xx = x; xx < xx2; xx++)
1489 { 1444 {
1490 *dst = *src; 1445 *dst = *src;
1491 src++; 1446 src++;
1492 dst -= w; 1447 dst -= ih;
1493 } 1448 }
1494 } 1449 }
1495 } 1450 }
1496 } 1451 }
1497 PUTDAT;
1498} 1452}
1499 1453
1500static void * 1454static void
1501_image_flip_transpose(void *data, Image_Entry *im) 1455_image_flip_transpose(DATA32 *pixels_out, const DATA32 *pixels_in,
1456 int iw, int ih)
1502{ 1457{
1503 GETDAT(ih, iw);
1504 int x, y; 1458 int x, y;
1505 unsigned int *src, *dst; 1459 const unsigned int *src;
1506 1460
1507 src = image_data2; 1461 src = pixels_in;
1508 for (y = 0; y < ih; y++) 1462 for (y = 0; y < ih; y++)
1509 { 1463 {
1510 dst = image_data + y; 1464 unsigned int *dst;
1465
1466 dst = pixels_out + y;
1511 for (x = 0; x < iw; x++) 1467 for (x = 0; x < iw; x++)
1512 { 1468 {
1513 *dst = *src; 1469 unsigned int tmp = *src;
1470 *dst = tmp;
1514 src++; 1471 src++;
1515 dst += w; 1472 dst += ih;
1516 } 1473 }
1517 } 1474 }
1518 PUTDAT;
1519} 1475}
1520 1476
1521static void * 1477static void
1522_image_flip_transverse(void *data, Image_Entry *im) 1478_image_flip_transverse(DATA32 *pixels_out, const DATA32 *pixels_in,
1479 int iw, int ih)
1523{ 1480{
1524 GETDAT(ih, iw);
1525 int x, y; 1481 int x, y;
1526 unsigned int *src, *dst; 1482 const unsigned int *src;
1527 1483
1528 src = image_data2 + (iw * ih) - 1; 1484 src = pixels_in + (iw * ih) - 1;
1529 for (y = 0; y < ih; y++) 1485 for (y = 0; y < ih; y++)
1530 { 1486 {
1531 dst = image_data + y; 1487 unsigned int *dst;
1488
1489 dst = pixels_out + y;
1532 for (x = 0; x < iw; x++) 1490 for (x = 0; x < iw; x++)
1533 { 1491 {
1534 *dst = *src; 1492 *dst = *src;
1535 src--; 1493 src--;
1536 dst += w; 1494 dst += ih;
1537 } 1495 }
1538 } 1496 }
1539 PUTDAT;
1540} 1497}
1541 1498
1542#undef GETDAT
1543#undef PUTDAT
1544
1545static void * 1499static void *
1546eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient) 1500eng_image_orient_set(void *data EINA_UNUSED, void *image, Evas_Image_Orient orient)
1547{ 1501{
1548 Image_Entry *im; 1502 Image_Entry *im;
1503 Image_Entry *im_new;
1504 void *pixels_in;
1505 void *pixels_out;
1506 int tw, th;
1507 int w, h;
1549 1508
1550 if (!image) return NULL; 1509 if (!image) return NULL;
1551 im = image; 1510 im = image;
1552 if (im->orient == orient) return im; 1511 if (im->orient == orient) return im;
1553 1512
1513 if (im->orient == EVAS_IMAGE_ORIENT_90 ||
1514 im->orient == EVAS_IMAGE_ORIENT_270 ||
1515 im->orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
1516 im->orient == EVAS_IMAGE_FLIP_TRANSVERSE)
1517 {
1518 tw = im->h;
1519 th = im->w;
1520 }
1521 else
1522 {
1523 th = im->h;
1524 tw = im->w;
1525 }
1526
1527 if (orient == EVAS_IMAGE_ORIENT_90 ||
1528 orient == EVAS_IMAGE_ORIENT_270 ||
1529 orient == EVAS_IMAGE_FLIP_TRANSPOSE ||
1530 orient == EVAS_IMAGE_FLIP_TRANSVERSE)
1531 {
1532 w = th;
1533 h = tw;
1534 }
1535 else
1536 {
1537 h = th;
1538 w = tw;
1539 }
1540
1541 im_new = evas_cache_image_copied_data(evas_common_image_cache_get(),
1542 w, h, NULL, im->flags.alpha,
1543 EVAS_COLORSPACE_ARGB8888);
1544 if (!im_new) return im;
1545
1546#if EVAS_CSERVE2
1547 if (evas_cserve2_use_get() && evas_cache2_image_cached(im))
1548 evas_cache2_image_load_data(im);
1549 else
1550#endif
1551 evas_cache_image_load_data(im);
1552
1553 pixels_in = evas_cache_image_pixels(im);
1554 pixels_out = evas_cache_image_pixels(im_new);
1555
1556 if (!pixels_out || !pixels_in) goto on_error;
1557
1554 if ((im->orient >= EVAS_IMAGE_ORIENT_0) && 1558 if ((im->orient >= EVAS_IMAGE_ORIENT_0) &&
1555 (im->orient <= EVAS_IMAGE_ORIENT_270) && 1559 (im->orient <= EVAS_IMAGE_ORIENT_270) &&
1556 (orient >= EVAS_IMAGE_ORIENT_0) && 1560 (orient >= EVAS_IMAGE_ORIENT_0) &&
@@ -1562,23 +1566,20 @@ eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient)
1562 switch (rot_delta) 1566 switch (rot_delta)
1563 { 1567 {
1564 case EVAS_IMAGE_ORIENT_0: 1568 case EVAS_IMAGE_ORIENT_0:
1565 ERR("You shouldn't get this message, wrong orient value"); 1569 ERR("You shouldn't get this message, wrong orient value");
1566 break; 1570 goto on_error;
1567 case EVAS_IMAGE_ORIENT_90: 1571 case EVAS_IMAGE_ORIENT_90:
1568 im = _image_rotate_90(data, im); 1572 _image_rotate_90(pixels_out, pixels_in, im->w, im->h);
1569 im->orient = orient; 1573 break;
1570 break;
1571 case EVAS_IMAGE_ORIENT_180: 1574 case EVAS_IMAGE_ORIENT_180:
1572 im = _image_rotate_180(data, im); 1575 _image_rotate_180(pixels_out, pixels_in, im->w, im->h);
1573 im->orient = orient; 1576 break;
1574 break;
1575 case EVAS_IMAGE_ORIENT_270: 1577 case EVAS_IMAGE_ORIENT_270:
1576 im = _image_rotate_270(data, im); 1578 _image_rotate_270(pixels_out, pixels_in, im->w, im->h);
1577 im->orient = orient; 1579 break;
1578 break;
1579 default: 1580 default:
1580 ERR("Wrong orient value"); 1581 ERR("Wrong orient value");
1581 break; 1582 goto on_error;
1582 } 1583 }
1583 } 1584 }
1584 else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) && 1585 else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) &&
@@ -1587,8 +1588,7 @@ eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient)
1587 (orient == EVAS_IMAGE_ORIENT_NONE))) 1588 (orient == EVAS_IMAGE_ORIENT_NONE)))
1588 { 1589 {
1589 // flip horizontally to get the new orientation 1590 // flip horizontally to get the new orientation
1590 im = _image_flip_horizontal(data, im); 1591 _image_flip_horizontal(pixels_out, pixels_in, im->w, im->h);
1591 im->orient = orient;
1592 } 1592 }
1593 else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) && 1593 else if (((im->orient == EVAS_IMAGE_ORIENT_NONE) &&
1594 (orient == EVAS_IMAGE_FLIP_VERTICAL)) || 1594 (orient == EVAS_IMAGE_FLIP_VERTICAL)) ||
@@ -1596,51 +1596,90 @@ eng_image_orient_set(void *data, void *image, Evas_Image_Orient orient)
1596 (orient == EVAS_IMAGE_ORIENT_NONE))) 1596 (orient == EVAS_IMAGE_ORIENT_NONE)))
1597 { 1597 {
1598 // flip vertically to get the new orientation 1598 // flip vertically to get the new orientation
1599 im = _image_flip_vertical(data, im); 1599 _image_flip_vertical(pixels_out, pixels_in, im->w, im->h);
1600 im->orient = orient;
1601 } 1600 }
1602 else 1601 else
1603 { 1602 {
1604 // generic solution - undo the previous orientation and then apply the 1603 // generic solution - undo the previous orientation and then apply the
1605 // new one after that 1604 // new one after that
1606 int i; 1605 void *pixels_tmp;
1607 1606
1608 for (i = 0; i < 2; i++) 1607 pixels_tmp = malloc(sizeof (unsigned int) * w * h);
1608 if (!pixels_tmp) goto on_error;
1609
1610 // Undoing previous rotation
1611 switch (im->orient)
1609 { 1612 {
1610 switch (im->orient) 1613 case EVAS_IMAGE_ORIENT_0:
1611 { 1614 // FIXME: could be easily optimized away
1612 case EVAS_IMAGE_ORIENT_0: 1615 memcpy(pixels_tmp, pixels_in, sizeof (unsigned int) * w * h);
1613 break; 1616 break;
1614 case EVAS_IMAGE_ORIENT_90: 1617 case EVAS_IMAGE_ORIENT_90:
1615 if(i == 1) im = _image_rotate_90(data, im); 1618 _image_rotate_270(pixels_tmp, pixels_in, im->w, im->h);
1616 else im = _image_rotate_270(data, im); 1619 break;
1617 break; 1620 case EVAS_IMAGE_ORIENT_180:
1618 case EVAS_IMAGE_ORIENT_180: 1621 _image_rotate_180(pixels_tmp, pixels_in, im->w, im->h);
1619 im = _image_rotate_180(data, im); 1622 break;
1620 break; 1623 case EVAS_IMAGE_ORIENT_270:
1621 case EVAS_IMAGE_ORIENT_270: 1624 _image_rotate_90(pixels_tmp, pixels_in, im->w, im->h);
1622 if(i == 1) im = _image_rotate_270(data, im); 1625 break;
1623 else im = _image_rotate_90(data, im); 1626 case EVAS_IMAGE_FLIP_HORIZONTAL:
1624 break; 1627 _image_flip_horizontal(pixels_tmp, pixels_in, im->w, im->h);
1625 case EVAS_IMAGE_FLIP_HORIZONTAL: 1628 break;
1626 im = _image_flip_horizontal(data, im); 1629 case EVAS_IMAGE_FLIP_VERTICAL:
1627 break; 1630 _image_flip_vertical(pixels_tmp, pixels_in, im->w, im->h);
1628 case EVAS_IMAGE_FLIP_VERTICAL: 1631 break;
1629 im = _image_flip_vertical(data, im); 1632 case EVAS_IMAGE_FLIP_TRANSPOSE:
1630 break; 1633 _image_flip_transpose(pixels_tmp, pixels_in, im->w, im->h);
1631 case EVAS_IMAGE_FLIP_TRANSPOSE: 1634 break;
1632 im = _image_flip_transpose(data, im); 1635 case EVAS_IMAGE_FLIP_TRANSVERSE:
1633 break; 1636 _image_flip_transverse(pixels_tmp, pixels_in, im->w, im->h);
1634 case EVAS_IMAGE_FLIP_TRANSVERSE: 1637 break;
1635 im = _image_flip_transverse(data, im); 1638 default:
1636 break; 1639 ERR("Wrong orient value");
1637 default: 1640 goto on_error;
1638 ERR("Wrong orient value"); 1641 }
1639 break; 1642
1640 } 1643 // Doing the new requested one
1641 im->orient = orient; 1644 switch (orient)
1645 {
1646 case EVAS_IMAGE_ORIENT_0:
1647 // FIXME: could be easily optimized away
1648 memcpy(pixels_out, pixels_tmp, sizeof (unsigned int) * w * h);
1649 break;
1650 case EVAS_IMAGE_ORIENT_90:
1651 _image_rotate_90(pixels_out, pixels_tmp, tw, th);
1652 break;
1653 case EVAS_IMAGE_ORIENT_180:
1654 _image_rotate_180(pixels_out, pixels_tmp, tw, th);
1655 break;
1656 case EVAS_IMAGE_ORIENT_270:
1657 _image_rotate_270(pixels_out, pixels_tmp, tw, th);
1658 break;
1659 case EVAS_IMAGE_FLIP_HORIZONTAL:
1660 _image_flip_horizontal(pixels_out, pixels_tmp, tw, th);
1661 break;
1662 case EVAS_IMAGE_FLIP_VERTICAL:
1663 _image_flip_vertical(pixels_out, pixels_tmp, tw, th);
1664 break;
1665 case EVAS_IMAGE_FLIP_TRANSPOSE:
1666 _image_flip_transpose(pixels_out, pixels_tmp, tw, th);
1667 break;
1668 case EVAS_IMAGE_FLIP_TRANSVERSE:
1669 _image_flip_transverse(pixels_out, pixels_tmp, tw, th);
1670 break;
1642 } 1671 }
1672
1673 free(pixels_tmp);
1643 } 1674 }
1675
1676 im_new->orient = orient;
1677 evas_cache_image_drop(im);
1678
1679 return im_new;
1680
1681 on_error:
1682 evas_cache_image_drop(im_new);
1644 return im; 1683 return im;
1645} 1684}
1646 1685