/alps/ufodecode

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/ufodecode

« back to all changes in this revision

Viewing changes to src/ufodecode.c

  • Committer: Suren A. Chilingaryan
  • Date: 2012-07-25 17:24:22 UTC
  • Revision ID: csa@dside.dyndns.org-20120725172422-oscj3kb2tbyfkj2m
Black magick from Michele

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
#define IPECAMERA_PIXELS_PER_CHANNEL    128     /**< Number of pixels per channel */
18
18
#define IPECAMERA_WIDTH (IPECAMERA_NUM_CHANNELS * IPECAMERA_PIXELS_PER_CHANNEL) /**< Total pixel width of row */
19
19
 
 
20
#define IPECAMERA_MODE_16_CHAN_IO       0
 
21
#define IPECAMERA_MODE_4_CHAN_IO        2
 
22
 
 
23
#define IPECAMERA_MODE_12_BIT_ADC       2
 
24
#define IPECAMERA_MODE_11_BIT_ADC       1
 
25
#define IPECAMERA_MODE_10_BIT_ADC       0
 
26
 
20
27
typedef struct {
21
28
    unsigned int pixel_number : 8;
22
29
    unsigned int row_number : 12;
113
120
}
114
121
 
115
122
static int
116
 
ufo_decode_frame_channels_v0(UfoDecoder     *decoder, 
117
 
                             uint16_t       *pixel_buffer, 
118
 
                             uint32_t       *raw, 
119
 
                             size_t          num_words, 
 
123
ufo_decode_frame_channels_v0(UfoDecoder     *decoder,
 
124
                             uint16_t       *pixel_buffer,
 
125
                             uint32_t       *raw,
 
126
                             size_t          num_words,
120
127
                             size_t         *offset)
121
128
{
122
129
    static int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 };
171
178
            /* base++; */
172
179
        }
173
180
#ifdef CHECKS
174
 
        else 
 
181
        else
175
182
            CHECK_FLAG("number of pixels, %i is expected", pixels == IPECAMERA_PIXELS_PER_CHANNEL, pixels, IPECAMERA_PIXELS_PER_CHANNEL);
176
183
#endif
177
184
 
218
225
        for (int i = 1 ; i < bytes; i++) {
219
226
            data = raw[i];
220
227
#ifdef DEBUG
221
 
            header = (data >> 30) & 0x03;   
 
228
            header = (data >> 30) & 0x03;
222
229
            CHECK_FLAG("raw data magic", header == 3, header);
223
 
            if (err) 
 
230
            if (err)
224
231
                return err;
225
232
#endif
226
233
            pixel_buffer[base++] = (data >> 20) & 0x3FF;
234
241
        header = (data >> 30) & 0x03;
235
242
        CHECK_FLAG("raw data magic", header == 3, header);
236
243
        CHECK_FLAG("raw footer magic", (data & 0x3FF) == 0x55, (data & 0x3FF));
237
 
        if (err) 
 
244
        if (err)
238
245
            return err;
239
246
#endif
240
247
 
252
259
 
253
260
static int
254
261
ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
255
 
                             uint16_t       *pixel_buffer, 
256
 
                             uint32_t       *raw, 
257
 
                             size_t          num_words, 
258
 
                             size_t          num_rows, 
 
262
                             uint16_t       *pixel_buffer,
 
263
                             uint32_t       *raw,
 
264
                             size_t          num_words,
 
265
                             size_t          num_rows,
259
266
                             size_t         *offset)
260
267
{
261
268
    static const int channel_order[IPECAMERA_NUM_CHANNELS] = { 15, 13, 14, 12, 10, 8, 11, 7, 9, 6, 5, 2, 4, 3, 0, 1 };
355
362
        for (int i = 1 ; i < bytes; i++) {
356
363
            data = raw[i];
357
364
#ifdef DEBUG
358
 
            header = (data >> 30) & 0x03;   
 
365
            header = (data >> 30) & 0x03;
359
366
            CHECK_FLAG("raw data magic", header == 3, header);
360
 
            if (err) 
 
367
            if (err)
361
368
                return err;
362
369
#endif
363
370
            pixel_buffer[base++] = (data >> 20) & 0x3FF;
371
378
        header = (data >> 30) & 0x03;
372
379
        CHECK_FLAG("raw data magic", header == 3, header);
373
380
        CHECK_FLAG("raw footer magic", (data & 0x3FF) == 0x55, (data & 0x3FF));
374
 
        if (err) 
 
381
        if (err)
375
382
            return err;
376
383
#endif
377
384
 
388
395
}
389
396
 
390
397
static int
391
 
ufo_decode_frame_channels_v5(UfoDecoder     *decoder, 
392
 
                             uint16_t       *pixel_buffer, 
393
 
                             uint32_t       *raw, 
394
 
                             size_t          num_words, 
395
 
                             size_t          num_rows, 
396
 
                             size_t         *offset)
 
398
ufo_decode_frame_channels_v5(UfoDecoder     *decoder,
 
399
                             uint16_t       *pixel_buffer,
 
400
                             uint32_t       *raw,
 
401
                             size_t          num_words,
 
402
                             size_t          num_rows,
 
403
                             size_t         *offset,
 
404
                             uint8_t         output_mode)
397
405
{
398
406
    payload_header_v5 *header;
399
407
    size_t base = 0, index = 0;
401
409
 
402
410
    header = (payload_header_v5 *) &raw[base];
403
411
 
404
 
    if (header->pixel_size == 12) {
 
412
    if (output_mode == IPECAMERA_MODE_4_CHAN_IO) {
405
413
        while (raw[base] != 0xAAAAAAA) {
406
414
            header = (payload_header_v5 *) &raw[base];
407
415
            index = header->row_number * IPECAMERA_WIDTH + header->pixel_number;
416
424
                pixel_buffer[index + (12+off)*IPECAMERA_PIXELS_PER_CHANNEL] = 0xfff & (raw[base+1] >> 16);
417
425
            }
418
426
            else {
419
 
                off++; 
 
427
                off++;
420
428
 
421
429
                if (header->magic == 0xc0)
422
430
                    off = 0;
425
433
            base += 6;
426
434
        }
427
435
    }
428
 
    else if (header->pixel_size == 10) {
 
436
    else { /*if (output_mode == IPECAMERA_MODE_16_CHAN_IO)*/
429
437
        while (raw[base] != 0xAAAAAAA) {
430
438
            header = (payload_header_v5 *) &raw[base];
431
439
            index = header->row_number * IPECAMERA_WIDTH + header->pixel_number;
432
440
 
433
441
            /* Skip header + two zero-filled words */
434
 
            base += 3;
435
 
 
436
 
            pixel_buffer[index + 15*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 22);
437
 
            pixel_buffer[index + 13*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 12);
438
 
            pixel_buffer[index + 14*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 2);
439
 
            pixel_buffer[index + 12*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3 & raw[base]) << 8) | (0x3ff & (raw[base+1] >> 24));
440
 
            pixel_buffer[index + 10*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 14);
441
 
            pixel_buffer[index +  8*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 4);
442
 
            pixel_buffer[index + 11*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xf & raw[base+1]) << 6) | (0x3ff & (raw[base+2] >> 26));
443
 
            pixel_buffer[index +  7*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 16);
444
 
            pixel_buffer[index +  9*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 6);
445
 
            pixel_buffer[index +  6*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3f & raw[base+2]) << 4) | (0x3ff & (raw[base+3] >> 28));
446
 
            pixel_buffer[index +  5*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 18);
447
 
            pixel_buffer[index +  2*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 8);
448
 
            pixel_buffer[index +  4*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xff & raw[base+3]) << 2) | (0x3ff & (raw[base+4] >> 30));
449
 
            pixel_buffer[index +  3*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 20);
450
 
            pixel_buffer[index +  0*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 10);
451
 
            pixel_buffer[index +  1*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+4];
452
 
            base += 5;
 
442
            /*
 
443
                        base += 3;
 
444
                        pixel_buffer[index + 15*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 22);
 
445
                        pixel_buffer[index + 13*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 12);
 
446
                        pixel_buffer[index + 14*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 2);
 
447
                        pixel_buffer[index + 12*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3 & raw[base]) << 8) | (0x3ff & (raw[base+1] >> 24));
 
448
                        pixel_buffer[index + 10*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 14);
 
449
                        pixel_buffer[index +  8*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 4);
 
450
                        pixel_buffer[index + 11*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xf & raw[base+1]) << 6) | (0x3ff & (raw[base+2] >> 26));
 
451
                        pixel_buffer[index +  7*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 16);
 
452
                        pixel_buffer[index +  9*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 6);
 
453
                        pixel_buffer[index +  6*IPECAMERA_PIXELS_PER_CHANNEL] = ((0x3f & raw[base+2]) << 4) | (0x3ff & (raw[base+3] >> 28));
 
454
                        pixel_buffer[index +  5*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 18);
 
455
                        pixel_buffer[index +  2*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 8);
 
456
                        pixel_buffer[index +  4*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xff & raw[base+3]) << 2) | (0x3ff & (raw[base+4] >> 30));
 
457
                        pixel_buffer[index +  3*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 20);
 
458
                        pixel_buffer[index +  0*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 10);
 
459
                        pixel_buffer[index +  1*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+4];
 
460
                        base += 5;
 
461
            */
 
462
 
 
463
            base += 2;
 
464
 
 
465
            if (header->magic != 0xc0) {
 
466
                pixel_buffer[index + 15*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 20);
 
467
                pixel_buffer[index + 13*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base] >> 8);
 
468
                pixel_buffer[index + 14*IPECAMERA_PIXELS_PER_CHANNEL] = (0xff & raw[base]) << 4 | (raw[base+1] >> 28);
 
469
                pixel_buffer[index + 12*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 16);
 
470
                pixel_buffer[index + 10*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+1] >> 4);
 
471
                pixel_buffer[index +  8*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xf & raw[base+1]) << 8) | (raw[base+2] >> 24);
 
472
                pixel_buffer[index + 11*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+2] >> 12);
 
473
                pixel_buffer[index +  7*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+2];
 
474
                pixel_buffer[index +  9*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 20);
 
475
                pixel_buffer[index +  6*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+3] >> 8);
 
476
                pixel_buffer[index +  5*IPECAMERA_PIXELS_PER_CHANNEL] = (0xff & raw[base+3]) << 4 | (raw[base+4] >> 28);
 
477
                pixel_buffer[index +  2*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 16);
 
478
                pixel_buffer[index +  4*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+4] >> 4);
 
479
                pixel_buffer[index +  3*IPECAMERA_PIXELS_PER_CHANNEL] = ((0xf & raw[base+4]) << 8) | (raw[base+5] >> 24);
 
480
                pixel_buffer[index +  0*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & (raw[base+5] >> 12);
 
481
                pixel_buffer[index +  1*IPECAMERA_PIXELS_PER_CHANNEL] = 0x3ff & raw[base+5];
 
482
            }
 
483
            else {
 
484
                off++;
 
485
 
 
486
                if (header->magic == 0xc0)
 
487
                    off = 0;
 
488
            }
 
489
 
 
490
            base += 6;
 
491
 
453
492
        }
454
493
    }
455
494
 
 
495
 
456
496
    *offset = base;
457
497
    return 0;
458
498
}
473
513
        memcpy(out, in + row*width, row_size_bytes);
474
514
        out += width;
475
515
 
476
 
        /* Interpolate between source row and row+1 */ 
 
516
        /* Interpolate between source row and row+1 */
477
517
        for (int x = 0; x < width; x++)
478
518
            out[x] = (int) (0.5 * in[row*width + x] + 0.5 * in[(row+1)*width + x]);
479
519
 
497
537
{
498
538
    const size_t row_size_bytes = width * sizeof(uint16_t);
499
539
    for (int row = 0; row < height; row++) {
500
 
        memcpy(out, in1 + row*width, row_size_bytes); 
 
540
        memcpy(out, in1 + row*width, row_size_bytes);
501
541
        out += width;
502
 
        memcpy(out, in2 + row*width, row_size_bytes); 
 
542
        memcpy(out, in2 + row*width, row_size_bytes);
503
543
        out += width;
504
544
    }
505
545
}
520
560
 * \return number of decoded bytes or 0 in case of error
521
561
 */
522
562
size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
523
 
                                uint32_t        *raw, 
524
 
                                size_t           num_bytes, 
525
 
                                uint16_t        *pixels, 
 
563
                                uint32_t        *raw,
 
564
                                size_t           num_bytes,
 
565
                                uint16_t        *pixels,
526
566
                                UfoDecoderMeta  *meta)
527
567
{
528
568
    int err = 0;
544
584
    CHECK_VALUE(raw[pos++], 0x55555555);
545
585
 
546
586
    switch (version) {
547
 
        case 0:
548
 
            CHECK_VALUE(raw[pos++], 0x56666666);
549
 
            CHECK_VALUE(raw[pos] >> 28, 0x5);
550
 
            meta->frame_number = raw[pos++] & 0xFFFFFFF;
551
 
            CHECK_VALUE(raw[pos] >> 28, 0x5);
552
 
            meta->time_stamp = raw[pos++] & 0xFFFFFFF;
553
 
            break;
554
 
 
555
 
        case 4:
556
 
        case 5:
557
 
            CHECK_VALUE(raw[pos] >> 28, 0x5);
558
 
            meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF;
559
 
            meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F;
560
 
            meta->n_rows = rows_per_frame = raw[pos] & 0x7FF;
561
 
            pos++;
562
 
 
563
 
            meta->frame_number = raw[pos++] & 0x1FFFFFF;
564
 
            CHECK_VALUE(raw[pos] >> 28, 0x5);
565
 
            meta->time_stamp = raw[pos++] & 0xFFFFFF;
566
 
            meta->output_mode = (raw[pos] >> 24) & 0x3;
567
 
            meta->adc_resolution = (raw[pos] >> 26) & 0x3
568
 
            break;
569
 
 
570
 
        default:
571
 
            fprintf(stderr, "Unsupported data format detected\n");
572
 
            return 0;
 
587
    case 0:
 
588
        CHECK_VALUE(raw[pos++], 0x56666666);
 
589
        CHECK_VALUE(raw[pos] >> 28, 0x5);
 
590
        meta->frame_number = raw[pos++] & 0xFFFFFFF;
 
591
        CHECK_VALUE(raw[pos] >> 28, 0x5);
 
592
        meta->time_stamp = raw[pos++] & 0xFFFFFFF;
 
593
        break;
 
594
 
 
595
    case 4:
 
596
    case 5:
 
597
        CHECK_VALUE(raw[pos] >> 28, 0x5);
 
598
        meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF;
 
599
        meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F;
 
600
        meta->n_rows = rows_per_frame = raw[pos] & 0x7FF;
 
601
        pos++;
 
602
 
 
603
        meta->frame_number = raw[pos++] & 0x1FFFFFF;
 
604
        CHECK_VALUE(raw[pos] >> 28, 0x5);
 
605
        meta->time_stamp = raw[pos] & 0xFFFFFF;
 
606
        meta->output_mode = (raw[pos] >> 24) & 0x3;
 
607
        meta->adc_resolution = (raw[pos] >> 26) & 0x3;
 
608
        pos++;
 
609
 
 
610
        if ((meta->output_mode != IPECAMERA_MODE_4_CHAN_IO)&&(meta->output_mode != IPECAMERA_MODE_4_CHAN_IO)) {
 
611
#ifdef DEBUG
 
612
            fprintf(stderr, "Output mode 0x%lx is not supported\n", meta->output_mode);
 
613
#endif
 
614
            return EILSEQ;
 
615
        }
 
616
        break;
 
617
 
 
618
    default:
 
619
        fprintf(stderr, "Unsupported data format detected\n");
 
620
        return 0;
573
621
    }
574
622
 
575
 
    if (err) 
 
623
    if (err)
576
624
        return 0;
577
625
#else
578
626
    switch (version) {
579
 
        case 0:
580
 
            meta->frame_number = raw[pos + 6] & 0xFFFFFFF;
581
 
            meta->time_stamp = raw[pos + 7] & 0xFFFFFFF;
582
 
            break;
583
 
        case 4:
584
 
        case 5:
585
 
            meta->frame_number = raw[pos + 6] & 0x1FFFFFF;
586
 
            meta->time_stamp = raw[pos + 7] & 0xFFFFFF;
587
 
            break;
588
 
        default:
589
 
            fprintf(stderr, "Unsupported data format detected\n");
590
 
            return 0;
 
627
    case 0:
 
628
        meta->frame_number = raw[pos + 6] & 0xFFFFFFF;
 
629
        meta->time_stamp = raw[pos + 7] & 0xFFFFFFF;
 
630
        break;
 
631
    case 4:
 
632
    case 5:
 
633
        meta->frame_number = raw[pos + 6] & 0x1FFFFFF;
 
634
        meta->time_stamp = raw[pos + 7] & 0xFFFFFF;
 
635
        meta->output_mode = (raw[pos + 7] >> 24) & 0x3;
 
636
        meta->adc_resolution = (raw[pos + 7] >> 26) & 0x3;
 
637
 
 
638
        break;
 
639
    default:
 
640
        fprintf(stderr, "Unsupported data format detected\n");
 
641
        return 0;
591
642
    }
592
643
 
593
644
    pos += 8;
594
645
#endif
595
646
 
596
647
    switch (version) {
597
 
        case 0:
598
 
            err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance);
599
 
            break;
600
 
        case 4:
601
 
            err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
602
 
            break;
603
 
        case 5:
604
 
            err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
605
 
            break;
606
 
        default:
607
 
            break;
 
648
    case 0:
 
649
        err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance);
 
650
        break;
 
651
    case 4:
 
652
        err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
 
653
        break;
 
654
    case 5:
 
655
        err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance, meta->output_mode);
 
656
        break;
 
657
    default:
 
658
        break;
608
659
    }
609
660
 
610
661
    if (err)
623
674
    CHECK_VALUE(raw[pos++], 0x00000000);
624
675
    CHECK_VALUE(raw[pos++], 0x01111111);
625
676
 
626
 
    if (err) 
 
677
    if (err)
627
678
        return 0;
628
679
#else
629
680
    pos += 8;
636
687
 * \brief Iterate and decode next frame
637
688
 *
638
689
 * This function tries to decode the next frame in the currently set raw data
639
 
 * stream. 
 
690
 * stream.
640
691
 *
641
692
 * \param decoder An UfoDecoder instance
642
693
 * \param pixels If pointer with NULL content is passed, a new buffer is
649
700
 * NULL was passed but no memory could be allocated, EILSEQ if data stream is
650
701
 * corrupt and EFAULT if pixels is a NULL-pointer.
651
702
 */
652
 
int ufo_decoder_get_next_frame(UfoDecoder     *decoder, 
653
 
                               uint16_t      **pixels, 
 
703
int ufo_decoder_get_next_frame(UfoDecoder     *decoder,
 
704
                               uint16_t      **pixels,
654
705
                               UfoDecoderMeta *meta)
655
706
{
656
707
    uint32_t *raw = decoder->raw;
662
713
        return 0;
663
714
 
664
715
    if (pos >= num_words)
665
 
        return EIO; 
 
716
        return EIO;
666
717
 
667
718
    if (num_words < 16)
668
719
        return EILSEQ;