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.
This commit is contained in:
parent
84ccbf972d
commit
0c847e515d
28
main.c
28
main.c
|
@ -47,6 +47,8 @@ int main(int argc, char *argv[])
|
||||||
char encode = -1;
|
char encode = -1;
|
||||||
char type = SSDV_TYPE_NORMAL;
|
char type = SSDV_TYPE_NORMAL;
|
||||||
int droptest = 0;
|
int droptest = 0;
|
||||||
|
int verbose = 0;
|
||||||
|
int errors;
|
||||||
char callsign[7];
|
char callsign[7];
|
||||||
uint8_t image_id = 0;
|
uint8_t image_id = 0;
|
||||||
ssdv_t ssdv;
|
ssdv_t ssdv;
|
||||||
|
@ -57,7 +59,7 @@ int main(int argc, char *argv[])
|
||||||
callsign[0] = '\0';
|
callsign[0] = '\0';
|
||||||
|
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
while((c = getopt(argc, argv, "ednc:i:t:")) != -1)
|
while((c = getopt(argc, argv, "ednc:i:t:v")) != -1)
|
||||||
{
|
{
|
||||||
switch(c)
|
switch(c)
|
||||||
{
|
{
|
||||||
|
@ -71,6 +73,7 @@ int main(int argc, char *argv[])
|
||||||
break;
|
break;
|
||||||
case 'i': image_id = atoi(optarg); break;
|
case 'i': image_id = atoi(optarg); break;
|
||||||
case 't': droptest = atoi(optarg); break;
|
case 't': droptest = atoi(optarg); break;
|
||||||
|
case 'v': verbose = 1; break;
|
||||||
case '?': exit_usage();
|
case '?': exit_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,7 +127,28 @@ int main(int argc, char *argv[])
|
||||||
if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue;
|
if(droptest && (rand() / (RAND_MAX / 100) < droptest)) continue;
|
||||||
|
|
||||||
/* Test the packet is valid */
|
/* 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 */
|
/* Feed it to the decoder */
|
||||||
ssdv_dec_feed(&ssdv, pkt);
|
ssdv_dec_feed(&ssdv, pkt);
|
||||||
|
|
42
ssdv.c
42
ssdv.c
|
@ -177,8 +177,8 @@ static uint32_t encode_callsign(char *callsign)
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
char *c;
|
char *c;
|
||||||
|
|
||||||
/* Point c at the end of the callsign */
|
/* Point c at the end of the callsign, maximum of 6 characters */
|
||||||
for(c = callsign; *c; c++);
|
for(x = 0, c = callsign; x < SSDV_MAX_CALLSIGN && *c; x++, c++);
|
||||||
|
|
||||||
/* Encode it backwards */
|
/* Encode it backwards */
|
||||||
x = 0;
|
x = 0;
|
||||||
|
@ -960,21 +960,23 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A packet is ready, create the headers */
|
/* A packet is ready, create the headers */
|
||||||
s->out[0] = 0x55; /* Sync */
|
s->out[0] = 0x55; /* Sync */
|
||||||
s->out[1] = 0x66 + s->type; /* Type */
|
s->out[1] = 0x66 + s->type; /* Type */
|
||||||
s->out[2] = s->callsign >> 24;
|
s->out[2] = s->callsign >> 24;
|
||||||
s->out[3] = s->callsign >> 16;
|
s->out[3] = s->callsign >> 16;
|
||||||
s->out[4] = s->callsign >> 8;
|
s->out[4] = s->callsign >> 8;
|
||||||
s->out[5] = s->callsign;
|
s->out[5] = s->callsign;
|
||||||
s->out[6] = s->image_id; /* Image ID */
|
s->out[6] = s->image_id; /* Image ID */
|
||||||
s->out[7] = s->packet_id >> 8; /* Packet ID MSB */
|
s->out[7] = s->packet_id >> 8; /* Packet ID MSB */
|
||||||
s->out[8] = s->packet_id & 0xFF; /* Packet ID LSB */
|
s->out[8] = s->packet_id & 0xFF; /* Packet ID LSB */
|
||||||
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] = 0x00;
|
||||||
s->out[12] = mcu_offset; /* Next MCU offset */
|
s->out[11] |= (r == SSDV_EOI ? 1 : 0) << 2; /* EOI flag (1 bit) */
|
||||||
s->out[13] = mcu_id >> 8; /* MCU ID MSB */
|
s->out[11] |= s->mcu_mode & 0x03; /* MCU mode (2 bits) */
|
||||||
s->out[14] = mcu_id & 0xFF; /* MCU ID LSB */
|
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 */
|
/* 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);
|
||||||
|
@ -1173,7 +1175,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
||||||
if(s->packet_id == 0)
|
if(s->packet_id == 0)
|
||||||
{
|
{
|
||||||
const char *factor;
|
const char *factor;
|
||||||
char callsign[7];
|
char callsign[SSDV_MAX_CALLSIGN + 1];
|
||||||
|
|
||||||
/* Read the fixed headers from the packet */
|
/* Read the fixed headers from the packet */
|
||||||
s->callsign = (packet[2] << 24) | (packet[3] << 16) | (packet[4] << 8) | packet[5];
|
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)
|
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->image_id = packet[6];
|
||||||
info->packet_id = (packet[7] << 8) | packet[8];
|
info->packet_id = (packet[7] << 8) | packet[8];
|
||||||
info->width = packet[9] << 4;
|
info->width = packet[9] << 4;
|
||||||
info->height = packet[10] << 4;
|
info->height = packet[10] << 4;
|
||||||
|
info->eoi = (packet[11] >> 2) & 1;
|
||||||
info->mcu_mode = packet[11] & 0x03;
|
info->mcu_mode = packet[11] & 0x03;
|
||||||
info->mcu_offset = packet[12];
|
info->mcu_offset = packet[12];
|
||||||
info->mcu_id = (packet[13] << 8) | packet[14];
|
info->mcu_id = (packet[13] << 8) | packet[14];
|
||||||
|
|
5
ssdv.h
5
ssdv.h
|
@ -39,7 +39,8 @@ extern "C" {
|
||||||
|
|
||||||
#define TBL_LEN (546) /* Maximum size of the DQT and DHT tables */
|
#define TBL_LEN (546) /* Maximum size of the DQT and DHT tables */
|
||||||
#define HBUFF_LEN (16) /* Extra space for reading marker data */
|
#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_NORMAL (0)
|
||||||
#define SSDV_TYPE_NOFEC (1)
|
#define SSDV_TYPE_NOFEC (1)
|
||||||
|
@ -126,10 +127,12 @@ typedef struct
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t callsign;
|
uint32_t callsign;
|
||||||
|
char callsign_s[SSDV_MAX_CALLSIGN + 1];
|
||||||
uint8_t image_id;
|
uint8_t image_id;
|
||||||
uint16_t packet_id;
|
uint16_t packet_id;
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
|
uint8_t eoi;
|
||||||
uint16_t mcu_mode;
|
uint16_t mcu_mode;
|
||||||
uint8_t mcu_offset;
|
uint8_t mcu_offset;
|
||||||
uint16_t mcu_id;
|
uint16_t mcu_id;
|
||||||
|
|
Loading…
Reference in New Issue