diff options
-rw-r--r-- | apps/plugins/jpeg.c | 136 |
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 | ||
601 | struct jpeg | 601 | struct 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 */ |
638 | int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) | 639 | int 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) | |||
1154 | INLINE void check_bit_buffer(struct bitstream* pb, int nbits) | 1125 | INLINE 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) */ | ||
1165 | void 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(); |