36#include "config_components.h"
73 uint8_t
tmp[UINT16_MAX];
76static int decode_hybrid(
const uint8_t *sptr,
const uint8_t *sptr_end, uint8_t *dptr,
int dx,
int dy,
77 int h,
int w,
int stride,
const uint32_t *pal)
80 const uint8_t *orig_src = sptr;
82 for (y = dx +
h; y > dx; y--) {
83 uint8_t *
dst = dptr + (y *
stride) + dy * 3;
84 for (x = 0; x <
w; x++) {
88 if (sptr + 2 > sptr_end)
91 unsigned c =
AV_RB16(sptr) & ~0x8000;
92 unsigned b =
c & 0x1F;
93 unsigned g = (
c >> 5) & 0x1F;
96 *
dst++ = (
b << 3) | (
b >> 2);
97 *
dst++ = (
g << 3) | (
g >> 2);
98 *
dst++ = (
r << 3) | (
r >> 2);
102 uint32_t
c = pal[*sptr++];
103 bytestream_put_le24(&
dst,
c);
107 return sptr - orig_src;
142 static const uint8_t zlib_header[] = { 0x78, 0x01 };
143 z_stream *
const zstream = &
s->zstream.zstream;
144 uint8_t *
data =
s->tmpblock;
150 zstream->next_in =
src;
151 zstream->avail_in =
size;
152 zstream->next_out =
data;
153 zstream->avail_out =
s->block_size * 3;
154 zret =
inflate(zstream, Z_SYNC_FLUSH);
155 if (zret != Z_OK && zret != Z_STREAM_END)
157 remaining =
s->block_size * 3 - zstream->avail_out;
159 if ((zret = inflateReset(zstream)) != Z_OK) {
170 zstream->next_in = zlib_header;
171 zstream->avail_in =
sizeof(zlib_header);
172 zret =
inflate(zstream, Z_SYNC_FLUSH);
175 while (remaining > 0) {
176 unsigned block_size =
FFMIN(UINT16_MAX, remaining);
184 zstream->next_in =
header;
185 zstream->avail_in =
sizeof(
header);
186 zstream->next_out =
s->tmp;
187 zstream->avail_out =
sizeof(
s->tmp);
188 zret =
inflate(zstream, Z_SYNC_FLUSH);
191 zstream->next_in =
data;
192 zstream->avail_in = block_size;
193 zret =
inflate(zstream, Z_SYNC_FLUSH);
197 remaining -= block_size;
209 z_stream *
const zstream = &
s->zstream.zstream;
210 uint8_t *
line =
s->tmpblock;
212 int ret = inflateReset(
zstream);
217 if (
s->zlibprime_curr ||
s->zlibprime_prev) {
219 s->blocks[blk_idx].pos,
220 s->blocks[blk_idx].size);
227 zstream->avail_out =
s->block_size * 3;
229 if (ret == Z_DATA_ERROR) {
235 if (
s->is_keyframe) {
240 y_pos +=
s->diff_start;
242 if (!
s->color_depth) {
243 int inflated =
s->block_size * 3 -
zstream->avail_out;
247 inflated,
width * 3 *
s->diff_height);
252 for (k = 1; k <=
s->diff_height; k++) {
253 memcpy(
s->frame->data[0] + x_pos * 3 +
254 (
s->image_height - y_pos - k) *
s->frame->linesize[0],
263 s->image_height - (y_pos + 1 +
s->diff_height),
264 x_pos,
s->diff_height,
width,
265 s->frame->linesize[0],
s->pal);
277 int buf_size = avpkt->
size;
279 int h_blocks, v_blocks, h_part, v_part,
i, j, ret;
281 int last_blockwidth =
s->block_width;
282 int last_blockheight=
s->block_height;
294 s->block_width = 16 * (
get_bits(&gb, 4) + 1);
296 s->block_height = 16 * (
get_bits(&gb, 4) + 1);
299 if ( last_blockwidth !=
s->block_width
300 || last_blockheight!=
s->block_height)
316 h_blocks =
s->image_width /
s->block_width;
317 h_part =
s->image_width %
s->block_width;
318 v_blocks =
s->image_height /
s->block_height;
319 v_part =
s->image_height %
s->block_height;
326 if (
s->block_size <
s->block_width *
s->block_height) {
327 int tmpblock_size = 3 *
s->block_width *
s->block_height, err;
329 if ((err =
av_reallocp(&
s->tmpblock, tmpblock_size)) < 0) {
332 "Cannot allocate decompression buffer.\n");
336 s->block_size =
s->block_width *
s->block_height;
347 "Frame width or height differs from first frame!\n");
355 if (
s->is_keyframe) {
359 s->keyframedata = avpkt->
data;
361 memset(
s->blocks, 0, (v_blocks + !!v_part) * (h_blocks + !!h_part) *
362 sizeof(
s->blocks[0]));
364 if(
s->ver == 2 && !
s->blocks)
365 s->blocks =
av_mallocz((v_blocks + !!v_part) * (h_blocks + !!h_part) *
366 sizeof(
s->blocks[0]));
368 ff_dlog(
avctx,
"image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
369 s->image_width,
s->image_height,
s->block_width,
s->block_height,
370 h_blocks, v_blocks, h_part, v_part);
376 for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
378 int y_pos = j *
s->block_height;
379 int cur_blk_height = (j < v_blocks) ?
s->block_height : v_part;
382 for (
i = 0;
i < h_blocks + (h_part ? 1 : 0);
i++) {
383 int x_pos =
i *
s->block_width;
384 int cur_blk_width = (
i < h_blocks) ?
s->block_width : h_part;
391 s->zlibprime_curr = 0;
392 s->zlibprime_prev = 0;
394 s->diff_height = cur_blk_height;
401 if (
s->ver == 2 &&
size) {
408 if (
s->color_depth != 0 &&
s->color_depth != 2) {
410 "%dx%d invalid color depth %d\n",
411 i, j,
s->color_depth);
422 "Inter frame without keyframe\n");
427 if (
s->diff_start +
s->diff_height > cur_blk_height) {
429 "Block parameters invalid: %d + %d > %d\n",
430 s->diff_start,
s->diff_height, cur_blk_height);
434 "%dx%d diff start %d height %d\n",
435 i, j,
s->diff_start,
s->diff_height);
439 if (
s->zlibprime_prev)
442 if (
s->zlibprime_curr) {
455 if (!
s->blocks && (
s->zlibprime_curr ||
s->zlibprime_prev)) {
457 "no data available for zlib priming\n");
465 int off = (
s->image_height - y_pos - 1) *
s->frame->linesize[0];
467 for (k = 0; k < cur_blk_height; k++) {
468 int x = off - k *
s->frame->linesize[0] + x_pos * 3;
469 memcpy(
s->frame->data[0] + x,
s->keyframe + x,
477 cur_blk_width, cur_blk_height,
479 i + j * (h_blocks + !!h_part)))
481 "error in decompression of block %dx%d\n",
i, j);
486 if (
s->is_keyframe &&
s->ver == 2) {
494 memcpy(
s->keyframe,
s->frame->data[0],
511#if CONFIG_FLASHSV_DECODER
526#if CONFIG_FLASHSV2_DECODER
527static const uint32_t ff_flashsv2_default_palette[128] = {
528 0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
529 0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
530 0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
531 0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
532 0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
533 0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
534 0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
535 0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
536 0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
537 0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
538 0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
539 0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
540 0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
541 0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
542 0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
543 0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
544 0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
545 0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
546 0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
547 0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
548 0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
560 s->pal = ff_flashsv2_default_palette;
571 s->keyframedata =
NULL;
580 .p.name =
"flashsv2",
585 .
init = flashsv2_decode_init,
586 .
close = flashsv2_decode_end,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
const FFCodec ff_flashsv2_decoder
const FFCodec ff_flashsv_decoder
static av_cold void close(AVCodecParserContext *s)
Libavcodec external API header.
#define i(width, name, range_min, range_max)
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Identical in function to ff_get_buffer(), except it reuses the existing buffer if available.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
int(* init)(AVBSFContext *ctx)
static int flashsv2_prime(FlashSVContext *s, const uint8_t *src, int size)
static av_cold int flashsv_decode_end(AVCodecContext *avctx)
static av_cold int flashsv_decode_init(AVCodecContext *avctx)
static int flashsv_decode_frame(AVCodecContext *avctx, AVFrame *rframe, int *got_frame, AVPacket *avpkt)
static int flashsv_decode_block(AVCodecContext *avctx, const AVPacket *avpkt, GetBitContext *gb, int block_size, int width, int height, int x_pos, int y_pos, int blk_idx)
static int decode_hybrid(const uint8_t *sptr, const uint8_t *sptr_end, uint8_t *dptr, int dx, int dy, int h, int w, int stride, const uint32_t *pal)
bitstream reader API header.
static int get_bits_left(GetBitContext *gb)
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
static unsigned int get_bits1(GetBitContext *s)
static void skip_bits(GetBitContext *s, int n)
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
static int get_bits_count(const GetBitContext *s)
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Memory handling functions.
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
static const uint8_t header[24]
A reference to a data buffer.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
int flags
A combination of AV_PKT_FLAG values.
AVBufferRef * keyframedata_buf
const uint8_t * keyframedata
#define avpriv_request_sample(...)
static void inflate(uint8_t *dst, const uint8_t *p1, int width, int threshold, const uint8_t *coordinates[], int coord, int maxc)
void ff_inflate_end(FFZStream *zstream)
Wrapper around inflateEnd().
int ff_inflate_init(FFZStream *zstream, void *logctx)
Wrapper around inflateInit().