Add option to override packet length from the standard 256 bytes
This commit is contained in:
parent
3f60ec89e9
commit
69944cb29a
32
main.c
32
main.c
|
@ -26,7 +26,8 @@
|
|||
void exit_usage()
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage: ssdv [-e|-d] [-n] [-t <percentage>] [-c <callsign>] [-i <id>] [-q <level>] [<in file>] [<out file>]\n"
|
||||
"\n"
|
||||
"Usage: ssdv [-e|-d] [-n] [-t <percentage>] [-c <callsign>] [-i <id>] [-q <level>] [-l <length>] [<in file>] [<out file>]\n"
|
||||
"\n"
|
||||
" -e Encode JPEG to SSDV packets.\n"
|
||||
" -d Decode SSDV packets to JPEG.\n"
|
||||
|
@ -36,7 +37,13 @@ void exit_usage()
|
|||
" -c Set the callign. Accepts A-Z 0-9 and space, up to 6 characters.\n"
|
||||
" -i Set the image ID (0-255).\n"
|
||||
" -q Set the JPEG quality level (0 to 7, defaults to 4).\n"
|
||||
" -l Set packet length in bytes (max: 256, default 256).\n"
|
||||
" -v Print data for each packet decoded.\n"
|
||||
"\n"
|
||||
"Packet Length\n"
|
||||
"\n"
|
||||
"The packet length must be specified for both encoding and decoding if not\n"
|
||||
"the default 256 bytes. Smaller packets will increase overhead.\n"
|
||||
"\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
@ -54,6 +61,7 @@ int main(int argc, char *argv[])
|
|||
char callsign[7];
|
||||
uint8_t image_id = 0;
|
||||
int8_t quality = 4;
|
||||
int pkt_length = SSDV_PKT_SIZE;
|
||||
ssdv_t ssdv;
|
||||
|
||||
uint8_t pkt[SSDV_PKT_SIZE], b[128], *jpeg;
|
||||
|
@ -62,7 +70,7 @@ int main(int argc, char *argv[])
|
|||
callsign[0] = '\0';
|
||||
|
||||
opterr = 0;
|
||||
while((c = getopt(argc, argv, "ednc:i:q:t:v")) != -1)
|
||||
while((c = getopt(argc, argv, "ednc:i:q:l:t:v")) != -1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
|
@ -77,6 +85,7 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
case 'i': image_id = atoi(optarg); break;
|
||||
case 'q': quality = atoi(optarg); break;
|
||||
case 'l': pkt_length = atoi(optarg); break;
|
||||
case 't': droptest = atoi(optarg); break;
|
||||
case 'v': verbose = 1; break;
|
||||
case '?': exit_usage();
|
||||
|
@ -117,22 +126,26 @@ int main(int argc, char *argv[])
|
|||
switch(encode)
|
||||
{
|
||||
case 0: /* Decode */
|
||||
|
||||
if(droptest > 0) fprintf(stderr, "*** NOTE: Drop test enabled: %i ***\n", droptest);
|
||||
|
||||
ssdv_dec_init(&ssdv);
|
||||
if(ssdv_dec_init(&ssdv, pkt_length) != SSDV_OK)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
jpeg_length = 1024 * 1024 * 4;
|
||||
jpeg = malloc(jpeg_length);
|
||||
ssdv_dec_set_buffer(&ssdv, jpeg, jpeg_length);
|
||||
|
||||
i = 0;
|
||||
while(fread(pkt, 1, SSDV_PKT_SIZE, fin) > 0)
|
||||
while(fread(pkt, 1, pkt_length, fin) > 0)
|
||||
{
|
||||
/* Drop % of packets */
|
||||
if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue;
|
||||
|
||||
/* Test the packet is valid */
|
||||
if(ssdv_dec_is_packet(pkt, &errors) != 0) continue;
|
||||
if(ssdv_dec_is_packet(pkt, pkt_length, &errors) != 0) continue;
|
||||
|
||||
if(verbose)
|
||||
{
|
||||
|
@ -171,7 +184,12 @@ int main(int argc, char *argv[])
|
|||
break;
|
||||
|
||||
case 1: /* Encode */
|
||||
ssdv_enc_init(&ssdv, type, callsign, image_id, quality);
|
||||
|
||||
if(ssdv_enc_init(&ssdv, type, callsign, image_id, quality, pkt_length) != SSDV_OK)
|
||||
{
|
||||
return(-1);
|
||||
}
|
||||
|
||||
ssdv_enc_set_buffer(&ssdv, pkt);
|
||||
|
||||
i = 0;
|
||||
|
@ -201,7 +219,7 @@ int main(int argc, char *argv[])
|
|||
return(-1);
|
||||
}
|
||||
|
||||
fwrite(pkt, 1, SSDV_PKT_SIZE, fout);
|
||||
fwrite(pkt, 1, pkt_length, fout);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
39
ssdv.c
39
ssdv.c
|
@ -643,12 +643,12 @@ static void ssdv_set_packet_conf(ssdv_t *s)
|
|||
switch(s->type)
|
||||
{
|
||||
case SSDV_TYPE_NORMAL:
|
||||
s->pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES;
|
||||
s->pkt_size_payload = s->pkt_size - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES;
|
||||
s->pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + s->pkt_size_payload - 1;
|
||||
break;
|
||||
|
||||
case SSDV_TYPE_NOFEC:
|
||||
s->pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC;
|
||||
s->pkt_size_payload = s->pkt_size - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC;
|
||||
s->pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + s->pkt_size_payload - 1;
|
||||
break;
|
||||
}
|
||||
|
@ -919,18 +919,27 @@ static char ssdv_have_marker_data(ssdv_t *s)
|
|||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
char ssdv_enc_init(ssdv_t *s, uint8_t type, char *callsign, uint8_t image_id, int8_t quality)
|
||||
char ssdv_enc_init(ssdv_t *s, uint8_t type, char *callsign, uint8_t image_id, int8_t quality, int pkt_size)
|
||||
{
|
||||
/* Limit the quality level */
|
||||
if(quality < 0) quality = 0;
|
||||
if(quality > 7) quality = 7;
|
||||
|
||||
/* Limit the packet length */
|
||||
if(pkt_size > SSDV_PKT_SIZE ||
|
||||
pkt_size - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - (type == SSDV_TYPE_NORMAL ? SSDV_PKT_SIZE_RSCODES : 0) < 2)
|
||||
{
|
||||
fprintf(stderr, "Invalid SSDV packet length\n");
|
||||
return(SSDV_ERROR);
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(ssdv_t));
|
||||
s->image_id = image_id;
|
||||
s->callsign = encode_callsign(callsign);
|
||||
s->mode = S_ENCODING;
|
||||
s->type = type;
|
||||
s->quality = quality;
|
||||
s->pkt_size = pkt_size;
|
||||
ssdv_set_packet_conf(s);
|
||||
|
||||
/* Prepare the output JPEG tables */
|
||||
|
@ -951,7 +960,7 @@ char ssdv_enc_set_buffer(ssdv_t *s, uint8_t *buffer)
|
|||
s->out_len = s->pkt_size_payload;
|
||||
|
||||
/* Zero the payload memory */
|
||||
memset(s->out, 0, SSDV_PKT_SIZE);
|
||||
memset(s->out, 0, s->pkt_size);
|
||||
|
||||
/* Flush the output bits */
|
||||
ssdv_outbits(s, 0, 0);
|
||||
|
@ -1210,9 +1219,17 @@ static void ssdv_fill_gap(ssdv_t *s, uint16_t next_mcu)
|
|||
}
|
||||
}
|
||||
|
||||
char ssdv_dec_init(ssdv_t *s)
|
||||
char ssdv_dec_init(ssdv_t *s, int pkt_size)
|
||||
{
|
||||
/* Limit the packet length */
|
||||
if(pkt_size > SSDV_PKT_SIZE)
|
||||
{
|
||||
fprintf(stderr, "Invalid SSDV packet length\n");
|
||||
return(SSDV_ERROR);
|
||||
}
|
||||
|
||||
memset(s, 0, sizeof(ssdv_t));
|
||||
s->pkt_size = pkt_size;
|
||||
|
||||
/* The packet data should contain only scan data, no headers */
|
||||
s->state = S_HUFF;
|
||||
|
@ -1407,7 +1424,7 @@ 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)
|
||||
char ssdv_dec_is_packet(uint8_t *packet, int pkt_size, int *errors)
|
||||
{
|
||||
uint8_t pkt[SSDV_PKT_SIZE];
|
||||
uint8_t type;
|
||||
|
@ -1418,7 +1435,7 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors)
|
|||
int i;
|
||||
|
||||
/* Testing is destructive, work on a copy */
|
||||
memcpy(pkt, packet, SSDV_PKT_SIZE);
|
||||
memcpy(pkt, packet, pkt_size);
|
||||
pkt[0] = 0x55;
|
||||
|
||||
type = SSDV_TYPE_INVALID;
|
||||
|
@ -1426,7 +1443,7 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors)
|
|||
if(pkt[1] == 0x66 + SSDV_TYPE_NOFEC)
|
||||
{
|
||||
/* Test for a valid NOFEC packet */
|
||||
pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC;
|
||||
pkt_size_payload = pkt_size - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC;
|
||||
pkt_size_crcdata = SSDV_PKT_SIZE_HEADER + pkt_size_payload - 1;
|
||||
|
||||
/* No FEC scan */
|
||||
|
@ -1445,7 +1462,7 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors)
|
|||
else if(pkt[1] == 0x66 + SSDV_TYPE_NORMAL)
|
||||
{
|
||||
/* Test for a valid NORMAL packet */
|
||||
pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES;
|
||||
pkt_size_payload = 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;
|
||||
|
||||
/* No FEC scan */
|
||||
|
@ -1465,7 +1482,7 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors)
|
|||
if(type == SSDV_TYPE_INVALID)
|
||||
{
|
||||
/* Test for a valid NORMAL packet with correctable errors */
|
||||
pkt_size_payload = SSDV_PKT_SIZE - SSDV_PKT_SIZE_HEADER - SSDV_PKT_SIZE_CRC - SSDV_PKT_SIZE_RSCODES;
|
||||
pkt_size_payload = 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 */
|
||||
|
@ -1504,7 +1521,7 @@ char ssdv_dec_is_packet(uint8_t *packet, int *errors)
|
|||
}
|
||||
|
||||
/* Appears to be a valid packet! Copy it back */
|
||||
memcpy(packet, pkt, SSDV_PKT_SIZE);
|
||||
memcpy(packet, pkt, pkt_size);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
11
ssdv.h
11
ssdv.h
|
@ -49,10 +49,11 @@ extern "C" {
|
|||
typedef struct
|
||||
{
|
||||
/* Packet type configuration */
|
||||
uint8_t type; /* 0 = Normal mode (224 byte packet + 32 bytes FEC),
|
||||
1 = No-FEC mode (256 byte packet) */
|
||||
uint8_t type; /* 0 = Normal mode (nom. 224 byte packet + 32 bytes FEC),
|
||||
1 = No-FEC mode (nom. 256 byte packet) */
|
||||
uint16_t pkt_size_payload;
|
||||
uint16_t pkt_size_crcdata;
|
||||
int pkt_size;
|
||||
|
||||
/* Image information */
|
||||
uint16_t width;
|
||||
|
@ -146,18 +147,18 @@ typedef struct {
|
|||
} ssdv_packet_info_t;
|
||||
|
||||
/* Encoding */
|
||||
extern char ssdv_enc_init(ssdv_t *s, uint8_t type, char *callsign, uint8_t image_id, int8_t quality);
|
||||
extern char ssdv_enc_init(ssdv_t *s, uint8_t type, char *callsign, uint8_t image_id, int8_t quality, int pkt_size);
|
||||
extern char ssdv_enc_set_buffer(ssdv_t *s, uint8_t *buffer);
|
||||
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);
|
||||
extern char ssdv_dec_init(ssdv_t *s, int pkt_size);
|
||||
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);
|
||||
extern char ssdv_dec_is_packet(uint8_t *packet, int pkt_size, int *errors);
|
||||
extern void ssdv_dec_header(ssdv_packet_info_t *info, uint8_t *packet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue