First attempt at handling non-standard DQT tables in source image

This commit is contained in:
Philip Heron 2011-06-24 22:01:08 +01:00
parent abd4181863
commit 2c90f35f92
2 changed files with 38 additions and 11 deletions

48
ssdv.c
View File

@ -118,6 +118,15 @@ static uint8_t *sdht_ac[3] = { std_dht10, std_dht11, std_dht11 };
static uint8_t *dht_dc[3] = { std_dht00, std_dht01, std_dht01 }; static uint8_t *dht_dc[3] = { std_dht00, std_dht01, std_dht01 };
static uint8_t *dht_ac[3] = { std_dht10, std_dht11, std_dht11 }; static uint8_t *dht_ac[3] = { std_dht10, std_dht11, std_dht11 };
/* Helpers for looking up the current DQT values */
#define SDQT (sdqt[s->component][1 + s->acpart])
#define DDQT (dqt[s->component][1 + s->acpart])
/* Helpers for converting between DQT tables */
#define AADJ(i) (SDQT == DDQT ? (i) : (i / DDQT))
#define UADJ(i) (SDQT == DDQT ? (i) : (i * SDQT))
#define BADJ(i) (SDQT == DDQT ? (i) : (i * SDQT / DDQT))
/* /*
static char *strbits(uint32_t value, uint8_t bits) static char *strbits(uint32_t value, uint8_t bits)
{ {
@ -278,10 +287,6 @@ static char ssdv_out_jpeg_int(ssdv_t *s, uint8_t rle, int value)
if(s->acpart == 0) dht = dht_dc[s->component]; if(s->acpart == 0) dht = dht_dc[s->component];
else dht = dht_ac[s->component]; else dht = dht_ac[s->component];
/* Adjust for output DQT */
//value *= sdqt[s->component][1 + s->acpart];
//value /= dqt[s->component][1 + s->acpart];
jpeg_encode_int(value, &intbits, &intlen); jpeg_encode_int(value, &intbits, &intlen);
r = jpeg_dht_lookup_symbol(dht, (rle << 4) | (intlen & 0x0F), &huffbits, &hufflen); r = jpeg_dht_lookup_symbol(dht, (rle << 4) | (intlen & 0x0F), &huffbits, &hufflen);
@ -311,7 +316,7 @@ static char ssdv_process(ssdv_t *s)
/* No change in DC from last block */ /* No change in DC from last block */
if(s->mcupart == 0 || s->mcupart == 4 || s->mcupart == 5) if(s->mcupart == 0 || s->mcupart == 4 || s->mcupart == 5)
{ {
if(s->dcmode == 0) ssdv_out_jpeg_int(s, 0, s->dc[s->component]); if(s->dcmode == 0) ssdv_out_jpeg_int(s, 0, AADJ(s->dc[s->component]));
else else
{ {
ssdv_out_jpeg_int(s, 0, 0 - s->dc[s->component]); ssdv_out_jpeg_int(s, 0, 0 - s->dc[s->component]);
@ -376,8 +381,8 @@ static char ssdv_process(ssdv_t *s)
if(s->dcmode == 0) if(s->dcmode == 0)
{ {
/* Output absolute DC value */ /* Output absolute DC value */
s->dc[s->component] += i; s->dc[s->component] += UADJ(i);
ssdv_out_jpeg_int(s, 0, s->dc[s->component]); ssdv_out_jpeg_int(s, 0, AADJ(s->dc[s->component]));
} }
else else
{ {
@ -389,14 +394,33 @@ static char ssdv_process(ssdv_t *s)
else else
{ {
/* Output relative DC value */ /* Output relative DC value */
s->dc[s->component] += i; s->dc[s->component] += UADJ(i);
ssdv_out_jpeg_int(s, 0, i); ssdv_out_jpeg_int(s, 0, BADJ(i));
} }
} }
else /* AC */ else /* AC */
{ {
/* Output AC codes directly */ if((i = BADJ(i)))
ssdv_out_jpeg_int(s, s->acrle, i); {
s->accrle += s->acrle;
while(s->accrle >= 16)
{
ssdv_out_jpeg_int(s, 15, 0);
s->accrle -= 16;
}
ssdv_out_jpeg_int(s, s->accrle, i);
s->accrle = 0;
}
else
{
/* AC value got reduced to 0 in the DQT conversion */
if(s->acpart >= 63)
{
ssdv_out_jpeg_int(s, 0, 0);
s->accrle = 0;
}
else s->accrle += s->acrle + 1;
}
} }
/* Next AC part to expect */ /* Next AC part to expect */
@ -439,6 +463,7 @@ static char ssdv_process(ssdv_t *s)
else s->component = s->mcupart - 3; else s->component = s->mcupart - 3;
s->acpart = 0; s->acpart = 0;
s->accrle = 0;
} }
if(s->out_len == 0) return(SSDV_BUFFER_FULL); if(s->out_len == 0) return(SSDV_BUFFER_FULL);
@ -976,6 +1001,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
s->component = 0; s->component = 0;
s->mcupart = 0; s->mcupart = 0;
s->acpart = 0; s->acpart = 0;
s->accrle = 0;
s->packet_id = packet_id; s->packet_id = packet_id;
} }

1
ssdv.h
View File

@ -90,6 +90,7 @@ typedef struct
uint8_t acpart; /* 0 - 64; 0 = DC, 1 - 64 = AC */ uint8_t acpart; /* 0 - 64; 0 = DC, 1 - 64 = AC */
int dc[COMPONENTS]; /* DC value for each component */ int dc[COMPONENTS]; /* DC value for each component */
uint8_t acrle; /* RLE value for current AC value */ uint8_t acrle; /* RLE value for current AC value */
uint8_t accrle; /* Accumulative RLE value */
char dcmode; /* 0 = Absolute, 1 = Relative (parts 0, 4 & 5) */ char dcmode; /* 0 = Absolute, 1 = Relative (parts 0, 4 & 5) */
char needbits; /* Number of bits needed to decode integer */ char needbits; /* Number of bits needed to decode integer */