1/* 2 * LCL (LossLess Codec Library) Codec 3 * Copyright (c) 2002-2004 Roberto Togni 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file libavcodec/lclenc.c 24 * LCL (LossLess Codec Library) Video Codec 25 * Decoder for MSZH and ZLIB codecs 26 * Experimental encoder for ZLIB RGB24 27 * 28 * Fourcc: MSZH, ZLIB 29 * 30 * Original Win32 dll: 31 * Ver2.23 By Kenji Oshima 2000.09.20 32 * avimszh.dll, avizlib.dll 33 * 34 * A description of the decoding algorithm can be found here: 35 * http://www.pcisys.net/~melanson/codecs 36 * 37 * Supports: BGR24 (RGB 24bpp) 38 * 39 */ 40 41#include <stdio.h> 42#include <stdlib.h> 43 44#include "avcodec.h" 45#include "bitstream.h" 46#include "lcl.h" 47 48#if CONFIG_ZLIB 49#include <zlib.h> 50#endif 51 52/* 53 * Decoder context 54 */ 55typedef struct LclEncContext { 56 57 AVCodecContext *avctx; 58 AVFrame pic; 59 PutBitContext pb; 60 61 // Image type 62 int imgtype; 63 // Compression type 64 int compression; 65 // Flags 66 int flags; 67 // Decompressed data size 68 unsigned int decomp_size; 69 // Maximum compressed data size 70 unsigned int max_comp_size; 71 // Compression buffer 72 unsigned char* comp_buf; 73#if CONFIG_ZLIB 74 z_stream zstream; 75#endif 76} LclEncContext; 77 78/* 79 * 80 * Encode a frame 81 * 82 */ 83static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ 84 LclEncContext *c = avctx->priv_data; 85 AVFrame *pict = data; 86 AVFrame * const p = &c->pic; 87 int i; 88 int zret; // Zlib return code 89 90#if !CONFIG_ZLIB 91 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); 92 return -1; 93#else 94 95 init_put_bits(&c->pb, buf, buf_size); 96 97 *p = *pict; 98 p->pict_type= FF_I_TYPE; 99 p->key_frame= 1; 100 101 if(avctx->pix_fmt != PIX_FMT_BGR24){ 102 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); 103 return -1; 104 } 105 106 zret = deflateReset(&(c->zstream)); 107 if (zret != Z_OK) { 108 av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); 109 return -1; 110 } 111 c->zstream.next_out = c->comp_buf; 112 c->zstream.avail_out = c->max_comp_size; 113 114 for(i = avctx->height - 1; i >= 0; i--) { 115 c->zstream.next_in = p->data[0]+p->linesize[0]*i; 116 c->zstream.avail_in = avctx->width*3; 117 zret = deflate(&(c->zstream), Z_NO_FLUSH); 118 if (zret != Z_OK) { 119 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); 120 return -1; 121 } 122 } 123 zret = deflate(&(c->zstream), Z_FINISH); 124 if (zret != Z_STREAM_END) { 125 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); 126 return -1; 127 } 128 129 for (i = 0; i < c->zstream.total_out; i++) 130 put_bits(&c->pb, 8, c->comp_buf[i]); 131 flush_put_bits(&c->pb); 132 133 return c->zstream.total_out; 134#endif 135} 136 137/* 138 * 139 * Init lcl encoder 140 * 141 */ 142static av_cold int encode_init(AVCodecContext *avctx) 143{ 144 LclEncContext *c = avctx->priv_data; 145 int zret; // Zlib return code 146 147#if !CONFIG_ZLIB 148 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); 149 return 1; 150#else 151 152 c->avctx= avctx; 153 154 assert(avctx->width && avctx->height); 155 156 avctx->extradata= av_mallocz(8); 157 avctx->coded_frame= &c->pic; 158 159 // Will be user settable someday 160 c->compression = 6; 161 c->flags = 0; 162 163 switch(avctx->pix_fmt){ 164 case PIX_FMT_BGR24: 165 c->imgtype = IMGTYPE_RGB24; 166 c->decomp_size = avctx->width * avctx->height * 3; 167 avctx->bits_per_coded_sample= 24; 168 break; 169 default: 170 av_log(avctx, AV_LOG_ERROR, "Input pixel format %s not supported\n", avcodec_get_pix_fmt_name(avctx->pix_fmt)); 171 return -1; 172 } 173 174 ((uint8_t*)avctx->extradata)[0]= 4; 175 ((uint8_t*)avctx->extradata)[1]= 0; 176 ((uint8_t*)avctx->extradata)[2]= 0; 177 ((uint8_t*)avctx->extradata)[3]= 0; 178 ((uint8_t*)avctx->extradata)[4]= c->imgtype; 179 ((uint8_t*)avctx->extradata)[5]= c->compression; 180 ((uint8_t*)avctx->extradata)[6]= c->flags; 181 ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB; 182 c->avctx->extradata_size= 8; 183 184 c->zstream.zalloc = Z_NULL; 185 c->zstream.zfree = Z_NULL; 186 c->zstream.opaque = Z_NULL; 187 zret = deflateInit(&(c->zstream), c->compression); 188 if (zret != Z_OK) { 189 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); 190 return 1; 191 } 192 193 /* Conservative upper bound taken from zlib v1.2.1 source */ 194 c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + 195 ((c->decomp_size + 63) >> 6) + 11; 196 if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { 197 av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); 198 return 1; 199 } 200 201 return 0; 202#endif 203} 204 205/* 206 * 207 * Uninit lcl encoder 208 * 209 */ 210static av_cold int encode_end(AVCodecContext *avctx) 211{ 212 LclEncContext *c = avctx->priv_data; 213 214 av_freep(&avctx->extradata); 215 av_freep(&c->comp_buf); 216#if CONFIG_ZLIB 217 deflateEnd(&(c->zstream)); 218#endif 219 220 return 0; 221} 222 223AVCodec zlib_encoder = { 224 "zlib", 225 CODEC_TYPE_VIDEO, 226 CODEC_ID_ZLIB, 227 sizeof(LclEncContext), 228 encode_init, 229 encode_frame, 230 encode_end, 231 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), 232}; 233