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