kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Fix AC RLE bug, and some tidyup
rodzic
0c74c11c2c
commit
0636d3c4ed
|
@ -55,7 +55,14 @@ typedef struct
|
|||
uint8_t outlen; /* Number of bits in the output bit buffer */
|
||||
|
||||
/* JPEG decoder state */
|
||||
enum { J_MARKER = 0, J_MARKER_LEN, J_MARKER_DATA, J_HUFF, J_INT } state;
|
||||
enum {
|
||||
S_MARKER = 0,
|
||||
S_MARKER_LEN,
|
||||
S_MARKER_DATA,
|
||||
S_HUFF,
|
||||
S_INT,
|
||||
S_EOI,
|
||||
} state;
|
||||
uint16_t marker; /* Current marker */
|
||||
uint16_t marker_len; /* Length of data following marker */
|
||||
uint8_t *marker_data; /* Where to copy marker data too */
|
||||
|
@ -91,11 +98,10 @@ 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_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);
|
||||
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
|
||||
|
|
|
@ -44,6 +44,7 @@ private:
|
|||
int image_width;
|
||||
int image_height;
|
||||
int image_lost_packets;
|
||||
int image_errors;
|
||||
|
||||
/* Private functions */
|
||||
void feed_buffer(uint8_t byte);
|
||||
|
|
|
@ -25,11 +25,6 @@ static uint8_t app0[14] = {
|
|||
0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x00,0x48,0x00,0x48,0x00,0x00,
|
||||
};
|
||||
|
||||
/* SOF0 header data */
|
||||
static uint8_t sof0[15] = {
|
||||
0x08,0x00,0xF0,0x01,0x40,0x03,0x01,0x22,0x00,0x02,0x11,0x01,0x03,0x11,0x01,
|
||||
};
|
||||
|
||||
/* SOS header data */
|
||||
static uint8_t sos[10] = {
|
||||
0x03,0x01,0x00,0x02,0x11,0x03,0x11,0x00,0x3F,0x00,
|
||||
|
@ -242,7 +237,7 @@ static char ssdv_out_jpeg_int(ssdv_t *s, uint8_t rle, int value)
|
|||
|
||||
static char ssdv_process(ssdv_t *s)
|
||||
{
|
||||
if(s->state == J_HUFF)
|
||||
if(s->state == S_HUFF)
|
||||
{
|
||||
uint8_t symbol, width;
|
||||
int r;
|
||||
|
@ -273,7 +268,7 @@ static char ssdv_process(ssdv_t *s)
|
|||
else
|
||||
{
|
||||
/* DC value follows, 'symbol' bits wide */
|
||||
s->state = J_INT;
|
||||
s->state = S_INT;
|
||||
s->needbits = symbol;
|
||||
}
|
||||
}
|
||||
|
@ -288,14 +283,14 @@ static char ssdv_process(ssdv_t *s)
|
|||
}
|
||||
else if(symbol == 0xF0)
|
||||
{
|
||||
/* The next 15 AC parts are zero */
|
||||
/* The next 16 AC parts are zero */
|
||||
ssdv_out_jpeg_int(s, 15, 0);
|
||||
s->acpart += 15;
|
||||
s->acpart += 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Next bits are an integer value */
|
||||
s->state = J_INT;
|
||||
s->state = S_INT;
|
||||
s->acrle = symbol >> 4;
|
||||
s->acpart += s->acrle;
|
||||
s->needbits = symbol & 0x0F;
|
||||
|
@ -306,7 +301,7 @@ static char ssdv_process(ssdv_t *s)
|
|||
s->worklen -= width;
|
||||
s->workbits &= (1 << s->worklen) - 1;
|
||||
}
|
||||
else if(s->state == J_INT)
|
||||
else if(s->state == S_INT)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -350,7 +345,7 @@ static char ssdv_process(ssdv_t *s)
|
|||
s->acpart++;
|
||||
|
||||
/* Next bits are a huffman code */
|
||||
s->state = J_HUFF;
|
||||
s->state = S_HUFF;
|
||||
|
||||
/* Clear processed bits */
|
||||
s->worklen -= s->needbits;
|
||||
|
@ -405,7 +400,7 @@ static char ssdv_have_marker(ssdv_t *s)
|
|||
|
||||
s->marker_data = s->hbuff;
|
||||
s->marker_data_len = 0;
|
||||
s->state = J_MARKER_DATA;
|
||||
s->state = S_MARKER_DATA;
|
||||
break;
|
||||
|
||||
case J_DHT:
|
||||
|
@ -413,13 +408,17 @@ static char ssdv_have_marker(ssdv_t *s)
|
|||
/* Copy the tables into memory */
|
||||
s->marker_data = malloc(s->marker_len);
|
||||
s->marker_data_len = 0;
|
||||
s->state = J_MARKER_DATA;
|
||||
s->state = S_MARKER_DATA;
|
||||
break;
|
||||
|
||||
case J_EOI:
|
||||
s->state = S_EOI;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Ignore other marks, skipping any associated data */
|
||||
s->in_skip = s->marker_len;
|
||||
s->state = J_MARKER;
|
||||
s->state = S_MARKER;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -497,7 +496,7 @@ static char ssdv_have_marker_data(ssdv_t *s)
|
|||
/* 00 3F 00 */
|
||||
|
||||
/* The SOS data is followed by the image data */
|
||||
s->state = J_HUFF;
|
||||
s->state = S_HUFF;
|
||||
|
||||
return(SSDV_OK);
|
||||
|
||||
|
@ -518,7 +517,7 @@ static char ssdv_have_marker_data(ssdv_t *s)
|
|||
break;
|
||||
}
|
||||
|
||||
s->state = J_MARKER;
|
||||
s->state = S_MARKER;
|
||||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
|
@ -549,6 +548,8 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
int r;
|
||||
uint8_t b;
|
||||
|
||||
if(s->state == S_EOI) return(SSDV_EOI);
|
||||
|
||||
/* If the output buffer is empty, re-initialise */
|
||||
if(s->out_len == 0) ssdv_enc_set_buffer(s, s->out);
|
||||
|
||||
|
@ -562,7 +563,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
|
||||
switch(s->state)
|
||||
{
|
||||
case J_MARKER:
|
||||
case S_MARKER:
|
||||
s->marker = (s->marker << 8) | b;
|
||||
|
||||
if(s->marker == J_TEM ||
|
||||
|
@ -576,12 +577,12 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
{
|
||||
/* All other markers are followed by data */
|
||||
s->marker_len = 0;
|
||||
s->state = J_MARKER_LEN;
|
||||
s->state = S_MARKER_LEN;
|
||||
s->needbits = 16;
|
||||
}
|
||||
break;
|
||||
|
||||
case J_MARKER_LEN:
|
||||
case S_MARKER_LEN:
|
||||
s->marker_len = (s->marker_len << 8) | b;
|
||||
if((s->needbits -= 8) == 0)
|
||||
{
|
||||
|
@ -590,7 +591,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
}
|
||||
break;
|
||||
|
||||
case J_MARKER_DATA:
|
||||
case S_MARKER_DATA:
|
||||
s->marker_data[s->marker_data_len++] = b;
|
||||
if(s->marker_data_len == s->marker_len)
|
||||
{
|
||||
|
@ -598,8 +599,8 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
}
|
||||
break;
|
||||
|
||||
case J_HUFF:
|
||||
case J_INT:
|
||||
case S_HUFF:
|
||||
case S_INT:
|
||||
/* Is the next byte a stuffing byte? Skip it */
|
||||
/* TODO: Test the next byte is actually 0x00 */
|
||||
if(b == 0xFF) s->in_skip++;
|
||||
|
@ -647,7 +648,7 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
s->packet_id++;
|
||||
|
||||
/* Have we reached the end of the image data? */
|
||||
if(r == SSDV_EOI) s->state = J_MARKER;
|
||||
if(r == SSDV_EOI) s->state = S_EOI;
|
||||
|
||||
return(SSDV_OK);
|
||||
}
|
||||
|
@ -658,6 +659,10 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
return(SSDV_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case S_EOI:
|
||||
/* Shouldn't reach this point */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -686,11 +691,31 @@ static void ssdv_write_marker(ssdv_t *s, uint16_t id, uint16_t length, uint8_t *
|
|||
|
||||
static void ssdv_out_headers(ssdv_t *s)
|
||||
{
|
||||
uint8_t *b = s->hbuff;
|
||||
|
||||
ssdv_write_marker(s, J_SOI, 0, 0);
|
||||
ssdv_write_marker(s, J_APP0, 14, app0);
|
||||
ssdv_write_marker(s, J_DQT, 65, dqt0); /* DQT Luminance */
|
||||
ssdv_write_marker(s, J_DQT, 65, dqt1); /* DQT Chrominance */
|
||||
ssdv_write_marker(s, J_SOF0, 15, sof0); /* SOF0 (Baseline DCT) */
|
||||
|
||||
/* Build SOF0 header */
|
||||
b[0] = 8; /* Precision */
|
||||
b[1] = s->height >> 8;
|
||||
b[2] = s->height & 0xFF;
|
||||
b[3] = s->width >> 8;
|
||||
b[4] = s->width & 0xFF;
|
||||
b[5] = 3; /* Components (Y'Cb'Cr) */
|
||||
b[6] = 1; /* Y */
|
||||
b[7] = 0x22;
|
||||
b[8] = 0x00;
|
||||
b[9] = 2; /* Cb */
|
||||
b[10] = 0x11;
|
||||
b[11] = 0x01;
|
||||
b[12] = 3; /* Cr */
|
||||
b[13] = 0x11;
|
||||
b[14] = 0x01;
|
||||
ssdv_write_marker(s, J_SOF0, 15, b); /* SOF0 (Baseline DCT) */
|
||||
|
||||
ssdv_write_marker(s, J_DHT, 29, dht00); /* DHT (DC Luminance) */
|
||||
ssdv_write_marker(s, J_DHT, 179, dht10); /* DHT (AC Luminance) */
|
||||
ssdv_write_marker(s, J_DHT, 29, dht01); /* DHT (DC Chrominance */
|
||||
|
@ -740,7 +765,7 @@ 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 = J_HUFF;
|
||||
s->state = S_HUFF;
|
||||
|
||||
/* Converting absolute values to relative */
|
||||
s->dcmode = 1;
|
||||
|
@ -757,20 +782,6 @@ char ssdv_dec_init(ssdv_t *s)
|
|||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
//char ssdv_dec_set_buffer(ssdv_t *s, uint8_t *buffer, size_t length)
|
||||
//{
|
||||
// size_t c = s->outp - s->out;
|
||||
//
|
||||
// s->outp = buffer + c;
|
||||
// s->out = buffer;
|
||||
// s->out_len = length - c;
|
||||
//
|
||||
// /* Flush the output bits */
|
||||
// ssdv_outbits(s, 0, 0);
|
||||
//
|
||||
// return(SSDV_OK);
|
||||
//}
|
||||
|
||||
char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
||||
{
|
||||
int i = 0, r;
|
||||
|
@ -825,7 +836,7 @@ char ssdv_dec_feed(ssdv_t *s, uint8_t *packet)
|
|||
}
|
||||
|
||||
/* Reset the JPEG decoder state */
|
||||
s->state = J_HUFF;
|
||||
s->state = S_HUFF;
|
||||
s->component = 0;
|
||||
s->mcupart = 0;
|
||||
s->acpart = 0;
|
||||
|
@ -897,7 +908,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)
|
||||
char ssdv_dec_is_packet(uint8_t *packet, int *errors)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -909,6 +920,8 @@ char ssdv_dec_is_packet(uint8_t *packet)
|
|||
if(i < 0) return(-1); /* Reed-solomon decoder failed */
|
||||
if(i > 0) fprintf(stderr, "ssdv: %i bytes corrected\n", i);
|
||||
|
||||
if(errors) *errors = i;
|
||||
|
||||
/* Appears to be a valid packet */
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -379,7 +379,10 @@ void ssdv_rx::put_byte(uint8_t byte, int lost)
|
|||
|
||||
/* Test if this is a packet and is valid */
|
||||
uint8_t *b = &buffer[bc];
|
||||
if(ssdv_dec_is_packet(b) != 0) return;
|
||||
if(ssdv_dec_is_packet(b, &i) != 0) return;
|
||||
|
||||
/* Make a note of the number of errors */
|
||||
image_errors += i;
|
||||
|
||||
/* Packet received.. upload to server */
|
||||
if(progdefaults.dl_online) upload_packet();
|
||||
|
@ -398,6 +401,7 @@ void ssdv_rx::put_byte(uint8_t byte, int lost)
|
|||
image_width = pkt_info.width;
|
||||
image_height = pkt_info.height;
|
||||
image_lost_packets = 0;
|
||||
image_errors = 0;
|
||||
|
||||
/* Clear the image buffer */
|
||||
memset(image, 0x80, IMG_SIZE);
|
||||
|
@ -446,19 +450,9 @@ void ssdv_rx::put_byte(uint8_t byte, int lost)
|
|||
habCustom->color(FL_GREEN);
|
||||
}
|
||||
|
||||
/* TODO: Dynamic allocation */
|
||||
//size_t length = 128 * 1024;
|
||||
//uint8_t *jpeg = (uint8_t *) malloc(length);
|
||||
//if(!jpeg)
|
||||
//{
|
||||
// perror("malloc");
|
||||
// return;
|
||||
//}
|
||||
|
||||
/* Initialise the decoder */
|
||||
ssdv_t dec;
|
||||
ssdv_dec_init(&dec);
|
||||
//ssdv_dec_set_buffer(&dec, jpeg, length);
|
||||
|
||||
image_lost_packets = 0;
|
||||
for(i = 0; i < packets_len; i++)
|
||||
|
@ -499,8 +493,8 @@ void ssdv_rx::put_byte(uint8_t byte, int lost)
|
|||
snprintf(s, 16, "%d", image_lost_packets);
|
||||
flmissing->copy_label(s);
|
||||
|
||||
//snprintf(s, 16, "%d", img_errors);
|
||||
//flfixes->copy_label(s);
|
||||
snprintf(s, 16, "%d", image_errors);
|
||||
flfixes->copy_label(s);
|
||||
|
||||
flprogress->maximum(dec.mcu_count);
|
||||
flprogress->value(mcu_id);
|
||||
|
|
Ładowanie…
Reference in New Issue