Mercurial > libavcodec.hg
annotate lcl.c @ 5040:5c6cd6601371 libavcodec
change brute force search to min-heap. 3.6x faster generate_len_table, 8% faster ffvhuff encoding.
author | lorenm |
---|---|
date | Sat, 19 May 2007 02:32:59 +0000 |
parents | f99e40a7155b |
children | bff60ecc02f9 |
rev | line source |
---|---|
1743 | 1 /* |
2 * LCL (LossLess Codec Library) Codec | |
3 * Copyright (c) 2002-2004 Roberto Togni | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1743 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1743 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1743 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1743 | 20 * |
21 */ | |
22 | |
23 /** | |
24 * @file lcl.c | |
25 * LCL (LossLess Codec Library) Video Codec | |
26 * Decoder for MSZH and ZLIB codecs | |
27 * Experimental encoder for ZLIB RGB24 | |
28 * | |
29 * Fourcc: MSZH, ZLIB | |
30 * | |
31 * Original Win32 dll: | |
32 * Ver2.23 By Kenji Oshima 2000.09.20 | |
33 * avimszh.dll, avizlib.dll | |
34 * | |
35 * A description of the decoding algorithm can be found here: | |
36 * http://www.pcisys.net/~melanson/codecs | |
37 * | |
38 * Supports: BGR24 (RGB 24bpp) | |
39 * | |
40 */ | |
41 | |
42 #include <stdio.h> | |
43 #include <stdlib.h> | |
44 | |
4962
f99e40a7155b
Remove redundant #inclusion of common.h, avcodec.h already #includes it.
diego
parents:
4827
diff
changeset
|
45 #include "avcodec.h" |
2398
582e635cfa08
common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents:
2250
diff
changeset
|
46 #include "bitstream.h" |
1743 | 47 |
48 #ifdef CONFIG_ZLIB | |
49 #include <zlib.h> | |
50 #endif | |
51 | |
52 | |
53 #define BMPTYPE_YUV 1 | |
54 #define BMPTYPE_RGB 2 | |
55 | |
56 #define IMGTYPE_YUV111 0 | |
57 #define IMGTYPE_YUV422 1 | |
58 #define IMGTYPE_RGB24 2 | |
59 #define IMGTYPE_YUV411 3 | |
60 #define IMGTYPE_YUV211 4 | |
61 #define IMGTYPE_YUV420 5 | |
62 | |
63 #define COMP_MSZH 0 | |
64 #define COMP_MSZH_NOCOMP 1 | |
65 #define COMP_ZLIB_HISPEED 1 | |
66 #define COMP_ZLIB_HICOMP 9 | |
67 #define COMP_ZLIB_NORMAL -1 | |
68 | |
69 #define FLAG_MULTITHREAD 1 | |
70 #define FLAG_NULLFRAME 2 | |
71 #define FLAG_PNGFILTER 4 | |
72 #define FLAGMASK_UNUSED 0xf8 | |
73 | |
74 #define CODEC_MSZH 1 | |
75 #define CODEC_ZLIB 3 | |
76 | |
77 #define FOURCC_MSZH mmioFOURCC('M','S','Z','H') | |
78 #define FOURCC_ZLIB mmioFOURCC('Z','L','I','B') | |
79 | |
80 /* | |
81 * Decoder context | |
82 */ | |
83 typedef struct LclContext { | |
84 | |
2979 | 85 AVCodecContext *avctx; |
86 AVFrame pic; | |
1743 | 87 PutBitContext pb; |
88 | |
89 // Image type | |
90 int imgtype; | |
91 // Compression type | |
92 int compression; | |
93 // Flags | |
94 int flags; | |
95 // Decompressed data size | |
96 unsigned int decomp_size; | |
97 // Decompression buffer | |
98 unsigned char* decomp_buf; | |
99 // Maximum compressed data size | |
100 unsigned int max_comp_size; | |
101 // Compression buffer | |
102 unsigned char* comp_buf; | |
103 #ifdef CONFIG_ZLIB | |
104 z_stream zstream; | |
105 #endif | |
106 } LclContext; | |
107 | |
108 | |
109 /* | |
110 * | |
111 * Helper functions | |
112 * | |
113 */ | |
114 static inline unsigned char fix (int pix14) | |
115 { | |
116 int tmp; | |
117 | |
118 tmp = (pix14 + 0x80000) >> 20; | |
119 if (tmp < 0) | |
120 return 0; | |
121 if (tmp > 255) | |
122 return 255; | |
123 return tmp; | |
124 } | |
125 | |
126 | |
127 | |
128 static inline unsigned char get_b (unsigned char yq, signed char bq) | |
129 { | |
130 return fix((yq << 20) + bq * 1858076); | |
131 } | |
132 | |
133 | |
134 | |
135 static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) | |
136 { | |
137 return fix((yq << 20) - bq * 360857 - rq * 748830); | |
138 } | |
139 | |
140 | |
141 | |
142 static inline unsigned char get_r (unsigned char yq, signed char rq) | |
143 { | |
144 return fix((yq << 20) + rq * 1470103); | |
145 } | |
146 | |
147 | |
148 | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
149 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
1743 | 150 { |
151 unsigned char *destptr_bak = destptr; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
152 unsigned char *destptr_end = destptr + destsize; |
1743 | 153 unsigned char mask = 0; |
154 unsigned char maskbit = 0; | |
155 unsigned int ofs, cnt; | |
2967 | 156 |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
157 while ((srclen > 0) && (destptr < destptr_end)) { |
1743 | 158 if (maskbit == 0) { |
159 mask = *(srcptr++); | |
160 maskbit = 8; | |
161 srclen--; | |
162 continue; | |
163 } | |
164 if ((mask & (1 << (--maskbit))) == 0) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
165 if (destptr + 4 > destptr_end) |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
166 break; |
1743 | 167 *(int*)destptr = *(int*)srcptr; |
168 srclen -= 4; | |
169 destptr += 4; | |
170 srcptr += 4; | |
171 } else { | |
172 ofs = *(srcptr++); | |
173 cnt = *(srcptr++); | |
174 ofs += cnt * 256;; | |
175 cnt = ((cnt >> 3) & 0x1f) + 1; | |
176 ofs &= 0x7ff; | |
177 srclen -= 2; | |
178 cnt *= 4; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
179 if (destptr + cnt > destptr_end) { |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
180 cnt = destptr_end - destptr; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
181 } |
1743 | 182 for (; cnt > 0; cnt--) { |
183 *(destptr) = *(destptr - ofs); | |
184 destptr++; | |
185 } | |
186 } | |
187 } | |
188 | |
189 return (destptr - destptr_bak); | |
190 } | |
191 | |
192 | |
193 | |
3777 | 194 #ifdef CONFIG_DECODERS |
1743 | 195 /* |
196 * | |
197 * Decode a frame | |
198 * | |
199 */ | |
200 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) | |
201 { | |
4827 | 202 LclContext * const c = avctx->priv_data; |
2979 | 203 unsigned char *encoded = (unsigned char *)buf; |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
204 unsigned int pixel_ptr; |
1743 | 205 int row, col; |
206 unsigned char *outptr; | |
207 unsigned int width = avctx->width; // Real image width | |
208 unsigned int height = avctx->height; // Real image height | |
209 unsigned int mszh_dlen; | |
210 unsigned char yq, y1q, uq, vq; | |
211 int uqvq; | |
212 unsigned int mthread_inlen, mthread_outlen; | |
213 #ifdef CONFIG_ZLIB | |
214 int zret; // Zlib return code | |
215 #endif | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
216 unsigned int len = buf_size; |
1743 | 217 |
2979 | 218 if(c->pic.data[0]) |
219 avctx->release_buffer(avctx, &c->pic); | |
1743 | 220 |
2979 | 221 c->pic.reference = 0; |
222 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; | |
223 if(avctx->get_buffer(avctx, &c->pic) < 0){ | |
224 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
225 return -1; | |
226 } | |
1743 | 227 |
228 outptr = c->pic.data[0]; // Output image pointer | |
229 | |
230 /* Decompress frame */ | |
231 switch (avctx->codec_id) { | |
232 case CODEC_ID_MSZH: | |
233 switch (c->compression) { | |
234 case COMP_MSZH: | |
235 if (c->flags & FLAG_MULTITHREAD) { | |
236 mthread_inlen = *((unsigned int*)encoded); | |
237 mthread_outlen = *((unsigned int*)(encoded+4)); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
238 if (mthread_outlen > c->decomp_size) // this should not happen |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
239 mthread_outlen = c->decomp_size; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
240 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); |
1743 | 241 if (mthread_outlen != mszh_dlen) { |
242 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", | |
243 mthread_outlen, mszh_dlen); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
244 return -1; |
1743 | 245 } |
246 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
247 c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
248 if (mthread_outlen != mszh_dlen) { |
1743 | 249 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
250 mthread_outlen, mszh_dlen); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
251 return -1; |
1743 | 252 } |
253 encoded = c->decomp_buf; | |
254 len = c->decomp_size; | |
255 } else { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
256 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); |
1743 | 257 if (c->decomp_size != mszh_dlen) { |
258 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", | |
259 c->decomp_size, mszh_dlen); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
260 return -1; |
1743 | 261 } |
262 encoded = c->decomp_buf; | |
263 len = mszh_dlen; | |
264 } | |
265 break; | |
266 case COMP_MSZH_NOCOMP: | |
267 break; | |
268 default: | |
269 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); | |
270 return -1; | |
271 } | |
272 break; | |
273 case CODEC_ID_ZLIB: | |
274 #ifdef CONFIG_ZLIB | |
275 /* Using the original dll with normal compression (-1) and RGB format | |
276 * gives a file with ZLIB fourcc, but frame is really uncompressed. | |
277 * To be sure that's true check also frame size */ | |
278 if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) && | |
279 (len == width * height * 3)) | |
280 break; | |
281 zret = inflateReset(&(c->zstream)); | |
282 if (zret != Z_OK) { | |
283 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); | |
284 return -1; | |
285 } | |
286 if (c->flags & FLAG_MULTITHREAD) { | |
287 mthread_inlen = *((unsigned int*)encoded); | |
288 mthread_outlen = *((unsigned int*)(encoded+4)); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
289 if (mthread_outlen > c->decomp_size) |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
290 mthread_outlen = c->decomp_size; |
1743 | 291 c->zstream.next_in = encoded + 8; |
292 c->zstream.avail_in = mthread_inlen; | |
293 c->zstream.next_out = c->decomp_buf; | |
2967 | 294 c->zstream.avail_out = c->decomp_size; |
1743 | 295 zret = inflate(&(c->zstream), Z_FINISH); |
296 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
297 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); | |
298 return -1; | |
299 } | |
300 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { | |
301 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", | |
302 mthread_outlen, c->zstream.total_out); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
303 return -1; |
1743 | 304 } |
305 zret = inflateReset(&(c->zstream)); | |
306 if (zret != Z_OK) { | |
307 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); | |
308 return -1; | |
309 } | |
310 c->zstream.next_in = encoded + 8 + mthread_inlen; | |
311 c->zstream.avail_in = len - mthread_inlen; | |
312 c->zstream.next_out = c->decomp_buf + mthread_outlen; | |
2967 | 313 c->zstream.avail_out = c->decomp_size - mthread_outlen; |
1743 | 314 zret = inflate(&(c->zstream), Z_FINISH); |
315 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
316 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); | |
317 return -1; | |
318 } | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
319 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { |
1743 | 320 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
321 mthread_outlen, c->zstream.total_out); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
322 return -1; |
1743 | 323 } |
324 } else { | |
325 c->zstream.next_in = encoded; | |
326 c->zstream.avail_in = len; | |
327 c->zstream.next_out = c->decomp_buf; | |
328 c->zstream.avail_out = c->decomp_size; | |
329 zret = inflate(&(c->zstream), Z_FINISH); | |
330 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
331 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); | |
332 return -1; | |
333 } | |
334 if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { | |
335 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", | |
336 c->decomp_size, c->zstream.total_out); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
337 return -1; |
1743 | 338 } |
339 } | |
340 encoded = c->decomp_buf; | |
341 len = c->decomp_size;; | |
342 #else | |
343 av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); | |
344 return -1; | |
345 #endif | |
346 break; | |
347 default: | |
348 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); | |
349 return -1; | |
350 } | |
351 | |
352 | |
353 /* Apply PNG filter */ | |
354 if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) { | |
355 switch (c->imgtype) { | |
356 case IMGTYPE_YUV111: | |
357 case IMGTYPE_RGB24: | |
358 for (row = 0; row < height; row++) { | |
359 pixel_ptr = row * width * 3; | |
360 yq = encoded[pixel_ptr++]; | |
361 uqvq = encoded[pixel_ptr++]; | |
2979 | 362 uqvq+=(encoded[pixel_ptr++] << 8); |
1743 | 363 for (col = 1; col < width; col++) { |
364 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
365 uqvq -= (encoded[pixel_ptr+1] | (encoded[pixel_ptr+2]<<8)); | |
366 encoded[pixel_ptr+1] = (uqvq) & 0xff; | |
367 encoded[pixel_ptr+2] = ((uqvq)>>8) & 0xff; | |
368 pixel_ptr += 3; | |
369 } | |
370 } | |
371 break; | |
372 case IMGTYPE_YUV422: | |
373 for (row = 0; row < height; row++) { | |
374 pixel_ptr = row * width * 2; | |
375 yq = uq = vq =0; | |
376 for (col = 0; col < width/4; col++) { | |
377 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
378 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
379 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
380 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
381 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
382 encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; | |
383 encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; | |
384 encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; | |
385 pixel_ptr += 8; | |
386 } | |
387 } | |
388 break; | |
389 case IMGTYPE_YUV411: | |
390 for (row = 0; row < height; row++) { | |
391 pixel_ptr = row * width / 2 * 3; | |
392 yq = uq = vq =0; | |
393 for (col = 0; col < width/4; col++) { | |
394 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
395 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
396 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
397 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
398 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
399 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
400 pixel_ptr += 6; | |
401 } | |
402 } | |
403 break; | |
404 case IMGTYPE_YUV211: | |
405 for (row = 0; row < height; row++) { | |
406 pixel_ptr = row * width * 2; | |
407 yq = uq = vq =0; | |
408 for (col = 0; col < width/2; col++) { | |
409 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
410 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
411 encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; | |
412 encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; | |
413 pixel_ptr += 4; | |
414 } | |
415 } | |
416 break; | |
417 case IMGTYPE_YUV420: | |
418 for (row = 0; row < height/2; row++) { | |
419 pixel_ptr = row * width * 3; | |
420 yq = y1q = uq = vq =0; | |
421 for (col = 0; col < width/2; col++) { | |
422 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
423 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
424 encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; | |
425 encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; | |
426 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
427 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
428 pixel_ptr += 6; | |
429 } | |
430 } | |
431 break; | |
432 default: | |
433 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); | |
434 return -1; | |
435 } | |
436 } | |
437 | |
438 /* Convert colorspace */ | |
439 switch (c->imgtype) { | |
440 case IMGTYPE_YUV111: | |
441 for (row = height - 1; row >= 0; row--) { | |
442 pixel_ptr = row * c->pic.linesize[0]; | |
443 for (col = 0; col < width; col++) { | |
444 outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); | |
445 outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); | |
446 outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); | |
447 encoded += 3; | |
448 } | |
449 } | |
450 break; | |
451 case IMGTYPE_YUV422: | |
452 for (row = height - 1; row >= 0; row--) { | |
453 pixel_ptr = row * c->pic.linesize[0]; | |
454 for (col = 0; col < width/4; col++) { | |
455 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | |
456 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); | |
457 outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); | |
458 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | |
459 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); | |
460 outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); | |
461 outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); | |
462 outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); | |
463 outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); | |
464 outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); | |
465 outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); | |
466 outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); | |
467 encoded += 8; | |
468 } | |
469 } | |
470 break; | |
471 case IMGTYPE_RGB24: | |
472 for (row = height - 1; row >= 0; row--) { | |
473 pixel_ptr = row * c->pic.linesize[0]; | |
474 for (col = 0; col < width; col++) { | |
475 outptr[pixel_ptr++] = encoded[0]; | |
476 outptr[pixel_ptr++] = encoded[1]; | |
477 outptr[pixel_ptr++] = encoded[2]; | |
478 encoded += 3; | |
479 } | |
480 } | |
481 break; | |
482 case IMGTYPE_YUV411: | |
483 for (row = height - 1; row >= 0; row--) { | |
484 pixel_ptr = row * c->pic.linesize[0]; | |
485 for (col = 0; col < width/4; col++) { | |
486 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | |
487 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); | |
488 outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); | |
489 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | |
490 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); | |
491 outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); | |
492 outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); | |
493 outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); | |
494 outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); | |
495 outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); | |
496 outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); | |
497 outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); | |
498 encoded += 6; | |
499 } | |
500 } | |
501 break; | |
502 case IMGTYPE_YUV211: | |
503 for (row = height - 1; row >= 0; row--) { | |
504 pixel_ptr = row * c->pic.linesize[0]; | |
505 for (col = 0; col < width/2; col++) { | |
506 outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); | |
507 outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); | |
508 outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); | |
509 outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); | |
510 outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); | |
511 outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); | |
512 encoded += 4; | |
513 } | |
514 } | |
515 break; | |
516 case IMGTYPE_YUV420: | |
517 for (row = height / 2 - 1; row >= 0; row--) { | |
518 pixel_ptr = 2 * row * c->pic.linesize[0]; | |
519 for (col = 0; col < width/2; col++) { | |
520 outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); | |
521 outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); | |
522 outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); | |
523 outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); | |
524 outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); | |
525 outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); | |
526 outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); | |
527 outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); | |
528 outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); | |
529 outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); | |
530 outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); | |
531 outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); | |
532 pixel_ptr += 6; | |
533 encoded += 6; | |
534 } | |
535 } | |
536 break; | |
537 default: | |
538 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); | |
539 return -1; | |
540 } | |
541 | |
542 *data_size = sizeof(AVFrame); | |
543 *(AVFrame*)data = c->pic; | |
544 | |
545 /* always report that the buffer was completely consumed */ | |
546 return buf_size; | |
547 } | |
3777 | 548 #endif |
1743 | 549 |
3777 | 550 #ifdef CONFIG_ENCODERS |
1743 | 551 /* |
552 * | |
553 * Encode a frame | |
554 * | |
555 */ | |
556 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ | |
557 LclContext *c = avctx->priv_data; | |
558 AVFrame *pict = data; | |
559 AVFrame * const p = &c->pic; | |
560 int i; | |
561 int zret; // Zlib return code | |
562 | |
563 #ifndef CONFIG_ZLIB | |
564 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); | |
565 return -1; | |
566 #else | |
567 | |
568 init_put_bits(&c->pb, buf, buf_size); | |
2967 | 569 |
1743 | 570 *p = *pict; |
571 p->pict_type= FF_I_TYPE; | |
572 p->key_frame= 1; | |
2967 | 573 |
1743 | 574 if(avctx->pix_fmt != PIX_FMT_BGR24){ |
575 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); | |
576 return -1; | |
577 } | |
578 | |
579 zret = deflateReset(&(c->zstream)); | |
580 if (zret != Z_OK) { | |
581 av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); | |
582 return -1; | |
583 } | |
584 c->zstream.next_out = c->comp_buf; | |
585 c->zstream.avail_out = c->max_comp_size; | |
586 | |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
587 for(i = avctx->height - 1; i >= 0; i--) { |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
588 c->zstream.next_in = p->data[0]+p->linesize[0]*i; |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
589 c->zstream.avail_in = avctx->width*3; |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
590 zret = deflate(&(c->zstream), Z_NO_FLUSH); |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
591 if (zret != Z_OK) { |
2979 | 592 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); |
593 return -1; | |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
594 } |
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
595 } |
1743 | 596 zret = deflate(&(c->zstream), Z_FINISH); |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
597 if (zret != Z_STREAM_END) { |
1743 | 598 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); |
599 return -1; | |
600 } | |
601 | |
602 for (i = 0; i < c->zstream.total_out; i++) | |
603 put_bits(&c->pb, 8, c->comp_buf[i]); | |
604 flush_put_bits(&c->pb); | |
605 | |
606 return c->zstream.total_out; | |
607 #endif | |
608 } | |
3777 | 609 #endif /* CONFIG_ENCODERS */ |
1743 | 610 |
3777 | 611 #ifdef CONFIG_DECODERS |
1743 | 612 /* |
613 * | |
614 * Init lcl decoder | |
615 * | |
616 */ | |
617 static int decode_init(AVCodecContext *avctx) | |
618 { | |
4827 | 619 LclContext * const c = avctx->priv_data; |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
620 unsigned int basesize = avctx->width * avctx->height; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
621 unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3); |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
622 unsigned int max_decomp_size; |
1743 | 623 int zret; // Zlib return code |
624 | |
625 c->avctx = avctx; | |
626 | |
627 c->pic.data[0] = NULL; | |
628 | |
629 #ifdef CONFIG_ZLIB | |
630 // Needed if zlib unused or init aborted before inflateInit | |
2967 | 631 memset(&(c->zstream), 0, sizeof(z_stream)); |
1743 | 632 #endif |
633 | |
634 if (avctx->extradata_size < 8) { | |
635 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); | |
636 return 1; | |
637 } | |
638 | |
2429
4b350cc506a7
Use avcodec_check_dimensions instead of custom hack
rtognimp
parents:
2418
diff
changeset
|
639 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
640 return 1; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
641 } |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
642 |
2967 | 643 /* Check codec type */ |
1743 | 644 if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || |
645 ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { | |
646 av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); | |
647 } | |
648 | |
649 /* Detect image type */ | |
650 switch (c->imgtype = *((char *)avctx->extradata + 4)) { | |
651 case IMGTYPE_YUV111: | |
652 c->decomp_size = basesize * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
653 max_decomp_size = max_basesize * 3; |
1743 | 654 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); |
655 break; | |
656 case IMGTYPE_YUV422: | |
657 c->decomp_size = basesize * 2; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
658 max_decomp_size = max_basesize * 2; |
1743 | 659 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); |
660 break; | |
661 case IMGTYPE_RGB24: | |
662 c->decomp_size = basesize * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
663 max_decomp_size = max_basesize * 3; |
1743 | 664 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); |
665 break; | |
666 case IMGTYPE_YUV411: | |
667 c->decomp_size = basesize / 2 * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
668 max_decomp_size = max_basesize / 2 * 3; |
1743 | 669 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); |
670 break; | |
671 case IMGTYPE_YUV211: | |
672 c->decomp_size = basesize * 2; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
673 max_decomp_size = max_basesize * 2; |
1743 | 674 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); |
675 break; | |
676 case IMGTYPE_YUV420: | |
677 c->decomp_size = basesize / 2 * 3; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
678 max_decomp_size = max_basesize / 2 * 3; |
1743 | 679 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); |
680 break; | |
681 default: | |
682 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); | |
683 return 1; | |
684 } | |
685 | |
686 /* Detect compression method */ | |
687 c->compression = *((char *)avctx->extradata + 5); | |
688 switch (avctx->codec_id) { | |
689 case CODEC_ID_MSZH: | |
690 switch (c->compression) { | |
691 case COMP_MSZH: | |
692 av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); | |
693 break; | |
694 case COMP_MSZH_NOCOMP: | |
695 c->decomp_size = 0; | |
696 av_log(avctx, AV_LOG_INFO, "No compression.\n"); | |
697 break; | |
698 default: | |
699 av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); | |
700 return 1; | |
701 } | |
702 break; | |
703 case CODEC_ID_ZLIB: | |
704 #ifdef CONFIG_ZLIB | |
705 switch (c->compression) { | |
706 case COMP_ZLIB_HISPEED: | |
707 av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); | |
708 break; | |
709 case COMP_ZLIB_HICOMP: | |
710 av_log(avctx, AV_LOG_INFO, "High compression.\n"); | |
711 break; | |
712 case COMP_ZLIB_NORMAL: | |
713 av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); | |
714 break; | |
715 default: | |
716 if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { | |
2979 | 717 av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); |
1743 | 718 return 1; |
719 } | |
720 av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); | |
721 } | |
722 #else | |
723 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
724 return 1; | |
725 #endif | |
726 break; | |
727 default: | |
728 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); | |
729 return 1; | |
730 } | |
731 | |
732 /* Allocate decompression buffer */ | |
733 if (c->decomp_size) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
734 if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { |
1743 | 735 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); |
736 return 1; | |
737 } | |
738 } | |
2967 | 739 |
740 /* Detect flags */ | |
1743 | 741 c->flags = *((char *)avctx->extradata + 6); |
742 if (c->flags & FLAG_MULTITHREAD) | |
743 av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); | |
744 if (c->flags & FLAG_NULLFRAME) | |
745 av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); | |
746 if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) | |
747 av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); | |
748 if (c->flags & FLAGMASK_UNUSED) | |
749 av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); | |
750 | |
751 /* If needed init zlib */ | |
752 if (avctx->codec_id == CODEC_ID_ZLIB) { | |
753 #ifdef CONFIG_ZLIB | |
754 c->zstream.zalloc = Z_NULL; | |
755 c->zstream.zfree = Z_NULL; | |
756 c->zstream.opaque = Z_NULL; | |
757 zret = inflateInit(&(c->zstream)); | |
758 if (zret != Z_OK) { | |
759 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); | |
760 return 1; | |
761 } | |
762 #else | |
763 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
764 return 1; | |
765 #endif | |
766 } | |
767 | |
768 avctx->pix_fmt = PIX_FMT_BGR24; | |
769 | |
770 return 0; | |
771 } | |
3777 | 772 #endif /* CONFIG_DECODERS */ |
1743 | 773 |
3777 | 774 #ifdef CONFIG_ENCODERS |
1743 | 775 /* |
776 * | |
777 * Init lcl encoder | |
778 * | |
779 */ | |
780 static int encode_init(AVCodecContext *avctx) | |
781 { | |
782 LclContext *c = avctx->priv_data; | |
783 int zret; // Zlib return code | |
784 | |
785 #ifndef CONFIG_ZLIB | |
786 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
787 return 1; | |
788 #else | |
789 | |
790 c->avctx= avctx; | |
2967 | 791 |
1743 | 792 assert(avctx->width && avctx->height); |
2967 | 793 |
1743 | 794 avctx->extradata= av_mallocz(8); |
795 avctx->coded_frame= &c->pic; | |
796 | |
797 // Will be user settable someday | |
798 c->compression = 6; | |
799 c->flags = 0; | |
800 | |
801 switch(avctx->pix_fmt){ | |
802 case PIX_FMT_BGR24: | |
803 c->imgtype = IMGTYPE_RGB24; | |
804 c->decomp_size = avctx->width * avctx->height * 3; | |
805 avctx->bits_per_sample= 24; | |
806 break; | |
807 default: | |
808 av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt); | |
809 return -1; | |
810 } | |
811 | |
812 ((uint8_t*)avctx->extradata)[0]= 4; | |
813 ((uint8_t*)avctx->extradata)[1]= 0; | |
814 ((uint8_t*)avctx->extradata)[2]= 0; | |
815 ((uint8_t*)avctx->extradata)[3]= 0; | |
816 ((uint8_t*)avctx->extradata)[4]= c->imgtype; | |
817 ((uint8_t*)avctx->extradata)[5]= c->compression; | |
818 ((uint8_t*)avctx->extradata)[6]= c->flags; | |
2250
902caf560c43
Zlib encoder: fix image orientation (was flipped), 100l in deflate error
rtognimp
parents:
2248
diff
changeset
|
819 ((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB; |
1743 | 820 c->avctx->extradata_size= 8; |
2967 | 821 |
1743 | 822 c->zstream.zalloc = Z_NULL; |
823 c->zstream.zfree = Z_NULL; | |
824 c->zstream.opaque = Z_NULL; | |
825 zret = deflateInit(&(c->zstream), c->compression); | |
826 if (zret != Z_OK) { | |
827 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); | |
828 return 1; | |
829 } | |
830 | |
831 /* Conservative upper bound taken from zlib v1.2.1 source */ | |
832 c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + | |
833 ((c->decomp_size + 63) >> 6) + 11; | |
834 if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { | |
835 av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); | |
836 return 1; | |
837 } | |
838 | |
839 return 0; | |
840 #endif | |
841 } | |
3777 | 842 #endif /* CONFIG_ENCODERS */ |
1743 | 843 |
844 | |
845 | |
3777 | 846 #ifdef CONFIG_DECODERS |
1743 | 847 /* |
848 * | |
849 * Uninit lcl decoder | |
850 * | |
851 */ | |
852 static int decode_end(AVCodecContext *avctx) | |
853 { | |
4827 | 854 LclContext * const c = avctx->priv_data; |
1743 | 855 |
2979 | 856 if (c->pic.data[0]) |
857 avctx->release_buffer(avctx, &c->pic); | |
1743 | 858 #ifdef CONFIG_ZLIB |
859 inflateEnd(&(c->zstream)); | |
860 #endif | |
861 | |
2979 | 862 return 0; |
1743 | 863 } |
3777 | 864 #endif |
1743 | 865 |
3777 | 866 #ifdef CONFIG_ENCODERS |
1743 | 867 /* |
868 * | |
869 * Uninit lcl encoder | |
870 * | |
871 */ | |
872 static int encode_end(AVCodecContext *avctx) | |
873 { | |
874 LclContext *c = avctx->priv_data; | |
875 | |
876 av_freep(&avctx->extradata); | |
2248
e4e1b4f31db6
segfault fix by (Kostya <cannonball at bw-team dot com>)
michael
parents:
1744
diff
changeset
|
877 av_freep(&c->comp_buf); |
1743 | 878 #ifdef CONFIG_ZLIB |
879 deflateEnd(&(c->zstream)); | |
880 #endif | |
2967 | 881 |
1743 | 882 return 0; |
883 } | |
3777 | 884 #endif |
1743 | 885 |
3777 | 886 #ifdef CONFIG_MSZH_DECODER |
1743 | 887 AVCodec mszh_decoder = { |
2979 | 888 "mszh", |
889 CODEC_TYPE_VIDEO, | |
890 CODEC_ID_MSZH, | |
891 sizeof(LclContext), | |
892 decode_init, | |
893 NULL, | |
894 decode_end, | |
895 decode_frame, | |
896 CODEC_CAP_DR1, | |
1743 | 897 }; |
3777 | 898 #endif |
1743 | 899 |
3777 | 900 #ifdef CONFIG_ZLIB_DECODER |
1743 | 901 AVCodec zlib_decoder = { |
2979 | 902 "zlib", |
903 CODEC_TYPE_VIDEO, | |
904 CODEC_ID_ZLIB, | |
905 sizeof(LclContext), | |
906 decode_init, | |
907 NULL, | |
908 decode_end, | |
909 decode_frame, | |
910 CODEC_CAP_DR1, | |
1743 | 911 }; |
3777 | 912 #endif |
1743 | 913 |
914 #ifdef CONFIG_ENCODERS | |
915 | |
916 AVCodec zlib_encoder = { | |
917 "zlib", | |
918 CODEC_TYPE_VIDEO, | |
919 CODEC_ID_ZLIB, | |
920 sizeof(LclContext), | |
921 encode_init, | |
922 encode_frame, | |
923 encode_end, | |
924 }; | |
925 | |
926 #endif //CONFIG_ENCODERS |