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 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 "lcl.h" 46 47#include <zlib.h> 48 49/* 50 * Decoder context 51 */ 52typedef struct LclEncContext { 53 54 AVCodecContext *avctx; 55 AVFrame pic; 56 57 // Image type 58 int imgtype; 59 // Compression type 60 int compression; 61 // Flags 62 int flags; 63 z_stream zstream; 64} LclEncContext; 65 66/* 67 * 68 * Encode a frame 69 * 70 */ 71static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ 72 LclEncContext *c = avctx->priv_data; 73 AVFrame *pict = data; 74 AVFrame * const p = &c->pic; 75 int i; 76 int zret; // Zlib return code 77 78 *p = *pict; 79 p->pict_type= FF_I_TYPE; 80 p->key_frame= 1; 81 82 if(avctx->pix_fmt != PIX_FMT_BGR24){ 83 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); 84 return -1; 85 } 86 87 zret = deflateReset(&c->zstream); 88 if (zret != Z_OK) { 89 av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); 90 return -1; 91 } 92 c->zstream.next_out = buf; 93 c->zstream.avail_out = buf_size; 94 95 for(i = avctx->height - 1; i >= 0; i--) { 96 c->zstream.next_in = p->data[0]+p->linesize[0]*i; 97 c->zstream.avail_in = avctx->width*3; 98 zret = deflate(&c->zstream, Z_NO_FLUSH); 99 if (zret != Z_OK) { 100 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); 101 return -1; 102 } 103 } 104 zret = deflate(&c->zstream, Z_FINISH); 105 if (zret != Z_STREAM_END) { 106 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); 107 return -1; 108 } 109 110 return c->zstream.total_out; 111} 112 113/* 114 * 115 * Init lcl encoder 116 * 117 */ 118static av_cold int encode_init(AVCodecContext *avctx) 119{ 120 LclEncContext *c = avctx->priv_data; 121 int zret; // Zlib return code 122 123 c->avctx= avctx; 124 125 assert(avctx->width && avctx->height); 126 127 avctx->extradata= av_mallocz(8); 128 avctx->coded_frame= &c->pic; 129 130 // Will be user settable someday 131 c->compression = 6; 132 c->flags = 0; 133 134 switch(avctx->pix_fmt){ 135 case PIX_FMT_BGR24: 136 c->imgtype = IMGTYPE_RGB24; 137 avctx->bits_per_coded_sample= 24; 138 break; 139 default: 140 av_log(avctx, AV_LOG_ERROR, "Input pixel format %s not supported\n", avcodec_get_pix_fmt_name(avctx->pix_fmt)); 141 return -1; 142 } 143 144 avctx->extradata[0]= 4; 145 avctx->extradata[1]= 0; 146 avctx->extradata[2]= 0; 147 avctx->extradata[3]= 0; 148 avctx->extradata[4]= c->imgtype; 149 avctx->extradata[5]= c->compression; 150 avctx->extradata[6]= c->flags; 151 avctx->extradata[7]= CODEC_ZLIB; 152 c->avctx->extradata_size= 8; 153 154 c->zstream.zalloc = Z_NULL; 155 c->zstream.zfree = Z_NULL; 156 c->zstream.opaque = Z_NULL; 157 zret = deflateInit(&c->zstream, c->compression); 158 if (zret != Z_OK) { 159 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); 160 return 1; 161 } 162 163 return 0; 164} 165 166/* 167 * 168 * Uninit lcl encoder 169 * 170 */ 171static av_cold int encode_end(AVCodecContext *avctx) 172{ 173 LclEncContext *c = avctx->priv_data; 174 175 av_freep(&avctx->extradata); 176 deflateEnd(&c->zstream); 177 178 return 0; 179} 180 181AVCodec zlib_encoder = { 182 "zlib", 183 AVMEDIA_TYPE_VIDEO, 184 CODEC_ID_ZLIB, 185 sizeof(LclEncContext), 186 encode_init, 187 encode_frame, 188 encode_end, 189 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), 190}; 191