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