Byte-align the first MCU of each packet

This commit is contained in:
Philip Heron 2012-03-04 09:43:52 +00:00
parent 723c6bc426
commit fe8a1a642c
3 changed files with 31 additions and 36 deletions

View File

@ -3,7 +3,7 @@ CC=gcc
CFLAGS=-g -Wall CFLAGS=-g -Wall
LDFLAGS=-g -lm LDFLAGS=-g -lm
ssdv: main.o ssdv.o rs8.o ssdv: main.o ssdv.o rs8.o ssdv.h rs8.h
$(CC) $(LDFLAGS) main.o ssdv.o rs8.o -o ssdv $(CC) $(LDFLAGS) main.o ssdv.o rs8.o -o ssdv
.c.o: .c.o:

57
ssdv.c
View File

@ -514,14 +514,19 @@ static char ssdv_process(ssdv_t *s)
} }
/* Set the packet MCU marker - encoder only */ /* Set the packet MCU marker - encoder only */
if(s->packet_mcu_id == 0xFFFF) if(s->mode == S_ENCODING && s->packet_mcu_id == 0xFFFF)
{ {
if(s->mode == S_ENCODING) s->reset_mcu = s->mcu_id; /* The first MCU of each packet should be byte aligned */
ssdv_outbits_sync(s);
s->reset_mcu = s->mcu_id;
s->packet_mcu_id = s->mcu_id; s->packet_mcu_id = s->mcu_id;
s->packet_mcu_offset = s->packet_mcu_offset = SSDV_PKT_SIZE_PAYLOAD - s->out_len;
(SSDV_PKT_SIZE_PAYLOAD - s->out_len) * 8 + s->outlen;
} }
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 */
if(s->dri > 0 && s->mcu_id > 0 && s->mcu_id % s->dri == 0) if(s->dri > 0 && s->mcu_id > 0 && s->mcu_id % s->dri == 0)
{ {
@ -908,19 +913,21 @@ char ssdv_enc_get_packet(ssdv_t *s)
if(r == SSDV_BUFFER_FULL || r == SSDV_EOI) if(r == SSDV_BUFFER_FULL || r == SSDV_EOI)
{ {
uint16_t mcu_id = s->packet_mcu_id; uint16_t mcu_id = s->packet_mcu_id;
uint16_t mcu_offset = s->packet_mcu_offset; uint8_t mcu_offset = s->packet_mcu_offset;
uint16_t i, x; uint16_t i, x;
if(mcu_offset != 0xFFFF && mcu_offset >= SSDV_PKT_SIZE_PAYLOAD * 8) if(mcu_offset != 0xFF && mcu_offset >= SSDV_PKT_SIZE_PAYLOAD)
{ {
/* The first MCU begins in the next packet, not this one */ /* The first MCU begins in the next packet, not this one */
mcu_id = mcu_offset = 0xFFFF; mcu_id = 0xFFFF;
s->packet_mcu_offset -= SSDV_PKT_SIZE_PAYLOAD * 8; mcu_offset = 0xFF;
s->packet_mcu_offset -= SSDV_PKT_SIZE_PAYLOAD;
} }
else else
{ {
/* Clear the MCU data for the next packet */ /* Clear the MCU data for the next packet */
s->packet_mcu_id = s->packet_mcu_offset = 0xFFFF; s->packet_mcu_id = 0xFFFF;
s->packet_mcu_offset = 0xFF;
} }
/* A packet is ready, create the headers */ /* A packet is ready, create the headers */
@ -936,10 +943,9 @@ char ssdv_enc_get_packet(ssdv_t *s)
s->out[9] = s->width >> 4; /* Width / 16 */ s->out[9] = s->width >> 4; /* Width / 16 */
s->out[10] = s->height >> 4; /* Height / 16 */ s->out[10] = s->height >> 4; /* Height / 16 */
s->out[11] = s->mcu_mode & 0x03; /* MCU mode (2 bits) */ s->out[11] = s->mcu_mode & 0x03; /* MCU mode (2 bits) */
s->out[12] = mcu_offset >> 8; /* Next MCU offset MSB */ s->out[12] = mcu_offset; /* Next MCU offset */
s->out[13] = mcu_offset & 0xFF; /* Next MCU offset LSB */ s->out[13] = mcu_id >> 8; /* MCU ID MSB */
s->out[14] = mcu_id >> 8; /* MCU ID MSB */ s->out[14] = mcu_id & 0xFF; /* MCU ID LSB */
s->out[15] = mcu_id & 0xFF; /* MCU ID LSB */
/* Fill any remaining bytes with noise */ /* Fill any remaining bytes with noise */
if(s->out_len > 0) ssdv_memset_prng(s->outp, s->out_len); if(s->out_len > 0) ssdv_memset_prng(s->outp, s->out_len);
@ -1124,8 +1130,8 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
/* Read the packet header */ /* Read the packet header */
packet_id = (packet[7] << 8) | packet[8]; packet_id = (packet[7] << 8) | packet[8];
s->packet_mcu_offset = (packet[12] << 8) | packet[13]; s->packet_mcu_offset = packet[12];
s->packet_mcu_id = (packet[14] << 8) | packet[15]; s->packet_mcu_id = (packet[13] << 8) | packet[14];
if(s->packet_mcu_id != 0xFFFF) s->reset_mcu = s->packet_mcu_id; if(s->packet_mcu_id != 0xFFFF) s->reset_mcu = s->packet_mcu_id;
@ -1170,7 +1176,7 @@ 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 == 0xFFFF) return(SSDV_FEED_ME); if(s->packet_mcu_offset == 0xFF) 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);
@ -1179,18 +1185,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
s->workbits = s->worklen = 0; s->workbits = s->worklen = 0;
/* Skip the bytes of the lost MCU */ /* Skip the bytes of the lost MCU */
i = s->packet_mcu_offset >> 3; i = s->packet_mcu_offset;
/* Skip any remaining bits too */
if((r = s->packet_mcu_offset & 7))
{
/* Add the first bits of the new MCU */
r = 8 - r;
b = packet[SSDV_PKT_SIZE_HEADER + i++];
b &= ((1 << r) - 1);
s->workbits = b;
s->worklen += r;
}
/* Reset the JPEG decoder state */ /* Reset the JPEG decoder state */
s->state = S_HUFF; s->state = S_HUFF;
@ -1278,7 +1273,7 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors)
if(p.mcu_id != 0xFFFF) if(p.mcu_id != 0xFFFF)
{ {
if(p.mcu_id >= p.mcu_count) return(-1); if(p.mcu_id >= p.mcu_count) return(-1);
if(p.mcu_offset >= SSDV_PKT_SIZE_PAYLOAD * 8) return(-1); if(p.mcu_offset >= SSDV_PKT_SIZE_PAYLOAD) return(-1);
} }
/* Test the checksum */ /* Test the checksum */
@ -1302,8 +1297,8 @@ void ssdv_dec_header(ssdv_packet_info_t *info, uint8_t *packet)
info->width = packet[9] << 4; info->width = packet[9] << 4;
info->height = packet[10] << 4; info->height = packet[10] << 4;
info->mcu_mode = packet[11] & 0x03; info->mcu_mode = packet[11] & 0x03;
info->mcu_offset = (packet[12] << 8) | packet[13]; info->mcu_offset = packet[12];
info->mcu_id = (packet[14] << 8) | packet[15]; info->mcu_id = (packet[13] << 8) | packet[14];
info->mcu_count = packet[9] * packet[10]; info->mcu_count = packet[9] * packet[10];
if(info->mcu_mode == 1 || info->mcu_mode == 2) info->mcu_count *= 2; if(info->mcu_mode == 1 || info->mcu_mode == 2) info->mcu_count *= 2;
else if(info->mcu_mode == 3) info->mcu_count *= 4; else if(info->mcu_mode == 3) info->mcu_count *= 4;

6
ssdv.h
View File

@ -33,7 +33,7 @@ extern "C" {
/* Packet details */ /* Packet details */
#define SSDV_PKT_SIZE (0x100) #define SSDV_PKT_SIZE (0x100)
#define SSDV_PKT_SIZE_HEADER (0x10) #define SSDV_PKT_SIZE_HEADER (0x0F)
#define SSDV_PKT_SIZE_CRC (0x02) #define SSDV_PKT_SIZE_CRC (0x02)
#define SSDV_PKT_SIZE_RSCODES (0x20) #define SSDV_PKT_SIZE_RSCODES (0x20)
#define SSDV_PKT_SIZE_PAYLOAD (SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES) #define SSDV_PKT_SIZE_PAYLOAD (SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES)
@ -54,7 +54,7 @@ typedef struct
uint16_t mcu_id; uint16_t mcu_id;
uint16_t mcu_count; uint16_t mcu_count;
uint16_t packet_mcu_id; uint16_t packet_mcu_id;
uint16_t packet_mcu_offset; uint8_t packet_mcu_offset;
/* Source buffer */ /* Source buffer */
uint8_t *inp; /* Pointer to next input byte */ uint8_t *inp; /* Pointer to next input byte */
@ -123,7 +123,7 @@ typedef struct {
uint16_t width; uint16_t width;
uint16_t height; uint16_t height;
uint16_t mcu_mode; uint16_t mcu_mode;
uint16_t mcu_offset; uint8_t mcu_offset;
uint16_t mcu_id; uint16_t mcu_id;
uint16_t mcu_count; uint16_t mcu_count;
} ssdv_packet_info_t; } ssdv_packet_info_t;