Libav 0.7.1
|
00001 /* 00002 * LCL (LossLess Codec Library) Codec 00003 * Copyright (c) 2002-2004 Roberto Togni 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00041 #include <stdio.h> 00042 #include <stdlib.h> 00043 00044 #include "avcodec.h" 00045 #include "bytestream.h" 00046 #include "lcl.h" 00047 #include "libavutil/lzo.h" 00048 00049 #if CONFIG_ZLIB_DECODER 00050 #include <zlib.h> 00051 #endif 00052 00053 /* 00054 * Decoder context 00055 */ 00056 typedef struct LclDecContext { 00057 AVFrame pic; 00058 00059 // Image type 00060 int imgtype; 00061 // Compression type 00062 int compression; 00063 // Flags 00064 int flags; 00065 // Decompressed data size 00066 unsigned int decomp_size; 00067 // Decompression buffer 00068 unsigned char* decomp_buf; 00069 #if CONFIG_ZLIB_DECODER 00070 z_stream zstream; 00071 #endif 00072 } LclDecContext; 00073 00074 00079 static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) 00080 { 00081 unsigned char *destptr_bak = destptr; 00082 unsigned char *destptr_end = destptr + destsize; 00083 const unsigned char *srcptr_end = srcptr + srclen; 00084 unsigned mask = *srcptr++; 00085 unsigned maskbit = 0x80; 00086 00087 while (srcptr < srcptr_end && destptr < destptr_end) { 00088 if (!(mask & maskbit)) { 00089 memcpy(destptr, srcptr, 4); 00090 destptr += 4; 00091 srcptr += 4; 00092 } else { 00093 unsigned ofs = bytestream_get_le16(&srcptr); 00094 unsigned cnt = (ofs >> 11) + 1; 00095 ofs &= 0x7ff; 00096 ofs = FFMIN(ofs, destptr - destptr_bak); 00097 cnt *= 4; 00098 cnt = FFMIN(cnt, destptr_end - destptr); 00099 av_memcpy_backptr(destptr, ofs, cnt); 00100 destptr += cnt; 00101 } 00102 maskbit >>= 1; 00103 if (!maskbit) { 00104 mask = *srcptr++; 00105 while (!mask) { 00106 if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break; 00107 memcpy(destptr, srcptr, 32); 00108 destptr += 32; 00109 srcptr += 32; 00110 mask = *srcptr++; 00111 } 00112 maskbit = 0x80; 00113 } 00114 } 00115 00116 return destptr - destptr_bak; 00117 } 00118 00119 00120 #if CONFIG_ZLIB_DECODER 00121 00128 static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) 00129 { 00130 LclDecContext *c = avctx->priv_data; 00131 int zret = inflateReset(&c->zstream); 00132 if (zret != Z_OK) { 00133 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); 00134 return -1; 00135 } 00136 c->zstream.next_in = src; 00137 c->zstream.avail_in = src_len; 00138 c->zstream.next_out = c->decomp_buf + offset; 00139 c->zstream.avail_out = c->decomp_size - offset; 00140 zret = inflate(&c->zstream, Z_FINISH); 00141 if (zret != Z_OK && zret != Z_STREAM_END) { 00142 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); 00143 return -1; 00144 } 00145 if (expected != (unsigned int)c->zstream.total_out) { 00146 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", 00147 expected, c->zstream.total_out); 00148 return -1; 00149 } 00150 return c->zstream.total_out; 00151 } 00152 #endif 00153 00154 00155 /* 00156 * 00157 * Decode a frame 00158 * 00159 */ 00160 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) 00161 { 00162 const uint8_t *buf = avpkt->data; 00163 int buf_size = avpkt->size; 00164 LclDecContext * const c = avctx->priv_data; 00165 unsigned char *encoded = (unsigned char *)buf; 00166 unsigned int pixel_ptr; 00167 int row, col; 00168 unsigned char *outptr; 00169 uint8_t *y_out, *u_out, *v_out; 00170 unsigned int width = avctx->width; // Real image width 00171 unsigned int height = avctx->height; // Real image height 00172 unsigned int mszh_dlen; 00173 unsigned char yq, y1q, uq, vq; 00174 int uqvq; 00175 unsigned int mthread_inlen, mthread_outlen; 00176 unsigned int len = buf_size; 00177 00178 if(c->pic.data[0]) 00179 avctx->release_buffer(avctx, &c->pic); 00180 00181 c->pic.reference = 0; 00182 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; 00183 if(avctx->get_buffer(avctx, &c->pic) < 0){ 00184 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 00185 return -1; 00186 } 00187 00188 outptr = c->pic.data[0]; // Output image pointer 00189 00190 /* Decompress frame */ 00191 switch (avctx->codec_id) { 00192 case CODEC_ID_MSZH: 00193 switch (c->compression) { 00194 case COMP_MSZH: 00195 if (c->flags & FLAG_MULTITHREAD) { 00196 mthread_inlen = AV_RL32(encoded); 00197 mthread_inlen = FFMIN(mthread_inlen, len - 8); 00198 mthread_outlen = AV_RL32(encoded+4); 00199 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); 00200 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); 00201 if (mthread_outlen != mszh_dlen) { 00202 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", 00203 mthread_outlen, mszh_dlen); 00204 return -1; 00205 } 00206 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, 00207 c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); 00208 if (mthread_outlen != mszh_dlen) { 00209 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", 00210 mthread_outlen, mszh_dlen); 00211 return -1; 00212 } 00213 encoded = c->decomp_buf; 00214 len = c->decomp_size; 00215 } else { 00216 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); 00217 if (c->decomp_size != mszh_dlen) { 00218 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", 00219 c->decomp_size, mszh_dlen); 00220 return -1; 00221 } 00222 encoded = c->decomp_buf; 00223 len = mszh_dlen; 00224 } 00225 break; 00226 case COMP_MSZH_NOCOMP: { 00227 int bppx2; 00228 switch (c->imgtype) { 00229 case IMGTYPE_YUV111: 00230 case IMGTYPE_RGB24: 00231 bppx2 = 6; 00232 break; 00233 case IMGTYPE_YUV422: 00234 case IMGTYPE_YUV211: 00235 bppx2 = 4; 00236 break; 00237 case IMGTYPE_YUV411: 00238 case IMGTYPE_YUV420: 00239 bppx2 = 3; 00240 break; 00241 default: 00242 bppx2 = 0; // will error out below 00243 break; 00244 } 00245 if (len < ((width * height * bppx2) >> 1)) 00246 return AVERROR_INVALIDDATA; 00247 break; 00248 } 00249 default: 00250 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); 00251 return -1; 00252 } 00253 break; 00254 #if CONFIG_ZLIB_DECODER 00255 case CODEC_ID_ZLIB: 00256 /* Using the original dll with normal compression (-1) and RGB format 00257 * gives a file with ZLIB fourcc, but frame is really uncompressed. 00258 * To be sure that's true check also frame size */ 00259 if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 && 00260 len == width * height * 3) 00261 break; 00262 if (c->flags & FLAG_MULTITHREAD) { 00263 int ret; 00264 mthread_inlen = AV_RL32(encoded); 00265 mthread_inlen = FFMIN(mthread_inlen, len - 8); 00266 mthread_outlen = AV_RL32(encoded+4); 00267 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); 00268 ret = zlib_decomp(avctx, encoded + 8, mthread_inlen, 0, mthread_outlen); 00269 if (ret < 0) return ret; 00270 ret = zlib_decomp(avctx, encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, 00271 mthread_outlen, mthread_outlen); 00272 if (ret < 0) return ret; 00273 } else { 00274 int ret = zlib_decomp(avctx, encoded, len, 0, c->decomp_size); 00275 if (ret < 0) return ret; 00276 } 00277 encoded = c->decomp_buf; 00278 len = c->decomp_size; 00279 break; 00280 #endif 00281 default: 00282 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); 00283 return -1; 00284 } 00285 00286 00287 /* Apply PNG filter */ 00288 if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) { 00289 switch (c->imgtype) { 00290 case IMGTYPE_YUV111: 00291 case IMGTYPE_RGB24: 00292 for (row = 0; row < height; row++) { 00293 pixel_ptr = row * width * 3; 00294 yq = encoded[pixel_ptr++]; 00295 uqvq = AV_RL16(encoded+pixel_ptr); 00296 pixel_ptr += 2; 00297 for (col = 1; col < width; col++) { 00298 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; 00299 uqvq -= AV_RL16(encoded+pixel_ptr+1); 00300 AV_WL16(encoded+pixel_ptr+1, uqvq); 00301 pixel_ptr += 3; 00302 } 00303 } 00304 break; 00305 case IMGTYPE_YUV422: 00306 for (row = 0; row < height; row++) { 00307 pixel_ptr = row * width * 2; 00308 yq = uq = vq =0; 00309 for (col = 0; col < width/4; col++) { 00310 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; 00311 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; 00312 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; 00313 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; 00314 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; 00315 encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; 00316 encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; 00317 encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; 00318 pixel_ptr += 8; 00319 } 00320 } 00321 break; 00322 case IMGTYPE_YUV411: 00323 for (row = 0; row < height; row++) { 00324 pixel_ptr = row * width / 2 * 3; 00325 yq = uq = vq =0; 00326 for (col = 0; col < width/4; col++) { 00327 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; 00328 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; 00329 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; 00330 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; 00331 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; 00332 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; 00333 pixel_ptr += 6; 00334 } 00335 } 00336 break; 00337 case IMGTYPE_YUV211: 00338 for (row = 0; row < height; row++) { 00339 pixel_ptr = row * width * 2; 00340 yq = uq = vq =0; 00341 for (col = 0; col < width/2; col++) { 00342 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; 00343 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; 00344 encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; 00345 encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; 00346 pixel_ptr += 4; 00347 } 00348 } 00349 break; 00350 case IMGTYPE_YUV420: 00351 for (row = 0; row < height/2; row++) { 00352 pixel_ptr = row * width * 3; 00353 yq = y1q = uq = vq =0; 00354 for (col = 0; col < width/2; col++) { 00355 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; 00356 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; 00357 encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; 00358 encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; 00359 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; 00360 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; 00361 pixel_ptr += 6; 00362 } 00363 } 00364 break; 00365 default: 00366 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); 00367 return -1; 00368 } 00369 } 00370 00371 /* Convert colorspace */ 00372 y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; 00373 u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; 00374 v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; 00375 switch (c->imgtype) { 00376 case IMGTYPE_YUV111: 00377 for (row = 0; row < height; row++) { 00378 for (col = 0; col < width; col++) { 00379 y_out[col] = *encoded++; 00380 u_out[col] = *encoded++ + 128; 00381 v_out[col] = *encoded++ + 128; 00382 } 00383 y_out -= c->pic.linesize[0]; 00384 u_out -= c->pic.linesize[1]; 00385 v_out -= c->pic.linesize[2]; 00386 } 00387 break; 00388 case IMGTYPE_YUV422: 00389 for (row = 0; row < height; row++) { 00390 for (col = 0; col < width - 3; col += 4) { 00391 memcpy(y_out + col, encoded, 4); 00392 encoded += 4; 00393 u_out[ col >> 1 ] = *encoded++ + 128; 00394 u_out[(col >> 1) + 1] = *encoded++ + 128; 00395 v_out[ col >> 1 ] = *encoded++ + 128; 00396 v_out[(col >> 1) + 1] = *encoded++ + 128; 00397 } 00398 y_out -= c->pic.linesize[0]; 00399 u_out -= c->pic.linesize[1]; 00400 v_out -= c->pic.linesize[2]; 00401 } 00402 break; 00403 case IMGTYPE_RGB24: 00404 for (row = height - 1; row >= 0; row--) { 00405 pixel_ptr = row * c->pic.linesize[0]; 00406 memcpy(outptr + pixel_ptr, encoded, 3 * width); 00407 encoded += 3 * width; 00408 } 00409 break; 00410 case IMGTYPE_YUV411: 00411 for (row = 0; row < height; row++) { 00412 for (col = 0; col < width - 3; col += 4) { 00413 memcpy(y_out + col, encoded, 4); 00414 encoded += 4; 00415 u_out[col >> 2] = *encoded++ + 128; 00416 v_out[col >> 2] = *encoded++ + 128; 00417 } 00418 y_out -= c->pic.linesize[0]; 00419 u_out -= c->pic.linesize[1]; 00420 v_out -= c->pic.linesize[2]; 00421 } 00422 break; 00423 case IMGTYPE_YUV211: 00424 for (row = 0; row < height; row++) { 00425 for (col = 0; col < width - 1; col += 2) { 00426 memcpy(y_out + col, encoded, 2); 00427 encoded += 2; 00428 u_out[col >> 1] = *encoded++ + 128; 00429 v_out[col >> 1] = *encoded++ + 128; 00430 } 00431 y_out -= c->pic.linesize[0]; 00432 u_out -= c->pic.linesize[1]; 00433 v_out -= c->pic.linesize[2]; 00434 } 00435 break; 00436 case IMGTYPE_YUV420: 00437 u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; 00438 v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; 00439 for (row = 0; row < height - 1; row += 2) { 00440 for (col = 0; col < width - 1; col += 2) { 00441 memcpy(y_out + col, encoded, 2); 00442 encoded += 2; 00443 memcpy(y_out + col - c->pic.linesize[0], encoded, 2); 00444 encoded += 2; 00445 u_out[col >> 1] = *encoded++ + 128; 00446 v_out[col >> 1] = *encoded++ + 128; 00447 } 00448 y_out -= c->pic.linesize[0] << 1; 00449 u_out -= c->pic.linesize[1]; 00450 v_out -= c->pic.linesize[2]; 00451 } 00452 break; 00453 default: 00454 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); 00455 return -1; 00456 } 00457 00458 *data_size = sizeof(AVFrame); 00459 *(AVFrame*)data = c->pic; 00460 00461 /* always report that the buffer was completely consumed */ 00462 return buf_size; 00463 } 00464 00465 /* 00466 * 00467 * Init lcl decoder 00468 * 00469 */ 00470 static av_cold int decode_init(AVCodecContext *avctx) 00471 { 00472 LclDecContext * const c = avctx->priv_data; 00473 unsigned int basesize = avctx->width * avctx->height; 00474 unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; 00475 unsigned int max_decomp_size; 00476 00477 if (avctx->extradata_size < 8) { 00478 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); 00479 return AVERROR_INVALIDDATA; 00480 } 00481 00482 /* Check codec type */ 00483 if ((avctx->codec_id == CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) || 00484 (avctx->codec_id == CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) { 00485 av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); 00486 } 00487 00488 /* Detect image type */ 00489 switch (c->imgtype = avctx->extradata[4]) { 00490 case IMGTYPE_YUV111: 00491 c->decomp_size = basesize * 3; 00492 max_decomp_size = max_basesize * 3; 00493 avctx->pix_fmt = PIX_FMT_YUV444P; 00494 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n"); 00495 break; 00496 case IMGTYPE_YUV422: 00497 c->decomp_size = basesize * 2; 00498 max_decomp_size = max_basesize * 2; 00499 avctx->pix_fmt = PIX_FMT_YUV422P; 00500 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); 00501 break; 00502 case IMGTYPE_RGB24: 00503 c->decomp_size = basesize * 3; 00504 max_decomp_size = max_basesize * 3; 00505 avctx->pix_fmt = PIX_FMT_BGR24; 00506 av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n"); 00507 break; 00508 case IMGTYPE_YUV411: 00509 c->decomp_size = basesize / 2 * 3; 00510 max_decomp_size = max_basesize / 2 * 3; 00511 avctx->pix_fmt = PIX_FMT_YUV411P; 00512 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n"); 00513 break; 00514 case IMGTYPE_YUV211: 00515 c->decomp_size = basesize * 2; 00516 max_decomp_size = max_basesize * 2; 00517 avctx->pix_fmt = PIX_FMT_YUV422P; 00518 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n"); 00519 break; 00520 case IMGTYPE_YUV420: 00521 c->decomp_size = basesize / 2 * 3; 00522 max_decomp_size = max_basesize / 2 * 3; 00523 avctx->pix_fmt = PIX_FMT_YUV420P; 00524 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n"); 00525 break; 00526 default: 00527 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); 00528 return AVERROR_INVALIDDATA; 00529 } 00530 00531 /* Detect compression method */ 00532 c->compression = (int8_t)avctx->extradata[5]; 00533 switch (avctx->codec_id) { 00534 case CODEC_ID_MSZH: 00535 switch (c->compression) { 00536 case COMP_MSZH: 00537 av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n"); 00538 break; 00539 case COMP_MSZH_NOCOMP: 00540 c->decomp_size = 0; 00541 av_log(avctx, AV_LOG_DEBUG, "No compression.\n"); 00542 break; 00543 default: 00544 av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); 00545 return AVERROR_INVALIDDATA; 00546 } 00547 break; 00548 #if CONFIG_ZLIB_DECODER 00549 case CODEC_ID_ZLIB: 00550 switch (c->compression) { 00551 case COMP_ZLIB_HISPEED: 00552 av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n"); 00553 break; 00554 case COMP_ZLIB_HICOMP: 00555 av_log(avctx, AV_LOG_DEBUG, "High compression.\n"); 00556 break; 00557 case COMP_ZLIB_NORMAL: 00558 av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n"); 00559 break; 00560 default: 00561 if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) { 00562 av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); 00563 return AVERROR_INVALIDDATA; 00564 } 00565 av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); 00566 } 00567 break; 00568 #endif 00569 default: 00570 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); 00571 return AVERROR_INVALIDDATA; 00572 } 00573 00574 /* Allocate decompression buffer */ 00575 if (c->decomp_size) { 00576 if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { 00577 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); 00578 return AVERROR(ENOMEM); 00579 } 00580 } 00581 00582 /* Detect flags */ 00583 c->flags = avctx->extradata[6]; 00584 if (c->flags & FLAG_MULTITHREAD) 00585 av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n"); 00586 if (c->flags & FLAG_NULLFRAME) 00587 av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n"); 00588 if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) 00589 av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n"); 00590 if (c->flags & FLAGMASK_UNUSED) 00591 av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); 00592 00593 /* If needed init zlib */ 00594 #if CONFIG_ZLIB_DECODER 00595 if (avctx->codec_id == CODEC_ID_ZLIB) { 00596 int zret; 00597 c->zstream.zalloc = Z_NULL; 00598 c->zstream.zfree = Z_NULL; 00599 c->zstream.opaque = Z_NULL; 00600 zret = inflateInit(&c->zstream); 00601 if (zret != Z_OK) { 00602 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); 00603 av_freep(&c->decomp_buf); 00604 return AVERROR_INVALIDDATA; 00605 } 00606 } 00607 #endif 00608 00609 return 0; 00610 } 00611 00612 /* 00613 * 00614 * Uninit lcl decoder 00615 * 00616 */ 00617 static av_cold int decode_end(AVCodecContext *avctx) 00618 { 00619 LclDecContext * const c = avctx->priv_data; 00620 00621 av_freep(&c->decomp_buf); 00622 if (c->pic.data[0]) 00623 avctx->release_buffer(avctx, &c->pic); 00624 #if CONFIG_ZLIB_DECODER 00625 if (avctx->codec_id == CODEC_ID_ZLIB) 00626 inflateEnd(&c->zstream); 00627 #endif 00628 00629 return 0; 00630 } 00631 00632 #if CONFIG_MSZH_DECODER 00633 AVCodec ff_mszh_decoder = { 00634 "mszh", 00635 AVMEDIA_TYPE_VIDEO, 00636 CODEC_ID_MSZH, 00637 sizeof(LclDecContext), 00638 decode_init, 00639 NULL, 00640 decode_end, 00641 decode_frame, 00642 CODEC_CAP_DR1, 00643 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), 00644 }; 00645 #endif 00646 00647 #if CONFIG_ZLIB_DECODER 00648 AVCodec ff_zlib_decoder = { 00649 "zlib", 00650 AVMEDIA_TYPE_VIDEO, 00651 CODEC_ID_ZLIB, 00652 sizeof(LclDecContext), 00653 decode_init, 00654 NULL, 00655 decode_end, 00656 decode_frame, 00657 CODEC_CAP_DR1, 00658 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), 00659 }; 00660 #endif