Libav
flashsv.c
Go to the documentation of this file.
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 Libav.
7  *
8  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
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 {
48  int size;
49 } BlockInfo;
50 
51 typedef struct FlashSVContext {
58  z_stream zstream;
59  int ver;
60  const uint32_t *pal;
71 
72 static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
73  int h, int w, int stride, const uint32_t *pal)
74 {
75  int x, y;
76  const uint8_t *orig_src = sptr;
77 
78  for (y = dx + h; y > dx; y--) {
79  uint8_t *dst = dptr + (y * stride) + dy * 3;
80  for (x = 0; x < w; x++) {
81  if (*sptr & 0x80) {
82  /* 15-bit color */
83  unsigned c = AV_RB16(sptr) & ~0x8000;
84  unsigned b = c & 0x1F;
85  unsigned g = (c >> 5) & 0x1F;
86  unsigned r = c >> 10;
87  /* 000aaabb -> aaabbaaa */
88  *dst++ = (b << 3) | (b >> 2);
89  *dst++ = (g << 3) | (g >> 2);
90  *dst++ = (r << 3) | (r >> 2);
91  sptr += 2;
92  } else {
93  /* palette index */
94  uint32_t c = pal[*sptr++];
95  bytestream_put_le24(&dst, c);
96  }
97  }
98  }
99  return sptr - orig_src;
100 }
101 
103 {
104  FlashSVContext *s = avctx->priv_data;
105  inflateEnd(&s->zstream);
106  /* release the frame if needed */
107  av_frame_free(&s->frame);
108 
109  /* free the tmpblock */
110  av_free(s->tmpblock);
111 
112  return 0;
113 }
114 
116 {
117  FlashSVContext *s = avctx->priv_data;
118  int zret; // Zlib return code
119 
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  if (zret != Z_OK) {
126  av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
127  return 1;
128  }
129  avctx->pix_fmt = AV_PIX_FMT_BGR24;
130 
131  s->frame = av_frame_alloc();
132  if (!s->frame) {
133  flashsv_decode_end(avctx);
134  return AVERROR(ENOMEM);
135  }
136 
137  return 0;
138 }
139 
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  zs.zalloc = NULL;
146  zs.zfree = NULL;
147  zs.opaque = NULL;
148 
149  s->zstream.next_in = src;
150  s->zstream.avail_in = size;
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  deflateInit(&zs, 0);
156  zs.next_in = s->tmpblock;
157  zs.avail_in = s->block_size * 3 - s->zstream.avail_out;
158  zs.next_out = s->deflate_block;
159  zs.avail_out = s->deflate_block_size;
160  deflate(&zs, Z_SYNC_FLUSH);
161  deflateEnd(&zs);
162 
163  if ((zret = inflateReset(&s->zstream)) != Z_OK) {
164  av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
165  return AVERROR_UNKNOWN;
166  }
167 
168  s->zstream.next_in = s->deflate_block;
169  s->zstream.avail_in = s->deflate_block_size - zs.avail_out;
170  s->zstream.next_out = s->tmpblock;
171  s->zstream.avail_out = s->block_size * 3;
172  inflate(&s->zstream, Z_SYNC_FLUSH);
173 
174  return 0;
175 }
176 
177 static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
178  GetBitContext *gb, int block_size,
179  int width, int height, int x_pos, int y_pos,
180  int blk_idx)
181 {
182  struct FlashSVContext *s = avctx->priv_data;
183  uint8_t *line = s->tmpblock;
184  int k;
185  int ret = inflateReset(&s->zstream);
186  if (ret != Z_OK) {
187  av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
188  return AVERROR_UNKNOWN;
189  }
190  if (s->zlibprime_curr || s->zlibprime_prev) {
191  ret = flashsv2_prime(s,
192  s->blocks[blk_idx].pos,
193  s->blocks[blk_idx].size);
194  if (ret < 0)
195  return ret;
196  }
197  s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8;
198  s->zstream.avail_in = block_size;
199  s->zstream.next_out = s->tmpblock;
200  s->zstream.avail_out = s->block_size * 3;
201  ret = inflate(&s->zstream, Z_FINISH);
202  if (ret == Z_DATA_ERROR) {
203  av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
204  inflateSync(&s->zstream);
205  ret = inflate(&s->zstream, Z_FINISH);
206  }
207 
208  if (ret != Z_OK && ret != Z_STREAM_END) {
209  //return -1;
210  }
211 
212  if (s->is_keyframe) {
213  s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8);
214  s->blocks[blk_idx].size = block_size;
215  }
216 
217  y_pos += s->diff_start;
218 
219  if (!s->color_depth) {
220  /* Flash Screen Video stores the image upside down, so copy
221  * lines to destination in reverse order. */
222  for (k = 1; k <= s->diff_height; k++) {
223  memcpy(s->frame->data[0] + x_pos * 3 +
224  (s->image_height - y_pos - k) * s->frame->linesize[0],
225  line, width * 3);
226  /* advance source pointer to next line */
227  line += width * 3;
228  }
229  } else {
230  /* 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  skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
237  return 0;
238 }
239 
240 static int calc_deflate_block_size(int tmpblock_size)
241 {
242  z_stream zstream;
243  int size;
244 
245  zstream.zalloc = Z_NULL;
246  zstream.zfree = Z_NULL;
247  zstream.opaque = Z_NULL;
248  if (deflateInit(&zstream, 0) != Z_OK)
249  return -1;
250  size = deflateBound(&zstream, tmpblock_size);
251  deflateEnd(&zstream);
252 
253  return size;
254 }
255 
257  int *got_frame, AVPacket *avpkt)
258 {
259  int buf_size = avpkt->size;
260  FlashSVContext *s = avctx->priv_data;
261  int h_blocks, v_blocks, h_part, v_part, i, j, ret;
262  GetBitContext gb;
263 
264  /* no supplementary picture */
265  if (buf_size == 0)
266  return 0;
267  if (buf_size < 4)
268  return -1;
269 
270  init_get_bits(&gb, avpkt->data, buf_size * 8);
271 
272  /* start to parse the bitstream */
273  s->block_width = 16 * (get_bits(&gb, 4) + 1);
274  s->image_width = get_bits(&gb, 12);
275  s->block_height = 16 * (get_bits(&gb, 4) + 1);
276  s->image_height = get_bits(&gb, 12);
277 
278  if (s->ver == 2) {
279  skip_bits(&gb, 6);
280  if (get_bits1(&gb)) {
281  avpriv_request_sample(avctx, "iframe");
282  return AVERROR_PATCHWELCOME;
283  }
284  if (get_bits1(&gb)) {
285  avpriv_request_sample(avctx, "Custom palette");
286  return AVERROR_PATCHWELCOME;
287  }
288  }
289 
290  /* calculate number of blocks and size of border (partial) blocks */
291  h_blocks = s->image_width / s->block_width;
292  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  /* the block size could change between frames, make sure the buffer
297  * 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  if ((err = av_reallocp(&s->tmpblock, tmpblock_size)) < 0) {
302  s->block_size = 0;
303  av_log(avctx, AV_LOG_ERROR,
304  "Cannot allocate decompression buffer.\n");
305  return err;
306  }
307  if (s->ver == 2) {
308  s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
309  if (s->deflate_block_size <= 0) {
310  av_log(avctx, AV_LOG_ERROR,
311  "Cannot determine deflate buffer size.\n");
312  return -1;
313  }
314  if ((err = av_reallocp(&s->deflate_block, s->deflate_block_size)) < 0) {
315  s->block_size = 0;
316  av_log(avctx, AV_LOG_ERROR, "Cannot allocate deflate buffer.\n");
317  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  avctx->height = s->image_height;
327  }
328 
329  /* 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  av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n",
334  avctx->height, avctx->width, s->image_height, s->image_width);
335  return AVERROR_INVALIDDATA;
336  }
337 
338  /* we care for keyframes only in Screen Video v2 */
339  s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
340  if (s->is_keyframe) {
341  int err;
342  if ((err = av_reallocp(&s->keyframedata, avpkt->size)) < 0)
343  return err;
344  memcpy(s->keyframedata, avpkt->data, avpkt->size);
345  if ((err = av_reallocp(&s->blocks, (v_blocks + !!v_part) *
346  (h_blocks + !!h_part) * sizeof(s->blocks[0]))) < 0)
347  return err;
348  }
349 
350  av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
352  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  int y_pos = j * s->block_height; // vertical position in frame
363  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  int x_pos = i * s->block_width; // horizontal position in frame
368  int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
369  int has_diff = 0;
370 
371  /* get the size of the compressed zlib chunk */
372  int size = get_bits(&gb, 16);
373 
374  s->color_depth = 0;
375  s->zlibprime_curr = 0;
376  s->zlibprime_prev = 0;
377  s->diff_start = 0;
378  s->diff_height = cur_blk_height;
379 
380  if (8 * size > get_bits_left(&gb)) {
381  av_frame_unref(s->frame);
382  return AVERROR_INVALIDDATA;
383  }
384 
385  if (s->ver == 2 && size) {
386  skip_bits(&gb, 3);
387  s->color_depth = get_bits(&gb, 2);
388  has_diff = get_bits1(&gb);
389  s->zlibprime_curr = get_bits1(&gb);
390  s->zlibprime_prev = get_bits1(&gb);
391 
392  if (s->color_depth != 0 && s->color_depth != 2) {
393  av_log(avctx, AV_LOG_ERROR,
394  "%dx%d invalid color depth %d\n",
395  i, j, s->color_depth);
396  return AVERROR_INVALIDDATA;
397  }
398 
399  if (has_diff) {
400  if (!s->keyframe) {
401  av_log(avctx, AV_LOG_ERROR,
402  "Inter frame without keyframe\n");
403  return AVERROR_INVALIDDATA;
404  }
405  s->diff_start = get_bits(&gb, 8);
406  s->diff_height = get_bits(&gb, 8);
407  if (s->diff_start + s->diff_height > cur_blk_height) {
408  av_log(avctx, AV_LOG_ERROR,
409  "Block parameters invalid: %d + %d > %d\n",
410  s->diff_start, s->diff_height, cur_blk_height);
411  return AVERROR_INVALIDDATA;
412  }
413  av_log(avctx, AV_LOG_DEBUG,
414  "%dx%d diff start %d height %d\n",
415  i, j, s->diff_start, s->diff_height);
416  size -= 2;
417  }
418 
419  if (s->zlibprime_prev)
420  av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
421 
422  if (s->zlibprime_curr) {
423  int col = get_bits(&gb, 8);
424  int row = get_bits(&gb, 8);
425  av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n",
426  i, j, col, row);
427  size -= 2;
428  avpriv_request_sample(avctx, "zlibprime_curr");
429  return AVERROR_PATCHWELCOME;
430  }
431  if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
432  av_log(avctx, AV_LOG_ERROR,
433  "no data available for zlib priming\n");
434  return AVERROR_INVALIDDATA;
435  }
436  size--; // account for flags byte
437  }
438 
439  if (has_diff) {
440  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  int x = off - k * s->frame->linesize[0] + x_pos * 3;
445  memcpy(s->frame->data[0] + x, s->keyframe + x,
446  cur_blk_width * 3);
447  }
448  }
449 
450  /* skip unchanged blocks, which have size 0 */
451  if (size) {
452  if (flashsv_decode_block(avctx, avpkt, &gb, size,
453  cur_blk_width, cur_blk_height,
454  x_pos, y_pos,
455  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  if (s->is_keyframe && s->ver == 2) {
462  if (!s->keyframe) {
463  s->keyframe = av_malloc(s->frame->linesize[0] * avctx->height);
464  if (!s->keyframe) {
465  av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
466  return AVERROR(ENOMEM);
467  }
468  }
469  memcpy(s->keyframe, s->frame->data[0],
470  s->frame->linesize[0] * avctx->height);
471  }
472 
473  if ((ret = av_frame_ref(data, s->frame)) < 0)
474  return ret;
475 
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  /* report that the buffer was completely consumed */
483  return buf_size;
484 }
485 
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  .priv_data_size = sizeof(FlashSVContext),
496  .capabilities = CODEC_CAP_DR1,
497  .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
498 };
499 #endif /* CONFIG_FLASHSV_DECODER */
500 
501 #if CONFIG_FLASHSV2_DECODER
502 static const uint32_t ff_flashsv2_default_palette[128] = {
503  0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
504  0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
505  0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
506  0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
507  0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
508  0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
509  0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
510  0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
511  0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
512  0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
513  0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
514  0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
515  0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
516  0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
517  0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
518  0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
519  0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
520  0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
521  0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
522  0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
523  0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
524  0xDDDDDD, 0xEEEEEE
525 };
526 
527 static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
528 {
529  FlashSVContext *s = avctx->priv_data;
530  flashsv_decode_init(avctx);
531  s->pal = ff_flashsv2_default_palette;
532  s->ver = 2;
533 
534  return 0;
535 }
536 
537 static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
538 {
539  FlashSVContext *s = avctx->priv_data;
540 
541  av_freep(&s->keyframedata);
542  av_freep(&s->blocks);
543  av_freep(&s->keyframe);
544  av_freep(&s->deflate_block);
545  flashsv_decode_end(avctx);
546 
547  return 0;
548 }
549 
550 AVCodec ff_flashsv2_decoder = {
551  .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  .priv_data_size = sizeof(FlashSVContext),
556  .init = flashsv2_decode_init,
557  .close = flashsv2_decode_end,
559  .capabilities = CODEC_CAP_DR1,
560  .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
561 };
562 #endif /* CONFIG_FLASHSV2_DECODER */