Mercurial > libavcodec.hg
annotate lcldec.c @ 5876:731ee5ad6bde libavcodec
Correct assignment of interlaced_frame; was being set on output frames,
in display order, based on decoding information in decoding order. Now
set properly, immediately upon completion of decode.
Based on original patch from Reinhard Nissl, rnisssl % gmx , de
Original Thread: [FFmpeg-devel] H.264 + PAFF: BBC HD recording shows
extreme interlacing artefacts, Thu, 01 Nov 2007 22:43:09
author | heydowns |
---|---|
date | Mon, 05 Nov 2007 18:16:42 +0000 |
parents | fc46b3f5de1a |
children | dfdff1ca78a7 |
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 * @file lcl.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 | |
4962
f99e40a7155b
Remove redundant #inclusion of common.h, avcodec.h already #includes it.
diego
parents:
4827
diff
changeset
|
44 #include "avcodec.h" |
2398
582e635cfa08
common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents:
2250
diff
changeset
|
45 #include "bitstream.h" |
5294 | 46 #include "lcl.h" |
1743 | 47 |
48 #ifdef CONFIG_ZLIB | |
49 #include <zlib.h> | |
50 #endif | |
51 | |
52 /* | |
53 * Decoder context | |
54 */ | |
5294 | 55 typedef struct LclDecContext { |
5297 | 56 AVFrame pic; |
1743 | 57 |
58 // Image type | |
59 int imgtype; | |
60 // Compression type | |
61 int compression; | |
62 // Flags | |
63 int flags; | |
64 // Decompressed data size | |
65 unsigned int decomp_size; | |
66 // Decompression buffer | |
67 unsigned char* decomp_buf; | |
68 #ifdef CONFIG_ZLIB | |
69 z_stream zstream; | |
70 #endif | |
5294 | 71 } LclDecContext; |
1743 | 72 |
73 | |
74 /* | |
75 * | |
76 * Helper functions | |
77 * | |
78 */ | |
79 static inline unsigned char fix (int pix14) | |
80 { | |
81 int tmp; | |
82 | |
83 tmp = (pix14 + 0x80000) >> 20; | |
84 if (tmp < 0) | |
85 return 0; | |
86 if (tmp > 255) | |
87 return 255; | |
88 return tmp; | |
89 } | |
90 | |
91 | |
92 | |
93 static inline unsigned char get_b (unsigned char yq, signed char bq) | |
94 { | |
95 return fix((yq << 20) + bq * 1858076); | |
96 } | |
97 | |
98 | |
99 | |
100 static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) | |
101 { | |
102 return fix((yq << 20) - bq * 360857 - rq * 748830); | |
103 } | |
104 | |
105 | |
106 | |
107 static inline unsigned char get_r (unsigned char yq, signed char rq) | |
108 { | |
109 return fix((yq << 20) + rq * 1470103); | |
110 } | |
111 | |
112 | |
113 | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
114 static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
1743 | 115 { |
116 unsigned char *destptr_bak = destptr; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
117 unsigned char *destptr_end = destptr + destsize; |
1743 | 118 unsigned char mask = 0; |
119 unsigned char maskbit = 0; | |
120 unsigned int ofs, cnt; | |
2967 | 121 |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
122 while ((srclen > 0) && (destptr < destptr_end)) { |
1743 | 123 if (maskbit == 0) { |
124 mask = *(srcptr++); | |
125 maskbit = 8; | |
126 srclen--; | |
127 continue; | |
128 } | |
129 if ((mask & (1 << (--maskbit))) == 0) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
130 if (destptr + 4 > destptr_end) |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
131 break; |
1743 | 132 *(int*)destptr = *(int*)srcptr; |
133 srclen -= 4; | |
134 destptr += 4; | |
135 srcptr += 4; | |
136 } else { | |
137 ofs = *(srcptr++); | |
138 cnt = *(srcptr++); | |
139 ofs += cnt * 256;; | |
140 cnt = ((cnt >> 3) & 0x1f) + 1; | |
141 ofs &= 0x7ff; | |
142 srclen -= 2; | |
143 cnt *= 4; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
144 if (destptr + cnt > destptr_end) { |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
145 cnt = destptr_end - destptr; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
146 } |
1743 | 147 for (; cnt > 0; cnt--) { |
148 *(destptr) = *(destptr - ofs); | |
149 destptr++; | |
150 } | |
151 } | |
152 } | |
153 | |
154 return (destptr - destptr_bak); | |
155 } | |
156 | |
157 | |
158 | |
159 /* | |
160 * | |
161 * Decode a frame | |
162 * | |
163 */ | |
164 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) | |
165 { | |
5297 | 166 LclDecContext * const c = avctx->priv_data; |
167 unsigned char *encoded = (unsigned char *)buf; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
168 unsigned int pixel_ptr; |
1743 | 169 int row, col; |
170 unsigned char *outptr; | |
171 unsigned int width = avctx->width; // Real image width | |
172 unsigned int height = avctx->height; // Real image height | |
173 unsigned int mszh_dlen; | |
174 unsigned char yq, y1q, uq, vq; | |
175 int uqvq; | |
176 unsigned int mthread_inlen, mthread_outlen; | |
177 #ifdef CONFIG_ZLIB | |
178 int zret; // Zlib return code | |
179 #endif | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
180 unsigned int len = buf_size; |
1743 | 181 |
5297 | 182 if(c->pic.data[0]) |
183 avctx->release_buffer(avctx, &c->pic); | |
1743 | 184 |
5297 | 185 c->pic.reference = 0; |
186 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; | |
187 if(avctx->get_buffer(avctx, &c->pic) < 0){ | |
188 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
189 return -1; | |
190 } | |
1743 | 191 |
192 outptr = c->pic.data[0]; // Output image pointer | |
193 | |
194 /* Decompress frame */ | |
195 switch (avctx->codec_id) { | |
5297 | 196 case CODEC_ID_MSZH: |
197 switch (c->compression) { | |
198 case COMP_MSZH: | |
1743 | 199 if (c->flags & FLAG_MULTITHREAD) { |
200 mthread_inlen = *((unsigned int*)encoded); | |
201 mthread_outlen = *((unsigned int*)(encoded+4)); | |
5297 | 202 if (mthread_outlen > c->decomp_size) // this should not happen |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
203 mthread_outlen = c->decomp_size; |
5297 | 204 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); |
205 if (mthread_outlen != mszh_dlen) { | |
206 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", | |
207 mthread_outlen, mszh_dlen); | |
1743 | 208 return -1; |
209 } | |
5297 | 210 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen, |
211 c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); | |
212 if (mthread_outlen != mszh_dlen) { | |
213 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", | |
214 mthread_outlen, mszh_dlen); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
215 return -1; |
1743 | 216 } |
5297 | 217 encoded = c->decomp_buf; |
218 len = c->decomp_size; | |
219 } else { | |
220 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); | |
221 if (c->decomp_size != mszh_dlen) { | |
222 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", | |
223 c->decomp_size, mszh_dlen); | |
1743 | 224 return -1; |
225 } | |
5297 | 226 encoded = c->decomp_buf; |
227 len = mszh_dlen; | |
1743 | 228 } |
5297 | 229 break; |
230 case COMP_MSZH_NOCOMP: | |
1743 | 231 break; |
232 default: | |
5297 | 233 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); |
234 return -1; | |
235 } | |
236 break; | |
237 case CODEC_ID_ZLIB: | |
238 #ifdef CONFIG_ZLIB | |
239 /* Using the original dll with normal compression (-1) and RGB format | |
240 * gives a file with ZLIB fourcc, but frame is really uncompressed. | |
241 * To be sure that's true check also frame size */ | |
242 if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) && | |
243 (len == width * height * 3)) | |
244 break; | |
245 zret = inflateReset(&(c->zstream)); | |
246 if (zret != Z_OK) { | |
247 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); | |
1743 | 248 return -1; |
5297 | 249 } |
250 if (c->flags & FLAG_MULTITHREAD) { | |
251 mthread_inlen = *((unsigned int*)encoded); | |
252 mthread_outlen = *((unsigned int*)(encoded+4)); | |
253 if (mthread_outlen > c->decomp_size) | |
254 mthread_outlen = c->decomp_size; | |
255 c->zstream.next_in = encoded + 8; | |
256 c->zstream.avail_in = mthread_inlen; | |
257 c->zstream.next_out = c->decomp_buf; | |
258 c->zstream.avail_out = c->decomp_size; | |
259 zret = inflate(&(c->zstream), Z_FINISH); | |
260 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
261 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); | |
262 return -1; | |
263 } | |
264 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { | |
265 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", | |
266 mthread_outlen, c->zstream.total_out); | |
267 return -1; | |
268 } | |
269 zret = inflateReset(&(c->zstream)); | |
270 if (zret != Z_OK) { | |
271 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); | |
272 return -1; | |
273 } | |
274 c->zstream.next_in = encoded + 8 + mthread_inlen; | |
275 c->zstream.avail_in = len - mthread_inlen; | |
276 c->zstream.next_out = c->decomp_buf + mthread_outlen; | |
277 c->zstream.avail_out = c->decomp_size - mthread_outlen; | |
278 zret = inflate(&(c->zstream), Z_FINISH); | |
279 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
280 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); | |
281 return -1; | |
282 } | |
283 if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { | |
284 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", | |
285 mthread_outlen, c->zstream.total_out); | |
286 return -1; | |
287 } | |
288 } else { | |
289 c->zstream.next_in = encoded; | |
290 c->zstream.avail_in = len; | |
291 c->zstream.next_out = c->decomp_buf; | |
292 c->zstream.avail_out = c->decomp_size; | |
293 zret = inflate(&(c->zstream), Z_FINISH); | |
294 if ((zret != Z_OK) && (zret != Z_STREAM_END)) { | |
295 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); | |
296 return -1; | |
297 } | |
298 if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { | |
299 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", | |
300 c->decomp_size, c->zstream.total_out); | |
301 return -1; | |
302 } | |
303 } | |
304 encoded = c->decomp_buf; | |
305 len = c->decomp_size;; | |
306 #else | |
307 av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); | |
308 return -1; | |
309 #endif | |
310 break; | |
311 default: | |
312 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); | |
313 return -1; | |
1743 | 314 } |
315 | |
316 | |
317 /* Apply PNG filter */ | |
318 if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) { | |
319 switch (c->imgtype) { | |
5297 | 320 case IMGTYPE_YUV111: |
321 case IMGTYPE_RGB24: | |
322 for (row = 0; row < height; row++) { | |
323 pixel_ptr = row * width * 3; | |
324 yq = encoded[pixel_ptr++]; | |
325 uqvq = AV_RL16(encoded+pixel_ptr); | |
326 pixel_ptr += 2; | |
327 for (col = 1; col < width; col++) { | |
328 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
329 uqvq -= AV_RL16(encoded+pixel_ptr+1); | |
330 AV_WL16(encoded+pixel_ptr+1, uqvq); | |
331 pixel_ptr += 3; | |
1743 | 332 } |
5297 | 333 } |
334 break; | |
335 case IMGTYPE_YUV422: | |
336 for (row = 0; row < height; row++) { | |
337 pixel_ptr = row * width * 2; | |
338 yq = uq = vq =0; | |
339 for (col = 0; col < width/4; col++) { | |
340 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
341 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
342 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
343 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
344 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
345 encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; | |
346 encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; | |
347 encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; | |
348 pixel_ptr += 8; | |
1743 | 349 } |
5297 | 350 } |
351 break; | |
352 case IMGTYPE_YUV411: | |
353 for (row = 0; row < height; row++) { | |
354 pixel_ptr = row * width / 2 * 3; | |
355 yq = uq = vq =0; | |
356 for (col = 0; col < width/4; col++) { | |
357 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
358 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
359 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
360 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
361 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
362 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
363 pixel_ptr += 6; | |
1743 | 364 } |
5297 | 365 } |
366 break; | |
367 case IMGTYPE_YUV211: | |
368 for (row = 0; row < height; row++) { | |
369 pixel_ptr = row * width * 2; | |
370 yq = uq = vq =0; | |
371 for (col = 0; col < width/2; col++) { | |
372 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
373 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
374 encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; | |
375 encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; | |
376 pixel_ptr += 4; | |
1743 | 377 } |
5297 | 378 } |
379 break; | |
380 case IMGTYPE_YUV420: | |
381 for (row = 0; row < height/2; row++) { | |
382 pixel_ptr = row * width * 3; | |
383 yq = y1q = uq = vq =0; | |
384 for (col = 0; col < width/2; col++) { | |
385 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
386 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
387 encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; | |
388 encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; | |
389 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
390 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
391 pixel_ptr += 6; | |
1743 | 392 } |
5297 | 393 } |
394 break; | |
395 default: | |
396 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); | |
397 return -1; | |
1743 | 398 } |
399 } | |
400 | |
401 /* Convert colorspace */ | |
402 switch (c->imgtype) { | |
5297 | 403 case IMGTYPE_YUV111: |
404 for (row = height - 1; row >= 0; row--) { | |
405 pixel_ptr = row * c->pic.linesize[0]; | |
406 for (col = 0; col < width; col++) { | |
407 outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); | |
408 outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); | |
409 outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); | |
410 encoded += 3; | |
1743 | 411 } |
5297 | 412 } |
413 break; | |
414 case IMGTYPE_YUV422: | |
415 for (row = height - 1; row >= 0; row--) { | |
416 pixel_ptr = row * c->pic.linesize[0]; | |
417 for (col = 0; col < width/4; col++) { | |
418 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | |
419 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); | |
420 outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); | |
421 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | |
422 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); | |
423 outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); | |
424 outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); | |
425 outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); | |
426 outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); | |
427 outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); | |
428 outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); | |
429 outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); | |
430 encoded += 8; | |
1743 | 431 } |
5297 | 432 } |
433 break; | |
434 case IMGTYPE_RGB24: | |
435 for (row = height - 1; row >= 0; row--) { | |
436 pixel_ptr = row * c->pic.linesize[0]; | |
437 for (col = 0; col < width; col++) { | |
438 outptr[pixel_ptr++] = encoded[0]; | |
439 outptr[pixel_ptr++] = encoded[1]; | |
440 outptr[pixel_ptr++] = encoded[2]; | |
441 encoded += 3; | |
1743 | 442 } |
5297 | 443 } |
444 break; | |
445 case IMGTYPE_YUV411: | |
446 for (row = height - 1; row >= 0; row--) { | |
447 pixel_ptr = row * c->pic.linesize[0]; | |
448 for (col = 0; col < width/4; col++) { | |
449 outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); | |
450 outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); | |
451 outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); | |
452 outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); | |
453 outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); | |
454 outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); | |
455 outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); | |
456 outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); | |
457 outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); | |
458 outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); | |
459 outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); | |
460 outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); | |
461 encoded += 6; | |
1743 | 462 } |
5297 | 463 } |
464 break; | |
465 case IMGTYPE_YUV211: | |
466 for (row = height - 1; row >= 0; row--) { | |
467 pixel_ptr = row * c->pic.linesize[0]; | |
468 for (col = 0; col < width/2; col++) { | |
469 outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); | |
470 outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); | |
471 outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); | |
472 outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); | |
473 outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); | |
474 outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); | |
475 encoded += 4; | |
1743 | 476 } |
5297 | 477 } |
478 break; | |
479 case IMGTYPE_YUV420: | |
480 for (row = height / 2 - 1; row >= 0; row--) { | |
481 pixel_ptr = 2 * row * c->pic.linesize[0]; | |
482 for (col = 0; col < width/2; col++) { | |
483 outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); | |
484 outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); | |
485 outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); | |
486 outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); | |
487 outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); | |
488 outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); | |
489 outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); | |
490 outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); | |
491 outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); | |
492 outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); | |
493 outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); | |
494 outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); | |
495 pixel_ptr += 6; | |
496 encoded += 6; | |
1743 | 497 } |
5297 | 498 } |
499 break; | |
500 default: | |
501 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); | |
502 return -1; | |
1743 | 503 } |
504 | |
505 *data_size = sizeof(AVFrame); | |
506 *(AVFrame*)data = c->pic; | |
507 | |
508 /* always report that the buffer was completely consumed */ | |
509 return buf_size; | |
510 } | |
511 | |
512 /* | |
513 * | |
514 * Init lcl decoder | |
515 * | |
516 */ | |
517 static int decode_init(AVCodecContext *avctx) | |
518 { | |
5294 | 519 LclDecContext * const c = avctx->priv_data; |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
520 unsigned int basesize = avctx->width * avctx->height; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
521 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
|
522 unsigned int max_decomp_size; |
1743 | 523 int zret; // Zlib return code |
524 | |
525 c->pic.data[0] = NULL; | |
526 | |
527 #ifdef CONFIG_ZLIB | |
528 // Needed if zlib unused or init aborted before inflateInit | |
2967 | 529 memset(&(c->zstream), 0, sizeof(z_stream)); |
1743 | 530 #endif |
531 | |
532 if (avctx->extradata_size < 8) { | |
533 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); | |
534 return 1; | |
535 } | |
536 | |
2429
4b350cc506a7
Use avcodec_check_dimensions instead of custom hack
rtognimp
parents:
2418
diff
changeset
|
537 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
|
538 return 1; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
539 } |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
540 |
2967 | 541 /* Check codec type */ |
1743 | 542 if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || |
543 ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { | |
544 av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); | |
545 } | |
546 | |
547 /* Detect image type */ | |
548 switch (c->imgtype = *((char *)avctx->extradata + 4)) { | |
5297 | 549 case IMGTYPE_YUV111: |
550 c->decomp_size = basesize * 3; | |
551 max_decomp_size = max_basesize * 3; | |
552 av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); | |
553 break; | |
554 case IMGTYPE_YUV422: | |
555 c->decomp_size = basesize * 2; | |
556 max_decomp_size = max_basesize * 2; | |
557 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); | |
558 break; | |
559 case IMGTYPE_RGB24: | |
560 c->decomp_size = basesize * 3; | |
561 max_decomp_size = max_basesize * 3; | |
562 av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); | |
563 break; | |
564 case IMGTYPE_YUV411: | |
565 c->decomp_size = basesize / 2 * 3; | |
566 max_decomp_size = max_basesize / 2 * 3; | |
567 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); | |
568 break; | |
569 case IMGTYPE_YUV211: | |
570 c->decomp_size = basesize * 2; | |
571 max_decomp_size = max_basesize * 2; | |
572 av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); | |
573 break; | |
574 case IMGTYPE_YUV420: | |
575 c->decomp_size = basesize / 2 * 3; | |
576 max_decomp_size = max_basesize / 2 * 3; | |
577 av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); | |
578 break; | |
579 default: | |
580 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); | |
581 return 1; | |
1743 | 582 } |
583 | |
584 /* Detect compression method */ | |
585 c->compression = *((char *)avctx->extradata + 5); | |
586 switch (avctx->codec_id) { | |
5297 | 587 case CODEC_ID_MSZH: |
588 switch (c->compression) { | |
589 case COMP_MSZH: | |
590 av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); | |
1743 | 591 break; |
5297 | 592 case COMP_MSZH_NOCOMP: |
593 c->decomp_size = 0; | |
594 av_log(avctx, AV_LOG_INFO, "No compression.\n"); | |
1743 | 595 break; |
596 default: | |
5297 | 597 av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); |
1743 | 598 return 1; |
5297 | 599 } |
600 break; | |
601 case CODEC_ID_ZLIB: | |
602 #ifdef CONFIG_ZLIB | |
603 switch (c->compression) { | |
604 case COMP_ZLIB_HISPEED: | |
605 av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); | |
606 break; | |
607 case COMP_ZLIB_HICOMP: | |
608 av_log(avctx, AV_LOG_INFO, "High compression.\n"); | |
609 break; | |
610 case COMP_ZLIB_NORMAL: | |
611 av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); | |
612 break; | |
613 default: | |
614 if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { | |
615 av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); | |
616 return 1; | |
617 } | |
618 av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); | |
619 } | |
620 #else | |
621 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); | |
622 return 1; | |
623 #endif | |
624 break; | |
625 default: | |
626 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); | |
627 return 1; | |
1743 | 628 } |
629 | |
630 /* Allocate decompression buffer */ | |
631 if (c->decomp_size) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
632 if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { |
1743 | 633 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); |
634 return 1; | |
635 } | |
636 } | |
2967 | 637 |
638 /* Detect flags */ | |
1743 | 639 c->flags = *((char *)avctx->extradata + 6); |
640 if (c->flags & FLAG_MULTITHREAD) | |
641 av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); | |
642 if (c->flags & FLAG_NULLFRAME) | |
643 av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); | |
644 if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) | |
645 av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); | |
646 if (c->flags & FLAGMASK_UNUSED) | |
647 av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); | |
648 | |
649 /* If needed init zlib */ | |
650 if (avctx->codec_id == CODEC_ID_ZLIB) { | |
651 #ifdef CONFIG_ZLIB | |
652 c->zstream.zalloc = Z_NULL; | |
653 c->zstream.zfree = Z_NULL; | |
654 c->zstream.opaque = Z_NULL; | |
655 zret = inflateInit(&(c->zstream)); | |
656 if (zret != Z_OK) { | |
657 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); | |
658 return 1; | |
659 } | |
660 #else | |
5297 | 661 av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); |
662 return 1; | |
1743 | 663 #endif |
664 } | |
665 | |
666 avctx->pix_fmt = PIX_FMT_BGR24; | |
667 | |
668 return 0; | |
669 } | |
670 | |
671 /* | |
672 * | |
673 * Uninit lcl decoder | |
674 * | |
675 */ | |
676 static int decode_end(AVCodecContext *avctx) | |
677 { | |
5297 | 678 LclDecContext * const c = avctx->priv_data; |
1743 | 679 |
5297 | 680 if (c->pic.data[0]) |
681 avctx->release_buffer(avctx, &c->pic); | |
1743 | 682 #ifdef CONFIG_ZLIB |
683 inflateEnd(&(c->zstream)); | |
684 #endif | |
685 | |
5297 | 686 return 0; |
1743 | 687 } |
688 | |
3777 | 689 #ifdef CONFIG_MSZH_DECODER |
1743 | 690 AVCodec mszh_decoder = { |
5297 | 691 "mszh", |
692 CODEC_TYPE_VIDEO, | |
693 CODEC_ID_MSZH, | |
694 sizeof(LclDecContext), | |
695 decode_init, | |
696 NULL, | |
697 decode_end, | |
698 decode_frame, | |
699 CODEC_CAP_DR1, | |
1743 | 700 }; |
3777 | 701 #endif |
1743 | 702 |
3777 | 703 #ifdef CONFIG_ZLIB_DECODER |
1743 | 704 AVCodec zlib_decoder = { |
5297 | 705 "zlib", |
706 CODEC_TYPE_VIDEO, | |
707 CODEC_ID_ZLIB, | |
708 sizeof(LclDecContext), | |
709 decode_init, | |
710 NULL, | |
711 decode_end, | |
712 decode_frame, | |
713 CODEC_CAP_DR1, | |
1743 | 714 }; |
3777 | 715 #endif |