~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/flashsv.c

  • Committer: Gauvain Pocentek
  • Date: 2012-03-06 11:59:12 UTC
  • mfrom: (66.1.15 precise)
  • Revision ID: gauvain@pocentek.net-20120306115912-h9d6kt9j0l532oo5
* Merge from Ubuntu:
  - put back faac support
  - recommends apport-hooks-medibuntu
  - change Maintainer, Uploaders & Vcs-* fields.
* New upstream snapshot
* upload to unstable
* Build against external libmpeg2
* drop 51_FTBFS_arm.patch again
* no longer build depend on libcdparanoia-dev on the Hurd
* Fix FTBFS on the hurd.
  Thanks to Samuel Thibault <sthibault@debian.org> (Closes: #654974)
* Fix FTBFS on arm
* New upstream snapshot, Closes: #650339, #643621, #481807
* Imported Upstream version 1.0~rc4+svn34492
* Bump standards version
* Bump dependency on libav >= 4:0.8~, Closes: #653887
* Fix build-indep
* Build mplayer-gui again, Closes: #568514
* Drop debian/all-lang-config-mak.sh, no longer needed
* include .dfsg1 in version number
* remove get-orig-source target
* no longer prune compiler flags from the environment
* No longer advertise nor build 3fdx, mga and dxr3 backends,
  Closes: #496106, #442181, #533546
* beautify mplayer version identification string
* Brown paperbag upload.
* Next try to fix build failure on sparce after recent binutils change.
* Brown paperbag upload.
* Really fix build failure on sparc after recent binutils change.
* Properly set Replaces/Conflicts on mplayer2{,-dbg} to avoid
  file overwrite errors.
* Adjust versioning of mplayer listed in the mplayer-dbg's Depends field.
* Fix build failure on sparc after recent binutils change.
* Urgency medium bumped because of RC-level bugfix
  and speeding up x264 transition.
* Update to my @debian.org email.
* Upload to unstable
* Enable joystick support on Linux only, Closes: #638408
* Rebuild fixes toolchain issue on arm, Closes: #637077
* New upstream snapshot
* following the discussion started by Diego Biurrun <diego@biurrun.de>
  in debian-devel, I have prepared a new packaging of 'mplayer'
  (with code that comes from CVS)
* the upstream tar.bz cannot be distributed by Debian, since it contains
   CSS code; so I am repackaging it 
* I have tried my best to address all known issues:
  - the package contains the detailed Copyright made by Diego Biurrun 
  - the package does not contain CSS code, or  AFAIK other code on which 
     there is active patent enforcement
  - there is a script  debian/cvs-changelog.sh  that shows all changes
     done to files included in this source.
    This should comply with GPLv2 sec 2.a  (in spirit if not in letter)
    For this reason, the source code contains CVS directories.
* needs   make (>= 3.80) for 'html-chunked-$(1)' in DOCS/xml/Makefile

* some corrections, as suggested Diego Biurrun
  - binary codecs should go into /usr/lib/codecs (upstream default)
  - better template 'mplayer/install_codecs'
  - an empty 'font=' in mplayer.conf breaks mplayer: postinst corrected
* correction in 'mplayer/cfgnote'
* better mplayer.postinst and mplayer.config

* New upstream release
* better debian/copyright file
* do not ship a skin
* New upstream release
* changed DEB_BUILD_OPTIONS to DEB_BUILD_CONFIGURE ,
  DEB_BUILD_OPTIONS is used as in debian policy
* use gcc-3.4
* changed xlibs-dev to a long list of dependencies, for Debian/etch
* try to adhere to  http://www.mplayerhq.hu/DOCS/tech/binary-packaging.txt
  (see README.Debian for details)
* removed dependency on xlibmesa-dev, disabled opengl
* New upstream release
* Simon McVittie <hacks@pseudorandom.co.uk> wonderful work:
- Work around Debian bug #267442 (glibc's sys/uio.h and gcc's altivec.h have
  conflicting uses for __vector) by re-ordering #includes
- Fix potential symlink attack in ./configure
- Disable support for binary codecs on platforms for which those codecs
  aren't available; also disable the corresponding Debconf note when it's
  inappropriate
- Changed Build-Depends: so it works in pbuilder
- Explicitly build-depend on libjpeg62-dev, libfontconfig1-dev,
  libungif4-dev 
- Tweak debian/rules to avoid certain errors being ignored
- Use --language=all
* provide a target  'debian/rules get-orig-source' 
  that recreates the orig.tar.gz ; then use the above orig.tar.gz
* rewrote some parts of debian/rules
* don't clean and recompile docs if upstream ships them
* mplayer-doc was shipping too much stuff
* translated man pages where not installed properly
* compile with libdv4-dev
* correct README.Debian
* Forgot build-dep on libtheora
* Must not depend on libxvidcore
* New upstream release
* new release.
* rc1 to become 0.90
* new pre-release
* new pre-release
* gtk bug fixed.
* new release.
* version bumped
* 0.60 pre2 release
* 0.60 pre-release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
 * Flash Screen Video decoder
26
26
 * @author Alex Beregszaszi
27
27
 * @author Benjamin Larsson
28
 
 */
29
 
 
30
 
/* Bitstream description
31
 
 * The picture is divided into blocks that are zlib compressed.
32
 
 *
33
 
 * The decoder is fed complete frames, the frameheader contains:
34
 
 * 4bits of block width
35
 
 * 12bits of frame width
36
 
 * 4bits of block height
37
 
 * 12bits of frame height
38
 
 *
39
 
 * Directly after the header are the compressed blocks. The blocks
40
 
 * have their compressed size represented with 16bits in the beginnig.
41
 
 * If the size = 0 then the block is unchanged from the previous frame.
42
 
 * All blocks are decompressed until the buffer is consumed.
43
 
 *
44
 
 * Encoding ideas, a basic encoder would just use a fixed block size.
45
 
 * Block sizes can be multipels of 16, from 16 to 256. The blocks don't
46
 
 * have to be quadratic. A brute force search with a set of diffrent
47
 
 * block sizes should give a better result then to just use a fixed size.
 
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.
48
34
 */
49
35
 
50
36
#include <stdio.h>
51
37
#include <stdlib.h>
52
38
#include <zlib.h>
53
39
 
 
40
#include "libavutil/intreadwrite.h"
54
41
#include "avcodec.h"
 
42
#include "bytestream.h"
55
43
#include "get_bits.h"
56
44
 
 
45
typedef struct BlockInfo {
 
46
    uint8_t *pos;
 
47
    int      size;
 
48
    int      unp_size;
 
49
} BlockInfo;
 
50
 
57
51
typedef struct FlashSVContext {
58
52
    AVCodecContext *avctx;
59
53
    AVFrame         frame;
62
56
    uint8_t        *tmpblock;
63
57
    int             block_size;
64
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;
65
70
} FlashSVContext;
66
71
 
67
72
 
68
 
static void copy_region(uint8_t *sptr, uint8_t *dptr,
69
 
                        int dx, int dy, int h, int w, int stride)
 
73
static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
 
74
                         int h, int w, int stride, const uint32_t *pal)
70
75
{
71
 
    int i;
 
76
    int x, y;
 
77
    const uint8_t *orig_src = sptr;
72
78
 
73
 
    for (i = dx + h; i > dx; i--) {
74
 
        memcpy(dptr + (i * stride) + dy * 3, sptr, w * 3);
75
 
        sptr += w * 3;
 
79
    for (y = dx+h; y > dx; y--) {
 
80
        uint8_t *dst = dptr + (y * stride) + dy * 3;
 
81
        for (x = 0; x < w; x++) {
 
82
            if (*sptr & 0x80) {
 
83
                /* 15-bit color */
 
84
                unsigned c = AV_RB16(sptr) & ~0x8000;
 
85
                unsigned b =  c        & 0x1F;
 
86
                unsigned g = (c >>  5) & 0x1F;
 
87
                unsigned r =  c >> 10;
 
88
                /* 000aaabb -> aaabbaaa  */
 
89
                *dst++ = (b << 3) | (b >> 2);
 
90
                *dst++ = (g << 3) | (g >> 2);
 
91
                *dst++ = (r << 3) | (r >> 2);
 
92
                sptr += 2;
 
93
            } else {
 
94
                /* palette index */
 
95
                uint32_t c = pal[*sptr++];
 
96
                bytestream_put_le24(&dst, c);
 
97
            }
 
98
        }
76
99
    }
 
100
    return sptr - orig_src;
77
101
}
78
102
 
79
 
 
80
103
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
81
104
{
82
105
    FlashSVContext *s = avctx->priv_data;
86
109
    s->zstream.zalloc = Z_NULL;
87
110
    s->zstream.zfree  = Z_NULL;
88
111
    s->zstream.opaque = Z_NULL;
89
 
    zret = inflateInit(&(s->zstream));
 
112
    zret = inflateInit(&s->zstream);
90
113
    if (zret != Z_OK) {
91
114
        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
92
115
        return 1;
98
121
}
99
122
 
100
123
 
 
124
static void flashsv2_prime(FlashSVContext *s, uint8_t *src,
 
125
                           int size, int unp_size)
 
126
{
 
127
    z_stream zs;
 
128
 
 
129
    zs.zalloc = NULL;
 
130
    zs.zfree  = NULL;
 
131
    zs.opaque = NULL;
 
132
 
 
133
    s->zstream.next_in   = src;
 
134
    s->zstream.avail_in  = size;
 
135
    s->zstream.next_out  = s->tmpblock;
 
136
    s->zstream.avail_out = s->block_size * 3;
 
137
    inflate(&s->zstream, Z_SYNC_FLUSH);
 
138
 
 
139
    deflateInit(&zs, 0);
 
140
    zs.next_in   = s->tmpblock;
 
141
    zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
 
142
    zs.next_out  = s->deflate_block;
 
143
    zs.avail_out = s->deflate_block_size;
 
144
    deflate(&zs, Z_SYNC_FLUSH);
 
145
    deflateEnd(&zs);
 
146
 
 
147
    inflateReset(&s->zstream);
 
148
 
 
149
    s->zstream.next_in   = s->deflate_block;
 
150
    s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
 
151
    s->zstream.next_out  = s->tmpblock;
 
152
    s->zstream.avail_out = s->block_size * 3;
 
153
    inflate(&s->zstream, Z_SYNC_FLUSH);
 
154
}
 
155
 
 
156
static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
 
157
                                GetBitContext *gb, int block_size,
 
158
                                int width, int height, int x_pos, int y_pos,
 
159
                                int blk_idx)
 
160
{
 
161
    struct FlashSVContext *s = avctx->priv_data;
 
162
    uint8_t *line = s->tmpblock;
 
163
    int k;
 
164
    int ret = inflateReset(&s->zstream);
 
165
    if (ret != Z_OK) {
 
166
        //return -1;
 
167
    }
 
168
    if (s->zlibprime_curr || s->zlibprime_prev) {
 
169
        flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size,
 
170
                       s->blocks[blk_idx].unp_size);
 
171
    }
 
172
    s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
 
173
    s->zstream.avail_in  = block_size;
 
174
    s->zstream.next_out  = s->tmpblock;
 
175
    s->zstream.avail_out = s->block_size * 3;
 
176
    ret = inflate(&s->zstream, Z_FINISH);
 
177
    if (ret == Z_DATA_ERROR) {
 
178
        av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
 
179
        inflateSync(&s->zstream);
 
180
        ret = inflate(&s->zstream, Z_FINISH);
 
181
    }
 
182
 
 
183
    if (ret != Z_OK && ret != Z_STREAM_END) {
 
184
        //return -1;
 
185
    }
 
186
 
 
187
    if (s->is_keyframe) {
 
188
        s->blocks[blk_idx].pos      = s->keyframedata + (get_bits_count(gb) / 8);
 
189
        s->blocks[blk_idx].size     = block_size;
 
190
        s->blocks[blk_idx].unp_size = s->block_size * 3 - s->zstream.avail_out;
 
191
    }
 
192
    if (!s->color_depth) {
 
193
        /* Flash Screen Video stores the image upside down, so copy
 
194
         * lines to destination in reverse order. */
 
195
        for (k = 1; k <= s->diff_height; k++) {
 
196
            memcpy(s->frame.data[0] + x_pos * 3 +
 
197
                   (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
 
198
                   line, width * 3);
 
199
            /* advance source pointer to next line */
 
200
            line += width * 3;
 
201
        }
 
202
    } else {
 
203
        /* hybrid 15-bit/palette mode */
 
204
        decode_hybrid(s->tmpblock, s->frame.data[0],
 
205
                      s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
 
206
                      x_pos, s->diff_height, width,
 
207
                      s->frame.linesize[0], s->pal);
 
208
    }
 
209
    skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
 
210
    return 0;
 
211
}
 
212
 
 
213
static int calc_deflate_block_size(int tmpblock_size)
 
214
{
 
215
    z_stream zstream;
 
216
    int size;
 
217
 
 
218
    zstream.zalloc = Z_NULL;
 
219
    zstream.zfree  = Z_NULL;
 
220
    zstream.opaque = Z_NULL;
 
221
    if (deflateInit(&zstream, 0) != Z_OK)
 
222
        return -1;
 
223
    size = deflateBound(&zstream, tmpblock_size);
 
224
    deflateEnd(&zstream);
 
225
 
 
226
    return size;
 
227
}
 
228
 
101
229
static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
102
230
                                int *data_size, AVPacket *avpkt)
103
231
{
104
 
    const uint8_t *buf = avpkt->data;
105
232
    int buf_size       = avpkt->size;
106
233
    FlashSVContext *s  = avctx->priv_data;
107
234
    int h_blocks, v_blocks, h_part, v_part, i, j;
113
240
    if (buf_size < 4)
114
241
        return -1;
115
242
 
116
 
    init_get_bits(&gb, buf, buf_size * 8);
 
243
    init_get_bits(&gb, avpkt->data, buf_size * 8);
117
244
 
118
245
    /* start to parse the bitstream */
119
246
    s->block_width  = 16 * (get_bits(&gb,  4) + 1);
121
248
    s->block_height = 16 * (get_bits(&gb,  4) + 1);
122
249
    s->image_height =       get_bits(&gb, 12);
123
250
 
124
 
    /* calculate amount of blocks and the size of the border blocks */
 
251
    if (s->ver == 2) {
 
252
        skip_bits(&gb, 6);
 
253
        if (get_bits1(&gb)) {
 
254
            av_log_missing_feature(avctx, "iframe", 1);
 
255
            return AVERROR_PATCHWELCOME;
 
256
        }
 
257
        if (get_bits1(&gb)) {
 
258
            av_log_missing_feature(avctx, "custom palette", 1);
 
259
            return AVERROR_PATCHWELCOME;
 
260
        }
 
261
    }
 
262
 
 
263
    /* calculate number of blocks and size of border (partial) blocks */
125
264
    h_blocks = s->image_width  / s->block_width;
126
265
    h_part   = s->image_width  % s->block_width;
127
266
    v_blocks = s->image_height / s->block_height;
130
269
    /* the block size could change between frames, make sure the buffer
131
270
     * is large enough, if not, get a larger one */
132
271
    if (s->block_size < s->block_width * s->block_height) {
133
 
        av_free(s->tmpblock);
134
 
        if ((s->tmpblock = av_malloc(3 * s->block_width * s->block_height)) == NULL) {
 
272
        int tmpblock_size = 3 * s->block_width * s->block_height;
 
273
 
 
274
        s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
 
275
        if (!s->tmpblock) {
135
276
            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
136
277
            return AVERROR(ENOMEM);
137
278
        }
 
279
        if (s->ver == 2) {
 
280
            s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
 
281
            if (s->deflate_block_size <= 0) {
 
282
                av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
 
283
                return -1;
 
284
            }
 
285
            s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
 
286
            if (!s->deflate_block) {
 
287
                av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
 
288
                return AVERROR(ENOMEM);
 
289
            }
 
290
        }
138
291
    }
139
292
    s->block_size = s->block_width * s->block_height;
140
293
 
141
 
    /* init the image size once */
142
 
    if ((avctx->width == 0) && (avctx->height == 0)) {
 
294
    /* initialize the image size once */
 
295
    if (avctx->width == 0 && avctx->height == 0) {
143
296
        avctx->width  = s->image_width;
144
297
        avctx->height = s->image_height;
145
298
    }
146
299
 
147
300
    /* check for changes of image width and image height */
148
 
    if ((avctx->width != s->image_width) || (avctx->height != s->image_height)) {
149
 
        av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frames!\n");
150
 
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n", avctx->height,
151
 
        avctx->width, s->image_height, s->image_width);
152
 
        return -1;
153
 
    }
154
 
 
155
 
    av_log(avctx, AV_LOG_DEBUG, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
156
 
           s->image_width, s->image_height, s->block_width, s->block_height,
157
 
           h_blocks, v_blocks, h_part, v_part);
158
 
 
159
 
    s->frame.reference    = 1;
160
 
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
 
301
    if (avctx->width != s->image_width || avctx->height != s->image_height) {
 
302
        av_log(avctx, AV_LOG_ERROR,
 
303
               "Frame width or height differs from first frame!\n");
 
304
        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
 
305
               avctx->height, avctx->width, s->image_height, s->image_width);
 
306
        return AVERROR_INVALIDDATA;
 
307
    }
 
308
 
 
309
    /* we care for keyframes only in Screen Video v2 */
 
310
    s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
 
311
    if (s->is_keyframe) {
 
312
        s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
 
313
        memcpy(s->keyframedata, avpkt->data, avpkt->size);
 
314
        s->blocks = av_realloc(s->blocks,
 
315
                               (v_blocks + !!v_part) * (h_blocks + !!h_part)
 
316
                               * sizeof(s->blocks[0]));
 
317
    }
 
318
 
 
319
    av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
 
320
            s->image_width, s->image_height, s->block_width, s->block_height,
 
321
            h_blocks, v_blocks, h_part, v_part);
 
322
 
 
323
    s->frame.reference    = 3;
 
324
    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |
 
325
                            FF_BUFFER_HINTS_PRESERVE |
 
326
                            FF_BUFFER_HINTS_REUSABLE;
161
327
    if (avctx->reget_buffer(avctx, &s->frame) < 0) {
162
328
        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
163
329
        return -1;
166
332
    /* loop over all block columns */
167
333
    for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
168
334
 
169
 
        int hp = j * s->block_height; // horiz position in frame
170
 
        int hs = (j < v_blocks) ? s->block_height : v_part; // size of block
171
 
 
 
335
        int y_pos  = j * s->block_height; // vertical position in frame
 
336
        int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
172
337
 
173
338
        /* loop over all block rows */
174
339
        for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
175
 
            int wp = i * s->block_width; // vert position in frame
176
 
            int ws = (i < h_blocks) ? s->block_width : h_part; // size of block
 
340
            int x_pos = i * s->block_width; // horizontal position in frame
 
341
            int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
 
342
            int has_diff = 0;
177
343
 
178
344
            /* get the size of the compressed zlib chunk */
179
345
            int size = get_bits(&gb, 16);
 
346
 
 
347
            s->color_depth    = 0;
 
348
            s->zlibprime_curr = 0;
 
349
            s->zlibprime_prev = 0;
 
350
            s->diff_start     = 0;
 
351
            s->diff_height    = cur_blk_height;
 
352
 
180
353
            if (8 * size > get_bits_left(&gb)) {
181
354
                avctx->release_buffer(avctx, &s->frame);
182
355
                s->frame.data[0] = NULL;
183
 
                return -1;
184
 
            }
185
 
 
186
 
            if (size == 0) {
187
 
                /* no change, don't do anything */
188
 
            } else {
189
 
                /* decompress block */
190
 
                int ret = inflateReset(&(s->zstream));
191
 
                if (ret != Z_OK) {
192
 
                    av_log(avctx, AV_LOG_ERROR, "error in decompression (reset) of block %dx%d\n", i, j);
193
 
                    /* return -1; */
194
 
                }
195
 
                s->zstream.next_in   = buf + (get_bits_count(&gb) / 8);
196
 
                s->zstream.avail_in  = size;
197
 
                s->zstream.next_out  = s->tmpblock;
198
 
                s->zstream.avail_out = s->block_size * 3;
199
 
                ret = inflate(&(s->zstream), Z_FINISH);
200
 
                if (ret == Z_DATA_ERROR) {
201
 
                    av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
202
 
                    inflateSync(&(s->zstream));
203
 
                    ret = inflate(&(s->zstream), Z_FINISH);
204
 
                }
205
 
 
206
 
                if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
207
 
                    av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d: %d\n", i, j, ret);
208
 
                    /* return -1; */
209
 
                }
210
 
                copy_region(s->tmpblock, s->frame.data[0], s->image_height - (hp + hs + 1),
211
 
                            wp, hs, ws, s->frame.linesize[0]);
212
 
                skip_bits_long(&gb, 8 * size);   /* skip the consumed bits */
213
 
            }
214
 
        }
 
356
                return AVERROR_INVALIDDATA;
 
357
            }
 
358
 
 
359
            if (s->ver == 2 && size) {
 
360
                skip_bits(&gb, 3);
 
361
                s->color_depth    = get_bits(&gb, 2);
 
362
                has_diff          = get_bits1(&gb);
 
363
                s->zlibprime_curr = get_bits1(&gb);
 
364
                s->zlibprime_prev = get_bits1(&gb);
 
365
 
 
366
                if (s->color_depth != 0 && s->color_depth != 2) {
 
367
                    av_log(avctx, AV_LOG_ERROR,
 
368
                           "%dx%d invalid color depth %d\n", i, j, s->color_depth);
 
369
                    return AVERROR_INVALIDDATA;
 
370
                }
 
371
 
 
372
                if (has_diff) {
 
373
                    s->diff_start  = get_bits(&gb, 8);
 
374
                    s->diff_height = get_bits(&gb, 8);
 
375
                    av_log(avctx, AV_LOG_DEBUG,
 
376
                           "%dx%d diff start %d height %d\n",
 
377
                           i, j, s->diff_start, s->diff_height);
 
378
                    size -= 2;
 
379
                }
 
380
 
 
381
                if (s->zlibprime_prev)
 
382
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
 
383
 
 
384
                if (s->zlibprime_curr) {
 
385
                    int col = get_bits(&gb, 8);
 
386
                    int row = get_bits(&gb, 8);
 
387
                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
 
388
                    size -= 2;
 
389
                    av_log_missing_feature(avctx, "zlibprime_curr", 1);
 
390
                    return AVERROR_PATCHWELCOME;
 
391
                }
 
392
                size--; // account for flags byte
 
393
            }
 
394
 
 
395
            if (has_diff) {
 
396
                int k;
 
397
                int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
 
398
 
 
399
                for (k = 0; k < cur_blk_height; k++)
 
400
                    memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
 
401
                           s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
 
402
                           cur_blk_width * 3);
 
403
            }
 
404
 
 
405
            /* skip unchanged blocks, which have size 0 */
 
406
            if (size) {
 
407
                if (flashsv_decode_block(avctx, avpkt, &gb, size,
 
408
                                         cur_blk_width, cur_blk_height,
 
409
                                         x_pos, y_pos,
 
410
                                         i + j * (h_blocks + !!h_part)))
 
411
                    av_log(avctx, AV_LOG_ERROR,
 
412
                           "error in decompression of block %dx%d\n", i, j);
 
413
            }
 
414
        }
 
415
    }
 
416
    if (s->is_keyframe && s->ver == 2) {
 
417
        if (!s->keyframe) {
 
418
            s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
 
419
            if (!s->keyframe) {
 
420
                av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
 
421
                return AVERROR(ENOMEM);
 
422
            }
 
423
        }
 
424
        memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
215
425
    }
216
426
 
217
427
    *data_size = sizeof(AVFrame);
229
439
static av_cold int flashsv_decode_end(AVCodecContext *avctx)
230
440
{
231
441
    FlashSVContext *s = avctx->priv_data;
232
 
    inflateEnd(&(s->zstream));
 
442
    inflateEnd(&s->zstream);
233
443
    /* release the frame if needed */
234
444
    if (s->frame.data[0])
235
445
        avctx->release_buffer(avctx, &s->frame);
241
451
}
242
452
 
243
453
 
 
454
#if CONFIG_FLASHSV_DECODER
244
455
AVCodec ff_flashsv_decoder = {
245
456
    .name           = "flashsv",
246
457
    .type           = AVMEDIA_TYPE_VIDEO,
253
464
    .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
254
465
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
255
466
};
 
467
#endif /* CONFIG_FLASHSV_DECODER */
 
468
 
 
469
#if CONFIG_FLASHSV2_DECODER
 
470
static const uint32_t ff_flashsv2_default_palette[128] = {
 
471
    0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
 
472
    0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
 
473
    0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
 
474
    0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
 
475
    0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
 
476
    0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
 
477
    0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
 
478
    0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
 
479
    0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
 
480
    0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
 
481
    0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
 
482
    0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
 
483
    0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
 
484
    0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
 
485
    0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
 
486
    0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
 
487
    0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
 
488
    0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
 
489
    0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
 
490
    0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
 
491
    0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
 
492
    0xDDDDDD, 0xEEEEEE
 
493
};
 
494
 
 
495
static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
 
496
{
 
497
    FlashSVContext *s = avctx->priv_data;
 
498
    flashsv_decode_init(avctx);
 
499
    s->pal = ff_flashsv2_default_palette;
 
500
    s->ver = 2;
 
501
 
 
502
    return 0;
 
503
}
 
504
 
 
505
static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
 
506
{
 
507
    FlashSVContext *s = avctx->priv_data;
 
508
 
 
509
    av_freep(&s->keyframedata);
 
510
    av_freep(&s->blocks);
 
511
    av_freep(&s->keyframe);
 
512
    av_freep(&s->deflate_block);
 
513
    flashsv_decode_end(avctx);
 
514
 
 
515
    return 0;
 
516
}
 
517
 
 
518
AVCodec ff_flashsv2_decoder = {
 
519
    .name           = "flashsv2",
 
520
    .type           = AVMEDIA_TYPE_VIDEO,
 
521
    .id             = CODEC_ID_FLASHSV2,
 
522
    .priv_data_size = sizeof(FlashSVContext),
 
523
    .init           = flashsv2_decode_init,
 
524
    .close          = flashsv2_decode_end,
 
525
    .decode         = flashsv_decode_frame,
 
526
    .capabilities   = CODEC_CAP_DR1,
 
527
    .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
 
528
    .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
 
529
};
 
530
#endif /* CONFIG_FLASHSV2_DECODER */