~ubuntu-branches/ubuntu/vivid/ffmpeg/vivid

« back to all changes in this revision

Viewing changes to libavcodec/dxtory.c

  • Committer: Package Import Robot
  • Author(s): Andreas Cadhalpun
  • Date: 2014-11-05 01:18:23 UTC
  • mfrom: (0.2.17 sid)
  • Revision ID: package-import@ubuntu.com-20141105011823-xsbeceffs43wtkn7
Tags: 7:2.4.3-1
* Import new upstream bugfix release 2.4.3.
   - Refresh Change-symbol-versioning.patch.
   - Add new symbols to the libavdevice symbols file.
* Enable libbs2b on arm64, since it is now available.
* Disable frei0r and libx264 on x32, libsoxr and openal on sparc64
  and libopencv on m68k, sh4, sparc64 and x32, because they are not
  (yet) avialable there.
* Disable assembler optimizations on x32, as they wouldn't work there.
* Include config.log in the build-log, when compiling fails.
* Add fix-hppa-tests.patch to work around a gcc bug on hppa.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Dxtory decoder
 
3
 *
 
4
 * Copyright (c) 2011 Konstantin Shishkov
 
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
#include <inttypes.h>
 
24
 
 
25
#define BITSTREAM_READER_LE
 
26
#include "avcodec.h"
 
27
#include "bytestream.h"
 
28
#include "get_bits.h"
 
29
#include "internal.h"
 
30
#include "unary.h"
 
31
#include "libavutil/common.h"
 
32
#include "libavutil/intreadwrite.h"
 
33
 
 
34
static int dxtory_decode_v1_rgb(AVCodecContext *avctx, AVFrame *pic,
 
35
                                const uint8_t *src, int src_size,
 
36
                                int id, int bpp)
 
37
{
 
38
    int h;
 
39
    uint8_t *dst;
 
40
    int ret;
 
41
 
 
42
    if (src_size < avctx->width * avctx->height * (int64_t)bpp) {
 
43
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
 
44
        return AVERROR_INVALIDDATA;
 
45
    }
 
46
 
 
47
    avctx->pix_fmt = id;
 
48
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
49
        return ret;
 
50
 
 
51
    dst = pic->data[0];
 
52
    for (h = 0; h < avctx->height; h++) {
 
53
        memcpy(dst, src, avctx->width * bpp);
 
54
        src += avctx->width * bpp;
 
55
        dst += pic->linesize[0];
 
56
    }
 
57
 
 
58
    return 0;
 
59
}
 
60
 
 
61
static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic,
 
62
                                const uint8_t *src, int src_size)
 
63
{
 
64
    int h, w;
 
65
    uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V;
 
66
    int ret;
 
67
 
 
68
    if (src_size < avctx->width * avctx->height * 9L / 8) {
 
69
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
 
70
        return AVERROR_INVALIDDATA;
 
71
    }
 
72
 
 
73
    avctx->pix_fmt = AV_PIX_FMT_YUV410P;
 
74
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
75
        return ret;
 
76
 
 
77
    Y1 = pic->data[0];
 
78
    Y2 = pic->data[0] + pic->linesize[0];
 
79
    Y3 = pic->data[0] + pic->linesize[0] * 2;
 
80
    Y4 = pic->data[0] + pic->linesize[0] * 3;
 
81
    U  = pic->data[1];
 
82
    V  = pic->data[2];
 
83
    for (h = 0; h < avctx->height; h += 4) {
 
84
        for (w = 0; w < avctx->width; w += 4) {
 
85
            AV_COPY32(Y1 + w, src);
 
86
            AV_COPY32(Y2 + w, src + 4);
 
87
            AV_COPY32(Y3 + w, src + 8);
 
88
            AV_COPY32(Y4 + w, src + 12);
 
89
            U[w >> 2] = src[16] + 0x80;
 
90
            V[w >> 2] = src[17] + 0x80;
 
91
            src += 18;
 
92
        }
 
93
        Y1 += pic->linesize[0] << 2;
 
94
        Y2 += pic->linesize[0] << 2;
 
95
        Y3 += pic->linesize[0] << 2;
 
96
        Y4 += pic->linesize[0] << 2;
 
97
        U  += pic->linesize[1];
 
98
        V  += pic->linesize[2];
 
99
    }
 
100
 
 
101
    return 0;
 
102
}
 
103
 
 
104
static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic,
 
105
                                const uint8_t *src, int src_size)
 
106
{
 
107
    int h, w;
 
108
    uint8_t *Y1, *Y2, *U, *V;
 
109
    int ret;
 
110
 
 
111
    if (src_size < avctx->width * avctx->height * 3L / 2) {
 
112
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
 
113
        return AVERROR_INVALIDDATA;
 
114
    }
 
115
 
 
116
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
117
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
118
        return ret;
 
119
 
 
120
    Y1 = pic->data[0];
 
121
    Y2 = pic->data[0] + pic->linesize[0];
 
122
    U  = pic->data[1];
 
123
    V  = pic->data[2];
 
124
    for (h = 0; h < avctx->height; h += 2) {
 
125
        for (w = 0; w < avctx->width; w += 2) {
 
126
            AV_COPY16(Y1 + w, src);
 
127
            AV_COPY16(Y2 + w, src + 2);
 
128
            U[w >> 1] = src[4] + 0x80;
 
129
            V[w >> 1] = src[5] + 0x80;
 
130
            src += 6;
 
131
        }
 
132
        Y1 += pic->linesize[0] << 1;
 
133
        Y2 += pic->linesize[0] << 1;
 
134
        U  += pic->linesize[1];
 
135
        V  += pic->linesize[2];
 
136
    }
 
137
 
 
138
    return 0;
 
139
}
 
140
 
 
141
static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic,
 
142
                                const uint8_t *src, int src_size)
 
143
{
 
144
    int h, w;
 
145
    uint8_t *Y, *U, *V;
 
146
    int ret;
 
147
 
 
148
    if (src_size < avctx->width * avctx->height * 3L) {
 
149
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
 
150
        return AVERROR_INVALIDDATA;
 
151
    }
 
152
 
 
153
    avctx->pix_fmt = AV_PIX_FMT_YUV444P;
 
154
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
155
        return ret;
 
156
 
 
157
    Y = pic->data[0];
 
158
    U = pic->data[1];
 
159
    V = pic->data[2];
 
160
    for (h = 0; h < avctx->height; h++) {
 
161
        for (w = 0; w < avctx->width; w++) {
 
162
            Y[w] = *src++;
 
163
            U[w] = *src++ ^ 0x80;
 
164
            V[w] = *src++ ^ 0x80;
 
165
        }
 
166
        Y += pic->linesize[0];
 
167
        U += pic->linesize[1];
 
168
        V += pic->linesize[2];
 
169
    }
 
170
 
 
171
    return 0;
 
172
}
 
173
 
 
174
static const uint8_t def_lru[8] = { 0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xFF };
 
175
static const uint8_t def_lru_555[8] = { 0x00, 0x08, 0x10, 0x18, 0x1F };
 
176
static const uint8_t def_lru_565[8] = { 0x00, 0x08, 0x10, 0x20, 0x30, 0x3F };
 
177
 
 
178
static inline uint8_t decode_sym(GetBitContext *gb, uint8_t lru[8])
 
179
{
 
180
    uint8_t c, val;
 
181
 
 
182
    c = get_unary(gb, 0, 8);
 
183
    if (!c) {
 
184
        val = get_bits(gb, 8);
 
185
        memmove(lru + 1, lru, sizeof(*lru) * (8 - 1));
 
186
    } else {
 
187
        val = lru[c - 1];
 
188
        memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
 
189
    }
 
190
    lru[0] = val;
 
191
 
 
192
    return val;
 
193
}
 
194
 
 
195
static inline uint8_t decode_sym_565(GetBitContext *gb, uint8_t lru[8],
 
196
                                     int bits)
 
197
{
 
198
    uint8_t c, val;
 
199
 
 
200
    c = get_unary(gb, 0, bits);
 
201
    if (!c) {
 
202
        val = get_bits(gb, bits);
 
203
        memmove(lru + 1, lru, sizeof(*lru) * (6 - 1));
 
204
    } else {
 
205
        val = lru[c - 1];
 
206
        memmove(lru + 1, lru, sizeof(*lru) * (c - 1));
 
207
    }
 
208
    lru[0] = val;
 
209
 
 
210
    return val;
 
211
}
 
212
 
 
213
static int dx2_decode_slice_565(GetBitContext *gb, int width, int height,
 
214
                                uint8_t *dst, int stride, int is_565)
 
215
{
 
216
    int x, y;
 
217
    int r, g, b;
 
218
    uint8_t lru[3][8];
 
219
 
 
220
    memcpy(lru[0], def_lru_555, 8 * sizeof(*def_lru));
 
221
    memcpy(lru[1], is_565 ? def_lru_565 : def_lru_555, 8 * sizeof(*def_lru));
 
222
    memcpy(lru[2], def_lru_555, 8 * sizeof(*def_lru));
 
223
 
 
224
    for (y = 0; y < height; y++) {
 
225
        for (x = 0; x < width; x++) {
 
226
            b = decode_sym_565(gb, lru[0], 5);
 
227
            g = decode_sym_565(gb, lru[1], is_565 ? 6 : 5);
 
228
            r = decode_sym_565(gb, lru[2], 5);
 
229
            dst[x * 3 + 0] = (r << 3) | (r >> 2);
 
230
            dst[x * 3 + 1] = is_565 ? (g << 2) | (g >> 4) : (g << 3) | (g >> 2);
 
231
            dst[x * 3 + 2] = (b << 3) | (b >> 2);
 
232
        }
 
233
 
 
234
        dst += stride;
 
235
    }
 
236
 
 
237
    return 0;
 
238
}
 
239
 
 
240
static int dxtory_decode_v2_565(AVCodecContext *avctx, AVFrame *pic,
 
241
                                const uint8_t *src, int src_size, int is_565)
 
242
{
 
243
    GetByteContext gb;
 
244
    GetBitContext  gb2;
 
245
    int nslices, slice, slice_height;
 
246
    uint32_t off, slice_size;
 
247
    uint8_t *dst;
 
248
    int ret;
 
249
 
 
250
    bytestream2_init(&gb, src, src_size);
 
251
    nslices = bytestream2_get_le16(&gb);
 
252
    off = FFALIGN(nslices * 4 + 2, 16);
 
253
    if (src_size < off) {
 
254
        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
 
255
        return AVERROR_INVALIDDATA;
 
256
    }
 
257
 
 
258
    if (!nslices || avctx->height % nslices) {
 
259
        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
 
260
                              avctx->width, avctx->height);
 
261
        return AVERROR_PATCHWELCOME;
 
262
    }
 
263
 
 
264
    slice_height = avctx->height / nslices;
 
265
    avctx->pix_fmt = AV_PIX_FMT_RGB24;
 
266
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
267
        return ret;
 
268
 
 
269
    dst = pic->data[0];
 
270
    for (slice = 0; slice < nslices; slice++) {
 
271
        slice_size = bytestream2_get_le32(&gb);
 
272
        if (slice_size > src_size - off) {
 
273
            av_log(avctx, AV_LOG_ERROR,
 
274
                   "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
 
275
                   slice_size, src_size - off);
 
276
            return AVERROR_INVALIDDATA;
 
277
        }
 
278
        if (slice_size <= 16) {
 
279
            av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
 
280
            return AVERROR_INVALIDDATA;
 
281
        }
 
282
 
 
283
        if (AV_RL32(src + off) != slice_size - 16) {
 
284
            av_log(avctx, AV_LOG_ERROR,
 
285
                   "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
 
286
                   AV_RL32(src + off), slice_size - 16);
 
287
        }
 
288
        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
 
289
        dx2_decode_slice_565(&gb2, avctx->width, slice_height, dst,
 
290
                             pic->linesize[0], is_565);
 
291
 
 
292
        dst += pic->linesize[0] * slice_height;
 
293
        off += slice_size;
 
294
    }
 
295
 
 
296
    return 0;
 
297
}
 
298
 
 
299
static int dx2_decode_slice_rgb(GetBitContext *gb, int width, int height,
 
300
                                uint8_t *dst, int stride)
 
301
{
 
302
    int x, y, i;
 
303
    uint8_t lru[3][8];
 
304
 
 
305
    for (i = 0; i < 3; i++)
 
306
        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
 
307
 
 
308
    for (y = 0; y < height; y++) {
 
309
        for (x = 0; x < width; x++) {
 
310
            dst[x * 3 + 0] = decode_sym(gb, lru[0]);
 
311
            dst[x * 3 + 1] = decode_sym(gb, lru[1]);
 
312
            dst[x * 3 + 2] = decode_sym(gb, lru[2]);
 
313
        }
 
314
 
 
315
        dst += stride;
 
316
    }
 
317
 
 
318
    return 0;
 
319
}
 
320
 
 
321
static int dxtory_decode_v2_rgb(AVCodecContext *avctx, AVFrame *pic,
 
322
                                const uint8_t *src, int src_size)
 
323
{
 
324
    GetByteContext gb;
 
325
    GetBitContext  gb2;
 
326
    int nslices, slice, slice_height;
 
327
    uint32_t off, slice_size;
 
328
    uint8_t *dst;
 
329
    int ret;
 
330
 
 
331
    bytestream2_init(&gb, src, src_size);
 
332
    nslices = bytestream2_get_le16(&gb);
 
333
    off = FFALIGN(nslices * 4 + 2, 16);
 
334
    if (src_size < off) {
 
335
        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
 
336
        return AVERROR_INVALIDDATA;
 
337
    }
 
338
 
 
339
    if (!nslices || avctx->height % nslices) {
 
340
        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
 
341
                              avctx->width, avctx->height);
 
342
        return AVERROR_PATCHWELCOME;
 
343
    }
 
344
 
 
345
    slice_height = avctx->height / nslices;
 
346
    avctx->pix_fmt = AV_PIX_FMT_BGR24;
 
347
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
348
        return ret;
 
349
 
 
350
    dst = pic->data[0];
 
351
    for (slice = 0; slice < nslices; slice++) {
 
352
        slice_size = bytestream2_get_le32(&gb);
 
353
        if (slice_size > src_size - off) {
 
354
            av_log(avctx, AV_LOG_ERROR,
 
355
                   "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
 
356
                   slice_size, src_size - off);
 
357
            return AVERROR_INVALIDDATA;
 
358
        }
 
359
        if (slice_size <= 16) {
 
360
            av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n",
 
361
                   slice_size);
 
362
            return AVERROR_INVALIDDATA;
 
363
        }
 
364
 
 
365
        if (AV_RL32(src + off) != slice_size - 16) {
 
366
            av_log(avctx, AV_LOG_ERROR,
 
367
                   "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
 
368
                   AV_RL32(src + off), slice_size - 16);
 
369
        }
 
370
        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
 
371
        dx2_decode_slice_rgb(&gb2, avctx->width, slice_height, dst,
 
372
                             pic->linesize[0]);
 
373
 
 
374
        dst += pic->linesize[0] * slice_height;
 
375
        off += slice_size;
 
376
    }
 
377
 
 
378
    return 0;
 
379
}
 
380
 
 
381
static int dx2_decode_slice_410(GetBitContext *gb, int width, int height,
 
382
                                uint8_t *Y, uint8_t *U, uint8_t *V,
 
383
                                int ystride, int ustride, int vstride)
 
384
{
 
385
    int x, y, i, j;
 
386
    uint8_t lru[3][8];
 
387
 
 
388
    for (i = 0; i < 3; i++)
 
389
        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
 
390
 
 
391
    for (y = 0; y < height; y += 4) {
 
392
        for (x = 0; x < width; x += 4) {
 
393
            for (j = 0; j < 4; j++)
 
394
                for (i = 0; i < 4; i++)
 
395
                    Y[x + i + j * ystride] = decode_sym(gb, lru[0]);
 
396
            U[x >> 2] = decode_sym(gb, lru[1]) ^ 0x80;
 
397
            V[x >> 2] = decode_sym(gb, lru[2]) ^ 0x80;
 
398
        }
 
399
 
 
400
        Y += ystride << 2;
 
401
        U += ustride;
 
402
        V += vstride;
 
403
    }
 
404
 
 
405
    return 0;
 
406
}
 
407
 
 
408
static int dxtory_decode_v2_410(AVCodecContext *avctx, AVFrame *pic,
 
409
                                const uint8_t *src, int src_size)
 
410
{
 
411
    GetByteContext gb;
 
412
    GetBitContext  gb2;
 
413
    int nslices, slice, slice_height, ref_slice_height;
 
414
    int cur_y, next_y;
 
415
    uint32_t off, slice_size;
 
416
    uint8_t *Y, *U, *V;
 
417
    int ret;
 
418
 
 
419
    bytestream2_init(&gb, src, src_size);
 
420
    nslices = bytestream2_get_le16(&gb);
 
421
    off = FFALIGN(nslices * 4 + 2, 16);
 
422
    if (src_size < off) {
 
423
        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
 
424
        return AVERROR_INVALIDDATA;
 
425
    }
 
426
 
 
427
    if (!nslices || avctx->height % nslices) {
 
428
        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
 
429
                              avctx->width, avctx->height);
 
430
        return AVERROR_PATCHWELCOME;
 
431
    }
 
432
 
 
433
    ref_slice_height = avctx->height / nslices;
 
434
    if ((avctx->width & 3) || (avctx->height & 3)) {
 
435
        avpriv_request_sample(avctx, "Frame dimensions %dx%d",
 
436
                              avctx->width, avctx->height);
 
437
    }
 
438
 
 
439
    avctx->pix_fmt = AV_PIX_FMT_YUV410P;
 
440
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
441
        return ret;
 
442
 
 
443
    Y = pic->data[0];
 
444
    U = pic->data[1];
 
445
    V = pic->data[2];
 
446
 
 
447
    cur_y  = 0;
 
448
    next_y = ref_slice_height;
 
449
    for (slice = 0; slice < nslices; slice++) {
 
450
        slice_size   = bytestream2_get_le32(&gb);
 
451
        slice_height = (next_y & ~3) - (cur_y & ~3);
 
452
        if (slice_size > src_size - off) {
 
453
            av_log(avctx, AV_LOG_ERROR,
 
454
                   "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
 
455
                   slice_size, src_size - off);
 
456
            return AVERROR_INVALIDDATA;
 
457
        }
 
458
        if (slice_size <= 16) {
 
459
            av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
 
460
            return AVERROR_INVALIDDATA;
 
461
        }
 
462
 
 
463
        if (AV_RL32(src + off) != slice_size - 16) {
 
464
            av_log(avctx, AV_LOG_ERROR,
 
465
                   "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
 
466
                   AV_RL32(src + off), slice_size - 16);
 
467
        }
 
468
        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
 
469
        dx2_decode_slice_410(&gb2, avctx->width, slice_height, Y, U, V,
 
470
                             pic->linesize[0], pic->linesize[1],
 
471
                             pic->linesize[2]);
 
472
 
 
473
        Y += pic->linesize[0] *  slice_height;
 
474
        U += pic->linesize[1] * (slice_height >> 2);
 
475
        V += pic->linesize[2] * (slice_height >> 2);
 
476
        off += slice_size;
 
477
        cur_y   = next_y;
 
478
        next_y += ref_slice_height;
 
479
    }
 
480
 
 
481
    return 0;
 
482
}
 
483
 
 
484
static int dx2_decode_slice_420(GetBitContext *gb, int width, int height,
 
485
                                uint8_t *Y, uint8_t *U, uint8_t *V,
 
486
                                int ystride, int ustride, int vstride)
 
487
{
 
488
    int x, y, i;
 
489
    uint8_t lru[3][8];
 
490
 
 
491
    for (i = 0; i < 3; i++)
 
492
        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
 
493
 
 
494
    for (y = 0; y < height; y+=2) {
 
495
        for (x = 0; x < width; x += 2) {
 
496
            Y[x + 0 + 0 * ystride] = decode_sym(gb, lru[0]);
 
497
            Y[x + 1 + 0 * ystride] = decode_sym(gb, lru[0]);
 
498
            Y[x + 0 + 1 * ystride] = decode_sym(gb, lru[0]);
 
499
            Y[x + 1 + 1 * ystride] = decode_sym(gb, lru[0]);
 
500
            U[x >> 1] = decode_sym(gb, lru[1]) ^ 0x80;
 
501
            V[x >> 1] = decode_sym(gb, lru[2]) ^ 0x80;
 
502
        }
 
503
 
 
504
        Y += ystride << 1;
 
505
        U += ustride;
 
506
        V += vstride;
 
507
    }
 
508
 
 
509
    return 0;
 
510
}
 
511
 
 
512
static int dxtory_decode_v2_420(AVCodecContext *avctx, AVFrame *pic,
 
513
                                const uint8_t *src, int src_size)
 
514
{
 
515
    GetByteContext gb;
 
516
    GetBitContext  gb2;
 
517
    int nslices, slice, slice_height, ref_slice_height;
 
518
    int cur_y, next_y;
 
519
    uint32_t off, slice_size;
 
520
    uint8_t *Y, *U, *V;
 
521
    int ret;
 
522
 
 
523
    bytestream2_init(&gb, src, src_size);
 
524
    nslices = bytestream2_get_le16(&gb);
 
525
    off = FFALIGN(nslices * 4 + 2, 16);
 
526
    if (src_size < off) {
 
527
        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
 
528
        return AVERROR_INVALIDDATA;
 
529
    }
 
530
 
 
531
    if (!nslices || avctx->height % nslices) {
 
532
        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
 
533
                              avctx->width, avctx->height);
 
534
        return AVERROR_PATCHWELCOME;
 
535
    }
 
536
 
 
537
    ref_slice_height = avctx->height / nslices;
 
538
    if ((avctx->width & 1) || (avctx->height & 1)) {
 
539
        avpriv_request_sample(avctx, "Frame dimensions %dx%d",
 
540
                              avctx->width, avctx->height);
 
541
    }
 
542
 
 
543
    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 
544
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
545
        return ret;
 
546
 
 
547
    Y = pic->data[0];
 
548
    U = pic->data[1];
 
549
    V = pic->data[2];
 
550
 
 
551
    cur_y  = 0;
 
552
    next_y = ref_slice_height;
 
553
    for (slice = 0; slice < nslices; slice++) {
 
554
        slice_size   = bytestream2_get_le32(&gb);
 
555
        slice_height = (next_y & ~1) - (cur_y & ~1);
 
556
        if (slice_size > src_size - off) {
 
557
            av_log(avctx, AV_LOG_ERROR,
 
558
                   "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
 
559
                   slice_size, src_size - off);
 
560
            return AVERROR_INVALIDDATA;
 
561
        }
 
562
        if (slice_size <= 16) {
 
563
            av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
 
564
            return AVERROR_INVALIDDATA;
 
565
        }
 
566
 
 
567
        if (AV_RL32(src + off) != slice_size - 16) {
 
568
            av_log(avctx, AV_LOG_ERROR,
 
569
                   "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
 
570
                   AV_RL32(src + off), slice_size - 16);
 
571
        }
 
572
        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
 
573
        dx2_decode_slice_420(&gb2, avctx->width, slice_height, Y, U, V,
 
574
                             pic->linesize[0], pic->linesize[1],
 
575
                             pic->linesize[2]);
 
576
 
 
577
        Y += pic->linesize[0] *  slice_height;
 
578
        U += pic->linesize[1] * (slice_height >> 1);
 
579
        V += pic->linesize[2] * (slice_height >> 1);
 
580
        off += slice_size;
 
581
        cur_y   = next_y;
 
582
        next_y += ref_slice_height;
 
583
    }
 
584
 
 
585
    return 0;
 
586
}
 
587
 
 
588
static int dx2_decode_slice_444(GetBitContext *gb, int width, int height,
 
589
                                uint8_t *Y, uint8_t *U, uint8_t *V,
 
590
                                int ystride, int ustride, int vstride)
 
591
{
 
592
    int x, y, i;
 
593
    uint8_t lru[3][8];
 
594
 
 
595
    for (i = 0; i < 3; i++)
 
596
        memcpy(lru[i], def_lru, 8 * sizeof(*def_lru));
 
597
 
 
598
    for (y = 0; y < height; y++) {
 
599
        for (x = 0; x < width; x++) {
 
600
            Y[x] = decode_sym(gb, lru[0]);
 
601
            U[x] = decode_sym(gb, lru[1]) ^ 0x80;
 
602
            V[x] = decode_sym(gb, lru[2]) ^ 0x80;
 
603
        }
 
604
 
 
605
        Y += ystride;
 
606
        U += ustride;
 
607
        V += vstride;
 
608
    }
 
609
 
 
610
    return 0;
 
611
}
 
612
 
 
613
static int dxtory_decode_v2_444(AVCodecContext *avctx, AVFrame *pic,
 
614
                                const uint8_t *src, int src_size)
 
615
{
 
616
    GetByteContext gb;
 
617
    GetBitContext  gb2;
 
618
    int nslices, slice, slice_height;
 
619
    uint32_t off, slice_size;
 
620
    uint8_t *Y, *U, *V;
 
621
    int ret;
 
622
 
 
623
    bytestream2_init(&gb, src, src_size);
 
624
    nslices = bytestream2_get_le16(&gb);
 
625
    off = FFALIGN(nslices * 4 + 2, 16);
 
626
    if (src_size < off) {
 
627
        av_log(avctx, AV_LOG_ERROR, "no slice data\n");
 
628
        return AVERROR_INVALIDDATA;
 
629
    }
 
630
 
 
631
    if (!nslices || avctx->height % nslices) {
 
632
        avpriv_request_sample(avctx, "%d slices for %dx%d", nslices,
 
633
                              avctx->width, avctx->height);
 
634
        return AVERROR_PATCHWELCOME;
 
635
    }
 
636
 
 
637
    slice_height = avctx->height / nslices;
 
638
 
 
639
    avctx->pix_fmt = AV_PIX_FMT_YUV444P;
 
640
    if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
 
641
        return ret;
 
642
 
 
643
    Y = pic->data[0];
 
644
    U = pic->data[1];
 
645
    V = pic->data[2];
 
646
 
 
647
    for (slice = 0; slice < nslices; slice++) {
 
648
        slice_size = bytestream2_get_le32(&gb);
 
649
        if (slice_size > src_size - off) {
 
650
            av_log(avctx, AV_LOG_ERROR,
 
651
                   "invalid slice size %"PRIu32" (only %"PRIu32" bytes left)\n",
 
652
                   slice_size, src_size - off);
 
653
            return AVERROR_INVALIDDATA;
 
654
        }
 
655
        if (slice_size <= 16) {
 
656
            av_log(avctx, AV_LOG_ERROR, "invalid slice size %"PRIu32"\n", slice_size);
 
657
            return AVERROR_INVALIDDATA;
 
658
        }
 
659
 
 
660
        if (AV_RL32(src + off) != slice_size - 16) {
 
661
            av_log(avctx, AV_LOG_ERROR,
 
662
                   "Slice sizes mismatch: got %"PRIu32" instead of %"PRIu32"\n",
 
663
                   AV_RL32(src + off), slice_size - 16);
 
664
        }
 
665
        init_get_bits(&gb2, src + off + 16, (slice_size - 16) * 8);
 
666
        dx2_decode_slice_444(&gb2, avctx->width, slice_height, Y, U, V,
 
667
                             pic->linesize[0], pic->linesize[1],
 
668
                             pic->linesize[2]);
 
669
 
 
670
        Y += pic->linesize[0] * slice_height;
 
671
        U += pic->linesize[1] * slice_height;
 
672
        V += pic->linesize[2] * slice_height;
 
673
        off += slice_size;
 
674
    }
 
675
 
 
676
    return 0;
 
677
}
 
678
 
 
679
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
 
680
                        AVPacket *avpkt)
 
681
{
 
682
    AVFrame *pic = data;
 
683
    const uint8_t *src = avpkt->data;
 
684
    int ret;
 
685
 
 
686
    if (avpkt->size < 16) {
 
687
        av_log(avctx, AV_LOG_ERROR, "packet too small\n");
 
688
        return AVERROR_INVALIDDATA;
 
689
    }
 
690
 
 
691
    switch (AV_RB32(src)) {
 
692
    case 0x01000001:
 
693
        ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
 
694
                                   AV_PIX_FMT_BGR24, 3);
 
695
        break;
 
696
    case 0x01000009:
 
697
        ret = dxtory_decode_v2_rgb(avctx, pic, src + 16, avpkt->size - 16);
 
698
        break;
 
699
    case 0x02000001:
 
700
        ret = dxtory_decode_v1_420(avctx, pic, src + 16, avpkt->size - 16);
 
701
        break;
 
702
    case 0x02000009:
 
703
        ret = dxtory_decode_v2_420(avctx, pic, src + 16, avpkt->size - 16);
 
704
        break;
 
705
    case 0x03000001:
 
706
        ret = dxtory_decode_v1_410(avctx, pic, src + 16, avpkt->size - 16);
 
707
        break;
 
708
    case 0x03000009:
 
709
        ret = dxtory_decode_v2_410(avctx, pic, src + 16, avpkt->size - 16);
 
710
        break;
 
711
    case 0x04000001:
 
712
        ret = dxtory_decode_v1_444(avctx, pic, src + 16, avpkt->size - 16);
 
713
        break;
 
714
    case 0x04000009:
 
715
        ret = dxtory_decode_v2_444(avctx, pic, src + 16, avpkt->size - 16);
 
716
        break;
 
717
    case 0x17000001:
 
718
        ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
 
719
                                   AV_PIX_FMT_RGB565LE, 2);
 
720
        break;
 
721
    case 0x17000009:
 
722
        ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 1);
 
723
        break;
 
724
    case 0x18000001:
 
725
    case 0x19000001:
 
726
        ret = dxtory_decode_v1_rgb(avctx, pic, src + 16, avpkt->size - 16,
 
727
                                   AV_PIX_FMT_RGB555LE, 2);
 
728
        break;
 
729
    case 0x18000009:
 
730
    case 0x19000009:
 
731
        ret = dxtory_decode_v2_565(avctx, pic, src + 16, avpkt->size - 16, 0);
 
732
        break;
 
733
    default:
 
734
        avpriv_request_sample(avctx, "Frame header %"PRIX32, AV_RB32(src));
 
735
        return AVERROR_PATCHWELCOME;
 
736
    }
 
737
 
 
738
    if (ret)
 
739
        return ret;
 
740
 
 
741
    pic->pict_type = AV_PICTURE_TYPE_I;
 
742
    pic->key_frame = 1;
 
743
    *got_frame = 1;
 
744
 
 
745
    return avpkt->size;
 
746
}
 
747
 
 
748
AVCodec ff_dxtory_decoder = {
 
749
    .name           = "dxtory",
 
750
    .long_name      = NULL_IF_CONFIG_SMALL("Dxtory"),
 
751
    .type           = AVMEDIA_TYPE_VIDEO,
 
752
    .id             = AV_CODEC_ID_DXTORY,
 
753
    .decode         = decode_frame,
 
754
    .capabilities   = CODEC_CAP_DR1,
 
755
};