/alps/ufodecode

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/ufodecode

« back to all changes in this revision

Viewing changes to src/ufodecode.c

  • Committer: Matthias Vogelgesang
  • Date: 2012-07-17 14:28:58 UTC
  • Revision ID: matthias.vogelgesang@kit.edu-20120717142858-9gsb7mux5vttdt31
Commit version 0.2 of libufodecode

Show diffs side-by-side

added added

removed removed

Lines of Context:
69
69
 * \return A new decoder instance that can be used to iterate over the frames
70
70
 * using ufo_decoder_get_next_frame.
71
71
 */
72
 
ufo_decoder
 
72
UfoDecoder *
73
73
ufo_decoder_new (int32_t height, uint32_t width, uint32_t *raw, size_t num_bytes)
74
74
{
75
75
    if (width % IPECAMERA_PIXELS_PER_CHANNEL)
76
76
        return NULL;
77
77
 
78
 
    ufo_decoder decoder = malloc(sizeof(struct ufo_decoder_t));
 
78
    UfoDecoder *decoder = malloc(sizeof(UfoDecoder));
79
79
 
80
80
    if (decoder == NULL)
81
81
        return NULL;
82
82
 
83
83
    decoder->width = width;
84
84
    decoder->height = height;
85
 
    decoder->old_time_stamp = 0;
86
85
    ufo_decoder_set_raw_data(decoder, raw, num_bytes);
87
86
    return decoder;
88
87
}
90
89
/**
91
90
 * \brief Release decoder instance
92
91
 *
93
 
 * \param decoder An ufo_decoder instance
 
92
 * \param decoder An UfoDecoder instance
94
93
 */
95
94
void
96
 
ufo_decoder_free(ufo_decoder decoder)
 
95
ufo_decoder_free(UfoDecoder *decoder)
97
96
{
98
97
    free(decoder);
99
98
}
101
100
/**
102
101
 * \brief Set raw data stream
103
102
 *
104
 
 * \param decoder An ufo_decoder instance
 
103
 * \param decoder An UfoDecoder instance
105
104
 * \param raw Raw data stream
106
105
 * \param num_bytes Size of data stream buffer in bytes
107
106
 */
108
107
void
109
 
ufo_decoder_set_raw_data(ufo_decoder decoder, uint32_t *raw, size_t num_bytes)
 
108
ufo_decoder_set_raw_data(UfoDecoder *decoder, uint32_t *raw, size_t num_bytes)
110
109
{
111
110
    decoder->raw = raw;
112
111
    decoder->num_bytes = num_bytes;
114
113
}
115
114
 
116
115
static int
117
 
ufo_decode_frame_channels_v0(ufo_decoder     decoder, 
 
116
ufo_decode_frame_channels_v0(UfoDecoder     *decoder, 
118
117
                             uint16_t       *pixel_buffer, 
119
 
                             uint16_t       *cmask, 
120
118
                             uint32_t       *raw, 
121
119
                             size_t          num_words, 
122
120
                             size_t         *offset)
159
157
        CHECK_FLAG("row number, only %i rows requested", row < num_rows, row, num_rows);
160
158
        CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
161
159
        CHECK_FLAG("channel, limited by %zu output channels", channel < cpl, channel, cpl);
162
 
        CHECK_FLAG("channel (line %i), duplicate entry",
163
 
                (!cmask) || (cmask[row] & (1<<channel_order[channel])) == 0,
164
 
                channel_order[channel], row);
165
160
#endif
166
161
 
167
162
        if ((row > num_rows) || (channel > cpl) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
170
165
        channel = channel_order[channel];
171
166
        int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
172
167
 
173
 
        if (cmask) 
174
 
            cmask[row] |= (1 << channel);
175
 
 
176
168
        /* "Correct" missing pixel */
177
169
        if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
178
170
            pixel_buffer[base] = 0;
259
251
}
260
252
 
261
253
static int
262
 
ufo_decode_frame_channels_v4(ufo_decoder     decoder,
 
254
ufo_decode_frame_channels_v4(UfoDecoder     *decoder,
263
255
                             uint16_t       *pixel_buffer, 
264
 
                             uint16_t       *cmask, 
265
256
                             uint32_t       *raw, 
266
257
                             size_t          num_words, 
267
258
                             size_t          num_rows, 
307
298
 
308
299
        CHECK_FLAG("pixel size, only 10 bits are supported", bpp == 10, bpp);
309
300
        CHECK_FLAG("channel, limited by %zu output channels", channel < channels_per_row, channel, channels_per_row);
310
 
        CHECK_FLAG("channel (line %i), duplicate entry",
311
 
                (!cmask) || (cmask[row] & (1 << channel_order[channel])) == 0,
312
 
                channel_order[channel], row);
313
301
#endif
314
302
 
315
303
        if ((channel > channels_per_row) || (pixels > IPECAMERA_PIXELS_PER_CHANNEL))
318
306
        channel = channel_order[channel];
319
307
        int base = row * IPECAMERA_WIDTH + channel * IPECAMERA_PIXELS_PER_CHANNEL;
320
308
 
321
 
        if (cmask) 
322
 
            cmask[row] |= (1 << channel);
323
 
 
324
309
        /* "Correct" missing pixel */
325
310
        if ((row < 2) && (pixels == (IPECAMERA_PIXELS_PER_CHANNEL - 1))) {
326
311
            pixel_buffer[base] = 0;
407
392
}
408
393
 
409
394
static int
410
 
ufo_decode_frame_channels_v5(ufo_decoder     decoder, 
 
395
ufo_decode_frame_channels_v5(UfoDecoder     *decoder, 
411
396
                             uint16_t       *pixel_buffer, 
412
 
                             uint16_t       *cmask, 
413
397
                             uint32_t       *raw, 
414
398
                             size_t          num_words, 
415
399
                             size_t          num_rows, 
549
533
 *
550
534
 * This function tries to decode the supplied data
551
535
 *
552
 
 * \param decoder An ufo_decoder instance
 
536
 * \param decoder An UfoDecoder instance
553
537
 * \param raw Raw data stream
554
538
 * \param num_bytes Size of data stream buffer in bytes
555
539
 * \param pixels If pointer with NULL content is passed, a new buffer is
556
540
 * allocated otherwise, this user-supplied buffer is used.
557
541
 * \param frame_number Frame number as reported in the header
558
542
 * \param time_stamp Time stamp of the frame as reported in the header
559
 
 * \paran cmask Change-mask
560
543
 *
561
544
 * \return number of decoded bytes or 0 in case of error
562
545
 */
563
 
size_t ufo_decoder_decode_frame(ufo_decoder  decoder,
564
 
                                uint32_t    *raw, 
565
 
                                size_t       num_bytes, 
566
 
                                uint16_t    *pixels, 
567
 
                                uint32_t    *num_rows, 
568
 
                                uint32_t    *frame_number,
569
 
                                uint32_t    *time_stamp, 
570
 
                                uint16_t    *cmask)
 
546
size_t ufo_decoder_decode_frame(UfoDecoder      *decoder,
 
547
                                uint32_t        *raw, 
 
548
                                size_t           num_bytes, 
 
549
                                uint16_t        *pixels, 
 
550
                                UfoDecoderMeta  *meta)
571
551
{
572
552
    int err = 0;
573
553
    size_t pos = 0;
591
571
        case 0:
592
572
            CHECK_VALUE(raw[pos++], 0x56666666);
593
573
            CHECK_VALUE(raw[pos] >> 28, 0x5);
594
 
            *frame_number = raw[pos++] & 0xFFFFFFF;
 
574
            meta->frame_number = raw[pos++] & 0xFFFFFFF;
595
575
            CHECK_VALUE(raw[pos] >> 28, 0x5);
596
 
            *time_stamp = raw[pos++] & 0xFFFFFFF;
 
576
            meta->time_stamp = raw[pos++] & 0xFFFFFFF;
597
577
            break;
598
578
 
599
579
        case 4:
600
580
        case 5:
601
581
            CHECK_VALUE(raw[pos] >> 28, 0x5);
602
 
            rows_per_frame = raw[pos] & 0x7FF;
 
582
            meta->cmosis_start_address = (raw[pos] >> 21) & 0x1FF;
 
583
            meta->n_skipped_rows = (raw[pos] >> 15) & 0x3F;
 
584
            meta->n_rows = rows_per_frame = raw[pos] & 0x7FF;
603
585
            pos++;
604
 
            *frame_number = raw[pos++] & 0x1FFFFFF;
 
586
 
 
587
            meta->frame_number = raw[pos++] & 0x1FFFFFF;
605
588
            CHECK_VALUE(raw[pos] >> 24, 0x50);
606
 
            *time_stamp = raw[pos++] & 0xFFFFFF;
 
589
            meta->time_stamp = raw[pos++] & 0xFFFFFF;
607
590
            break;
608
591
 
609
592
        default:
616
599
#else
617
600
    switch (version) {
618
601
        case 0:
619
 
            *frame_number = raw[pos + 6] & 0xFFFFFFF;
620
 
            *time_stamp = raw[pos + 7] & 0xFFFFFFF;
 
602
            meta->frame_number = raw[pos + 6] & 0xFFFFFFF;
 
603
            meta->time_stamp = raw[pos + 7] & 0xFFFFFFF;
621
604
            break;
622
605
        case 4:
623
606
        case 5:
624
 
            *frame_number = raw[pos + 6] & 0x1FFFFFF;
625
 
            *time_stamp = raw[pos + 7] & 0xFFFFFF;
 
607
            meta->frame_number = raw[pos + 6] & 0x1FFFFFF;
 
608
            meta->time_stamp = raw[pos + 7] & 0xFFFFFF;
626
609
            break;
627
610
        default:
628
611
            fprintf(stderr, "Unsupported data format detected\n");
632
615
    pos += 8;
633
616
#endif
634
617
 
635
 
    *num_rows = rows_per_frame;
636
 
 
637
618
    switch (version) {
638
619
        case 0:
639
 
            err = ufo_decode_frame_channels_v0(decoder, pixels, cmask, raw + pos, num_words - pos - 8, &advance);
 
620
            err = ufo_decode_frame_channels_v0(decoder, pixels, raw + pos, num_words - pos - 8, &advance);
640
621
            break;
641
622
        case 4:
642
 
            err = ufo_decode_frame_channels_v4(decoder, pixels, cmask, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
 
623
            err = ufo_decode_frame_channels_v4(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
643
624
            break;
644
625
        case 5:
645
 
            err = ufo_decode_frame_channels_v5(decoder, pixels, cmask, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
 
626
            err = ufo_decode_frame_channels_v5(decoder, pixels, raw + pos, num_words - pos - 8, rows_per_frame, &advance);
646
627
            break;
647
628
        default:
648
629
            break;
655
636
 
656
637
#ifdef CHECKS
657
638
    CHECK_VALUE(raw[pos++], 0x0AAAAAAA);
 
639
 
 
640
    meta->status1.bits = raw[pos++];
 
641
    meta->status2.bits = raw[pos++];
 
642
    meta->status3.bits = raw[pos++];
658
643
    pos++;
659
 
    pos++; /* 0x840dffff expected */
660
 
    pos++; /* 0x0f001001 expected */
661
 
    pos++; /* 0x28000111 explains problems if status2 is wrong */
662
644
    pos++;
663
645
    CHECK_VALUE(raw[pos++], 0x00000000);
664
646
    CHECK_VALUE(raw[pos++], 0x01111111);
678
660
 * This function tries to decode the next frame in the currently set raw data
679
661
 * stream. 
680
662
 *
681
 
 * \param decoder An ufo_decoder instance
 
663
 * \param decoder An UfoDecoder instance
682
664
 * \param pixels If pointer with NULL content is passed, a new buffer is
683
665
 * allocated otherwise, this user-supplied buffer is used.
684
666
 * \param num_rows Number of actual decoded rows
685
667
 * \param frame_number Frame number as reported in the header
686
668
 * \param time_stamp Time stamp of the frame as reported in the header
687
 
 * \paran cmask Change-mask
688
669
 *
689
670
 * \return 0 in case of no error, EIO if end of stream was reached, ENOMEM if
690
671
 * NULL was passed but no memory could be allocated, EILSEQ if data stream is
691
672
 * corrupt and EFAULT if pixels is a NULL-pointer.
692
673
 */
693
 
int ufo_decoder_get_next_frame(ufo_decoder    decoder, 
694
 
                               uint16_t     **pixels, 
695
 
                               uint32_t      *num_rows, 
696
 
                               uint32_t      *frame_number, 
697
 
                               uint32_t      *time_stamp, 
698
 
                               uint16_t      *cmask)
 
674
int ufo_decoder_get_next_frame(UfoDecoder     *decoder, 
 
675
                               uint16_t      **pixels, 
 
676
                               UfoDecoderMeta *meta)
699
677
{
700
678
    uint32_t *raw = decoder->raw;
701
679
    size_t pos = decoder->current_pos;
720
698
    while ((pos < num_words) && (raw[pos] != 0x51111111))
721
699
        pos++;
722
700
 
723
 
    advance = ufo_decoder_decode_frame(decoder, raw + pos, decoder->num_bytes -
724
 
            pos, *pixels, num_rows, frame_number, time_stamp, cmask);
 
701
    advance = ufo_decoder_decode_frame(decoder, raw + pos, decoder->num_bytes - pos, *pixels, meta);
725
702
 
726
703
    /*
727
704
     * On error, advance is 0 but we have to advance at least a bit to net get