diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ufodecode.c | 120 |
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; |