1
0
Fork 0
forked from len0rd/rockbox

more compatible huffman table parsing, tolerate restart markers

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4618 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jörg Hohensohn 2004-05-13 21:32:52 +00:00
parent 5ed894fd50
commit ec98b18846

View file

@ -1269,13 +1269,18 @@ void gray_drawbitmap(unsigned char *src, int x, int y, int nx, int ny,
/**************** end grayscale framework ********************/ /**************** end grayscale framework ********************/
#define MEMSET(p,v,c) rb->memset(p,v,c) // for portability of below /* for portability of below JPEG code */
#define MEMSET(p,v,c) rb->memset(p,v,c)
#define INLINE static inline #define INLINE static inline
#define ENDIAN_SWAP16(n) n /* only for poor little endian machines */
/**************** begin JPEG code ********************/ /**************** begin JPEG code ********************/
/* LUT for IDCT, this could also be used for gamma correction */ /* LUT for IDCT, this could also be used for gamma correction */
const unsigned char range_limit[1024] = { const unsigned char range_limit[1024] =
{
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 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)
/* and also undo the PASS1_BITS scaling. */ /* and also undo the PASS1_BITS scaling. */
wsptr = workspace; wsptr = workspace;
for (ctr = 0; ctr < 8; ctr++) { for (ctr = 0; ctr < 8; ctr++)
{
outptr = p_byte + (ctr*skip_line); outptr = p_byte + (ctr*skip_line);
/* Rows of zeroes can be exploited in the same way as we did with columns. /* Rows of zeroes can be exploited in the same way as we did with columns.
* However, the column calculation has created many nonzero AC terms, so * However, the column calculation has created many nonzero AC terms, so
@ -1868,18 +1874,12 @@ struct jpeg
int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg) int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
{ {
unsigned char* p_src = p_bytes; unsigned char* p_src = p_bytes;
unsigned char* p_temp;
/* write without markers nor stuffing in same buffer */ /* write without markers nor stuffing in same buffer */
unsigned short* p_dest = (unsigned short*) p_bytes; unsigned char* p_dest;
int marker_size; /* variable length of marker segment */ int marker_size; /* variable length of marker segment */
int i, j, n; int i, j, n;
unsigned char highbyte, lowbyte;
int ret = 0; /* returned flags */ int ret = 0; /* returned flags */
/* memory location for later decompress */
p_jpeg->p_entropy_data = (unsigned short*)p_bytes;
while (p_src < p_bytes + size) while (p_src < p_bytes + size)
{ {
if (*p_src++ != 0xFF) /* no marker? */ if (*p_src++ != 0xFF) /* no marker? */
@ -2005,6 +2005,8 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
case 0xC4: /* Define Huffman Table(s) */ case 0xC4: /* Define Huffman Table(s) */
{ {
unsigned char* p_temp;
ret |= DHT; ret |= DHT;
marker_size = *p_src++ << 8; /* Highbyte */ marker_size = *p_src++ << 8; /* Highbyte */
marker_size |= *p_src++; /* Lowbyte */ marker_size |= *p_src++; /* Lowbyte */
@ -2019,12 +2021,12 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
} }
if (*p_src++ & 0xF0) /* AC table */ if (*p_src++ & 0xF0) /* AC table */
{ {
for (j=0; j<AC_LEN; j++) for (j=0; j<MIN(AC_LEN, marker_size-3); j++)
p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++; p_jpeg->hufftable[i].huffmancodes_ac[j] = *p_src++;
} }
else /* DC table */ else /* DC table */
{ {
for (j=0; j<DC_LEN; j++) for (j=0; j<MIN(DC_LEN, marker_size-3); j++)
p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++; p_jpeg->hufftable[i].huffmancodes_dc[j] = *p_src++;
} }
} /* while */ } /* while */
@ -2129,22 +2131,36 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
} /* switch */ } /* switch */
} /* while */ } /* while */
/* undo byte stuffing, endian conversion */
/* ToDo: remove restart markers, if present */ /* memory location for later decompress (16-bit aligned) */
p_dest = (unsigned char*)((int)p_bytes + 1 & ~1);
p_jpeg->p_entropy_data = (unsigned short*)p_dest;
/* remove byte stuffing and restart markers, if present */
while (p_src < p_bytes + size) while (p_src < p_bytes + size)
{ {
highbyte = *p_src++; if ((*p_dest++ = *p_src++) != 0xFF)
if (highbyte==0xFF && *p_src++) break; /* end on marker */ continue;
lowbyte = *p_src++;
if (lowbyte==0xFF && *p_src++) /* 0xFF marker found, have a closer look at the next byte */
if (*p_src == 0x00)
{ {
*p_dest++ = highbyte<<8; /* write remaining */ p_src++; /* continue reading after marker */
break; /* end on marker */ continue; /* stuffing byte, a true 0xFF */
} }
*p_dest++ = highbyte<<8 | lowbyte; else if (*p_src >= 0xD0 && *p_src <= 0xD7) /* restart marker */
{
p_src++; /* continue reading after marker */
p_dest--; /* roll back, don't copy it */
continue; /* ignore */
}
else
break; /* exit on any other marker */
} }
MEMSET(p_dest, 0, size-((unsigned char*)p_dest-p_bytes)); /* fill tail with zeros */ MEMSET(p_dest, 0, size - (p_dest - p_bytes)); /* fill tail with zeros */
p_jpeg->words_in_buffer = p_dest-(unsigned short*)p_bytes; p_jpeg->words_in_buffer = (p_dest - p_bytes) / sizeof(unsigned short);
return (ret); /* return flags with seen markers */ return (ret); /* return flags with seen markers */
} }
@ -2292,7 +2308,8 @@ void fix_huff_tbl(int* htbl, struct derived_tbl* dtbl)
* reference values beyond the end of the array. To avoid a wild store, * reference values beyond the end of the array. To avoid a wild store,
* we put some extra zeroes after the real entries. * we put some extra zeroes after the real entries.
*/ */
static const int zag[] = { static const int zag[] =
{
0, 1, 8, 16, 9, 2, 3, 10, 0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5, 17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34, 12, 19, 26, 33, 40, 48, 41, 34,
@ -2347,7 +2364,8 @@ INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
if (pb->bits_left < nbits) if (pb->bits_left < nbits)
{ {
pb->words_left--; pb->words_left--;
pb->get_buffer = (pb->get_buffer << 16) | *pb->next_input_word++; pb->get_buffer = (pb->get_buffer << 16)
| ENDIAN_SWAP16(*pb->next_input_word++);
pb->bits_left += 16; pb->bits_left += 16;
} }
} }
@ -2619,10 +2637,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
return 0; /* success */ return 0; /* success */
} }
/**************** end JPEG code ********************/ /**************** end JPEG code ********************/
/**************** begin Application ********************/ /**************** begin Application ********************/