ffmpeg / libavcodec / lcldec.c @ d36beb3f
History | View | Annotate | Download (21.6 KB)
1 |
/*
|
---|---|
2 |
* LCL (LossLess Codec Library) Codec
|
3 |
* Copyright (c) 2002-2004 Roberto Togni
|
4 |
*
|
5 |
* This file is part of FFmpeg.
|
6 |
*
|
7 |
* FFmpeg is free software; you can redistribute it and/or
|
8 |
* modify it under the terms of the GNU Lesser General Public
|
9 |
* License as published by the Free Software Foundation; either
|
10 |
* version 2.1 of the License, or (at your option) any later version.
|
11 |
*
|
12 |
* FFmpeg is distributed in the hope that it will be useful,
|
13 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15 |
* Lesser General Public License for more details.
|
16 |
*
|
17 |
* You should have received a copy of the GNU Lesser General Public
|
18 |
* License along with FFmpeg; if not, write to the Free Software
|
19 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 |
*/
|
21 |
|
22 |
/**
|
23 |
* @file
|
24 |
* LCL (LossLess Codec Library) Video Codec
|
25 |
* Decoder for MSZH and ZLIB codecs
|
26 |
* Experimental encoder for ZLIB RGB24
|
27 |
*
|
28 |
* Fourcc: MSZH, ZLIB
|
29 |
*
|
30 |
* Original Win32 dll:
|
31 |
* Ver2.23 By Kenji Oshima 2000.09.20
|
32 |
* avimszh.dll, avizlib.dll
|
33 |
*
|
34 |
* A description of the decoding algorithm can be found here:
|
35 |
* http://www.pcisys.net/~melanson/codecs
|
36 |
*
|
37 |
* Supports: BGR24 (RGB 24bpp)
|
38 |
*
|
39 |
*/
|
40 |
|
41 |
#include <stdio.h> |
42 |
#include <stdlib.h> |
43 |
|
44 |
#include "avcodec.h" |
45 |
#include "bytestream.h" |
46 |
#include "lcl.h" |
47 |
#include "libavutil/lzo.h" |
48 |
|
49 |
#if CONFIG_ZLIB_DECODER
|
50 |
#include <zlib.h> |
51 |
#endif
|
52 |
|
53 |
/*
|
54 |
* Decoder context
|
55 |
*/
|
56 |
typedef struct LclDecContext { |
57 |
AVFrame pic; |
58 |
|
59 |
// Image type
|
60 |
int imgtype;
|
61 |
// Compression type
|
62 |
int compression;
|
63 |
// Flags
|
64 |
int flags;
|
65 |
// Decompressed data size
|
66 |
unsigned int decomp_size; |
67 |
// Decompression buffer
|
68 |
unsigned char* decomp_buf; |
69 |
#if CONFIG_ZLIB_DECODER
|
70 |
z_stream zstream; |
71 |
#endif
|
72 |
} LclDecContext; |
73 |
|
74 |
|
75 |
/**
|
76 |
* \param srcptr compressed source buffer, must be padded with at least 5 extra bytes
|
77 |
* \param destptr must be padded sufficiently for av_memcpy_backptr
|
78 |
*/
|
79 |
static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
80 |
{ |
81 |
unsigned char *destptr_bak = destptr; |
82 |
unsigned char *destptr_end = destptr + destsize; |
83 |
const unsigned char *srcptr_end = srcptr + srclen; |
84 |
unsigned mask = *srcptr++;
|
85 |
unsigned maskbit = 0x80; |
86 |
|
87 |
while (srcptr < srcptr_end && destptr < destptr_end) {
|
88 |
if (!(mask & maskbit)) {
|
89 |
memcpy(destptr, srcptr, 4);
|
90 |
destptr += 4;
|
91 |
srcptr += 4;
|
92 |
} else {
|
93 |
unsigned ofs = bytestream_get_le16(&srcptr);
|
94 |
unsigned cnt = (ofs >> 11) + 1; |
95 |
ofs &= 0x7ff;
|
96 |
ofs = FFMIN(ofs, destptr - destptr_bak); |
97 |
cnt *= 4;
|
98 |
cnt = FFMIN(cnt, destptr_end - destptr); |
99 |
av_memcpy_backptr(destptr, ofs, cnt); |
100 |
destptr += cnt; |
101 |
} |
102 |
maskbit >>= 1;
|
103 |
if (!maskbit) {
|
104 |
mask = *srcptr++; |
105 |
while (!mask) {
|
106 |
if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break; |
107 |
memcpy(destptr, srcptr, 32);
|
108 |
destptr += 32;
|
109 |
srcptr += 32;
|
110 |
mask = *srcptr++; |
111 |
} |
112 |
maskbit = 0x80;
|
113 |
} |
114 |
} |
115 |
|
116 |
return destptr - destptr_bak;
|
117 |
} |
118 |
|
119 |
|
120 |
#if CONFIG_ZLIB_DECODER
|
121 |
/**
|
122 |
* \brief decompress a zlib-compressed data block into decomp_buf
|
123 |
* \param src compressed input buffer
|
124 |
* \param src_len data length in input buffer
|
125 |
* \param offset offset in decomp_buf
|
126 |
* \param expected expected decompressed length
|
127 |
*/
|
128 |
static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) |
129 |
{ |
130 |
LclDecContext *c = avctx->priv_data; |
131 |
int zret = inflateReset(&c->zstream);
|
132 |
if (zret != Z_OK) {
|
133 |
av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
|
134 |
return -1; |
135 |
} |
136 |
c->zstream.next_in = src; |
137 |
c->zstream.avail_in = src_len; |
138 |
c->zstream.next_out = c->decomp_buf + offset; |
139 |
c->zstream.avail_out = c->decomp_size - offset; |
140 |
zret = inflate(&c->zstream, Z_FINISH); |
141 |
if (zret != Z_OK && zret != Z_STREAM_END) {
|
142 |
av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
|
143 |
return -1; |
144 |
} |
145 |
if (expected != (unsigned int)c->zstream.total_out) { |
146 |
av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
|
147 |
expected, c->zstream.total_out); |
148 |
return -1; |
149 |
} |
150 |
return c->zstream.total_out;
|
151 |
} |
152 |
#endif
|
153 |
|
154 |
|
155 |
/*
|
156 |
*
|
157 |
* Decode a frame
|
158 |
*
|
159 |
*/
|
160 |
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) |
161 |
{ |
162 |
const uint8_t *buf = avpkt->data;
|
163 |
int buf_size = avpkt->size;
|
164 |
LclDecContext * const c = avctx->priv_data;
|
165 |
unsigned char *encoded = (unsigned char *)buf; |
166 |
unsigned int pixel_ptr; |
167 |
int row, col;
|
168 |
unsigned char *outptr; |
169 |
uint8_t *y_out, *u_out, *v_out; |
170 |
unsigned int width = avctx->width; // Real image width |
171 |
unsigned int height = avctx->height; // Real image height |
172 |
unsigned int mszh_dlen; |
173 |
unsigned char yq, y1q, uq, vq; |
174 |
int uqvq;
|
175 |
unsigned int mthread_inlen, mthread_outlen; |
176 |
unsigned int len = buf_size; |
177 |
|
178 |
if(c->pic.data[0]) |
179 |
avctx->release_buffer(avctx, &c->pic); |
180 |
|
181 |
c->pic.reference = 0;
|
182 |
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; |
183 |
if(avctx->get_buffer(avctx, &c->pic) < 0){ |
184 |
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
185 |
return -1; |
186 |
} |
187 |
|
188 |
outptr = c->pic.data[0]; // Output image pointer |
189 |
|
190 |
/* Decompress frame */
|
191 |
switch (avctx->codec_id) {
|
192 |
case CODEC_ID_MSZH:
|
193 |
switch (c->compression) {
|
194 |
case COMP_MSZH:
|
195 |
if (c->flags & FLAG_MULTITHREAD) {
|
196 |
mthread_inlen = AV_RL32(encoded); |
197 |
mthread_inlen = FFMIN(mthread_inlen, len - 8);
|
198 |
mthread_outlen = AV_RL32(encoded+4);
|
199 |
mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); |
200 |
mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
|
201 |
if (mthread_outlen != mszh_dlen) {
|
202 |
av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
|
203 |
mthread_outlen, mszh_dlen); |
204 |
return -1; |
205 |
} |
206 |
mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, |
207 |
c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); |
208 |
if (mthread_outlen != mszh_dlen) {
|
209 |
av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
|
210 |
mthread_outlen, mszh_dlen); |
211 |
return -1; |
212 |
} |
213 |
encoded = c->decomp_buf; |
214 |
len = c->decomp_size; |
215 |
} else {
|
216 |
mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); |
217 |
if (c->decomp_size != mszh_dlen) {
|
218 |
av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
|
219 |
c->decomp_size, mszh_dlen); |
220 |
return -1; |
221 |
} |
222 |
encoded = c->decomp_buf; |
223 |
len = mszh_dlen; |
224 |
} |
225 |
break;
|
226 |
case COMP_MSZH_NOCOMP:
|
227 |
break;
|
228 |
default:
|
229 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
|
230 |
return -1; |
231 |
} |
232 |
break;
|
233 |
#if CONFIG_ZLIB_DECODER
|
234 |
case CODEC_ID_ZLIB:
|
235 |
/* Using the original dll with normal compression (-1) and RGB format
|
236 |
* gives a file with ZLIB fourcc, but frame is really uncompressed.
|
237 |
* To be sure that's true check also frame size */
|
238 |
if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 &&
|
239 |
len == width * height * 3)
|
240 |
break;
|
241 |
if (c->flags & FLAG_MULTITHREAD) {
|
242 |
int ret;
|
243 |
mthread_inlen = AV_RL32(encoded); |
244 |
mthread_inlen = FFMIN(mthread_inlen, len - 8);
|
245 |
mthread_outlen = AV_RL32(encoded+4);
|
246 |
mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); |
247 |
ret = zlib_decomp(avctx, encoded + 8, mthread_inlen, 0, mthread_outlen); |
248 |
if (ret < 0) return ret; |
249 |
ret = zlib_decomp(avctx, encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, |
250 |
mthread_outlen, mthread_outlen); |
251 |
if (ret < 0) return ret; |
252 |
} else {
|
253 |
int ret = zlib_decomp(avctx, encoded, len, 0, c->decomp_size); |
254 |
if (ret < 0) return ret; |
255 |
} |
256 |
encoded = c->decomp_buf; |
257 |
len = c->decomp_size; |
258 |
break;
|
259 |
#endif
|
260 |
default:
|
261 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
|
262 |
return -1; |
263 |
} |
264 |
|
265 |
|
266 |
/* Apply PNG filter */
|
267 |
if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) {
|
268 |
switch (c->imgtype) {
|
269 |
case IMGTYPE_YUV111:
|
270 |
case IMGTYPE_RGB24:
|
271 |
for (row = 0; row < height; row++) { |
272 |
pixel_ptr = row * width * 3;
|
273 |
yq = encoded[pixel_ptr++]; |
274 |
uqvq = AV_RL16(encoded+pixel_ptr); |
275 |
pixel_ptr += 2;
|
276 |
for (col = 1; col < width; col++) { |
277 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
278 |
uqvq -= AV_RL16(encoded+pixel_ptr+1);
|
279 |
AV_WL16(encoded+pixel_ptr+1, uqvq);
|
280 |
pixel_ptr += 3;
|
281 |
} |
282 |
} |
283 |
break;
|
284 |
case IMGTYPE_YUV422:
|
285 |
for (row = 0; row < height; row++) { |
286 |
pixel_ptr = row * width * 2;
|
287 |
yq = uq = vq =0;
|
288 |
for (col = 0; col < width/4; col++) { |
289 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
290 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
291 |
encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; |
292 |
encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; |
293 |
encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; |
294 |
encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; |
295 |
encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; |
296 |
encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; |
297 |
pixel_ptr += 8;
|
298 |
} |
299 |
} |
300 |
break;
|
301 |
case IMGTYPE_YUV411:
|
302 |
for (row = 0; row < height; row++) { |
303 |
pixel_ptr = row * width / 2 * 3; |
304 |
yq = uq = vq =0;
|
305 |
for (col = 0; col < width/4; col++) { |
306 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
307 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
308 |
encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; |
309 |
encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; |
310 |
encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; |
311 |
encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; |
312 |
pixel_ptr += 6;
|
313 |
} |
314 |
} |
315 |
break;
|
316 |
case IMGTYPE_YUV211:
|
317 |
for (row = 0; row < height; row++) { |
318 |
pixel_ptr = row * width * 2;
|
319 |
yq = uq = vq =0;
|
320 |
for (col = 0; col < width/2; col++) { |
321 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
322 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
323 |
encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; |
324 |
encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; |
325 |
pixel_ptr += 4;
|
326 |
} |
327 |
} |
328 |
break;
|
329 |
case IMGTYPE_YUV420:
|
330 |
for (row = 0; row < height/2; row++) { |
331 |
pixel_ptr = row * width * 3;
|
332 |
yq = y1q = uq = vq =0;
|
333 |
for (col = 0; col < width/2; col++) { |
334 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
335 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
336 |
encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; |
337 |
encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; |
338 |
encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; |
339 |
encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; |
340 |
pixel_ptr += 6;
|
341 |
} |
342 |
} |
343 |
break;
|
344 |
default:
|
345 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
|
346 |
return -1; |
347 |
} |
348 |
} |
349 |
|
350 |
/* Convert colorspace */
|
351 |
y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; |
352 |
u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; |
353 |
v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; |
354 |
switch (c->imgtype) {
|
355 |
case IMGTYPE_YUV111:
|
356 |
for (row = 0; row < height; row++) { |
357 |
for (col = 0; col < width; col++) { |
358 |
y_out[col] = *encoded++; |
359 |
u_out[col] = *encoded++ + 128;
|
360 |
v_out[col] = *encoded++ + 128;
|
361 |
} |
362 |
y_out -= c->pic.linesize[0];
|
363 |
u_out -= c->pic.linesize[1];
|
364 |
v_out -= c->pic.linesize[2];
|
365 |
} |
366 |
break;
|
367 |
case IMGTYPE_YUV422:
|
368 |
for (row = 0; row < height; row++) { |
369 |
for (col = 0; col < width - 3; col += 4) { |
370 |
memcpy(y_out + col, encoded, 4);
|
371 |
encoded += 4;
|
372 |
u_out[ col >> 1 ] = *encoded++ + 128; |
373 |
u_out[(col >> 1) + 1] = *encoded++ + 128; |
374 |
v_out[ col >> 1 ] = *encoded++ + 128; |
375 |
v_out[(col >> 1) + 1] = *encoded++ + 128; |
376 |
} |
377 |
y_out -= c->pic.linesize[0];
|
378 |
u_out -= c->pic.linesize[1];
|
379 |
v_out -= c->pic.linesize[2];
|
380 |
} |
381 |
break;
|
382 |
case IMGTYPE_RGB24:
|
383 |
for (row = height - 1; row >= 0; row--) { |
384 |
pixel_ptr = row * c->pic.linesize[0];
|
385 |
memcpy(outptr + pixel_ptr, encoded, 3 * width);
|
386 |
encoded += 3 * width;
|
387 |
} |
388 |
break;
|
389 |
case IMGTYPE_YUV411:
|
390 |
for (row = 0; row < height; row++) { |
391 |
for (col = 0; col < width - 3; col += 4) { |
392 |
memcpy(y_out + col, encoded, 4);
|
393 |
encoded += 4;
|
394 |
u_out[col >> 2] = *encoded++ + 128; |
395 |
v_out[col >> 2] = *encoded++ + 128; |
396 |
} |
397 |
y_out -= c->pic.linesize[0];
|
398 |
u_out -= c->pic.linesize[1];
|
399 |
v_out -= c->pic.linesize[2];
|
400 |
} |
401 |
break;
|
402 |
case IMGTYPE_YUV211:
|
403 |
for (row = 0; row < height; row++) { |
404 |
for (col = 0; col < width - 1; col += 2) { |
405 |
memcpy(y_out + col, encoded, 2);
|
406 |
encoded += 2;
|
407 |
u_out[col >> 1] = *encoded++ + 128; |
408 |
v_out[col >> 1] = *encoded++ + 128; |
409 |
} |
410 |
y_out -= c->pic.linesize[0];
|
411 |
u_out -= c->pic.linesize[1];
|
412 |
v_out -= c->pic.linesize[2];
|
413 |
} |
414 |
break;
|
415 |
case IMGTYPE_YUV420:
|
416 |
u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; |
417 |
v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; |
418 |
for (row = 0; row < height - 1; row += 2) { |
419 |
for (col = 0; col < width - 1; col += 2) { |
420 |
memcpy(y_out + col, encoded, 2);
|
421 |
encoded += 2;
|
422 |
memcpy(y_out + col - c->pic.linesize[0], encoded, 2); |
423 |
encoded += 2;
|
424 |
u_out[col >> 1] = *encoded++ + 128; |
425 |
v_out[col >> 1] = *encoded++ + 128; |
426 |
} |
427 |
y_out -= c->pic.linesize[0] << 1; |
428 |
u_out -= c->pic.linesize[1];
|
429 |
v_out -= c->pic.linesize[2];
|
430 |
} |
431 |
break;
|
432 |
default:
|
433 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
|
434 |
return -1; |
435 |
} |
436 |
|
437 |
*data_size = sizeof(AVFrame);
|
438 |
*(AVFrame*)data = c->pic; |
439 |
|
440 |
/* always report that the buffer was completely consumed */
|
441 |
return buf_size;
|
442 |
} |
443 |
|
444 |
/*
|
445 |
*
|
446 |
* Init lcl decoder
|
447 |
*
|
448 |
*/
|
449 |
static av_cold int decode_init(AVCodecContext *avctx) |
450 |
{ |
451 |
LclDecContext * const c = avctx->priv_data;
|
452 |
unsigned int basesize = avctx->width * avctx->height; |
453 |
unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; |
454 |
unsigned int max_decomp_size; |
455 |
|
456 |
if (avctx->extradata_size < 8) { |
457 |
av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
|
458 |
return 1; |
459 |
} |
460 |
|
461 |
/* Check codec type */
|
462 |
if ((avctx->codec_id == CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) || |
463 |
(avctx->codec_id == CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) {
|
464 |
av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
|
465 |
} |
466 |
|
467 |
/* Detect image type */
|
468 |
switch (c->imgtype = avctx->extradata[4]) { |
469 |
case IMGTYPE_YUV111:
|
470 |
c->decomp_size = basesize * 3;
|
471 |
max_decomp_size = max_basesize * 3;
|
472 |
avctx->pix_fmt = PIX_FMT_YUV444P; |
473 |
av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n");
|
474 |
break;
|
475 |
case IMGTYPE_YUV422:
|
476 |
c->decomp_size = basesize * 2;
|
477 |
max_decomp_size = max_basesize * 2;
|
478 |
avctx->pix_fmt = PIX_FMT_YUV422P; |
479 |
av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n");
|
480 |
break;
|
481 |
case IMGTYPE_RGB24:
|
482 |
c->decomp_size = basesize * 3;
|
483 |
max_decomp_size = max_basesize * 3;
|
484 |
avctx->pix_fmt = PIX_FMT_BGR24; |
485 |
av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n");
|
486 |
break;
|
487 |
case IMGTYPE_YUV411:
|
488 |
c->decomp_size = basesize / 2 * 3; |
489 |
max_decomp_size = max_basesize / 2 * 3; |
490 |
avctx->pix_fmt = PIX_FMT_YUV411P; |
491 |
av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n");
|
492 |
break;
|
493 |
case IMGTYPE_YUV211:
|
494 |
c->decomp_size = basesize * 2;
|
495 |
max_decomp_size = max_basesize * 2;
|
496 |
avctx->pix_fmt = PIX_FMT_YUV422P; |
497 |
av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n");
|
498 |
break;
|
499 |
case IMGTYPE_YUV420:
|
500 |
c->decomp_size = basesize / 2 * 3; |
501 |
max_decomp_size = max_basesize / 2 * 3; |
502 |
avctx->pix_fmt = PIX_FMT_YUV420P; |
503 |
av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n");
|
504 |
break;
|
505 |
default:
|
506 |
av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
|
507 |
return 1; |
508 |
} |
509 |
|
510 |
/* Detect compression method */
|
511 |
c->compression = (int8_t)avctx->extradata[5];
|
512 |
switch (avctx->codec_id) {
|
513 |
case CODEC_ID_MSZH:
|
514 |
switch (c->compression) {
|
515 |
case COMP_MSZH:
|
516 |
av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n");
|
517 |
break;
|
518 |
case COMP_MSZH_NOCOMP:
|
519 |
c->decomp_size = 0;
|
520 |
av_log(avctx, AV_LOG_DEBUG, "No compression.\n");
|
521 |
break;
|
522 |
default:
|
523 |
av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
|
524 |
return 1; |
525 |
} |
526 |
break;
|
527 |
#if CONFIG_ZLIB_DECODER
|
528 |
case CODEC_ID_ZLIB:
|
529 |
switch (c->compression) {
|
530 |
case COMP_ZLIB_HISPEED:
|
531 |
av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n");
|
532 |
break;
|
533 |
case COMP_ZLIB_HICOMP:
|
534 |
av_log(avctx, AV_LOG_DEBUG, "High compression.\n");
|
535 |
break;
|
536 |
case COMP_ZLIB_NORMAL:
|
537 |
av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n");
|
538 |
break;
|
539 |
default:
|
540 |
if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
|
541 |
av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
|
542 |
return 1; |
543 |
} |
544 |
av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
|
545 |
} |
546 |
break;
|
547 |
#endif
|
548 |
default:
|
549 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
|
550 |
return 1; |
551 |
} |
552 |
|
553 |
/* Allocate decompression buffer */
|
554 |
if (c->decomp_size) {
|
555 |
if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { |
556 |
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
|
557 |
return 1; |
558 |
} |
559 |
} |
560 |
|
561 |
/* Detect flags */
|
562 |
c->flags = avctx->extradata[6];
|
563 |
if (c->flags & FLAG_MULTITHREAD)
|
564 |
av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n");
|
565 |
if (c->flags & FLAG_NULLFRAME)
|
566 |
av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n");
|
567 |
if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER))
|
568 |
av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n");
|
569 |
if (c->flags & FLAGMASK_UNUSED)
|
570 |
av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
|
571 |
|
572 |
/* If needed init zlib */
|
573 |
#if CONFIG_ZLIB_DECODER
|
574 |
if (avctx->codec_id == CODEC_ID_ZLIB) {
|
575 |
int zret;
|
576 |
c->zstream.zalloc = Z_NULL; |
577 |
c->zstream.zfree = Z_NULL; |
578 |
c->zstream.opaque = Z_NULL; |
579 |
zret = inflateInit(&c->zstream); |
580 |
if (zret != Z_OK) {
|
581 |
av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
|
582 |
av_freep(&c->decomp_buf); |
583 |
return 1; |
584 |
} |
585 |
} |
586 |
#endif
|
587 |
|
588 |
return 0; |
589 |
} |
590 |
|
591 |
/*
|
592 |
*
|
593 |
* Uninit lcl decoder
|
594 |
*
|
595 |
*/
|
596 |
static av_cold int decode_end(AVCodecContext *avctx) |
597 |
{ |
598 |
LclDecContext * const c = avctx->priv_data;
|
599 |
|
600 |
av_freep(&c->decomp_buf); |
601 |
if (c->pic.data[0]) |
602 |
avctx->release_buffer(avctx, &c->pic); |
603 |
#if CONFIG_ZLIB_DECODER
|
604 |
if (avctx->codec_id == CODEC_ID_ZLIB)
|
605 |
inflateEnd(&c->zstream); |
606 |
#endif
|
607 |
|
608 |
return 0; |
609 |
} |
610 |
|
611 |
#if CONFIG_MSZH_DECODER
|
612 |
AVCodec ff_mszh_decoder = { |
613 |
"mszh",
|
614 |
AVMEDIA_TYPE_VIDEO, |
615 |
CODEC_ID_MSZH, |
616 |
sizeof(LclDecContext),
|
617 |
decode_init, |
618 |
NULL,
|
619 |
decode_end, |
620 |
decode_frame, |
621 |
CODEC_CAP_DR1, |
622 |
.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
|
623 |
}; |
624 |
#endif
|
625 |
|
626 |
#if CONFIG_ZLIB_DECODER
|
627 |
AVCodec ff_zlib_decoder = { |
628 |
"zlib",
|
629 |
AVMEDIA_TYPE_VIDEO, |
630 |
CODEC_ID_ZLIB, |
631 |
sizeof(LclDecContext),
|
632 |
decode_init, |
633 |
NULL,
|
634 |
decode_end, |
635 |
decode_frame, |
636 |
CODEC_CAP_DR1, |
637 |
.long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
|
638 |
}; |
639 |
#endif
|