]> git.sesse.net Git - ffmpeg/blob - libavcodec/cri.c
avcodec/indeo3: add support for more dimensions
[ffmpeg] / libavcodec / cri.c
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 = avcodec_open2(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, a1, a2, a3;
84         if (bytestream2_get_bytes_left(gb) < 4)
85             break;
86         a0 = bytestream2_get_le32(gb);
87         a1 = bytestream2_get_le32(gb);
88         a2 = bytestream2_get_le32(gb);
89         a3 = bytestream2_get_le32(gb);
90         dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift;
91         pos++;
92         if (pos >= w) {
93             if (count == 1)
94                 break;
95             dst += stride;
96             pos = 0;
97         }
98         dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
99         pos++;
100         if (pos >= w) {
101             if (count == 2)
102                 break;
103             dst += stride;
104             pos = 0;
105         }
106         dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
107         pos++;
108         if (pos >= w) {
109             if (count == 3)
110                 break;
111             dst += stride;
112             pos = 0;
113         }
114         dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
115         pos++;
116         if (pos >= w) {
117             if (count == 4)
118                 break;
119             dst += stride;
120             pos = 0;
121         }
122         dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
123         pos++;
124         if (pos >= w) {
125             if (count == 5)
126                 break;
127             dst += stride;
128             pos = 0;
129         }
130         dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
131         pos++;
132         if (pos >= w) {
133             if (count == 6)
134                 break;
135             dst += stride;
136             pos = 0;
137         }
138         dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
139         pos++;
140         if (pos >= w) {
141             if (count == 7)
142                 break;
143             dst += stride;
144             pos = 0;
145         }
146         dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
147         pos++;
148         if (pos >= w) {
149             if (count == 8)
150                 break;
151             dst += stride;
152             pos = 0;
153         }
154         dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
155         pos++;
156         if (pos >= w) {
157             if (count == 9)
158                 break;
159             dst += stride;
160             pos = 0;
161         }
162
163         count -= 9;
164     }
165 }
166
167 static int cri_decode_frame(AVCodecContext *avctx, void *data,
168                             int *got_frame, AVPacket *avpkt)
169 {
170     CRIContext *s = avctx->priv_data;
171     GetByteContext *gb = &s->gb;
172     ThreadFrame frame = { .f = data };
173     int ret, bps, hflip = 0, vflip = 0;
174     AVFrameSideData *rotation;
175     int compressed = 0;
176     AVFrame *p = data;
177
178     s->data = NULL;
179     s->data_size = 0;
180
181     bytestream2_init(gb, avpkt->data, avpkt->size);
182
183     while (bytestream2_get_bytes_left(gb) > 8) {
184         char codec_name[1024];
185         uint32_t key, length;
186         float framerate;
187         int width, height;
188
189         key    = bytestream2_get_le32(gb);
190         length = bytestream2_get_le32(gb);
191
192         switch (key) {
193         case 1:
194             if (length != 4)
195                 return AVERROR_INVALIDDATA;
196
197             if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
198                 return AVERROR_INVALIDDATA;
199             break;
200         case 100:
201             if (length < 16)
202                 return AVERROR_INVALIDDATA;
203             width   = bytestream2_get_le32(gb);
204             height  = bytestream2_get_le32(gb);
205             s->color_model = bytestream2_get_le32(gb);
206             if (bytestream2_get_le32(gb) != 1)
207                 return AVERROR_INVALIDDATA;
208             ret = ff_set_dimensions(avctx, width, height);
209             if (ret < 0)
210                 return ret;
211             length -= 16;
212             goto skip;
213         case 101:
214             if (length != 4)
215                 return AVERROR_INVALIDDATA;
216
217             if (bytestream2_get_le32(gb) != 0)
218                 return AVERROR_INVALIDDATA;
219             break;
220         case 102:
221             bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1));
222             length -= FFMIN(length, sizeof(codec_name) - 1);
223             if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1)))
224                 return AVERROR_INVALIDDATA;
225             compressed = 1;
226             goto skip;
227         case 103:
228             if (bytestream2_get_bytes_left(gb) < length)
229                 return AVERROR_INVALIDDATA;
230             s->data = gb->buffer;
231             s->data_size = length;
232             goto skip;
233         case 105:
234             hflip = bytestream2_get_byte(gb) != 0;
235             length--;
236             goto skip;
237         case 106:
238             vflip = bytestream2_get_byte(gb) != 0;
239             length--;
240             goto skip;
241         case 107:
242             if (length != 4)
243                 return AVERROR_INVALIDDATA;
244             framerate = av_int2float(bytestream2_get_le32(gb));
245             avctx->framerate.num = framerate * 1000;
246             avctx->framerate.den = 1000;
247             break;
248         case 119:
249             if (length != 32)
250                 return AVERROR_INVALIDDATA;
251
252             for (int i = 0; i < 4; i++)
253                 s->tile_size[i] = bytestream2_get_le64(gb);
254             break;
255         default:
256             av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
257 skip:
258             bytestream2_skip(gb, length);
259         }
260     }
261
262     switch (s->color_model) {
263     case 76:
264     case 88:
265         avctx->pix_fmt = AV_PIX_FMT_BAYER_BGGR16;
266         break;
267     case 77:
268     case 89:
269         avctx->pix_fmt = AV_PIX_FMT_BAYER_GBRG16;
270         break;
271     case 78:
272     case 90:
273         avctx->pix_fmt = AV_PIX_FMT_BAYER_RGGB16;
274         break;
275     case 45:
276     case 79:
277     case 91:
278         avctx->pix_fmt = AV_PIX_FMT_BAYER_GRBG16;
279         break;
280     }
281
282     switch (s->color_model) {
283     case 45:
284         bps = 10;
285         break;
286     case 76:
287     case 77:
288     case 78:
289     case 79:
290         bps = 12;
291         break;
292     case 88:
293     case 89:
294     case 90:
295     case 91:
296         bps = 16;
297         break;
298     default:
299         return AVERROR_INVALIDDATA;
300     }
301
302     if (compressed) {
303         for (int i = 0; i < 4; i++) {
304             if (s->tile_size[i] >= s->data_size)
305                 return AVERROR_INVALIDDATA;
306         }
307
308         if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
309             s->data_size)
310             return AVERROR_INVALIDDATA;
311     }
312
313     if (!s->data || !s->data_size)
314         return AVERROR_INVALIDDATA;
315
316     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
317         return ret;
318
319     avctx->bits_per_raw_sample = bps;
320
321     if (!compressed && s->color_model == 45) {
322         uint16_t *dst = (uint16_t *)p->data[0];
323         GetByteContext gb;
324
325         bytestream2_init(&gb, s->data, s->data_size);
326         unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
327     } else if (!compressed) {
328         GetBitContext gbit;
329         const int shift = 16 - bps;
330
331         ret = init_get_bits8(&gbit, s->data, s->data_size);
332         if (ret < 0)
333             return ret;
334
335         for (int y = 0; y < avctx->height; y++) {
336             uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);
337
338             for (int x = 0; x < avctx->width; x++)
339                 dst[x] = get_bits(&gbit, bps) << shift;
340         }
341     } else {
342         unsigned offset = 0;
343
344         for (int tile = 0; tile < 4; tile++) {
345             AVPacket jpkt;
346
347             av_init_packet(&jpkt);
348             jpkt.data = (uint8_t *)s->data + offset;
349             jpkt.size = s->tile_size[tile];
350
351             ret = avcodec_send_packet(s->jpeg_avctx, &jpkt);
352             if (ret < 0) {
353                 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
354                 return ret;
355             }
356
357             ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe);
358             if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
359                 s->jpeg_avctx->width  * 2 != avctx->width ||
360                 s->jpeg_avctx->height * 2 != avctx->height) {
361                 if (ret < 0) {
362                     av_log(avctx, AV_LOG_ERROR,
363                            "JPEG decoding error (%d).\n", ret);
364                 } else {
365                     av_log(avctx, AV_LOG_ERROR,
366                            "JPEG invalid format.\n");
367                     ret = AVERROR_INVALIDDATA;
368                 }
369
370                 /* Normally skip, if error explode */
371                 if (avctx->err_recognition & AV_EF_EXPLODE)
372                     return ret;
373                 else
374                     return 0;
375             }
376
377             for (int y = 0; y < s->jpeg_avctx->height; y++) {
378                 const int hw =  s->jpgframe->width / 2;
379                 uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
380                 const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);
381
382                 memcpy(dst, src, hw * 2);
383                 src += hw;
384                 dst += p->linesize[0] / 2;
385                 memcpy(dst, src, hw * 2);
386             }
387
388             av_frame_unref(s->jpgframe);
389             offset += s->tile_size[tile];
390         }
391     }
392
393     if (hflip || vflip) {
394         rotation = av_frame_new_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX,
395                                           sizeof(int32_t) * 9);
396         if (rotation) {
397             av_display_rotation_set((int32_t *)rotation->data, 0.f);
398             av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
399         }
400     }
401
402     p->pict_type = AV_PICTURE_TYPE_I;
403     p->key_frame = 1;
404
405     *got_frame = 1;
406
407     return 0;
408 }
409
410 static av_cold int cri_decode_close(AVCodecContext *avctx)
411 {
412     CRIContext *s = avctx->priv_data;
413
414     av_frame_free(&s->jpgframe);
415     avcodec_free_context(&s->jpeg_avctx);
416
417     return 0;
418 }
419
420 AVCodec ff_cri_decoder = {
421     .name           = "cri",
422     .type           = AVMEDIA_TYPE_VIDEO,
423     .id             = AV_CODEC_ID_CRI,
424     .priv_data_size = sizeof(CRIContext),
425     .init           = cri_decode_init,
426     .decode         = cri_decode_frame,
427     .close          = cri_decode_close,
428     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
429     .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
430     .long_name      = NULL_IF_CONFIG_SMALL("Cintel RAW"),
431 };