Statistics
| Branch: | Revision:

ffmpeg / libavcodec / lclenc.c @ 3b855101

History | View | Annotate | Download (4.8 KB)

1
/*
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
/**
23
 * @file libavcodec/lclenc.c
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 "put_bits.h"
46
#include "lcl.h"
47

    
48
#include <zlib.h>
49

    
50
/*
51
 * Decoder context
52
 */
53
typedef struct LclEncContext {
54

    
55
    AVCodecContext *avctx;
56
    AVFrame pic;
57
    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;
71
    z_stream zstream;
72
} LclEncContext;
73

    
74
/*
75
 *
76
 * Encode a frame
77
 *
78
 */
79
static 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

    
86
    *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

    
95
    zret = deflateReset(&c->zstream);
96
    if (zret != Z_OK) {
97
        av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret);
98
        return -1;
99
    }
100
    c->zstream.next_out = buf;
101
    c->zstream.avail_out = buf_size;
102

    
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;
106
        zret = deflate(&c->zstream, Z_NO_FLUSH);
107
        if (zret != Z_OK) {
108
            av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
109
            return -1;
110
        }
111
    }
112
    zret = deflate(&c->zstream, Z_FINISH);
113
    if (zret != Z_STREAM_END) {
114
        av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
115
        return -1;
116
    }
117

    
118
    return c->zstream.total_out;
119
}
120

    
121
/*
122
 *
123
 * Init lcl encoder
124
 *
125
 */
126
static av_cold int encode_init(AVCodecContext *avctx)
127
{
128
    LclEncContext *c = avctx->priv_data;
129
    int zret; // Zlib return code
130

    
131
    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;
146
            avctx->bits_per_coded_sample= 24;
147
            break;
148
        default:
149
            av_log(avctx, AV_LOG_ERROR, "Input pixel format %s not supported\n", avcodec_get_pix_fmt_name(avctx->pix_fmt));
150
            return -1;
151
    }
152

    
153
    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;
161
    c->avctx->extradata_size= 8;
162

    
163
    c->zstream.zalloc = Z_NULL;
164
    c->zstream.zfree = Z_NULL;
165
    c->zstream.opaque = Z_NULL;
166
    zret = deflateInit(&c->zstream, c->compression);
167
    if (zret != Z_OK) {
168
        av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret);
169
        return 1;
170
    }
171

    
172
    return 0;
173
}
174

    
175
/*
176
 *
177
 * Uninit lcl encoder
178
 *
179
 */
180
static av_cold int encode_end(AVCodecContext *avctx)
181
{
182
    LclEncContext *c = avctx->priv_data;
183

    
184
    av_freep(&avctx->extradata);
185
    av_freep(&c->comp_buf);
186
    deflateEnd(&c->zstream);
187

    
188
    return 0;
189
}
190

    
191
AVCodec zlib_encoder = {
192
    "zlib",
193
    CODEC_TYPE_VIDEO,
194
    CODEC_ID_ZLIB,
195
    sizeof(LclEncContext),
196
    encode_init,
197
    encode_frame,
198
    encode_end,
199
    .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
200
};