From fe7ff490746e82ba1c1766872f6b3ee29f84724a Mon Sep 17 00:00:00 2001 From: Philip Heron Date: Sun, 29 Jan 2012 18:56:17 +0000 Subject: [PATCH] Only reset the MCU DC values for the first MCU on each packet --- .gitignore | 2 +- ssdv.c | 37 ++++++++++++++++++++++++++----------- ssdv.h | 10 ++++++---- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 3318b89..57592d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ ssdv *.o *.jpeg -*.bin +*.bin* diff --git a/ssdv.c b/ssdv.c index fe01018..25bb505 100644 --- a/ssdv.c +++ b/ssdv.c @@ -314,9 +314,9 @@ static char ssdv_process(ssdv_t *s) if(symbol == 0x00) { /* No change in DC from last block */ - if(s->mcupart == 0 || s->mcupart == 4 || s->mcupart == 5) + if(s->reset_mcu == s->mcu_id && (s->mcupart == 0 || s->mcupart == 4 || s->mcupart == 5)) { - if(s->dcmode == 0) ssdv_out_jpeg_int(s, 0, AADJ(s->dc[s->component])); + if(s->mode == S_ENCODING) ssdv_out_jpeg_int(s, 0, s->adc[s->component]); else { ssdv_out_jpeg_int(s, 0, 0 - s->dc[s->component]); @@ -376,13 +376,14 @@ static char ssdv_process(ssdv_t *s) if(s->acpart == 0) /* DC */ { - if(s->mcupart == 0 || s->mcupart == 4 || s->mcupart == 5) + if(s->reset_mcu == s->mcu_id && (s->mcupart == 0 || s->mcupart == 4 || s->mcupart == 5)) { - if(s->dcmode == 0) + if(s->mode == S_ENCODING) { /* Output absolute DC value */ s->dc[s->component] += UADJ(i); - ssdv_out_jpeg_int(s, 0, AADJ(s->dc[s->component])); + s->adc[s->component] = AADJ(s->dc[s->component]); + ssdv_out_jpeg_int(s, 0, s->adc[s->component]); } else { @@ -393,9 +394,21 @@ static char ssdv_process(ssdv_t *s) } else { - /* Output relative DC value */ - s->dc[s->component] += UADJ(i); - ssdv_out_jpeg_int(s, 0, BADJ(i)); + if(s->mode == S_DECODING) + { + s->dc[s->component] += UADJ(i); + ssdv_out_jpeg_int(s, 0, i); + } + else + { + /* Output relative DC value */ + s->dc[s->component] += UADJ(i); + + /* Calculate closest adjusted DC value */ + i = AADJ(s->dc[s->component]); + ssdv_out_jpeg_int(s, 0, i - s->adc[s->component]); + s->adc[s->component] = i; + } } } else /* AC */ @@ -453,6 +466,7 @@ static char ssdv_process(ssdv_t *s) /* Set the packet MCU marker - encoder only */ if(s->packet_mcu_id == 0xFFFF) { + if(s->mode == S_ENCODING) s->reset_mcu = s->mcu_id; s->packet_mcu_id = s->mcu_id; s->packet_mcu_offset = (SSDV_PKT_SIZE_PAYLOAD - s->out_len) * 8 + s->outlen; @@ -677,6 +691,7 @@ char ssdv_enc_init(ssdv_t *s, uint8_t image_id) { memset(s, 0, sizeof(ssdv_t)); s->image_id = image_id; + s->mode = S_ENCODING; return(SSDV_OK); } @@ -933,9 +948,7 @@ char ssdv_dec_init(ssdv_t *s) /* The packet data should contain only scan data, no headers */ s->state = S_HUFF; - - /* Converting absolute values to relative */ - s->dcmode = 1; + s->mode = S_DECODING; return(SSDV_OK); } @@ -965,6 +978,8 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet) s->packet_mcu_offset = (packet[7] << 8) | packet[8]; s->packet_mcu_id = (packet[9] << 8) | packet[10]; + if(s->packet_mcu_id != 0xFFFF) s->reset_mcu = s->packet_mcu_id; + /* If this is the first packet, write the JPEG headers */ if(s->packet_id == 0) { diff --git a/ssdv.h b/ssdv.h index 7216730..5d03a7a 100644 --- a/ssdv.h +++ b/ssdv.h @@ -89,17 +89,19 @@ typedef struct uint8_t mcupart; /* 0-3 = Y, 4 = Cb, 5 = Cr */ uint8_t acpart; /* 0 - 64; 0 = DC, 1 - 64 = AC */ int dc[COMPONENTS]; /* DC value for each component */ + int adc[COMPONENTS];/* DC adjusted value for each component */ 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) */ + enum { + S_ENCODING = 0, + S_DECODING, + } mode; + uint32_t reset_mcu; /* MCU block to do absolute encoding */ char needbits; /* Number of bits needed to decode integer */ /* Small buffer for reading SOF0 and SOS header data into */ uint8_t hbuff[HBUFF_LEN]; - /* SSDV2 experiment */ - int block[64]; - } ssdv_t; typedef struct {