Further image corruption fixes.

This commit is contained in:
Philip Heron 2018-06-27 20:06:01 +01:00
parent 94db83a707
commit 3310c6f0c3
1 changed files with 24 additions and 25 deletions

49
ssdv.c
View File

@ -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 */