1
0
Fork 0
forked from len0rd/rockbox

now supports images with restart markers

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@4693 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jörg Hohensohn 2004-05-23 06:23:02 +00:00
parent bdaf5884ca
commit 9592ebb879

View file

@ -594,8 +594,8 @@ struct bitstream
{
unsigned long get_buffer; /* current bit-extraction buffer */
int bits_left; /* # of unused bits in it */
unsigned short* next_input_word;
long words_left; /* # of words remaining in source buffer */
unsigned char* next_input_byte;
unsigned char* input_end; /* upper limit +1 */
};
struct jpeg
@ -605,9 +605,10 @@ struct jpeg
int x_mbl; /* x dimension of MBL */
int y_mbl; /* y dimension of MBL */
int blocks; /* blocks per MBL */
int restart_interval; /* number of MCUs between RSTm markers */
unsigned short* p_entropy_data;
long words_in_buffer; /* # of valid words in source buffer */
unsigned char* p_entropy_data;
unsigned char* p_entropy_end;
int quanttable[4][QUANT_TABLE_LENGTH]; /* raw quantization tables 0-3 */
int qt_idct[2][QUANT_TABLE_LENGTH]; /* quantization tables for IDCT */
@ -635,20 +636,21 @@ struct jpeg
#define DQT 0x0080 /* with definition of quantization table */
/* Preprocess the JPEG JFIF file */
int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
{
unsigned char* p_src = p_bytes;
/* write without markers nor stuffing in same buffer */
unsigned char* p_dest;
unsigned char* p_bytes = p_src;
int marker_size; /* variable length of marker segment */
int i, j, n;
int ret = 0; /* returned flags */
p_jpeg->p_entropy_end = p_src + size;
while (p_src < p_bytes + size)
{
if (*p_src++ != 0xFF) /* no marker? */
{
p_src--; /* it's image data, put it back */
p_jpeg->p_entropy_data = p_src;
break; /* exit marker processing */
}
@ -818,14 +820,6 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
case 0xCC: /* Define Arithmetic coding conditioning(s) */
return(-6); /* Arithmetic coding not supported */
case 0xD0: /* Restart with modulo 8 count 0 */
case 0xD1: /* Restart with modulo 8 count 1 */
case 0xD2: /* Restart with modulo 8 count 2 */
case 0xD3: /* Restart with modulo 8 count 3 */
case 0xD4: /* Restart with modulo 8 count 4 */
case 0xD5: /* Restart with modulo 8 count 5 */
case 0xD6: /* Restart with modulo 8 count 6 */
case 0xD7: /* Restart with modulo 8 count 7 */
case 0xD8: /* Start of Image */
case 0xD9: /* End of Image */
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)
}
break;
case 0xDC: /* Define Number of Lines */
case 0xDD: /* Define Restart Interval */
{
marker_size = *p_src++ << 8; /* Highbyte */
marker_size |= *p_src++; /* Lowbyte */
p_jpeg->restart_interval = *p_src++ << 8; /* Highbyte */
p_jpeg->restart_interval |= *p_src++; /* Lowbyte */
p_src += marker_size-4; /* skip segment */
}
break;
case 0xDC: /* Define Number of Lines */
case 0xDE: /* Define Hierarchical progression */
case 0xDF: /* Expand Reference Component(s) */
case 0xE0: /* Application Field 0*/
@ -921,38 +924,6 @@ int process_markers(unsigned char* p_bytes, long size, struct jpeg* p_jpeg)
} /* switch */
} /* while */
/* 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)
{
if ((*p_dest++ = *p_src++) != 0xFF)
continue;
/* 0xFF marker found, have a closer look at the next byte */
if (*p_src == 0x00)
{
p_src++; /* continue reading after marker */
continue; /* stuffing byte, a true 0xFF */
}
else if (*p_src >= 0xD0 && *p_src <= 0xD7) /* restart marker */
{
return (-12); /* can't decode such images for now */
/* below won't work, is not seamless to the huffman decoder */
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 - (p_dest - p_bytes)); /* fill tail with zeros */
p_jpeg->words_in_buffer = (p_dest - p_bytes) / sizeof(unsigned short);
return (ret); /* return flags with seen markers */
}
@ -1154,10 +1125,23 @@ void build_lut(struct jpeg* p_jpeg)
INLINE void check_bit_buffer(struct bitstream* pb, int nbits)
{
if (pb->bits_left < nbits)
{
pb->words_left--;
pb->get_buffer = (pb->get_buffer << 16)
| ENDIAN_SWAP16(*pb->next_input_word++);
{ /* nbits is <= 16, so I can always refill 2 bytes in this case */
unsigned char byte;
byte = *pb->next_input_byte++;
if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
{ /* simplification: just skip the (one-byte) marker code */
pb->next_input_byte++;
}
pb->get_buffer = (pb->get_buffer << 8) | byte;
byte = *pb->next_input_byte++;
if (byte == 0xFF) /* legal marker can be byte stuffing or RSTm */
{ /* simplification: just skip the (one-byte) marker code */
pb->next_input_byte++;
}
pb->get_buffer = (pb->get_buffer << 8) | byte;
pb->bits_left += 16;
}
}
@ -1177,6 +1161,19 @@ INLINE void drop_bits(struct bitstream* pb, int nbits)
pb->bits_left -= nbits;
}
/* re-synchronize to entropy data (skip restart marker) */
void search_restart(struct bitstream* pb)
{
pb->next_input_byte--; /* we may have overread it, taking 2 bytes */
/* search for a non-byte-padding marker, has to be RSTm or EOS */
while (pb->next_input_byte < pb->input_end &&
(pb->next_input_byte[-2] != 0xFF || pb->next_input_byte[-1] == 0x00))
{
pb->next_input_byte++;
}
pb->bits_left = 0;
}
/* Figure F.12: extend sign bit. */
#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
@ -1295,6 +1292,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
int last_dc_val = 0;
int store_offs[4]; /* memory offsets: order of Y11 Y12 Y21 Y22 U V */
int restart = p_jpeg->restart_interval; /* MCUs until restart marker */
/* pick the IDCT we want, determine how to work with coefs */
if (downscale == 1)
@ -1323,10 +1321,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
}
else return -1; /* not supported */
/* init bitstream */
/* init bitstream, fake a restart to make it start */
bs.next_input_byte = p_jpeg->p_entropy_data;
bs.bits_left = 0;
bs.next_input_word = p_jpeg->p_entropy_data;
bs.words_left = p_jpeg->words_in_buffer;
bs.input_end = p_jpeg->p_entropy_end;
width = p_jpeg->x_phys / downscale;
height = p_jpeg->y_phys / downscale;
@ -1340,7 +1338,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
store_offs[2] = width * 8 / downscale; /* below */
store_offs[3] = store_offs[1] + store_offs[2]; /* right+below */
for(y=0; y<p_jpeg->y_mbl; y++)
for(y=0; y<p_jpeg->y_mbl && bs.next_input_byte <= bs.input_end; y++)
{
p_byte = p_pixel;
p_pixel += skip_strip;
@ -1349,8 +1347,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
int blkn;
/* Outer loop handles each block in the MCU */
for (blkn = 0; blkn < p_jpeg->blocks && bs.words_left>=0; blkn++)
for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
{ /* Decode a single block's worth of coefficients */
int k = 1; /* coefficient index */
int s, r; /* huffman values */
@ -1368,7 +1365,7 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
block[0] = last_dc_val; /* output it (assumes zag[0] = 0) */
/* coefficient buffer must be cleared */
MEMSET(block+1, 0, zero_need*sizeof(int));
MEMSET(block+1, 0, zero_need*sizeof(block[0]));
/* Section F.2.2.2: decode the AC coefficients */
for (; k < k_need; k++)
@ -1418,11 +1415,17 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel, int downscale,
if (ci == 0)
{ /* only for Y component */
pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
pf_idct(p_byte+store_offs[blkn], block, p_jpeg->qt_idct[ti],
skip_line);
}
} /* for blkn */
p_byte += skip_mcu;
if (p_jpeg->restart_interval && --restart == 0)
{ /* if a restart marker is due: */
restart = p_jpeg->restart_interval; /* count again */
search_restart(&bs); /* align the bitstream */
last_dc_val = 0; /* reset decoder */
}
} /* for x */
if (pf_progress != NULL)
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,
return 0; /* success */
}
/**************** end JPEG code ********************/
@ -1765,6 +1769,8 @@ int main(char* filename)
buf_jpeg = (unsigned char*)(((int)buf + 1) & ~1);
buf += filesize;
buf_size -= filesize;
buf_root = buf; /* we can start the decompressed images behind it */
root_size = buf_size;
if (buf_size <= 0)
{
rb->splash(HZ*2, true, "out of memory");
@ -1795,14 +1801,6 @@ int main(char* filename)
default_huff_tbl(&jpg); /* use default */
build_lut(&jpg); /* derive Huffman and other lookup-tables */
/* I can correct the buffer now, re-gain what the removed markers took */
buf -= filesize; /* back to before */
buf_size += filesize;
buf += jpg.words_in_buffer * sizeof(short); /* real space */
buf_size -= jpg.words_in_buffer * sizeof(short);
buf_root = buf; /* we can start the images here */
root_size = buf_size;
rb->snprintf(print, sizeof(print), "image %d*%d", jpg.x_size, jpg.y_size);
rb->lcd_puts(0, 2, print);
rb->lcd_update();