• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavcodec/tscc.c

Go to the documentation of this file.
00001 /*
00002  * TechSmith Camtasia decoder
00003  * Copyright (c) 2004 Konstantin Shishkov
00004  *
00005  * This file is part of Libav.
00006  *
00007  * Libav is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * Libav is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with Libav; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 
00041 #include "avcodec.h"
00042 #include "msrledec.h"
00043 
00044 #include <zlib.h>
00045 
00046 
00047 /*
00048  * Decoder context
00049  */
00050 typedef struct TsccContext {
00051 
00052     AVCodecContext *avctx;
00053     AVFrame pic;
00054 
00055     // Bits per pixel
00056     int bpp;
00057     // Decompressed data size
00058     unsigned int decomp_size;
00059     // Decompression buffer
00060     unsigned char* decomp_buf;
00061     GetByteContext gb;
00062     int height;
00063     z_stream zstream;
00064 
00065     uint32_t pal[256];
00066 } CamtasiaContext;
00067 
00068 /*
00069  *
00070  * Decode a frame
00071  *
00072  */
00073 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
00074 {
00075     const uint8_t *buf = avpkt->data;
00076     int buf_size = avpkt->size;
00077     CamtasiaContext * const c = avctx->priv_data;
00078     const unsigned char *encoded = buf;
00079     int zret; // Zlib return code
00080     int len = buf_size;
00081 
00082     if(c->pic.data[0])
00083             avctx->release_buffer(avctx, &c->pic);
00084 
00085     c->pic.reference = 1;
00086     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID;
00087     if(avctx->get_buffer(avctx, &c->pic) < 0){
00088         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00089         return -1;
00090     }
00091 
00092     zret = inflateReset(&c->zstream);
00093     if (zret != Z_OK) {
00094         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
00095         return -1;
00096     }
00097     c->zstream.next_in = encoded;
00098     c->zstream.avail_in = len;
00099     c->zstream.next_out = c->decomp_buf;
00100     c->zstream.avail_out = c->decomp_size;
00101     zret = inflate(&c->zstream, Z_FINISH);
00102     // Z_DATA_ERROR means empty picture
00103     if ((zret != Z_OK) && (zret != Z_STREAM_END) && (zret != Z_DATA_ERROR)) {
00104         av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
00105         return -1;
00106     }
00107 
00108 
00109     if (zret != Z_DATA_ERROR) {
00110         bytestream2_init(&c->gb, c->decomp_buf,
00111                          c->decomp_size - c->zstream.avail_out);
00112         ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, &c->gb);
00113     }
00114 
00115     /* make the palette available on the way out */
00116     if (c->avctx->pix_fmt == PIX_FMT_PAL8) {
00117         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
00118 
00119         if (pal) {
00120             c->pic.palette_has_changed = 1;
00121             memcpy(c->pal, pal, AVPALETTE_SIZE);
00122         }
00123         memcpy(c->pic.data[1], c->pal, AVPALETTE_SIZE);
00124     }
00125 
00126     *data_size = sizeof(AVFrame);
00127     *(AVFrame*)data = c->pic;
00128 
00129     /* always report that the buffer was completely consumed */
00130     return buf_size;
00131 }
00132 
00133 
00134 
00135 /*
00136  *
00137  * Init tscc decoder
00138  *
00139  */
00140 static av_cold int decode_init(AVCodecContext *avctx)
00141 {
00142     CamtasiaContext * const c = avctx->priv_data;
00143     int zret; // Zlib return code
00144 
00145     c->avctx = avctx;
00146 
00147     c->height = avctx->height;
00148 
00149     // Needed if zlib unused or init aborted before inflateInit
00150     memset(&c->zstream, 0, sizeof(z_stream));
00151     switch(avctx->bits_per_coded_sample){
00152     case  8: avctx->pix_fmt = PIX_FMT_PAL8; break;
00153     case 16: avctx->pix_fmt = PIX_FMT_RGB555; break;
00154     case 24:
00155              avctx->pix_fmt = PIX_FMT_BGR24;
00156              break;
00157     case 32: avctx->pix_fmt = PIX_FMT_RGB32; break;
00158     default: av_log(avctx, AV_LOG_ERROR, "Camtasia error: unknown depth %i bpp\n", avctx->bits_per_coded_sample);
00159              return -1;
00160     }
00161     c->bpp = avctx->bits_per_coded_sample;
00162     // buffer size for RLE 'best' case when 2-byte code precedes each pixel and there may be padding after it too
00163     c->decomp_size = (((avctx->width * c->bpp + 7) >> 3) + 3 * avctx->width + 2) * avctx->height + 2;
00164 
00165     /* Allocate decompression buffer */
00166     if (c->decomp_size) {
00167         if ((c->decomp_buf = av_malloc(c->decomp_size)) == NULL) {
00168             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
00169             return 1;
00170         }
00171     }
00172 
00173     c->zstream.zalloc = Z_NULL;
00174     c->zstream.zfree = Z_NULL;
00175     c->zstream.opaque = Z_NULL;
00176     zret = inflateInit(&c->zstream);
00177     if (zret != Z_OK) {
00178         av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
00179         return 1;
00180     }
00181 
00182     return 0;
00183 }
00184 
00185 
00186 
00187 /*
00188  *
00189  * Uninit tscc decoder
00190  *
00191  */
00192 static av_cold int decode_end(AVCodecContext *avctx)
00193 {
00194     CamtasiaContext * const c = avctx->priv_data;
00195 
00196     av_freep(&c->decomp_buf);
00197 
00198     if (c->pic.data[0])
00199         avctx->release_buffer(avctx, &c->pic);
00200     inflateEnd(&c->zstream);
00201 
00202     return 0;
00203 }
00204 
00205 AVCodec ff_tscc_decoder = {
00206     .name           = "camtasia",
00207     .type           = AVMEDIA_TYPE_VIDEO,
00208     .id             = CODEC_ID_TSCC,
00209     .priv_data_size = sizeof(CamtasiaContext),
00210     .init           = decode_init,
00211     .close          = decode_end,
00212     .decode         = decode_frame,
00213     .capabilities   = CODEC_CAP_DR1,
00214     .long_name      = NULL_IF_CONFIG_SMALL("TechSmith Screen Capture Codec"),
00215 };
00216 
Generated on Thu Jul 11 2013 15:38:21 for Libav by doxygen 1.7.1