Browse Source

Few bug fixes and more coherent debug flags

Suren A. Chilingaryan 11 years ago
parent
commit
7b7d201983
1 changed files with 56 additions and 37 deletions
  1. 56 37
      src/ufodecode.c

+ 56 - 37
src/ufodecode.c

@@ -12,6 +12,17 @@
 
 #define CHECKS
 
+#ifdef DEBUG
+# define SLOW_CHECKS
+# define ALL_CHECKS
+# define VERBOSE
+#endif /* DEBUG */
+
+#ifdef ALL_CHECKS
+# undef HAVE_SSE
+#endif /* ALL_CHECKS */
+
+
 #define IPECAMERA_NUM_ROWS              1088
 #define IPECAMERA_NUM_CHANNELS          16      /**< Number of channels per row */
 #define IPECAMERA_PIXELS_PER_CHANNEL    128     /**< Number of pixels per channel */
@@ -35,7 +46,7 @@ typedef struct {
 /**
  * Check if value matches expected input.
  */
-#ifdef DEBUG
+#ifdef VERBOSE
 # define CHECK_VALUE(value, expected) \
     if (value != expected) { \
         fprintf(stderr, "<%s:%i> 0x%x != 0x%x\n", __FILE__, __LINE__, value, expected); \
@@ -51,7 +62,7 @@ typedef struct {
 /**
  * Check that flag evaluates to non-zero.
  */
-#ifdef DEBUG
+#ifdef VERBOSE
 # define CHECK_FLAG(flag, check, ...) \
     if (!(check)) { \
         fprintf(stderr, "<%s:%i> Unexpected value 0x%x of " flag "\n", __FILE__, __LINE__,  __VA_ARGS__); \
@@ -136,7 +147,7 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
     int pos = 0;
     uint32_t data;
 
-#if defined(HAVE_SSE) && !defined(DEBUG)
+#ifdef HAVE_SSE
     __m128i mask = _mm_set_epi32(0x3FF, 0x3FF, 0x3FF, 0x3FF);
     __m128i packed;
     __m128i tmp1, tmp2;
@@ -144,7 +155,7 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
 #endif
 
     if (cpi * channel_size > num_words) {
-#ifdef DEBUG
+#ifdef VERBOSE
         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;
@@ -156,7 +167,7 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
         int channel = info & 0x0F;
         int pixels = (info >> 20) & 0xFF;
 
-#ifdef CHECKS
+#ifdef SLOW_CHECKS
         int header = (info >> 30) & 0x03;
         const int bpp = (info >> 16) & 0x0F;
         int err;
@@ -177,12 +188,12 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
             pixel_buffer[base] = 0;
             /* base++; */
         }
-#ifdef CHECKS
+#ifdef SLOW_CHECKS
         else
             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)
+#ifdef HAVE_SSE
         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]);
 
@@ -224,12 +235,12 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
 #else
         for (int i = 1 ; i < bytes; i++) {
             data = raw[i];
-#ifdef DEBUG
+# ifdef SLOW_CHECKS
             header = (data >> 30) & 0x03;
             CHECK_FLAG("raw data magic", header == 3, header);
             if (err)
                 return err;
-#endif
+# endif
             pixel_buffer[base++] = (data >> 20) & 0x3FF;
             pixel_buffer[base++] = (data >> 10) & 0x3FF;
             pixel_buffer[base++] = data & 0x3FF;
@@ -237,7 +248,7 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
 #endif
 
         data = raw[bytes];
-#ifdef DEBUG
+#ifdef SLOW_CHECKS
         header = (data >> 30) & 0x03;
         CHECK_FLAG("raw data magic", header == 3, header);
         CHECK_FLAG("raw footer magic", (data & 0x3FF) == 0x55, (data & 0x3FF));
@@ -253,7 +264,7 @@ ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
         raw += channel_size;
     }
 
-    *offset = pos;
+    *offset += pos;
     return 0;
 }
 
@@ -274,7 +285,7 @@ ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
     int pos = 0;
     uint32_t data;
 
-#if defined(HAVE_SSE) && !defined(DEBUG)
+#ifdef HAVE_SSE
     __m128i mask = _mm_set_epi32(0x3FF, 0x3FF, 0x3FF, 0x3FF);
     __m128i packed;
     __m128i tmp1, tmp2;
@@ -282,28 +293,29 @@ ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
 #endif
 
     if (cpi * channel_size > num_words) {
-#ifdef DEBUG
+#ifdef VERBOSE
         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;
     }
 
     for (size_t c = 0; c < cpi; c++) {
+        int err = 0;
         const int info = raw[0];
         int row = (info >> 4) & 0x7FF;
         int channel = info & 0x0F;
         int pixels = (info >> 20) & 0xFF;
 
-#ifdef DEBUG
-        int err = 0;
+#ifdef SLOW_CHECKS
         int header = (info >> 30) & 0x03;
         const int bpp = (info >> 16) & 0x0F;
         CHECK_FLAG("raw header magick", header == 2, header);
         CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
-        CHECK_FLAG("channel, limited by %zu output channels", channel < channels_per_row, channel, channels_per_row);
 #endif
 
-        if ((channel > channels_per_row) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
+        CHECK_FLAG("pixels, only %u pixels per channel (offset: %zx)", pixels <= IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL, (*offset + pos));
+        CHECK_FLAG("channel, limited by %zu output channels (offset: %zx)", channel <= channels_per_row, channel, channels_per_row, (*offset + pos));
+        if (err)
             return EILSEQ;
 
         channel = channel_order[channel];
@@ -315,7 +327,7 @@ ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
             /* base++; */
         }
 
-#if defined(HAVE_SSE) && !defined(DEBUG)
+#ifdef HAVE_SSE
         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]);
 
@@ -357,12 +369,12 @@ ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
 #else
         for (int i = 1 ; i < bytes; i++) {
             data = raw[i];
-#ifdef DEBUG
+# ifdef SLOW_CHECKS
             header = (data >> 30) & 0x03;
-            CHECK_FLAG("raw data magic", header == 3, header);
+            CHECK_FLAG("raw data magic (offset: 0x%zx, expected: 0x02)", header == 3, header, (*offset + pos + i)*sizeof(uint32_t));
             if (err)
                 return err;
-#endif
+# endif
             pixel_buffer[base++] = (data >> 20) & 0x3FF;
             pixel_buffer[base++] = (data >> 10) & 0x3FF;
             pixel_buffer[base++] = data & 0x3FF;
@@ -370,10 +382,10 @@ ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
 #endif
 
         data = raw[bytes];
-#ifdef DEBUG
+#ifdef SLOW_CHECKS
         header = (data >> 30) & 0x03;
-        CHECK_FLAG("raw data magic", header == 3, header);
-        CHECK_FLAG("raw footer magic", (data & 0x3FF) == 0x55, (data & 0x3FF));
+        CHECK_FLAG("raw data magic (offset: 0x%zx, expected: 0x03)", header == 3, header, (*offset + pos + bytes)*sizeof(uint32_t));
+        CHECK_FLAG("raw footer magic (offset: 0x%zx, expected: 0x55)", (data & 0x3FF) == 0x55, (data & 0x3FF), (*offset + pos + bytes)*sizeof(uint32_t));
         if (err)
             return err;
 #endif
@@ -386,7 +398,7 @@ ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
         raw += channel_size;
     }
 
-    *offset = pos;
+    *offset += pos;
     return 0;
 }
 
@@ -460,7 +472,7 @@ ufo_decode_frame_channels_v5(UfoDecoder     *decoder,
         }
     }
 
-    *offset = base;
+    *offset += base;
     return 0;
 }
 
@@ -535,16 +547,20 @@ size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
 {
     int err = 0;
     size_t pos = 0;
-    size_t advance = 0;
     const size_t num_words = num_bytes / 4;
 
-    if ((pixels == NULL) || (num_words < 16))
+    if ((pixels == NULL) || (num_words < 16)) {
+#ifdef VERBOSE
+	if (num_words < 16) 
+	    fprintf(stderr, "Not enough frame data, only %zu bytes supplied \n", num_bytes);
+#endif
         return 0;
+    }
 
     size_t rows_per_frame = decoder->height;
     const int version = (raw[pos+6] >> 24) & 0xF;
 
-#ifdef DEBUG
+#ifdef CHECKS
     CHECK_VALUE(raw[pos++], 0x51111111);
     CHECK_VALUE(raw[pos++], 0x52222222);
     CHECK_VALUE(raw[pos++], 0x53333333);
@@ -576,15 +592,17 @@ size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
             pos++;
 
             if ((meta->output_mode != IPECAMERA_MODE_4_CHAN_IO) && (meta->output_mode != IPECAMERA_MODE_16_CHAN_IO)) {
-#ifdef DEBUG
+# ifdef VERBOSE
                 fprintf(stderr, "Output mode 0x%x is not supported\n", meta->output_mode);
-#endif
-                return EILSEQ;
+# endif
+                return 0;
             }
             break;
 
         default:
+# ifdef VERBOSE
             fprintf(stderr, "Unsupported data format version %i detected\n", version);
+# endif
             return 0;
     }
 
@@ -597,6 +615,7 @@ size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
             meta->time_stamp = raw[pos + 7] & 0xFFFFFFF;
             break;
         case 4:
+            meta->n_rows = rows_per_frame = raw[pos + 5] & 0x7FF;
         case 5:
             meta->frame_number = raw[pos + 6] & 0x1FFFFFF;
             meta->time_stamp = raw[pos + 7] & 0xFFFFFF;
@@ -605,7 +624,9 @@ size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
 
             break;
         default:
+# ifdef VERBOSE
             fprintf(stderr, "Unsupported data format detected\n");
+# endif
             return 0;
     }
 
@@ -614,13 +635,13 @@ size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
 
     switch (version) {
         case 0:
-            err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance);
+            err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &pos);
             break;
         case 4:
-            err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
+            err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &pos);
             break;
         case 5:
-            err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, rows_per_frame, &advance, meta->output_mode);
+            err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, rows_per_frame, &pos, meta->output_mode);
             break;
         default:
             break;
@@ -629,8 +650,6 @@ size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
     if (err)
         return 0;
 
-    pos += advance;
-
 #ifdef CHECKS
     CHECK_VALUE(raw[pos++], 0x0AAAAAAA);