| @@ -70,6 +70,45 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx) | |||
| } | |||
| static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, | |||
| GetBitContext *gb, int block_size, | |||
| int width, int height, int x_pos, int y_pos) | |||
| { | |||
| struct FlashSVContext *s = avctx->priv_data; | |||
| uint8_t *line = s->tmpblock; | |||
| int k; | |||
| int ret = inflateReset(&s->zstream); | |||
| if (ret != Z_OK) { | |||
| //return -1; | |||
| } | |||
| s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8; | |||
| s->zstream.avail_in = block_size; | |||
| s->zstream.next_out = s->tmpblock; | |||
| s->zstream.avail_out = s->block_size * 3; | |||
| ret = inflate(&s->zstream, Z_FINISH); | |||
| if (ret == Z_DATA_ERROR) { | |||
| av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n"); | |||
| inflateSync(&s->zstream); | |||
| ret = inflate(&s->zstream, Z_FINISH); | |||
| } | |||
| if (ret != Z_OK && ret != Z_STREAM_END) { | |||
| //return -1; | |||
| } | |||
| /* Flash Screen Video stores the image upside down, so copy | |||
| * lines to destination in reverse order. */ | |||
| for (k = 1; k <= height; k++) { | |||
| memcpy(s->frame.data[0] + x_pos * 3 + | |||
| (s->image_height - y_pos - k) * s->frame.linesize[0], | |||
| line, width * 3); | |||
| /* advance source pointer to next line */ | |||
| line += width * 3; | |||
| } | |||
| skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */ | |||
| return 0; | |||
| } | |||
| static int flashsv_decode_frame(AVCodecContext *avctx, void *data, | |||
| int *data_size, AVPacket *avpkt) | |||
| { | |||
| @@ -158,41 +197,11 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, | |||
| /* skip unchanged blocks, which have size 0 */ | |||
| if (size) { | |||
| /* decompress block */ | |||
| uint8_t *line = s->tmpblock; | |||
| int k; | |||
| int ret = inflateReset(&s->zstream); | |||
| if (ret != Z_OK) { | |||
| av_log(avctx, AV_LOG_ERROR, | |||
| "error in decompression (reset) of block %dx%d\n", i, j); | |||
| /* return -1; */ | |||
| } | |||
| s->zstream.next_in = avpkt->data + get_bits_count(&gb) / 8; | |||
| s->zstream.avail_in = size; | |||
| s->zstream.next_out = s->tmpblock; | |||
| s->zstream.avail_out = s->block_size * 3; | |||
| ret = inflate(&s->zstream, Z_FINISH); | |||
| if (ret == Z_DATA_ERROR) { | |||
| av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n"); | |||
| inflateSync(&s->zstream); | |||
| ret = inflate(&s->zstream, Z_FINISH); | |||
| } | |||
| if (ret != Z_OK && ret != Z_STREAM_END) { | |||
| if (flashsv_decode_block(avctx, avpkt, &gb, size, | |||
| cur_blk_width, cur_blk_height, | |||
| x_pos, y_pos)) | |||
| av_log(avctx, AV_LOG_ERROR, | |||
| "error in decompression of block %dx%d: %d\n", i, j, ret); | |||
| /* return -1; */ | |||
| } | |||
| /* Flash Screen Video stores the image upside down, so copy | |||
| * lines to destination in reverse order. */ | |||
| for (k = 1; k <= cur_blk_height; k++) { | |||
| memcpy(s->frame.data[0] + x_pos * 3 + | |||
| (s->image_height - y_pos - k) * s->frame.linesize[0], | |||
| line, cur_blk_width * 3); | |||
| /* advance source pointer to next line */ | |||
| line += cur_blk_width * 3; | |||
| } | |||
| skip_bits_long(&gb, 8 * size); /* skip the consumed bits */ | |||
| "error in decompression of block %dx%d\n", i, j); | |||
| } | |||
| } | |||
| } | |||