diff --git a/main.c b/main.c index 51a14a3..4b4e4c4 100644 --- a/main.c +++ b/main.c @@ -31,7 +31,7 @@ void exit_usage() " -e Encode JPEG to SSDV packets.\n" " -d Decode SSDV packets to JPEG.\n" "\n" - " -n Encode or decode packets with no FEC.\n" + " -n Encode packets with no FEC.\n" " -t For testing, drops the specified percentage of packets while decoding.\n" " -c Set the callign. Accepts A-Z 0-9 and space, up to 6 characters.\n" " -i Set the image ID (0-255).\n" @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) case 0: /* Decode */ if(droptest > 0) fprintf(stderr, "*** NOTE: Drop test enabled: %i ***\n", droptest); - ssdv_dec_init(&ssdv, type); + ssdv_dec_init(&ssdv); jpeg_length = 1024 * 1024 * 4; jpeg = malloc(jpeg_length); @@ -128,7 +128,7 @@ 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, &errors, type) != 0) continue; + if(ssdv_dec_is_packet(pkt, &errors) != 0) continue; if(verbose) { @@ -136,13 +136,14 @@ int main(int argc, char *argv[]) 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", + ">> Type: %d, 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.type, p.eoi, p.mcu_mode, p.mcu_offset, diff --git a/ssdv.c b/ssdv.c index 2f9de6f..6211039 100644 --- a/ssdv.c +++ b/ssdv.c @@ -1115,15 +1115,13 @@ static void ssdv_fill_gap(ssdv_t *s, uint16_t next_mcu) } } -char ssdv_dec_init(ssdv_t *s, uint8_t type) +char ssdv_dec_init(ssdv_t *s) { memset(s, 0, sizeof(ssdv_t)); /* The packet data should contain only scan data, no headers */ s->state = S_HUFF; s->mode = S_DECODING; - s->type = type; - ssdv_set_packet_conf(s); /* Prepare the source JPEG tables */ s->sdqt[0] = stblcpy(s, std_dqt0, sizeof(std_dqt0)); @@ -1178,6 +1176,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet) char callsign[SSDV_MAX_CALLSIGN + 1]; /* Read the fixed headers from the packet */ + s->type = packet[1] - 0x66; s->callsign = (packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5]; s->image_id = packet[6]; s->width = packet[9] << 4; @@ -1185,6 +1184,9 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet) s->mcu_count = packet[9] * packet[10]; s->mcu_mode = packet[11] & 0x03; + /* Configure the payload size and CRC position */ + ssdv_set_packet_conf(s); + switch(s->mcu_mode) { case 0: factor = "2x2"; s->ycparts = 4; break; @@ -1284,9 +1286,10 @@ char ssdv_dec_get_jpeg(ssdv_t *s, uint8_t **jpeg, size_t *length) return(SSDV_OK); } -char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t type) +char ssdv_dec_is_packet(uint8_t *packet, int *errors) { uint8_t pkt[SSDV_PKT_SIZE]; + uint8_t type; uint16_t pkt_size_payload; uint16_t pkt_size_crcdata; ssdv_packet_info_t p; @@ -1296,37 +1299,35 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t type) /* Testing is destructive, work on a copy */ memcpy(pkt, packet, SSDV_PKT_SIZE); pkt[0] = 0x55; - pkt[1] = 0x66 + type; - switch(type) + if(pkt[1] == 0x66 + SSDV_TYPE_NOFEC) { - case SSDV_TYPE_NORMAL: - pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES; - pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + pkt_size_payload - 1; + type = SSDV_TYPE_NOFEC; - /* Run the reed-solomon decoder */ - i = decode_rs_8(&pkt[1], 0, 0, 0); - if(errors) *errors = 0; - - break; - - case SSDV_TYPE_NOFEC: pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC; pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + pkt_size_payload - 1; if(errors) *errors = 0; + } + else + { + type = SSDV_TYPE_NORMAL; - break; - - default: - fprintf(stderr, "Invalid packet type\n"); - return(-1); + pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES; + pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + pkt_size_payload - 1; + + /* Run the reed-solomon decoder */ + pkt[1] = 0x66 + SSDV_TYPE_NORMAL; + i = decode_rs_8(&pkt[1], 0, 0, 0); + + if(i < 0) return(-1); /* Reed-solomon decoder failed */ + if(errors) *errors = i; } /* Sanity checks */ - if(pkt[1] != 0x66 + type) return(-1); - ssdv_dec_header(&p, pkt); + + if(p.type != type) return(-1); if(p.width == 0 || p.height == 0) return(-1); if(p.mcu_id != 0xFFFF) { @@ -1351,6 +1352,7 @@ 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->type = packet[1] - 0x66; 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]; diff --git a/ssdv.h b/ssdv.h index eadc28b..abaea38 100644 --- a/ssdv.h +++ b/ssdv.h @@ -126,6 +126,7 @@ typedef struct } ssdv_t; typedef struct { + uint8_t type; uint32_t callsign; char callsign_s[SSDV_MAX_CALLSIGN + 1]; uint8_t image_id; @@ -146,12 +147,12 @@ extern char ssdv_enc_get_packet(ssdv_t *s); extern char ssdv_enc_feed(ssdv_t *s, uint8_t *buffer, size_t length); /* Decoding */ -extern char ssdv_dec_init(ssdv_t *s, uint8_t type); +extern char ssdv_dec_init(ssdv_t *s); extern char ssdv_dec_set_buffer(ssdv_t *s, uint8_t *buffer, size_t length); extern char ssdv_dec_feed(ssdv_t *s, uint8_t *packet); extern char ssdv_dec_get_jpeg(ssdv_t *s, uint8_t **jpeg, size_t *length); -extern char ssdv_dec_is_packet(uint8_t *packet, int *errors, uint8_t fec); +extern char ssdv_dec_is_packet(uint8_t *packet, int *errors); extern void ssdv_dec_header(ssdv_packet_info_t *info, uint8_t *packet); #ifdef __cplusplus