summaryrefslogtreecommitdiff
path: root/src/lib/emile
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-03-17 08:50:22 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-03-17 09:58:19 +0100
commitbafe5e9a7485db51d4cc52281fea6af6e7531934 (patch)
treedf150f7e770ab367773a5637dbc183600aec0fd7 /src/lib/emile
parent1a8384cd3c1b75eef39a3c03f6e3879b2e78f947 (diff)
emile: decode GRAY JPEG as GRY8.
Diffstat (limited to 'src/lib/emile')
-rw-r--r--src/lib/emile/emile_image.c225
1 files changed, 196 insertions, 29 deletions
diff --git a/src/lib/emile/emile_image.c b/src/lib/emile/emile_image.c
index ff5cff35e3..9c43e385a4 100644
--- a/src/lib/emile/emile_image.c
+++ b/src/lib/emile/emile_image.c
@@ -1077,6 +1077,88 @@ _rotate_change_wh(uint32_t *to, uint32_t *from,
1077 } 1077 }
1078} 1078}
1079 1079
1080static void
1081_rotate8_180(uint8_t *data, int w, int h)
1082{
1083 uint8_t *p1, *p2;
1084 uint8_t pt;
1085 int x;
1086
1087 p1 = data;
1088 p2 = data + (h * w) - 1;
1089 for (x = (w * h) / 2; --x >= 0;)
1090 {
1091 pt = *p1;
1092 *p1 = *p2;
1093 *p2 = pt;
1094 p1++;
1095 p2--;
1096 }
1097}
1098
1099static void
1100_flip_horizontal8(uint8_t *data, int w, int h)
1101{
1102 uint8_t *p1, *p2;
1103 uint8_t pt;
1104 int x, y;
1105
1106 for (y = 0; y < h; y++)
1107 {
1108 p1 = data + (y * w);
1109 p2 = data + ((y + 1) * w) - 1;
1110 for (x = 0; x < (w >> 1); x++)
1111 {
1112 pt = *p1;
1113 *p1 = *p2;
1114 *p2 = pt;
1115 p1++;
1116 p2--;
1117 }
1118 }
1119}
1120
1121static void
1122_flip_vertical8(uint8_t *data, int w, int h)
1123{
1124 uint8_t *p1, *p2;
1125 uint8_t pt;
1126 int x, y;
1127
1128 for (y = 0; y < (h >> 1); y++)
1129 {
1130 p1 = data + (y * w);
1131 p2 = data + ((h - 1 - y) * w);
1132 for (x = 0; x < w; x++)
1133 {
1134 pt = *p1;
1135 *p1 = *p2;
1136 *p2 = pt;
1137 p1++;
1138 p2++;
1139 }
1140 }
1141}
1142
1143static void
1144_rotate_change_wh8(uint8_t *to, uint8_t *from,
1145 int w, int h,
1146 int dx, int dy)
1147{
1148 int x, y;
1149
1150 for (x = h; --x >= 0;)
1151 {
1152 for (y = w; --y >= 0;)
1153 {
1154 *to = *from;
1155 from++;
1156 to += dy;
1157 }
1158 to += dx;
1159 }
1160}
1161
1080static Eina_Bool 1162static Eina_Bool
1081_emile_jpeg_bind(Emile_Image *image EINA_UNUSED, 1163_emile_jpeg_bind(Emile_Image *image EINA_UNUSED,
1082 Emile_Image_Load_Opts *opts EINA_UNUSED, 1164 Emile_Image_Load_Opts *opts EINA_UNUSED,
@@ -1139,12 +1221,6 @@ _emile_jpeg_head(Emile_Image *image,
1139 return EINA_FALSE; 1221 return EINA_FALSE;
1140 } 1222 }
1141 1223
1142 if (cinfo.output_components == 1)
1143 {
1144 // We do handle GRY8 colorspace as an output for JPEG
1145 prop->cspaces = cspaces_gry;
1146 }
1147
1148 jpeg_read_header(&cinfo, TRUE); 1224 jpeg_read_header(&cinfo, TRUE);
1149 cinfo.do_fancy_upsampling = FALSE; 1225 cinfo.do_fancy_upsampling = FALSE;
1150 cinfo.do_block_smoothing = FALSE; 1226 cinfo.do_block_smoothing = FALSE;
@@ -1153,6 +1229,12 @@ _emile_jpeg_head(Emile_Image *image,
1153 cinfo.buffered_image = TRUE; // buffered mode in case jpg is progressive 1229 cinfo.buffered_image = TRUE; // buffered mode in case jpg is progressive
1154 jpeg_start_decompress(&cinfo); 1230 jpeg_start_decompress(&cinfo);
1155 1231
1232 if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
1233 {
1234 // We do handle GRY8 colorspace as an output for JPEG
1235 prop->cspaces = cspaces_gry;
1236 }
1237
1156 /* rotation decoding */ 1238 /* rotation decoding */
1157 if (opts->orientation) 1239 if (opts->orientation)
1158 { 1240 {
@@ -1332,6 +1414,7 @@ _emile_jpeg_data(Emile_Image *image,
1332 const unsigned char *m = NULL; 1414 const unsigned char *m = NULL;
1333 uint8_t *ptr, *line[16], *data; 1415 uint8_t *ptr, *line[16], *data;
1334 uint32_t *ptr2, *ptr_rotate = NULL; 1416 uint32_t *ptr2, *ptr_rotate = NULL;
1417 uint8_t *ptrg, *ptrg_rotate = NULL;
1335 unsigned int x, y, l, i, scans; 1418 unsigned int x, y, l, i, scans;
1336 int region = 0; 1419 int region = 0;
1337 /* rotation setting */ 1420 /* rotation setting */
@@ -1398,6 +1481,11 @@ _emile_jpeg_data(Emile_Image *image,
1398 case JCS_UNKNOWN: 1481 case JCS_UNKNOWN:
1399 break; 1482 break;
1400 case JCS_GRAYSCALE: 1483 case JCS_GRAYSCALE:
1484 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1485 {
1486 cinfo.out_color_space = JCS_GRAYSCALE;
1487 break;
1488 }
1401 case JCS_RGB: 1489 case JCS_RGB:
1402 case JCS_YCbCr: 1490 case JCS_YCbCr:
1403 cinfo.out_color_space = JCS_RGB; 1491 cinfo.out_color_space = JCS_RGB;
@@ -1485,12 +1573,27 @@ _emile_jpeg_data(Emile_Image *image,
1485 /* } */ 1573 /* } */
1486 } 1574 }
1487 1575
1488 if (!(((cinfo.out_color_space == JCS_RGB) && 1576 switch (prop->cspace)
1489 ((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
1490 ((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
1491 { 1577 {
1492 *error = EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT; 1578 case EMILE_COLORSPACE_GRY8:
1493 goto on_error; 1579 if (!(cinfo.out_color_space == JCS_GRAYSCALE &&
1580 cinfo.output_components == 1))
1581 {
1582 *error = EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT;
1583 goto on_error;
1584 }
1585 break;
1586 case EMILE_COLORSPACE_ARGB8888:
1587 if (!((cinfo.out_color_space == JCS_RGB && cinfo.output_components == 3) ||
1588 (cinfo.out_color_space == JCS_CMYK && cinfo.output_components == 4)))
1589 {
1590 *error = EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT;
1591 goto on_error;
1592 }
1593 break;
1594 default:
1595 *error = EMILE_IMAGE_LOAD_ERROR_GENERIC;
1596 goto on_error;
1494 } 1597 }
1495 1598
1496/* end head decoding */ 1599/* end head decoding */
@@ -1503,13 +1606,24 @@ _emile_jpeg_data(Emile_Image *image,
1503 data = alloca(w * 16 * cinfo.output_components); 1606 data = alloca(w * 16 * cinfo.output_components);
1504 if ((prop->rotated) && change_wh) 1607 if ((prop->rotated) && change_wh)
1505 { 1608 {
1506 ptr2 = malloc(w * h * sizeof(uint32_t)); 1609 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1507 ptr_rotate = ptr2; 1610 {
1611 ptrg = malloc(w * h * sizeof(uint8_t));
1612 ptrg_rotate = ptrg;
1613 }
1614 else
1615 {
1616 ptr2 = malloc(w * h * sizeof(uint32_t));
1617 ptr_rotate = ptr2;
1618 }
1508 } 1619 }
1509 else 1620 else
1510 ptr2 = pixels; 1621 {
1622 ptr2 = pixels;
1623 ptrg = pixels;
1624 }
1511 1625
1512 if (!ptr2) 1626 if (!ptr2 && !ptrg)
1513 { 1627 {
1514 *error = EMILE_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; 1628 *error = EMILE_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
1515 goto on_error; 1629 goto on_error;
@@ -1742,9 +1856,17 @@ _emile_jpeg_data(Emile_Image *image,
1742 { 1856 {
1743 for (x = 0; x < w; x++) 1857 for (x = 0; x < w; x++)
1744 { 1858 {
1745 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]); 1859 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1860 {
1861 *ptrg = ptr[0];
1862 ptrg++;
1863 }
1864 else
1865 {
1866 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
1867 ptr2++;
1868 }
1746 ptr++; 1869 ptr++;
1747 ptr2++;
1748 } 1870 }
1749 } 1871 }
1750 } 1872 }
@@ -1773,9 +1895,17 @@ _emile_jpeg_data(Emile_Image *image,
1773 ptr += opts_region.x; 1895 ptr += opts_region.x;
1774 for (x = 0; x < opts_region.w; x++) 1896 for (x = 0; x < opts_region.w; x++)
1775 { 1897 {
1776 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]); 1898 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1899 {
1900 *ptrg = ptr[0];
1901 ptrg++;
1902 }
1903 else
1904 {
1905 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
1906 ptr2++;
1907 }
1777 ptr++; 1908 ptr++;
1778 ptr2++;
1779 } 1909 }
1780 ptr += w - (opts_region.x + opts_region.w); 1910 ptr += w - (opts_region.x + opts_region.w);
1781 } 1911 }
@@ -1792,34 +1922,71 @@ done:
1792 if (prop->rotated) 1922 if (prop->rotated)
1793 { 1923 {
1794 uint32_t *to; 1924 uint32_t *to;
1925 uint8_t *to8;
1795 int hw; 1926 int hw;
1796 1927
1797 hw = w * h; 1928 hw = w * h;
1798 to = pixels; 1929 to = pixels;
1930 to8 = pixels;
1799 1931
1800 switch (degree) 1932 switch (degree)
1801 { 1933 {
1802 case 90: 1934 case 90:
1803 if (prop->flipped) 1935 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1804 _rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h); 1936 {
1937 if (prop->flipped)
1938 _rotate_change_wh8(to8 + hw - 1, ptrg_rotate, w, h, hw - 1, -h);
1939 else
1940 _rotate_change_wh8(to8 + h - 1, ptrg_rotate, w, h, -hw - 1, h);
1941 }
1805 else 1942 else
1806 _rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h); 1943 {
1944 if (prop->flipped)
1945 _rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h);
1946 else
1947 _rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h);
1948 }
1807 break; 1949 break;
1808 case 180: 1950 case 180:
1809 if (prop->flipped) 1951 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1810 _flip_vertical(to, w, h); 1952 {
1953 if (prop->flipped)
1954 _flip_vertical8(to8, w, h);
1955 else
1956 _rotate8_180(to8, w, h);
1957 }
1811 else 1958 else
1812 _rotate_180(to, w, h); 1959 {
1960 if (prop->flipped)
1961 _flip_vertical(to, w, h);
1962 else
1963 _rotate_180(to, w, h);
1964 }
1813 break; 1965 break;
1814 case 270: 1966 case 270:
1815 if (prop->flipped) 1967 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1816 _rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h); 1968 {
1969 if (prop->flipped)
1970 _rotate_change_wh8(to8, ptrg_rotate, w, h, -hw + 1, h);
1971 else
1972 _rotate_change_wh8(to8 + hw - h, ptrg_rotate, w, h, hw + 1, -h);
1973 }
1817 else 1974 else
1818 _rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h); 1975 {
1976 if (prop->flipped)
1977 _rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h);
1978 else
1979 _rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h);
1980 }
1819 break; 1981 break;
1820 default: 1982 default:
1821 if (prop->flipped) 1983 if (prop->flipped)
1822 _flip_horizontal(to, w, h); 1984 {
1985 if (prop->cspace == EMILE_COLORSPACE_GRY8)
1986 _flip_horizontal8(to8, w, h);
1987 else
1988 _flip_horizontal(to, w, h);
1989 }
1823 break; 1990 break;
1824 } 1991 }
1825 if (ptr_rotate) 1992 if (ptr_rotate)