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