blob: 451f8e607e474c4baccf21e5c843e52832707317 [file] [log] [blame]
Måns Rullgård00eb27f2007-07-12 22:40:331/*
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/**
Diego Biurrunbad55372009-02-01 02:00:1923 * @file libavcodec/lclenc.c
Måns Rullgård00eb27f2007-07-12 22:40:3324 * 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"
Stefano Sabatinib2755002009-04-12 08:35:2645#include "put_bits.h"
Måns Rullgård00eb27f2007-07-12 22:40:3346#include "lcl.h"
47
Måns Rullgård00eb27f2007-07-12 22:40:3348#include <zlib.h>
Måns Rullgård00eb27f2007-07-12 22:40:3349
50/*
51 * Decoder context
52 */
53typedef struct LclEncContext {
54
Reimar Döffinger8f033e32009-05-31 08:38:5155 AVCodecContext *avctx;
56 AVFrame pic;
Måns Rullgård00eb27f2007-07-12 22:40:3357 PutBitContext pb;
58
59 // Image type
60 int imgtype;
61 // Compression type
62 int compression;
63 // Flags
64 int flags;
65 // Decompressed data size
66 unsigned int decomp_size;
67 // Maximum compressed data size
68 unsigned int max_comp_size;
69 // Compression buffer
70 unsigned char* comp_buf;
Måns Rullgård00eb27f2007-07-12 22:40:3371 z_stream zstream;
Måns Rullgård00eb27f2007-07-12 22:40:3372} LclEncContext;
73
74/*
75 *
76 * Encode a frame
77 *
78 */
79static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
80 LclEncContext *c = avctx->priv_data;
81 AVFrame *pict = data;
82 AVFrame * const p = &c->pic;
83 int i;
84 int zret; // Zlib return code
85
Måns Rullgård00eb27f2007-07-12 22:40:3386 *p = *pict;
87 p->pict_type= FF_I_TYPE;
88 p->key_frame= 1;
89
90 if(avctx->pix_fmt != PIX_FMT_BGR24){
91 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
92 return -1;
93 }
94
Reimar Döffinger32b3ab92009-05-31 08:41:1195 zret = deflateReset(&c->zstream);
Måns Rullgård00eb27f2007-07-12 22:40:3396 if (zret != Z_OK) {
97 av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret);
98 return -1;
99 }
Reimar Döffingere786d3c2009-05-31 08:49:27100 c->zstream.next_out = buf;
101 c->zstream.avail_out = buf_size;
Måns Rullgård00eb27f2007-07-12 22:40:33102
103 for(i = avctx->height - 1; i >= 0; i--) {
104 c->zstream.next_in = p->data[0]+p->linesize[0]*i;
105 c->zstream.avail_in = avctx->width*3;
Reimar Döffinger32b3ab92009-05-31 08:41:11106 zret = deflate(&c->zstream, Z_NO_FLUSH);
Måns Rullgård00eb27f2007-07-12 22:40:33107 if (zret != Z_OK) {
108 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
109 return -1;
110 }
111 }
Reimar Döffinger32b3ab92009-05-31 08:41:11112 zret = deflate(&c->zstream, Z_FINISH);
Måns Rullgård00eb27f2007-07-12 22:40:33113 if (zret != Z_STREAM_END) {
114 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
115 return -1;
116 }
117
Måns Rullgård00eb27f2007-07-12 22:40:33118 return c->zstream.total_out;
Måns Rullgård00eb27f2007-07-12 22:40:33119}
120
121/*
122 *
123 * Init lcl encoder
124 *
125 */
Zuxy Meng98a6fff2008-03-21 03:11:20126static av_cold int encode_init(AVCodecContext *avctx)
Måns Rullgård00eb27f2007-07-12 22:40:33127{
128 LclEncContext *c = avctx->priv_data;
129 int zret; // Zlib return code
130
Måns Rullgård00eb27f2007-07-12 22:40:33131 c->avctx= avctx;
132
133 assert(avctx->width && avctx->height);
134
135 avctx->extradata= av_mallocz(8);
136 avctx->coded_frame= &c->pic;
137
138 // Will be user settable someday
139 c->compression = 6;
140 c->flags = 0;
141
142 switch(avctx->pix_fmt){
143 case PIX_FMT_BGR24:
144 c->imgtype = IMGTYPE_RGB24;
145 c->decomp_size = avctx->width * avctx->height * 3;
Luca Abenidd1c8f32008-09-08 14:24:59146 avctx->bits_per_coded_sample= 24;
Måns Rullgård00eb27f2007-07-12 22:40:33147 break;
148 default:
Stefano Sabatini747d1b82008-06-19 10:12:15149 av_log(avctx, AV_LOG_ERROR, "Input pixel format %s not supported\n", avcodec_get_pix_fmt_name(avctx->pix_fmt));
Måns Rullgård00eb27f2007-07-12 22:40:33150 return -1;
151 }
152
Reimar Döffinger3b855102009-05-31 08:51:30153 avctx->extradata[0]= 4;
154 avctx->extradata[1]= 0;
155 avctx->extradata[2]= 0;
156 avctx->extradata[3]= 0;
157 avctx->extradata[4]= c->imgtype;
158 avctx->extradata[5]= c->compression;
159 avctx->extradata[6]= c->flags;
160 avctx->extradata[7]= CODEC_ZLIB;
Måns Rullgård00eb27f2007-07-12 22:40:33161 c->avctx->extradata_size= 8;
162
163 c->zstream.zalloc = Z_NULL;
164 c->zstream.zfree = Z_NULL;
165 c->zstream.opaque = Z_NULL;
Reimar Döffinger32b3ab92009-05-31 08:41:11166 zret = deflateInit(&c->zstream, c->compression);
Måns Rullgård00eb27f2007-07-12 22:40:33167 if (zret != Z_OK) {
168 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret);
169 return 1;
170 }
171
Måns Rullgård00eb27f2007-07-12 22:40:33172 return 0;
Måns Rullgård00eb27f2007-07-12 22:40:33173}
174
175/*
176 *
177 * Uninit lcl encoder
178 *
179 */
Zuxy Meng98a6fff2008-03-21 03:11:20180static av_cold int encode_end(AVCodecContext *avctx)
Måns Rullgård00eb27f2007-07-12 22:40:33181{
182 LclEncContext *c = avctx->priv_data;
183
184 av_freep(&avctx->extradata);
185 av_freep(&c->comp_buf);
Reimar Döffinger32b3ab92009-05-31 08:41:11186 deflateEnd(&c->zstream);
Måns Rullgård00eb27f2007-07-12 22:40:33187
188 return 0;
189}
190
191AVCodec zlib_encoder = {
192 "zlib",
193 CODEC_TYPE_VIDEO,
194 CODEC_ID_ZLIB,
195 sizeof(LclEncContext),
196 encode_init,
197 encode_frame,
198 encode_end,
Stefano Sabatinife4bf372008-06-12 21:50:13199 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
Måns Rullgård00eb27f2007-07-12 22:40:33200};