Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 
28
#include 
29
 
30
#include "libavutil/common.h"
31
#include "libavutil/imgutils.h"
32
#include "libavutil/intreadwrite.h"
33
#include "avcodec.h"
34
#include "internal.h"
35
 
36
#include 
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
 
59
    int bpp;
60
    unsigned int decomp_size;
61
    uint8_t* decomp_buf;
62
    uint8_t pal[768];
63
    uint8_t *prev, *cur;
64
    int width, height;
65
    int fmt;
66
    int comp;
67
    int flags;
68
    int stride;
69
    int bw, bh, bx, by;
70
    int decomp_len;
71
    z_stream zstream;
72
    int (*decode_intra)(struct ZmbvContext *c);
73
    int (*decode_xor)(struct ZmbvContext *c);
74
} ZmbvContext;
75
 
76
/**
77
 * Decode XOR'ed frame - 8bpp version
78
 */
79
 
80
static int zmbv_decode_xor_8(ZmbvContext *c)
81
{
82
    uint8_t *src = c->decomp_buf;
83
    uint8_t *output, *prev;
84
    int8_t *mvec;
85
    int x, y;
86
    int d, dx, dy, bw2, bh2;
87
    int block;
88
    int i, j;
89
    int mx, my;
90
 
91
    output = c->cur;
92
    prev = c->prev;
93
 
94
    if (c->flags & ZMBV_DELTAPAL) {
95
        for (i = 0; i < 768; i++)
96
            c->pal[i] ^= *src++;
97
    }
98
 
99
    mvec = (int8_t*)src;
100
    src += ((c->bx * c->by * 2 + 3) & ~3);
101
 
102
    block = 0;
103
    for (y = 0; y < c->height; y += c->bh) {
104
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
105
        for (x = 0; x < c->width; x += c->bw) {
106
            uint8_t *out, *tprev;
107
 
108
            d = mvec[block] & 1;
109
            dx = mvec[block] >> 1;
110
            dy = mvec[block + 1] >> 1;
111
            block += 2;
112
 
113
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
114
 
115
            /* copy block - motion vectors out of bounds are used to zero blocks */
116
            out = output + x;
117
            tprev = prev + x + dx + dy * c->width;
118
            mx = x + dx;
119
            my = y + dy;
120
            for (j = 0; j < bh2; j++) {
121
                if (my + j < 0 || my + j >= c->height) {
122
                    memset(out, 0, bw2);
123
                } else {
124
                    for (i = 0; i < bw2; i++) {
125
                        if (mx + i < 0 || mx + i >= c->width)
126
                            out[i] = 0;
127
                        else
128
                            out[i] = tprev[i];
129
                    }
130
                }
131
                out += c->width;
132
                tprev += c->width;
133
            }
134
 
135
            if (d) { /* apply XOR'ed difference */
136
                out = output + x;
137
                for (j = 0; j < bh2; j++) {
138
                    for (i = 0; i < bw2; i++)
139
                        out[i] ^= *src++;
140
                    out += c->width;
141
                }
142
            }
143
        }
144
        output += c->width * c->bh;
145
        prev += c->width * c->bh;
146
    }
147
    if (src - c->decomp_buf != c->decomp_len)
148
        av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
149
               src-c->decomp_buf, c->decomp_len);
150
    return 0;
151
}
152
 
153
/**
154
 * Decode XOR'ed frame - 15bpp and 16bpp version
155
 */
156
 
157
static int zmbv_decode_xor_16(ZmbvContext *c)
158
{
159
    uint8_t *src = c->decomp_buf;
160
    uint16_t *output, *prev;
161
    int8_t *mvec;
162
    int x, y;
163
    int d, dx, dy, bw2, bh2;
164
    int block;
165
    int i, j;
166
    int mx, my;
167
 
168
    output = (uint16_t*)c->cur;
169
    prev = (uint16_t*)c->prev;
170
 
171
    mvec = (int8_t*)src;
172
    src += ((c->bx * c->by * 2 + 3) & ~3);
173
 
174
    block = 0;
175
    for (y = 0; y < c->height; y += c->bh) {
176
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
177
        for (x = 0; x < c->width; x += c->bw) {
178
            uint16_t *out, *tprev;
179
 
180
            d = mvec[block] & 1;
181
            dx = mvec[block] >> 1;
182
            dy = mvec[block + 1] >> 1;
183
            block += 2;
184
 
185
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
186
 
187
            /* copy block - motion vectors out of bounds are used to zero blocks */
188
            out = output + x;
189
            tprev = prev + x + dx + dy * c->width;
190
            mx = x + dx;
191
            my = y + dy;
192
            for (j = 0; j < bh2; j++) {
193
                if (my + j < 0 || my + j >= c->height) {
194
                    memset(out, 0, bw2 * 2);
195
                } else {
196
                    for (i = 0; i < bw2; i++) {
197
                        if (mx + i < 0 || mx + i >= c->width)
198
                            out[i] = 0;
199
                        else
200
                            out[i] = tprev[i];
201
                    }
202
                }
203
                out += c->width;
204
                tprev += c->width;
205
            }
206
 
207
            if (d) { /* apply XOR'ed difference */
208
                out = output + x;
209
                for (j = 0; j < bh2; j++){
210
                    for (i = 0; i < bw2; i++) {
211
                        out[i] ^= *((uint16_t*)src);
212
                        src += 2;
213
                    }
214
                    out += c->width;
215
                }
216
            }
217
        }
218
        output += c->width * c->bh;
219
        prev += c->width * c->bh;
220
    }
221
    if (src - c->decomp_buf != c->decomp_len)
222
        av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
223
               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",
306
               src-c->decomp_buf, c->decomp_len);
307
    return 0;
308
}
309
#endif //ZMBV_ENABLE_24BPP
310
 
311
/**
312
 * Decode XOR'ed frame - 32bpp version
313
 */
314
 
315
static int zmbv_decode_xor_32(ZmbvContext *c)
316
{
317
    uint8_t *src = c->decomp_buf;
318
    uint32_t *output, *prev;
319
    int8_t *mvec;
320
    int x, y;
321
    int d, dx, dy, bw2, bh2;
322
    int block;
323
    int i, j;
324
    int mx, my;
325
 
326
    output = (uint32_t*)c->cur;
327
    prev = (uint32_t*)c->prev;
328
 
329
    mvec = (int8_t*)src;
330
    src += ((c->bx * c->by * 2 + 3) & ~3);
331
 
332
    block = 0;
333
    for (y = 0; y < c->height; y += c->bh) {
334
        bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y);
335
        for (x = 0; x < c->width; x += c->bw) {
336
            uint32_t *out, *tprev;
337
 
338
            d = mvec[block] & 1;
339
            dx = mvec[block] >> 1;
340
            dy = mvec[block + 1] >> 1;
341
            block += 2;
342
 
343
            bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x);
344
 
345
            /* copy block - motion vectors out of bounds are used to zero blocks */
346
            out = output + x;
347
            tprev = prev + x + dx + dy * c->width;
348
            mx = x + dx;
349
            my = y + dy;
350
            for (j = 0; j < bh2; j++) {
351
                if (my + j < 0 || my + j >= c->height) {
352
                    memset(out, 0, bw2 * 4);
353
                } else {
354
                    for (i = 0; i < bw2; i++){
355
                        if (mx + i < 0 || mx + i >= c->width)
356
                            out[i] = 0;
357
                        else
358
                            out[i] = tprev[i];
359
                    }
360
                }
361
                out += c->width;
362
                tprev += c->width;
363
            }
364
 
365
            if (d) { /* apply XOR'ed difference */
366
                out = output + x;
367
                for (j = 0; j < bh2; j++){
368
                    for (i = 0; i < bw2; i++) {
369
                        out[i] ^= *((uint32_t *) src);
370
                        src += 4;
371
                    }
372
                    out += c->width;
373
                }
374
            }
375
        }
376
        output += c->width * c->bh;
377
        prev   += c->width * c->bh;
378
    }
379
    if (src - c->decomp_buf != c->decomp_len)
380
        av_log(c->avctx, AV_LOG_ERROR, "Used %ti of %i bytes\n",
381
               src-c->decomp_buf, c->decomp_len);
382
    return 0;
383
}
384
 
385
/**
386
 * Decode intraframe
387
 */
388
static int zmbv_decode_intra(ZmbvContext *c)
389
{
390
    uint8_t *src = c->decomp_buf;
391
 
392
    /* make the palette available on the way out */
393
    if (c->fmt == ZMBV_FMT_8BPP) {
394
        memcpy(c->pal, src, 768);
395
        src += 768;
396
    }
397
 
398
    memcpy(c->cur, src, c->width * c->height * (c->bpp / 8));
399
    return 0;
400
}
401
 
402
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
403
{
404
    AVFrame *frame = data;
405
    const uint8_t *buf = avpkt->data;
406
    int buf_size = avpkt->size;
407
    ZmbvContext * const c = avctx->priv_data;
408
    int zret = Z_OK; // Zlib return code
409
    int len = buf_size;
410
    int hi_ver, lo_ver, ret;
411
 
412
    /* parse header */
413
    c->flags = buf[0];
414
    buf++; len--;
415
    if (c->flags & ZMBV_KEYFRAME) {
416
        void *decode_intra = NULL;
417
        c->decode_intra= NULL;
418
        hi_ver = buf[0];
419
        lo_ver = buf[1];
420
        c->comp = buf[2];
421
        c->fmt = buf[3];
422
        c->bw = buf[4];
423
        c->bh = buf[5];
424
        c->decode_intra = NULL;
425
        c->decode_xor = NULL;
426
 
427
        buf += 6;
428
        len -= 6;
429
        av_log(avctx, AV_LOG_DEBUG,
430
               "Flags=%X ver=%i.%i comp=%i fmt=%i blk=%ix%i\n",
431
               c->flags,hi_ver,lo_ver,c->comp,c->fmt,c->bw,c->bh);
432
        if (hi_ver != 0 || lo_ver != 1) {
433
            avpriv_request_sample(avctx, "Version %i.%i", hi_ver, lo_ver);
434
            return AVERROR_PATCHWELCOME;
435
        }
436
        if (c->bw == 0 || c->bh == 0) {
437
            avpriv_request_sample(avctx, "Block size %ix%i", c->bw, c->bh);
438
            return AVERROR_PATCHWELCOME;
439
        }
440
        if (c->comp != 0 && c->comp != 1) {
441
            avpriv_request_sample(avctx, "Compression type %i", c->comp);
442
            return AVERROR_PATCHWELCOME;
443
        }
444
 
445
        switch (c->fmt) {
446
        case ZMBV_FMT_8BPP:
447
            c->bpp = 8;
448
            decode_intra = zmbv_decode_intra;
449
            c->decode_xor = zmbv_decode_xor_8;
450
            avctx->pix_fmt = AV_PIX_FMT_PAL8;
451
            c->stride = c->width;
452
            break;
453
        case ZMBV_FMT_15BPP:
454
        case ZMBV_FMT_16BPP:
455
            c->bpp = 16;
456
            decode_intra = zmbv_decode_intra;
457
            c->decode_xor = zmbv_decode_xor_16;
458
            if (c->fmt == ZMBV_FMT_15BPP)
459
                avctx->pix_fmt = AV_PIX_FMT_RGB555LE;
460
            else
461
                avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
462
            c->stride = c->width * 2;
463
            break;
464
#ifdef ZMBV_ENABLE_24BPP
465
        case ZMBV_FMT_24BPP:
466
            c->bpp = 24;
467
            decode_intra = zmbv_decode_intra;
468
            c->decode_xor = zmbv_decode_xor_24;
469
            avctx->pix_fmt = AV_PIX_FMT_RGB24;
470
            c->stride = c->width * 3;
471
            break;
472
#endif //ZMBV_ENABLE_24BPP
473
        case ZMBV_FMT_32BPP:
474
            c->bpp = 32;
475
            decode_intra = zmbv_decode_intra;
476
            c->decode_xor = zmbv_decode_xor_32;
477
            avctx->pix_fmt = AV_PIX_FMT_BGR0;
478
            c->stride = c->width * 4;
479
            break;
480
        default:
481
            c->decode_xor = NULL;
482
            avpriv_request_sample(avctx, "Format %i", c->fmt);
483
            return AVERROR_PATCHWELCOME;
484
        }
485
 
486
        zret = inflateReset(&c->zstream);
487
        if (zret != Z_OK) {
488
            av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
489
            return AVERROR_UNKNOWN;
490
        }
491
 
492
        c->cur  = av_realloc_f(c->cur, avctx->width * avctx->height,  (c->bpp / 8));
493
        c->prev = av_realloc_f(c->prev, avctx->width * avctx->height,  (c->bpp / 8));
494
        c->bx = (c->width + c->bw - 1) / c->bw;
495
        c->by = (c->height+ c->bh - 1) / c->bh;
496
        if (!c->cur || !c->prev)
497
            return AVERROR(ENOMEM);
498
        memset(c->cur, 0, avctx->width * avctx->height * (c->bpp / 8));
499
        memset(c->prev, 0, avctx->width * avctx->height * (c->bpp / 8));
500
        c->decode_intra= decode_intra;
501
    }
502
 
503
    if (c->decode_intra == NULL) {
504
        av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n");
505
        return AVERROR_INVALIDDATA;
506
    }
507
 
508
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
509
        return ret;
510
 
511
    if (c->comp == 0) { //Uncompressed data
512
        if (c->decomp_size < len) {
513
            av_log(avctx, AV_LOG_ERROR, "Buffer too small\n");
514
            return AVERROR_INVALIDDATA;
515
        }
516
        memcpy(c->decomp_buf, buf, len);
517
    } else { // ZLIB-compressed data
518
        c->zstream.total_in = c->zstream.total_out = 0;
519
        c->zstream.next_in = (uint8_t*)buf;
520
        c->zstream.avail_in = len;
521
        c->zstream.next_out = c->decomp_buf;
522
        c->zstream.avail_out = c->decomp_size;
523
        zret = inflate(&c->zstream, Z_SYNC_FLUSH);
524
        if (zret != Z_OK && zret != Z_STREAM_END) {
525
            av_log(avctx, AV_LOG_ERROR, "inflate error %d\n", zret);
526
            return AVERROR_INVALIDDATA;
527
        }
528
        c->decomp_len = c->zstream.total_out;
529
    }
530
    if (c->flags & ZMBV_KEYFRAME) {
531
        frame->key_frame = 1;
532
        frame->pict_type = AV_PICTURE_TYPE_I;
533
        c->decode_intra(c);
534
    } else {
535
        frame->key_frame = 0;
536
        frame->pict_type = AV_PICTURE_TYPE_P;
537
        if (c->decomp_len)
538
            c->decode_xor(c);
539
    }
540
 
541
    /* update frames */
542
    {
543
        uint8_t *out, *src;
544
        int j;
545
 
546
        out = frame->data[0];
547
        src = c->cur;
548
        switch (c->fmt) {
549
        case ZMBV_FMT_8BPP:
550
            for (j = 0; j < 256; j++)
551
                AV_WN32(&frame->data[1][j * 4], 0xFFU << 24 | AV_RB24(&c->pal[j * 3]));
552
        case ZMBV_FMT_15BPP:
553
        case ZMBV_FMT_16BPP:
554
#ifdef ZMBV_ENABLE_24BPP
555
        case ZMBV_FMT_24BPP:
556
#endif
557
        case ZMBV_FMT_32BPP:
558
            av_image_copy_plane(out, frame->linesize[0], src, c->stride,
559
                                c->stride, c->height);
560
            break;
561
        default:
562
            av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt);
563
        }
564
        FFSWAP(uint8_t *, c->cur, c->prev);
565
    }
566
    *got_frame = 1;
567
 
568
    /* always report that the buffer was completely consumed */
569
    return buf_size;
570
}
571
 
572
static av_cold int decode_init(AVCodecContext *avctx)
573
{
574
    ZmbvContext * const c = avctx->priv_data;
575
    int zret; // Zlib return code
576
 
577
    c->avctx = avctx;
578
 
579
    c->width = avctx->width;
580
    c->height = avctx->height;
581
 
582
    c->bpp = avctx->bits_per_coded_sample;
583
 
584
    // Needed if zlib unused or init aborted before inflateInit
585
    memset(&c->zstream, 0, sizeof(z_stream));
586
 
587
    c->decomp_size = (avctx->width + 255) * 4 * (avctx->height + 64);
588
 
589
    /* Allocate decompression buffer */
590
    if (c->decomp_size) {
591
        if ((c->decomp_buf = av_mallocz(c->decomp_size)) == NULL) {
592
            av_log(avctx, AV_LOG_ERROR,
593
                   "Can't allocate decompression buffer.\n");
594
            return AVERROR(ENOMEM);
595
        }
596
    }
597
 
598
    c->zstream.zalloc = Z_NULL;
599
    c->zstream.zfree = Z_NULL;
600
    c->zstream.opaque = Z_NULL;
601
    zret = inflateInit(&c->zstream);
602
    if (zret != Z_OK) {
603
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
604
        return AVERROR_UNKNOWN;
605
    }
606
 
607
    return 0;
608
}
609
 
610
static av_cold int decode_end(AVCodecContext *avctx)
611
{
612
    ZmbvContext * const c = avctx->priv_data;
613
 
614
    av_freep(&c->decomp_buf);
615
 
616
    inflateEnd(&c->zstream);
617
    av_freep(&c->cur);
618
    av_freep(&c->prev);
619
 
620
    return 0;
621
}
622
 
623
AVCodec ff_zmbv_decoder = {
624
    .name           = "zmbv",
625
    .long_name      = NULL_IF_CONFIG_SMALL("Zip Motion Blocks Video"),
626
    .type           = AVMEDIA_TYPE_VIDEO,
627
    .id             = AV_CODEC_ID_ZMBV,
628
    .priv_data_size = sizeof(ZmbvContext),
629
    .init           = decode_init,
630
    .close          = decode_end,
631
    .decode         = decode_frame,
632
    .capabilities   = CODEC_CAP_DR1,
633
};