GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/flashsv.c Lines: 198 276 71.7 %
Date: 2019-11-18 18:00:01 Branches: 92 148 62.2 %

Line Branch Exec Source
1
/*
2
 * Flash Screen Video decoder
3
 * Copyright (C) 2004 Alex Beregszaszi
4
 * Copyright (C) 2006 Benjamin Larsson
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
/**
24
 * @file
25
 * Flash Screen Video decoder
26
 * @author Alex Beregszaszi
27
 * @author Benjamin Larsson
28
 * @author Daniel Verkamp
29
 * @author Konstantin Shishkov
30
 *
31
 * A description of the bitstream format for Flash Screen Video version 1/2
32
 * is part of the SWF File Format Specification (version 10), which can be
33
 * downloaded from http://www.adobe.com/devnet/swf.html.
34
 */
35
36
#include <stdio.h>
37
#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
typedef struct BlockInfo {
47
    uint8_t *pos;
48
    int      size;
49
} BlockInfo;
50
51
typedef struct FlashSVContext {
52
    AVCodecContext *avctx;
53
    AVFrame        *frame;
54
    int             image_width, image_height;
55
    int             block_width, block_height;
56
    uint8_t        *tmpblock;
57
    int             block_size;
58
    z_stream        zstream;
59
    int             ver;
60
    const uint32_t *pal;
61
    int             is_keyframe;
62
    uint8_t        *keyframedata;
63
    uint8_t        *keyframe;
64
    BlockInfo      *blocks;
65
    uint8_t        *deflate_block;
66
    int             deflate_block_size;
67
    int             color_depth;
68
    int             zlibprime_curr, zlibprime_prev;
69
    int             diff_start, diff_height;
70
} FlashSVContext;
71
72
4641
static int decode_hybrid(const uint8_t *sptr, const uint8_t *sptr_end, uint8_t *dptr, int dx, int dy,
73
                         int h, int w, int stride, const uint32_t *pal)
74
{
75
    int x, y;
76
4641
    const uint8_t *orig_src = sptr;
77
78
270759
    for (y = dx + h; y > dx; y--) {
79
266118
        uint8_t *dst = dptr + (y * stride) + dy * 3;
80
15835602
        for (x = 0; x < w; x++) {
81
15569484
            if (sptr >= sptr_end)
82
                return AVERROR_INVALIDDATA;
83
15569484
            if (*sptr & 0x80) {
84
                /* 15-bit color */
85
12342661
                unsigned c = AV_RB16(sptr) & ~0x8000;
86
12342661
                unsigned b =  c        & 0x1F;
87
12342661
                unsigned g = (c >>  5) & 0x1F;
88
12342661
                unsigned r =  c >> 10;
89
                /* 000aaabb -> aaabbaaa  */
90
12342661
                *dst++ = (b << 3) | (b >> 2);
91
12342661
                *dst++ = (g << 3) | (g >> 2);
92
12342661
                *dst++ = (r << 3) | (r >> 2);
93
12342661
                sptr += 2;
94
            } else {
95
                /* palette index */
96
3226823
                uint32_t c = pal[*sptr++];
97
3226823
                bytestream_put_le24(&dst, c);
98
            }
99
        }
100
    }
101
4641
    return sptr - orig_src;
102
}
103
104
17
static av_cold int flashsv_decode_end(AVCodecContext *avctx)
105
{
106
17
    FlashSVContext *s = avctx->priv_data;
107
17
    inflateEnd(&s->zstream);
108
    /* release the frame if needed */
109
17
    av_frame_free(&s->frame);
110
111
    /* free the tmpblock */
112
17
    av_freep(&s->tmpblock);
113
114
17
    return 0;
115
}
116
117
17
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
118
{
119
17
    FlashSVContext *s = avctx->priv_data;
120
    int zret; // Zlib return code
121
122
17
    s->avctx          = avctx;
123
17
    s->zstream.zalloc = Z_NULL;
124
17
    s->zstream.zfree  = Z_NULL;
125
17
    s->zstream.opaque = Z_NULL;
126
17
    zret = inflateInit(&s->zstream);
127
17
    if (zret != Z_OK) {
128
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
129
        return 1;
130
    }
131
17
    avctx->pix_fmt = AV_PIX_FMT_BGR24;
132
133
17
    s->frame = av_frame_alloc();
134
17
    if (!s->frame) {
135
        return AVERROR(ENOMEM);
136
    }
137
138
17
    return 0;
139
}
140
141
4095
static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
142
{
143
    z_stream zs;
144
    int zret; // Zlib return code
145
146
4095
    if (!src)
147
        return AVERROR_INVALIDDATA;
148
149
4095
    zs.zalloc = NULL;
150
4095
    zs.zfree  = NULL;
151
4095
    zs.opaque = NULL;
152
153
4095
    s->zstream.next_in   = src;
154
4095
    s->zstream.avail_in  = size;
155
4095
    s->zstream.next_out  = s->tmpblock;
156
4095
    s->zstream.avail_out = s->block_size * 3;
157
4095
    inflate(&s->zstream, Z_SYNC_FLUSH);
158
159
4095
    if (deflateInit(&zs, 0) != Z_OK)
160
        return -1;
161
4095
    zs.next_in   = s->tmpblock;
162
4095
    zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
163
4095
    zs.next_out  = s->deflate_block;
164
4095
    zs.avail_out = s->deflate_block_size;
165
4095
    deflate(&zs, Z_SYNC_FLUSH);
166
4095
    deflateEnd(&zs);
167
168
4095
    if ((zret = inflateReset(&s->zstream)) != Z_OK) {
169
        av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
170
        return AVERROR_UNKNOWN;
171
    }
172
173
4095
    s->zstream.next_in   = s->deflate_block;
174
4095
    s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
175
4095
    s->zstream.next_out  = s->tmpblock;
176
4095
    s->zstream.avail_out = s->block_size * 3;
177
4095
    inflate(&s->zstream, Z_SYNC_FLUSH);
178
179
4095
    return 0;
180
}
181
182
9312
static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
183
                                GetBitContext *gb, int block_size,
184
                                int width, int height, int x_pos, int y_pos,
185
                                int blk_idx)
186
{
187
9312
    struct FlashSVContext *s = avctx->priv_data;
188
9312
    uint8_t *line = s->tmpblock;
189
    int k;
190
9312
    int ret = inflateReset(&s->zstream);
191
9312
    if (ret != Z_OK) {
192
        av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
193
        return AVERROR_UNKNOWN;
194
    }
195

9312
    if (s->zlibprime_curr || s->zlibprime_prev) {
196
4095
        ret = flashsv2_prime(s,
197
4095
                             s->blocks[blk_idx].pos,
198
4095
                             s->blocks[blk_idx].size);
199
4095
        if (ret < 0)
200
            return ret;
201
    }
202
9312
    s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
203
9312
    s->zstream.avail_in  = block_size;
204
9312
    s->zstream.next_out  = s->tmpblock;
205
9312
    s->zstream.avail_out = s->block_size * 3;
206
9312
    ret = inflate(&s->zstream, Z_FINISH);
207
9312
    if (ret == Z_DATA_ERROR) {
208
        av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
209
        inflateSync(&s->zstream);
210
        ret = inflate(&s->zstream, Z_FINISH);
211
    }
212
213
    if (ret != Z_OK && ret != Z_STREAM_END) {
214
        //return -1;
215
    }
216
217
9312
    if (s->is_keyframe) {
218
546
        s->blocks[blk_idx].pos  = s->keyframedata + (get_bits_count(gb) / 8);
219
546
        s->blocks[blk_idx].size = block_size;
220
    }
221
222
9312
    y_pos += s->diff_start;
223
224
9312
    if (!s->color_depth) {
225
        /* Flash Screen Video stores the image upside down, so copy
226
         * lines to destination in reverse order. */
227
272517
        for (k = 1; k <= s->diff_height; k++) {
228
267846
            memcpy(s->frame->data[0] + x_pos * 3 +
229
267846
                   (s->image_height - y_pos - k) * s->frame->linesize[0],
230
267846
                   line, width * 3);
231
            /* advance source pointer to next line */
232
267846
            line += width * 3;
233
        }
234
    } else {
235
        /* hybrid 15-bit/palette mode */
236
4641
        ret = decode_hybrid(s->tmpblock, s->zstream.next_out,
237
4641
                      s->frame->data[0],
238
4641
                      s->image_height - (y_pos + 1 + s->diff_height),
239
                      x_pos, s->diff_height, width,
240
4641
                      s->frame->linesize[0], s->pal);
241
4641
        if (ret < 0) {
242
            av_log(avctx, AV_LOG_ERROR, "decode_hybrid failed\n");
243
            return ret;
244
        }
245
    }
246
9312
    skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
247
9312
    return 0;
248
}
249
250
8
static int calc_deflate_block_size(int tmpblock_size)
251
{
252
    z_stream zstream;
253
    int size;
254
255
8
    zstream.zalloc = Z_NULL;
256
8
    zstream.zfree  = Z_NULL;
257
8
    zstream.opaque = Z_NULL;
258
8
    if (deflateInit(&zstream, 0) != Z_OK)
259
        return -1;
260
8
    size = deflateBound(&zstream, tmpblock_size);
261
8
    deflateEnd(&zstream);
262
263
8
    return size;
264
}
265
266
409
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
267
                                int *got_frame, AVPacket *avpkt)
268
{
269
409
    int buf_size = avpkt->size;
270
409
    FlashSVContext *s = avctx->priv_data;
271
    int h_blocks, v_blocks, h_part, v_part, i, j, ret;
272
    GetBitContext gb;
273
409
    int last_blockwidth = s->block_width;
274
409
    int last_blockheight= s->block_height;
275
276
    /* no supplementary picture */
277
409
    if (buf_size == 0)
278
        return 0;
279
409
    if (buf_size < 4)
280
        return -1;
281
282
409
    if ((ret = init_get_bits8(&gb, avpkt->data, buf_size)) < 0)
283
        return ret;
284
285
    /* start to parse the bitstream */
286
409
    s->block_width  = 16 * (get_bits(&gb, 4) + 1);
287
409
    s->image_width  = get_bits(&gb, 12);
288
409
    s->block_height = 16 * (get_bits(&gb, 4) + 1);
289
409
    s->image_height = get_bits(&gb, 12);
290
291
409
    if (   last_blockwidth != s->block_width
292
392
        || last_blockheight!= s->block_height)
293
17
        av_freep(&s->blocks);
294
295
409
    if (s->ver == 2) {
296
204
        skip_bits(&gb, 6);
297
204
        if (get_bits1(&gb)) {
298
            avpriv_request_sample(avctx, "iframe");
299
            return AVERROR_PATCHWELCOME;
300
        }
301
204
        if (get_bits1(&gb)) {
302
            avpriv_request_sample(avctx, "Custom palette");
303
            return AVERROR_PATCHWELCOME;
304
        }
305
    }
306
307
    /* calculate number of blocks and size of border (partial) blocks */
308
409
    h_blocks = s->image_width  / s->block_width;
309
409
    h_part   = s->image_width  % s->block_width;
310
409
    v_blocks = s->image_height / s->block_height;
311
409
    v_part   = s->image_height % s->block_height;
312
313
    /* the block size could change between frames, make sure the buffer
314
     * is large enough, if not, get a larger one */
315
409
    if (s->block_size < s->block_width * s->block_height) {
316
17
        int tmpblock_size = 3 * s->block_width * s->block_height, err;
317
318
17
        if ((err = av_reallocp(&s->tmpblock, tmpblock_size)) < 0) {
319
            s->block_size = 0;
320
            av_log(avctx, AV_LOG_ERROR,
321
                   "Cannot allocate decompression buffer.\n");
322
            return err;
323
        }
324
17
        if (s->ver == 2) {
325
8
            s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
326
8
            if (s->deflate_block_size <= 0) {
327
                av_log(avctx, AV_LOG_ERROR,
328
                       "Cannot determine deflate buffer size.\n");
329
                return -1;
330
            }
331
8
            if ((err = av_reallocp(&s->deflate_block, s->deflate_block_size)) < 0) {
332
                s->block_size = 0;
333
                av_log(avctx, AV_LOG_ERROR, "Cannot allocate deflate buffer.\n");
334
                return err;
335
            }
336
        }
337
    }
338
409
    s->block_size = s->block_width * s->block_height;
339
340
    /* initialize the image size once */
341

409
    if (avctx->width == 0 && avctx->height == 0) {
342
9
        if ((ret = ff_set_dimensions(avctx, s->image_width, s->image_height)) < 0)
343
            return ret;
344
    }
345
346
    /* check for changes of image width and image height */
347

409
    if (avctx->width != s->image_width || avctx->height != s->image_height) {
348
        av_log(avctx, AV_LOG_ERROR,
349
               "Frame width or height differs from first frame!\n");
350
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
351
               avctx->height, avctx->width, s->image_height, s->image_width);
352
        return AVERROR_INVALIDDATA;
353
    }
354
355
    /* we care for keyframes only in Screen Video v2 */
356

409
    s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
357
409
    if (s->is_keyframe) {
358
        int err;
359
24
        if ((err = av_reallocp(&s->keyframedata, avpkt->size)) < 0)
360
            return err;
361
24
        memcpy(s->keyframedata, avpkt->data, avpkt->size);
362
    }
363

409
    if(s->ver == 2 && !s->blocks)
364
8
        s->blocks = av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part) *
365
                               sizeof(s->blocks[0]));
366
367
    ff_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
368
            s->image_width, s->image_height, s->block_width, s->block_height,
369
            h_blocks, v_blocks, h_part, v_part);
370
371
409
    if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0)
372
        return ret;
373
374
    /* loop over all block columns */
375
2046
    for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
376
377
1637
        int y_pos  = j * s->block_height; // vertical position in frame
378
1637
        int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
379
380
        /* loop over all block rows */
381
10949
        for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
382
9312
            int x_pos = i * s->block_width; // horizontal position in frame
383
9312
            int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
384
9312
            int has_diff = 0;
385
386
            /* get the size of the compressed zlib chunk */
387
9312
            int size = get_bits(&gb, 16);
388
389
9312
            s->color_depth    = 0;
390
9312
            s->zlibprime_curr = 0;
391
9312
            s->zlibprime_prev = 0;
392
9312
            s->diff_start     = 0;
393
9312
            s->diff_height    = cur_blk_height;
394
395
9312
            if (8 * size > get_bits_left(&gb)) {
396
                av_frame_unref(s->frame);
397
                return AVERROR_INVALIDDATA;
398
            }
399
400

9312
            if (s->ver == 2 && size) {
401
4641
                skip_bits(&gb, 3);
402
4641
                s->color_depth    = get_bits(&gb, 2);
403
4641
                has_diff          = get_bits1(&gb);
404
4641
                s->zlibprime_curr = get_bits1(&gb);
405
4641
                s->zlibprime_prev = get_bits1(&gb);
406
407

4641
                if (s->color_depth != 0 && s->color_depth != 2) {
408
                    av_log(avctx, AV_LOG_ERROR,
409
                           "%dx%d invalid color depth %d\n",
410
                           i, j, s->color_depth);
411
                    return AVERROR_INVALIDDATA;
412
                }
413
414
4641
                if (has_diff) {
415
                    if (size < 3) {
416
                        av_log(avctx, AV_LOG_ERROR, "size too small for diff\n");
417
                        return AVERROR_INVALIDDATA;
418
                    }
419
                    if (!s->keyframe) {
420
                        av_log(avctx, AV_LOG_ERROR,
421
                               "Inter frame without keyframe\n");
422
                        return AVERROR_INVALIDDATA;
423
                    }
424
                    s->diff_start  = get_bits(&gb, 8);
425
                    s->diff_height = get_bits(&gb, 8);
426
                    if (s->diff_start + s->diff_height > cur_blk_height) {
427
                        av_log(avctx, AV_LOG_ERROR,
428
                               "Block parameters invalid: %d + %d > %d\n",
429
                               s->diff_start, s->diff_height, cur_blk_height);
430
                        return AVERROR_INVALIDDATA;
431
                    }
432
                    av_log(avctx, AV_LOG_DEBUG,
433
                           "%dx%d diff start %d height %d\n",
434
                           i, j, s->diff_start, s->diff_height);
435
                    size -= 2;
436
                }
437
438
4641
                if (s->zlibprime_prev)
439
4095
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
440
441
4641
                if (s->zlibprime_curr) {
442
                    int col = get_bits(&gb, 8);
443
                    int row = get_bits(&gb, 8);
444
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n",
445
                           i, j, col, row);
446
                    if (size < 3) {
447
                        av_log(avctx, AV_LOG_ERROR, "size too small for zlibprime_curr\n");
448
                        return AVERROR_INVALIDDATA;
449
                    }
450
                    size -= 2;
451
                    avpriv_request_sample(avctx, "zlibprime_curr");
452
                    return AVERROR_PATCHWELCOME;
453
                }
454

4641
                if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
455
                    av_log(avctx, AV_LOG_ERROR,
456
                           "no data available for zlib priming\n");
457
                    return AVERROR_INVALIDDATA;
458
                }
459
4641
                size--; // account for flags byte
460
            }
461
462
9312
            if (has_diff) {
463
                int k;
464
                int off = (s->image_height - y_pos - 1) * s->frame->linesize[0];
465
466
                for (k = 0; k < cur_blk_height; k++) {
467
                    int x = off - k * s->frame->linesize[0] + x_pos * 3;
468
                    memcpy(s->frame->data[0] + x, s->keyframe + x,
469
                           cur_blk_width * 3);
470
                }
471
            }
472
473
            /* skip unchanged blocks, which have size 0 */
474
9312
            if (size) {
475
9312
                if (flashsv_decode_block(avctx, avpkt, &gb, size,
476
                                         cur_blk_width, cur_blk_height,
477
                                         x_pos, y_pos,
478
9312
                                         i + j * (h_blocks + !!h_part)))
479
                    av_log(avctx, AV_LOG_ERROR,
480
                           "error in decompression of block %dx%d\n", i, j);
481
            }
482
        }
483
    }
484

409
    if (s->is_keyframe && s->ver == 2) {
485
24
        if (!s->keyframe) {
486
8
            s->keyframe = av_malloc(s->frame->linesize[0] * avctx->height);
487
8
            if (!s->keyframe) {
488
                av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
489
                return AVERROR(ENOMEM);
490
            }
491
        }
492
24
        memcpy(s->keyframe, s->frame->data[0],
493
24
               s->frame->linesize[0] * avctx->height);
494
    }
495
496
409
    if ((ret = av_frame_ref(data, s->frame)) < 0)
497
        return ret;
498
499
409
    *got_frame = 1;
500
501
409
    if ((get_bits_count(&gb) / 8) != buf_size)
502
        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
503
               buf_size, (get_bits_count(&gb) / 8));
504
505
    /* report that the buffer was completely consumed */
506
409
    return buf_size;
507
}
508
509
#if CONFIG_FLASHSV_DECODER
510
AVCodec ff_flashsv_decoder = {
511
    .name           = "flashsv",
512
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
513
    .type           = AVMEDIA_TYPE_VIDEO,
514
    .id             = AV_CODEC_ID_FLASHSV,
515
    .priv_data_size = sizeof(FlashSVContext),
516
    .init           = flashsv_decode_init,
517
    .close          = flashsv_decode_end,
518
    .decode         = flashsv_decode_frame,
519
    .capabilities   = AV_CODEC_CAP_DR1,
520
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
521
    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
522
};
523
#endif /* CONFIG_FLASHSV_DECODER */
524
525
#if CONFIG_FLASHSV2_DECODER
526
static const uint32_t ff_flashsv2_default_palette[128] = {
527
    0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
528
    0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
529
    0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
530
    0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
531
    0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
532
    0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
533
    0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
534
    0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
535
    0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
536
    0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
537
    0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
538
    0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
539
    0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
540
    0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
541
    0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
542
    0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
543
    0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
544
    0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
545
    0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
546
    0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
547
    0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
548
    0xDDDDDD, 0xEEEEEE
549
};
550
551
8
static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
552
{
553
8
    FlashSVContext *s = avctx->priv_data;
554
    int ret;
555
556
8
    ret = flashsv_decode_init(avctx);
557
8
    if (ret < 0)
558
        return ret;
559
8
    s->pal = ff_flashsv2_default_palette;
560
8
    s->ver = 2;
561
562
8
    return 0;
563
}
564
565
8
static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
566
{
567
8
    FlashSVContext *s = avctx->priv_data;
568
569
8
    av_freep(&s->keyframedata);
570
8
    av_freep(&s->blocks);
571
8
    av_freep(&s->keyframe);
572
8
    av_freep(&s->deflate_block);
573
8
    flashsv_decode_end(avctx);
574
575
8
    return 0;
576
}
577
578
AVCodec ff_flashsv2_decoder = {
579
    .name           = "flashsv2",
580
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
581
    .type           = AVMEDIA_TYPE_VIDEO,
582
    .id             = AV_CODEC_ID_FLASHSV2,
583
    .priv_data_size = sizeof(FlashSVContext),
584
    .init           = flashsv2_decode_init,
585
    .close          = flashsv2_decode_end,
586
    .decode         = flashsv_decode_frame,
587
    .capabilities   = AV_CODEC_CAP_DR1,
588
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
589
    .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
590
};
591
#endif /* CONFIG_FLASHSV2_DECODER */