summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/jpeg.c515
1 files changed, 374 insertions, 141 deletions
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index 408f5d1ea1..28c7aebbe8 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -1389,26 +1389,30 @@ INLINE int huff_decode_ac(struct bitstream* bs, struct derived_tbl* tbl)
1389} 1389}
1390 1390
1391 1391
1392/* a JPEG decoder specialized in decoding only the luminance (b&w) */ 1392#ifdef HAVE_LCD_COLOR
1393int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale, 1393
1394 void (*pf_progress)(int current, int total)) 1394/* JPEG decoder variant for YUV decoding, into 3 different planes */
1395/* Note: it keeps the original color subsampling, even if resized. */
1396int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1397 int downscale, void (*pf_progress)(int current, int total))
1395{ 1398{
1396 struct bitstream bs; /* bitstream "object" */ 1399 struct bitstream bs; /* bitstream "object" */
1397 static int block[64]; /* decoded DCT coefficients */ 1400 static int block[64]; /* decoded DCT coefficients */
1398 1401
1399 int width, height; 1402 int width, height;
1400 int skip_line; /* bytes from one line to the next (skip_line) */ 1403 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1401 int skip_strip, skip_mcu; /* bytes to next DCT row / column */ 1404 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1402 1405
1403 int x, y; /* loop counter */ 1406 int i, x, y; /* loop counter */
1404 1407
1405 unsigned char* p_byte; /* bitmap pointer */ 1408 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1409 unsigned char* p_byte[3]; /* bitmap pointer */
1406 1410
1407 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */ 1411 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1408 int k_need; /* AC coefficients needed up to here */ 1412 int k_need; /* AC coefficients needed up to here */
1409 int zero_need; /* init the block with this many zeros */ 1413 int zero_need; /* init the block with this many zeros */
1410 1414
1411 int last_dc_val = 0; 1415 int last_dc_val[3] = {0, 0, 0}; // or 128 for chroma?
1412 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */ 1416 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1413 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */ 1417 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1414 1418
@@ -1446,9 +1450,13 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1446 1450
1447 width = p_jpeg->x_phys / downscale; 1451 width = p_jpeg->x_phys / downscale;
1448 height = p_jpeg->y_phys / downscale; 1452 height = p_jpeg->y_phys / downscale;
1449 skip_line = width; 1453 for (i=0; i<3; i++) /* calculate some strides */
1450 skip_strip = skip_line * (height / p_jpeg->y_mbl); 1454 {
1451 skip_mcu = (width/p_jpeg->x_mbl); 1455 skip_line[i] = width / p_jpeg->subsample_x[i];
1456 skip_strip[i] = skip_line[i]
1457 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1458 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1459 }
1452 1460
1453 /* prepare offsets about where to store the different blocks */ 1461 /* prepare offsets about where to store the different blocks */
1454 store_offs[p_jpeg->store_pos[0]] = 0; 1462 store_offs[p_jpeg->store_pos[0]] = 0;
@@ -1458,8 +1466,11 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1458 1466
1459 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++) 1467 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1460 { 1468 {
1461 p_byte = p_pixel; 1469 for (i=0; i<3; i++) // scan line init
1462 p_pixel += skip_strip; 1470 {
1471 p_byte[i] = p_line[i];
1472 p_line[i] += skip_strip[i];
1473 }
1463 for (x=0; x<p_jpeg->x_mbl; x++) 1474 for (x=0; x<p_jpeg->x_mbl; x++)
1464 { 1475 {
1465 int blkn; 1476 int blkn;
@@ -1477,39 +1488,36 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1477 /* Section F.2.2.1: decode the DC coefficient difference */ 1488 /* Section F.2.2.1: decode the DC coefficient difference */
1478 s = huff_decode_dc(&bs, dctbl); 1489 s = huff_decode_dc(&bs, dctbl);
1479 1490
1480 if (ci == 0) /* only for Y component */ 1491 last_dc_val[ci] += s;
1481 { 1492 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1482 last_dc_val += s;
1483 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1484 1493
1485 /* coefficient buffer must be cleared */ 1494 /* coefficient buffer must be cleared */
1486 MEMSET(block+1, 0, zero_need*sizeof(block[0])); 1495 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1487 1496
1488 /* Section F.2.2.2: decode the AC coefficients */ 1497 /* Section F.2.2.2: decode the AC coefficients */
1489 for (; k < k_need; k++) 1498 for (; k < k_need; k++)
1490 { 1499 {
1491 s = huff_decode_ac(&bs, actbl); 1500 s = huff_decode_ac(&bs, actbl);
1492 r = s >> 4; 1501 r = s >> 4;
1493 s &= 15; 1502 s &= 15;
1494 1503
1495 if (s) 1504 if (s)
1496 { 1505 {
1497 k += r; 1506 k += r;
1498 check_bit_buffer(&bs, s); 1507 check_bit_buffer(&bs, s);
1499 r = get_bits(&bs, s); 1508 r = get_bits(&bs, s);
1500 block[zag[k]] = HUFF_EXTEND(r, s); 1509 block[zag[k]] = HUFF_EXTEND(r, s);
1501 } 1510 }
1502 else 1511 else
1512 {
1513 if (r != 15)
1503 { 1514 {
1504 if (r != 15) 1515 k = 64;
1505 { 1516 break;
1506 k = 64;
1507 break;
1508 }
1509 k += r;
1510 } 1517 }
1511 } /* for k */ 1518 k += r;
1512 } 1519 }
1520 } /* for k */
1513 /* In this path we just discard the values */ 1521 /* In this path we just discard the values */
1514 for (; k < 64; k++) 1522 for (; k < 64; k++)
1515 { 1523 {
@@ -1532,17 +1540,25 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1532 } /* for k */ 1540 } /* for k */
1533 1541
1534 if (ci == 0) 1542 if (ci == 0)
1535 { /* only for Y component */ 1543 { /* Y component needs to bother about block store */
1536 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti], 1544 pf_idct(p_byte[0]+store_offs[blkn], block,
1537 skip_line); 1545 p_jpeg->qt_idct[ti], skip_line[0]);
1546 }
1547 else
1548 { /* chroma */
1549 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1550 skip_line[ci]);
1538 } 1551 }
1539 } /* for blkn */ 1552 } /* for blkn */
1540 p_byte += skip_mcu; 1553 p_byte[0] += skip_mcu[0]; // unrolled for (i=0; i<3; i++) loop
1554 p_byte[1] += skip_mcu[1];
1555 p_byte[2] += skip_mcu[2];
1541 if (p_jpeg->restart_interval && --restart == 0) 1556 if (p_jpeg->restart_interval && --restart == 0)
1542 { /* if a restart marker is due: */ 1557 { /* if a restart marker is due: */
1543 restart = p_jpeg->restart_interval; /* count again */ 1558 restart = p_jpeg->restart_interval; /* count again */
1544 search_restart(&bs); /* align the bitstream */ 1559 search_restart(&bs); /* align the bitstream */
1545 last_dc_val = 0; /* reset decoder */ 1560 last_dc_val[0] = last_dc_val[1] =
1561 last_dc_val[2] = 0; /* reset decoder */
1546 } 1562 }
1547 } /* for x */ 1563 } /* for x */
1548 if (pf_progress != NULL) 1564 if (pf_progress != NULL)
@@ -1551,32 +1567,29 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1551 1567
1552 return 0; /* success */ 1568 return 0; /* success */
1553} 1569}
1570#else /* !HAVE_LCD_COLOR */
1554 1571
1555 1572/* a JPEG decoder specialized in decoding only the luminance (b&w) */
1556#ifdef HAVE_LCD_COLOR 1573int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
1557 1574 void (*pf_progress)(int current, int total))
1558/* JPEG decoder variant for YUV decoding, into 3 different planes */
1559/* Note: it keeps the original color subsampling, even if resized. */
1560int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1561 int downscale, void (*pf_progress)(int current, int total))
1562{ 1575{
1563 struct bitstream bs; /* bitstream "object" */ 1576 struct bitstream bs; /* bitstream "object" */
1564 static int block[64]; /* decoded DCT coefficients */ 1577 static int block[64]; /* decoded DCT coefficients */
1565 1578
1566 int width, height; 1579 int width, height;
1567 int skip_line[3]; /* bytes from one line to the next (skip_line) */ 1580 int skip_line; /* bytes from one line to the next (skip_line) */
1568 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */ 1581 int skip_strip, skip_mcu; /* bytes to next DCT row / column */
1569 1582
1570 int i, x, y; /* loop counter */ 1583 int x, y; /* loop counter */
1571 1584
1572 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]}; 1585 unsigned char* p_line = p_pixel[0];
1573 unsigned char* p_byte[3]; /* bitmap pointer */ 1586 unsigned char* p_byte; /* bitmap pointer */
1574 1587
1575 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */ 1588 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1576 int k_need; /* AC coefficients needed up to here */ 1589 int k_need; /* AC coefficients needed up to here */
1577 int zero_need; /* init the block with this many zeros */ 1590 int zero_need; /* init the block with this many zeros */
1578 1591
1579 int last_dc_val[3] = {0, 0, 0}; // or 128 for chroma? 1592 int last_dc_val = 0;
1580 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */ 1593 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1581 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */ 1594 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1582 1595
@@ -1614,13 +1627,9 @@ int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1614 1627
1615 width = p_jpeg->x_phys / downscale; 1628 width = p_jpeg->x_phys / downscale;
1616 height = p_jpeg->y_phys / downscale; 1629 height = p_jpeg->y_phys / downscale;
1617 for (i=0; i<3; i++) /* calculate some strides */ 1630 skip_line = width;
1618 { 1631 skip_strip = skip_line * (height / p_jpeg->y_mbl);
1619 skip_line[i] = width / p_jpeg->subsample_x[i]; 1632 skip_mcu = (width/p_jpeg->x_mbl);
1620 skip_strip[i] = skip_line[i]
1621 * (height / p_jpeg->y_mbl) / p_jpeg->subsample_y[i];
1622 skip_mcu[i] = width/p_jpeg->x_mbl / p_jpeg->subsample_x[i];
1623 }
1624 1633
1625 /* prepare offsets about where to store the different blocks */ 1634 /* prepare offsets about where to store the different blocks */
1626 store_offs[p_jpeg->store_pos[0]] = 0; 1635 store_offs[p_jpeg->store_pos[0]] = 0;
@@ -1630,11 +1639,8 @@ int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1630 1639
1631 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++) 1640 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1632 { 1641 {
1633 for (i=0; i<3; i++) // scan line init 1642 p_byte = p_line;
1634 { 1643 p_line += skip_strip;
1635 p_byte[i] = p_line[i];
1636 p_line[i] += skip_strip[i];
1637 }
1638 for (x=0; x<p_jpeg->x_mbl; x++) 1644 for (x=0; x<p_jpeg->x_mbl; x++)
1639 { 1645 {
1640 int blkn; 1646 int blkn;
@@ -1652,36 +1658,39 @@ int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1652 /* Section F.2.2.1: decode the DC coefficient difference */ 1658 /* Section F.2.2.1: decode the DC coefficient difference */
1653 s = huff_decode_dc(&bs, dctbl); 1659 s = huff_decode_dc(&bs, dctbl);
1654 1660
1655 last_dc_val[ci] += s; 1661 if (ci == 0) /* only for Y component */
1656 block[0] = last_dc_val[ci]; /* output it (assumes zag[0] = 0) */
1657
1658 /* coefficient buffer must be cleared */
1659 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1660
1661 /* Section F.2.2.2: decode the AC coefficients */
1662 for (; k < k_need; k++)
1663 { 1662 {
1664 s = huff_decode_ac(&bs, actbl); 1663 last_dc_val += s;
1665 r = s >> 4; 1664 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1666 s &= 15;
1667 1665
1668 if (s) 1666 /* coefficient buffer must be cleared */
1669 { 1667 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1670 k += r; 1668
1671 check_bit_buffer(&bs, s); 1669 /* Section F.2.2.2: decode the AC coefficients */
1672 r = get_bits(&bs, s); 1670 for (; k < k_need; k++)
1673 block[zag[k]] = HUFF_EXTEND(r, s);
1674 }
1675 else
1676 { 1671 {
1677 if (r != 15) 1672 s = huff_decode_ac(&bs, actbl);
1673 r = s >> 4;
1674 s &= 15;
1675
1676 if (s)
1678 { 1677 {
1679 k = 64; 1678 k += r;
1680 break; 1679 check_bit_buffer(&bs, s);
1680 r = get_bits(&bs, s);
1681 block[zag[k]] = HUFF_EXTEND(r, s);
1681 } 1682 }
1682 k += r; 1683 else
1683 } 1684 {
1684 } /* for k */ 1685 if (r != 15)
1686 {
1687 k = 64;
1688 break;
1689 }
1690 k += r;
1691 }
1692 } /* for k */
1693 }
1685 /* In this path we just discard the values */ 1694 /* In this path we just discard the values */
1686 for (; k < 64; k++) 1695 for (; k < 64; k++)
1687 { 1696 {
@@ -1704,25 +1713,17 @@ int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1704 } /* for k */ 1713 } /* for k */
1705 1714
1706 if (ci == 0) 1715 if (ci == 0)
1707 { /* Y component needs to bother about block store */ 1716 { /* only for Y component */
1708 pf_idct(p_byte[0]+store_offs[blkn], block, 1717 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1709 p_jpeg->qt_idct[ti], skip_line[0]); 1718 skip_line);
1710 }
1711 else
1712 { /* chroma */
1713 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1714 skip_line[ci]);
1715 } 1719 }
1716 } /* for blkn */ 1720 } /* for blkn */
1717 p_byte[0] += skip_mcu[0]; // unrolled for (i=0; i<3; i++) loop 1721 p_byte += skip_mcu;
1718 p_byte[1] += skip_mcu[1];
1719 p_byte[2] += skip_mcu[2];
1720 if (p_jpeg->restart_interval && --restart == 0) 1722 if (p_jpeg->restart_interval && --restart == 0)
1721 { /* if a restart marker is due: */ 1723 { /* if a restart marker is due: */
1722 restart = p_jpeg->restart_interval; /* count again */ 1724 restart = p_jpeg->restart_interval; /* count again */
1723 search_restart(&bs); /* align the bitstream */ 1725 search_restart(&bs); /* align the bitstream */
1724 last_dc_val[0] = last_dc_val[1] = 1726 last_dc_val = 0; /* reset decoder */
1725 last_dc_val[2] = 0; /* reset decoder */
1726 } 1727 }
1727 } /* for x */ 1728 } /* for x */
1728 if (pf_progress != NULL) 1729 if (pf_progress != NULL)
@@ -1731,8 +1732,7 @@ int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1731 1732
1732 return 0; /* success */ 1733 return 0; /* success */
1733} 1734}
1734 1735#endif /* !HAVE_LCD_COLOR */
1735#endif /* #ifdef HAVE_LCD_COLOR */
1736 1736
1737/**************** end JPEG code ********************/ 1737/**************** end JPEG code ********************/
1738 1738
@@ -1745,7 +1745,12 @@ int jpeg_decode_color(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
1745 1745
1746struct t_disp 1746struct t_disp
1747{ 1747{
1748 unsigned char* bitmap; 1748#ifdef HAVE_LCD_COLOR
1749 unsigned char* bitmap[3]; /* Y, Cr, Cb */
1750 int csub_x, csub_y;
1751#else
1752 unsigned char* bitmap[1]; /* Y only */
1753#endif
1749 int width; 1754 int width;
1750 int height; 1755 int height;
1751 int stride; 1756 int stride;
@@ -1767,6 +1772,151 @@ int root_size;
1767 1772
1768/************************* Implementation ***************************/ 1773/************************* Implementation ***************************/
1769 1774
1775#ifdef HAVE_LCD_COLOR
1776
1777#if (LCD_DEPTH == 16) && \
1778 ((LCD_PIXELFORMAT == RGB565) || (LCD_PIXELFORMAT == RGB565SWAPPED))
1779#define RYFAC (31*257)
1780#define GYFAC (63*257)
1781#define BYFAC (31*257)
1782#define RVFAC 11170 /* 31 * 257 * 1.402 */
1783#define GVFAC (-11563) /* 63 * 257 * -0.714136 */
1784#define GUFAC (-5572) /* 63 * 257 * -0.344136 */
1785#define BUFAC 14118 /* 31 * 257 * 1.772 */
1786#endif
1787
1788/* Draw a partial YUV colour bitmap */
1789void yuv_bitmap_part(unsigned char *src[3], int csub_x, int csub_y,
1790 int src_x, int src_y, int stride,
1791 int x, int y, int width, int height)
1792{
1793 fb_data *dst, *dst_end;
1794
1795 /* nothing to draw? */
1796 if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT)
1797 || (x + width <= 0) || (y + height <= 0))
1798 return;
1799
1800 /* clipping */
1801 if (x < 0)
1802 {
1803 width += x;
1804 src_x -= x;
1805 x = 0;
1806 }
1807 if (y < 0)
1808 {
1809 height += y;
1810 src_y -= y;
1811 y = 0;
1812 }
1813 if (x + width > LCD_WIDTH)
1814 width = LCD_WIDTH - x;
1815 if (y + height > LCD_HEIGHT)
1816 height = LCD_HEIGHT - y;
1817
1818 dst = rb->lcd_framebuffer + LCD_WIDTH * y + x;
1819 dst_end = dst + LCD_WIDTH * height;
1820
1821 do
1822 {
1823 fb_data *dst_row = dst;
1824 fb_data *row_end = dst_row + width;
1825 const unsigned char *ysrc = src[0] + stride * src_y + src_x;
1826 int y, u, v;
1827 int red, green, blue;
1828 unsigned rbits, gbits, bbits;
1829
1830 if (csub_y) /* colour */
1831 {
1832 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
1833 const unsigned char *usrc = src[1] + (stride/csub_x) * (src_y/csub_y)
1834 + (src_x/csub_x);
1835 const unsigned char *vsrc = src[2] + (stride/csub_x) * (src_y/csub_y)
1836 + (src_x/csub_x);
1837 int xphase = src_x % csub_x;
1838 int rc, gc, bc;
1839
1840 u = *usrc++ - 128;
1841 v = *vsrc++ - 128;
1842 rc = RVFAC * v + 32639;
1843 gc = GVFAC * v + GUFAC * u + 32639;
1844 bc = BUFAC * u + 32639;
1845
1846 do
1847 {
1848 y = *ysrc++;
1849 red = RYFAC * y + rc;
1850 green = GYFAC * y + gc;
1851 blue = BYFAC * y + bc;
1852
1853 if ((unsigned)red > (RYFAC*255+32639))
1854 {
1855 if (red < 0)
1856 red = 0;
1857 else
1858 red = (RYFAC*255+32639);
1859 }
1860 if ((unsigned)green > (GYFAC*255+32639))
1861 {
1862 if (green < 0)
1863 green = 0;
1864 else
1865 green = (GYFAC*255+32639);
1866 }
1867 if ((unsigned)blue > (BYFAC*255+32639))
1868 {
1869 if (blue < 0)
1870 blue = 0;
1871 else
1872 blue = (BYFAC*255+32639);
1873 }
1874 rbits = ((unsigned)red) >> 16 ;
1875 gbits = ((unsigned)green) >> 16 ;
1876 bbits = ((unsigned)blue) >> 16 ;
1877#if LCD_PIXELFORMAT == RGB565
1878 *dst_row++ = (rbits << 11) | (gbits << 5) | bbits;
1879#elif LCD_PIXELFORMAT == RGB565SWAPPED
1880 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | bbits);
1881#endif
1882
1883 if (++xphase >= csub_x)
1884 {
1885 u = *usrc++ - 128;
1886 v = *vsrc++ - 128;
1887 rc = RVFAC * v + 32639;
1888 gc = GVFAC * v + GUFAC * u + 32639;
1889 bc = BUFAC * u + 32639;
1890 xphase = 0;
1891 }
1892 }
1893 while (dst_row < row_end);
1894 }
1895 else /* monochrome */
1896 {
1897 do
1898 {
1899 y = *ysrc++;
1900 red = RYFAC * y + 32639; /* blue == red */
1901 green = GYFAC * y + 32639;
1902 rbits = ((unsigned)red) >> 16;
1903 gbits = ((unsigned)green) >> 16;
1904#if LCD_PIXELFORMAT == RGB565
1905 *dst_row++ = (rbits << 11) | (gbits << 5) | rbits;
1906#elif LCD_PIXELFORMAT == RGB565SWAPPED
1907 *dst_row++ = swap16((rbits << 11) | (gbits << 5) | rbits);
1908#endif
1909 }
1910 while (dst_row < row_end);
1911 }
1912
1913 src_y++;
1914 dst += LCD_WIDTH;
1915 }
1916 while (dst < dst_end);
1917}
1918#endif
1919
1770/* switch off overlay, for handling SYS_ events */ 1920/* switch off overlay, for handling SYS_ events */
1771void cleanup(void *parameter) 1921void cleanup(void *parameter)
1772{ 1922{
@@ -1806,10 +1956,18 @@ int scroll_bmp(struct t_disp* pdisp)
1806 { 1956 {
1807 MYXLCD(scroll_right)(move); /* scroll right */ 1957 MYXLCD(scroll_right)(move); /* scroll right */
1808 pdisp->x -= move; 1958 pdisp->x -= move;
1959#ifdef HAVE_LCD_COLOR
1960 yuv_bitmap_part(
1961 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
1962 pdisp->x, pdisp->y, pdisp->stride,
1963 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
1964 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
1965#else
1809 MYXLCD(gray_bitmap_part)( 1966 MYXLCD(gray_bitmap_part)(
1810 pdisp->bitmap, pdisp->x, pdisp->y, pdisp->stride, 1967 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
1811 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ 1968 0, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
1812 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ 1969 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
1970#endif
1813 MYLCD_UPDATE(); 1971 MYLCD_UPDATE();
1814 } 1972 }
1815 break; 1973 break;
@@ -1821,11 +1979,19 @@ int scroll_bmp(struct t_disp* pdisp)
1821 { 1979 {
1822 MYXLCD(scroll_left)(move); /* scroll left */ 1980 MYXLCD(scroll_left)(move); /* scroll left */
1823 pdisp->x += move; 1981 pdisp->x += move;
1982#ifdef HAVE_LCD_COLOR
1983 yuv_bitmap_part(
1984 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
1985 pdisp->x + LCD_WIDTH - move, pdisp->y, pdisp->stride,
1986 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
1987 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
1988#else
1824 MYXLCD(gray_bitmap_part)( 1989 MYXLCD(gray_bitmap_part)(
1825 pdisp->bitmap, pdisp->x + LCD_WIDTH - move, 1990 pdisp->bitmap[0], pdisp->x + LCD_WIDTH - move,
1826 pdisp->y, pdisp->stride, 1991 pdisp->y, pdisp->stride,
1827 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */ 1992 LCD_WIDTH - move, MAX(0, (LCD_HEIGHT-pdisp->height)/2), /* x, y */
1828 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */ 1993 move, MIN(LCD_HEIGHT, pdisp->height)); /* w, h */
1994#endif
1829 MYLCD_UPDATE(); 1995 MYLCD_UPDATE();
1830 } 1996 }
1831 break; 1997 break;
@@ -1837,10 +2003,18 @@ int scroll_bmp(struct t_disp* pdisp)
1837 { 2003 {
1838 MYXLCD(scroll_down)(move); /* scroll down */ 2004 MYXLCD(scroll_down)(move); /* scroll down */
1839 pdisp->y -= move; 2005 pdisp->y -= move;
2006#ifdef HAVE_LCD_COLOR
2007 yuv_bitmap_part(
2008 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y,
2009 pdisp->x, pdisp->y, pdisp->stride,
2010 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
2011 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2012#else
1840 MYXLCD(gray_bitmap_part)( 2013 MYXLCD(gray_bitmap_part)(
1841 pdisp->bitmap, pdisp->x, pdisp->y, pdisp->stride, 2014 pdisp->bitmap[0], pdisp->x, pdisp->y, pdisp->stride,
1842 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */ 2015 MAX(0, (LCD_WIDTH-pdisp->width)/2), 0, /* x, y */
1843 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ 2016 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2017#endif
1844 MYLCD_UPDATE(); 2018 MYLCD_UPDATE();
1845 } 2019 }
1846 break; 2020 break;
@@ -1852,11 +2026,19 @@ int scroll_bmp(struct t_disp* pdisp)
1852 { 2026 {
1853 MYXLCD(scroll_up)(move); /* scroll up */ 2027 MYXLCD(scroll_up)(move); /* scroll up */
1854 pdisp->y += move; 2028 pdisp->y += move;
2029#ifdef HAVE_LCD_COLOR
2030 yuv_bitmap_part(
2031 pdisp->bitmap, pdisp->csub_x, pdisp->csub_y, pdisp->x,
2032 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
2033 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
2034 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2035#else
1855 MYXLCD(gray_bitmap_part)( 2036 MYXLCD(gray_bitmap_part)(
1856 pdisp->bitmap, pdisp->x, 2037 pdisp->bitmap[0], pdisp->x,
1857 pdisp->y + LCD_HEIGHT - move, pdisp->stride, 2038 pdisp->y + LCD_HEIGHT - move, pdisp->stride,
1858 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */ 2039 MAX(0, (LCD_WIDTH-pdisp->width)/2), LCD_HEIGHT - move, /* x, y */
1859 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */ 2040 MIN(LCD_WIDTH, pdisp->width), move); /* w, h */
2041#endif
1860 MYLCD_UPDATE(); 2042 MYLCD_UPDATE();
1861 } 2043 }
1862 break; 2044 break;
@@ -1927,35 +2109,50 @@ void align(unsigned char** ppbuf, int* plen, int align)
1927 *ppbuf = (unsigned char*)aligned; 2109 *ppbuf = (unsigned char*)aligned;
1928} 2110}
1929 2111
2112int jpegmem(struct jpeg *p_jpg, int ds)
2113{
2114 int size;
2115
2116 size = (p_jpg->x_phys/ds/p_jpg->subsample_x[0])
2117 * (p_jpg->y_phys/ds/p_jpg->subsample_y[0]);
2118#ifdef HAVE_LCD_COLOR
2119 if (p_jpg->blocks > 1) /* colour, add requirements for chroma */
2120 {
2121 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[1])
2122 * (p_jpg->y_phys/ds/p_jpg->subsample_y[1]);
2123 size += (p_jpg->x_phys/ds/p_jpg->subsample_x[2])
2124 * (p_jpg->y_phys/ds/p_jpg->subsample_y[2]);
2125 }
2126#endif
2127 return size;
2128}
1930 2129
1931/* how far can we zoom in without running out of memory */ 2130/* how far can we zoom in without running out of memory */
1932int min_downscale(int x, int y, int bufsize) 2131int min_downscale(struct jpeg *p_jpg, int bufsize)
1933{ 2132{
1934 int downscale = 8; 2133 int downscale = 8;
1935 2134
1936 if ((x/8) * (y/8) > bufsize) 2135 if (jpegmem(p_jpg, 8) > bufsize)
1937 return 0; /* error, too large, even 1:8 doesn't fit */ 2136 return 0; /* error, too large, even 1:8 doesn't fit */
1938 2137
1939 while ((x*2/downscale) * (y*2/downscale) < bufsize 2138 while (downscale > 1 && jpegmem(p_jpg, downscale/2) <= bufsize)
1940 && downscale > 1)
1941 {
1942 downscale /= 2; 2139 downscale /= 2;
1943 } 2140
1944 return downscale; 2141 return downscale;
1945} 2142}
1946 2143
1947 2144
1948/* how far can we zoom out, to fit image into the LCD */ 2145/* how far can we zoom out, to fit image into the LCD */
1949int max_downscale(int x, int y) 2146int max_downscale(struct jpeg *p_jpg)
1950{ 2147{
1951 int downscale = 1; 2148 int downscale = 1;
1952 2149
1953 while ((x/downscale > LCD_WIDTH || y/downscale > LCD_HEIGHT) 2150 while (downscale < 8 && (p_jpg->x_size > LCD_WIDTH*downscale
1954 && downscale < 8) 2151 || p_jpg->y_size > LCD_HEIGHT*downscale))
1955 { 2152 {
1956 downscale *= 2; 2153 downscale *= 2;
1957 } 2154 }
1958 2155
1959 return downscale; 2156 return downscale;
1960} 2157}
1961 2158
@@ -1970,7 +2167,7 @@ struct t_disp* get_image(struct jpeg* p_jpg, int ds)
1970 2167
1971 struct t_disp* p_disp = &disp[ds]; /* short cut */ 2168 struct t_disp* p_disp = &disp[ds]; /* short cut */
1972 2169
1973 if (p_disp->bitmap != NULL) 2170 if (p_disp->bitmap[0] != NULL)
1974 { 2171 {
1975 return p_disp; /* we still have it */ 2172 return p_disp; /* we still have it */
1976 } 2173 }
@@ -1978,19 +2175,41 @@ struct t_disp* get_image(struct jpeg* p_jpg, int ds)
1978 /* assign image buffer */ 2175 /* assign image buffer */
1979 2176
1980 /* physical size needed for decoding */ 2177 /* physical size needed for decoding */
1981 size = (p_jpg->x_phys/ds) * (p_jpg->y_phys / ds); 2178 size = jpegmem(p_jpg, ds);
1982 if (buf_size <= size) 2179 if (buf_size <= size)
1983 { /* have to discard the current */ 2180 { /* have to discard the current */
1984 int i; 2181 int i;
1985 for (i=1; i<=8; i++) 2182 for (i=1; i<=8; i++)
1986 disp[i].bitmap = NULL; /* invalidate all bitmaps */ 2183 disp[i].bitmap[0] = NULL; /* invalidate all bitmaps */
1987 buf = buf_root; /* start again from the beginning of the buffer */ 2184 buf = buf_root; /* start again from the beginning of the buffer */
1988 buf_size = root_size; 2185 buf_size = root_size;
1989 } 2186 }
2187
2188#ifdef HAVE_LCD_COLOR
2189 if (p_jpg->blocks > 1) /* colour jpeg */
2190 {
2191 int i;
1990 2192
2193 for (i = 1; i < 3; i++)
2194 {
2195 size = (p_jpg->x_phys / ds / p_jpg->subsample_x[i])
2196 * (p_jpg->y_phys / ds / p_jpg->subsample_y[i]);
2197 p_disp->bitmap[i] = buf;
2198 buf += size;
2199 buf_size -= size;
2200 }
2201 p_disp->csub_x = p_jpg->subsample_x[1];
2202 p_disp->csub_y = p_jpg->subsample_y[1];
2203 }
2204 else
2205 {
2206 p_disp->csub_x = p_disp->csub_y = 0;
2207 p_disp->bitmap[1] = p_disp->bitmap[2] = buf;
2208 }
2209#endif
1991 /* size may be less when decoded (if height is not block aligned) */ 2210 /* size may be less when decoded (if height is not block aligned) */
1992 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds); 2211 size = (p_jpg->x_phys/ds) * (p_jpg->y_size / ds);
1993 p_disp->bitmap = buf; 2212 p_disp->bitmap[0] = buf;
1994 buf += size; 2213 buf += size;
1995 buf_size -= size; 2214 buf_size -= size;
1996 2215
@@ -2000,9 +2219,9 @@ struct t_disp* get_image(struct jpeg* p_jpg, int ds)
2000 rb->lcd_update(); 2219 rb->lcd_update();
2001 2220
2002 /* update image properties */ 2221 /* update image properties */
2003 p_disp->width = p_jpg->x_size/ds; 2222 p_disp->width = p_jpg->x_size / ds;
2004 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */ 2223 p_disp->stride = p_jpg->x_phys / ds; /* use physical size for stride */
2005 p_disp->height = p_jpg->y_size/ds; 2224 p_disp->height = p_jpg->y_size / ds;
2006 2225
2007 /* the actual decoding */ 2226 /* the actual decoding */
2008 time = *rb->current_tick; 2227 time = *rb->current_tick;
@@ -2106,7 +2325,7 @@ int plugin_main(char* filename)
2106 2325
2107 /* allocate JPEG buffer */ 2326 /* allocate JPEG buffer */
2108 align(&buf, &buf_size, 2); /* 16 bit align */ 2327 align(&buf, &buf_size, 2); /* 16 bit align */
2109 buf_jpeg = (unsigned char*)(((int)buf + 1) & ~1); 2328 buf_jpeg = buf;
2110 buf += filesize; 2329 buf += filesize;
2111 buf_size -= filesize; 2330 buf_size -= filesize;
2112 buf_root = buf; /* we can start the decompressed images behind it */ 2331 buf_root = buf; /* we can start the decompressed images behind it */
@@ -2117,6 +2336,12 @@ int plugin_main(char* filename)
2117 rb->close(fd); 2336 rb->close(fd);
2118 return PLUGIN_ERROR; 2337 return PLUGIN_ERROR;
2119 } 2338 }
2339
2340#ifdef HAVE_LCD_COLOR
2341 rb->lcd_set_foreground(LCD_WHITE);
2342 rb->lcd_set_background(LCD_BLACK);
2343 rb->lcd_clear_display();
2344#endif
2120 2345
2121 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize); 2346 rb->snprintf(print, sizeof(print), "loading %d bytes", filesize);
2122 rb->lcd_puts(0, 0, print); 2347 rb->lcd_puts(0, 0, print);
@@ -2145,10 +2370,8 @@ int plugin_main(char* filename)
2145 rb->lcd_puts(0, 2, print); 2370 rb->lcd_puts(0, 2, print);
2146 rb->lcd_update(); 2371 rb->lcd_update();
2147 2372
2148 /* check display constraint */ 2373 ds_max = max_downscale(&jpg); /* check display constraint */
2149 ds_max = max_downscale(jpg.x_size, jpg.y_size); 2374 ds_min = min_downscale(&jpg, buf_size); /* check memory constraint */
2150 /* check memory constraint */
2151 ds_min = min_downscale(jpg.x_phys, jpg.y_phys, buf_size);
2152 if (ds_min == 0) 2375 if (ds_min == 0)
2153 { 2376 {
2154 rb->splash(HZ*2, true, "too large"); 2377 rb->splash(HZ*2, true, "too large");
@@ -2172,12 +2395,22 @@ int plugin_main(char* filename)
2172 rb->lcd_update(); 2395 rb->lcd_update();
2173 2396
2174 MYLCD(clear_display)(); 2397 MYLCD(clear_display)();
2398#ifdef HAVE_LCD_COLOR
2399 yuv_bitmap_part(
2400 p_disp->bitmap, p_disp->csub_x, p_disp->csub_y,
2401 p_disp->x, p_disp->y, p_disp->stride,
2402 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
2403 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
2404 MIN(LCD_WIDTH, p_disp->width),
2405 MIN(LCD_HEIGHT, p_disp->height));
2406#else
2175 MYXLCD(gray_bitmap_part)( 2407 MYXLCD(gray_bitmap_part)(
2176 p_disp->bitmap, p_disp->x, p_disp->y, p_disp->stride, 2408 p_disp->bitmap[0], p_disp->x, p_disp->y, p_disp->stride,
2177 MAX(0, (LCD_WIDTH - p_disp->width) / 2), 2409 MAX(0, (LCD_WIDTH - p_disp->width) / 2),
2178 MAX(0, (LCD_HEIGHT - p_disp->height) / 2), 2410 MAX(0, (LCD_HEIGHT - p_disp->height) / 2),
2179 MIN(LCD_WIDTH, p_disp->width), 2411 MIN(LCD_WIDTH, p_disp->width),
2180 MIN(LCD_HEIGHT, p_disp->height)); 2412 MIN(LCD_HEIGHT, p_disp->height));
2413#endif
2181 MYLCD_UPDATE(); 2414 MYLCD_UPDATE();
2182 2415
2183#ifdef USEGSLIB 2416#ifdef USEGSLIB