summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2006-02-16 22:59:40 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2006-02-16 22:59:40 +0000
commit4c63ab6a6ef6c2b87a1923cbe40d397aff440977 (patch)
tree8e8d46fac15d61c1c1fea5d92487adb2673e7055
parent7ea4d591277e35b05baadebb0be3a1d909e830d7 (diff)
downloadrockbox-4c63ab6a6ef6c2b87a1923cbe40d397aff440977.tar.gz
rockbox-4c63ab6a6ef6c2b87a1923cbe40d397aff440977.zip
the JPEG core can now also decode color images, this has to be wired to the application (memory management, color space converting display)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8711 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/jpeg.c233
1 files changed, 222 insertions, 11 deletions
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index e24c048ae8..408f5d1ea1 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -669,7 +669,7 @@ struct jpeg
669 int x_phys, y_phys; /* physical size, block aligned */ 669 int x_phys, y_phys; /* physical size, block aligned */
670 int x_mbl; /* x dimension of MBL */ 670 int x_mbl; /* x dimension of MBL */
671 int y_mbl; /* y dimension of MBL */ 671 int y_mbl; /* y dimension of MBL */
672 int blocks; /* blocks per MBL */ 672 int blocks; /* blocks per MB */
673 int restart_interval; /* number of MCUs between RSTm markers */ 673 int restart_interval; /* number of MCUs between RSTm markers */
674 int store_pos[4]; /* for Y block ordering */ 674 int store_pos[4]; /* for Y block ordering */
675 675
@@ -688,6 +688,8 @@ struct jpeg
688 688
689 int mcu_membership[6]; /* info per block */ 689 int mcu_membership[6]; /* info per block */
690 int tab_membership[6]; 690 int tab_membership[6];
691 int subsample_x[3]; /* info per component */
692 int subsample_y[3];
691}; 693};
692 694
693 695
@@ -1126,14 +1128,20 @@ void build_lut(struct jpeg* p_jpeg)
1126 p_jpeg->x_phys = p_jpeg->x_mbl * 16; 1128 p_jpeg->x_phys = p_jpeg->x_mbl * 16;
1127 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; 1129 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1128 p_jpeg->y_phys = p_jpeg->y_mbl * 8; 1130 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1129 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ 1131 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1130 p_jpeg->mcu_membership[1] = 0; 1132 p_jpeg->mcu_membership[1] = 0;
1131 p_jpeg->mcu_membership[2] = 2; 1133 p_jpeg->mcu_membership[2] = 1;
1132 p_jpeg->mcu_membership[3] = 3; 1134 p_jpeg->mcu_membership[3] = 2;
1133 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ 1135 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1134 p_jpeg->tab_membership[1] = 0; 1136 p_jpeg->tab_membership[1] = 0;
1135 p_jpeg->tab_membership[2] = 1; 1137 p_jpeg->tab_membership[2] = 1;
1136 p_jpeg->tab_membership[3] = 1; 1138 p_jpeg->tab_membership[3] = 1;
1139 p_jpeg->subsample_x[0] = 1;
1140 p_jpeg->subsample_x[1] = 2;
1141 p_jpeg->subsample_x[2] = 2;
1142 p_jpeg->subsample_y[0] = 1;
1143 p_jpeg->subsample_y[1] = 1;
1144 p_jpeg->subsample_y[2] = 1;
1137 } 1145 }
1138 if (p_jpeg->frameheader[0].horizontal_sampling == 1 1146 if (p_jpeg->frameheader[0].horizontal_sampling == 1
1139 && p_jpeg->frameheader[0].vertical_sampling == 2) 1147 && p_jpeg->frameheader[0].vertical_sampling == 2)
@@ -1145,14 +1153,20 @@ void build_lut(struct jpeg* p_jpeg)
1145 p_jpeg->x_phys = p_jpeg->x_mbl * 8; 1153 p_jpeg->x_phys = p_jpeg->x_mbl * 8;
1146 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16; 1154 p_jpeg->y_mbl = (p_jpeg->y_size+15) / 16;
1147 p_jpeg->y_phys = p_jpeg->y_mbl * 16; 1155 p_jpeg->y_phys = p_jpeg->y_mbl * 16;
1148 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=2, V=3 */ 1156 p_jpeg->mcu_membership[0] = 0; /* Y1=Y2=0, U=1, V=2 */
1149 p_jpeg->mcu_membership[1] = 0; 1157 p_jpeg->mcu_membership[1] = 0;
1150 p_jpeg->mcu_membership[2] = 2; 1158 p_jpeg->mcu_membership[2] = 1;
1151 p_jpeg->mcu_membership[3] = 3; 1159 p_jpeg->mcu_membership[3] = 2;
1152 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */ 1160 p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
1153 p_jpeg->tab_membership[1] = 0; 1161 p_jpeg->tab_membership[1] = 0;
1154 p_jpeg->tab_membership[2] = 1; 1162 p_jpeg->tab_membership[2] = 1;
1155 p_jpeg->tab_membership[3] = 1; 1163 p_jpeg->tab_membership[3] = 1;
1164 p_jpeg->subsample_x[0] = 1;
1165 p_jpeg->subsample_x[1] = 1;
1166 p_jpeg->subsample_x[2] = 1;
1167 p_jpeg->subsample_y[0] = 1;
1168 p_jpeg->subsample_y[1] = 2;
1169 p_jpeg->subsample_y[2] = 2;
1156 } 1170 }
1157 else if (p_jpeg->frameheader[0].horizontal_sampling == 2 1171 else if (p_jpeg->frameheader[0].horizontal_sampling == 2
1158 && p_jpeg->frameheader[0].vertical_sampling == 2) 1172 && p_jpeg->frameheader[0].vertical_sampling == 2)
@@ -1166,14 +1180,20 @@ void build_lut(struct jpeg* p_jpeg)
1166 p_jpeg->mcu_membership[1] = 0; 1180 p_jpeg->mcu_membership[1] = 0;
1167 p_jpeg->mcu_membership[2] = 0; 1181 p_jpeg->mcu_membership[2] = 0;
1168 p_jpeg->mcu_membership[3] = 0; 1182 p_jpeg->mcu_membership[3] = 0;
1169 p_jpeg->mcu_membership[4] = 2; 1183 p_jpeg->mcu_membership[4] = 1;
1170 p_jpeg->mcu_membership[5] = 3; 1184 p_jpeg->mcu_membership[5] = 2;
1171 p_jpeg->tab_membership[0] = 0; 1185 p_jpeg->tab_membership[0] = 0;
1172 p_jpeg->tab_membership[1] = 0; 1186 p_jpeg->tab_membership[1] = 0;
1173 p_jpeg->tab_membership[2] = 0; 1187 p_jpeg->tab_membership[2] = 0;
1174 p_jpeg->tab_membership[3] = 0; 1188 p_jpeg->tab_membership[3] = 0;
1175 p_jpeg->tab_membership[4] = 1; 1189 p_jpeg->tab_membership[4] = 1;
1176 p_jpeg->tab_membership[5] = 1; 1190 p_jpeg->tab_membership[5] = 1;
1191 p_jpeg->subsample_x[0] = 1;
1192 p_jpeg->subsample_x[1] = 2;
1193 p_jpeg->subsample_x[2] = 2;
1194 p_jpeg->subsample_y[0] = 1;
1195 p_jpeg->subsample_y[1] = 2;
1196 p_jpeg->subsample_y[2] = 2;
1177 } 1197 }
1178 else if (p_jpeg->frameheader[0].horizontal_sampling == 1 1198 else if (p_jpeg->frameheader[0].horizontal_sampling == 1
1179 && p_jpeg->frameheader[0].vertical_sampling == 1) 1199 && p_jpeg->frameheader[0].vertical_sampling == 1)
@@ -1184,11 +1204,21 @@ void build_lut(struct jpeg* p_jpeg)
1184 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8; 1204 p_jpeg->y_mbl = (p_jpeg->y_size+7) / 8;
1185 p_jpeg->y_phys = p_jpeg->y_mbl * 8; 1205 p_jpeg->y_phys = p_jpeg->y_mbl * 8;
1186 p_jpeg->mcu_membership[0] = 0; 1206 p_jpeg->mcu_membership[0] = 0;
1187 p_jpeg->mcu_membership[1] = 2; 1207 p_jpeg->mcu_membership[1] = 1;
1188 p_jpeg->mcu_membership[2] = 3; 1208 p_jpeg->mcu_membership[2] = 2;
1189 p_jpeg->tab_membership[0] = 0; 1209 p_jpeg->tab_membership[0] = 0;
1190 p_jpeg->tab_membership[1] = 1; 1210 p_jpeg->tab_membership[1] = 1;
1191 p_jpeg->tab_membership[2] = 1; 1211 p_jpeg->tab_membership[2] = 1;
1212 p_jpeg->subsample_x[0] = 1;
1213 p_jpeg->subsample_x[1] = 1;
1214 p_jpeg->subsample_x[2] = 1;
1215 p_jpeg->subsample_y[0] = 1;
1216 p_jpeg->subsample_y[1] = 1;
1217 p_jpeg->subsample_y[2] = 1;
1218 }
1219 else
1220 {
1221 // error
1192 } 1222 }
1193 1223
1194} 1224}
@@ -1523,6 +1553,187 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1523} 1553}
1524 1554
1525 1555
1556#ifdef HAVE_LCD_COLOR
1557
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{
1563 struct bitstream bs; /* bitstream "object" */
1564 static int block[64]; /* decoded DCT coefficients */
1565
1566 int width, height;
1567 int skip_line[3]; /* bytes from one line to the next (skip_line) */
1568 int skip_strip[3], skip_mcu[3]; /* bytes to next DCT row / column */
1569
1570 int i, x, y; /* loop counter */
1571
1572 unsigned char* p_line[3] = {p_pixel[0], p_pixel[1], p_pixel[2]};
1573 unsigned char* p_byte[3]; /* bitmap pointer */
1574
1575 void (*pf_idct)(unsigned char*, int*, int*, int); /* selected IDCT */
1576 int k_need; /* AC coefficients needed up to here */
1577 int zero_need; /* init the block with this many zeros */
1578
1579 int last_dc_val[3] = {0, 0, 0}; // or 128 for chroma?
1580 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 */
1582
1583 /* pick the IDCT we want, determine how to work with coefs */
1584 if (downscale == 1)
1585 {
1586 pf_idct = idct8x8;
1587 k_need = 64; /* all */
1588 zero_need = 63; /* all */
1589 }
1590 else if (downscale == 2)
1591 {
1592 pf_idct = idct4x4;
1593 k_need = 25; /* this far in zig-zag to cover 4*4 */
1594 zero_need = 27; /* clear this far in linear order */
1595 }
1596 else if (downscale == 4)
1597 {
1598 pf_idct = idct2x2;
1599 k_need = 5; /* this far in zig-zag to cover 2*2 */
1600 zero_need = 9; /* clear this far in linear order */
1601 }
1602 else if (downscale == 8)
1603 {
1604 pf_idct = idct1x1;
1605 k_need = 0; /* no AC, not needed */
1606 zero_need = 0; /* no AC, not needed */
1607 }
1608 else return -1; /* not supported */
1609
1610 /* init bitstream, fake a restart to make it start */
1611 bs.next_input_byte = p_jpeg->p_entropy_data;
1612 bs.bits_left = 0;
1613 bs.input_end = p_jpeg->p_entropy_end;
1614
1615 width = p_jpeg->x_phys / downscale;
1616 height = p_jpeg->y_phys / downscale;
1617 for (i=0; i<3; i++) /* calculate some strides */
1618 {
1619 skip_line[i] = width / p_jpeg->subsample_x[i];
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
1625 /* prepare offsets about where to store the different blocks */
1626 store_offs[p_jpeg->store_pos[0]] = 0;
1627 store_offs[p_jpeg->store_pos[1]] = 8 / downscale; /* to the right */
1628 store_offs[p_jpeg->store_pos[2]] = width * 8 / downscale; /* below */
1629 store_offs[p_jpeg->store_pos[3]] = store_offs[1] + store_offs[2]; /* r+b */
1630
1631 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1632 {
1633 for (i=0; i<3; i++) // scan line init
1634 {
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++)
1639 {
1640 int blkn;
1641
1642 /* Outer loop handles each block in the MCU */
1643 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1644 { /* Decode a single block's worth of coefficients */
1645 int k = 1; /* coefficient index */
1646 int s, r; /* huffman values */
1647 int ci = p_jpeg->mcu_membership[blkn]; /* component index */
1648 int ti = p_jpeg->tab_membership[blkn]; /* table index */
1649 struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
1650 struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
1651
1652 /* Section F.2.2.1: decode the DC coefficient difference */
1653 s = huff_decode_dc(&bs, dctbl);
1654
1655 last_dc_val[ci] += s;
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 {
1664 s = huff_decode_ac(&bs, actbl);
1665 r = s >> 4;
1666 s &= 15;
1667
1668 if (s)
1669 {
1670 k += r;
1671 check_bit_buffer(&bs, s);
1672 r = get_bits(&bs, s);
1673 block[zag[k]] = HUFF_EXTEND(r, s);
1674 }
1675 else
1676 {
1677 if (r != 15)
1678 {
1679 k = 64;
1680 break;
1681 }
1682 k += r;
1683 }
1684 } /* for k */
1685 /* In this path we just discard the values */
1686 for (; k < 64; k++)
1687 {
1688 s = huff_decode_ac(&bs, actbl);
1689 r = s >> 4;
1690 s &= 15;
1691
1692 if (s)
1693 {
1694 k += r;
1695 check_bit_buffer(&bs, s);
1696 drop_bits(&bs, s);
1697 }
1698 else
1699 {
1700 if (r != 15)
1701 break;
1702 k += r;
1703 }
1704 } /* for k */
1705
1706 if (ci == 0)
1707 { /* Y component needs to bother about block store */
1708 pf_idct(p_byte[0]+store_offs[blkn], block,
1709 p_jpeg->qt_idct[ti], skip_line[0]);
1710 }
1711 else
1712 { /* chroma */
1713 pf_idct(p_byte[ci], block, p_jpeg->qt_idct[ti],
1714 skip_line[ci]);
1715 }
1716 } /* for blkn */
1717 p_byte[0] += skip_mcu[0]; // unrolled for (i=0; i<3; i++) loop
1718 p_byte[1] += skip_mcu[1];
1719 p_byte[2] += skip_mcu[2];
1720 if (p_jpeg->restart_interval && --restart == 0)
1721 { /* if a restart marker is due: */
1722 restart = p_jpeg->restart_interval; /* count again */
1723 search_restart(&bs); /* align the bitstream */
1724 last_dc_val[0] = last_dc_val[1] =
1725 last_dc_val[2] = 0; /* reset decoder */
1726 }
1727 } /* for x */
1728 if (pf_progress != NULL)
1729 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
1730 } /* for y */
1731
1732 return 0; /* success */
1733}
1734
1735#endif /* #ifdef HAVE_LCD_COLOR */
1736
1526/**************** end JPEG code ********************/ 1737/**************** end JPEG code ********************/
1527 1738
1528 1739