summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ufodecode.c120
1 files changed, 54 insertions, 66 deletions
diff --git a/src/ufodecode.c b/src/ufodecode.c
index e96dff3..776cc61 100644
--- a/src/ufodecode.c
+++ b/src/ufodecode.c
@@ -36,7 +36,6 @@
/**
* Check that flag evaluates to non-zero.
*/
-
#ifdef DEBUG
# define CHECK_FLAG(flag, check, ...) \
if (!(check)) { \
@@ -50,7 +49,6 @@
}
#endif
-
/**
* \brief Setup a new decoder instance
*
@@ -64,10 +62,11 @@
*/
ufo_decoder ufo_decoder_new(uint32_t height, uint32_t width, uint32_t *raw, size_t num_bytes)
{
- if (width%IPECAMERA_PIXELS_PER_CHANNEL)
- return NULL;
+ if (width % IPECAMERA_PIXELS_PER_CHANNEL)
+ return NULL;
ufo_decoder decoder = malloc(sizeof(struct ufo_decoder_t));
+
if (decoder == NULL)
return NULL;
@@ -77,7 +76,6 @@ ufo_decoder ufo_decoder_new(uint32_t height, uint32_t width, uint32_t *raw, size
return decoder;
}
-
/**
* \brief Release decoder instance
*
@@ -88,7 +86,6 @@ void ufo_decoder_free(ufo_decoder decoder)
free(decoder);
}
-
/**
* \brief Set raw data stream
*
@@ -103,25 +100,21 @@ void ufo_decoder_set_raw_data(ufo_decoder decoder, uint32_t *raw, size_t num_byt
decoder->current_pos = 0;
}
-static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer, uint16_t *cmask, uint32_t *raw, size_t num_words, size_t *offset)
+static int ufo_decode_frame_channels(ufo_decoder decoder,
+ uint16_t *pixel_buffer, uint16_t *cmask, uint32_t *raw,
+ size_t num_words, size_t *offset)
{
static int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 };
static int channel_size = (2 + IPECAMERA_PIXELS_PER_CHANNEL / 3);
- int info;
- int num_rows = decoder->height;
- int num_cols = decoder->width;
- size_t c;
- const size_t cpl = (num_cols / IPECAMERA_PIXELS_PER_CHANNEL);
+ const int bytes = channel_size - 1;
+ const int num_rows = decoder->height;
+ const size_t cpl = (decoder->width / IPECAMERA_PIXELS_PER_CHANNEL);
const size_t cpi = num_rows * cpl;
- int row = 0;
- int channel = 0;
- int pixels = 0;
int pos = 0;
uint32_t data;
- const int bytes = channel_size - 1;
-#if defined(HAVE_SSE)&&!defined(DEBUG)
+#if defined(HAVE_SSE) && !defined(DEBUG)
__m128i mask = _mm_set_epi32(0x3FF, 0x3FF, 0x3FF, 0x3FF);
__m128i packed;
__m128i tmp1, tmp2;
@@ -130,36 +123,39 @@ static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer
if (cpi * channel_size > num_words) {
#ifdef DEBUG
- fprintf(stderr, "Not enough data to decode frame, expected %lu bytes, but received %lu\n", cpi * channel_size * sizeof(uint32_t), num_words * sizeof(uint32_t));
+ fprintf(stderr, "Not enough data to decode frame, expected %lu bytes, but received %lu\n", cpi * channel_size * sizeof(uint32_t), num_words * sizeof(uint32_t));
#endif
- return EILSEQ;
+ return EILSEQ;
}
-
- for (c = 0; c < cpi; c++) {
- info = raw[0];
- row = (info >> 4) & 0x7FF;
- channel = info & 0x0F;
- pixels = (info >> 20) & 0xFF;
+
+ for (size_t c = 0; c < cpi; c++) {
+ const int info = raw[0];
+ int row = (info >> 4) & 0x7FF;
+ int channel = info & 0x0F;
+ int pixels = (info >> 20) & 0xFF;
#ifdef CHECKS
int err = 0;
- int header = (info >> 30) & 0x03; // 2 bits
- const int bpp = (info >> 16) & 0x0F; // 4 bits
+ int header = (info >> 30) & 0x03;
+ const int bpp = (info >> 16) & 0x0F;
CHECK_FLAG("raw header magick", header == 2, header);
- CHECK_FLAG("row number, only %i rows requested", row < num_rows, row, num_rows);
+ CHECK_FLAG("row number, only %i rows requested", row < num_rows, row, num_rows);
CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
CHECK_FLAG("channel, limited by %zu output channels", channel < cpl, channel, cpl);
- CHECK_FLAG("channel (line %i), duplicate entry", (!cmask)||(cmask[row]&(1<<channel_order[channel])) == 0, channel_order[channel], row);
+ CHECK_FLAG("channel (line %i), duplicate entry",
+ (!cmask) || (cmask[row] & (1<<channel_order[channel])) == 0,
+ channel_order[channel], row);
#endif
- if ((row > num_rows)||(channel > cpl)||(pixels>IPECAMERA_PIXELS_PER_CHANNEL))
- return EILSEQ;
-
- channel = channel_order[channel];
- if (cmask) cmask[row] |= (1<<channel);
+ if ((row > num_rows) || (channel > cpl) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
+ return EILSEQ;
+ channel = channel_order[channel];
int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
+ if (cmask)
+ cmask[row] |= (1 << channel);
+
/* "Correct" missing pixel */
if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
pixel_buffer[base] = 0;
@@ -170,7 +166,7 @@ static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer
CHECK_FLAG("number of pixels, %i is expected", pixels == IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL);
#endif
-#if defined(HAVE_SSE)&&!defined(DEBUG)
+#if defined(HAVE_SSE) && !defined(DEBUG)
for (int i = 1 ; i < bytes-4; i += 4, base += 12) {
packed = _mm_set_epi32(raw[i], raw[i+1], raw[i+2], raw[i+3]);
@@ -198,23 +194,23 @@ static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer
pixel_buffer[base+8] = result[1];
pixel_buffer[base+11] = result[0];
}
-
+
/* Compute last pixels by hand */
data = raw[41];
pixel_buffer[base++] = (data >> 20) & 0x3FF;
pixel_buffer[base++] = (data >> 10) & 0x3FF;
pixel_buffer[base++] = data & 0x3FF;
-
+
data = raw[42];
pixel_buffer[base++] = (data >> 20) & 0x3FF;
pixel_buffer[base++] = (data >> 10) & 0x3FF;
pixel_buffer[base++] = data & 0x3FF;
-#else /* HAVE_SSE */
+#else
for (int i = 1 ; i < bytes; i++) {
data = raw[i];
#ifdef DEBUG
header = (data >> 30) & 0x03;
- CHECK_FLAG("raw data magick", header == 3, header);
+ CHECK_FLAG("raw data magic", header == 3, header);
if (err)
return err;
#endif
@@ -222,13 +218,13 @@ static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer
pixel_buffer[base++] = (data >> 10) & 0x3FF;
pixel_buffer[base++] = data & 0x3FF;
}
-#endif /* HAVE_SSE */
+#endif
data = raw[bytes];
#ifdef DEBUG
header = (data >> 30) & 0x03;
- CHECK_FLAG("raw data magick", header == 3, header);
- CHECK_FLAG("raw footer magick", (data & 0x3FF) == 0x55, (data & 0x3FF));
+ CHECK_FLAG("raw data magic", header == 3, header);
+ CHECK_FLAG("raw footer magic", (data & 0x3FF) == 0x55, (data & 0x3FF));
if (err)
return err;
#endif
@@ -245,7 +241,6 @@ static int ufo_decode_frame_channels(ufo_decoder decoder, uint16_t *pixel_buffer
return 0;
}
-
/**
* \brief Deinterlace by interpolating between two rows
*
@@ -264,9 +259,9 @@ void ufo_deinterlace_interpolate(const uint16_t *in, uint16_t *out, int width, i
out += width;
/* Interpolate between source row and row+1 */
- for (int x = 0; x < width; x++) {
+ for (int x = 0; x < width; x++)
out[x] = (int) (0.5 * in[row*width + x] + 0.5 * in[(row+1)*width + x]);
- }
+
out += width;
}
@@ -274,7 +269,6 @@ void ufo_deinterlace_interpolate(const uint16_t *in, uint16_t *out, int width, i
memcpy(out, in + width * (height - 1), row_size_bytes);
}
-
/**
* \brief Deinterlace by "weaving" the rows of two frames
*
@@ -295,8 +289,6 @@ void ufo_deinterlace_weave(const uint16_t *in1, const uint16_t *in2, uint16_t *o
}
}
-
-
/**
* \brief Decodes frame
*
@@ -313,7 +305,9 @@ void ufo_deinterlace_weave(const uint16_t *in1, const uint16_t *in2, uint16_t *o
*
* \return number of decoded bytes or 0 in case of error
*/
-size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw, size_t num_bytes, uint16_t *pixels, uint32_t *frame_number, uint32_t *time_stamp, uint16_t *cmask)
+size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw,
+ size_t num_bytes, uint16_t *pixels, uint32_t *frame_number,
+ uint32_t *time_stamp, uint16_t *cmask)
{
int err = 0;
@@ -335,7 +329,8 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw, size_t num_b
*frame_number = raw[pos++] & 0xFFFFFFF;
CHECK_VALUE(raw[pos] >> 28, 0x5);
*time_stamp = raw[pos++] & 0xFFFFFFF;
- if (err) return 0;
+ if (err)
+ return 0;
#else
*frame_number = raw[pos + 6] & 0xFFFFFFF;
*time_stamp = raw[pos + 7] & 0xFFFFFFF;
@@ -343,27 +338,23 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw, size_t num_b
#endif
err = ufo_decode_frame_channels(decoder, pixels, cmask, raw + pos, num_words - pos - 8, &advance);
- if (err) return 0;
+ if (err)
+ return 0;
pos += advance;
#ifdef CHECKS
CHECK_VALUE(raw[pos++], 0x0AAAAAAA);
CHECK_VALUE(raw[pos++], 0x0BBBBBBB);
- // Statuses of previous! frame is following
- pos++; // status1 0x840dffff is expected
- pos++; // status2 0x0f001001 is expected
- pos++; // status3 0x28000111 explains problems if status2 is wrong
-/*
- CHECK_VALUE(raw[pos++], 0x0CCCCCCC);
- CHECK_VALUE(raw[pos++], 0x0DDDDDDD);
- CHECK_VALUE(raw[pos++], 0x0EEEEEEE);
-*/
+ pos++; /* 0x840dffff expected */
+ pos++; /* 0x0f001001 expected */
+ pos++; /* 0x28000111 explains problems if status2 is wrong */
CHECK_VALUE(raw[pos++], 0x0FFFFFFF);
CHECK_VALUE(raw[pos++], 0x00000000);
CHECK_VALUE(raw[pos++], 0x01111111);
- if (err) return 0;
+ if (err)
+ return 0;
#else
pos += 8;
#endif
@@ -371,8 +362,6 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw, size_t num_b
return pos;
}
-
-
/**
* \brief Iterate and decode next frame
*
@@ -392,7 +381,6 @@ size_t ufo_decoder_decode_frame(ufo_decoder decoder, uint32_t *raw, size_t num_b
*/
int ufo_decoder_get_next_frame(ufo_decoder decoder, uint16_t **pixels, uint32_t *frame_number, uint32_t *time_stamp, uint16_t *cmask)
{
-
uint32_t *raw = decoder->raw;
size_t pos = decoder->current_pos;
size_t advance;
@@ -412,10 +400,10 @@ int ufo_decoder_get_next_frame(ufo_decoder decoder, uint16_t **pixels, uint32_t
if (*pixels == NULL)
return ENOMEM;
}
-
+
advance = ufo_decoder_decode_frame(decoder, raw + pos * 4, decoder->num_bytes - pos * 4, *pixels, frame_number, time_stamp, cmask);
if (!advance)
- return EILSEQ;
+ return EILSEQ;
pos += advance;