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