kopia lustrzana https://github.com/fsphil/hadie
Handle the end of image better, and AC RLE fix
rodzic
ba17274a5a
commit
829baad2bc
2
hadie.c
2
hadie.c
|
@ -65,7 +65,7 @@ char tx_image(void)
|
|||
return(setup);
|
||||
}
|
||||
|
||||
if(c3_eof())
|
||||
if(ssdv.state == S_EOI || c3_eof())
|
||||
{
|
||||
/* The end of the image has been reached */
|
||||
c3_close();
|
||||
|
|
47
ssdv.c
47
ssdv.c
|
@ -202,7 +202,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;
|
||||
|
@ -226,7 +226,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;
|
||||
}
|
||||
}
|
||||
|
@ -242,14 +242,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;
|
||||
|
@ -260,7 +260,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;
|
||||
|
||||
|
@ -295,7 +295,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;
|
||||
|
@ -350,13 +350,17 @@ 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_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;
|
||||
}
|
||||
|
||||
|
@ -392,12 +396,12 @@ static char ssdv_have_marker_data(ssdv_t *s)
|
|||
if(d[0] != 3) return(SSDV_ERROR);
|
||||
|
||||
/* The SOS data is followed by the image data */
|
||||
s->state = J_HUFF;
|
||||
s->state = S_HUFF;
|
||||
|
||||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
s->state = J_MARKER;
|
||||
s->state = S_MARKER;
|
||||
return(SSDV_OK);
|
||||
}
|
||||
|
||||
|
@ -428,6 +432,9 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
int r;
|
||||
uint8_t b;
|
||||
|
||||
/* Have we reached the end of the image? */
|
||||
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);
|
||||
|
||||
|
@ -441,7 +448,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 ||
|
||||
|
@ -455,12 +462,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)
|
||||
{
|
||||
|
@ -469,7 +476,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)
|
||||
{
|
||||
|
@ -477,8 +484,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++;
|
||||
|
@ -526,7 +533,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);
|
||||
}
|
||||
|
@ -536,6 +543,10 @@ char ssdv_enc_get_packet(ssdv_t *s)
|
|||
return(SSDV_ERROR);
|
||||
}
|
||||
break;
|
||||
|
||||
case S_EOI:
|
||||
/* Shouldn't reach this point */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
9
ssdv.h
9
ssdv.h
|
@ -59,7 +59,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 */
|
||||
|
|
Ładowanie…
Reference in New Issue