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