flashsv.c 19.3 KB
Newer Older
1 2 3 4 5
/*
 * Flash Screen Video decoder
 * Copyright (C) 2004 Alex Beregszaszi
 * Copyright (C) 2006 Benjamin Larsson
 *
6
 * This file is part of Libav.
7
 *
8
 * Libav is free software; you can redistribute it and/or
9 10
 * modify it under the terms of the GNU Lesser General Public
 * 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
 * Libav is distributed in the hope that it will be useful,
14 15 16 17 18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with Libav; if not, write to the Free Software
20 21 22 23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
24
 * @file
25 26 27
 * Flash Screen Video decoder
 * @author Alex Beregszaszi
 * @author Benjamin Larsson
28 29
 * @author Daniel Verkamp
 * @author Konstantin Shishkov
30
 *
31 32 33
 * A description of the bitstream format for Flash Screen Video version 1/2
 * is part of the SWF File Format Specification (version 10), which can be
 * downloaded from http://www.adobe.com/devnet/swf.html.
34 35 36 37
 */

#include <stdio.h>
#include <stdlib.h>
38
#include <zlib.h>
39

40
#include "libavutil/intreadwrite.h"
41
#include "avcodec.h"
42
#include "bytestream.h"
43
#include "get_bits.h"
44
#include "internal.h"
45

46 47 48 49 50
typedef struct BlockInfo {
    uint8_t *pos;
    int      size;
} BlockInfo;

51 52
typedef struct FlashSVContext {
    AVCodecContext *avctx;
53
    AVFrame        *frame;
54 55 56 57 58
    int             image_width, image_height;
    int             block_width, block_height;
    uint8_t        *tmpblock;
    int             block_size;
    z_stream        zstream;
59 60 61 62 63 64 65 66 67 68 69
    int             ver;
    const uint32_t *pal;
    int             is_keyframe;
    uint8_t        *keyframedata;
    uint8_t        *keyframe;
    BlockInfo      *blocks;
    uint8_t        *deflate_block;
    int             deflate_block_size;
    int             color_depth;
    int             zlibprime_curr, zlibprime_prev;
    int             diff_start, diff_height;
70 71
} FlashSVContext;

72 73 74 75 76 77
static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
                         int h, int w, int stride, const uint32_t *pal)
{
    int x, y;
    const uint8_t *orig_src = sptr;

78
    for (y = dx + h; y > dx; y--) {
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
        uint8_t *dst = dptr + (y * stride) + dy * 3;
        for (x = 0; x < w; x++) {
            if (*sptr & 0x80) {
                /* 15-bit color */
                unsigned c = AV_RB16(sptr) & ~0x8000;
                unsigned b =  c        & 0x1F;
                unsigned g = (c >>  5) & 0x1F;
                unsigned r =  c >> 10;
                /* 000aaabb -> aaabbaaa  */
                *dst++ = (b << 3) | (b >> 2);
                *dst++ = (g << 3) | (g >> 2);
                *dst++ = (r << 3) | (r >> 2);
                sptr += 2;
            } else {
                /* palette index */
                uint32_t c = pal[*sptr++];
                bytestream_put_le24(&dst, c);
            }
        }
    }
    return sptr - orig_src;
}

102 103 104 105 106 107 108 109 110 111 112 113 114
static av_cold int flashsv_decode_end(AVCodecContext *avctx)
{
    FlashSVContext *s = avctx->priv_data;
    inflateEnd(&s->zstream);
    /* release the frame if needed */
    av_frame_free(&s->frame);

    /* free the tmpblock */
    av_free(s->tmpblock);

    return 0;
}

115
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
116
{
117
    FlashSVContext *s = avctx->priv_data;
118 119
    int zret; // Zlib return code

120
    s->avctx          = avctx;
121
    s->zstream.zalloc = Z_NULL;
122
    s->zstream.zfree  = Z_NULL;
123
    s->zstream.opaque = Z_NULL;
124
    zret = inflateInit(&s->zstream);
125 126 127 128
    if (zret != Z_OK) {
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
        return 1;
    }
129
    avctx->pix_fmt = AV_PIX_FMT_BGR24;
130 131 132 133 134 135

    s->frame = av_frame_alloc();
    if (!s->frame) {
        flashsv_decode_end(avctx);
        return AVERROR(ENOMEM);
    }
136 137 138 139

    return 0;
}

140
static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
141 142
{
    z_stream zs;
143
    int zret; // Zlib return code
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162

    zs.zalloc = NULL;
    zs.zfree  = NULL;
    zs.opaque = NULL;

    s->zstream.next_in   = src;
    s->zstream.avail_in  = size;
    s->zstream.next_out  = s->tmpblock;
    s->zstream.avail_out = s->block_size * 3;
    inflate(&s->zstream, Z_SYNC_FLUSH);

    deflateInit(&zs, 0);
    zs.next_in   = s->tmpblock;
    zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
    zs.next_out  = s->deflate_block;
    zs.avail_out = s->deflate_block_size;
    deflate(&zs, Z_SYNC_FLUSH);
    deflateEnd(&zs);

163 164 165 166
    if ((zret = inflateReset(&s->zstream)) != Z_OK) {
        av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
        return AVERROR_UNKNOWN;
    }
167 168 169 170 171 172

    s->zstream.next_in   = s->deflate_block;
    s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
    s->zstream.next_out  = s->tmpblock;
    s->zstream.avail_out = s->block_size * 3;
    inflate(&s->zstream, Z_SYNC_FLUSH);
173 174

    return 0;
175 176
}

177 178
static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
                                GetBitContext *gb, int block_size,
179 180
                                int width, int height, int x_pos, int y_pos,
                                int blk_idx)
181 182 183 184 185 186
{
    struct FlashSVContext *s = avctx->priv_data;
    uint8_t *line = s->tmpblock;
    int k;
    int ret = inflateReset(&s->zstream);
    if (ret != Z_OK) {
187 188
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
        return AVERROR_UNKNOWN;
189
    }
190
    if (s->zlibprime_curr || s->zlibprime_prev) {
191 192 193
        ret = flashsv2_prime(s,
                             s->blocks[blk_idx].pos,
                             s->blocks[blk_idx].size);
194 195
        if (ret < 0)
            return ret;
196
    }
197 198 199 200 201 202 203 204 205 206 207 208 209 210
    s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
    s->zstream.avail_in  = block_size;
    s->zstream.next_out  = s->tmpblock;
    s->zstream.avail_out = s->block_size * 3;
    ret = inflate(&s->zstream, Z_FINISH);
    if (ret == Z_DATA_ERROR) {
        av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
        inflateSync(&s->zstream);
        ret = inflate(&s->zstream, Z_FINISH);
    }

    if (ret != Z_OK && ret != Z_STREAM_END) {
        //return -1;
    }
211 212

    if (s->is_keyframe) {
213 214
        s->blocks[blk_idx].pos  = s->keyframedata + (get_bits_count(gb) / 8);
        s->blocks[blk_idx].size = block_size;
215
    }
216 217 218

    y_pos += s->diff_start;

219 220 221 222
    if (!s->color_depth) {
        /* Flash Screen Video stores the image upside down, so copy
         * lines to destination in reverse order. */
        for (k = 1; k <= s->diff_height; k++) {
223 224
            memcpy(s->frame->data[0] + x_pos * 3 +
                   (s->image_height - y_pos - k) * s->frame->linesize[0],
225 226 227 228 229 230
                   line, width * 3);
            /* advance source pointer to next line */
            line += width * 3;
        }
    } else {
        /* hybrid 15-bit/palette mode */
231
        decode_hybrid(s->tmpblock, s->frame->data[0],
232
                      s->image_height - (y_pos + 1 + s->diff_height),
233
                      x_pos, s->diff_height, width,
234
                      s->frame->linesize[0], s->pal);
235 236 237 238 239
    }
    skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
    return 0;
}

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
static int calc_deflate_block_size(int tmpblock_size)
{
    z_stream zstream;
    int size;

    zstream.zalloc = Z_NULL;
    zstream.zfree  = Z_NULL;
    zstream.opaque = Z_NULL;
    if (deflateInit(&zstream, 0) != Z_OK)
        return -1;
    size = deflateBound(&zstream, tmpblock_size);
    deflateEnd(&zstream);

    return size;
}
255

256
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
257
                                int *got_frame, AVPacket *avpkt)
258
{
259 260
    int buf_size = avpkt->size;
    FlashSVContext *s = avctx->priv_data;
261
    int h_blocks, v_blocks, h_part, v_part, i, j, ret;
262 263 264 265 266
    GetBitContext gb;

    /* no supplementary picture */
    if (buf_size == 0)
        return 0;
267 268
    if (buf_size < 4)
        return -1;
269

270
    init_get_bits(&gb, avpkt->data, buf_size * 8);
271 272

    /* start to parse the bitstream */
273 274 275 276
    s->block_width  = 16 * (get_bits(&gb, 4) + 1);
    s->image_width  = get_bits(&gb, 12);
    s->block_height = 16 * (get_bits(&gb, 4) + 1);
    s->image_height = get_bits(&gb, 12);
277

278 279 280
    if (s->ver == 2) {
        skip_bits(&gb, 6);
        if (get_bits1(&gb)) {
281
            avpriv_request_sample(avctx, "iframe");
282 283 284
            return AVERROR_PATCHWELCOME;
        }
        if (get_bits1(&gb)) {
285
            avpriv_request_sample(avctx, "Custom palette");
286 287 288 289
            return AVERROR_PATCHWELCOME;
        }
    }

290
    /* calculate number of blocks and size of border (partial) blocks */
291 292
    h_blocks = s->image_width  / s->block_width;
    h_part   = s->image_width  % s->block_width;
293
    v_blocks = s->image_height / s->block_height;
294
    v_part   = s->image_height % s->block_height;
295 296 297

    /* the block size could change between frames, make sure the buffer
     * is large enough, if not, get a larger one */
298
    if (s->block_size < s->block_width * s->block_height) {
299
        int tmpblock_size = 3 * s->block_width * s->block_height, err;
300

301 302
        if ((err = av_reallocp(&s->tmpblock, tmpblock_size)) < 0) {
            s->block_size = 0;
303 304
            av_log(avctx, AV_LOG_ERROR,
                   "Cannot allocate decompression buffer.\n");
305
            return err;
306
        }
307 308 309
        if (s->ver == 2) {
            s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
            if (s->deflate_block_size <= 0) {
310 311
                av_log(avctx, AV_LOG_ERROR,
                       "Cannot determine deflate buffer size.\n");
312 313
                return -1;
            }
314 315 316 317
            if ((err = av_reallocp(&s->deflate_block, s->deflate_block_size)) < 0) {
                s->block_size = 0;
                av_log(avctx, AV_LOG_ERROR, "Cannot allocate deflate buffer.\n");
                return err;
318 319
            }
        }
320
    }
321
    s->block_size = s->block_width * s->block_height;
322

323
    /* initialize the image size once */
324
    if (avctx->width == 0 && avctx->height == 0) {
325
        avctx->width  = s->image_width;
326 327 328 329
        avctx->height = s->image_height;
    }

    /* check for changes of image width and image height */
330
    if (avctx->width != s->image_width || avctx->height != s->image_height) {
331
        av_log(avctx, AV_LOG_ERROR,
332
               "Frame width or height differs from first frame!\n");
333 334
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
               avctx->height, avctx->width, s->image_height, s->image_width);
335
        return AVERROR_INVALIDDATA;
336 337
    }

338 339 340
    /* we care for keyframes only in Screen Video v2 */
    s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
    if (s->is_keyframe) {
341 342 343
        int err;
        if ((err = av_reallocp(&s->keyframedata, avpkt->size)) < 0)
            return err;
344
        memcpy(s->keyframedata, avpkt->data, avpkt->size);
345 346 347
        if ((err = av_reallocp(&s->blocks, (v_blocks + !!v_part) *
                               (h_blocks + !!h_part) * sizeof(s->blocks[0]))) < 0)
            return err;
348 349
    }

350 351 352
    av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
            s->image_width, s->image_height, s->block_width, s->block_height,
            h_blocks, v_blocks, h_part, v_part);
353

354
    if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) {
355
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
356
        return ret;
357 358 359
    }

    /* loop over all block columns */
360
    for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
361

362 363
        int y_pos  = j * s->block_height; // vertical position in frame
        int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
364 365

        /* loop over all block rows */
366
        for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
367 368
            int x_pos = i * s->block_width; // horizontal position in frame
            int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
369
            int has_diff = 0;
370 371 372

            /* get the size of the compressed zlib chunk */
            int size = get_bits(&gb, 16);
373 374 375 376 377 378 379

            s->color_depth    = 0;
            s->zlibprime_curr = 0;
            s->zlibprime_prev = 0;
            s->diff_start     = 0;
            s->diff_height    = cur_blk_height;

380
            if (8 * size > get_bits_left(&gb)) {
381
                av_frame_unref(s->frame);
382
                return AVERROR_INVALIDDATA;
383
            }
384

385 386 387 388 389 390 391 392 393
            if (s->ver == 2 && size) {
                skip_bits(&gb, 3);
                s->color_depth    = get_bits(&gb, 2);
                has_diff          = get_bits1(&gb);
                s->zlibprime_curr = get_bits1(&gb);
                s->zlibprime_prev = get_bits1(&gb);

                if (s->color_depth != 0 && s->color_depth != 2) {
                    av_log(avctx, AV_LOG_ERROR,
394 395
                           "%dx%d invalid color depth %d\n",
                           i, j, s->color_depth);
396
                    return AVERROR_INVALIDDATA;
397 398 399
                }

                if (has_diff) {
400 401
                    if (!s->keyframe) {
                        av_log(avctx, AV_LOG_ERROR,
402
                               "Inter frame without keyframe\n");
403 404
                        return AVERROR_INVALIDDATA;
                    }
405 406
                    s->diff_start  = get_bits(&gb, 8);
                    s->diff_height = get_bits(&gb, 8);
407 408 409 410 411 412
                    if (s->diff_start + s->diff_height > cur_blk_height) {
                        av_log(avctx, AV_LOG_ERROR,
                               "Block parameters invalid: %d + %d > %d\n",
                               s->diff_start, s->diff_height, cur_blk_height);
                        return AVERROR_INVALIDDATA;
                    }
413 414 415 416 417 418 419 420 421 422 423 424
                    av_log(avctx, AV_LOG_DEBUG,
                           "%dx%d diff start %d height %d\n",
                           i, j, s->diff_start, s->diff_height);
                    size -= 2;
                }

                if (s->zlibprime_prev)
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);

                if (s->zlibprime_curr) {
                    int col = get_bits(&gb, 8);
                    int row = get_bits(&gb, 8);
425 426
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n",
                           i, j, col, row);
427
                    size -= 2;
428
                    avpriv_request_sample(avctx, "zlibprime_curr");
429 430
                    return AVERROR_PATCHWELCOME;
                }
431
                if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
432 433
                    av_log(avctx, AV_LOG_ERROR,
                           "no data available for zlib priming\n");
434 435
                    return AVERROR_INVALIDDATA;
                }
436 437 438 439 440
                size--; // account for flags byte
            }

            if (has_diff) {
                int k;
441
                int off = (s->image_height - y_pos - 1) * s->frame->linesize[0];
442

443
                for (k = 0; k < cur_blk_height; k++) {
444 445
                    int x = off - k * s->frame->linesize[0] + x_pos * 3;
                    memcpy(s->frame->data[0] + x, s->keyframe + x,
446
                           cur_blk_width * 3);
447
                }
448 449
            }

450 451
            /* skip unchanged blocks, which have size 0 */
            if (size) {
452 453
                if (flashsv_decode_block(avctx, avpkt, &gb, size,
                                         cur_blk_width, cur_blk_height,
454 455
                                         x_pos, y_pos,
                                         i + j * (h_blocks + !!h_part)))
456
                    av_log(avctx, AV_LOG_ERROR,
457
                           "error in decompression of block %dx%d\n", i, j);
458 459 460
            }
        }
    }
461 462
    if (s->is_keyframe && s->ver == 2) {
        if (!s->keyframe) {
463
            s->keyframe = av_malloc(s->frame->linesize[0] * avctx->height);
464 465 466 467 468
            if (!s->keyframe) {
                av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
                return AVERROR(ENOMEM);
            }
        }
469 470
        memcpy(s->keyframe, s->frame->data[0],
               s->frame->linesize[0] * avctx->height);
471
    }
472

473
    if ((ret = av_frame_ref(data, s->frame)) < 0)
474 475
        return ret;

476
    *got_frame = 1;
477

478
    if ((get_bits_count(&gb) / 8) != buf_size)
479
        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
480
               buf_size, (get_bits_count(&gb) / 8));
481 482 483 484 485

    /* report that the buffer was completely consumed */
    return buf_size;
}

486
#if CONFIG_FLASHSV_DECODER
487
AVCodec ff_flashsv_decoder = {
488
    .name           = "flashsv",
489
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
490
    .type           = AVMEDIA_TYPE_VIDEO,
491
    .id             = AV_CODEC_ID_FLASHSV,
492 493 494 495 496
    .priv_data_size = sizeof(FlashSVContext),
    .init           = flashsv_decode_init,
    .close          = flashsv_decode_end,
    .decode         = flashsv_decode_frame,
    .capabilities   = CODEC_CAP_DR1,
497
    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
498
};
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
#endif /* CONFIG_FLASHSV_DECODER */

#if CONFIG_FLASHSV2_DECODER
static const uint32_t ff_flashsv2_default_palette[128] = {
    0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
    0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
    0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
    0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
    0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
    0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
    0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
    0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
    0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
    0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
    0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
    0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
    0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
    0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
    0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
    0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
    0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
    0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
    0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
    0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
    0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
    0xDDDDDD, 0xEEEEEE
};

static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
{
    FlashSVContext *s = avctx->priv_data;
    flashsv_decode_init(avctx);
    s->pal = ff_flashsv2_default_palette;
    s->ver = 2;

    return 0;
}

static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
{
    FlashSVContext *s = avctx->priv_data;

    av_freep(&s->keyframedata);
    av_freep(&s->blocks);
    av_freep(&s->keyframe);
    av_freep(&s->deflate_block);
    flashsv_decode_end(avctx);

    return 0;
}

AVCodec ff_flashsv2_decoder = {
    .name           = "flashsv2",
552
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
553
    .type           = AVMEDIA_TYPE_VIDEO,
554
    .id             = AV_CODEC_ID_FLASHSV2,
555 556 557 558 559
    .priv_data_size = sizeof(FlashSVContext),
    .init           = flashsv2_decode_init,
    .close          = flashsv2_decode_end,
    .decode         = flashsv_decode_frame,
    .capabilities   = CODEC_CAP_DR1,
560
    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
561 562
};
#endif /* CONFIG_FLASHSV2_DECODER */