libavcodec/flashsv.c
Go to the documentation of this file.
00001 /*
00002  * Flash Screen Video decoder
00003  * Copyright (C) 2004 Alex Beregszaszi
00004  * Copyright (C) 2006 Benjamin Larsson
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 #include <zlib.h>
00039 
00040 #include "libavutil/intreadwrite.h"
00041 #include "avcodec.h"
00042 #include "bytestream.h"
00043 #include "get_bits.h"
00044 
00045 typedef struct BlockInfo {
00046     uint8_t *pos;
00047     int      size;
00048     int      unp_size;
00049 } BlockInfo;
00050 
00051 typedef struct FlashSVContext {
00052     AVCodecContext *avctx;
00053     AVFrame         frame;
00054     int             image_width, image_height;
00055     int             block_width, block_height;
00056     uint8_t        *tmpblock;
00057     int             block_size;
00058     z_stream        zstream;
00059     int             ver;
00060     const uint32_t *pal;
00061     int             is_keyframe;
00062     uint8_t        *keyframedata;
00063     uint8_t        *keyframe;
00064     BlockInfo      *blocks;
00065     uint8_t        *deflate_block;
00066     int             deflate_block_size;
00067     int             color_depth;
00068     int             zlibprime_curr, zlibprime_prev;
00069     int             diff_start, diff_height;
00070 } FlashSVContext;
00071 
00072 
00073 static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy,
00074                          int h, int w, int stride, const uint32_t *pal)
00075 {
00076     int x, y;
00077     const uint8_t *orig_src = sptr;
00078 
00079     for (y = dx+h; y > dx; y--) {
00080         uint8_t *dst = dptr + (y * stride) + dy * 3;
00081         for (x = 0; x < w; x++) {
00082             if (*sptr & 0x80) {
00083                 /* 15-bit color */
00084                 unsigned c = AV_RB16(sptr) & ~0x8000;
00085                 unsigned b =  c        & 0x1F;
00086                 unsigned g = (c >>  5) & 0x1F;
00087                 unsigned r =  c >> 10;
00088                 /* 000aaabb -> aaabbaaa  */
00089                 *dst++ = (b << 3) | (b >> 2);
00090                 *dst++ = (g << 3) | (g >> 2);
00091                 *dst++ = (r << 3) | (r >> 2);
00092                 sptr += 2;
00093             } else {
00094                 /* palette index */
00095                 uint32_t c = pal[*sptr++];
00096                 bytestream_put_le24(&dst, c);
00097             }
00098         }
00099     }
00100     return sptr - orig_src;
00101 }
00102 
00103 static av_cold int flashsv_decode_init(AVCodecContext *avctx)
00104 {
00105     FlashSVContext *s = avctx->priv_data;
00106     int zret; // Zlib return code
00107 
00108     s->avctx          = avctx;
00109     s->zstream.zalloc = Z_NULL;
00110     s->zstream.zfree  = Z_NULL;
00111     s->zstream.opaque = Z_NULL;
00112     zret = inflateInit(&s->zstream);
00113     if (zret != Z_OK) {
00114         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00115         return 1;
00116     }
00117     avctx->pix_fmt = PIX_FMT_BGR24;
00118     avcodec_get_frame_defaults(&s->frame);
00119     s->frame.data[0] = NULL;
00120 
00121     return 0;
00122 }
00123 
00124 
00125 static int flashsv2_prime(FlashSVContext *s, uint8_t *src,
00126                           int size, int unp_size)
00127 {
00128     z_stream zs;
00129     int zret; // Zlib return code
00130 
00131     zs.zalloc = NULL;
00132     zs.zfree  = NULL;
00133     zs.opaque = NULL;
00134 
00135     s->zstream.next_in   = src;
00136     s->zstream.avail_in  = size;
00137     s->zstream.next_out  = s->tmpblock;
00138     s->zstream.avail_out = s->block_size * 3;
00139     inflate(&s->zstream, Z_SYNC_FLUSH);
00140 
00141     if (deflateInit(&zs, 0) != Z_OK)
00142         return -1;
00143     zs.next_in   = s->tmpblock;
00144     zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
00145     zs.next_out  = s->deflate_block;
00146     zs.avail_out = s->deflate_block_size;
00147     deflate(&zs, Z_SYNC_FLUSH);
00148     deflateEnd(&zs);
00149 
00150     if ((zret = inflateReset(&s->zstream)) != Z_OK) {
00151         av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
00152         return AVERROR_UNKNOWN;
00153     }
00154 
00155     s->zstream.next_in   = s->deflate_block;
00156     s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
00157     s->zstream.next_out  = s->tmpblock;
00158     s->zstream.avail_out = s->block_size * 3;
00159     inflate(&s->zstream, Z_SYNC_FLUSH);
00160 
00161     return 0;
00162 }
00163 
00164 static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
00165                                 GetBitContext *gb, int block_size,
00166                                 int width, int height, int x_pos, int y_pos,
00167                                 int blk_idx)
00168 {
00169     struct FlashSVContext *s = avctx->priv_data;
00170     uint8_t *line = s->tmpblock;
00171     int k;
00172     int ret = inflateReset(&s->zstream);
00173     if (ret != Z_OK) {
00174         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret);
00175         return AVERROR_UNKNOWN;
00176     }
00177     if (s->zlibprime_curr || s->zlibprime_prev) {
00178         ret = flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size,
00179                        s->blocks[blk_idx].unp_size);
00180         if (ret < 0)
00181             return ret;
00182     }
00183     s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
00184     s->zstream.avail_in  = block_size;
00185     s->zstream.next_out  = s->tmpblock;
00186     s->zstream.avail_out = s->block_size * 3;
00187     ret = inflate(&s->zstream, Z_FINISH);
00188     if (ret == Z_DATA_ERROR) {
00189         av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
00190         inflateSync(&s->zstream);
00191         ret = inflate(&s->zstream, Z_FINISH);
00192     }
00193 
00194     if (ret != Z_OK && ret != Z_STREAM_END) {
00195         //return -1;
00196     }
00197 
00198     if (s->is_keyframe) {
00199         s->blocks[blk_idx].pos      = s->keyframedata + (get_bits_count(gb) / 8);
00200         s->blocks[blk_idx].size     = block_size;
00201         s->blocks[blk_idx].unp_size = s->block_size * 3 - s->zstream.avail_out;
00202     }
00203     if (!s->color_depth) {
00204         /* Flash Screen Video stores the image upside down, so copy
00205          * lines to destination in reverse order. */
00206         for (k = 1; k <= s->diff_height; k++) {
00207             memcpy(s->frame.data[0] + x_pos * 3 +
00208                    (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
00209                    line, width * 3);
00210             /* advance source pointer to next line */
00211             line += width * 3;
00212         }
00213     } else {
00214         /* hybrid 15-bit/palette mode */
00215         decode_hybrid(s->tmpblock, s->frame.data[0],
00216                       s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
00217                       x_pos, s->diff_height, width,
00218                       s->frame.linesize[0], s->pal);
00219     }
00220     skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
00221     return 0;
00222 }
00223 
00224 static int calc_deflate_block_size(int tmpblock_size)
00225 {
00226     z_stream zstream;
00227     int size;
00228 
00229     zstream.zalloc = Z_NULL;
00230     zstream.zfree  = Z_NULL;
00231     zstream.opaque = Z_NULL;
00232     if (deflateInit(&zstream, 0) != Z_OK)
00233         return -1;
00234     size = deflateBound(&zstream, tmpblock_size);
00235     deflateEnd(&zstream);
00236 
00237     return size;
00238 }
00239 
00240 static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
00241                                 int *data_size, AVPacket *avpkt)
00242 {
00243     int buf_size       = avpkt->size;
00244     FlashSVContext *s  = avctx->priv_data;
00245     int h_blocks, v_blocks, h_part, v_part, i, j;
00246     GetBitContext gb;
00247 
00248     /* no supplementary picture */
00249     if (buf_size == 0)
00250         return 0;
00251     if (buf_size < 4)
00252         return -1;
00253 
00254     init_get_bits(&gb, avpkt->data, buf_size * 8);
00255 
00256     /* start to parse the bitstream */
00257     s->block_width  = 16 * (get_bits(&gb,  4) + 1);
00258     s->image_width  =       get_bits(&gb, 12);
00259     s->block_height = 16 * (get_bits(&gb,  4) + 1);
00260     s->image_height =       get_bits(&gb, 12);
00261 
00262     if (s->ver == 2) {
00263         skip_bits(&gb, 6);
00264         if (get_bits1(&gb)) {
00265             av_log_missing_feature(avctx, "iframe", 1);
00266             return AVERROR_PATCHWELCOME;
00267         }
00268         if (get_bits1(&gb)) {
00269             av_log_missing_feature(avctx, "custom palette", 1);
00270             return AVERROR_PATCHWELCOME;
00271         }
00272     }
00273 
00274     /* calculate number of blocks and size of border (partial) blocks */
00275     h_blocks = s->image_width  / s->block_width;
00276     h_part   = s->image_width  % s->block_width;
00277     v_blocks = s->image_height / s->block_height;
00278     v_part   = s->image_height % s->block_height;
00279 
00280     /* the block size could change between frames, make sure the buffer
00281      * is large enough, if not, get a larger one */
00282     if (s->block_size < s->block_width * s->block_height) {
00283         int tmpblock_size = 3 * s->block_width * s->block_height;
00284 
00285         s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
00286         if (!s->tmpblock) {
00287             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00288             return AVERROR(ENOMEM);
00289         }
00290         if (s->ver == 2) {
00291             s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
00292             if (s->deflate_block_size <= 0) {
00293                 av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
00294                 return -1;
00295             }
00296             s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
00297             if (!s->deflate_block) {
00298                 av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
00299                 return AVERROR(ENOMEM);
00300             }
00301         }
00302     }
00303     s->block_size = s->block_width * s->block_height;
00304 
00305     /* initialize the image size once */
00306     if (avctx->width == 0 && avctx->height == 0) {
00307         avctx->width  = s->image_width;
00308         avctx->height = s->image_height;
00309     }
00310 
00311     /* check for changes of image width and image height */
00312     if (avctx->width != s->image_width || avctx->height != s->image_height) {
00313         av_log(avctx, AV_LOG_ERROR,
00314                "Frame width or height differs from first frame!\n");
00315         av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
00316                avctx->height, avctx->width, s->image_height, s->image_width);
00317         return AVERROR_INVALIDDATA;
00318     }
00319 
00320     /* we care for keyframes only in Screen Video v2 */
00321     s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
00322     if (s->is_keyframe) {
00323         s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
00324         memcpy(s->keyframedata, avpkt->data, avpkt->size);
00325         s->blocks = av_realloc(s->blocks,
00326                                (v_blocks + !!v_part) * (h_blocks + !!h_part)
00327                                * sizeof(s->blocks[0]));
00328     }
00329 
00330     av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
00331             s->image_width, s->image_height, s->block_width, s->block_height,
00332             h_blocks, v_blocks, h_part, v_part);
00333 
00334     s->frame.reference    = 3;
00335     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |
00336                             FF_BUFFER_HINTS_PRESERVE |
00337                             FF_BUFFER_HINTS_REUSABLE;
00338     if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00339         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00340         return -1;
00341     }
00342 
00343     /* loop over all block columns */
00344     for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
00345 
00346         int y_pos  = j * s->block_height; // vertical position in frame
00347         int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
00348 
00349         /* loop over all block rows */
00350         for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
00351             int x_pos = i * s->block_width; // horizontal position in frame
00352             int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
00353             int has_diff = 0;
00354 
00355             /* get the size of the compressed zlib chunk */
00356             int size = get_bits(&gb, 16);
00357 
00358             s->color_depth    = 0;
00359             s->zlibprime_curr = 0;
00360             s->zlibprime_prev = 0;
00361             s->diff_start     = 0;
00362             s->diff_height    = cur_blk_height;
00363 
00364             if (8 * size > get_bits_left(&gb)) {
00365                 avctx->release_buffer(avctx, &s->frame);
00366                 s->frame.data[0] = NULL;
00367                 return AVERROR_INVALIDDATA;
00368             }
00369 
00370             if (s->ver == 2 && size) {
00371                 skip_bits(&gb, 3);
00372                 s->color_depth    = get_bits(&gb, 2);
00373                 has_diff          = get_bits1(&gb);
00374                 s->zlibprime_curr = get_bits1(&gb);
00375                 s->zlibprime_prev = get_bits1(&gb);
00376 
00377                 if (s->color_depth != 0 && s->color_depth != 2) {
00378                     av_log(avctx, AV_LOG_ERROR,
00379                            "%dx%d invalid color depth %d\n", i, j, s->color_depth);
00380                     return AVERROR_INVALIDDATA;
00381                 }
00382 
00383                 if (has_diff) {
00384                     s->diff_start  = get_bits(&gb, 8);
00385                     s->diff_height = get_bits(&gb, 8);
00386                     av_log(avctx, AV_LOG_DEBUG,
00387                            "%dx%d diff start %d height %d\n",
00388                            i, j, s->diff_start, s->diff_height);
00389                     size -= 2;
00390                 }
00391 
00392                 if (s->zlibprime_prev)
00393                     av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
00394 
00395                 if (s->zlibprime_curr) {
00396                     int col = get_bits(&gb, 8);
00397                     int row = get_bits(&gb, 8);
00398                     av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
00399                     size -= 2;
00400                     av_log_missing_feature(avctx, "zlibprime_curr", 1);
00401                     return AVERROR_PATCHWELCOME;
00402                 }
00403                 size--; // account for flags byte
00404             }
00405 
00406             if (has_diff) {
00407                 int k;
00408                 int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
00409 
00410                 for (k = 0; k < cur_blk_height; k++)
00411                     memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
00412                            s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
00413                            cur_blk_width * 3);
00414             }
00415 
00416             /* skip unchanged blocks, which have size 0 */
00417             if (size) {
00418                 if (flashsv_decode_block(avctx, avpkt, &gb, size,
00419                                          cur_blk_width, cur_blk_height,
00420                                          x_pos, y_pos,
00421                                          i + j * (h_blocks + !!h_part)))
00422                     av_log(avctx, AV_LOG_ERROR,
00423                            "error in decompression of block %dx%d\n", i, j);
00424             }
00425         }
00426     }
00427     if (s->is_keyframe && s->ver == 2) {
00428         if (!s->keyframe) {
00429             s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
00430             if (!s->keyframe) {
00431                 av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
00432                 return AVERROR(ENOMEM);
00433             }
00434         }
00435         memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
00436     }
00437 
00438     *data_size = sizeof(AVFrame);
00439     *(AVFrame*)data = s->frame;
00440 
00441     if ((get_bits_count(&gb) / 8) != buf_size)
00442         av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
00443                buf_size, (get_bits_count(&gb) / 8));
00444 
00445     /* report that the buffer was completely consumed */
00446     return buf_size;
00447 }
00448 
00449 
00450 static av_cold int flashsv_decode_end(AVCodecContext *avctx)
00451 {
00452     FlashSVContext *s = avctx->priv_data;
00453     inflateEnd(&s->zstream);
00454     /* release the frame if needed */
00455     if (s->frame.data[0])
00456         avctx->release_buffer(avctx, &s->frame);
00457 
00458     /* free the tmpblock */
00459     av_free(s->tmpblock);
00460 
00461     return 0;
00462 }
00463 
00464 
00465 #if CONFIG_FLASHSV_DECODER
00466 AVCodec ff_flashsv_decoder = {
00467     .name           = "flashsv",
00468     .type           = AVMEDIA_TYPE_VIDEO,
00469     .id             = CODEC_ID_FLASHSV,
00470     .priv_data_size = sizeof(FlashSVContext),
00471     .init           = flashsv_decode_init,
00472     .close          = flashsv_decode_end,
00473     .decode         = flashsv_decode_frame,
00474     .capabilities   = CODEC_CAP_DR1,
00475     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00476     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
00477 };
00478 #endif /* CONFIG_FLASHSV_DECODER */
00479 
00480 #if CONFIG_FLASHSV2_DECODER
00481 static const uint32_t ff_flashsv2_default_palette[128] = {
00482     0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
00483     0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
00484     0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
00485     0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
00486     0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
00487     0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
00488     0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
00489     0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
00490     0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
00491     0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
00492     0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
00493     0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
00494     0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
00495     0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
00496     0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
00497     0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
00498     0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
00499     0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
00500     0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
00501     0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
00502     0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
00503     0xDDDDDD, 0xEEEEEE
00504 };
00505 
00506 static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
00507 {
00508     FlashSVContext *s = avctx->priv_data;
00509     flashsv_decode_init(avctx);
00510     s->pal = ff_flashsv2_default_palette;
00511     s->ver = 2;
00512 
00513     return 0;
00514 }
00515 
00516 static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
00517 {
00518     FlashSVContext *s = avctx->priv_data;
00519 
00520     av_freep(&s->keyframedata);
00521     av_freep(&s->blocks);
00522     av_freep(&s->keyframe);
00523     av_freep(&s->deflate_block);
00524     flashsv_decode_end(avctx);
00525 
00526     return 0;
00527 }
00528 
00529 AVCodec ff_flashsv2_decoder = {
00530     .name           = "flashsv2",
00531     .type           = AVMEDIA_TYPE_VIDEO,
00532     .id             = CODEC_ID_FLASHSV2,
00533     .priv_data_size = sizeof(FlashSVContext),
00534     .init           = flashsv2_decode_init,
00535     .close          = flashsv2_decode_end,
00536     .decode         = flashsv_decode_frame,
00537     .capabilities   = CODEC_CAP_DR1,
00538     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00539     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
00540 };
00541 #endif /* CONFIG_FLASHSV2_DECODER */