GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/cri.c Lines: 0 259 0.0 %
Date: 2020-10-23 17:01:47 Branches: 0 139 0.0 %

Line Branch Exec Source
1
/*
2
 * CRI image decoder
3
 *
4
 * Copyright (c) 2020 Paul B Mahol
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
23
/**
24
 * @file
25
 * Cintel RAW image decoder
26
 */
27
28
#define BITSTREAM_READER_LE
29
30
#include "libavutil/intfloat.h"
31
#include "libavutil/display.h"
32
#include "avcodec.h"
33
#include "bytestream.h"
34
#include "get_bits.h"
35
#include "internal.h"
36
#include "thread.h"
37
38
typedef struct CRIContext {
39
    AVCodecContext *jpeg_avctx;   // wrapper context for MJPEG
40
    AVFrame *jpgframe;            // decoded JPEG tile
41
42
    GetByteContext gb;
43
    int color_model;
44
    const uint8_t *data;
45
    unsigned data_size;
46
    uint64_t tile_size[4];
47
} CRIContext;
48
49
static av_cold int cri_decode_init(AVCodecContext *avctx)
50
{
51
    CRIContext *s = avctx->priv_data;
52
    const AVCodec *codec;
53
    int ret;
54
55
    s->jpgframe = av_frame_alloc();
56
    if (!s->jpgframe)
57
        return AVERROR(ENOMEM);
58
59
    codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
60
    if (!codec)
61
        return AVERROR_BUG;
62
    s->jpeg_avctx = avcodec_alloc_context3(codec);
63
    if (!s->jpeg_avctx)
64
        return AVERROR(ENOMEM);
65
    s->jpeg_avctx->flags = avctx->flags;
66
    s->jpeg_avctx->flags2 = avctx->flags2;
67
    s->jpeg_avctx->dct_algo = avctx->dct_algo;
68
    s->jpeg_avctx->idct_algo = avctx->idct_algo;
69
    ret = ff_codec_open2_recursive(s->jpeg_avctx, codec, NULL);
70
    if (ret < 0)
71
        return ret;
72
73
    return 0;
74
}
75
76
static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift,
77
                         int w, int h, ptrdiff_t stride)
78
{
79
    int count = w * h;
80
    int pos = 0;
81
82
    while (count > 0) {
83
        uint32_t a0 = bytestream2_get_le32(gb);
84
        uint32_t a1 = bytestream2_get_le32(gb);
85
        uint32_t a2 = bytestream2_get_le32(gb);
86
        uint32_t a3 = bytestream2_get_le32(gb);
87
        dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift;
88
        pos++;
89
        if (pos >= w) {
90
            if (count == 1)
91
                break;
92
            dst += stride;
93
            pos = 0;
94
        }
95
        dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
96
        pos++;
97
        if (pos >= w) {
98
            if (count == 2)
99
                break;
100
            dst += stride;
101
            pos = 0;
102
        }
103
        dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
104
        pos++;
105
        if (pos >= w) {
106
            if (count == 3)
107
                break;
108
            dst += stride;
109
            pos = 0;
110
        }
111
        dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
112
        pos++;
113
        if (pos >= w) {
114
            if (count == 4)
115
                break;
116
            dst += stride;
117
            pos = 0;
118
        }
119
        dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
120
        pos++;
121
        if (pos >= w) {
122
            if (count == 5)
123
                break;
124
            dst += stride;
125
            pos = 0;
126
        }
127
        dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
128
        pos++;
129
        if (pos >= w) {
130
            if (count == 6)
131
                break;
132
            dst += stride;
133
            pos = 0;
134
        }
135
        dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
136
        pos++;
137
        if (pos >= w) {
138
            if (count == 7)
139
                break;
140
            dst += stride;
141
            pos = 0;
142
        }
143
        dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
144
        pos++;
145
        if (pos >= w) {
146
            if (count == 8)
147
                break;
148
            dst += stride;
149
            pos = 0;
150
        }
151
        dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
152
        pos++;
153
        if (pos >= w) {
154
            if (count == 9)
155
                break;
156
            dst += stride;
157
            pos = 0;
158
        }
159
160
        count -= 9;
161
    }
162
}
163
164
static int cri_decode_frame(AVCodecContext *avctx, void *data,
165
                            int *got_frame, AVPacket *avpkt)
166
{
167
    CRIContext *s = avctx->priv_data;
168
    GetByteContext *gb = &s->gb;
169
    ThreadFrame frame = { .f = data };
170
    int ret, bps, hflip = 0, vflip = 0;
171
    AVFrameSideData *rotation;
172
    int compressed = 0;
173
    AVFrame *p = data;
174
175
    s->data = NULL;
176
    s->data_size = 0;
177
178
    bytestream2_init(gb, avpkt->data, avpkt->size);
179
180
    while (bytestream2_get_bytes_left(gb) > 8) {
181
        char codec_name[1024];
182
        uint32_t key, length;
183
        float framerate;
184
185
        key    = bytestream2_get_le32(gb);
186
        length = bytestream2_get_le32(gb);
187
188
        switch (key) {
189
        case 1:
190
            if (length != 4)
191
                return AVERROR_INVALIDDATA;
192
193
            if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
194
                return AVERROR_INVALIDDATA;
195
            break;
196
        case 100:
197
            if (length < 16)
198
                return AVERROR_INVALIDDATA;
199
            avctx->width   = bytestream2_get_le32(gb);
200
            avctx->height  = bytestream2_get_le32(gb);
201
            s->color_model = bytestream2_get_le32(gb);
202
            if (bytestream2_get_le32(gb) != 1)
203
                return AVERROR_INVALIDDATA;
204
            length -= 16;
205
            goto skip;
206
        case 101:
207
            if (length != 4)
208
                return AVERROR_INVALIDDATA;
209
210
            if (bytestream2_get_le32(gb) != 0)
211
                return AVERROR_INVALIDDATA;
212
            break;
213
        case 102:
214
            bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1));
215
            length -= FFMIN(length, sizeof(codec_name) - 1);
216
            if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1)))
217
                return AVERROR_INVALIDDATA;
218
            compressed = 1;
219
            goto skip;
220
        case 103:
221
            if (bytestream2_get_bytes_left(gb) < length)
222
                return AVERROR_INVALIDDATA;
223
            s->data = gb->buffer;
224
            s->data_size = length;
225
            goto skip;
226
        case 105:
227
            hflip = bytestream2_get_byte(gb) != 0;
228
            length--;
229
            goto skip;
230
        case 106:
231
            vflip = bytestream2_get_byte(gb) != 0;
232
            length--;
233
            goto skip;
234
        case 107:
235
            if (length != 4)
236
                return AVERROR_INVALIDDATA;
237
            framerate = av_int2float(bytestream2_get_le32(gb));
238
            avctx->framerate.num = framerate * 1000;
239
            avctx->framerate.den = 1000;
240
            break;
241
        case 119:
242
            if (length != 32)
243
                return AVERROR_INVALIDDATA;
244
245
            for (int i = 0; i < 4; i++)
246
                s->tile_size[i] = bytestream2_get_le64(gb);
247
            break;
248
        default:
249
            av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
250
skip:
251
            bytestream2_skip(gb, length);
252
        }
253
    }
254
255
    switch (s->color_model) {
256
    case 76:
257
    case 88:
258
        avctx->pix_fmt = AV_PIX_FMT_BAYER_BGGR16;
259
        break;
260
    case 77:
261
    case 89:
262
        avctx->pix_fmt = AV_PIX_FMT_BAYER_GBRG16;
263
        break;
264
    case 78:
265
    case 90:
266
        avctx->pix_fmt = AV_PIX_FMT_BAYER_RGGB16;
267
        break;
268
    case 45:
269
    case 79:
270
    case 91:
271
        avctx->pix_fmt = AV_PIX_FMT_BAYER_GRBG16;
272
        break;
273
    }
274
275
    switch (s->color_model) {
276
    case 45:
277
        bps = 10;
278
        break;
279
    case 76:
280
    case 77:
281
    case 78:
282
    case 79:
283
        bps = 12;
284
        break;
285
    case 88:
286
    case 89:
287
    case 90:
288
    case 91:
289
        bps = 16;
290
        break;
291
    default:
292
        return AVERROR_INVALIDDATA;
293
    }
294
295
    if (compressed) {
296
        for (int i = 0; i < 4; i++) {
297
            if (s->tile_size[i] >= s->data_size)
298
                return AVERROR_INVALIDDATA;
299
        }
300
301
        if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
302
            s->data_size)
303
            return AVERROR_INVALIDDATA;
304
    }
305
306
    if (!s->data || !s->data_size)
307
        return AVERROR_INVALIDDATA;
308
309
    if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
310
        return ret;
311
312
    avctx->bits_per_raw_sample = bps;
313
314
    if (!compressed && s->color_model == 45) {
315
        uint16_t *dst = (uint16_t *)p->data[0];
316
        GetByteContext gb;
317
318
        bytestream2_init(&gb, s->data, s->data_size);
319
        unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
320
    } else if (!compressed) {
321
        GetBitContext gbit;
322
        const int shift = 16 - bps;
323
324
        ret = init_get_bits8(&gbit, s->data, s->data_size);
325
        if (ret < 0)
326
            return ret;
327
328
        for (int y = 0; y < avctx->height; y++) {
329
            uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);
330
331
            for (int x = 0; x < avctx->width; x++)
332
                dst[x] = get_bits(&gbit, bps) << shift;
333
        }
334
    } else {
335
        unsigned offset = 0;
336
337
        for (int tile = 0; tile < 4; tile++) {
338
            AVPacket jpkt;
339
340
            av_init_packet(&jpkt);
341
            jpkt.data = (uint8_t *)s->data + offset;
342
            jpkt.size = s->tile_size[tile];
343
344
            ret = avcodec_send_packet(s->jpeg_avctx, &jpkt);
345
            if (ret < 0) {
346
                av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
347
                return ret;
348
            }
349
350
            ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe);
351
            if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
352
                s->jpeg_avctx->width  * 2 != avctx->width ||
353
                s->jpeg_avctx->height * 2 != avctx->height) {
354
                if (ret < 0) {
355
                    av_log(avctx, AV_LOG_ERROR,
356
                           "JPEG decoding error (%d).\n", ret);
357
                } else {
358
                    av_log(avctx, AV_LOG_ERROR,
359
                           "JPEG invalid format.\n");
360
                    ret = AVERROR_INVALIDDATA;
361
                }
362
363
                /* Normally skip, if error explode */
364
                if (avctx->err_recognition & AV_EF_EXPLODE)
365
                    return ret;
366
                else
367
                    return 0;
368
            }
369
370
            for (int y = 0; y < s->jpeg_avctx->height; y++) {
371
                const int hw =  s->jpgframe->width / 2;
372
                uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
373
                const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);
374
375
                memcpy(dst, src, hw * 2);
376
                src += hw;
377
                dst += p->linesize[0] / 2;
378
                memcpy(dst, src, hw * 2);
379
            }
380
381
            av_frame_unref(s->jpgframe);
382
            offset += s->tile_size[tile];
383
        }
384
    }
385
386
    if (hflip || vflip) {
387
        rotation = av_frame_new_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX,
388
                                          sizeof(int32_t) * 9);
389
        if (rotation) {
390
            av_display_rotation_set((int32_t *)rotation->data, 0.f);
391
            av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
392
        }
393
    }
394
395
    p->pict_type = AV_PICTURE_TYPE_I;
396
    p->key_frame = 1;
397
398
    *got_frame = 1;
399
400
    return 0;
401
}
402
403
static av_cold int cri_decode_close(AVCodecContext *avctx)
404
{
405
    CRIContext *s = avctx->priv_data;
406
407
    av_frame_free(&s->jpgframe);
408
    avcodec_free_context(&s->jpeg_avctx);
409
410
    return 0;
411
}
412
413
AVCodec ff_cri_decoder = {
414
    .name           = "cri",
415
    .type           = AVMEDIA_TYPE_VIDEO,
416
    .id             = AV_CODEC_ID_CRI,
417
    .priv_data_size = sizeof(CRIContext),
418
    .init           = cri_decode_init,
419
    .decode         = cri_decode_frame,
420
    .close          = cri_decode_close,
421
    .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
422
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
423
    .long_name      = NULL_IF_CONFIG_SMALL("Cintel RAW"),
424
};