diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/jpeg.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/apps/plugins/jpeg.c b/apps/plugins/jpeg.c index ee6fb83f66..fee137b1eb 100644 --- a/apps/plugins/jpeg.c +++ b/apps/plugins/jpeg.c | |||
@@ -1269,13 +1269,18 @@ void gray_drawbitmap(unsigned char *src, int x, int y, int nx, int ny, | |||
1269 | 1269 | ||
1270 | /**************** end grayscale framework ********************/ | 1270 | /**************** end grayscale framework ********************/ |
1271 | 1271 | ||
1272 | #define MEMSET(p,v,c) rb->memset(p,v,c) // for portability of below | 1272 | /* for portability of below JPEG code */ |
1273 | #define MEMSET(p,v,c) rb->memset(p,v,c) | ||
1273 | #define INLINE static inline | 1274 | #define INLINE static inline |
1275 | #define ENDIAN_SWAP16(n) n /* only for poor little endian machines */ | ||
1276 | |||
1277 | |||
1274 | 1278 | ||
1275 | /**************** begin JPEG code ********************/ | 1279 | /**************** begin JPEG code ********************/ |
1276 | 1280 | ||
1277 | /* LUT for IDCT, this could also be used for gamma correction */ | 1281 | /* LUT for IDCT, this could also be used for gamma correction */ |
1278 | const unsigned char range_limit[1024] = { | 1282 | const unsigned char range_limit[1024] = |
1283 | { | ||
1279 | 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, | 1284 | 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, |
1280 | 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, | 1285 | 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, |
1281 | 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, | 1286 | 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, |
@@ -1663,7 +1668,8 @@ void idct8x8(unsigned char* p_byte, int* inptr, int* quantptr, int skip_line) | |||
1663 | /* and also undo the PASS1_BITS scaling. */ | 1668 | /* and also undo the PASS1_BITS scaling. */ |
1664 | 1669 | ||
1665 | wsptr = workspace; | 1670 | wsptr = workspace; |
1666 | for (ctr = 0; ctr < 8; ctr++) { | 1671 | for (ctr = 0; ctr < 8; ctr++) |
1672 | { | ||
1667 | outptr = p_byte + (ctr*skip_line); | 1673 | outptr = p_byte + (ctr*skip_line); |
1668 | /* Rows of zeroes can be exploited in the same way as we did with columns. | 1674 | /* Rows of zeroes can be exploited in the same way as we did with columns. |
1669 | * However, the column calculation has created many nonzero AC terms, so | 1675 | * However, the column calculation has created many nonzero AC terms, so |
@@ -1868,18 +1874,12 @@ struct jpeg | |||
1868 | int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) | 1874 | int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) |
1869 | { | 1875 | { |
1870 | unsigned char* p_src = p_bytes; | 1876 | unsigned char* p_src = p_bytes; |
1871 | unsigned char* p_temp; | ||
1872 | |||
1873 | /* write without markers nor stuffing in same buffer */ | 1877 | /* write without markers nor stuffing in same buffer */ |
1874 | unsigned short* p_dest = (unsigned short*) p_bytes; | 1878 | unsigned char* p_dest; |
1875 | int marker_size; /* variable length of marker segment */ | 1879 | int marker_size; /* variable length of marker segment */ |
1876 | int i, j, n; | 1880 | int i, j, n; |
1877 | unsigned char highbyte, lowbyte; | ||
1878 | int ret = 0; /* returned flags */ | 1881 | int ret = 0; /* returned flags */ |
1879 | 1882 | ||
1880 | /* memory location for later decompress */ | ||
1881 | p_jpeg->p_entropy_data = (unsigned short*)p_bytes; | ||
1882 | |||
1883 | while (p_src < p_bytes + size) | 1883 | while (p_src < p_bytes + size) |
1884 | { | 1884 | { |
1885 | if (*p_src++ != 0xFF) /* no marker? */ | 1885 | if (*p_src++ != 0xFF) /* no marker? */ |
@@ -2005,6 +2005,8 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) | |||
2005 | 2005 | ||
2006 | case 0xC4: /* Define Huffman Table(s) */ | 2006 | case 0xC4: /* Define Huffman Table(s) */ |
2007 | { | 2007 | { |
2008 | unsigned char* p_temp; | ||
2009 | |||
2008 | ret |= DHT; | 2010 | ret |= DHT; |
2009 | marker_size = *p_src++ << 8; /* Highbyte */ | 2011 | marker_size = *p_src++ << 8; /* Highbyte */ |
2010 | marker_size |= *p_src++; /* Lowbyte */ | 2012 | marker_size |= *p_src++; /* Lowbyte */ |
@@ -2019,12 +2021,12 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) | |||
2019 | } | 2021 | } |
2020 | if (*p_src++ & 0xF0) /* AC table */ | 2022 | if (*p_src++ & 0xF0) /* AC table */ |
2021 | { | 2023 | { |
2022 | for (j=0; j<AC_LEN; j++) | 2024 | for (j=0; j<MIN(AC_LEN, marker_size-3); j++) |
2023 | p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++; | 2025 | p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++; |
2024 | } | 2026 | } |
2025 | else /* DC table */ | 2027 | else /* DC table */ |
2026 | { | 2028 | { |
2027 | for (j=0; j<DC_LEN; j++) | 2029 | for (j=0; j<MIN(DC_LEN, marker_size-3); j++) |
2028 | p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++; | 2030 | p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++; |
2029 | } | 2031 | } |
2030 | } /* while */ | 2032 | } /* while */ |
@@ -2129,22 +2131,36 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) | |||
2129 | } /* switch */ | 2131 | } /* switch */ |
2130 | } /* while */ | 2132 | } /* while */ |
2131 | 2133 | ||
2132 | /* undo byte stuffing, endian conversion */ | 2134 | |
2133 | /* ToDo: remove restart markers, if present */ | 2135 | /* memory location for later decompress (16-bit aligned) */ |
2136 | p_dest = (unsigned char*)((int)p_bytes + 1 & ~1); | ||
2137 | p_jpeg->p_entropy_data = (unsigned short*)p_dest; | ||
2138 | |||
2139 | |||
2140 | /* remove byte stuffing and restart markers, if present */ | ||
2134 | while (p_src < p_bytes + size) | 2141 | while (p_src < p_bytes + size) |
2135 | { | 2142 | { |
2136 | highbyte = *p_src++; | 2143 | if ((*p_dest++ = *p_src++) != 0xFF) |
2137 | if (highbyte==0xFF && *p_src++) break; /* end on marker */ | 2144 | continue; |
2138 | lowbyte = *p_src++; | 2145 | |
2139 | if (lowbyte==0xFF && *p_src++) | 2146 | /* 0xFF marker found, have a closer look at the next byte */ |
2147 | |||
2148 | if (*p_src == 0x00) | ||
2149 | { | ||
2150 | p_src++; /* continue reading after marker */ | ||
2151 | continue; /* stuffing byte, a true 0xFF */ | ||
2152 | } | ||
2153 | else if (*p_src >= 0xD0 && *p_src <= 0xD7) /* restart marker */ | ||
2140 | { | 2154 | { |
2141 | *p_dest++ = highbyte<<8; /* write remaining */ | 2155 | p_src++; /* continue reading after marker */ |
2142 | break; /* end on marker */ | 2156 | p_dest--; /* roll back, don't copy it */ |
2157 | continue; /* ignore */ | ||
2143 | } | 2158 | } |
2144 | *p_dest++ = highbyte<<8 | lowbyte; | 2159 | else |
2160 | break; /* exit on any other marker */ | ||
2145 | } | 2161 | } |
2146 | MEMSET(p_dest, 0, size-((unsigned char*)p_dest-p_bytes)); /* fill tail with zeros */ | 2162 | MEMSET(p_dest, 0, size - (p_dest - p_bytes)); /* fill tail with zeros */ |
2147 | p_jpeg->words_in_buffer = p_dest-(unsigned short*)p_bytes; | 2163 | p_jpeg->words_in_buffer = (p_dest - p_bytes) / sizeof(unsigned short); |
2148 | return (ret); /* return flags with seen markers */ | 2164 | return (ret); /* return flags with seen markers */ |
2149 | } | 2165 | } |
2150 | 2166 | ||
@@ -2292,7 +2308,8 @@ void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl) | |||
2292 | * reference values beyond the end of the array. To avoid a wild store, | 2308 | * reference values beyond the end of the array. To avoid a wild store, |
2293 | * we put some extra zeroes after the real entries. | 2309 | * we put some extra zeroes after the real entries. |
2294 | */ | 2310 | */ |
2295 | static const int zag[] = { | 2311 | static const int zag[] = |
2312 | { | ||
2296 | 0, 1, 8, 16, 9, 2, 3, 10, | 2313 | 0, 1, 8, 16, 9, 2, 3, 10, |
2297 | 17, 24, 32, 25, 18, 11, 4, 5, | 2314 | 17, 24, 32, 25, 18, 11, 4, 5, |
2298 | 12, 19, 26, 33, 40, 48, 41, 34, | 2315 | 12, 19, 26, 33, 40, 48, 41, 34, |
@@ -2347,7 +2364,8 @@ INLINE void check_bit_buffer(struct bitstream* pb, int nbits) | |||
2347 | if (pb->bits_left < nbits) | 2364 | if (pb->bits_left < nbits) |
2348 | { | 2365 | { |
2349 | pb->words_left--; | 2366 | pb->words_left--; |
2350 | pb->get_buffer = (pb->get_buffer << 16) | *pb->next_input_word++; | 2367 | pb->get_buffer = (pb->get_buffer << 16) |
2368 | | ENDIAN_SWAP16(*pb->next_input_word++); | ||
2351 | pb->bits_left += 16; | 2369 | pb->bits_left += 16; |
2352 | } | 2370 | } |
2353 | } | 2371 | } |
@@ -2619,10 +2637,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale, | |||
2619 | return 0; /* success */ | 2637 | return 0; /* success */ |
2620 | } | 2638 | } |
2621 | 2639 | ||
2622 | |||
2623 | /**************** end JPEG code ********************/ | 2640 | /**************** end JPEG code ********************/ |
2624 | 2641 | ||
2625 | 2642 | ||
2643 | |||
2626 | /**************** begin Application ********************/ | 2644 | /**************** begin Application ********************/ |
2627 | 2645 | ||
2628 | 2646 | ||