summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorJörg Hohensohn <hohensoh@rockbox.org>2004-05-23 06:23:02 +0000
committerJörg Hohensohn <hohensoh@rockbox.org>2004-05-23 06:23:02 +0000
commit9592ebb879c739d71d456d72e7adaa00bb988baa (patch)
tree2988a062f3cb10687c15a0b29bd685893c34a9a2 /apps
parentbdaf5884caa72457fd2602ea7a1f220d3bd18298 (diff)
downloadrockbox-9592ebb879c739d71d456d72e7adaa00bb988baa.tar.gz
rockbox-9592ebb879c739d71d456d72e7adaa00bb988baa.zip
now supports images with restart markers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4693 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/jpeg.c136
1 files changed, 67 insertions, 69 deletions
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c
index 99cdf5ba61..637afcc131 100644
--- a/apps/plugins/jpeg.c
+++ b/apps/plugins/jpeg.c
@@ -594,8 +594,8 @@ struct bitstream
594{ 594{
595 unsigned long get_buffer; /* current bit-extraction buffer */ 595 unsigned long get_buffer; /* current bit-extraction buffer */
596 int bits_left; /* # of unused bits in it */ 596 int bits_left; /* # of unused bits in it */
597 unsigned short* next_input_word; 597 unsigned char* next_input_byte;
598 long words_left; /* # of words remaining in source buffer */ 598 unsigned char* input_end; /* upper limit +1 */
599}; 599};
600 600
601struct jpeg 601struct jpeg
@@ -605,9 +605,10 @@ struct jpeg
605 int x_mbl; /* x dimension of MBL */ 605 int x_mbl; /* x dimension of MBL */
606 int y_mbl; /* y dimension of MBL */ 606 int y_mbl; /* y dimension of MBL */
607 int blocks; /* blocks per MBL */ 607 int blocks; /* blocks per MBL */
608 int restart_interval; /* number of MCUs between RSTm markers */
608 609
609 unsigned short* p_entropy_data; 610 unsigned char* p_entropy_data;
610 long words_in_buffer; /* # of valid words in source buffer */ 611 unsigned char* p_entropy_end;
611 612
612 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */ 613 int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
613 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */ 614 int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
@@ -635,20 +636,21 @@ struct jpeg
635#define DQT 0x0080 /* with definition of quantization table */ 636#define DQT 0x0080 /* with definition of quantization table */
636 637
637/* Preprocess the JPEG JFIF file */ 638/* Preprocess the JPEG JFIF file */
638int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) 639int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
639{ 640{
640 unsigned char* p_src = p_bytes; 641 unsigned char* p_bytes = p_src;
641 /* write without markers nor stuffing in same buffer */
642 unsigned char* p_dest;
643 int marker_size; /* variable length of marker segment */ 642 int marker_size; /* variable length of marker segment */
644 int i, j, n; 643 int i, j, n;
645 int ret = 0; /* returned flags */ 644 int ret = 0; /* returned flags */
646 645
646 p_jpeg->p_entropy_end = p_src + size;
647
647 while (p_src < p_bytes + size) 648 while (p_src < p_bytes + size)
648 { 649 {
649 if (*p_src++ != 0xFF) /* no marker? */ 650 if (*p_src++ != 0xFF) /* no marker? */
650 { 651 {
651 p_src--; /* it's image data, put it back */ 652 p_src--; /* it's image data, put it back */
653 p_jpeg->p_entropy_data = p_src;
652 break; /* exit marker processing */ 654 break; /* exit marker processing */
653 } 655 }
654 656
@@ -818,14 +820,6 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
818 case 0xCC: /* Define Arithmetic coding conditioning(s) */ 820 case 0xCC: /* Define Arithmetic coding conditioning(s) */
819 return(-6); /* Arithmetic coding not supported */ 821 return(-6); /* Arithmetic coding not supported */
820 822
821 case 0xD0: /* Restart with modulo 8 count 0 */
822 case 0xD1: /* Restart with modulo 8 count 1 */
823 case 0xD2: /* Restart with modulo 8 count 2 */
824 case 0xD3: /* Restart with modulo 8 count 3 */
825 case 0xD4: /* Restart with modulo 8 count 4 */
826 case 0xD5: /* Restart with modulo 8 count 5 */
827 case 0xD6: /* Restart with modulo 8 count 6 */
828 case 0xD7: /* Restart with modulo 8 count 7 */
829 case 0xD8: /* Start of Image */ 823 case 0xD8: /* Start of Image */
830 case 0xD9: /* End of Image */ 824 case 0xD9: /* End of Image */
831 case 0x01: /* for temp private use arith code */ 825 case 0x01: /* for temp private use arith code */
@@ -873,8 +867,17 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
873 } 867 }
874 break; 868 break;
875 869
876 case 0xDC: /* Define Number of Lines */
877 case 0xDD: /* Define Restart Interval */ 870 case 0xDD: /* Define Restart Interval */
871 {
872 marker_size = *p_src++ << 8; /* Highbyte */
873 marker_size |= *p_src++; /* Lowbyte */
874 p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
875 p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
876 p_src += marker_size-4; /* skip segment */
877 }
878 break;
879
880 case 0xDC: /* Define Number of Lines */
878 case 0xDE: /* Define Hierarchical progression */ 881 case 0xDE: /* Define Hierarchical progression */
879 case 0xDF: /* Expand Reference Component(s) */ 882 case 0xDF: /* Expand Reference Component(s) */
880 case 0xE0: /* Application Field 0*/ 883 case 0xE0: /* Application Field 0*/
@@ -921,38 +924,6 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
921 } /* switch */ 924 } /* switch */
922 } /* while */ 925 } /* while */
923 926
924
925 /* memory location for later decompress (16-bit aligned) */
926 p_dest = (unsigned char*)(((int)p_bytes + 1) & ~1);
927 p_jpeg->p_entropy_data = (unsigned short*)p_dest;
928
929
930 /* remove byte stuffing and restart markers, if present */
931 while (p_src < p_bytes + size)
932 {
933 if ((*p_dest++ = *p_src++) != 0xFF)
934 continue;
935
936 /* 0xFF marker found, have a closer look at the next byte */
937
938 if (*p_src == 0x00)
939 {
940 p_src++; /* continue reading after marker */
941 continue; /* stuffing byte, a true 0xFF */
942 }
943 else if (*p_src >= 0xD0 && *p_src <= 0xD7) /* restart marker */
944 {
945 return (-12); /* can't decode such images for now */
946 /* below won't work, is not seamless to the huffman decoder */
947 p_src++; /* continue reading after marker */
948 p_dest--; /* roll back, don't copy it */
949 continue; /* ignore */
950 }
951 else
952 break; /* exit on any other marker */
953 }
954 MEMSET(p_dest, 0, size - (p_dest - p_bytes)); /* fill tail with zeros */
955 p_jpeg->words_in_buffer = (p_dest - p_bytes) / sizeof(unsigned short);
956 return (ret); /* return flags with seen markers */ 927 return (ret); /* return flags with seen markers */
957} 928}
958 929
@@ -1154,10 +1125,23 @@ void build_lut(struct jpeg* p_jpeg)
1154INLINE void check_bit_buffer(struct bitstream* pb, int nbits) 1125INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
1155{ 1126{
1156 if (pb->bits_left < nbits) 1127 if (pb->bits_left < nbits)
1157 { 1128 { /* nbits is <= 16, so I can always refill 2 bytes in this case */
1158 pb->words_left--; 1129 unsigned char byte;
1159 pb->get_buffer = (pb->get_buffer << 16) 1130
1160 | ENDIAN_SWAP16(*pb->next_input_word++); 1131 byte = *pb->next_input_byte++;
1132 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1133 { /* simplification: just skip the (one-byte) marker code */
1134 pb->next_input_byte++;
1135 }
1136 pb->get_buffer = (pb->get_buffer << 8) | byte;
1137
1138 byte = *pb->next_input_byte++;
1139 if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
1140 { /* simplification: just skip the (one-byte) marker code */
1141 pb->next_input_byte++;
1142 }
1143 pb->get_buffer = (pb->get_buffer << 8) | byte;
1144
1161 pb->bits_left += 16; 1145 pb->bits_left += 16;
1162 } 1146 }
1163} 1147}
@@ -1177,6 +1161,19 @@ INLINE void drop_bits(struct bitstream* pb, int nbits)
1177 pb->bits_left -= nbits; 1161 pb->bits_left -= nbits;
1178} 1162}
1179 1163
1164/* re-synchronize to entropy data (skip restart marker) */
1165void search_restart(struct bitstream* pb)
1166{
1167 pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
1168 /* search for a non-byte-padding marker, has to be RSTm or EOS */
1169 while (pb->next_input_byte < pb->input_end &&
1170 (pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
1171 {
1172 pb->next_input_byte++;
1173 }
1174 pb->bits_left = 0;
1175}
1176
1180/* Figure F.12: extend sign bit. */ 1177/* Figure F.12: extend sign bit. */
1181#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) 1178#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
1182 1179
@@ -1295,6 +1292,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1295 1292
1296 int last_dc_val = 0; 1293 int last_dc_val = 0;
1297 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */ 1294 int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
1295 int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
1298 1296
1299 /* pick the IDCT we want, determine how to work with coefs */ 1297 /* pick the IDCT we want, determine how to work with coefs */
1300 if (downscale == 1) 1298 if (downscale == 1)
@@ -1323,10 +1321,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1323 } 1321 }
1324 else return -1; /* not supported */ 1322 else return -1; /* not supported */
1325 1323
1326 /* init bitstream */ 1324 /* init bitstream, fake a restart to make it start */
1325 bs.next_input_byte = p_jpeg->p_entropy_data;
1327 bs.bits_left = 0; 1326 bs.bits_left = 0;
1328 bs.next_input_word = p_jpeg->p_entropy_data; 1327 bs.input_end = p_jpeg->p_entropy_end;
1329 bs.words_left = p_jpeg->words_in_buffer;
1330 1328
1331 width = p_jpeg->x_phys / downscale; 1329 width = p_jpeg->x_phys / downscale;
1332 height = p_jpeg->y_phys / downscale; 1330 height = p_jpeg->y_phys / downscale;
@@ -1340,7 +1338,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1340 store_offs[2] = width * 8 / downscale; /* below */ 1338 store_offs[2] = width * 8 / downscale; /* below */
1341 store_offs[3] = store_offs[1] + store_offs[2]; /* right+below */ 1339 store_offs[3] = store_offs[1] + store_offs[2]; /* right+below */
1342 1340
1343 for(y=0; y<p_jpeg->y_mbl; y++) 1341 for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
1344 { 1342 {
1345 p_byte = p_pixel; 1343 p_byte = p_pixel;
1346 p_pixel += skip_strip; 1344 p_pixel += skip_strip;
@@ -1349,8 +1347,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1349 int blkn; 1347 int blkn;
1350 1348
1351 /* Outer loop handles each block in the MCU */ 1349 /* Outer loop handles each block in the MCU */
1352 1350 for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
1353 for (blkn = 0; blkn < p_jpeg->blocks && bs.words_left>=0; blkn++)
1354 { /* Decode a single block's worth of coefficients */ 1351 { /* Decode a single block's worth of coefficients */
1355 int k = 1; /* coefficient index */ 1352 int k = 1; /* coefficient index */
1356 int s, r; /* huffman values */ 1353 int s, r; /* huffman values */
@@ -1368,7 +1365,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1368 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */ 1365 block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
1369 1366
1370 /* coefficient buffer must be cleared */ 1367 /* coefficient buffer must be cleared */
1371 MEMSET(block+1, 0, zero_need*sizeof(int)); 1368 MEMSET(block+1, 0, zero_need*sizeof(block[0]));
1372 1369
1373 /* Section F.2.2.2: decode the AC coefficients */ 1370 /* Section F.2.2.2: decode the AC coefficients */
1374 for (; k < k_need; k++) 1371 for (; k < k_need; k++)
@@ -1418,11 +1415,17 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1418 1415
1419 if (ci == 0) 1416 if (ci == 0)
1420 { /* only for Y component */ 1417 { /* only for Y component */
1421 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti], 1418 pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
1422 skip_line); 1419 skip_line);
1423 } 1420 }
1424 } /* for blkn */ 1421 } /* for blkn */
1425 p_byte += skip_mcu; 1422 p_byte += skip_mcu;
1423 if (p_jpeg->restart_interval && --restart == 0)
1424 { /* if a restart marker is due: */
1425 restart = p_jpeg->restart_interval; /* count again */
1426 search_restart(&bs); /* align the bitstream */
1427 last_dc_val = 0; /* reset decoder */
1428 }
1426 } /* for x */ 1429 } /* for x */
1427 if (pf_progress != NULL) 1430 if (pf_progress != NULL)
1428 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */ 1431 pf_progress(y, p_jpeg->y_mbl-1); /* notify about decoding progress */
@@ -1431,6 +1434,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
1431 return 0; /* success */ 1434 return 0; /* success */
1432} 1435}
1433 1436
1437
1434/**************** end JPEG code ********************/ 1438/**************** end JPEG code ********************/
1435 1439
1436 1440
@@ -1765,6 +1769,8 @@ int main(char* filename)
1765 buf_jpeg = (unsigned char*)(((int)buf + 1) & ~1); 1769 buf_jpeg = (unsigned char*)(((int)buf + 1) & ~1);
1766 buf += filesize; 1770 buf += filesize;
1767 buf_size -= filesize; 1771 buf_size -= filesize;
1772 buf_root = buf; /* we can start the decompressed images behind it */
1773 root_size = buf_size;
1768 if (buf_size <= 0) 1774 if (buf_size <= 0)
1769 { 1775 {
1770 rb->splash(HZ*2, true, "out of memory"); 1776 rb->splash(HZ*2, true, "out of memory");
@@ -1795,14 +1801,6 @@ int main(char* filename)
1795 default_huff_tbl(&jpg); /* use default */ 1801 default_huff_tbl(&jpg); /* use default */
1796 build_lut(&jpg); /* derive Huffman and other lookup-tables */ 1802 build_lut(&jpg); /* derive Huffman and other lookup-tables */
1797 1803
1798 /* I can correct the buffer now, re-gain what the removed markers took */
1799 buf -= filesize; /* back to before */
1800 buf_size += filesize;
1801 buf += jpg.words_in_buffer * sizeof(short); /* real space */
1802 buf_size -= jpg.words_in_buffer * sizeof(short);
1803 buf_root = buf; /* we can start the images here */
1804 root_size = buf_size;
1805
1806 rb->snprintf(print, sizeof(print), "image %d*%d", jpg.x_size, jpg.y_size); 1804 rb->snprintf(print, sizeof(print), "image %d*%d", jpg.x_size, jpg.y_size);
1807 rb->lcd_puts(0, 2, print); 1805 rb->lcd_puts(0, 2, print);
1808 rb->lcd_update(); 1806 rb->lcd_update();