2 * LCL (LossLess Codec Library) Codec
3 * Copyright (c) 2002-2004 Roberto Togni
5 * This file is part of FFmpeg.
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.
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.
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
24 * LCL (LossLess Codec Library) Video Codec
25 * Decoder for MSZH and ZLIB codecs
26 * Experimental encoder for ZLIB RGB24
31 * Ver2.23 By Kenji Oshima 2000.09.20
32 * avimszh.dll, avizlib.dll
34 * A description of the decoding algorithm can be found here:
35 * http://www.pcisys.net/~melanson/codecs
37 * Supports: BGR24 (RGB 24bpp)
44 #include "libavutil/avassert.h"
48 #include "libavutil/internal.h"
49 #include "libavutil/mem.h"
56 typedef struct LclEncContext
{
58 AVCodecContext
*avctx
;
74 static int encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
75 const AVFrame
*p
, int *got_packet
)
77 LclEncContext
*c
= avctx
->priv_data
;
79 int zret
; // Zlib return code
80 int max_size
= deflateBound(&c
->zstream
, avctx
->width
* avctx
->height
* 3);
82 if ((ret
= ff_alloc_packet2(avctx
, pkt
, max_size
)) < 0)
85 if(avctx
->pix_fmt
!= AV_PIX_FMT_BGR24
){
86 av_log(avctx
, AV_LOG_ERROR
, "Format not supported!\n");
90 zret
= deflateReset(&c
->zstream
);
92 av_log(avctx
, AV_LOG_ERROR
, "Deflate reset error: %d\n", zret
);
95 c
->zstream
.next_out
= pkt
->data
;
96 c
->zstream
.avail_out
= pkt
->size
;
98 for(i
= avctx
->height
- 1; i
>= 0; i
--) {
99 c
->zstream
.next_in
= p
->data
[0]+p
->linesize
[0]*i
;
100 c
->zstream
.avail_in
= avctx
->width
*3;
101 zret
= deflate(&c
->zstream
, Z_NO_FLUSH
);
103 av_log(avctx
, AV_LOG_ERROR
, "Deflate error: %d\n", zret
);
107 zret
= deflate(&c
->zstream
, Z_FINISH
);
108 if (zret
!= Z_STREAM_END
) {
109 av_log(avctx
, AV_LOG_ERROR
, "Deflate error: %d\n", zret
);
113 pkt
->size
= c
->zstream
.total_out
;
114 pkt
->flags
|= AV_PKT_FLAG_KEY
;
125 static av_cold
int encode_init(AVCodecContext
*avctx
)
127 LclEncContext
*c
= avctx
->priv_data
;
128 int zret
; // Zlib return code
132 av_assert0(avctx
->width
&& avctx
->height
);
134 avctx
->extradata
= av_mallocz(8 + FF_INPUT_BUFFER_PADDING_SIZE
);
135 if (!avctx
->extradata
)
136 return AVERROR(ENOMEM
);
138 avctx
->coded_frame
= av_frame_alloc();
139 if (!avctx
->coded_frame
)
140 return AVERROR(ENOMEM
);
142 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
143 avctx
->coded_frame
->key_frame
= 1;
145 c
->compression
= avctx
->compression_level
== FF_COMPRESSION_DEFAULT
?
147 av_clip(avctx
->compression_level
, 0, 9);
149 c
->imgtype
= IMGTYPE_RGB24
;
150 avctx
->bits_per_coded_sample
= 24;
152 avctx
->extradata
[0]= 4;
153 avctx
->extradata
[1]= 0;
154 avctx
->extradata
[2]= 0;
155 avctx
->extradata
[3]= 0;
156 avctx
->extradata
[4]= c
->imgtype
;
157 avctx
->extradata
[5]= c
->compression
;
158 avctx
->extradata
[6]= c
->flags
;
159 avctx
->extradata
[7]= CODEC_ZLIB
;
160 c
->avctx
->extradata_size
= 8;
162 c
->zstream
.zalloc
= Z_NULL
;
163 c
->zstream
.zfree
= Z_NULL
;
164 c
->zstream
.opaque
= Z_NULL
;
165 zret
= deflateInit(&c
->zstream
, c
->compression
);
167 av_log(avctx
, AV_LOG_ERROR
, "Deflate init error: %d\n", zret
);
179 static av_cold
int encode_end(AVCodecContext
*avctx
)
181 LclEncContext
*c
= avctx
->priv_data
;
183 av_freep(&avctx
->extradata
);
184 deflateEnd(&c
->zstream
);
186 av_frame_free(&avctx
->coded_frame
);
191 AVCodec ff_zlib_encoder
= {
193 .long_name
= NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
194 .type
= AVMEDIA_TYPE_VIDEO
,
195 .id
= AV_CODEC_ID_ZLIB
,
196 .priv_data_size
= sizeof(LclEncContext
),
198 .encode2
= encode_frame
,
200 .capabilities
= CODEC_CAP_FRAME_THREADS
| CODEC_CAP_INTRA_ONLY
,
201 .pix_fmts
= (const enum AVPixelFormat
[]) { AV_PIX_FMT_BGR24
, AV_PIX_FMT_NONE
},