From 0c847e515d2137caa5237c5739c4d8f96e35afc0 Mon Sep 17 00:00:00 2001 From: Philip Heron Date: Tue, 20 Oct 2015 00:15:15 +0100 Subject: [PATCH] Add an EOI (End of Image / Last Packet) flag to the encoder. Trim callsign correctly if longer than 6 characters. Add a verbose mode for the decoder. --- main.c | 28 ++++++++++++++++++++++++++-- ssdv.c | 42 +++++++++++++++++++++++------------------- ssdv.h | 5 ++++- 3 files changed, 53 insertions(+), 22 deletions(-) diff --git a/main.c b/main.c index cf4f4e1..a57ef01 100644 --- a/main.c +++ b/main.c @@ -47,6 +47,8 @@ int main(int argc, char *argv[]) char encode = -1; char type = SSDV_TYPE_NORMAL; int droptest = 0; + int verbose = 0; + int errors; char callsign[7]; uint8_t image_id = 0; ssdv_t ssdv; @@ -57,7 +59,7 @@ int main(int argc, char *argv[]) callsign[0] = '\0'; opterr = 0; - while((c = getopt(argc, argv, "ednc:i:t:")) != -1) + while((c = getopt(argc, argv, "ednc:i:t:v")) != -1) { switch(c) { @@ -71,6 +73,7 @@ int main(int argc, char *argv[]) break; case 'i': image_id = atoi(optarg); break; case 't': droptest = atoi(optarg); break; + case 'v': verbose = 1; break; case '?': exit_usage(); } } @@ -124,7 +127,28 @@ int main(int argc, char *argv[]) if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue; /* Test the packet is valid */ - if(ssdv_dec_is_packet(pkt, NULL, type) != 0) continue; + if(ssdv_dec_is_packet(pkt, &errors, type) != 0) continue; + + if(verbose) + { + ssdv_packet_info_t p; + + ssdv_dec_header(&p, pkt); + fprintf(stderr, "Decoded image packet. Callsign: %s, Image ID: %d, Resolution: %dx%d, Packet ID: %d (%d errors corrected)\n" + ">> EOI: %d, MCU Mode: %d, MCU Offset: %d, MCU ID: %d/%d\n", + p.callsign_s, + p.image_id, + p.width, + p.height, + p.packet_id, + errors, + p.eoi, + p.mcu_mode, + p.mcu_offset, + p.mcu_id, + p.mcu_count + ); + } /* Feed it to the decoder */ ssdv_dec_feed(&ssdv, pkt); diff --git a/ssdv.c b/ssdv.c index e93954f..2f9de6f 100644 --- a/ssdv.c +++ b/ssdv.c @@ -177,8 +177,8 @@ static uint32_t encode_callsign(char *callsign) uint32_t x; char *c; - /* Point c at the end of the callsign */ - for(c = callsign; *c; c++); + /* Point c at the end of the callsign, maximum of 6 characters */ + for(x = 0, c = callsign; x < SSDV_MAX_CALLSIGN && *c; x++, c++); /* Encode it backwards */ x = 0; @@ -960,21 +960,23 @@ char ssdv_enc_get_packet(ssdv_t *s) } /* A packet is ready, create the headers */ - s->out[0] = 0x55; /* Sync */ - s->out[1] = 0x66 + s->type; /* Type */ - s->out[2] = s->callsign >> 24; - s->out[3] = s->callsign >> 16; - s->out[4] = s->callsign >> 8; - s->out[5] = s->callsign; - s->out[6] = s->image_id; /* Image ID */ - s->out[7] = s->packet_id >> 8; /* Packet ID MSB */ - s->out[8] = s->packet_id & 0xFF; /* Packet ID LSB */ - s->out[9] = s->width >> 4; /* Width / 16 */ - s->out[10] = s->height >> 4; /* Height / 16 */ - s->out[11] = s->mcu_mode & 0x03; /* MCU mode (2 bits) */ - s->out[12] = mcu_offset; /* Next MCU offset */ - s->out[13] = mcu_id >> 8; /* MCU ID MSB */ - s->out[14] = mcu_id & 0xFF; /* MCU ID LSB */ + s->out[0] = 0x55; /* Sync */ + s->out[1] = 0x66 + s->type; /* Type */ + s->out[2] = s->callsign >> 24; + s->out[3] = s->callsign >> 16; + s->out[4] = s->callsign >> 8; + s->out[5] = s->callsign; + s->out[6] = s->image_id; /* Image ID */ + s->out[7] = s->packet_id >> 8; /* Packet ID MSB */ + s->out[8] = s->packet_id & 0xFF; /* Packet ID LSB */ + s->out[9] = s->width >> 4; /* Width / 16 */ + s->out[10] = s->height >> 4; /* Height / 16 */ + s->out[11] = 0x00; + s->out[11] |= (r == SSDV_EOI ? 1 : 0) << 2; /* EOI flag (1 bit) */ + s->out[11] |= s->mcu_mode & 0x03; /* MCU mode (2 bits) */ + s->out[12] = mcu_offset; /* Next MCU offset */ + s->out[13] = mcu_id >> 8; /* MCU ID MSB */ + s->out[14] = mcu_id & 0xFF; /* MCU ID LSB */ /* Fill any remaining bytes with noise */ if(s->out_len > 0) ssdv_memset_prng(s->outp, s->out_len); @@ -1173,7 +1175,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet) if(s->packet_id == 0) { const char *factor; - char callsign[7]; + char callsign[SSDV_MAX_CALLSIGN + 1]; /* Read the fixed headers from the packet */ s->callsign = (packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5]; @@ -1349,11 +1351,13 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t type) void ssdv_dec_header(ssdv_packet_info_t *info, uint8_t *packet) { - info->callsign = (packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5]; + info->callsign = (packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5]; + decode_callsign(info->callsign_s, info->callsign); info->image_id = packet[6]; info->packet_id = (packet[7] << 8) | packet[8]; info->width = packet[9] << 4; info->height = packet[10] << 4; + info->eoi = (packet[11] >> 2) & 1; info->mcu_mode = packet[11] & 0x03; info->mcu_offset = packet[12]; info->mcu_id = (packet[13] << 8) | packet[14]; diff --git a/ssdv.h b/ssdv.h index 956c113..eadc28b 100644 --- a/ssdv.h +++ b/ssdv.h @@ -39,7 +39,8 @@ extern "C" { #define TBL_LEN (546) /* Maximum size of the DQT and DHT tables */ #define HBUFF_LEN (16) /* Extra space for reading marker data */ -//#define COMPONENTS (3) + +#define SSDV_MAX_CALLSIGN (6) /* Maximum number of characters in a callsign */ #define SSDV_TYPE_NORMAL (0) #define SSDV_TYPE_NOFEC (1) @@ -126,10 +127,12 @@ typedef struct typedef struct { uint32_t callsign; + char callsign_s[SSDV_MAX_CALLSIGN + 1]; uint8_t image_id; uint16_t packet_id; uint16_t width; uint16_t height; + uint8_t eoi; uint16_t mcu_mode; uint8_t mcu_offset; uint16_t mcu_id;