ffmpeg / libavcodec / lcl.c @ 5509bffa
History | View | Annotate | Download (31.2 KB)
1 |
/*
|
---|---|
2 |
* LCL (LossLess Codec Library) Codec
|
3 |
* Copyright (c) 2002-2004 Roberto Togni
|
4 |
*
|
5 |
* This library is free software; you can redistribute it and/or
|
6 |
* modify it under the terms of the GNU Lesser General Public
|
7 |
* License as published by the Free Software Foundation; either
|
8 |
* version 2 of the License, or (at your option) any later version.
|
9 |
*
|
10 |
* This library is distributed in the hope that it will be useful,
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13 |
* Lesser General Public License for more details.
|
14 |
*
|
15 |
* You should have received a copy of the GNU Lesser General Public
|
16 |
* License along with this library; if not, write to the Free Software
|
17 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18 |
*
|
19 |
*/
|
20 |
|
21 |
/**
|
22 |
* @file lcl.c
|
23 |
* LCL (LossLess Codec Library) Video Codec
|
24 |
* Decoder for MSZH and ZLIB codecs
|
25 |
* Experimental encoder for ZLIB RGB24
|
26 |
*
|
27 |
* Fourcc: MSZH, ZLIB
|
28 |
*
|
29 |
* Original Win32 dll:
|
30 |
* Ver2.23 By Kenji Oshima 2000.09.20
|
31 |
* avimszh.dll, avizlib.dll
|
32 |
*
|
33 |
* A description of the decoding algorithm can be found here:
|
34 |
* http://www.pcisys.net/~melanson/codecs
|
35 |
*
|
36 |
* Supports: BGR24 (RGB 24bpp)
|
37 |
*
|
38 |
*/
|
39 |
|
40 |
#include <stdio.h> |
41 |
#include <stdlib.h> |
42 |
|
43 |
#include "common.h" |
44 |
#include "bitstream.h" |
45 |
#include "avcodec.h" |
46 |
|
47 |
#ifdef CONFIG_ZLIB
|
48 |
#include <zlib.h> |
49 |
#endif
|
50 |
|
51 |
|
52 |
#define BMPTYPE_YUV 1 |
53 |
#define BMPTYPE_RGB 2 |
54 |
|
55 |
#define IMGTYPE_YUV111 0 |
56 |
#define IMGTYPE_YUV422 1 |
57 |
#define IMGTYPE_RGB24 2 |
58 |
#define IMGTYPE_YUV411 3 |
59 |
#define IMGTYPE_YUV211 4 |
60 |
#define IMGTYPE_YUV420 5 |
61 |
|
62 |
#define COMP_MSZH 0 |
63 |
#define COMP_MSZH_NOCOMP 1 |
64 |
#define COMP_ZLIB_HISPEED 1 |
65 |
#define COMP_ZLIB_HICOMP 9 |
66 |
#define COMP_ZLIB_NORMAL -1 |
67 |
|
68 |
#define FLAG_MULTITHREAD 1 |
69 |
#define FLAG_NULLFRAME 2 |
70 |
#define FLAG_PNGFILTER 4 |
71 |
#define FLAGMASK_UNUSED 0xf8 |
72 |
|
73 |
#define CODEC_MSZH 1 |
74 |
#define CODEC_ZLIB 3 |
75 |
|
76 |
#define FOURCC_MSZH mmioFOURCC('M','S','Z','H') |
77 |
#define FOURCC_ZLIB mmioFOURCC('Z','L','I','B') |
78 |
|
79 |
/*
|
80 |
* Decoder context
|
81 |
*/
|
82 |
typedef struct LclContext { |
83 |
|
84 |
AVCodecContext *avctx; |
85 |
AVFrame pic; |
86 |
PutBitContext pb; |
87 |
|
88 |
// Image type
|
89 |
int imgtype;
|
90 |
// Compression type
|
91 |
int compression;
|
92 |
// Flags
|
93 |
int flags;
|
94 |
// Decompressed data size
|
95 |
unsigned int decomp_size; |
96 |
// Decompression buffer
|
97 |
unsigned char* decomp_buf; |
98 |
// Maximum compressed data size
|
99 |
unsigned int max_comp_size; |
100 |
// Compression buffer
|
101 |
unsigned char* comp_buf; |
102 |
#ifdef CONFIG_ZLIB
|
103 |
z_stream zstream; |
104 |
#endif
|
105 |
} LclContext; |
106 |
|
107 |
|
108 |
/*
|
109 |
*
|
110 |
* Helper functions
|
111 |
*
|
112 |
*/
|
113 |
static inline unsigned char fix (int pix14) |
114 |
{ |
115 |
int tmp;
|
116 |
|
117 |
tmp = (pix14 + 0x80000) >> 20; |
118 |
if (tmp < 0) |
119 |
return 0; |
120 |
if (tmp > 255) |
121 |
return 255; |
122 |
return tmp;
|
123 |
} |
124 |
|
125 |
|
126 |
|
127 |
static inline unsigned char get_b (unsigned char yq, signed char bq) |
128 |
{ |
129 |
return fix((yq << 20) + bq * 1858076); |
130 |
} |
131 |
|
132 |
|
133 |
|
134 |
static inline unsigned char get_g (unsigned char yq, signed char bq, signed char rq) |
135 |
{ |
136 |
return fix((yq << 20) - bq * 360857 - rq * 748830); |
137 |
} |
138 |
|
139 |
|
140 |
|
141 |
static inline unsigned char get_r (unsigned char yq, signed char rq) |
142 |
{ |
143 |
return fix((yq << 20) + rq * 1470103); |
144 |
} |
145 |
|
146 |
|
147 |
|
148 |
static unsigned int mszh_decomp(unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
149 |
{ |
150 |
unsigned char *destptr_bak = destptr; |
151 |
unsigned char *destptr_end = destptr + destsize; |
152 |
unsigned char mask = 0; |
153 |
unsigned char maskbit = 0; |
154 |
unsigned int ofs, cnt; |
155 |
|
156 |
while ((srclen > 0) && (destptr < destptr_end)) { |
157 |
if (maskbit == 0) { |
158 |
mask = *(srcptr++); |
159 |
maskbit = 8;
|
160 |
srclen--; |
161 |
continue;
|
162 |
} |
163 |
if ((mask & (1 << (--maskbit))) == 0) { |
164 |
if (destptr + 4 > destptr_end) |
165 |
break;
|
166 |
*(int*)destptr = *(int*)srcptr; |
167 |
srclen -= 4;
|
168 |
destptr += 4;
|
169 |
srcptr += 4;
|
170 |
} else {
|
171 |
ofs = *(srcptr++); |
172 |
cnt = *(srcptr++); |
173 |
ofs += cnt * 256;;
|
174 |
cnt = ((cnt >> 3) & 0x1f) + 1; |
175 |
ofs &= 0x7ff;
|
176 |
srclen -= 2;
|
177 |
cnt *= 4;
|
178 |
if (destptr + cnt > destptr_end) {
|
179 |
cnt = destptr_end - destptr; |
180 |
} |
181 |
for (; cnt > 0; cnt--) { |
182 |
*(destptr) = *(destptr - ofs); |
183 |
destptr++; |
184 |
} |
185 |
} |
186 |
} |
187 |
|
188 |
return (destptr - destptr_bak);
|
189 |
} |
190 |
|
191 |
|
192 |
|
193 |
|
194 |
/*
|
195 |
*
|
196 |
* Decode a frame
|
197 |
*
|
198 |
*/
|
199 |
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size) |
200 |
{ |
201 |
LclContext * const c = (LclContext *)avctx->priv_data;
|
202 |
unsigned char *encoded = (unsigned char *)buf; |
203 |
unsigned int pixel_ptr; |
204 |
int row, col;
|
205 |
unsigned char *outptr; |
206 |
unsigned int width = avctx->width; // Real image width |
207 |
unsigned int height = avctx->height; // Real image height |
208 |
unsigned int mszh_dlen; |
209 |
unsigned char yq, y1q, uq, vq; |
210 |
int uqvq;
|
211 |
unsigned int mthread_inlen, mthread_outlen; |
212 |
#ifdef CONFIG_ZLIB
|
213 |
int zret; // Zlib return code |
214 |
#endif
|
215 |
unsigned int len = buf_size; |
216 |
|
217 |
if(c->pic.data[0]) |
218 |
avctx->release_buffer(avctx, &c->pic); |
219 |
|
220 |
c->pic.reference = 0;
|
221 |
c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; |
222 |
if(avctx->get_buffer(avctx, &c->pic) < 0){ |
223 |
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
|
224 |
return -1; |
225 |
} |
226 |
|
227 |
outptr = c->pic.data[0]; // Output image pointer |
228 |
|
229 |
/* Decompress frame */
|
230 |
switch (avctx->codec_id) {
|
231 |
case CODEC_ID_MSZH:
|
232 |
switch (c->compression) {
|
233 |
case COMP_MSZH:
|
234 |
if (c->flags & FLAG_MULTITHREAD) {
|
235 |
mthread_inlen = *((unsigned int*)encoded); |
236 |
mthread_outlen = *((unsigned int*)(encoded+4)); |
237 |
if (mthread_outlen > c->decomp_size) // this should not happen |
238 |
mthread_outlen = c->decomp_size; |
239 |
mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size);
|
240 |
if (mthread_outlen != mszh_dlen) {
|
241 |
av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n",
|
242 |
mthread_outlen, mszh_dlen); |
243 |
return -1; |
244 |
} |
245 |
mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - mthread_inlen,
|
246 |
c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); |
247 |
if (mthread_outlen != mszh_dlen) {
|
248 |
av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n",
|
249 |
mthread_outlen, mszh_dlen); |
250 |
return -1; |
251 |
} |
252 |
encoded = c->decomp_buf; |
253 |
len = c->decomp_size; |
254 |
} else {
|
255 |
mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); |
256 |
if (c->decomp_size != mszh_dlen) {
|
257 |
av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n",
|
258 |
c->decomp_size, mszh_dlen); |
259 |
return -1; |
260 |
} |
261 |
encoded = c->decomp_buf; |
262 |
len = mszh_dlen; |
263 |
} |
264 |
break;
|
265 |
case COMP_MSZH_NOCOMP:
|
266 |
break;
|
267 |
default:
|
268 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n");
|
269 |
return -1; |
270 |
} |
271 |
break;
|
272 |
case CODEC_ID_ZLIB:
|
273 |
#ifdef CONFIG_ZLIB
|
274 |
/* Using the original dll with normal compression (-1) and RGB format
|
275 |
* gives a file with ZLIB fourcc, but frame is really uncompressed.
|
276 |
* To be sure that's true check also frame size */
|
277 |
if ((c->compression == COMP_ZLIB_NORMAL) && (c->imgtype == IMGTYPE_RGB24) &&
|
278 |
(len == width * height * 3))
|
279 |
break;
|
280 |
zret = inflateReset(&(c->zstream)); |
281 |
if (zret != Z_OK) {
|
282 |
av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret);
|
283 |
return -1; |
284 |
} |
285 |
if (c->flags & FLAG_MULTITHREAD) {
|
286 |
mthread_inlen = *((unsigned int*)encoded); |
287 |
mthread_outlen = *((unsigned int*)(encoded+4)); |
288 |
if (mthread_outlen > c->decomp_size)
|
289 |
mthread_outlen = c->decomp_size; |
290 |
c->zstream.next_in = encoded + 8;
|
291 |
c->zstream.avail_in = mthread_inlen; |
292 |
c->zstream.next_out = c->decomp_buf; |
293 |
c->zstream.avail_out = c->decomp_size; |
294 |
zret = inflate(&(c->zstream), Z_FINISH); |
295 |
if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
|
296 |
av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret);
|
297 |
return -1; |
298 |
} |
299 |
if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { |
300 |
av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n",
|
301 |
mthread_outlen, c->zstream.total_out); |
302 |
return -1; |
303 |
} |
304 |
zret = inflateReset(&(c->zstream)); |
305 |
if (zret != Z_OK) {
|
306 |
av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret);
|
307 |
return -1; |
308 |
} |
309 |
c->zstream.next_in = encoded + 8 + mthread_inlen;
|
310 |
c->zstream.avail_in = len - mthread_inlen; |
311 |
c->zstream.next_out = c->decomp_buf + mthread_outlen; |
312 |
c->zstream.avail_out = c->decomp_size - mthread_outlen; |
313 |
zret = inflate(&(c->zstream), Z_FINISH); |
314 |
if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
|
315 |
av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret);
|
316 |
return -1; |
317 |
} |
318 |
if (mthread_outlen != (unsigned int)(c->zstream.total_out)) { |
319 |
av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n",
|
320 |
mthread_outlen, c->zstream.total_out); |
321 |
return -1; |
322 |
} |
323 |
} else {
|
324 |
c->zstream.next_in = encoded; |
325 |
c->zstream.avail_in = len; |
326 |
c->zstream.next_out = c->decomp_buf; |
327 |
c->zstream.avail_out = c->decomp_size; |
328 |
zret = inflate(&(c->zstream), Z_FINISH); |
329 |
if ((zret != Z_OK) && (zret != Z_STREAM_END)) {
|
330 |
av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret);
|
331 |
return -1; |
332 |
} |
333 |
if (c->decomp_size != (unsigned int)(c->zstream.total_out)) { |
334 |
av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n",
|
335 |
c->decomp_size, c->zstream.total_out); |
336 |
return -1; |
337 |
} |
338 |
} |
339 |
encoded = c->decomp_buf; |
340 |
len = c->decomp_size;; |
341 |
#else
|
342 |
av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n");
|
343 |
return -1; |
344 |
#endif
|
345 |
break;
|
346 |
default:
|
347 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n");
|
348 |
return -1; |
349 |
} |
350 |
|
351 |
|
352 |
/* Apply PNG filter */
|
353 |
if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) {
|
354 |
switch (c->imgtype) {
|
355 |
case IMGTYPE_YUV111:
|
356 |
case IMGTYPE_RGB24:
|
357 |
for (row = 0; row < height; row++) { |
358 |
pixel_ptr = row * width * 3;
|
359 |
yq = encoded[pixel_ptr++]; |
360 |
uqvq = encoded[pixel_ptr++]; |
361 |
uqvq+=(encoded[pixel_ptr++] << 8);
|
362 |
for (col = 1; col < width; col++) { |
363 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
364 |
uqvq -= (encoded[pixel_ptr+1] | (encoded[pixel_ptr+2]<<8)); |
365 |
encoded[pixel_ptr+1] = (uqvq) & 0xff; |
366 |
encoded[pixel_ptr+2] = ((uqvq)>>8) & 0xff; |
367 |
pixel_ptr += 3;
|
368 |
} |
369 |
} |
370 |
break;
|
371 |
case IMGTYPE_YUV422:
|
372 |
for (row = 0; row < height; row++) { |
373 |
pixel_ptr = row * width * 2;
|
374 |
yq = uq = vq =0;
|
375 |
for (col = 0; col < width/4; col++) { |
376 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
377 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
378 |
encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; |
379 |
encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; |
380 |
encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; |
381 |
encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; |
382 |
encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; |
383 |
encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; |
384 |
pixel_ptr += 8;
|
385 |
} |
386 |
} |
387 |
break;
|
388 |
case IMGTYPE_YUV411:
|
389 |
for (row = 0; row < height; row++) { |
390 |
pixel_ptr = row * width / 2 * 3; |
391 |
yq = uq = vq =0;
|
392 |
for (col = 0; col < width/4; col++) { |
393 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
394 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
395 |
encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; |
396 |
encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; |
397 |
encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; |
398 |
encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; |
399 |
pixel_ptr += 6;
|
400 |
} |
401 |
} |
402 |
break;
|
403 |
case IMGTYPE_YUV211:
|
404 |
for (row = 0; row < height; row++) { |
405 |
pixel_ptr = row * width * 2;
|
406 |
yq = uq = vq =0;
|
407 |
for (col = 0; col < width/2; col++) { |
408 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
409 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
410 |
encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; |
411 |
encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; |
412 |
pixel_ptr += 4;
|
413 |
} |
414 |
} |
415 |
break;
|
416 |
case IMGTYPE_YUV420:
|
417 |
for (row = 0; row < height/2; row++) { |
418 |
pixel_ptr = row * width * 3;
|
419 |
yq = y1q = uq = vq =0;
|
420 |
for (col = 0; col < width/2; col++) { |
421 |
encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; |
422 |
encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; |
423 |
encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; |
424 |
encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; |
425 |
encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; |
426 |
encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; |
427 |
pixel_ptr += 6;
|
428 |
} |
429 |
} |
430 |
break;
|
431 |
default:
|
432 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n");
|
433 |
return -1; |
434 |
} |
435 |
} |
436 |
|
437 |
/* Convert colorspace */
|
438 |
switch (c->imgtype) {
|
439 |
case IMGTYPE_YUV111:
|
440 |
for (row = height - 1; row >= 0; row--) { |
441 |
pixel_ptr = row * c->pic.linesize[0];
|
442 |
for (col = 0; col < width; col++) { |
443 |
outptr[pixel_ptr++] = get_b(encoded[0], encoded[1]); |
444 |
outptr[pixel_ptr++] = get_g(encoded[0], encoded[1], encoded[2]); |
445 |
outptr[pixel_ptr++] = get_r(encoded[0], encoded[2]); |
446 |
encoded += 3;
|
447 |
} |
448 |
} |
449 |
break;
|
450 |
case IMGTYPE_YUV422:
|
451 |
for (row = height - 1; row >= 0; row--) { |
452 |
pixel_ptr = row * c->pic.linesize[0];
|
453 |
for (col = 0; col < width/4; col++) { |
454 |
outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); |
455 |
outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[6]); |
456 |
outptr[pixel_ptr++] = get_r(encoded[0], encoded[6]); |
457 |
outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); |
458 |
outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[6]); |
459 |
outptr[pixel_ptr++] = get_r(encoded[1], encoded[6]); |
460 |
outptr[pixel_ptr++] = get_b(encoded[2], encoded[5]); |
461 |
outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); |
462 |
outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); |
463 |
outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); |
464 |
outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); |
465 |
outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); |
466 |
encoded += 8;
|
467 |
} |
468 |
} |
469 |
break;
|
470 |
case IMGTYPE_RGB24:
|
471 |
for (row = height - 1; row >= 0; row--) { |
472 |
pixel_ptr = row * c->pic.linesize[0];
|
473 |
for (col = 0; col < width; col++) { |
474 |
outptr[pixel_ptr++] = encoded[0];
|
475 |
outptr[pixel_ptr++] = encoded[1];
|
476 |
outptr[pixel_ptr++] = encoded[2];
|
477 |
encoded += 3;
|
478 |
} |
479 |
} |
480 |
break;
|
481 |
case IMGTYPE_YUV411:
|
482 |
for (row = height - 1; row >= 0; row--) { |
483 |
pixel_ptr = row * c->pic.linesize[0];
|
484 |
for (col = 0; col < width/4; col++) { |
485 |
outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); |
486 |
outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); |
487 |
outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); |
488 |
outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); |
489 |
outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); |
490 |
outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); |
491 |
outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); |
492 |
outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); |
493 |
outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); |
494 |
outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); |
495 |
outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); |
496 |
outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); |
497 |
encoded += 6;
|
498 |
} |
499 |
} |
500 |
break;
|
501 |
case IMGTYPE_YUV211:
|
502 |
for (row = height - 1; row >= 0; row--) { |
503 |
pixel_ptr = row * c->pic.linesize[0];
|
504 |
for (col = 0; col < width/2; col++) { |
505 |
outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); |
506 |
outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); |
507 |
outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); |
508 |
outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); |
509 |
outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); |
510 |
outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); |
511 |
encoded += 4;
|
512 |
} |
513 |
} |
514 |
break;
|
515 |
case IMGTYPE_YUV420:
|
516 |
for (row = height / 2 - 1; row >= 0; row--) { |
517 |
pixel_ptr = 2 * row * c->pic.linesize[0]; |
518 |
for (col = 0; col < width/2; col++) { |
519 |
outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); |
520 |
outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); |
521 |
outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); |
522 |
outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); |
523 |
outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); |
524 |
outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); |
525 |
outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); |
526 |
outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); |
527 |
outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); |
528 |
outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); |
529 |
outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); |
530 |
outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); |
531 |
pixel_ptr += 6;
|
532 |
encoded += 6;
|
533 |
} |
534 |
} |
535 |
break;
|
536 |
default:
|
537 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n");
|
538 |
return -1; |
539 |
} |
540 |
|
541 |
*data_size = sizeof(AVFrame);
|
542 |
*(AVFrame*)data = c->pic; |
543 |
|
544 |
/* always report that the buffer was completely consumed */
|
545 |
return buf_size;
|
546 |
} |
547 |
|
548 |
|
549 |
|
550 |
/*
|
551 |
*
|
552 |
* Encode a frame
|
553 |
*
|
554 |
*/
|
555 |
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ |
556 |
LclContext *c = avctx->priv_data; |
557 |
AVFrame *pict = data; |
558 |
AVFrame * const p = &c->pic;
|
559 |
int i;
|
560 |
int zret; // Zlib return code |
561 |
|
562 |
#ifndef CONFIG_ZLIB
|
563 |
av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n");
|
564 |
return -1; |
565 |
#else
|
566 |
|
567 |
init_put_bits(&c->pb, buf, buf_size); |
568 |
|
569 |
*p = *pict; |
570 |
p->pict_type= FF_I_TYPE; |
571 |
p->key_frame= 1;
|
572 |
|
573 |
if(avctx->pix_fmt != PIX_FMT_BGR24){
|
574 |
av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
|
575 |
return -1; |
576 |
} |
577 |
|
578 |
zret = deflateReset(&(c->zstream)); |
579 |
if (zret != Z_OK) {
|
580 |
av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret);
|
581 |
return -1; |
582 |
} |
583 |
c->zstream.next_out = c->comp_buf; |
584 |
c->zstream.avail_out = c->max_comp_size; |
585 |
|
586 |
for(i = avctx->height - 1; i >= 0; i--) { |
587 |
c->zstream.next_in = p->data[0]+p->linesize[0]*i; |
588 |
c->zstream.avail_in = avctx->width*3;
|
589 |
zret = deflate(&(c->zstream), Z_NO_FLUSH); |
590 |
if (zret != Z_OK) {
|
591 |
av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
|
592 |
return -1; |
593 |
} |
594 |
} |
595 |
zret = deflate(&(c->zstream), Z_FINISH); |
596 |
if (zret != Z_STREAM_END) {
|
597 |
av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
|
598 |
return -1; |
599 |
} |
600 |
|
601 |
for (i = 0; i < c->zstream.total_out; i++) |
602 |
put_bits(&c->pb, 8, c->comp_buf[i]);
|
603 |
flush_put_bits(&c->pb); |
604 |
|
605 |
return c->zstream.total_out;
|
606 |
#endif
|
607 |
} |
608 |
|
609 |
|
610 |
|
611 |
/*
|
612 |
*
|
613 |
* Init lcl decoder
|
614 |
*
|
615 |
*/
|
616 |
static int decode_init(AVCodecContext *avctx) |
617 |
{ |
618 |
LclContext * const c = (LclContext *)avctx->priv_data;
|
619 |
unsigned int basesize = avctx->width * avctx->height; |
620 |
unsigned int max_basesize = ((avctx->width + 3) & ~3) * ((avctx->height + 3) & ~3); |
621 |
unsigned int max_decomp_size; |
622 |
int zret; // Zlib return code |
623 |
|
624 |
c->avctx = avctx; |
625 |
avctx->has_b_frames = 0;
|
626 |
|
627 |
c->pic.data[0] = NULL; |
628 |
|
629 |
#ifdef CONFIG_ZLIB
|
630 |
// Needed if zlib unused or init aborted before inflateInit
|
631 |
memset(&(c->zstream), 0, sizeof(z_stream)); |
632 |
#endif
|
633 |
|
634 |
if (avctx->extradata_size < 8) { |
635 |
av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n");
|
636 |
return 1; |
637 |
} |
638 |
|
639 |
if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
640 |
return 1; |
641 |
} |
642 |
|
643 |
/* Check codec type */
|
644 |
if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || |
645 |
((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { |
646 |
av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n");
|
647 |
} |
648 |
|
649 |
/* Detect image type */
|
650 |
switch (c->imgtype = *((char *)avctx->extradata + 4)) { |
651 |
case IMGTYPE_YUV111:
|
652 |
c->decomp_size = basesize * 3;
|
653 |
max_decomp_size = max_basesize * 3;
|
654 |
av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n");
|
655 |
break;
|
656 |
case IMGTYPE_YUV422:
|
657 |
c->decomp_size = basesize * 2;
|
658 |
max_decomp_size = max_basesize * 2;
|
659 |
av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n");
|
660 |
break;
|
661 |
case IMGTYPE_RGB24:
|
662 |
c->decomp_size = basesize * 3;
|
663 |
max_decomp_size = max_basesize * 3;
|
664 |
av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n");
|
665 |
break;
|
666 |
case IMGTYPE_YUV411:
|
667 |
c->decomp_size = basesize / 2 * 3; |
668 |
max_decomp_size = max_basesize / 2 * 3; |
669 |
av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n");
|
670 |
break;
|
671 |
case IMGTYPE_YUV211:
|
672 |
c->decomp_size = basesize * 2;
|
673 |
max_decomp_size = max_basesize * 2;
|
674 |
av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n");
|
675 |
break;
|
676 |
case IMGTYPE_YUV420:
|
677 |
c->decomp_size = basesize / 2 * 3; |
678 |
max_decomp_size = max_basesize / 2 * 3; |
679 |
av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n");
|
680 |
break;
|
681 |
default:
|
682 |
av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype);
|
683 |
return 1; |
684 |
} |
685 |
|
686 |
/* Detect compression method */
|
687 |
c->compression = *((char *)avctx->extradata + 5); |
688 |
switch (avctx->codec_id) {
|
689 |
case CODEC_ID_MSZH:
|
690 |
switch (c->compression) {
|
691 |
case COMP_MSZH:
|
692 |
av_log(avctx, AV_LOG_INFO, "Compression enabled.\n");
|
693 |
break;
|
694 |
case COMP_MSZH_NOCOMP:
|
695 |
c->decomp_size = 0;
|
696 |
av_log(avctx, AV_LOG_INFO, "No compression.\n");
|
697 |
break;
|
698 |
default:
|
699 |
av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression);
|
700 |
return 1; |
701 |
} |
702 |
break;
|
703 |
case CODEC_ID_ZLIB:
|
704 |
#ifdef CONFIG_ZLIB
|
705 |
switch (c->compression) {
|
706 |
case COMP_ZLIB_HISPEED:
|
707 |
av_log(avctx, AV_LOG_INFO, "High speed compression.\n");
|
708 |
break;
|
709 |
case COMP_ZLIB_HICOMP:
|
710 |
av_log(avctx, AV_LOG_INFO, "High compression.\n");
|
711 |
break;
|
712 |
case COMP_ZLIB_NORMAL:
|
713 |
av_log(avctx, AV_LOG_INFO, "Normal compression.\n");
|
714 |
break;
|
715 |
default:
|
716 |
if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) {
|
717 |
av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression);
|
718 |
return 1; |
719 |
} |
720 |
av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression);
|
721 |
} |
722 |
#else
|
723 |
av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
|
724 |
return 1; |
725 |
#endif
|
726 |
break;
|
727 |
default:
|
728 |
av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n");
|
729 |
return 1; |
730 |
} |
731 |
|
732 |
/* Allocate decompression buffer */
|
733 |
if (c->decomp_size) {
|
734 |
if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { |
735 |
av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");
|
736 |
return 1; |
737 |
} |
738 |
} |
739 |
|
740 |
/* Detect flags */
|
741 |
c->flags = *((char *)avctx->extradata + 6); |
742 |
if (c->flags & FLAG_MULTITHREAD)
|
743 |
av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n");
|
744 |
if (c->flags & FLAG_NULLFRAME)
|
745 |
av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n");
|
746 |
if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER))
|
747 |
av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n");
|
748 |
if (c->flags & FLAGMASK_UNUSED)
|
749 |
av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags);
|
750 |
|
751 |
/* If needed init zlib */
|
752 |
if (avctx->codec_id == CODEC_ID_ZLIB) {
|
753 |
#ifdef CONFIG_ZLIB
|
754 |
c->zstream.zalloc = Z_NULL; |
755 |
c->zstream.zfree = Z_NULL; |
756 |
c->zstream.opaque = Z_NULL; |
757 |
zret = inflateInit(&(c->zstream)); |
758 |
if (zret != Z_OK) {
|
759 |
av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
|
760 |
return 1; |
761 |
} |
762 |
#else
|
763 |
av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
|
764 |
return 1; |
765 |
#endif
|
766 |
} |
767 |
|
768 |
avctx->pix_fmt = PIX_FMT_BGR24; |
769 |
|
770 |
return 0; |
771 |
} |
772 |
|
773 |
|
774 |
|
775 |
/*
|
776 |
*
|
777 |
* Init lcl encoder
|
778 |
*
|
779 |
*/
|
780 |
static int encode_init(AVCodecContext *avctx) |
781 |
{ |
782 |
LclContext *c = avctx->priv_data; |
783 |
int zret; // Zlib return code |
784 |
|
785 |
#ifndef CONFIG_ZLIB
|
786 |
av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n");
|
787 |
return 1; |
788 |
#else
|
789 |
|
790 |
c->avctx= avctx; |
791 |
|
792 |
assert(avctx->width && avctx->height); |
793 |
|
794 |
avctx->extradata= av_mallocz(8);
|
795 |
avctx->coded_frame= &c->pic; |
796 |
|
797 |
// Will be user settable someday
|
798 |
c->compression = 6;
|
799 |
c->flags = 0;
|
800 |
|
801 |
switch(avctx->pix_fmt){
|
802 |
case PIX_FMT_BGR24:
|
803 |
c->imgtype = IMGTYPE_RGB24; |
804 |
c->decomp_size = avctx->width * avctx->height * 3;
|
805 |
avctx->bits_per_sample= 24;
|
806 |
break;
|
807 |
default:
|
808 |
av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt);
|
809 |
return -1; |
810 |
} |
811 |
|
812 |
((uint8_t*)avctx->extradata)[0]= 4; |
813 |
((uint8_t*)avctx->extradata)[1]= 0; |
814 |
((uint8_t*)avctx->extradata)[2]= 0; |
815 |
((uint8_t*)avctx->extradata)[3]= 0; |
816 |
((uint8_t*)avctx->extradata)[4]= c->imgtype;
|
817 |
((uint8_t*)avctx->extradata)[5]= c->compression;
|
818 |
((uint8_t*)avctx->extradata)[6]= c->flags;
|
819 |
((uint8_t*)avctx->extradata)[7]= CODEC_ZLIB;
|
820 |
c->avctx->extradata_size= 8;
|
821 |
|
822 |
c->zstream.zalloc = Z_NULL; |
823 |
c->zstream.zfree = Z_NULL; |
824 |
c->zstream.opaque = Z_NULL; |
825 |
zret = deflateInit(&(c->zstream), c->compression); |
826 |
if (zret != Z_OK) {
|
827 |
av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret);
|
828 |
return 1; |
829 |
} |
830 |
|
831 |
/* Conservative upper bound taken from zlib v1.2.1 source */
|
832 |
c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + |
833 |
((c->decomp_size + 63) >> 6) + 11; |
834 |
if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { |
835 |
av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n");
|
836 |
return 1; |
837 |
} |
838 |
|
839 |
return 0; |
840 |
#endif
|
841 |
} |
842 |
|
843 |
|
844 |
|
845 |
|
846 |
|
847 |
/*
|
848 |
*
|
849 |
* Uninit lcl decoder
|
850 |
*
|
851 |
*/
|
852 |
static int decode_end(AVCodecContext *avctx) |
853 |
{ |
854 |
LclContext * const c = (LclContext *)avctx->priv_data;
|
855 |
|
856 |
if (c->pic.data[0]) |
857 |
avctx->release_buffer(avctx, &c->pic); |
858 |
#ifdef CONFIG_ZLIB
|
859 |
inflateEnd(&(c->zstream)); |
860 |
#endif
|
861 |
|
862 |
return 0; |
863 |
} |
864 |
|
865 |
|
866 |
|
867 |
/*
|
868 |
*
|
869 |
* Uninit lcl encoder
|
870 |
*
|
871 |
*/
|
872 |
static int encode_end(AVCodecContext *avctx) |
873 |
{ |
874 |
LclContext *c = avctx->priv_data; |
875 |
|
876 |
av_freep(&avctx->extradata); |
877 |
av_freep(&c->comp_buf); |
878 |
#ifdef CONFIG_ZLIB
|
879 |
deflateEnd(&(c->zstream)); |
880 |
#endif
|
881 |
|
882 |
return 0; |
883 |
} |
884 |
|
885 |
AVCodec mszh_decoder = { |
886 |
"mszh",
|
887 |
CODEC_TYPE_VIDEO, |
888 |
CODEC_ID_MSZH, |
889 |
sizeof(LclContext),
|
890 |
decode_init, |
891 |
NULL,
|
892 |
decode_end, |
893 |
decode_frame, |
894 |
CODEC_CAP_DR1, |
895 |
}; |
896 |
|
897 |
|
898 |
AVCodec zlib_decoder = { |
899 |
"zlib",
|
900 |
CODEC_TYPE_VIDEO, |
901 |
CODEC_ID_ZLIB, |
902 |
sizeof(LclContext),
|
903 |
decode_init, |
904 |
NULL,
|
905 |
decode_end, |
906 |
decode_frame, |
907 |
CODEC_CAP_DR1, |
908 |
}; |
909 |
|
910 |
#ifdef CONFIG_ENCODERS
|
911 |
|
912 |
AVCodec zlib_encoder = { |
913 |
"zlib",
|
914 |
CODEC_TYPE_VIDEO, |
915 |
CODEC_ID_ZLIB, |
916 |
sizeof(LclContext),
|
917 |
encode_init, |
918 |
encode_frame, |
919 |
encode_end, |
920 |
}; |
921 |
|
922 |
#endif //CONFIG_ENCODERS |