2 * LCL (LossLess Codec Library) Codec
3 * Copyright (c) 2002-2004 Roberto Togni
5 * This file is part of Libav.
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.
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.
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
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)
46 #include "libavutil/internal.h"
47 #include "libavutil/mem.h"
51 typedef struct LclEncContext
{
53 AVCodecContext
*avctx
;
64 static int encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
65 const AVFrame
*pict
, int *got_packet
)
67 LclEncContext
*c
= avctx
->priv_data
;
68 const AVFrame
* const p
= pict
;
70 int zret
; // Zlib return code
71 int max_size
= deflateBound(&c
->zstream
, avctx
->width
* avctx
->height
* 3);
74 (ret
= av_new_packet(pkt
, max_size
)) < 0) {
75 av_log(avctx
, AV_LOG_ERROR
, "Error allocating packet of size %d.\n", max_size
);
79 if(avctx
->pix_fmt
!= AV_PIX_FMT_BGR24
){
80 av_log(avctx
, AV_LOG_ERROR
, "Format not supported!\n");
84 zret
= deflateReset(&c
->zstream
);
86 av_log(avctx
, AV_LOG_ERROR
, "Deflate reset error: %d\n", zret
);
89 c
->zstream
.next_out
= pkt
->data
;
90 c
->zstream
.avail_out
= pkt
->size
;
92 for(i
= avctx
->height
- 1; i
>= 0; i
--) {
93 c
->zstream
.next_in
= p
->data
[0]+p
->linesize
[0]*i
;
94 c
->zstream
.avail_in
= avctx
->width
*3;
95 zret
= deflate(&c
->zstream
, Z_NO_FLUSH
);
97 av_log(avctx
, AV_LOG_ERROR
, "Deflate error: %d\n", zret
);
101 zret
= deflate(&c
->zstream
, Z_FINISH
);
102 if (zret
!= Z_STREAM_END
) {
103 av_log(avctx
, AV_LOG_ERROR
, "Deflate error: %d\n", zret
);
107 pkt
->size
= c
->zstream
.total_out
;
108 pkt
->flags
|= AV_PKT_FLAG_KEY
;
114 static av_cold
int encode_init(AVCodecContext
*avctx
)
116 LclEncContext
*c
= avctx
->priv_data
;
117 int zret
; // Zlib return code
121 assert(avctx
->width
&& avctx
->height
);
123 avctx
->extradata
= av_mallocz(8);
124 if (!avctx
->extradata
)
125 return AVERROR(ENOMEM
);
127 #if FF_API_CODED_FRAME
128 FF_DISABLE_DEPRECATION_WARNINGS
129 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
130 avctx
->coded_frame
->key_frame
= 1;
131 FF_ENABLE_DEPRECATION_WARNINGS
134 // Will be user settable someday
137 c
->imgtype
= IMGTYPE_RGB24
;
138 avctx
->bits_per_coded_sample
= 24;
140 avctx
->extradata
[0]= 4;
141 avctx
->extradata
[1]= 0;
142 avctx
->extradata
[2]= 0;
143 avctx
->extradata
[3]= 0;
144 avctx
->extradata
[4]= c
->imgtype
;
145 avctx
->extradata
[5]= c
->compression
;
146 avctx
->extradata
[6]= c
->flags
;
147 avctx
->extradata
[7]= CODEC_ZLIB
;
148 c
->avctx
->extradata_size
= 8;
150 c
->zstream
.zalloc
= Z_NULL
;
151 c
->zstream
.zfree
= Z_NULL
;
152 c
->zstream
.opaque
= Z_NULL
;
153 zret
= deflateInit(&c
->zstream
, c
->compression
);
155 av_log(avctx
, AV_LOG_ERROR
, "Deflate init error: %d\n", zret
);
156 return AVERROR_UNKNOWN
;
162 static av_cold
int encode_end(AVCodecContext
*avctx
)
164 LclEncContext
*c
= avctx
->priv_data
;
166 av_freep(&avctx
->extradata
);
167 deflateEnd(&c
->zstream
);
172 AVCodec ff_zlib_encoder
= {
174 .long_name
= NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
175 .type
= AVMEDIA_TYPE_VIDEO
,
176 .id
= AV_CODEC_ID_ZLIB
,
177 .priv_data_size
= sizeof(LclEncContext
),
179 .encode2
= encode_frame
,
181 .pix_fmts
= (const enum AVPixelFormat
[]) { AV_PIX_FMT_BGR24
, AV_PIX_FMT_NONE
},
182 .caps_internal
= FF_CODEC_CAP_INIT_THREADSAFE
|
183 FF_CODEC_CAP_INIT_CLEANUP
,