Line data Source code
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 : #include <stdio.h>
41 : #include <stdlib.h>
42 :
43 : #include "libavutil/mem.h"
44 : #include "libavutil/pixdesc.h"
45 : #include "avcodec.h"
46 : #include "bytestream.h"
47 : #include "internal.h"
48 : #include "lcl.h"
49 : #include "thread.h"
50 :
51 : #if CONFIG_ZLIB_DECODER
52 : #include <zlib.h>
53 : #endif
54 :
55 : typedef struct LclDecContext {
56 : // Image type
57 : int imgtype;
58 : // Compression type
59 : int compression;
60 : // Flags
61 : int flags;
62 : // Decompressed data size
63 : unsigned int decomp_size;
64 : // Decompression buffer
65 : unsigned char* decomp_buf;
66 : #if CONFIG_ZLIB_DECODER
67 : z_stream zstream;
68 : #endif
69 : } LclDecContext;
70 :
71 :
72 : /**
73 : * @param srcptr compressed source buffer, must be padded with at least 5 extra bytes
74 : * @param destptr must be padded sufficiently for av_memcpy_backptr
75 : */
76 1 : static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize)
77 : {
78 1 : unsigned char *destptr_bak = destptr;
79 1 : unsigned char *destptr_end = destptr + destsize;
80 1 : const unsigned char *srcptr_end = srcptr + srclen;
81 1 : unsigned mask = *srcptr++;
82 1 : unsigned maskbit = 0x80;
83 :
84 30274 : while (srcptr < srcptr_end && destptr < destptr_end) {
85 30272 : if (!(mask & maskbit)) {
86 19751 : memcpy(destptr, srcptr, 4);
87 19751 : destptr += 4;
88 19751 : srcptr += 4;
89 : } else {
90 10521 : unsigned ofs = bytestream_get_le16(&srcptr);
91 10521 : unsigned cnt = (ofs >> 11) + 1;
92 10521 : ofs &= 0x7ff;
93 10521 : ofs = FFMIN(ofs, destptr - destptr_bak);
94 10521 : cnt *= 4;
95 10521 : cnt = FFMIN(cnt, destptr_end - destptr);
96 10521 : if (ofs) {
97 10521 : av_memcpy_backptr(destptr, ofs, cnt);
98 : } else {
99 : // Not known what the correct behaviour is, but
100 : // this at least avoids uninitialized data.
101 0 : memset(destptr, 0, cnt);
102 : }
103 10521 : destptr += cnt;
104 : }
105 30272 : maskbit >>= 1;
106 30272 : if (!maskbit) {
107 3784 : mask = *srcptr++;
108 10280 : while (!mask) {
109 2713 : if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break;
110 2712 : memcpy(destptr, srcptr, 32);
111 2712 : destptr += 32;
112 2712 : srcptr += 32;
113 2712 : mask = *srcptr++;
114 : }
115 3784 : maskbit = 0x80;
116 : }
117 : }
118 :
119 1 : return destptr - destptr_bak;
120 : }
121 :
122 :
123 : #if CONFIG_ZLIB_DECODER
124 : /**
125 : * @brief decompress a zlib-compressed data block into decomp_buf
126 : * @param src compressed input buffer
127 : * @param src_len data length in input buffer
128 : * @param offset offset in decomp_buf
129 : * @param expected expected decompressed length
130 : */
131 201 : static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected)
132 : {
133 201 : LclDecContext *c = avctx->priv_data;
134 201 : int zret = inflateReset(&c->zstream);
135 201 : if (zret != Z_OK) {
136 0 : av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
137 0 : return AVERROR_UNKNOWN;
138 : }
139 201 : c->zstream.next_in = (uint8_t *)src;
140 201 : c->zstream.avail_in = src_len;
141 201 : c->zstream.next_out = c->decomp_buf + offset;
142 201 : c->zstream.avail_out = c->decomp_size - offset;
143 201 : zret = inflate(&c->zstream, Z_FINISH);
144 201 : if (zret != Z_OK && zret != Z_STREAM_END) {
145 0 : av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
146 0 : return AVERROR_UNKNOWN;
147 : }
148 201 : if (expected != (unsigned int)c->zstream.total_out) {
149 0 : av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
150 : expected, c->zstream.total_out);
151 0 : return AVERROR_UNKNOWN;
152 : }
153 201 : return c->zstream.total_out;
154 : }
155 : #endif
156 :
157 :
158 202 : static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
159 : {
160 202 : AVFrame *frame = data;
161 202 : ThreadFrame tframe = { .f = data };
162 202 : const uint8_t *buf = avpkt->data;
163 202 : int buf_size = avpkt->size;
164 202 : LclDecContext * const c = avctx->priv_data;
165 : unsigned int pixel_ptr;
166 : int row, col;
167 202 : unsigned char *encoded = avpkt->data, *outptr;
168 : uint8_t *y_out, *u_out, *v_out;
169 202 : unsigned int width = avctx->width; // Real image width
170 202 : unsigned int height = avctx->height; // Real image height
171 : unsigned int mszh_dlen;
172 : unsigned char yq, y1q, uq, vq;
173 : int uqvq, ret;
174 : unsigned int mthread_inlen, mthread_outlen;
175 202 : unsigned int len = buf_size;
176 : int linesize;
177 :
178 202 : if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
179 0 : return ret;
180 :
181 202 : outptr = frame->data[0]; // Output image pointer
182 :
183 : /* Decompress frame */
184 202 : switch (avctx->codec_id) {
185 1 : case AV_CODEC_ID_MSZH:
186 1 : switch (c->compression) {
187 1 : case COMP_MSZH:
188 2 : if (c->imgtype == IMGTYPE_RGB24 && len == FFALIGN(width * 3, 4) * height ||
189 1 : c->imgtype == IMGTYPE_YUV111 && len == width * height * 3) {
190 : ;
191 1 : } else if (c->flags & FLAG_MULTITHREAD) {
192 0 : mthread_inlen = AV_RL32(buf);
193 0 : if (len < 8) {
194 0 : av_log(avctx, AV_LOG_ERROR, "len %d is too small\n", len);
195 0 : return AVERROR_INVALIDDATA;
196 : }
197 0 : mthread_inlen = FFMIN(mthread_inlen, len - 8);
198 0 : mthread_outlen = AV_RL32(buf + 4);
199 0 : mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
200 0 : mszh_dlen = mszh_decomp(buf + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
201 0 : if (mthread_outlen != mszh_dlen) {
202 0 : av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
203 : mthread_outlen, mszh_dlen);
204 0 : return AVERROR_INVALIDDATA;
205 : }
206 0 : mszh_dlen = mszh_decomp(buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
207 0 : c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen);
208 0 : if (mthread_outlen != mszh_dlen) {
209 0 : av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
210 : mthread_outlen, mszh_dlen);
211 0 : return AVERROR_INVALIDDATA;
212 : }
213 0 : encoded = c->decomp_buf;
214 0 : len = c->decomp_size;
215 : } else {
216 1 : mszh_dlen = mszh_decomp(buf, len, c->decomp_buf, c->decomp_size);
217 1 : if (c->decomp_size != mszh_dlen) {
218 0 : av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
219 : c->decomp_size, mszh_dlen);
220 0 : return AVERROR_INVALIDDATA;
221 : }
222 1 : encoded = c->decomp_buf;
223 1 : len = mszh_dlen;
224 : }
225 1 : break;
226 0 : case COMP_MSZH_NOCOMP: {
227 : int bppx2;
228 0 : switch (c->imgtype) {
229 0 : case IMGTYPE_YUV111:
230 : case IMGTYPE_RGB24:
231 0 : bppx2 = 6;
232 0 : break;
233 0 : case IMGTYPE_YUV422:
234 : case IMGTYPE_YUV211:
235 0 : bppx2 = 4;
236 0 : break;
237 0 : case IMGTYPE_YUV411:
238 : case IMGTYPE_YUV420:
239 0 : bppx2 = 3;
240 0 : break;
241 0 : default:
242 0 : bppx2 = 0; // will error out below
243 0 : break;
244 : }
245 0 : if (len < ((width * height * bppx2) >> 1))
246 0 : return AVERROR_INVALIDDATA;
247 0 : break;
248 : }
249 0 : default:
250 0 : av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
251 0 : return AVERROR_INVALIDDATA;
252 : }
253 1 : break;
254 : #if CONFIG_ZLIB_DECODER
255 201 : case AV_CODEC_ID_ZLIB:
256 : /* Using the original dll with normal compression (-1) and RGB format
257 : * gives a file with ZLIB fourcc, but frame is really uncompressed.
258 : * To be sure that's true check also frame size */
259 401 : if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 &&
260 200 : len == width * height * 3) {
261 0 : if (c->flags & FLAG_PNGFILTER) {
262 0 : memcpy(c->decomp_buf, buf, len);
263 0 : encoded = c->decomp_buf;
264 : } else {
265 0 : break;
266 : }
267 201 : } else if (c->flags & FLAG_MULTITHREAD) {
268 0 : mthread_inlen = AV_RL32(buf);
269 0 : mthread_inlen = FFMIN(mthread_inlen, len - 8);
270 0 : mthread_outlen = AV_RL32(buf + 4);
271 0 : mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
272 0 : ret = zlib_decomp(avctx, buf + 8, mthread_inlen, 0, mthread_outlen);
273 0 : if (ret < 0) return ret;
274 0 : ret = zlib_decomp(avctx, buf + 8 + mthread_inlen, len - 8 - mthread_inlen,
275 : mthread_outlen, mthread_outlen);
276 0 : if (ret < 0) return ret;
277 : } else {
278 201 : int ret = zlib_decomp(avctx, buf, len, 0, c->decomp_size);
279 201 : if (ret < 0) return ret;
280 : }
281 201 : encoded = c->decomp_buf;
282 201 : len = c->decomp_size;
283 201 : break;
284 : #endif
285 0 : default:
286 0 : av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
287 0 : return AVERROR_INVALIDDATA;
288 : }
289 :
290 :
291 : /* Apply PNG filter */
292 202 : if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) {
293 0 : switch (c->imgtype) {
294 0 : case IMGTYPE_YUV111:
295 : case IMGTYPE_RGB24:
296 0 : for (row = 0; row < height; row++) {
297 0 : pixel_ptr = row * width * 3;
298 0 : yq = encoded[pixel_ptr++];
299 0 : uqvq = AV_RL16(encoded+pixel_ptr);
300 0 : pixel_ptr += 2;
301 0 : for (col = 1; col < width; col++) {
302 0 : encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
303 0 : uqvq -= AV_RL16(encoded+pixel_ptr+1);
304 0 : AV_WL16(encoded+pixel_ptr+1, uqvq);
305 0 : pixel_ptr += 3;
306 : }
307 : }
308 0 : break;
309 0 : case IMGTYPE_YUV422:
310 0 : for (row = 0; row < height; row++) {
311 0 : pixel_ptr = row * width * 2;
312 0 : yq = uq = vq =0;
313 0 : for (col = 0; col < width/4; col++) {
314 0 : encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
315 0 : encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
316 0 : encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
317 0 : encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
318 0 : encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
319 0 : encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5];
320 0 : encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6];
321 0 : encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7];
322 0 : pixel_ptr += 8;
323 : }
324 : }
325 0 : break;
326 0 : case IMGTYPE_YUV411:
327 0 : for (row = 0; row < height; row++) {
328 0 : pixel_ptr = row * width / 2 * 3;
329 0 : yq = uq = vq =0;
330 0 : for (col = 0; col < width/4; col++) {
331 0 : encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
332 0 : encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
333 0 : encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2];
334 0 : encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3];
335 0 : encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
336 0 : encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
337 0 : pixel_ptr += 6;
338 : }
339 : }
340 0 : break;
341 0 : case IMGTYPE_YUV211:
342 0 : for (row = 0; row < height; row++) {
343 0 : pixel_ptr = row * width * 2;
344 0 : yq = uq = vq =0;
345 0 : for (col = 0; col < width/2; col++) {
346 0 : encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
347 0 : encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
348 0 : encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2];
349 0 : encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3];
350 0 : pixel_ptr += 4;
351 : }
352 : }
353 0 : break;
354 0 : case IMGTYPE_YUV420:
355 0 : for (row = 0; row < height/2; row++) {
356 0 : pixel_ptr = row * width * 3;
357 0 : yq = y1q = uq = vq =0;
358 0 : for (col = 0; col < width/2; col++) {
359 0 : encoded[pixel_ptr] = yq -= encoded[pixel_ptr];
360 0 : encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1];
361 0 : encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2];
362 0 : encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3];
363 0 : encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4];
364 0 : encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5];
365 0 : pixel_ptr += 6;
366 : }
367 : }
368 0 : break;
369 0 : default:
370 0 : av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
371 0 : return AVERROR_INVALIDDATA;
372 : }
373 202 : }
374 :
375 : /* Convert colorspace */
376 202 : y_out = frame->data[0] + (height - 1) * frame->linesize[0];
377 202 : u_out = frame->data[1] + (height - 1) * frame->linesize[1];
378 202 : v_out = frame->data[2] + (height - 1) * frame->linesize[2];
379 202 : switch (c->imgtype) {
380 0 : case IMGTYPE_YUV111:
381 0 : for (row = 0; row < height; row++) {
382 0 : for (col = 0; col < width; col++) {
383 0 : y_out[col] = *encoded++;
384 0 : u_out[col] = *encoded++ + 128;
385 0 : v_out[col] = *encoded++ + 128;
386 : }
387 0 : y_out -= frame->linesize[0];
388 0 : u_out -= frame->linesize[1];
389 0 : v_out -= frame->linesize[2];
390 : }
391 0 : break;
392 0 : case IMGTYPE_YUV422:
393 0 : for (row = 0; row < height; row++) {
394 0 : for (col = 0; col < width - 3; col += 4) {
395 0 : memcpy(y_out + col, encoded, 4);
396 0 : encoded += 4;
397 0 : u_out[ col >> 1 ] = *encoded++ + 128;
398 0 : u_out[(col >> 1) + 1] = *encoded++ + 128;
399 0 : v_out[ col >> 1 ] = *encoded++ + 128;
400 0 : v_out[(col >> 1) + 1] = *encoded++ + 128;
401 : }
402 0 : y_out -= frame->linesize[0];
403 0 : u_out -= frame->linesize[1];
404 0 : v_out -= frame->linesize[2];
405 : }
406 0 : break;
407 202 : case IMGTYPE_RGB24:
408 202 : linesize = len < FFALIGN(3 * width, 4) * height ? 3 * width : FFALIGN(3 * width, 4);
409 45582 : for (row = height - 1; row >= 0; row--) {
410 45380 : pixel_ptr = row * frame->linesize[0];
411 45380 : memcpy(outptr + pixel_ptr, encoded, 3 * width);
412 45380 : encoded += linesize;
413 : }
414 202 : break;
415 0 : case IMGTYPE_YUV411:
416 0 : for (row = 0; row < height; row++) {
417 0 : for (col = 0; col < width - 3; col += 4) {
418 0 : memcpy(y_out + col, encoded, 4);
419 0 : encoded += 4;
420 0 : u_out[col >> 2] = *encoded++ + 128;
421 0 : v_out[col >> 2] = *encoded++ + 128;
422 : }
423 0 : y_out -= frame->linesize[0];
424 0 : u_out -= frame->linesize[1];
425 0 : v_out -= frame->linesize[2];
426 : }
427 0 : break;
428 0 : case IMGTYPE_YUV211:
429 0 : for (row = 0; row < height; row++) {
430 0 : for (col = 0; col < width - 1; col += 2) {
431 0 : memcpy(y_out + col, encoded, 2);
432 0 : encoded += 2;
433 0 : u_out[col >> 1] = *encoded++ + 128;
434 0 : v_out[col >> 1] = *encoded++ + 128;
435 : }
436 0 : y_out -= frame->linesize[0];
437 0 : u_out -= frame->linesize[1];
438 0 : v_out -= frame->linesize[2];
439 : }
440 0 : break;
441 0 : case IMGTYPE_YUV420:
442 0 : u_out = frame->data[1] + ((height >> 1) - 1) * frame->linesize[1];
443 0 : v_out = frame->data[2] + ((height >> 1) - 1) * frame->linesize[2];
444 0 : for (row = 0; row < height - 1; row += 2) {
445 0 : for (col = 0; col < width - 1; col += 2) {
446 0 : memcpy(y_out + col, encoded, 2);
447 0 : encoded += 2;
448 0 : memcpy(y_out + col - frame->linesize[0], encoded, 2);
449 0 : encoded += 2;
450 0 : u_out[col >> 1] = *encoded++ + 128;
451 0 : v_out[col >> 1] = *encoded++ + 128;
452 : }
453 0 : y_out -= frame->linesize[0] << 1;
454 0 : u_out -= frame->linesize[1];
455 0 : v_out -= frame->linesize[2];
456 : }
457 0 : break;
458 0 : default:
459 0 : av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
460 0 : return AVERROR_INVALIDDATA;
461 : }
462 :
463 202 : frame->key_frame = 1;
464 202 : frame->pict_type = AV_PICTURE_TYPE_I;
465 :
466 202 : *got_frame = 1;
467 :
468 : /* always report that the buffer was completely consumed */
469 202 : return buf_size;
470 : }
471 :
472 12 : static av_cold int decode_init(AVCodecContext *avctx)
473 : {
474 12 : LclDecContext * const c = avctx->priv_data;
475 12 : unsigned int basesize = avctx->width * avctx->height;
476 24 : unsigned int max_basesize = FFALIGN(avctx->width, 4) *
477 12 : FFALIGN(avctx->height, 4);
478 : unsigned int max_decomp_size;
479 : int subsample_h, subsample_v;
480 :
481 12 : if (avctx->extradata_size < 8) {
482 0 : av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
483 0 : return AVERROR_INVALIDDATA;
484 : }
485 :
486 : /* Check codec type */
487 24 : if ((avctx->codec_id == AV_CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) ||
488 22 : (avctx->codec_id == AV_CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) {
489 0 : av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
490 : }
491 :
492 : /* Detect image type */
493 12 : switch (c->imgtype = avctx->extradata[4]) {
494 0 : case IMGTYPE_YUV111:
495 0 : c->decomp_size = basesize * 3;
496 0 : max_decomp_size = max_basesize * 3;
497 0 : avctx->pix_fmt = AV_PIX_FMT_YUV444P;
498 0 : av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n");
499 0 : break;
500 0 : case IMGTYPE_YUV422:
501 0 : c->decomp_size = basesize * 2;
502 0 : max_decomp_size = max_basesize * 2;
503 0 : avctx->pix_fmt = AV_PIX_FMT_YUV422P;
504 0 : av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n");
505 0 : if (avctx->width % 4) {
506 0 : avpriv_request_sample(avctx, "Unsupported dimensions");
507 0 : return AVERROR_INVALIDDATA;
508 : }
509 0 : break;
510 12 : case IMGTYPE_RGB24:
511 12 : c->decomp_size = basesize * 3;
512 12 : max_decomp_size = max_basesize * 3;
513 12 : avctx->pix_fmt = AV_PIX_FMT_BGR24;
514 12 : av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n");
515 12 : break;
516 0 : case IMGTYPE_YUV411:
517 0 : c->decomp_size = basesize / 2 * 3;
518 0 : max_decomp_size = max_basesize / 2 * 3;
519 0 : avctx->pix_fmt = AV_PIX_FMT_YUV411P;
520 0 : av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n");
521 0 : break;
522 0 : case IMGTYPE_YUV211:
523 0 : c->decomp_size = basesize * 2;
524 0 : max_decomp_size = max_basesize * 2;
525 0 : avctx->pix_fmt = AV_PIX_FMT_YUV422P;
526 0 : av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n");
527 0 : break;
528 0 : case IMGTYPE_YUV420:
529 0 : c->decomp_size = basesize / 2 * 3;
530 0 : max_decomp_size = max_basesize / 2 * 3;
531 0 : avctx->pix_fmt = AV_PIX_FMT_YUV420P;
532 0 : av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n");
533 0 : break;
534 0 : default:
535 0 : av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
536 0 : return AVERROR_INVALIDDATA;
537 : }
538 :
539 12 : av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v);
540 12 : if (avctx->width % (1<<subsample_h) || avctx->height % (1<<subsample_v)) {
541 0 : avpriv_request_sample(avctx, "Unsupported dimensions");
542 0 : return AVERROR_INVALIDDATA;
543 : }
544 :
545 : /* Detect compression method */
546 12 : c->compression = (int8_t)avctx->extradata[5];
547 12 : switch (avctx->codec_id) {
548 2 : case AV_CODEC_ID_MSZH:
549 2 : switch (c->compression) {
550 2 : case COMP_MSZH:
551 2 : av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n");
552 2 : break;
553 0 : case COMP_MSZH_NOCOMP:
554 0 : c->decomp_size = 0;
555 0 : av_log(avctx, AV_LOG_DEBUG, "No compression.\n");
556 0 : break;
557 0 : default:
558 0 : av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
559 0 : return AVERROR_INVALIDDATA;
560 : }
561 2 : break;
562 : #if CONFIG_ZLIB_DECODER
563 10 : case AV_CODEC_ID_ZLIB:
564 10 : switch (c->compression) {
565 0 : case COMP_ZLIB_HISPEED:
566 0 : av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n");
567 0 : break;
568 2 : case COMP_ZLIB_HICOMP:
569 2 : av_log(avctx, AV_LOG_DEBUG, "High compression.\n");
570 2 : break;
571 8 : case COMP_ZLIB_NORMAL:
572 8 : av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n");
573 8 : break;
574 0 : default:
575 0 : if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) {
576 0 : av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
577 0 : return AVERROR_INVALIDDATA;
578 : }
579 0 : av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression);
580 : }
581 10 : break;
582 : #endif
583 0 : default:
584 0 : av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
585 0 : return AVERROR_INVALIDDATA;
586 : }
587 :
588 : /* Allocate decompression buffer */
589 12 : if (c->decomp_size) {
590 12 : if (!(c->decomp_buf = av_malloc(max_decomp_size))) {
591 0 : av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
592 0 : return AVERROR(ENOMEM);
593 : }
594 : }
595 :
596 : /* Detect flags */
597 12 : c->flags = avctx->extradata[6];
598 12 : if (c->flags & FLAG_MULTITHREAD)
599 0 : av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n");
600 12 : if (c->flags & FLAG_NULLFRAME)
601 0 : av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n");
602 12 : if (avctx->codec_id == AV_CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER))
603 0 : av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n");
604 12 : if (c->flags & FLAGMASK_UNUSED)
605 0 : av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
606 :
607 : /* If needed init zlib */
608 : #if CONFIG_ZLIB_DECODER
609 12 : if (avctx->codec_id == AV_CODEC_ID_ZLIB) {
610 : int zret;
611 10 : c->zstream.zalloc = Z_NULL;
612 10 : c->zstream.zfree = Z_NULL;
613 10 : c->zstream.opaque = Z_NULL;
614 10 : zret = inflateInit(&c->zstream);
615 10 : if (zret != Z_OK) {
616 0 : av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
617 0 : av_freep(&c->decomp_buf);
618 0 : return AVERROR_UNKNOWN;
619 : }
620 : }
621 : #endif
622 :
623 12 : return 0;
624 : }
625 :
626 : #if HAVE_THREADS
627 0 : static int init_thread_copy(AVCodecContext *avctx)
628 : {
629 0 : return decode_init(avctx);
630 : }
631 : #endif
632 :
633 12 : static av_cold int decode_end(AVCodecContext *avctx)
634 : {
635 12 : LclDecContext * const c = avctx->priv_data;
636 :
637 12 : av_freep(&c->decomp_buf);
638 : #if CONFIG_ZLIB_DECODER
639 12 : if (avctx->codec_id == AV_CODEC_ID_ZLIB)
640 10 : inflateEnd(&c->zstream);
641 : #endif
642 :
643 12 : return 0;
644 : }
645 :
646 : #if CONFIG_MSZH_DECODER
647 : AVCodec ff_mszh_decoder = {
648 : .name = "mszh",
649 : .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"),
650 : .type = AVMEDIA_TYPE_VIDEO,
651 : .id = AV_CODEC_ID_MSZH,
652 : .priv_data_size = sizeof(LclDecContext),
653 : .init = decode_init,
654 : .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
655 : .close = decode_end,
656 : .decode = decode_frame,
657 : .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
658 : .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
659 : };
660 : #endif
661 :
662 : #if CONFIG_ZLIB_DECODER
663 : AVCodec ff_zlib_decoder = {
664 : .name = "zlib",
665 : .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
666 : .type = AVMEDIA_TYPE_VIDEO,
667 : .id = AV_CODEC_ID_ZLIB,
668 : .priv_data_size = sizeof(LclDecContext),
669 : .init = decode_init,
670 : .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
671 : .close = decode_end,
672 : .decode = decode_frame,
673 : .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
674 : .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
675 : };
676 : #endif
|