~ubuntu-branches/ubuntu/oneiric/libav/oneiric

« back to all changes in this revision

Viewing changes to libavcodec/zmbv.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2011-03-20 12:09:31 UTC
  • Revision ID: james.westby@ubuntu.com-20110320120931-nfhi9tiok27gxhw1
Tags: upstream-0.6.2
ImportĀ upstreamĀ versionĀ 0.6.2

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