~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/zmbv.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Zip Motion Blocks Video (ZMBV) decoder
 
3
 * Copyright (c) 2006 Konstantin Shishkov
 
4
 *
 
5
 * This file is part of FFmpeg.
 
6
 *
 
7
 * FFmpeg is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * FFmpeg is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with FFmpeg; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
20
 *
 
21
 */
 
22
 
 
23
/**
 
24
 * @file zmbv.c
 
25
 * Zip Motion Blocks Video decoder
 
26
 */
 
27
 
 
28
#include <stdio.h>
 
29
#include <stdlib.h>
 
30
 
 
31
#include "common.h"
 
32
#include "avcodec.h"
 
33
 
 
34
#ifdef CONFIG_ZLIB
 
35
#include <zlib.h>
 
36
#endif
 
37
 
 
38
#define ZMBV_KEYFRAME 1
 
39
#define ZMBV_DELTAPAL 2
 
40
 
 
41
enum ZmbvFormat {
 
42
    ZMBV_FMT_NONE  = 0,
 
43
    ZMBV_FMT_1BPP  = 1,
 
44
    ZMBV_FMT_2BPP  = 2,
 
45
    ZMBV_FMT_4BPP  = 3,
 
46
    ZMBV_FMT_8BPP  = 4,
 
47
    ZMBV_FMT_15BPP = 5,
 
48
    ZMBV_FMT_16BPP = 6,
 
49
    ZMBV_FMT_24BPP = 7,
 
50
    ZMBV_FMT_32BPP = 8
 
51
};
 
52
 
 
53
/*
 
54
 * Decoder context
 
55
 */
 
56
typedef struct ZmbvContext {
 
57
    AVCodecContext *avctx;
 
58
    AVFrame pic;
 
59
 
 
60
    int bpp;
 
61
    unsigned int decomp_size;
 
62
    uint8_t* decomp_buf;
 
63
    uint8_t pal[768];
 
64
    uint8_t *prev, *cur;
 
65
    int width, height;
 
66
    int fmt;
 
67
    int comp;
 
68
    int flags;
 
69
    int bw, bh, bx, by;
 
70
    int decomp_len;
 
71
#ifdef CONFIG_ZLIB
 
72
    z_stream zstream;
 
73
#endif
 
74
    int (*decode_intra)(struct ZmbvContext *c);
 
75
    int (*decode_xor)(struct ZmbvContext *c);
 
76
} ZmbvContext;
 
77
 
 
78
/**
 
79
 * Decode XOR'ed frame - 8bpp version
 
80
 */
 
81
 
 
82
static int zmbv_decode_xor_8(ZmbvContext *c)
 
83
{
 
84
    uint8_t *src = c->decomp_buf;
 
85
    uint8_t *output, *prev;
 
86
    int8_t *mvec;
 
87
    int x, y;
 
88
    int d, dx, dy, bw2, bh2;
 
89
    int block;
 
90
    int i, j;
 
91
    int mx, my;
 
92
 
 
93
    output = c->cur;
 
94
    prev = c->prev;
 
95
 
 
96
    if(c->flags & ZMBV_DELTAPAL){
 
97
        for(i = 0; i < 768; i++)
 
98
            c->pal[i] ^= *src++;
 
99
    }
 
100
 
 
101
    mvec = (int8_t*)src;
 
102
    src += ((c->bx * c->by * 2 + 3) & ~3);
 
103
 
 
104
    block = 0;
 
105
    for(y = 0; y < c->height; y += c->bh) {
 
106
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
 
107
        for(x = 0; x < c->width; x += c->bw) {
 
108
            uint8_t *out, *tprev;
 
109
 
 
110
            d = mvec[block] & 1;
 
111
            dx = mvec[block] >> 1;
 
112
            dy = mvec[block + 1] >> 1;
 
113
            block += 2;
 
114
 
 
115
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
 
116
 
 
117
            /* copy block - motion vectors out of bounds are used to zero blocks */
 
118
            out = output + x;
 
119
            tprev = prev + x + dx + dy * c->width;
 
120
            mx = x + dx;
 
121
            my = y + dy;
 
122
            for(j = 0; j < bh2; j++){
 
123
                if((my + j < 0) || (my + j >= c->height)) {
 
124
                    memset(out, 0, bw2);
 
125
                } else {
 
126
                    for(i = 0; i < bw2; i++){
 
127
                        if((mx + i < 0) || (mx + i >= c->width))
 
128
                            out[i] = 0;
 
129
                        else
 
130
                            out[i] = tprev[i];
 
131
                    }
 
132
                }
 
133
                out += c->width;
 
134
                tprev += c->width;
 
135
            }
 
136
 
 
137
            if(d) { /* apply XOR'ed difference */
 
138
                out = output + x;
 
139
                for(j = 0; j < bh2; j++){
 
140
                    for(i = 0; i < bw2; i++)
 
141
                        out[i] ^= *src++;
 
142
                    out += c->width;
 
143
                }
 
144
            }
 
145
        }
 
146
        output += c->width * c->bh;
 
147
        prev += c->width * c->bh;
 
148
    }
 
149
    if(src - c->decomp_buf != c->decomp_len)
 
150
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
 
151
    return 0;
 
152
}
 
153
 
 
154
/**
 
155
 * Decode XOR'ed frame - 15bpp and 16bpp version
 
156
 */
 
157
 
 
158
static int zmbv_decode_xor_16(ZmbvContext *c)
 
159
{
 
160
    uint8_t *src = c->decomp_buf;
 
161
    uint16_t *output, *prev;
 
162
    int8_t *mvec;
 
163
    int x, y;
 
164
    int d, dx, dy, bw2, bh2;
 
165
    int block;
 
166
    int i, j;
 
167
    int mx, my;
 
168
 
 
169
    output = (uint16_t*)c->cur;
 
170
    prev = (uint16_t*)c->prev;
 
171
 
 
172
    mvec = (int8_t*)src;
 
173
    src += ((c->bx * c->by * 2 + 3) & ~3);
 
174
 
 
175
    block = 0;
 
176
    for(y = 0; y < c->height; y += c->bh) {
 
177
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
 
178
        for(x = 0; x < c->width; x += c->bw) {
 
179
            uint16_t *out, *tprev;
 
180
 
 
181
            d = mvec[block] & 1;
 
182
            dx = mvec[block] >> 1;
 
183
            dy = mvec[block + 1] >> 1;
 
184
            block += 2;
 
185
 
 
186
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
 
187
 
 
188
            /* copy block - motion vectors out of bounds are used to zero blocks */
 
189
            out = output + x;
 
190
            tprev = prev + x + dx + dy * c->width;
 
191
            mx = x + dx;
 
192
            my = y + dy;
 
193
            for(j = 0; j < bh2; j++){
 
194
                if((my + j < 0) || (my + j >= c->height)) {
 
195
                    memset(out, 0, bw2 * 2);
 
196
                } else {
 
197
                    for(i = 0; i < bw2; i++){
 
198
                        if((mx + i < 0) || (mx + i >= c->width))
 
199
                            out[i] = 0;
 
200
                        else
 
201
                            out[i] = tprev[i];
 
202
                    }
 
203
                }
 
204
                out += c->width;
 
205
                tprev += c->width;
 
206
            }
 
207
 
 
208
            if(d) { /* apply XOR'ed difference */
 
209
                out = output + x;
 
210
                for(j = 0; j < bh2; j++){
 
211
                    for(i = 0; i < bw2; i++) {
 
212
                        out[i] ^= *((uint16_t*)src);
 
213
                        src += 2;
 
214
                    }
 
215
                    out += c->width;
 
216
                }
 
217
            }
 
218
        }
 
219
        output += c->width * c->bh;
 
220
        prev += c->width * c->bh;
 
221
    }
 
222
    if(src - c->decomp_buf != c->decomp_len)
 
223
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
 
224
    return 0;
 
225
}
 
226
 
 
227
#ifdef ZMBV_ENABLE_24BPP
 
228
/**
 
229
 * Decode XOR'ed frame - 24bpp version
 
230
 */
 
231
 
 
232
static int zmbv_decode_xor_24(ZmbvContext *c)
 
233
{
 
234
    uint8_t *src = c->decomp_buf;
 
235
    uint8_t *output, *prev;
 
236
    int8_t *mvec;
 
237
    int x, y;
 
238
    int d, dx, dy, bw2, bh2;
 
239
    int block;
 
240
    int i, j;
 
241
    int mx, my;
 
242
    int stride;
 
243
 
 
244
    output = c->cur;
 
245
    prev = c->prev;
 
246
 
 
247
    stride = c->width * 3;
 
248
    mvec = (int8_t*)src;
 
249
    src += ((c->bx * c->by * 2 + 3) & ~3);
 
250
 
 
251
    block = 0;
 
252
    for(y = 0; y < c->height; y += c->bh) {
 
253
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
 
254
        for(x = 0; x < c->width; x += c->bw) {
 
255
            uint8_t *out, *tprev;
 
256
 
 
257
            d = mvec[block] & 1;
 
258
            dx = mvec[block] >> 1;
 
259
            dy = mvec[block + 1] >> 1;
 
260
            block += 2;
 
261
 
 
262
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
 
263
 
 
264
            /* copy block - motion vectors out of bounds are used to zero blocks */
 
265
            out = output + x * 3;
 
266
            tprev = prev + (x + dx) * 3 + dy * stride;
 
267
            mx = x + dx;
 
268
            my = y + dy;
 
269
            for(j = 0; j < bh2; j++){
 
270
                if((my + j < 0) || (my + j >= c->height)) {
 
271
                    memset(out, 0, bw2 * 3);
 
272
                } else {
 
273
                    for(i = 0; i < bw2; i++){
 
274
                        if((mx + i < 0) || (mx + i >= c->width)) {
 
275
                            out[i * 3 + 0] = 0;
 
276
                            out[i * 3 + 1] = 0;
 
277
                            out[i * 3 + 2] = 0;
 
278
                        } else {
 
279
                            out[i * 3 + 0] = tprev[i * 3 + 0];
 
280
                            out[i * 3 + 1] = tprev[i * 3 + 1];
 
281
                            out[i * 3 + 2] = tprev[i * 3 + 2];
 
282
                        }
 
283
                    }
 
284
                }
 
285
                out += stride;
 
286
                tprev += stride;
 
287
            }
 
288
 
 
289
            if(d) { /* apply XOR'ed difference */
 
290
                out = output + x * 3;
 
291
                for(j = 0; j < bh2; j++){
 
292
                    for(i = 0; i < bw2; i++) {
 
293
                        out[i * 3 + 0] ^= *src++;
 
294
                        out[i * 3 + 1] ^= *src++;
 
295
                        out[i * 3 + 2] ^= *src++;
 
296
                    }
 
297
                    out += stride;
 
298
                }
 
299
            }
 
300
        }
 
301
        output += stride * c->bh;
 
302
        prev += stride * c->bh;
 
303
    }
 
304
    if(src - c->decomp_buf != c->decomp_len)
 
305
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
 
306
    return 0;
 
307
}
 
308
#endif //ZMBV_ENABLE_24BPP
 
309
 
 
310
/**
 
311
 * Decode XOR'ed frame - 32bpp version
 
312
 */
 
313
 
 
314
static int zmbv_decode_xor_32(ZmbvContext *c)
 
315
{
 
316
    uint8_t *src = c->decomp_buf;
 
317
    uint32_t *output, *prev;
 
318
    int8_t *mvec;
 
319
    int x, y;
 
320
    int d, dx, dy, bw2, bh2;
 
321
    int block;
 
322
    int i, j;
 
323
    int mx, my;
 
324
 
 
325
    output = (uint32_t*)c->cur;
 
326
    prev = (uint32_t*)c->prev;
 
327
 
 
328
    mvec = (int8_t*)src;
 
329
    src += ((c->bx * c->by * 2 + 3) & ~3);
 
330
 
 
331
    block = 0;
 
332
    for(y = 0; y < c->height; y += c->bh) {
 
333
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
 
334
        for(x = 0; x < c->width; x += c->bw) {
 
335
            uint32_t *out, *tprev;
 
336
 
 
337
            d = mvec[block] & 1;
 
338
            dx = mvec[block] >> 1;
 
339
            dy = mvec[block + 1] >> 1;
 
340
            block += 2;
 
341
 
 
342
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
 
343
 
 
344
            /* copy block - motion vectors out of bounds are used to zero blocks */
 
345
            out = output + x;
 
346
            tprev = prev + x + dx + dy * c->width;
 
347
            mx = x + dx;
 
348
            my = y + dy;
 
349
            for(j = 0; j < bh2; j++){
 
350
                if((my + j < 0) || (my + j >= c->height)) {
 
351
                    memset(out, 0, bw2 * 4);
 
352
                } else {
 
353
                    for(i = 0; i < bw2; i++){
 
354
                        if((mx + i < 0) || (mx + i >= c->width))
 
355
                            out[i] = 0;
 
356
                        else
 
357
                            out[i] = tprev[i];
 
358
                    }
 
359
                }
 
360
                out += c->width;
 
361
                tprev += c->width;
 
362
            }
 
363
 
 
364
            if(d) { /* apply XOR'ed difference */
 
365
                out = output + x;
 
366
                for(j = 0; j < bh2; j++){
 
367
                    for(i = 0; i < bw2; i++) {
 
368
                        out[i] ^= *((uint32_t*)src);
 
369
                        src += 4;
 
370
                    }
 
371
                    out += c->width;
 
372
                }
 
373
            }
 
374
        }
 
375
        output += c->width * c->bh;
 
376
        prev += c->width * c->bh;
 
377
    }
 
378
    if(src - c->decomp_buf != c->decomp_len)
 
379
        av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len);
 
380
    return 0;
 
381
}
 
382
 
 
383
/**
 
384
 * Decode intraframe
 
385
 */
 
386
static int zmbv_decode_intra(ZmbvContext *c)
 
387
{
 
388
    uint8_t *src = c->decomp_buf;
 
389
 
 
390
    /* make the palette available on the way out */
 
391
    if (c->fmt == ZMBV_FMT_8BPP) {
 
392
        memcpy(c->pal, src, 768);
 
393
        src += 768;
 
394
    }
 
395
 
 
396
    memcpy(c->cur, src, c->width * c->height * (c->bpp / 8));
 
397
    return 0;
 
398
}
 
399
 
 
400
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
 
401
{
 
402
    ZmbvContext * const c = (ZmbvContext *)avctx->priv_data;
 
403
    uint8_t *outptr;
 
404
#ifdef CONFIG_ZLIB
 
405
    int zret = Z_OK; // Zlib return code
 
406
#endif
 
407
    int len = buf_size;
 
408
    int hi_ver, lo_ver;
 
409
 
 
410
    if(c->pic.data[0])
 
411
            avctx->release_buffer(avctx, &c->pic);
 
412
 
 
413
    c->pic.reference = 1;
 
414
    c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
 
415
    if(avctx->get_buffer(avctx, &c->pic) < 0){
 
416
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 
417
        return -1;
 
418
    }
 
419
 
 
420
    outptr = c->pic.data[0]; // Output image pointer
 
421
 
 
422
    /* parse header */
 
423
    c->flags = buf[0];
 
424
    buf++; len--;
 
425
    if(c->flags & ZMBV_KEYFRAME) {
 
426
        hi_ver = buf[0];
 
427
        lo_ver = buf[1];
 
428
        c->comp = buf[2];
 
429
        c->fmt = buf[3];
 
430
        c->bw = buf[4];
 
431
        c->bh = buf[5];
 
432
 
 
433
        buf += 6;
 
434
        len -= 6;
 
435
        av_log(avctx, AV_LOG_DEBUG, "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
 
436
        if(hi_ver != 0 || lo_ver != 1) {
 
437
            av_log(avctx, AV_LOG_ERROR, "Unsupported version %i.%i\n", hi_ver, lo_ver);
 
438
            return -1;
 
439
        }
 
440
        if(c->bw == 0 || c->bh == 0) {
 
441
            av_log(avctx, AV_LOG_ERROR, "Unsupported block size %ix%i\n", c->bw, c->bh);
 
442
        }
 
443
        if(c->comp != 0 && c->comp != 1) {
 
444
            av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp);
 
445
            return -1;
 
446
        }
 
447
 
 
448
        switch(c->fmt) {
 
449
        case ZMBV_FMT_8BPP:
 
450
            c->bpp = 8;
 
451
            c->decode_intra = zmbv_decode_intra;
 
452
            c->decode_xor = zmbv_decode_xor_8;
 
453
            break;
 
454
        case ZMBV_FMT_15BPP:
 
455
        case ZMBV_FMT_16BPP:
 
456
            c->bpp = 16;
 
457
            c->decode_intra = zmbv_decode_intra;
 
458
            c->decode_xor = zmbv_decode_xor_16;
 
459
            break;
 
460
#ifdef ZMBV_ENABLE_24BPP
 
461
        case ZMBV_FMT_24BPP:
 
462
            c->bpp = 24;
 
463
            c->decode_intra = zmbv_decode_intra;
 
464
            c->decode_xor = zmbv_decode_xor_24;
 
465
            break;
 
466
#endif //ZMBV_ENABLE_24BPP
 
467
        case ZMBV_FMT_32BPP:
 
468
            c->bpp = 32;
 
469
            c->decode_intra = zmbv_decode_intra;
 
470
            c->decode_xor = zmbv_decode_xor_32;
 
471
            break;
 
472
        default:
 
473
            c->decode_intra = NULL;
 
474
            c->decode_xor = NULL;
 
475
            av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt);
 
476
            return -1;
 
477
        }
 
478
#ifdef CONFIG_ZLIB
 
479
        zret = inflateReset(&c->zstream);
 
480
        if (zret != Z_OK) {
 
481
            av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
 
482
            return -1;
 
483
        }
 
484
#else
 
485
        av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
 
486
        return -1;
 
487
#endif  /* CONFIG_ZLIB */
 
488
        c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8));
 
489
        c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8));
 
490
        c->bx = (c->width + c->bw - 1) / c->bw;
 
491
        c->by = (c->height+ c->bh - 1) / c->bh;
 
492
    }
 
493
 
 
494
    if(c->decode_intra == NULL) {
 
495
        av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
 
496
        return -1;
 
497
    }
 
498
 
 
499
    if(c->comp == 0) { //Uncompressed data
 
500
        memcpy(c->decomp_buf, buf, len);
 
501
        c->decomp_size = 1;
 
502
    } else { // ZLIB-compressed data
 
503
#ifdef CONFIG_ZLIB
 
504
        c->zstream.total_in = c->zstream.total_out = 0;
 
505
        c->zstream.next_in = buf;
 
506
        c->zstream.avail_in = len;
 
507
        c->zstream.next_out = c->decomp_buf;
 
508
        c->zstream.avail_out = c->decomp_size;
 
509
        inflate(&c->zstream, Z_FINISH);
 
510
        c->decomp_len = c->zstream.total_out;
 
511
#else
 
512
        av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
 
513
        return -1;
 
514
#endif
 
515
    }
 
516
    if(c->flags & ZMBV_KEYFRAME) {
 
517
        c->pic.key_frame = 1;
 
518
        c->pic.pict_type = FF_I_TYPE;
 
519
        c->decode_intra(c);
 
520
    } else {
 
521
        c->pic.key_frame = 0;
 
522
        c->pic.pict_type = FF_P_TYPE;
 
523
        c->decode_xor(c);
 
524
    }
 
525
 
 
526
    /* update frames */
 
527
    {
 
528
        uint8_t *out, *src;
 
529
        int i, j;
 
530
 
 
531
        out = c->pic.data[0];
 
532
        src = c->cur;
 
533
        switch(c->fmt) {
 
534
        case ZMBV_FMT_8BPP:
 
535
            for(j = 0; j < c->height; j++) {
 
536
                for(i = 0; i < c->width; i++) {
 
537
                    out[i * 3 + 0] = c->pal[(*src) * 3 + 0];
 
538
                    out[i * 3 + 1] = c->pal[(*src) * 3 + 1];
 
539
                    out[i * 3 + 2] = c->pal[(*src) * 3 + 2];
 
540
                    *src++;
 
541
                }
 
542
                out += c->pic.linesize[0];
 
543
            }
 
544
            break;
 
545
        case ZMBV_FMT_15BPP:
 
546
            for(j = 0; j < c->height; j++) {
 
547
                for(i = 0; i < c->width; i++) {
 
548
                    uint16_t tmp = AV_RL16(src);
 
549
                    src += 2;
 
550
                    out[i * 3 + 0] = (tmp & 0x7C00) >> 7;
 
551
                    out[i * 3 + 1] = (tmp & 0x03E0) >> 2;
 
552
                    out[i * 3 + 2] = (tmp & 0x001F) << 3;
 
553
                }
 
554
                out += c->pic.linesize[0];
 
555
            }
 
556
            break;
 
557
        case ZMBV_FMT_16BPP:
 
558
            for(j = 0; j < c->height; j++) {
 
559
                for(i = 0; i < c->width; i++) {
 
560
                    uint16_t tmp = AV_RL16(src);
 
561
                    src += 2;
 
562
                    out[i * 3 + 0] = (tmp & 0xF800) >> 8;
 
563
                    out[i * 3 + 1] = (tmp & 0x07E0) >> 3;
 
564
                    out[i * 3 + 2] = (tmp & 0x001F) << 3;
 
565
                }
 
566
                out += c->pic.linesize[0];
 
567
            }
 
568
            break;
 
569
#ifdef ZMBV_ENABLE_24BPP
 
570
        case ZMBV_FMT_24BPP:
 
571
            for(j = 0; j < c->height; j++) {
 
572
                memcpy(out, src, c->width * 3);
 
573
                src += c->width * 3;
 
574
                out += c->pic.linesize[0];
 
575
            }
 
576
            break;
 
577
#endif //ZMBV_ENABLE_24BPP
 
578
        case ZMBV_FMT_32BPP:
 
579
            for(j = 0; j < c->height; j++) {
 
580
                for(i = 0; i < c->width; i++) {
 
581
                    uint32_t tmp = AV_RL32(src);
 
582
                    src += 4;
 
583
                    out[i * 3 + 0] = tmp >> 16;
 
584
                    out[i * 3 + 1] = tmp >> 8;
 
585
                    out[i * 3 + 2] = tmp >> 0;
 
586
                }
 
587
                out += c->pic.linesize[0];
 
588
            }
 
589
            break;
 
590
        default:
 
591
            av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
 
592
        }
 
593
        memcpy(c->prev, c->cur, c->width * c->height * (c->bpp / 8));
 
594
    }
 
595
    *data_size = sizeof(AVFrame);
 
596
    *(AVFrame*)data = c->pic;
 
597
 
 
598
    /* always report that the buffer was completely consumed */
 
599
    return buf_size;
 
600
}
 
601
 
 
602
 
 
603
 
 
604
/*
 
605
 *
 
606
 * Init zmbv decoder
 
607
 *
 
608
 */
 
609
static int decode_init(AVCodecContext *avctx)
 
610
{
 
611
    ZmbvContext * const c = (ZmbvContext *)avctx->priv_data;
 
612
    int zret; // Zlib return code
 
613
 
 
614
    c->avctx = avctx;
 
615
    avctx->has_b_frames = 0;
 
616
 
 
617
    c->pic.data[0] = NULL;
 
618
    c->width = avctx->width;
 
619
    c->height = avctx->height;
 
620
 
 
621
    if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) {
 
622
        return 1;
 
623
    }
 
624
    c->bpp = avctx->bits_per_sample;
 
625
 
 
626
#ifdef CONFIG_ZLIB
 
627
    // Needed if zlib unused or init aborted before inflateInit
 
628
    memset(&(c->zstream), 0, sizeof(z_stream));
 
629
#else
 
630
    av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
 
631
    return 1;
 
632
#endif
 
633
    avctx->pix_fmt = PIX_FMT_RGB24;
 
634
    c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64);
 
635
 
 
636
    /* Allocate decompression buffer */
 
637
    if (c->decomp_size) {
 
638
        if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
 
639
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
 
640
            return 1;
 
641
        }
 
642
    }
 
643
 
 
644
#ifdef CONFIG_ZLIB
 
645
    c->zstream.zalloc = Z_NULL;
 
646
    c->zstream.zfree = Z_NULL;
 
647
    c->zstream.opaque = Z_NULL;
 
648
    zret = inflateInit(&(c->zstream));
 
649
    if (zret != Z_OK) {
 
650
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
 
651
        return 1;
 
652
    }
 
653
#endif
 
654
 
 
655
    return 0;
 
656
}
 
657
 
 
658
 
 
659
 
 
660
/*
 
661
 *
 
662
 * Uninit zmbv decoder
 
663
 *
 
664
 */
 
665
static int decode_end(AVCodecContext *avctx)
 
666
{
 
667
    ZmbvContext * const c = (ZmbvContext *)avctx->priv_data;
 
668
 
 
669
    av_freep(&c->decomp_buf);
 
670
 
 
671
    if (c->pic.data[0])
 
672
        avctx->release_buffer(avctx, &c->pic);
 
673
#ifdef CONFIG_ZLIB
 
674
    inflateEnd(&(c->zstream));
 
675
#endif
 
676
    av_freep(&c->cur);
 
677
    av_freep(&c->prev);
 
678
 
 
679
    return 0;
 
680
}
 
681
 
 
682
AVCodec zmbv_decoder = {
 
683
    "zmbv",
 
684
    CODEC_TYPE_VIDEO,
 
685
    CODEC_ID_ZMBV,
 
686
    sizeof(ZmbvContext),
 
687
    decode_init,
 
688
    NULL,
 
689
    decode_end,
 
690
    decode_frame
 
691
};
 
692