mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
jpeg: use the Huffman tables the scan header selects
Both JPEG decoders ignored the DC/AC table selectors in the SOS header and always decoded luma with tables 0 and chroma with tables 1, the layout libjpeg writes by default. Files where all components share table 0, or where the slots are assigned differently, decoded to noise. Look up each component's tables from its selectors instead. Baseline JPEG only allows tables 0 and 1, which both decoders already hold, so this needs no extra memory; selectors above 1 are rejected. In the core loader tab_membership is no longer used and is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: Ie1ec407ddecf1256fef410b1256b97af412fb194
This commit is contained in:
parent
c12f6ebacd
commit
b897766a7a
3 changed files with 24 additions and 27 deletions
|
|
@ -638,6 +638,11 @@ int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
|
|||
p_jpeg->scanheader[i].ID = *p_src++;
|
||||
p_jpeg->scanheader[i].DC_select = *p_src >> 4;
|
||||
p_jpeg->scanheader[i].AC_select = *p_src++ & 0x0F;
|
||||
if (p_jpeg->scanheader[i].DC_select > 1
|
||||
|| p_jpeg->scanheader[i].AC_select > 1)
|
||||
{
|
||||
return (-5); /* Huffman table index out of range */
|
||||
}
|
||||
}
|
||||
p_src += 3; /* skip spectral information */
|
||||
p_jpeg->p_entropy_data = p_src;
|
||||
|
|
@ -1282,8 +1287,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[3],
|
|||
int s, r; /* huffman values */
|
||||
int ci = p_jpeg->mcu_membership[blkn]; /* component index */
|
||||
int ti = p_jpeg->tab_membership[blkn]; /* table index */
|
||||
struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
|
||||
struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
|
||||
struct derived_tbl* dctbl =
|
||||
&p_jpeg->dc_derived_tbls[p_jpeg->scanheader[ci].DC_select];
|
||||
struct derived_tbl* actbl =
|
||||
&p_jpeg->ac_derived_tbls[p_jpeg->scanheader[ci].AC_select];
|
||||
|
||||
/* Section F.2.2.1: decode the DC coefficient difference */
|
||||
s = huff_decode_dc(&bs, dctbl);
|
||||
|
|
@ -1453,8 +1460,10 @@ int jpeg_decode(struct jpeg* p_jpeg, unsigned char* p_pixel[1], int downscale,
|
|||
int s, r; /* huffman values */
|
||||
int ci = p_jpeg->mcu_membership[blkn]; /* component index */
|
||||
int ti = p_jpeg->tab_membership[blkn]; /* table index */
|
||||
struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
|
||||
struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
|
||||
struct derived_tbl* dctbl =
|
||||
&p_jpeg->dc_derived_tbls[p_jpeg->scanheader[ci].DC_select];
|
||||
struct derived_tbl* actbl =
|
||||
&p_jpeg->ac_derived_tbls[p_jpeg->scanheader[ci].AC_select];
|
||||
|
||||
/* Section F.2.2.1: decode the DC coefficient difference */
|
||||
s = huff_decode_dc(&bs, dctbl);
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct jpeg
|
|||
struct derived_tbl ac_derived_tbls[2];
|
||||
|
||||
struct frame_component frameheader[3]; /* Component descriptor */
|
||||
struct scan_component scanheader[3]; /* currently not used */
|
||||
struct scan_component scanheader[3]; /* Huffman tables per component */
|
||||
|
||||
int mcu_membership[6]; /* info per block */
|
||||
int tab_membership[6];
|
||||
|
|
|
|||
|
|
@ -128,10 +128,9 @@ struct jpeg
|
|||
struct derived_tbl ac_derived_tbls[2];
|
||||
|
||||
struct frame_component frameheader[3]; /* Component descriptor */
|
||||
struct scan_component scanheader[3]; /* currently not used */
|
||||
struct scan_component scanheader[3]; /* Huffman tables per component */
|
||||
|
||||
int mcu_membership[6]; /* info per block */
|
||||
int tab_membership[6];
|
||||
int subsample_x[3]; /* info per component */
|
||||
int subsample_y[3];
|
||||
bool resize;
|
||||
|
|
@ -1171,6 +1170,11 @@ static int process_markers(struct jpeg* p_jpeg)
|
|||
>> 4;
|
||||
p_jpeg->scanheader[i].AC_select = c & 0x0F;
|
||||
marker_size -= 2;
|
||||
if (p_jpeg->scanheader[i].DC_select > 1
|
||||
|| p_jpeg->scanheader[i].AC_select > 1)
|
||||
{
|
||||
return (-5); /* Huffman table index out of range */
|
||||
}
|
||||
}
|
||||
/* skip spectral information */
|
||||
e_skip_bytes(p_jpeg, marker_size);
|
||||
|
|
@ -1472,10 +1476,6 @@ INLINE void fix_headers(struct jpeg* p_jpeg)
|
|||
p_jpeg->mcu_membership[1] = 0;
|
||||
p_jpeg->mcu_membership[2] = 1;
|
||||
p_jpeg->mcu_membership[3] = 2;
|
||||
p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
|
||||
p_jpeg->tab_membership[1] = 0;
|
||||
p_jpeg->tab_membership[2] = 1;
|
||||
p_jpeg->tab_membership[3] = 1;
|
||||
p_jpeg->subsample_x[0] = 1;
|
||||
p_jpeg->subsample_x[1] = 2;
|
||||
p_jpeg->subsample_x[2] = 2;
|
||||
|
|
@ -1497,10 +1497,6 @@ INLINE void fix_headers(struct jpeg* p_jpeg)
|
|||
p_jpeg->mcu_membership[1] = 0;
|
||||
p_jpeg->mcu_membership[2] = 1;
|
||||
p_jpeg->mcu_membership[3] = 2;
|
||||
p_jpeg->tab_membership[0] = 0; /* DC, DC, AC, AC */
|
||||
p_jpeg->tab_membership[1] = 0;
|
||||
p_jpeg->tab_membership[2] = 1;
|
||||
p_jpeg->tab_membership[3] = 1;
|
||||
p_jpeg->subsample_x[0] = 1;
|
||||
p_jpeg->subsample_x[1] = 1;
|
||||
p_jpeg->subsample_x[2] = 1;
|
||||
|
|
@ -1522,12 +1518,6 @@ INLINE void fix_headers(struct jpeg* p_jpeg)
|
|||
p_jpeg->mcu_membership[3] = 0;
|
||||
p_jpeg->mcu_membership[4] = 1;
|
||||
p_jpeg->mcu_membership[5] = 2;
|
||||
p_jpeg->tab_membership[0] = 0;
|
||||
p_jpeg->tab_membership[1] = 0;
|
||||
p_jpeg->tab_membership[2] = 0;
|
||||
p_jpeg->tab_membership[3] = 0;
|
||||
p_jpeg->tab_membership[4] = 1;
|
||||
p_jpeg->tab_membership[5] = 1;
|
||||
p_jpeg->subsample_x[0] = 1;
|
||||
p_jpeg->subsample_x[1] = 2;
|
||||
p_jpeg->subsample_x[2] = 2;
|
||||
|
|
@ -1546,9 +1536,6 @@ INLINE void fix_headers(struct jpeg* p_jpeg)
|
|||
p_jpeg->mcu_membership[0] = 0;
|
||||
p_jpeg->mcu_membership[1] = 1;
|
||||
p_jpeg->mcu_membership[2] = 2;
|
||||
p_jpeg->tab_membership[0] = 0;
|
||||
p_jpeg->tab_membership[1] = 1;
|
||||
p_jpeg->tab_membership[2] = 1;
|
||||
p_jpeg->subsample_x[0] = 1;
|
||||
p_jpeg->subsample_x[1] = 1;
|
||||
p_jpeg->subsample_x[2] = 1;
|
||||
|
|
@ -1845,14 +1832,15 @@ static struct img_part *store_row_jpeg(void *jpeg_args)
|
|||
for (blkn = 0; blkn < p_jpeg->blocks; blkn++)
|
||||
{
|
||||
int ci = p_jpeg->mcu_membership[blkn]; /* component index */
|
||||
int ti = p_jpeg->tab_membership[blkn]; /* table index */
|
||||
#ifdef JPEG_IDCT_TRANSPOSE
|
||||
bool transpose = p_jpeg->v_scale[!!ci] > 2;
|
||||
#endif
|
||||
int k = 1; /* coefficient index */
|
||||
int s, r; /* huffman values */
|
||||
struct derived_tbl* dctbl = &p_jpeg->dc_derived_tbls[ti];
|
||||
struct derived_tbl* actbl = &p_jpeg->ac_derived_tbls[ti];
|
||||
struct derived_tbl* dctbl =
|
||||
&p_jpeg->dc_derived_tbls[p_jpeg->scanheader[ci].DC_select];
|
||||
struct derived_tbl* actbl =
|
||||
&p_jpeg->ac_derived_tbls[p_jpeg->scanheader[ci].AC_select];
|
||||
|
||||
/* Section F.2.2.1: decode the DC coefficient difference */
|
||||
huff_decode_dc(p_jpeg, dctbl, s, r);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue