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 void flashsv2_prime(FlashSVContext *s, uint8_t *src,
00126                            int size, int unp_size)
00127 {
00128     z_stream zs;
00129 
00130     zs.zalloc = NULL;
00131     zs.zfree  = NULL;
00132     zs.opaque = NULL;
00133 
00134     s->zstream.next_in   = src;
00135     s->zstream.avail_in  = size;
00136     s->zstream.next_out  = s->tmpblock;
00137     s->zstream.avail_out = s->block_size * 3;
00138     inflate(&s->zstream, Z_SYNC_FLUSH);
00139 
00140     deflateInit(&zs, 0);
00141     zs.next_in   = s->tmpblock;
00142     zs.avail_in  = s->block_size * 3 - s->zstream.avail_out;
00143     zs.next_out  = s->deflate_block;
00144     zs.avail_out = s->deflate_block_size;
00145     deflate(&zs, Z_SYNC_FLUSH);
00146     deflateEnd(&zs);
00147 
00148     inflateReset(&s->zstream);
00149 
00150     s->zstream.next_in   = s->deflate_block;
00151     s->zstream.avail_in  = s->deflate_block_size - zs.avail_out;
00152     s->zstream.next_out  = s->tmpblock;
00153     s->zstream.avail_out = s->block_size * 3;
00154     inflate(&s->zstream, Z_SYNC_FLUSH);
00155 }
00156 
00157 static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt,
00158                                 GetBitContext *gb, int block_size,
00159                                 int width, int height, int x_pos, int y_pos,
00160                                 int blk_idx)
00161 {
00162     struct FlashSVContext *s = avctx->priv_data;
00163     uint8_t *line = s->tmpblock;
00164     int k;
00165     int ret = inflateReset(&s->zstream);
00166     if (ret != Z_OK) {
00167         //return -1;
00168     }
00169     if (s->zlibprime_curr || s->zlibprime_prev) {
00170         flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size,
00171                        s->blocks[blk_idx].unp_size);
00172     }
00173     s->zstream.next_in   = avpkt->data + get_bits_count(gb) / 8;
00174     s->zstream.avail_in  = block_size;
00175     s->zstream.next_out  = s->tmpblock;
00176     s->zstream.avail_out = s->block_size * 3;
00177     ret = inflate(&s->zstream, Z_FINISH);
00178     if (ret == Z_DATA_ERROR) {
00179         av_log(avctx, AV_LOG_ERROR, "Zlib resync occurred\n");
00180         inflateSync(&s->zstream);
00181         ret = inflate(&s->zstream, Z_FINISH);
00182     }
00183 
00184     if (ret != Z_OK && ret != Z_STREAM_END) {
00185         //return -1;
00186     }
00187 
00188     if (s->is_keyframe) {
00189         s->blocks[blk_idx].pos      = s->keyframedata + (get_bits_count(gb) / 8);
00190         s->blocks[blk_idx].size     = block_size;
00191         s->blocks[blk_idx].unp_size = s->block_size * 3 - s->zstream.avail_out;
00192     }
00193     if (!s->color_depth) {
00194         /* Flash Screen Video stores the image upside down, so copy
00195          * lines to destination in reverse order. */
00196         for (k = 1; k <= s->diff_height; k++) {
00197             memcpy(s->frame.data[0] + x_pos * 3 +
00198                    (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0],
00199                    line, width * 3);
00200             /* advance source pointer to next line */
00201             line += width * 3;
00202         }
00203     } else {
00204         /* hybrid 15-bit/palette mode */
00205         decode_hybrid(s->tmpblock, s->frame.data[0],
00206                       s->image_height - (y_pos + 1 + s->diff_start + s->diff_height),
00207                       x_pos, s->diff_height, width,
00208                       s->frame.linesize[0], s->pal);
00209     }
00210     skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */
00211     return 0;
00212 }
00213 
00214 static int calc_deflate_block_size(int tmpblock_size)
00215 {
00216     z_stream zstream;
00217     int size;
00218 
00219     zstream.zalloc = Z_NULL;
00220     zstream.zfree  = Z_NULL;
00221     zstream.opaque = Z_NULL;
00222     if (deflateInit(&zstream, 0) != Z_OK)
00223         return -1;
00224     size = deflateBound(&zstream, tmpblock_size);
00225     deflateEnd(&zstream);
00226 
00227     return size;
00228 }
00229 
00230 static int flashsv_decode_frame(AVCodecContext *avctx, void *data,
00231                                 int *data_size, AVPacket *avpkt)
00232 {
00233     int buf_size       = avpkt->size;
00234     FlashSVContext *s  = avctx->priv_data;
00235     int h_blocks, v_blocks, h_part, v_part, i, j;
00236     GetBitContext gb;
00237 
00238     /* no supplementary picture */
00239     if (buf_size == 0)
00240         return 0;
00241     if (buf_size < 4)
00242         return -1;
00243 
00244     init_get_bits(&gb, avpkt->data, buf_size * 8);
00245 
00246     /* start to parse the bitstream */
00247     s->block_width  = 16 * (get_bits(&gb,  4) + 1);
00248     s->image_width  =       get_bits(&gb, 12);
00249     s->block_height = 16 * (get_bits(&gb,  4) + 1);
00250     s->image_height =       get_bits(&gb, 12);
00251 
00252     if (s->ver == 2) {
00253         skip_bits(&gb, 6);
00254         if (get_bits1(&gb)) {
00255             av_log_missing_feature(avctx, "iframe", 1);
00256             return AVERROR_PATCHWELCOME;
00257         }
00258         if (get_bits1(&gb)) {
00259             av_log_missing_feature(avctx, "custom palette", 1);
00260             return AVERROR_PATCHWELCOME;
00261         }
00262     }
00263 
00264     /* calculate number of blocks and size of border (partial) blocks */
00265     h_blocks = s->image_width  / s->block_width;
00266     h_part   = s->image_width  % s->block_width;
00267     v_blocks = s->image_height / s->block_height;
00268     v_part   = s->image_height % s->block_height;
00269 
00270     /* the block size could change between frames, make sure the buffer
00271      * is large enough, if not, get a larger one */
00272     if (s->block_size < s->block_width * s->block_height) {
00273         int tmpblock_size = 3 * s->block_width * s->block_height;
00274 
00275         s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);
00276         if (!s->tmpblock) {
00277             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00278             return AVERROR(ENOMEM);
00279         }
00280         if (s->ver == 2) {
00281             s->deflate_block_size = calc_deflate_block_size(tmpblock_size);
00282             if (s->deflate_block_size <= 0) {
00283                 av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");
00284                 return -1;
00285             }
00286             s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);
00287             if (!s->deflate_block) {
00288                 av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");
00289                 return AVERROR(ENOMEM);
00290             }
00291         }
00292     }
00293     s->block_size = s->block_width * s->block_height;
00294 
00295     /* initialize the image size once */
00296     if (avctx->width == 0 && avctx->height == 0) {
00297         avctx->width  = s->image_width;
00298         avctx->height = s->image_height;
00299     }
00300 
00301     /* check for changes of image width and image height */
00302     if (avctx->width != s->image_width || avctx->height != s->image_height) {
00303         av_log(avctx, AV_LOG_ERROR,
00304                "Frame width or height differs from first frame!\n");
00305         av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",
00306                avctx->height, avctx->width, s->image_height, s->image_width);
00307         return AVERROR_INVALIDDATA;
00308     }
00309 
00310     /* we care for keyframes only in Screen Video v2 */
00311     s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);
00312     if (s->is_keyframe) {
00313         s->keyframedata = av_realloc(s->keyframedata, avpkt->size);
00314         memcpy(s->keyframedata, avpkt->data, avpkt->size);
00315         s->blocks = av_realloc(s->blocks,
00316                                (v_blocks + !!v_part) * (h_blocks + !!h_part)
00317                                * sizeof(s->blocks[0]));
00318     }
00319 
00320     av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",
00321             s->image_width, s->image_height, s->block_width, s->block_height,
00322             h_blocks, v_blocks, h_part, v_part);
00323 
00324     s->frame.reference    = 3;
00325     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |
00326                             FF_BUFFER_HINTS_PRESERVE |
00327                             FF_BUFFER_HINTS_REUSABLE;
00328     if (avctx->reget_buffer(avctx, &s->frame) < 0) {
00329         av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
00330         return -1;
00331     }
00332 
00333     /* loop over all block columns */
00334     for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {
00335 
00336         int y_pos  = j * s->block_height; // vertical position in frame
00337         int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;
00338 
00339         /* loop over all block rows */
00340         for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {
00341             int x_pos = i * s->block_width; // horizontal position in frame
00342             int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;
00343             int has_diff = 0;
00344 
00345             /* get the size of the compressed zlib chunk */
00346             int size = get_bits(&gb, 16);
00347 
00348             s->color_depth    = 0;
00349             s->zlibprime_curr = 0;
00350             s->zlibprime_prev = 0;
00351             s->diff_start     = 0;
00352             s->diff_height    = cur_blk_height;
00353 
00354             if (8 * size > get_bits_left(&gb)) {
00355                 avctx->release_buffer(avctx, &s->frame);
00356                 s->frame.data[0] = NULL;
00357                 return AVERROR_INVALIDDATA;
00358             }
00359 
00360             if (s->ver == 2 && size) {
00361                 skip_bits(&gb, 3);
00362                 s->color_depth    = get_bits(&gb, 2);
00363                 has_diff          = get_bits1(&gb);
00364                 s->zlibprime_curr = get_bits1(&gb);
00365                 s->zlibprime_prev = get_bits1(&gb);
00366 
00367                 if (s->color_depth != 0 && s->color_depth != 2) {
00368                     av_log(avctx, AV_LOG_ERROR,
00369                            "%dx%d invalid color depth %d\n", i, j, s->color_depth);
00370                     return AVERROR_INVALIDDATA;
00371                 }
00372 
00373                 if (has_diff) {
00374                     s->diff_start  = get_bits(&gb, 8);
00375                     s->diff_height = get_bits(&gb, 8);
00376                     av_log(avctx, AV_LOG_DEBUG,
00377                            "%dx%d diff start %d height %d\n",
00378                            i, j, s->diff_start, s->diff_height);
00379                     size -= 2;
00380                 }
00381 
00382                 if (s->zlibprime_prev)
00383                     av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);
00384 
00385                 if (s->zlibprime_curr) {
00386                     int col = get_bits(&gb, 8);
00387                     int row = get_bits(&gb, 8);
00388                     av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);
00389                     size -= 2;
00390                     av_log_missing_feature(avctx, "zlibprime_curr", 1);
00391                     return AVERROR_PATCHWELCOME;
00392                 }
00393                 size--; // account for flags byte
00394             }
00395 
00396             if (has_diff) {
00397                 int k;
00398                 int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];
00399 
00400                 for (k = 0; k < cur_blk_height; k++)
00401                     memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,
00402                            s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,
00403                            cur_blk_width * 3);
00404             }
00405 
00406             /* skip unchanged blocks, which have size 0 */
00407             if (size) {
00408                 if (flashsv_decode_block(avctx, avpkt, &gb, size,
00409                                          cur_blk_width, cur_blk_height,
00410                                          x_pos, y_pos,
00411                                          i + j * (h_blocks + !!h_part)))
00412                     av_log(avctx, AV_LOG_ERROR,
00413                            "error in decompression of block %dx%d\n", i, j);
00414             }
00415         }
00416     }
00417     if (s->is_keyframe && s->ver == 2) {
00418         if (!s->keyframe) {
00419             s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);
00420             if (!s->keyframe) {
00421                 av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");
00422                 return AVERROR(ENOMEM);
00423             }
00424         }
00425         memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);
00426     }
00427 
00428     *data_size = sizeof(AVFrame);
00429     *(AVFrame*)data = s->frame;
00430 
00431     if ((get_bits_count(&gb) / 8) != buf_size)
00432         av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",
00433                buf_size, (get_bits_count(&gb) / 8));
00434 
00435     /* report that the buffer was completely consumed */
00436     return buf_size;
00437 }
00438 
00439 
00440 static av_cold int flashsv_decode_end(AVCodecContext *avctx)
00441 {
00442     FlashSVContext *s = avctx->priv_data;
00443     inflateEnd(&s->zstream);
00444     /* release the frame if needed */
00445     if (s->frame.data[0])
00446         avctx->release_buffer(avctx, &s->frame);
00447 
00448     /* free the tmpblock */
00449     av_free(s->tmpblock);
00450 
00451     return 0;
00452 }
00453 
00454 
00455 #if CONFIG_FLASHSV_DECODER
00456 AVCodec ff_flashsv_decoder = {
00457     .name           = "flashsv",
00458     .type           = AVMEDIA_TYPE_VIDEO,
00459     .id             = CODEC_ID_FLASHSV,
00460     .priv_data_size = sizeof(FlashSVContext),
00461     .init           = flashsv_decode_init,
00462     .close          = flashsv_decode_end,
00463     .decode         = flashsv_decode_frame,
00464     .capabilities   = CODEC_CAP_DR1,
00465     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00466     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v1"),
00467 };
00468 #endif /* CONFIG_FLASHSV_DECODER */
00469 
00470 #if CONFIG_FLASHSV2_DECODER
00471 static const uint32_t ff_flashsv2_default_palette[128] = {
00472     0x000000, 0x333333, 0x666666, 0x999999, 0xCCCCCC, 0xFFFFFF,
00473     0x330000, 0x660000, 0x990000, 0xCC0000, 0xFF0000, 0x003300,
00474     0x006600, 0x009900, 0x00CC00, 0x00FF00, 0x000033, 0x000066,
00475     0x000099, 0x0000CC, 0x0000FF, 0x333300, 0x666600, 0x999900,
00476     0xCCCC00, 0xFFFF00, 0x003333, 0x006666, 0x009999, 0x00CCCC,
00477     0x00FFFF, 0x330033, 0x660066, 0x990099, 0xCC00CC, 0xFF00FF,
00478     0xFFFF33, 0xFFFF66, 0xFFFF99, 0xFFFFCC, 0xFF33FF, 0xFF66FF,
00479     0xFF99FF, 0xFFCCFF, 0x33FFFF, 0x66FFFF, 0x99FFFF, 0xCCFFFF,
00480     0xCCCC33, 0xCCCC66, 0xCCCC99, 0xCCCCFF, 0xCC33CC, 0xCC66CC,
00481     0xCC99CC, 0xCCFFCC, 0x33CCCC, 0x66CCCC, 0x99CCCC, 0xFFCCCC,
00482     0x999933, 0x999966, 0x9999CC, 0x9999FF, 0x993399, 0x996699,
00483     0x99CC99, 0x99FF99, 0x339999, 0x669999, 0xCC9999, 0xFF9999,
00484     0x666633, 0x666699, 0x6666CC, 0x6666FF, 0x663366, 0x669966,
00485     0x66CC66, 0x66FF66, 0x336666, 0x996666, 0xCC6666, 0xFF6666,
00486     0x333366, 0x333399, 0x3333CC, 0x3333FF, 0x336633, 0x339933,
00487     0x33CC33, 0x33FF33, 0x663333, 0x993333, 0xCC3333, 0xFF3333,
00488     0x003366, 0x336600, 0x660033, 0x006633, 0x330066, 0x663300,
00489     0x336699, 0x669933, 0x993366, 0x339966, 0x663399, 0x996633,
00490     0x6699CC, 0x99CC66, 0xCC6699, 0x66CC99, 0x9966CC, 0xCC9966,
00491     0x99CCFF, 0xCCFF99, 0xFF99CC, 0x99FFCC, 0xCC99FF, 0xFFCC99,
00492     0x111111, 0x222222, 0x444444, 0x555555, 0xAAAAAA, 0xBBBBBB,
00493     0xDDDDDD, 0xEEEEEE
00494 };
00495 
00496 static av_cold int flashsv2_decode_init(AVCodecContext *avctx)
00497 {
00498     FlashSVContext *s = avctx->priv_data;
00499     flashsv_decode_init(avctx);
00500     s->pal = ff_flashsv2_default_palette;
00501     s->ver = 2;
00502 
00503     return 0;
00504 }
00505 
00506 static av_cold int flashsv2_decode_end(AVCodecContext *avctx)
00507 {
00508     FlashSVContext *s = avctx->priv_data;
00509 
00510     av_freep(&s->keyframedata);
00511     av_freep(&s->blocks);
00512     av_freep(&s->keyframe);
00513     av_freep(&s->deflate_block);
00514     flashsv_decode_end(avctx);
00515 
00516     return 0;
00517 }
00518 
00519 AVCodec ff_flashsv2_decoder = {
00520     .name           = "flashsv2",
00521     .type           = AVMEDIA_TYPE_VIDEO,
00522     .id             = CODEC_ID_FLASHSV2,
00523     .priv_data_size = sizeof(FlashSVContext),
00524     .init           = flashsv2_decode_init,
00525     .close          = flashsv2_decode_end,
00526     .decode         = flashsv_decode_frame,
00527     .capabilities   = CODEC_CAP_DR1,
00528     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_BGR24, PIX_FMT_NONE},
00529     .long_name      = NULL_IF_CONFIG_SMALL("Flash Screen Video v2"),
00530 };
00531 #endif /* CONFIG_FLASHSV2_DECODER */