Browse code

Merge commit '247e370e2a913db52ca079b347a174c8d393b171'

* commit '247e370e2a913db52ca079b347a174c8d393b171':
TDSC decoder

Conflicts:
Changelog
doc/general.texi
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/version.h
tests/fate/video.mak

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2015/03/14 07:17:54
Showing 12 changed files
... ...
@@ -3,6 +3,7 @@ releases are sorted from youngest to oldest.
3 3
 
4 4
 version <next>:
5 5
 - FFT video filter
6
+- TDSC decoder
6 7
 
7 8
 
8 9
 version 2.6:
... ...
@@ -2231,6 +2231,8 @@ svq1_encoder_select="aandcttables hpeldsp me_cmp mpegvideoenc"
2231 2231
 svq3_decoder_select="h264_decoder hpeldsp tpeldsp"
2232 2232
 svq3_decoder_suggest="zlib"
2233 2233
 tak_decoder_select="audiodsp"
2234
+tdsc_decoder_deps="zlib"
2235
+tdsc_decoder_select="mjpeg_decoder"
2234 2236
 theora_decoder_select="vp3_decoder"
2235 2237
 thp_decoder_select="mjpeg_decoder"
2236 2238
 tiff_decoder_suggest="zlib lzma"
... ...
@@ -466,6 +466,7 @@ library:
466 466
 @item SoX native format         @tab X @tab X
467 467
 @item SUN AU format             @tab X @tab X
468 468
 @item SUP raw PGS subtitles     @tab   @tab X
469
+@item TDSC                      @tab   @tab X
469 470
 @item Text files                @tab   @tab X
470 471
 @item THP                       @tab   @tab X
471 472
     @tab Used on the Nintendo GameCube.
... ...
@@ -458,6 +458,7 @@ OBJS-$(CONFIG_TAK_DECODER)             += takdec.o tak.o
458 458
 OBJS-$(CONFIG_TARGA_DECODER)           += targa.o
459 459
 OBJS-$(CONFIG_TARGA_ENCODER)           += targaenc.o rle.o
460 460
 OBJS-$(CONFIG_TARGA_Y216_DECODER)      += targa_y216dec.o
461
+OBJS-$(CONFIG_TDSC_DECODER)            += tdsc.o
461 462
 OBJS-$(CONFIG_TIERTEXSEQVIDEO_DECODER) += tiertexseqv.o
462 463
 OBJS-$(CONFIG_TIFF_DECODER)            += tiff.o lzw.o faxcompr.o tiff_data.o tiff_common.o
463 464
 OBJS-$(CONFIG_TIFF_ENCODER)            += tiffenc.o rle.o lzwenc.o tiff_data.o
... ...
@@ -269,6 +269,7 @@ void avcodec_register_all(void)
269 269
     REGISTER_DECODER(SVQ3,              svq3);
270 270
     REGISTER_ENCDEC (TARGA,             targa);
271 271
     REGISTER_DECODER(TARGA_Y216,        targa_y216);
272
+    REGISTER_DECODER(TDSC,              tdsc);
272 273
     REGISTER_DECODER(THEORA,            theora);
273 274
     REGISTER_DECODER(THP,               thp);
274 275
     REGISTER_DECODER(TIERTEXSEQVIDEO,   tiertexseqvideo);
... ...
@@ -291,6 +291,7 @@ enum AVCodecID {
291 291
     AV_CODEC_ID_MVC1_DEPRECATED,
292 292
     AV_CODEC_ID_MVC2_DEPRECATED,
293 293
     AV_CODEC_ID_HQX,
294
+    AV_CODEC_ID_TDSC,
294 295
 
295 296
     AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'),
296 297
     AV_CODEC_ID_Y41P       = MKBETAG('Y','4','1','P'),
... ...
@@ -1395,6 +1395,13 @@ static const AVCodecDescriptor codec_descriptors[] = {
1395 1395
         .mime_types= MT("image/x-targa", "image/x-tga"),
1396 1396
     },
1397 1397
     {
1398
+        .id        = AV_CODEC_ID_TDSC,
1399
+        .type      = AVMEDIA_TYPE_VIDEO,
1400
+        .name      = "tdsc",
1401
+        .long_name = NULL_IF_CONFIG_SMALL("TDSC"),
1402
+        .props     = AV_CODEC_PROP_LOSSY,
1403
+    },
1404
+    {
1398 1405
         .id        = AV_CODEC_ID_TIFF,
1399 1406
         .type      = AVMEDIA_TYPE_VIDEO,
1400 1407
         .name      = "tiff",
1401 1408
new file mode 100644
... ...
@@ -0,0 +1,627 @@
0
+/*
1
+ * TDSC decoder
2
+ * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@gmail.com>
3
+ *
4
+ * This file is part of FFmpeg.
5
+ *
6
+ * FFmpeg is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * FFmpeg is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with FFmpeg; if not, write to the Free Software
18
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
+ */
20
+
21
+/**
22
+ * @file
23
+ * TDSC decoder
24
+ *
25
+ * Fourcc: TSDC
26
+ *
27
+ * TDSC is very simple. It codes picture by tiles, storing them in raw BGR24
28
+ * format or compressing them in JPEG. Frames can be full pictures or just
29
+ * updates to the previous frame. Cursor is found in its own frame or at the
30
+ * bottom of the picture. Every frame is then packed with zlib.
31
+ *
32
+ * Supports: BGR24
33
+ */
34
+
35
+#include <stdint.h>
36
+#include <zlib.h>
37
+
38
+#include "libavutil/imgutils.h"
39
+
40
+#include "avcodec.h"
41
+#include "bytestream.h"
42
+#include "internal.h"
43
+
44
+#define BITMAPINFOHEADER_SIZE 0x28
45
+#define TDSF_HEADER_SIZE      0x56
46
+#define TDSB_HEADER_SIZE      0x08
47
+
48
+typedef struct TDSCContext {
49
+    AVCodecContext *jpeg_avctx;   // wrapper context for MJPEG
50
+
51
+    int width, height;
52
+    GetByteContext gbc;
53
+
54
+    AVFrame *refframe;          // full decoded frame (without cursor)
55
+    AVFrame *jpgframe;          // decoded JPEG tile
56
+    uint8_t *tilebuffer;        // buffer containing tile data
57
+
58
+    /* zlib interation */
59
+    uint8_t *deflatebuffer;
60
+    uLongf deflatelen;
61
+
62
+    /* All that is cursor */
63
+    uint8_t    *cursor;
64
+    int        cursor_stride;
65
+    int        cursor_w, cursor_h, cursor_x, cursor_y;
66
+    int        cursor_hot_x, cursor_hot_y;
67
+} TDSCContext;
68
+
69
+/* 1 byte bits, 1 byte planes, 2 bytes format (probably) */
70
+enum TDSCCursorFormat {
71
+    CUR_FMT_MONO = 0x01010004,
72
+    CUR_FMT_BGRA = 0x20010004,
73
+    CUR_FMT_RGBA = 0x20010008,
74
+};
75
+
76
+static av_cold int tdsc_close(AVCodecContext *avctx)
77
+{
78
+    TDSCContext *ctx = avctx->priv_data;
79
+
80
+    av_frame_free(&ctx->refframe);
81
+    av_frame_free(&ctx->jpgframe);
82
+    av_freep(&ctx->deflatebuffer);
83
+    av_freep(&ctx->tilebuffer);
84
+    av_freep(&ctx->cursor);
85
+    avcodec_free_context(&ctx->jpeg_avctx);
86
+
87
+    return 0;
88
+}
89
+
90
+static av_cold int tdsc_init(AVCodecContext *avctx)
91
+{
92
+    TDSCContext *ctx = avctx->priv_data;
93
+    const AVCodec *codec;
94
+    int ret;
95
+
96
+    avctx->pix_fmt = AV_PIX_FMT_BGR24;
97
+
98
+    /* These needs to be set to estimate buffer and frame size */
99
+    if (!(avctx->width && avctx->height)) {
100
+        av_log(avctx, AV_LOG_ERROR, "Video size not set.\n");
101
+        return AVERROR_INVALIDDATA;
102
+    }
103
+
104
+    /* This value should be large enough for a RAW-only frame plus headers */
105
+    ctx->deflatelen = avctx->width * avctx->height * (3 + 1);
106
+    ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen);
107
+    if (ret < 0)
108
+        return ret;
109
+
110
+    /* Allocate reference and JPEG frame */
111
+    ctx->refframe = av_frame_alloc();
112
+    ctx->jpgframe = av_frame_alloc();
113
+    if (!ctx->refframe || !ctx->jpgframe)
114
+        return AVERROR(ENOMEM);
115
+
116
+    /* Prepare everything needed for JPEG decoding */
117
+    codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
118
+    if (!codec)
119
+        return AVERROR_BUG;
120
+    ctx->jpeg_avctx = avcodec_alloc_context3(codec);
121
+    if (!ctx->jpeg_avctx)
122
+        return AVERROR(ENOMEM);
123
+    ctx->jpeg_avctx->flags = avctx->flags;
124
+    ctx->jpeg_avctx->flags2 = avctx->flags2;
125
+    ctx->jpeg_avctx->dct_algo = avctx->dct_algo;
126
+    ctx->jpeg_avctx->idct_algo = avctx->idct_algo;;
127
+    ret = avcodec_open2(ctx->jpeg_avctx, codec, NULL);
128
+    if (ret < 0)
129
+        return ret;
130
+
131
+    /* Set the output pixel format on the reference frame */
132
+    ctx->refframe->format = avctx->pix_fmt;
133
+
134
+    return 0;
135
+}
136
+
137
+#define APPLY_ALPHA(src, new, alpha) \
138
+    src = (src * (256 - alpha) + new * alpha) >> 8
139
+
140
+/* Paint a region over a buffer, without drawing out of its bounds. */
141
+static void tdsc_paint_cursor(AVCodecContext *avctx, uint8_t *dst, int stride)
142
+{
143
+    TDSCContext *ctx = avctx->priv_data;
144
+    const uint8_t *cursor = ctx->cursor;
145
+    int x = ctx->cursor_x - ctx->cursor_hot_x;
146
+    int y = ctx->cursor_y - ctx->cursor_hot_y;
147
+    int w = ctx->cursor_w;
148
+    int h = ctx->cursor_h;
149
+    int i, j;
150
+
151
+    if (!ctx->cursor)
152
+        return;
153
+
154
+    if (x + w > ctx->width)
155
+        w = ctx->width - x;
156
+    if (y + h > ctx->height)
157
+        h = ctx->height - y;
158
+    if (x < 0) {
159
+        w      +=  x;
160
+        cursor += -x * 4;
161
+    } else {
162
+        dst    +=  x * 3;
163
+    }
164
+    if (y < 0) {
165
+        h      +=  y;
166
+        cursor += -y * ctx->cursor_stride;
167
+    } else {
168
+        dst    +=  y * stride;
169
+    }
170
+    if (w < 0 || h < 0)
171
+        return;
172
+
173
+    for (j = 0; j < h; j++) {
174
+        for (i = 0; i < w; i++) {
175
+            uint8_t alpha = cursor[i * 4];
176
+            APPLY_ALPHA(dst[i * 3 + 0], cursor[i * 4 + 1], alpha);
177
+            APPLY_ALPHA(dst[i * 3 + 1], cursor[i * 4 + 2], alpha);
178
+            APPLY_ALPHA(dst[i * 3 + 2], cursor[i * 4 + 3], alpha);
179
+        }
180
+        dst    += stride;
181
+        cursor += ctx->cursor_stride;
182
+    }
183
+}
184
+
185
+/* Load cursor data and store it in ABGR mode. */
186
+static int tdsc_load_cursor(AVCodecContext *avctx)
187
+{
188
+    TDSCContext *ctx  = avctx->priv_data;
189
+    int i, j, k, ret, bits, cursor_fmt;
190
+    uint8_t *dst;
191
+
192
+    ctx->cursor_hot_x = bytestream2_get_le16(&ctx->gbc);
193
+    ctx->cursor_hot_y = bytestream2_get_le16(&ctx->gbc);
194
+    ctx->cursor_w     = bytestream2_get_le16(&ctx->gbc);
195
+    ctx->cursor_h     = bytestream2_get_le16(&ctx->gbc);
196
+
197
+    ctx->cursor_stride = FFALIGN(ctx->cursor_w, 32) * 4;
198
+    cursor_fmt = bytestream2_get_le32(&ctx->gbc);
199
+
200
+    if (ctx->cursor_x >= avctx->width || ctx->cursor_y >= avctx->height) {
201
+        av_log(avctx, AV_LOG_ERROR,
202
+               "Invalid cursor position (%d.%d outside %dx%d).\n",
203
+               ctx->cursor_x, ctx->cursor_y, avctx->width, avctx->height);
204
+        return AVERROR_INVALIDDATA;
205
+    }
206
+    if (ctx->cursor_w < 1 || ctx->cursor_w > 256 ||
207
+        ctx->cursor_h < 1 || ctx->cursor_h > 256) {
208
+        av_log(avctx, AV_LOG_ERROR,
209
+               "Invalid cursor dimensions %dx%d.\n",
210
+               ctx->cursor_w, ctx->cursor_h);
211
+        return AVERROR_INVALIDDATA;
212
+    }
213
+    if (ctx->cursor_hot_x > ctx->cursor_w ||
214
+        ctx->cursor_hot_y > ctx->cursor_h) {
215
+        av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d.%d.\n",
216
+               ctx->cursor_hot_x, ctx->cursor_hot_y);
217
+        ctx->cursor_hot_x = FFMIN(ctx->cursor_hot_x, ctx->cursor_w - 1);
218
+        ctx->cursor_hot_y = FFMIN(ctx->cursor_hot_y, ctx->cursor_h - 1);
219
+    }
220
+
221
+    ret = av_reallocp(&ctx->cursor, ctx->cursor_stride * ctx->cursor_h);
222
+    if (ret < 0) {
223
+        av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer.\n");
224
+        return ret;
225
+    }
226
+
227
+    dst = ctx->cursor;
228
+    /* here data is packed in BE */
229
+    switch (cursor_fmt) {
230
+    case CUR_FMT_MONO:
231
+        for (j = 0; j < ctx->cursor_h; j++) {
232
+            for (i = 0; i < ctx->cursor_w; i += 32) {
233
+                bits = bytestream2_get_be32(&ctx->gbc);
234
+                for (k = 0; k < 32; k++) {
235
+                    dst[0] = !!(bits & 0x80000000);
236
+                    dst   += 4;
237
+                    bits <<= 1;
238
+                }
239
+            }
240
+            dst += ctx->cursor_stride - ctx->cursor_w * 4;
241
+        }
242
+
243
+        dst = ctx->cursor;
244
+        for (j = 0; j < ctx->cursor_h; j++) {
245
+            for (i = 0; i < ctx->cursor_w; i += 32) {
246
+                bits = bytestream2_get_be32(&ctx->gbc);
247
+                for (k = 0; k < 32; k++) {
248
+                    int mask_bit = !!(bits & 0x80000000);
249
+                    switch (dst[0] * 2 + mask_bit) {
250
+                    case 0:
251
+                        dst[0] = 0xFF;
252
+                        dst[1] = 0x00;
253
+                        dst[2] = 0x00;
254
+                        dst[3] = 0x00;
255
+                        break;
256
+                    case 1:
257
+                        dst[0] = 0xFF;
258
+                        dst[1] = 0xFF;
259
+                        dst[2] = 0xFF;
260
+                        dst[3] = 0xFF;
261
+                        break;
262
+                    default:
263
+                        dst[0] = 0x00;
264
+                        dst[1] = 0x00;
265
+                        dst[2] = 0x00;
266
+                        dst[3] = 0x00;
267
+                    }
268
+                    dst   += 4;
269
+                    bits <<= 1;
270
+                }
271
+            }
272
+            dst += ctx->cursor_stride - ctx->cursor_w * 4;
273
+        }
274
+        break;
275
+    case CUR_FMT_BGRA:
276
+    case CUR_FMT_RGBA:
277
+        /* Skip monochrome version of the cursor */
278
+        bytestream2_skip(&ctx->gbc,
279
+                         ctx->cursor_h * (FFALIGN(ctx->cursor_w, 32) >> 3));
280
+        if (cursor_fmt & 8) { // RGBA -> ABGR
281
+            for (j = 0; j < ctx->cursor_h; j++) {
282
+                for (i = 0; i < ctx->cursor_w; i++) {
283
+                    int val = bytestream2_get_be32(&ctx->gbc);
284
+                    *dst++ = val >> 24;
285
+                    *dst++ = val >> 16;
286
+                    *dst++ = val >>  8;
287
+                    *dst++ = val >>  0;
288
+                }
289
+                dst += ctx->cursor_stride - ctx->cursor_w * 4;
290
+            }
291
+        } else { // BGRA -> ABGR
292
+            for (j = 0; j < ctx->cursor_h; j++) {
293
+                for (i = 0; i < ctx->cursor_w; i++) {
294
+                    int val = bytestream2_get_be32(&ctx->gbc);
295
+                    *dst++ = val >>  0;
296
+                    *dst++ = val >> 24;
297
+                    *dst++ = val >> 16;
298
+                    *dst++ = val >>  8;
299
+                }
300
+                dst += ctx->cursor_stride - ctx->cursor_w * 4;
301
+            }
302
+        }
303
+        break;
304
+    default:
305
+        avpriv_request_sample(avctx, "Cursor format %08x", cursor_fmt);
306
+        return AVERROR_PATCHWELCOME;
307
+    }
308
+
309
+    return 0;
310
+}
311
+
312
+/* Convert a single YUV pixel to RGB. */
313
+static inline void tdsc_yuv2rgb(uint8_t *out, int Y, int U, int V)
314
+{
315
+    out[0] = av_clip_uint8(Y + (             91881 * V + 32768 >> 16));
316
+    out[1] = av_clip_uint8(Y + (-22554 * U - 46802 * V + 32768 >> 16));
317
+    out[2] = av_clip_uint8(Y + (116130 * U             + 32768 >> 16));
318
+}
319
+
320
+/* Convert a YUV420 buffer to a RGB buffer. */
321
+static av_always_inline void tdsc_blit(uint8_t *dst, int dst_stride,
322
+                                       const uint8_t *srcy, int srcy_stride,
323
+                                       const uint8_t *srcu, const uint8_t *srcv,
324
+                                       int srcuv_stride, int width, int height)
325
+{
326
+    int col, line;
327
+    for (line = 0; line < height; line++) {
328
+        for (col = 0; col < width; col++)
329
+            tdsc_yuv2rgb(dst + col * 3, srcy[col],
330
+                         srcu[col >> 1] - 128, srcv[col >> 1] - 128);
331
+
332
+        dst  +=   dst_stride;
333
+        srcy +=  srcy_stride;
334
+        srcu += srcuv_stride * (line & 1);
335
+        srcv += srcuv_stride * (line & 1);
336
+    }
337
+}
338
+
339
+/* Invoke the MJPEG decoder to decode the tile. */
340
+static int tdsc_decode_jpeg_tile(AVCodecContext *avctx, int tile_size,
341
+                                 int x, int y, int w, int h)
342
+{
343
+    TDSCContext *ctx = avctx->priv_data;
344
+    AVPacket jpkt;
345
+    int got_frame = 0;
346
+    int ret;
347
+
348
+    /* Prepare a packet and send to the MJPEG decoder */
349
+    av_init_packet(&jpkt);
350
+    jpkt.data = ctx->tilebuffer;
351
+    jpkt.size = tile_size;
352
+
353
+    ret = avcodec_decode_video2(ctx->jpeg_avctx, ctx->jpgframe,
354
+                                &got_frame, &jpkt);
355
+    if (ret < 0 || !got_frame || ctx->jpgframe->format != AV_PIX_FMT_YUVJ420P) {
356
+        av_log(avctx, AV_LOG_ERROR,
357
+               "JPEG decoding error (%d) for (%d) frame.\n",
358
+               ret, got_frame);
359
+
360
+        /* Normally skip, error if explode */
361
+        if (avctx->err_recognition & AV_EF_EXPLODE)
362
+            return AVERROR_INVALIDDATA;
363
+        else
364
+            return 0;
365
+    }
366
+
367
+    /* Let's paint ont the buffer */
368
+    tdsc_blit(ctx->refframe->data[0] + x * 3 + ctx->refframe->linesize[0] * y,
369
+              ctx->refframe->linesize[0],
370
+              ctx->jpgframe->data[0], ctx->jpgframe->linesize[0],
371
+              ctx->jpgframe->data[1], ctx->jpgframe->data[2],
372
+              ctx->jpgframe->linesize[1], w, h);
373
+
374
+    av_frame_unref(ctx->jpgframe);
375
+
376
+    return 0;
377
+}
378
+
379
+/* Parse frame and either copy data or decode JPEG. */
380
+static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles)
381
+{
382
+    TDSCContext *ctx = avctx->priv_data;
383
+    int i;
384
+
385
+    /* Iterate over the number of tiles */
386
+    for (i = 0; i < number_tiles; i++) {
387
+        int tile_size;
388
+        int tile_mode;
389
+        int x, y, w, h;
390
+        int ret;
391
+
392
+        if (bytestream2_get_bytes_left(&ctx->gbc) < 4 ||
393
+            bytestream2_get_le32(&ctx->gbc) != MKTAG('T','D','S','B') ||
394
+            bytestream2_get_bytes_left(&ctx->gbc) < TDSB_HEADER_SIZE - 4) {
395
+            av_log(avctx, AV_LOG_ERROR, "TDSB tag is too small.\n");
396
+            return AVERROR_INVALIDDATA;
397
+        }
398
+
399
+        tile_size = bytestream2_get_le32(&ctx->gbc);
400
+        if (bytestream2_get_bytes_left(&ctx->gbc) < tile_size)
401
+            return AVERROR_INVALIDDATA;
402
+
403
+        tile_mode = bytestream2_get_le32(&ctx->gbc);
404
+        bytestream2_skip(&ctx->gbc, 4); // unknown
405
+        x = bytestream2_get_le32(&ctx->gbc);
406
+        y = bytestream2_get_le32(&ctx->gbc);
407
+        w = bytestream2_get_le32(&ctx->gbc) - x;
408
+        h = bytestream2_get_le32(&ctx->gbc) - y;
409
+
410
+        if (x >= ctx->width || y >= ctx->height) {
411
+            av_log(avctx, AV_LOG_ERROR,
412
+                   "Invalid tile position (%d.%d outside %dx%d).\n",
413
+                   x, y, ctx->width, ctx->height);
414
+            return AVERROR_INVALIDDATA;
415
+        }
416
+        if (x + w > ctx->width || y + h > ctx->height) {
417
+            av_log(avctx, AV_LOG_ERROR,
418
+                   "Invalid tile size %dx%d\n", w, h);
419
+            return AVERROR_INVALIDDATA;
420
+        }
421
+
422
+        ret = av_reallocp(&ctx->tilebuffer, tile_size);
423
+        if (!ctx->tilebuffer)
424
+            return ret;
425
+
426
+        bytestream2_get_buffer(&ctx->gbc, ctx->tilebuffer, tile_size);
427
+
428
+        if (tile_mode == MKTAG('G','E','P','J')) {
429
+            /* Decode JPEG tile and copy it in the reference frame */
430
+            ret = tdsc_decode_jpeg_tile(avctx, tile_size, x, y, w, h);
431
+            if (ret < 0)
432
+                return ret;
433
+        } else if (tile_mode == MKTAG(' ','W','A','R')) {
434
+            /* Just copy the buffer to output */
435
+            av_image_copy_plane(ctx->refframe->data[0] + x * 3 +
436
+                                ctx->refframe->linesize[0] * y,
437
+                                ctx->refframe->linesize[0], ctx->tilebuffer,
438
+                                w * 3, w * 3, h);
439
+        } else {
440
+            av_log(avctx, AV_LOG_ERROR, "Unknown tile type %08x.\n", tile_mode);
441
+            return AVERROR_INVALIDDATA;
442
+        }
443
+        av_log(avctx, AV_LOG_DEBUG, "Tile %d, %dx%d (%d.%d)\n", i, w, h, x, y);
444
+    }
445
+
446
+    return 0;
447
+}
448
+
449
+static int tdsc_parse_tdsf(AVCodecContext *avctx, int number_tiles)
450
+{
451
+    TDSCContext *ctx = avctx->priv_data;
452
+    int ret, w, h, init_refframe = !ctx->refframe->data[0];
453
+
454
+    /* BITMAPINFOHEADER
455
+     * http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx */
456
+    if (bytestream2_get_le32(&ctx->gbc) != BITMAPINFOHEADER_SIZE)
457
+        return AVERROR_INVALIDDATA;
458
+
459
+    /* Store size, but wait for context reinit before updating avctx */
460
+    w =  bytestream2_get_le32(&ctx->gbc);
461
+    h = -bytestream2_get_le32(&ctx->gbc);
462
+
463
+    if (bytestream2_get_le16(&ctx->gbc) != 1 ||  // 1 plane
464
+        bytestream2_get_le16(&ctx->gbc) != 24)   // BGR24
465
+        return AVERROR_INVALIDDATA;
466
+
467
+    bytestream2_skip(&ctx->gbc, 24); // unused fields
468
+
469
+    /* Update sizes */
470
+    if (avctx->width != w || avctx->height != h) {
471
+        av_log(avctx, AV_LOG_DEBUG, "Size update %dx%d -> %d%d.\n",
472
+               avctx->width, avctx->height, ctx->width, ctx->height);
473
+        ret = ff_set_dimensions(avctx, w, h);
474
+        if (ret < 0)
475
+            return ret;
476
+        init_refframe = 1;
477
+    }
478
+    ctx->refframe->width  = ctx->width  = w;
479
+    ctx->refframe->height = ctx->height = h;
480
+
481
+    /* Allocate the reference frame if not already done or on size change */
482
+    if (init_refframe) {
483
+        ret = av_frame_get_buffer(ctx->refframe, 32);
484
+        if (ret < 0)
485
+            return ret;
486
+    }
487
+
488
+    /* Decode all tiles in a frame */
489
+    return tdsc_decode_tiles(avctx, number_tiles);
490
+}
491
+
492
+static int tdsc_parse_dtsm(AVCodecContext *avctx)
493
+{
494
+    TDSCContext *ctx = avctx->priv_data;
495
+    int ret;
496
+    int action = bytestream2_get_le32(&ctx->gbc);
497
+
498
+    bytestream2_skip(&ctx->gbc, 4); // some kind of ID or version maybe?
499
+
500
+    if (action == 2 || action == 3) {
501
+        /* Load cursor coordinates */
502
+        ctx->cursor_x = bytestream2_get_le32(&ctx->gbc);
503
+        ctx->cursor_y = bytestream2_get_le32(&ctx->gbc);
504
+
505
+        /* Load a full cursor sprite */
506
+        if (action == 3) {
507
+            ret = tdsc_load_cursor(avctx);
508
+            /* Do not consider cursor errors fatal unless in explode mode */
509
+            if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE))
510
+                return ret;
511
+        }
512
+    } else {
513
+        avpriv_request_sample(avctx, "Cursor action %d", action);
514
+    }
515
+
516
+    return 0;
517
+}
518
+
519
+static int tdsc_decode_frame(AVCodecContext *avctx, void *data,
520
+                             int *got_frame, AVPacket *avpkt)
521
+{
522
+    TDSCContext *ctx = avctx->priv_data;
523
+    AVFrame *frame = data;
524
+    int ret, tag_header, keyframe = 0;
525
+    uLongf dlen;
526
+
527
+    /* Resize deflate buffer on resolution change */
528
+    if (ctx->width != avctx->width || ctx->height != avctx->height) {
529
+        ctx->deflatelen = avctx->width * avctx->height * (3 + 1);
530
+        ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen);
531
+        if (ret < 0)
532
+            return ret;
533
+    }
534
+    dlen = ctx->deflatelen;
535
+
536
+    /* Frames are deflated, need to inflate them first */
537
+    ret = uncompress(ctx->deflatebuffer, &dlen, avpkt->data, avpkt->size);
538
+    if (ret) {
539
+        av_log(avctx, AV_LOG_ERROR, "Deflate error %d.\n", ret);
540
+        return AVERROR_UNKNOWN;
541
+    }
542
+
543
+    bytestream2_init(&ctx->gbc, ctx->deflatebuffer, dlen);
544
+
545
+    /* Check for tag and for size info */
546
+    if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) {
547
+        av_log(avctx, AV_LOG_ERROR, "Frame is too small.\n");
548
+        return AVERROR_INVALIDDATA;
549
+    }
550
+
551
+    /* Read tag */
552
+    tag_header = bytestream2_get_le32(&ctx->gbc);
553
+
554
+    if (tag_header == MKTAG('T','D','S','F')) {
555
+        int number_tiles;
556
+        if (bytestream2_get_bytes_left(&ctx->gbc) < TDSF_HEADER_SIZE) {
557
+            av_log(avctx, AV_LOG_ERROR, "TDSF tag is too small.\n");
558
+            return AVERROR_INVALIDDATA;
559
+        }
560
+        /* First 4 bytes here are the number of GEPJ/WAR tiles in this frame */
561
+        number_tiles = bytestream2_get_le32(&ctx->gbc);
562
+
563
+        bytestream2_skip(&ctx->gbc, 4); // internal timestamp maybe?
564
+        keyframe = bytestream2_get_le32(&ctx->gbc) == 0x30;
565
+
566
+        ret = tdsc_parse_tdsf(avctx, number_tiles);
567
+        if (ret < 0)
568
+            return ret;
569
+
570
+        /* Check if there is anything else we are able to parse */
571
+        if (bytestream2_get_bytes_left(&ctx->gbc) >= 4 + 4)
572
+            tag_header = bytestream2_get_le32(&ctx->gbc);
573
+    }
574
+
575
+    /* This tag can be after a TDSF block or on its own frame */
576
+    if (tag_header == MKTAG('D','T','S','M')) {
577
+        /* First 4 bytes here are the total size in bytes for this frame */
578
+        int tag_size = bytestream2_get_le32(&ctx->gbc);
579
+
580
+        if (bytestream2_get_bytes_left(&ctx->gbc) < tag_size) {
581
+            av_log(avctx, AV_LOG_ERROR, "DTSM tag is too small.\n");
582
+            return AVERROR_INVALIDDATA;
583
+        }
584
+
585
+        ret = tdsc_parse_dtsm(avctx);
586
+        if (ret < 0)
587
+            return ret;
588
+    }
589
+
590
+    /* Get the output frame and copy the reference frame */
591
+    ret = ff_get_buffer(avctx, frame, 0);
592
+    if (ret < 0)
593
+        return ret;
594
+
595
+    ret = av_frame_copy(frame, ctx->refframe);
596
+    if (ret < 0)
597
+        return ret;
598
+
599
+    /* Paint the cursor on the output frame */
600
+    tdsc_paint_cursor(avctx, frame->data[0], frame->linesize[0]);
601
+
602
+    /* Frame is ready to be output */
603
+    if (keyframe) {
604
+        frame->pict_type = AV_PICTURE_TYPE_I;
605
+        frame->key_frame = 1;
606
+    } else {
607
+        frame->pict_type = AV_PICTURE_TYPE_P;
608
+    }
609
+    *got_frame = 1;
610
+
611
+    return 0;
612
+}
613
+
614
+AVCodec ff_tdsc_decoder = {
615
+    .name           = "tdsc",
616
+    .long_name      = NULL_IF_CONFIG_SMALL("TDSC"),
617
+    .type           = AVMEDIA_TYPE_VIDEO,
618
+    .id             = AV_CODEC_ID_TDSC,
619
+    .init           = tdsc_init,
620
+    .decode         = tdsc_decode_frame,
621
+    .close          = tdsc_close,
622
+    .priv_data_size = sizeof(TDSCContext),
623
+    .capabilities   = CODEC_CAP_DR1,
624
+    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE |
625
+                      FF_CODEC_CAP_INIT_CLEANUP,
626
+};
... ...
@@ -29,7 +29,7 @@
29 29
 #include "libavutil/version.h"
30 30
 
31 31
 #define LIBAVCODEC_VERSION_MAJOR 56
32
-#define LIBAVCODEC_VERSION_MINOR  26
32
+#define LIBAVCODEC_VERSION_MINOR  27
33 33
 #define LIBAVCODEC_VERSION_MICRO 100
34 34
 
35 35
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -363,6 +363,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
363 363
     { AV_CODEC_ID_G2M,          MKTAG('G', '2', 'M', '5') },
364 364
     { AV_CODEC_ID_FIC,          MKTAG('F', 'I', 'C', 'V') },
365 365
     { AV_CODEC_ID_HQX,          MKTAG('C', 'H', 'Q', 'X') },
366
+    { AV_CODEC_ID_TDSC,         MKTAG('T', 'D', 'S', 'C') },
366 367
     { AV_CODEC_ID_NONE,         0 }
367 368
 };
368 369
 
... ...
@@ -256,6 +256,9 @@ fate-smc: CMD = framecrc -i $(TARGET_SAMPLES)/smc/cass_schi.qt -pix_fmt rgb24
256 256
 FATE_VIDEO-$(call DEMDEC, AVI, SP5X) += fate-sp5x
257 257
 fate-sp5x: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/sp5x/sp5x_problem.avi
258 258
 
259
+FATE_VIDEO-$(call DEMDEC, ASF, TDSC) += fate-tdsc
260
+fate-tdsc: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/tdsc/tdsc.asf -an -pix_fmt bgr24
261
+
259 262
 FATE_VIDEO-$(call DEMDEC, THP, THP) += fate-thp
260 263
 fate-thp: CMD = framecrc -idct simple -i $(TARGET_SAMPLES)/thp/pikmin2-opening1-partial.thp -an
261 264
 
262 265
new file mode 100644
... ...
@@ -0,0 +1,42 @@
0
+#tb 0: 1/30
1
+0,          0,          0,        1,  3888000, 0x9c498657
2
+0,          7,          7,        1,  3888000, 0x72a2ae22
3
+0,          8,          8,        1,  3888000, 0x72a2ae22
4
+0,         10,         10,        1,  3888000, 0x72a2ae22
5
+0,         16,         16,        1,  3888000, 0x72a2ae22
6
+0,         17,         17,        1,  3888000, 0x72a2ae22
7
+0,         20,         20,        1,  3888000, 0x550e417b
8
+0,         29,         29,        1,  3888000, 0x550e417b
9
+0,         30,         30,        1,  3888000, 0x550e417b
10
+0,         31,         31,        1,  3888000, 0x550e417b
11
+0,         32,         32,        1,  3888000, 0x550e417b
12
+0,         34,         34,        1,  3888000, 0x550e417b
13
+0,         35,         35,        1,  3888000, 0x38dcde13
14
+0,         47,         47,        1,  3888000, 0x2b7c0edd
15
+0,         48,         48,        1,  3888000, 0xaaaf3c7b
16
+0,         49,         49,        1,  3888000, 0x26d1710f
17
+0,         50,         50,        1,  3888000, 0xa6609f3f
18
+0,         51,         51,        1,  3888000, 0xaa41c6f3
19
+0,         52,         52,        1,  3888000, 0xc0ffd4d5
20
+0,         53,         53,        1,  3888000, 0x44d4f383
21
+0,         55,         55,        1,  3888000, 0x517047eb
22
+0,         56,         56,        1,  3888000, 0x1d5a4d5b
23
+0,         57,         57,        1,  3888000, 0x7d2da2f6
24
+0,         58,         58,        1,  3888000, 0x27f7a2f6
25
+0,         59,         59,        1,  3888000, 0x9de49edb
26
+0,         60,         60,        1,  3888000, 0x5ccb9f38
27
+0,         61,         61,        1,  3888000, 0x88069fb2
28
+0,         62,         62,        1,  3888000, 0x1d059fd3
29
+0,         63,         63,        1,  3888000, 0xe16d9fd3
30
+0,         64,         64,        1,  3888000, 0xb6a69fd3
31
+0,         65,         65,        1,  3888000, 0xb6a69fd3
32
+0,         66,         66,        1,  3888000, 0x61709fd3
33
+0,         67,         67,        1,  3888000, 0xb6f59fd3
34
+0,         68,         68,        1,  3888000, 0x5c7b9fd3
35
+0,         69,         69,        1,  3888000, 0x57869fd3
36
+0,         70,         70,        1,  3888000, 0x9d3f9fd3
37
+0,         73,         73,        1,  3888000, 0x5e6082a5
38
+0,         74,         74,        1,  3888000, 0x5e6082a5
39
+0,         75,         75,        1,  3888000, 0x5e6082a5
40
+0,         76,         76,        1,  3888000, 0x48ce82f3
41
+0,         77,         77,        1,  3888000, 0x4c5ebeaf