Further image corruption fixes.
This commit is contained in:
parent
94db83a707
commit
3310c6f0c3
49
ssdv.c
49
ssdv.c
|
@ -425,9 +425,16 @@ static char ssdv_process(ssdv_t *s)
|
||||||
uint8_t symbol, width;
|
uint8_t symbol, width;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
if(s->mcupart == 0 && s->acpart == 0 && s->next_reset_mcu > s->reset_mcu)
|
||||||
|
{
|
||||||
|
s->reset_mcu = s->next_reset_mcu;
|
||||||
|
}
|
||||||
|
|
||||||
/* Lookup the code, return if error or not enough bits yet */
|
/* Lookup the code, return if error or not enough bits yet */
|
||||||
if((r = jpeg_dht_lookup(s, &symbol, &width)) != SSDV_OK)
|
if((r = jpeg_dht_lookup(s, &symbol, &width)) != SSDV_OK)
|
||||||
|
{
|
||||||
return(r);
|
return(r);
|
||||||
|
}
|
||||||
|
|
||||||
if(s->acpart == 0) /* DC */
|
if(s->acpart == 0) /* DC */
|
||||||
{
|
{
|
||||||
|
@ -436,7 +443,10 @@ static char ssdv_process(ssdv_t *s)
|
||||||
/* No change in DC from last block */
|
/* No change in DC from last block */
|
||||||
if(s->reset_mcu == s->mcu_id && (s->mcupart == 0 || s->mcupart >= s->ycparts))
|
if(s->reset_mcu == s->mcu_id && (s->mcupart == 0 || s->mcupart >= s->ycparts))
|
||||||
{
|
{
|
||||||
if(s->mode == S_ENCODING) ssdv_out_jpeg_int(s, 0, s->adc[s->component]);
|
if(s->mode == S_ENCODING)
|
||||||
|
{
|
||||||
|
ssdv_out_jpeg_int(s, 0, s->adc[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]);
|
||||||
|
@ -576,19 +586,17 @@ static char ssdv_process(ssdv_t *s)
|
||||||
/* For greyscale input images, pad the 2x1 MCUs with empty colour blocks */
|
/* For greyscale input images, pad the 2x1 MCUs with empty colour blocks */
|
||||||
for(; s->mcupart < s->ycparts + 2; s->mcupart++)
|
for(; s->mcupart < s->ycparts + 2; s->mcupart++)
|
||||||
{
|
{
|
||||||
if(s->mcupart < s->ycparts) s->component = 0;
|
s->component = s->mcupart - s->ycparts + 1;
|
||||||
else s->component = s->mcupart - s->ycparts + 1;
|
|
||||||
s->acpart = 0; ssdv_out_jpeg_int(s, 0, 0); /* DC */
|
s->acpart = 0; ssdv_out_jpeg_int(s, 0, 0); /* DC */
|
||||||
s->acpart = 1; ssdv_out_jpeg_int(s, 0, 0); /* AC */
|
s->acpart = 1; ssdv_out_jpeg_int(s, 0, 0); /* AC */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reached the end of this MCU part */
|
/* Reached the end of this MCU */
|
||||||
if(s->mcupart == s->ycparts + 2)
|
if(s->mcupart == s->ycparts + 2)
|
||||||
{
|
{
|
||||||
s->mcupart = 0;
|
s->mcupart = 0;
|
||||||
s->mcu_id++;
|
s->mcu_id++;
|
||||||
s->reset_mcu = s->next_reset_mcu;
|
|
||||||
|
|
||||||
/* Test for the end of image */
|
/* Test for the end of image */
|
||||||
if(s->mcu_id >= s->mcu_count)
|
if(s->mcu_id >= s->mcu_count)
|
||||||
|
@ -604,14 +612,9 @@ static char ssdv_process(ssdv_t *s)
|
||||||
/* The first MCU of each packet should be byte aligned */
|
/* The first MCU of each packet should be byte aligned */
|
||||||
ssdv_outbits_sync(s);
|
ssdv_outbits_sync(s);
|
||||||
|
|
||||||
s->next_reset_mcu = s->reset_mcu = s->mcu_id;
|
s->next_reset_mcu = s->mcu_id;
|
||||||
s->packet_mcu_id = s->mcu_id;
|
s->packet_mcu_id = s->mcu_id;
|
||||||
s->packet_mcu_offset = s->pkt_size_payload - s->out_len;
|
s->packet_mcu_offset = s->pkt_size_payload - s->out_len + ((s->outlen + 7) / 8);
|
||||||
}
|
|
||||||
|
|
||||||
if(s->mode == S_DECODING && s->mcu_id == s->reset_mcu)
|
|
||||||
{
|
|
||||||
s->workbits = s->worklen = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test for a reset marker */
|
/* Test for a reset marker */
|
||||||
|
@ -1257,9 +1260,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
||||||
|
|
||||||
if(s->packet_mcu_id != 0xFFFF)
|
if(s->packet_mcu_id != 0xFFFF)
|
||||||
{
|
{
|
||||||
/* Set the next reset MCU ID. We can't set it
|
/* Set the next reset MCU ID */
|
||||||
* directly here as the previous MCU may still
|
|
||||||
* be being processed. */
|
|
||||||
s->next_reset_mcu = s->packet_mcu_id;
|
s->next_reset_mcu = s->packet_mcu_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1316,14 +1317,11 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
||||||
fprintf(stderr, "Gap detected between packets %i and %i\n", s->packet_id - 1, packet_id);
|
fprintf(stderr, "Gap detected between packets %i and %i\n", s->packet_id - 1, packet_id);
|
||||||
|
|
||||||
/* If this packet has no new MCU, ignore */
|
/* If this packet has no new MCU, ignore */
|
||||||
if(s->packet_mcu_offset == 0xFF) return(SSDV_FEED_ME);
|
if(s->packet_mcu_id == 0xFFFF) return(SSDV_FEED_ME);
|
||||||
|
|
||||||
/* Fill the gap left by the missing packet */
|
/* Fill the gap left by the missing packet */
|
||||||
ssdv_fill_gap(s, s->packet_mcu_id);
|
ssdv_fill_gap(s, s->packet_mcu_id);
|
||||||
|
|
||||||
/* Clear the workbits */
|
|
||||||
s->workbits = s->worklen = 0;
|
|
||||||
|
|
||||||
/* Skip the bytes of the lost MCU */
|
/* Skip the bytes of the lost MCU */
|
||||||
i = s->packet_mcu_offset;
|
i = s->packet_mcu_offset;
|
||||||
|
|
||||||
|
@ -1337,15 +1335,16 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
||||||
s->packet_id = packet_id;
|
s->packet_id = packet_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear the work area if there is no overlap from previous packet */
|
|
||||||
if(s->packet_mcu_offset == 0)
|
|
||||||
{
|
|
||||||
s->workbits = s->worklen = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Feed the JPEG data into the processor */
|
/* Feed the JPEG data into the processor */
|
||||||
for(; i < s->pkt_size_payload; i++)
|
for(; i < s->pkt_size_payload; i++)
|
||||||
{
|
{
|
||||||
|
if(i == s->packet_mcu_offset)
|
||||||
|
{
|
||||||
|
/* The first MCU in a packet is byte aligned,
|
||||||
|
* any old bits should be dropped. */
|
||||||
|
s->workbits = s->worklen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
b = packet[SSDV_PKT_SIZE_HEADER + i];
|
b = packet[SSDV_PKT_SIZE_HEADER + i];
|
||||||
|
|
||||||
/* Add the new byte to the work area */
|
/* Add the new byte to the work area */
|
||||||
|
|
Loading…
Reference in New Issue