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 
45 typedef struct BlockInfo {
47  int size;
48 } BlockInfo;
49 
50 typedef struct FlashSVContext {
57  z_stream zstream;
58  int ver;
59  const uint32_t *pal;
70 
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  int zret; // Zlib return code
106 
107  s->avctx = avctx;
108  s->zstream.zalloc = Z_NULL;
109  s->zstream.zfree = Z_NULL;
110  s->zstream.opaque = Z_NULL;
111  zret = inflateInit(&s->zstream);
112  if (zret != Z_OK) {
113  av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
114  return 1;
115  }
116  avctx->pix_fmt = AV_PIX_FMT_BGR24;
117  s->frame.data[0] = NULL;
118 
119  return 0;
120 }
121 
122 
123 static int flashsv2_prime(FlashSVContext *s, uint8_t *src, int size)
124 {
125  z_stream zs;
126  int zret; // Zlib return code
127 
128  zs.zalloc = NULL;
129  zs.zfree = NULL;
130  zs.opaque = NULL;
131 
132  s->zstream.next_in = src;
133  s->zstream.avail_in = size;
134  s->zstream.next_out = s->tmpblock;
135  s->zstream.avail_out = s->block_size * 3;
136  inflate(&s->zstream, Z_SYNC_FLUSH);
137 
138  deflateInit(&zs, 0);
139  zs.next_in = s->tmpblock;
140  zs.avail_in = s->block_size * 3 - s->zstream.avail_out;
141  zs.next_out = s->deflate_block;
142  zs.avail_out = s->deflate_block_size;
143  deflate(&zs, Z_SYNC_FLUSH);
144  deflateEnd(&zs);
145 
146  if ((zret = inflateReset(&s->zstream)) != Z_OK) {
147  av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
148  return AVERROR_UNKNOWN;
149  }
150 
151  s->zstream.next_in = s->deflate_block;
152  s->zstream.avail_in = s->deflate_block_size - zs.avail_out;
153  s->zstream.next_out = s->tmpblock;
154  s->zstream.avail_out = s->block_size * 3;
155  inflate(&s->zstream, Z_SYNC_FLUSH);
156 
157  return 0;
158 }
159 
160 static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
161  GetBitContext *gb, int block_size,
162  int width, int height, int x_pos, int y_pos,
163  int blk_idx)
164 {
165  struct FlashSVContext *s = avctx->priv_data;
166  uint8_t *line = s->tmpblock;
167  int k;
168  int ret = inflateReset(&s->zstream);
169  if (ret != Z_OK) {
170  av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
171  return AVERROR_UNKNOWN;
172  }
173  if (s->zlibprime_curr || s->zlibprime_prev) {
174  ret = flashsv2_prime(s,
175  s->blocks[blk_idx].pos,
176  s->blocks[blk_idx].size);
177  if (ret < 0)
178  return ret;
179  }
180  s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8;
181  s->zstream.avail_in = block_size;
182  s->zstream.next_out = s->tmpblock;
183  s->zstream.avail_out = s->block_size * 3;
184  ret = inflate(&s->zstream, Z_FINISH);
185  if (ret == Z_DATA_ERROR) {
186  av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
187  inflateSync(&s->zstream);
188  ret = inflate(&s->zstream, Z_FINISH);
189  }
190 
191  if (ret != Z_OK && ret != Z_STREAM_END) {
192  //return -1;
193  }
194 
195  if (s->is_keyframe) {
196  s->blocks[blk_idx].pos = s->keyframedata + (get_bits_count(gb) / 8);
197  s->blocks[blk_idx].size = block_size;
198  }
199  if (!s->color_depth) {
200  /* Flash Screen Video stores the image upside down, so copy
201  * lines to destination in reverse order. */
202  for (k = 1; k <= s->diff_height; k++) {
203  memcpy(s->frame.data[0] + x_pos * 3 +
204  (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
205  line, width * 3);
206  /* advance source pointer to next line */
207  line += width * 3;
208  }
209  } else {
210  /* hybrid 15-bit/palette mode */
211  decode_hybrid(s->tmpblock, s->frame.data[0],
212  s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
213  x_pos, s->diff_height, width,
214  s->frame.linesize[0], s->pal);
215  }
216  skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
217  return 0;
218 }
219 
220 static int calc_deflate_block_size(int tmpblock_size)
221 {
222  z_stream zstream;
223  int size;
224 
225  zstream.zalloc = Z_NULL;
226  zstream.zfree = Z_NULL;
227  zstream.opaque = Z_NULL;
228  if (deflateInit(&zstream, 0) != Z_OK)
229  return -1;
230  size = deflateBound(&zstream, tmpblock_size);
231  deflateEnd(&zstream);
232 
233  return size;
234 }
235 
237  int *got_frame, AVPacket *avpkt)
238 {
239  int buf_size = avpkt->size;
240  FlashSVContext *s = avctx->priv_data;
241  int h_blocks, v_blocks, h_part, v_part, i, j;
242  GetBitContext gb;
243 
244  /* no supplementary picture */
245  if (buf_size == 0)
246  return 0;
247  if (buf_size < 4)
248  return -1;
249 
250  init_get_bits(&gb, avpkt->data, buf_size * 8);
251 
252  /* start to parse the bitstream */
253  s->block_width = 16 * (get_bits(&gb, 4) + 1);
254  s->image_width = get_bits(&gb, 12);
255  s->block_height = 16 * (get_bits(&gb, 4) + 1);
256  s->image_height = get_bits(&gb, 12);
257 
258  if (s->ver == 2) {
259  skip_bits(&gb, 6);
260  if (get_bits1(&gb)) {
261  av_log_missing_feature(avctx, "iframe", 1);
262  return AVERROR_PATCHWELCOME;
263  }
264  if (get_bits1(&gb)) {
265  av_log_missing_feature(avctx, "Custom palette", 1);
266  return AVERROR_PATCHWELCOME;
267  }
268  }
269 
270  /* calculate number of blocks and size of border (partial) blocks */
271  h_blocks = s->image_width / s->block_width;
272  h_part = s->image_width % s->block_width;
273  v_blocks = s->image_height / s->block_height;
274  v_part = s->image_height % s->block_height;
275 
276  /* the block size could change between frames, make sure the buffer
277  * is large enough, if not, get a larger one */
278  if (s->block_size < s->block_width * s->block_height) {
279  int tmpblock_size = 3 * s->block_width * s->block_height;
280 
281  s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
282  if (!s->tmpblock) {
283  av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
284  return AVERROR(ENOMEM);
285  }
286  if (s->ver == 2) {
287  s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
288  if (s->deflate_block_size <= 0) {
289  av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
290  return -1;
291  }
293  if (!s->deflate_block) {
294  av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
295  return AVERROR(ENOMEM);
296  }
297  }
298  }
299  s->block_size = s->block_width * s->block_height;
300 
301  /* initialize the image size once */
302  if (avctx->width == 0 && avctx->height == 0) {
303  avctx->width = s->image_width;
304  avctx->height = s->image_height;
305  }
306 
307  /* check for changes of image width and image height */
308  if (avctx->width != s->image_width || avctx->height != s->image_height) {
309  av_log(avctx, AV_LOG_ERROR,
310  "Frame width or height differs from first frame!\n");
311  av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n",
312  avctx->height, avctx->width, s->image_height, s->image_width);
313  return AVERROR_INVALIDDATA;
314  }
315 
316  /* we care for keyframes only in Screen Video v2 */
317  s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
318  if (s->is_keyframe) {
319  s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
320  memcpy(s->keyframedata, avpkt->data, avpkt->size);
321  s->blocks = av_realloc(s->blocks,
322  (v_blocks + !!v_part) * (h_blocks + !!h_part)
323  * sizeof(s->blocks[0]));
324  }
325 
326  av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
328  h_blocks, v_blocks, h_part, v_part);
329 
330  s->frame.reference = 3;
334  if (avctx->reget_buffer(avctx, &s->frame) < 0) {
335  av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
336  return -1;
337  }
338 
339  /* loop over all block columns */
340  for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
341 
342  int y_pos = j * s->block_height; // vertical position in frame
343  int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
344 
345  /* loop over all block rows */
346  for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
347  int x_pos = i * s->block_width; // horizontal position in frame
348  int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
349  int has_diff = 0;
350 
351  /* get the size of the compressed zlib chunk */
352  int size = get_bits(&gb, 16);
353 
354  s->color_depth = 0;
355  s->zlibprime_curr = 0;
356  s->zlibprime_prev = 0;
357  s->diff_start = 0;
358  s->diff_height = cur_blk_height;
359 
360  if (8 * size > get_bits_left(&gb)) {
361  avctx->release_buffer(avctx, &s->frame);
362  s->frame.data[0] = NULL;
363  return AVERROR_INVALIDDATA;
364  }
365 
366  if (s->ver == 2 && size) {
367  skip_bits(&gb, 3);
368  s->color_depth = get_bits(&gb, 2);
369  has_diff = get_bits1(&gb);
370  s->zlibprime_curr = get_bits1(&gb);
371  s->zlibprime_prev = get_bits1(&gb);
372 
373  if (s->color_depth != 0 && s->color_depth != 2) {
374  av_log(avctx, AV_LOG_ERROR,
375  "%dx%d invalid color depth %d\n", i, j, s->color_depth);
376  return AVERROR_INVALIDDATA;
377  }
378 
379  if (has_diff) {
380  if (!s->keyframe) {
381  av_log(avctx, AV_LOG_ERROR,
382  "inter frame without keyframe\n");
383  return AVERROR_INVALIDDATA;
384  }
385  s->diff_start = get_bits(&gb, 8);
386  s->diff_height = get_bits(&gb, 8);
387  av_log(avctx, AV_LOG_DEBUG,
388  "%dx%d diff start %d height %d\n",
389  i, j, s->diff_start, s->diff_height);
390  size -= 2;
391  }
392 
393  if (s->zlibprime_prev)
394  av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
395 
396  if (s->zlibprime_curr) {
397  int col = get_bits(&gb, 8);
398  int row = get_bits(&gb, 8);
399  av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
400  size -= 2;
401  av_log_missing_feature(avctx, "zlibprime_curr", 1);
402  return AVERROR_PATCHWELCOME;
403  }
404  if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {
405  av_log(avctx, AV_LOG_ERROR, "no data available for zlib "
406  "priming\n");
407  return AVERROR_INVALIDDATA;
408  }
409  size--; // account for flags byte
410  }
411 
412  if (has_diff) {
413  int k;
414  int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
415 
416  for (k = 0; k < cur_blk_height; k++)
417  memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
418  s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
419  cur_blk_width * 3);
420  }
421 
422  /* skip unchanged blocks, which have size 0 */
423  if (size) {
424  if (flashsv_decode_block(avctx, avpkt, &gb, size,
425  cur_blk_width, cur_blk_height,
426  x_pos, y_pos,
427  i + j * (h_blocks + !!h_part)))
428  av_log(avctx, AV_LOG_ERROR,
429  "error in decompression of block %dx%d\n", i, j);
430  }
431  }
432  }
433  if (s->is_keyframe && s->ver == 2) {
434  if (!s->keyframe) {
435  s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
436  if (!s->keyframe) {
437  av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
438  return AVERROR(ENOMEM);
439  }
440  }
441  memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
442  }
443 
444  *got_frame = 1;
445  *(AVFrame*)data = s->frame;
446 
447  if ((get_bits_count(&gb) / 8) != buf_size)
448  av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
449  buf_size, (get_bits_count(&gb) / 8));
450 
451  /* report that the buffer was completely consumed */
452  return buf_size;
453 }
454 
455 
457 {
458  FlashSVContext *s = avctx->priv_data;
459  inflateEnd(&s->zstream);
460  /* release the frame if needed */
461  if (s->frame.data[0])
462  avctx->release_buffer(avctx, &s->frame);
463 
464  /* free the tmpblock */
465  av_free(s->tmpblock);
466 
467  return 0;
468 }
469 
470 
471 #if CONFIG_FLASHSV_DECODER
472 AVCodec ff_flashsv_decoder = {
473  .name = "flashsv",
474  .type = AVMEDIA_TYPE_VIDEO,
475  .id = AV_CODEC_ID_FLASHSV,
476  .priv_data_size = sizeof(FlashSVContext),
480  .capabilities = CODEC_CAP_DR1,
481  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
482  .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
483 };
484 #endif /* CONFIG_FLASHSV_DECODER */
485 
486 #if CONFIG_FLASHSV2_DECODER
487 static const uint32_t ff_flashsv2_default_palette[128] = {
488  0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
489  0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
490  0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
491  0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
492  0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
493  0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
494  0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
495  0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
496  0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
497  0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
498  0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
499  0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
500  0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
501  0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
502  0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
503  0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
504  0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
505  0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
506  0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
507  0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
508  0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
509  0xDDDDDD, 0xEEEEEE
510 };
511 
512 static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
513 {
514  FlashSVContext *s = avctx->priv_data;
515  flashsv_decode_init(avctx);
516  s->pal = ff_flashsv2_default_palette;
517  s->ver = 2;
518 
519  return 0;
520 }
521 
522 static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
523 {
524  FlashSVContext *s = avctx->priv_data;
525 
526  av_freep(&s->keyframedata);
527  av_freep(&s->blocks);
528  av_freep(&s->keyframe);
529  av_freep(&s->deflate_block);
530  flashsv_decode_end(avctx);
531 
532  return 0;
533 }
534 
535 AVCodec ff_flashsv2_decoder = {
536  .name = "flashsv2",
537  .type = AVMEDIA_TYPE_VIDEO,
538  .id = AV_CODEC_ID_FLASHSV2,
539  .priv_data_size = sizeof(FlashSVContext),
540  .init = flashsv2_decode_init,
541  .close = flashsv2_decode_end,
543  .capabilities = CODEC_CAP_DR1,
544  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE },
545  .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
546 };
547 #endif /* CONFIG_FLASHSV2_DECODER */