mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
jpeg: decode 16-bit quantization tables (SOF1)
Both decoders rejected extended sequential JPEGs (SOF1), which are baseline files in all but name when they have 8-bit samples, and 16-bit quantization tables, which libjpeg writes for very low quality settings unless told to force baseline. Accept SOF1 with 8-bit samples, and read 16-bit table entries. The core loader keeps its tables in 16 bits and scales them for the IDCT, so it rejects entries over 8191; libjpeg's largest at quality 1 is 4950. Files using more than two Huffman tables are still rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: I705a61402b4a0ab252995f8559b7ff2f68b05d72
This commit is contained in:
parent
2890d4a40d
commit
dcee3ce62f
2 changed files with 28 additions and 14 deletions
|
|
@ -519,6 +519,7 @@ int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
|
|||
break;
|
||||
|
||||
case 0xC0: /* SOF Huff - Baseline DCT */
|
||||
case 0xC1: /* SOF Huff - Extended sequential DCT (8 bit samples) */
|
||||
{
|
||||
ret |= SOF0;
|
||||
marker_size = *p_src++ << 8; /* Highbyte */
|
||||
|
|
@ -569,7 +570,6 @@ int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0xC1: /* SOF Huff - Extended sequential DCT*/
|
||||
case 0xC2: /* SOF Huff - Progressive DCT*/
|
||||
case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
|
||||
case 0xC5: /* SOF Huff - Differential sequential DCT*/
|
||||
|
|
@ -695,18 +695,27 @@ int process_markers(unsigned char* p_src, long size, struct jpeg* p_jpeg)
|
|||
ret |= DQT;
|
||||
marker_size = *p_src++ << 8; /* Highbyte */
|
||||
marker_size |= *p_src++; /* Lowbyte */
|
||||
n = (marker_size-2)/(QUANT_TABLE_LENGTH+1); /* # of tables */
|
||||
for (i=0; i<n; i++)
|
||||
unsigned char *p_seg_end = p_src + marker_size - 2;
|
||||
while (p_seg_end - p_src > QUANT_TABLE_LENGTH) /* a table */
|
||||
{
|
||||
int id = *p_src++; /* ID */
|
||||
if (id >= 4)
|
||||
int id = *p_src++; /* Pq: precision, Tq: ID */
|
||||
int pq = id >> 4;
|
||||
id &= 0x0F;
|
||||
if (id >= 4 || pq > 1
|
||||
|| p_seg_end - p_src < QUANT_TABLE_LENGTH * (pq + 1))
|
||||
{
|
||||
return (-8); /* Unsupported quantization table */
|
||||
}
|
||||
/* Read Quantisation table: */
|
||||
for (j=0; j<QUANT_TABLE_LENGTH; j++)
|
||||
p_jpeg->quanttable[id][j] = *p_src++;
|
||||
{
|
||||
int q = *p_src++;
|
||||
if (pq) /* 16 bit entries (SOF1) */
|
||||
q = q << 8 | *p_src++;
|
||||
p_jpeg->quanttable[id][j] = q;
|
||||
}
|
||||
}
|
||||
p_src = p_seg_end;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -1019,6 +1019,7 @@ static int process_markers(struct jpeg* p_jpeg)
|
|||
break; /* discard */
|
||||
|
||||
case 0xC0: /* SOF Huff - Baseline DCT */
|
||||
case 0xC1: /* SOF Huff - Extended sequential DCT (8 bit samples) */
|
||||
{
|
||||
JDEBUGF("SOF marker ");
|
||||
ret |= SOF0;
|
||||
|
|
@ -1082,7 +1083,6 @@ static int process_markers(struct jpeg* p_jpeg)
|
|||
}
|
||||
break;
|
||||
|
||||
case 0xC1: /* SOF Huff - Extended sequential DCT*/
|
||||
case 0xC2: /* SOF Huff - Progressive DCT*/
|
||||
case 0xC3: /* SOF Huff - Spatial (sequential) lossless*/
|
||||
case 0xC5: /* SOF Huff - Differential sequential DCT*/
|
||||
|
|
@ -1231,20 +1231,25 @@ static int process_markers(struct jpeg* p_jpeg)
|
|||
marker_size |= e_getc(p_jpeg, -1); /* Lowbyte */
|
||||
marker_size -= 2;
|
||||
|
||||
n = (marker_size)/(QUANT_TABLE_LENGTH+1); /* # of tables */
|
||||
for (i=0; i<n; i++)
|
||||
while (marker_size > QUANT_TABLE_LENGTH) /* another table */
|
||||
{
|
||||
int id = e_getc(p_jpeg, -1); /* ID */
|
||||
marker_size--;
|
||||
if (id >= 4)
|
||||
int id = e_getc(p_jpeg, -1); /* Pq: precision, Tq: ID */
|
||||
int pq = id >> 4;
|
||||
id &= 0x0F;
|
||||
marker_size -= 1 + QUANT_TABLE_LENGTH * (pq + 1);
|
||||
if (id >= 4 || pq > 1 || marker_size < 0)
|
||||
{
|
||||
return (-8); /* Unsupported quantization table */
|
||||
}
|
||||
/* Read Quantisation table: */
|
||||
for (j=0; j<QUANT_TABLE_LENGTH; j++)
|
||||
{
|
||||
p_jpeg->quanttable[id][j] = e_getc(p_jpeg, -1);
|
||||
marker_size--;
|
||||
int q = e_getc(p_jpeg, -1);
|
||||
if (pq) /* 16 bit entries (SOF1) */
|
||||
q = q << 8 | e_getc(p_jpeg, -1);
|
||||
if (q > 8191)
|
||||
return (-8); /* too big once scaled for the IDCT */
|
||||
p_jpeg->quanttable[id][j] = q;
|
||||
}
|
||||
}
|
||||
e_skip_bytes(p_jpeg, marker_size);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue