1/* 2 * LCL (LossLess Codec Library) Codec 3 * Copyright (c) 2002-2004 Roberto Togni 4 * 5 * This file is part of Libav. 6 * 7 * Libav 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 * Libav 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 Libav; 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= AV_PICTURE_TYPE_I; 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 c->imgtype = IMGTYPE_RGB24; 134 avctx->bits_per_coded_sample= 24; 135 136 avctx->extradata[0]= 4; 137 avctx->extradata[1]= 0; 138 avctx->extradata[2]= 0; 139 avctx->extradata[3]= 0; 140 avctx->extradata[4]= c->imgtype; 141 avctx->extradata[5]= c->compression; 142 avctx->extradata[6]= c->flags; 143 avctx->extradata[7]= CODEC_ZLIB; 144 c->avctx->extradata_size= 8; 145 146 c->zstream.zalloc = Z_NULL; 147 c->zstream.zfree = Z_NULL; 148 c->zstream.opaque = Z_NULL; 149 zret = deflateInit(&c->zstream, c->compression); 150 if (zret != Z_OK) { 151 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); 152 return 1; 153 } 154 155 return 0; 156} 157 158/* 159 * 160 * Uninit lcl encoder 161 * 162 */ 163static av_cold int encode_end(AVCodecContext *avctx) 164{ 165 LclEncContext *c = avctx->priv_data; 166 167 av_freep(&avctx->extradata); 168 deflateEnd(&c->zstream); 169 170 return 0; 171} 172 173AVCodec ff_zlib_encoder = { 174 .name = "zlib", 175 .type = AVMEDIA_TYPE_VIDEO, 176 .id = CODEC_ID_ZLIB, 177 .priv_data_size = sizeof(LclEncContext), 178 .init = encode_init, 179 .encode = encode_frame, 180 .close = encode_end, 181 .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_BGR24, PIX_FMT_NONE }, 182 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), 183}; 184