yading@10: /* yading@10: * LCL (LossLess Codec Library) Codec yading@10: * Copyright (c) 2002-2004 Roberto Togni yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * LCL (LossLess Codec Library) Video Codec yading@10: * Decoder for MSZH and ZLIB codecs yading@10: * Experimental encoder for ZLIB RGB24 yading@10: * yading@10: * Fourcc: MSZH, ZLIB yading@10: * yading@10: * Original Win32 dll: yading@10: * Ver2.23 By Kenji Oshima 2000.09.20 yading@10: * avimszh.dll, avizlib.dll yading@10: * yading@10: * A description of the decoding algorithm can be found here: yading@10: * http://www.pcisys.net/~melanson/codecs yading@10: * yading@10: * Supports: BGR24 (RGB 24bpp) yading@10: * yading@10: */ yading@10: yading@10: #include yading@10: #include yading@10: yading@10: #include "libavutil/avassert.h" yading@10: #include "avcodec.h" yading@10: #include "internal.h" yading@10: #include "lcl.h" yading@10: #include "libavutil/internal.h" yading@10: #include "libavutil/mem.h" yading@10: yading@10: #include yading@10: yading@10: /* yading@10: * Decoder context yading@10: */ yading@10: typedef struct LclEncContext { yading@10: yading@10: AVCodecContext *avctx; yading@10: AVFrame pic; yading@10: yading@10: // Image type yading@10: int imgtype; yading@10: // Compression type yading@10: int compression; yading@10: // Flags yading@10: int flags; yading@10: z_stream zstream; yading@10: } LclEncContext; yading@10: yading@10: /* yading@10: * yading@10: * Encode a frame yading@10: * yading@10: */ yading@10: static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, yading@10: const AVFrame *pict, int *got_packet) yading@10: { yading@10: LclEncContext *c = avctx->priv_data; yading@10: AVFrame * const p = &c->pic; yading@10: int i, ret; yading@10: int zret; // Zlib return code yading@10: int max_size = deflateBound(&c->zstream, avctx->width * avctx->height * 3); yading@10: yading@10: if ((ret = ff_alloc_packet2(avctx, pkt, max_size)) < 0) yading@10: return ret; yading@10: yading@10: *p = *pict; yading@10: p->pict_type= AV_PICTURE_TYPE_I; yading@10: p->key_frame= 1; yading@10: yading@10: if(avctx->pix_fmt != AV_PIX_FMT_BGR24){ yading@10: av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); yading@10: return -1; yading@10: } yading@10: yading@10: zret = deflateReset(&c->zstream); yading@10: if (zret != Z_OK) { yading@10: av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); yading@10: return -1; yading@10: } yading@10: c->zstream.next_out = pkt->data; yading@10: c->zstream.avail_out = pkt->size; yading@10: yading@10: for(i = avctx->height - 1; i >= 0; i--) { yading@10: c->zstream.next_in = p->data[0]+p->linesize[0]*i; yading@10: c->zstream.avail_in = avctx->width*3; yading@10: zret = deflate(&c->zstream, Z_NO_FLUSH); yading@10: if (zret != Z_OK) { yading@10: av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); yading@10: return -1; yading@10: } yading@10: } yading@10: zret = deflate(&c->zstream, Z_FINISH); yading@10: if (zret != Z_STREAM_END) { yading@10: av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); yading@10: return -1; yading@10: } yading@10: yading@10: pkt->size = c->zstream.total_out; yading@10: pkt->flags |= AV_PKT_FLAG_KEY; yading@10: *got_packet = 1; yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: /* yading@10: * yading@10: * Init lcl encoder yading@10: * yading@10: */ yading@10: static av_cold int encode_init(AVCodecContext *avctx) yading@10: { yading@10: LclEncContext *c = avctx->priv_data; yading@10: int zret; // Zlib return code yading@10: yading@10: c->avctx= avctx; yading@10: yading@10: av_assert0(avctx->width && avctx->height); yading@10: yading@10: avctx->extradata= av_mallocz(8); yading@10: avctx->coded_frame= &c->pic; yading@10: yading@10: c->compression = avctx->compression_level == FF_COMPRESSION_DEFAULT ? yading@10: COMP_ZLIB_NORMAL : yading@10: av_clip(avctx->compression_level, 0, 9); yading@10: c->flags = 0; yading@10: c->imgtype = IMGTYPE_RGB24; yading@10: avctx->bits_per_coded_sample= 24; yading@10: yading@10: avctx->extradata[0]= 4; yading@10: avctx->extradata[1]= 0; yading@10: avctx->extradata[2]= 0; yading@10: avctx->extradata[3]= 0; yading@10: avctx->extradata[4]= c->imgtype; yading@10: avctx->extradata[5]= c->compression; yading@10: avctx->extradata[6]= c->flags; yading@10: avctx->extradata[7]= CODEC_ZLIB; yading@10: c->avctx->extradata_size= 8; yading@10: yading@10: c->zstream.zalloc = Z_NULL; yading@10: c->zstream.zfree = Z_NULL; yading@10: c->zstream.opaque = Z_NULL; yading@10: zret = deflateInit(&c->zstream, c->compression); yading@10: if (zret != Z_OK) { yading@10: av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); yading@10: return 1; yading@10: } yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: /* yading@10: * yading@10: * Uninit lcl encoder yading@10: * yading@10: */ yading@10: static av_cold int encode_end(AVCodecContext *avctx) yading@10: { yading@10: LclEncContext *c = avctx->priv_data; yading@10: yading@10: av_freep(&avctx->extradata); yading@10: deflateEnd(&c->zstream); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: AVCodec ff_zlib_encoder = { yading@10: .name = "zlib", yading@10: .type = AVMEDIA_TYPE_VIDEO, yading@10: .id = AV_CODEC_ID_ZLIB, yading@10: .priv_data_size = sizeof(LclEncContext), yading@10: .init = encode_init, yading@10: .encode2 = encode_frame, yading@10: .close = encode_end, yading@10: .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_NONE }, yading@10: .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), yading@10: };