| @@ -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, | static int flashsv_decode_frame(AVCodecContext *avctx, void *data, | ||||
| int *data_size, AVPacket *avpkt) | 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 */ | /* skip unchanged blocks, which have size 0 */ | ||||
| if (size) { | 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, | 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); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||