| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * LCL (LossLess Codec Library) Codec | 
					
						
							|  |  |  |  * Copyright (c) 2002-2004 Roberto Togni | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This file is part of FFmpeg. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FFmpeg is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License as published by the Free Software Foundation; either | 
					
						
							|  |  |  |  * version 2.1 of the License, or (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * FFmpeg is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
					
						
							|  |  |  |  * Lesser General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Lesser General Public | 
					
						
							|  |  |  |  * License along with FFmpeg; if not, write to the Free Software | 
					
						
							|  |  |  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2010-04-20 14:45:34 +00:00
										 |  |  |  * @file | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |  * LCL (LossLess Codec Library) Video Codec | 
					
						
							|  |  |  |  * Decoder for MSZH and ZLIB codecs | 
					
						
							|  |  |  |  * Experimental encoder for ZLIB RGB24 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Fourcc: MSZH, ZLIB | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Original Win32 dll: | 
					
						
							|  |  |  |  * Ver2.23 By Kenji Oshima 2000.09.20 | 
					
						
							|  |  |  |  * avimszh.dll, avizlib.dll | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * A description of the decoding algorithm can be found here: | 
					
						
							|  |  |  |  *   http://www.pcisys.net/~melanson/codecs
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Supports: BGR24 (RGB 24bpp) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "avcodec.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-31 10:35:39 +00:00
										 |  |  | #include "bytestream.h"
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | #include "lcl.h"
 | 
					
						
							| 
									
										
										
										
											2009-05-31 10:42:26 +00:00
										 |  |  | #include "libavutil/lzo.h"
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:16:06 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | #include <zlib.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Decoder context | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | typedef struct LclDecContext { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     AVFrame pic; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Image type
 | 
					
						
							|  |  |  |     int imgtype; | 
					
						
							|  |  |  |     // Compression type
 | 
					
						
							|  |  |  |     int compression; | 
					
						
							|  |  |  |     // Flags
 | 
					
						
							|  |  |  |     int flags; | 
					
						
							|  |  |  |     // Decompressed data size
 | 
					
						
							|  |  |  |     unsigned int decomp_size; | 
					
						
							|  |  |  |     // Decompression buffer
 | 
					
						
							|  |  |  |     unsigned char* decomp_buf; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:16:06 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     z_stream zstream; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } LclDecContext; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-31 10:28:40 +00:00
										 |  |  | /**
 | 
					
						
							| 
									
										
										
										
											2009-05-31 11:32:03 +00:00
										 |  |  |  * \param srcptr compressed source buffer, must be padded with at least 5 extra bytes | 
					
						
							| 
									
										
										
										
											2009-05-31 10:42:26 +00:00
										 |  |  |  * \param destptr must be padded sufficiently for av_memcpy_backptr | 
					
						
							| 
									
										
										
										
											2009-05-31 10:28:40 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-31 10:38:17 +00:00
										 |  |  | static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned char *destptr_bak = destptr; | 
					
						
							|  |  |  |     unsigned char *destptr_end = destptr + destsize; | 
					
						
							| 
									
										
										
										
											2009-05-31 10:38:17 +00:00
										 |  |  |     const unsigned char *srcptr_end = srcptr + srclen; | 
					
						
							| 
									
										
										
										
											2009-05-31 11:34:19 +00:00
										 |  |  |     unsigned mask = *srcptr++; | 
					
						
							|  |  |  |     unsigned maskbit = 0x80; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-31 10:26:58 +00:00
										 |  |  |     while (srcptr < srcptr_end && destptr < destptr_end) { | 
					
						
							| 
									
										
										
										
											2009-05-31 10:58:20 +00:00
										 |  |  |         if (!(mask & maskbit)) { | 
					
						
							| 
									
										
										
										
											2009-05-31 10:16:28 +00:00
										 |  |  |             memcpy(destptr, srcptr, 4); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             destptr += 4; | 
					
						
							|  |  |  |             srcptr += 4; | 
					
						
							|  |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2009-05-31 11:35:20 +00:00
										 |  |  |             unsigned ofs = bytestream_get_le16(&srcptr); | 
					
						
							|  |  |  |             unsigned cnt = (ofs >> 11) + 1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             ofs &= 0x7ff; | 
					
						
							| 
									
										
										
										
											2009-05-31 17:44:35 +00:00
										 |  |  |             ofs = FFMIN(ofs, destptr - destptr_bak); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             cnt *= 4; | 
					
						
							| 
									
										
										
										
											2009-05-31 10:44:42 +00:00
										 |  |  |             cnt = FFMIN(cnt, destptr_end - destptr); | 
					
						
							| 
									
										
										
										
											2009-05-31 10:42:26 +00:00
										 |  |  |             av_memcpy_backptr(destptr, ofs, cnt); | 
					
						
							|  |  |  |             destptr += cnt; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-05-31 10:58:20 +00:00
										 |  |  |         maskbit >>= 1; | 
					
						
							| 
									
										
										
										
											2009-05-31 11:32:03 +00:00
										 |  |  |         if (!maskbit) { | 
					
						
							|  |  |  |             mask = *srcptr++; | 
					
						
							| 
									
										
										
										
											2009-05-31 18:17:33 +00:00
										 |  |  |             while (!mask) { | 
					
						
							|  |  |  |                 if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break; | 
					
						
							|  |  |  |                 memcpy(destptr, srcptr, 32); | 
					
						
							|  |  |  |                 destptr += 32; | 
					
						
							|  |  |  |                 srcptr += 32; | 
					
						
							|  |  |  |                 mask = *srcptr++; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 11:32:03 +00:00
										 |  |  |             maskbit = 0x80; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-30 09:07:10 +00:00
										 |  |  |     return destptr - destptr_bak; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \brief decompress a zlib-compressed data block into decomp_buf | 
					
						
							|  |  |  |  * \param src compressed input buffer | 
					
						
							|  |  |  |  * \param src_len data length in input buffer | 
					
						
							|  |  |  |  * \param offset offset in decomp_buf | 
					
						
							|  |  |  |  * \param expected expected decompressed length | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-05-31 19:51:21 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  | static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     LclDecContext *c = avctx->priv_data; | 
					
						
							|  |  |  |     int zret = inflateReset(&c->zstream); | 
					
						
							|  |  |  |     if (zret != Z_OK) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     c->zstream.next_in = src; | 
					
						
							|  |  |  |     c->zstream.avail_in = src_len; | 
					
						
							|  |  |  |     c->zstream.next_out = c->decomp_buf + offset; | 
					
						
							|  |  |  |     c->zstream.avail_out = c->decomp_size - offset; | 
					
						
							|  |  |  |     zret = inflate(&c->zstream, Z_FINISH); | 
					
						
							|  |  |  |     if (zret != Z_OK && zret != Z_STREAM_END) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (expected != (unsigned int)c->zstream.total_out) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", | 
					
						
							|  |  |  |                expected, c->zstream.total_out); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return c->zstream.total_out; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-05-31 19:51:21 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Decode a frame | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2009-04-07 15:59:50 +00:00
										 |  |  | static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-04-07 15:59:50 +00:00
										 |  |  |     const uint8_t *buf = avpkt->data; | 
					
						
							|  |  |  |     int buf_size = avpkt->size; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     LclDecContext * const c = avctx->priv_data; | 
					
						
							|  |  |  |     unsigned char *encoded = (unsigned char *)buf; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     unsigned int pixel_ptr; | 
					
						
							|  |  |  |     int row, col; | 
					
						
							|  |  |  |     unsigned char *outptr; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |     uint8_t *y_out, *u_out, *v_out; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     unsigned int width = avctx->width; // Real image width
 | 
					
						
							|  |  |  |     unsigned int height = avctx->height; // Real image height
 | 
					
						
							|  |  |  |     unsigned int mszh_dlen; | 
					
						
							|  |  |  |     unsigned char yq, y1q, uq, vq; | 
					
						
							|  |  |  |     int uqvq; | 
					
						
							|  |  |  |     unsigned int mthread_inlen, mthread_outlen; | 
					
						
							|  |  |  |     unsigned int len = buf_size; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     if(c->pic.data[0]) | 
					
						
							|  |  |  |         avctx->release_buffer(avctx, &c->pic); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     c->pic.reference = 0; | 
					
						
							|  |  |  |     c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; | 
					
						
							|  |  |  |     if(avctx->get_buffer(avctx, &c->pic) < 0){ | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     outptr = c->pic.data[0]; // Output image pointer
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Decompress frame */ | 
					
						
							|  |  |  |     switch (avctx->codec_id) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     case CODEC_ID_MSZH: | 
					
						
							|  |  |  |         switch (c->compression) { | 
					
						
							|  |  |  |         case COMP_MSZH: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             if (c->flags & FLAG_MULTITHREAD) { | 
					
						
							| 
									
										
										
										
											2009-05-31 10:14:27 +00:00
										 |  |  |                 mthread_inlen = AV_RL32(encoded); | 
					
						
							| 
									
										
										
										
											2009-05-31 09:59:46 +00:00
										 |  |  |                 mthread_inlen = FFMIN(mthread_inlen, len - 8); | 
					
						
							| 
									
										
										
										
											2009-05-31 10:14:27 +00:00
										 |  |  |                 mthread_outlen = AV_RL32(encoded+4); | 
					
						
							| 
									
										
										
										
											2009-05-31 09:57:42 +00:00
										 |  |  |                 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); | 
					
						
							|  |  |  |                 if (mthread_outlen != mszh_dlen) { | 
					
						
							|  |  |  |                     av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", | 
					
						
							|  |  |  |                            mthread_outlen, mszh_dlen); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                     return -1; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2009-05-31 10:01:26 +00:00
										 |  |  |                 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                                         c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); | 
					
						
							|  |  |  |                 if (mthread_outlen != mszh_dlen) { | 
					
						
							|  |  |  |                     av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", | 
					
						
							|  |  |  |                            mthread_outlen, mszh_dlen); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                     return -1; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                 encoded = c->decomp_buf; | 
					
						
							|  |  |  |                 len = c->decomp_size; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             } else { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); | 
					
						
							|  |  |  |                 if (c->decomp_size != mszh_dlen) { | 
					
						
							|  |  |  |                     av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", | 
					
						
							|  |  |  |                            c->decomp_size, mszh_dlen); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                     return -1; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                 encoded = c->decomp_buf; | 
					
						
							|  |  |  |                 len = mszh_dlen; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case COMP_MSZH_NOCOMP: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:16:06 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:19:21 +00:00
										 |  |  |     case CODEC_ID_ZLIB: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         /* Using the original dll with normal compression (-1) and RGB format
 | 
					
						
							|  |  |  |          * gives a file with ZLIB fourcc, but frame is really uncompressed. | 
					
						
							|  |  |  |          * To be sure that's true check also frame size */ | 
					
						
							| 
									
										
										
										
											2009-05-30 09:07:10 +00:00
										 |  |  |         if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 && | 
					
						
							|  |  |  |             len == width * height * 3) | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         if (c->flags & FLAG_MULTITHREAD) { | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  |             int ret; | 
					
						
							| 
									
										
										
										
											2009-05-31 10:14:27 +00:00
										 |  |  |             mthread_inlen = AV_RL32(encoded); | 
					
						
							| 
									
										
										
										
											2009-05-31 09:59:46 +00:00
										 |  |  |             mthread_inlen = FFMIN(mthread_inlen, len - 8); | 
					
						
							| 
									
										
										
										
											2009-05-31 10:14:27 +00:00
										 |  |  |             mthread_outlen = AV_RL32(encoded+4); | 
					
						
							| 
									
										
										
										
											2009-05-31 09:57:42 +00:00
										 |  |  |             mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  |             ret = zlib_decomp(avctx, encoded + 8, mthread_inlen, 0, mthread_outlen); | 
					
						
							|  |  |  |             if (ret < 0) return ret; | 
					
						
							| 
									
										
										
										
											2009-05-31 10:01:26 +00:00
										 |  |  |             ret = zlib_decomp(avctx, encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  |                               mthread_outlen, mthread_outlen); | 
					
						
							|  |  |  |             if (ret < 0) return ret; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2009-05-31 09:51:46 +00:00
										 |  |  |             int ret = zlib_decomp(avctx, encoded, len, 0, c->decomp_size); | 
					
						
							|  |  |  |             if (ret < 0) return ret; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         encoded = c->decomp_buf; | 
					
						
							| 
									
										
										
										
											2008-02-19 21:46:40 +00:00
										 |  |  |         len = c->decomp_size; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:19:21 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     default: | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Apply PNG filter */ | 
					
						
							| 
									
										
										
										
											2009-05-30 09:07:10 +00:00
										 |  |  |     if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |         switch (c->imgtype) { | 
					
						
							|  |  |  |         case IMGTYPE_YUV111: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         case IMGTYPE_RGB24: | 
					
						
							|  |  |  |             for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |                 pixel_ptr = row * width * 3; | 
					
						
							|  |  |  |                 yq = encoded[pixel_ptr++]; | 
					
						
							|  |  |  |                 uqvq = AV_RL16(encoded+pixel_ptr); | 
					
						
							|  |  |  |                 pixel_ptr += 2; | 
					
						
							|  |  |  |                 for (col = 1; col < width; col++) { | 
					
						
							|  |  |  |                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | 
					
						
							|  |  |  |                     uqvq -= AV_RL16(encoded+pixel_ptr+1); | 
					
						
							|  |  |  |                     AV_WL16(encoded+pixel_ptr+1, uqvq); | 
					
						
							|  |  |  |                     pixel_ptr += 3; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IMGTYPE_YUV422: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |                 pixel_ptr = row * width * 2; | 
					
						
							|  |  |  |                 yq = uq = vq =0; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 for (col = 0; col < width/4; col++) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; | 
					
						
							|  |  |  |                     pixel_ptr += 8; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IMGTYPE_YUV411: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |                 pixel_ptr = row * width / 2 * 3; | 
					
						
							|  |  |  |                 yq = uq = vq =0; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 for (col = 0; col < width/4; col++) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | 
					
						
							|  |  |  |                     pixel_ptr += 6; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IMGTYPE_YUV211: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |                 pixel_ptr = row * width * 2; | 
					
						
							|  |  |  |                 yq = uq = vq =0; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 for (col = 0; col < width/2; col++) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; | 
					
						
							|  |  |  |                     pixel_ptr += 4; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case IMGTYPE_YUV420: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             for (row = 0; row < height/2; row++) { | 
					
						
							|  |  |  |                 pixel_ptr = row * width * 3; | 
					
						
							|  |  |  |                 yq = y1q = uq = vq =0; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                 for (col = 0; col < width/2; col++) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                     encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | 
					
						
							|  |  |  |                     encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |                     pixel_ptr += 6; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             return -1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Convert colorspace */ | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |     y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; | 
					
						
							|  |  |  |     u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; | 
					
						
							|  |  |  |     v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     switch (c->imgtype) { | 
					
						
							|  |  |  |     case IMGTYPE_YUV111: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         for (row = 0; row < height; row++) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             for (col = 0; col < width; col++) { | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |                 y_out[col] = *encoded++; | 
					
						
							|  |  |  |                 u_out[col] = *encoded++ + 128; | 
					
						
							|  |  |  |                 v_out[col] = *encoded++ + 128; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |             y_out -= c->pic.linesize[0]; | 
					
						
							|  |  |  |             u_out -= c->pic.linesize[1]; | 
					
						
							|  |  |  |             v_out -= c->pic.linesize[2]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV422: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |             for (col = 0; col < width - 3; col += 4) { | 
					
						
							|  |  |  |                 memcpy(y_out + col, encoded, 4); | 
					
						
							|  |  |  |                 encoded += 4; | 
					
						
							|  |  |  |                 u_out[ col >> 1     ] = *encoded++ + 128; | 
					
						
							|  |  |  |                 u_out[(col >> 1) + 1] = *encoded++ + 128; | 
					
						
							|  |  |  |                 v_out[ col >> 1     ] = *encoded++ + 128; | 
					
						
							|  |  |  |                 v_out[(col >> 1) + 1] = *encoded++ + 128; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |             y_out -= c->pic.linesize[0]; | 
					
						
							|  |  |  |             u_out -= c->pic.linesize[1]; | 
					
						
							|  |  |  |             v_out -= c->pic.linesize[2]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_RGB24: | 
					
						
							|  |  |  |         for (row = height - 1; row >= 0; row--) { | 
					
						
							|  |  |  |             pixel_ptr = row * c->pic.linesize[0]; | 
					
						
							| 
									
										
										
										
											2009-05-30 11:20:07 +00:00
										 |  |  |             memcpy(outptr + pixel_ptr, encoded, 3 * width); | 
					
						
							|  |  |  |             encoded += 3 * width; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV411: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |             for (col = 0; col < width - 3; col += 4) { | 
					
						
							|  |  |  |                 memcpy(y_out + col, encoded, 4); | 
					
						
							|  |  |  |                 encoded += 4; | 
					
						
							|  |  |  |                 u_out[col >> 2] = *encoded++ + 128; | 
					
						
							|  |  |  |                 v_out[col >> 2] = *encoded++ + 128; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |             y_out -= c->pic.linesize[0]; | 
					
						
							|  |  |  |             u_out -= c->pic.linesize[1]; | 
					
						
							|  |  |  |             v_out -= c->pic.linesize[2]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV211: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         for (row = 0; row < height; row++) { | 
					
						
							|  |  |  |             for (col = 0; col < width - 1; col += 2) { | 
					
						
							|  |  |  |                 memcpy(y_out + col, encoded, 2); | 
					
						
							|  |  |  |                 encoded += 2; | 
					
						
							|  |  |  |                 u_out[col >> 1] = *encoded++ + 128; | 
					
						
							|  |  |  |                 v_out[col >> 1] = *encoded++ + 128; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |             y_out -= c->pic.linesize[0]; | 
					
						
							|  |  |  |             u_out -= c->pic.linesize[1]; | 
					
						
							|  |  |  |             v_out -= c->pic.linesize[2]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV420: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; | 
					
						
							|  |  |  |         v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; | 
					
						
							|  |  |  |         for (row = 0; row < height - 1; row += 2) { | 
					
						
							|  |  |  |             for (col = 0; col < width - 1; col += 2) { | 
					
						
							|  |  |  |                 memcpy(y_out + col, encoded, 2); | 
					
						
							|  |  |  |                 encoded += 2; | 
					
						
							|  |  |  |                 memcpy(y_out + col - c->pic.linesize[0], encoded, 2); | 
					
						
							|  |  |  |                 encoded += 2; | 
					
						
							|  |  |  |                 u_out[col >> 1] = *encoded++ + 128; | 
					
						
							|  |  |  |                 v_out[col >> 1] = *encoded++ + 128; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |             y_out -= c->pic.linesize[0] << 1; | 
					
						
							|  |  |  |             u_out -= c->pic.linesize[1]; | 
					
						
							|  |  |  |             v_out -= c->pic.linesize[2]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *data_size = sizeof(AVFrame); | 
					
						
							|  |  |  |     *(AVFrame*)data = c->pic; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* always report that the buffer was completely consumed */ | 
					
						
							|  |  |  |     return buf_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Init lcl decoder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-03-21 03:11:20 +00:00
										 |  |  | static av_cold int decode_init(AVCodecContext *avctx) | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     LclDecContext * const c = avctx->priv_data; | 
					
						
							|  |  |  |     unsigned int basesize = avctx->width * avctx->height; | 
					
						
							| 
									
										
										
										
											2009-05-31 10:42:26 +00:00
										 |  |  |     unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     unsigned int max_decomp_size; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (avctx->extradata_size < 8) { | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); | 
					
						
							|  |  |  |         return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Check codec type */ | 
					
						
							| 
									
										
										
										
											2009-05-31 09:12:17 +00:00
										 |  |  |     if ((avctx->codec_id == CODEC_ID_MSZH  && avctx->extradata[7] != CODEC_MSZH) || | 
					
						
							|  |  |  |         (avctx->codec_id == CODEC_ID_ZLIB  && avctx->extradata[7] != CODEC_ZLIB)) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |         av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Detect image type */ | 
					
						
							| 
									
										
										
										
											2009-05-31 09:12:17 +00:00
										 |  |  |     switch (c->imgtype = avctx->extradata[4]) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     case IMGTYPE_YUV111: | 
					
						
							|  |  |  |         c->decomp_size = basesize * 3; | 
					
						
							|  |  |  |         max_decomp_size = max_basesize * 3; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         avctx->pix_fmt = PIX_FMT_YUV444P; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV422: | 
					
						
							|  |  |  |         c->decomp_size = basesize * 2; | 
					
						
							|  |  |  |         max_decomp_size = max_basesize * 2; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         avctx->pix_fmt = PIX_FMT_YUV422P; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_RGB24: | 
					
						
							|  |  |  |         c->decomp_size = basesize * 3; | 
					
						
							|  |  |  |         max_decomp_size = max_basesize * 3; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         avctx->pix_fmt = PIX_FMT_BGR24; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV411: | 
					
						
							|  |  |  |         c->decomp_size = basesize / 2 * 3; | 
					
						
							|  |  |  |         max_decomp_size = max_basesize / 2 * 3; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         avctx->pix_fmt = PIX_FMT_YUV411P; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV211: | 
					
						
							|  |  |  |         c->decomp_size = basesize * 2; | 
					
						
							|  |  |  |         max_decomp_size = max_basesize * 2; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         avctx->pix_fmt = PIX_FMT_YUV422P; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     case IMGTYPE_YUV420: | 
					
						
							|  |  |  |         c->decomp_size = basesize / 2 * 3; | 
					
						
							|  |  |  |         max_decomp_size = max_basesize / 2 * 3; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:09:32 +00:00
										 |  |  |         avctx->pix_fmt = PIX_FMT_YUV420P; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); | 
					
						
							|  |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Detect compression method */ | 
					
						
							| 
									
										
										
										
											2009-05-31 10:50:54 +00:00
										 |  |  |     c->compression = (int8_t)avctx->extradata[5]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     switch (avctx->codec_id) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     case CODEC_ID_MSZH: | 
					
						
							|  |  |  |         switch (c->compression) { | 
					
						
							|  |  |  |         case COMP_MSZH: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |             av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         case COMP_MSZH_NOCOMP: | 
					
						
							|  |  |  |             c->decomp_size = 0; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |             av_log(avctx, AV_LOG_DEBUG, "No compression.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:16:06 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:19:21 +00:00
										 |  |  |     case CODEC_ID_ZLIB: | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         switch (c->compression) { | 
					
						
							|  |  |  |         case COMP_ZLIB_HISPEED: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |             av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case COMP_ZLIB_HICOMP: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |             av_log(avctx, AV_LOG_DEBUG, "High compression.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         case COMP_ZLIB_NORMAL: | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |             av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |             break; | 
					
						
							|  |  |  |         default: | 
					
						
							| 
									
										
										
										
											2009-05-30 09:07:10 +00:00
										 |  |  |             if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |                 av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); | 
					
						
							|  |  |  |                 return 1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |             av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         break; | 
					
						
							| 
									
										
										
										
											2009-05-31 09:19:21 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     default: | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); | 
					
						
							|  |  |  |         return 1; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Allocate decompression buffer */ | 
					
						
							|  |  |  |     if (c->decomp_size) { | 
					
						
							|  |  |  |         if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { | 
					
						
							|  |  |  |             av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Detect flags */ | 
					
						
							| 
									
										
										
										
											2009-05-31 09:12:17 +00:00
										 |  |  |     c->flags = avctx->extradata[6]; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     if (c->flags & FLAG_MULTITHREAD) | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     if (c->flags & FLAG_NULLFRAME) | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n"); | 
					
						
							| 
									
										
										
										
											2009-05-31 10:05:21 +00:00
										 |  |  |     if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) | 
					
						
							| 
									
										
										
										
											2009-05-31 09:23:54 +00:00
										 |  |  |         av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n"); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |     if (c->flags & FLAGMASK_UNUSED) | 
					
						
							|  |  |  |         av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* If needed init zlib */ | 
					
						
							| 
									
										
										
										
											2009-05-31 09:16:06 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2009-05-31 09:19:21 +00:00
										 |  |  |     if (avctx->codec_id == CODEC_ID_ZLIB) { | 
					
						
							| 
									
										
										
										
											2009-05-31 09:27:07 +00:00
										 |  |  |         int zret; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |         c->zstream.zalloc = Z_NULL; | 
					
						
							|  |  |  |         c->zstream.zfree = Z_NULL; | 
					
						
							|  |  |  |         c->zstream.opaque = Z_NULL; | 
					
						
							| 
									
										
										
										
											2009-05-30 09:07:10 +00:00
										 |  |  |         zret = inflateInit(&c->zstream); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |         if (zret != Z_OK) { | 
					
						
							|  |  |  |             av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); | 
					
						
							| 
									
										
										
										
											2009-05-31 11:47:52 +00:00
										 |  |  |             av_freep(&c->decomp_buf); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  |             return 1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-05-31 09:19:21 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Uninit lcl decoder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-03-21 03:11:20 +00:00
										 |  |  | static av_cold int decode_end(AVCodecContext *avctx) | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     LclDecContext * const c = avctx->priv_data; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-31 11:47:52 +00:00
										 |  |  |     av_freep(&c->decomp_buf); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     if (c->pic.data[0]) | 
					
						
							|  |  |  |         avctx->release_buffer(avctx, &c->pic); | 
					
						
							| 
									
										
										
										
											2009-05-31 09:16:06 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2009-05-31 11:42:50 +00:00
										 |  |  |     if (avctx->codec_id == CODEC_ID_ZLIB) | 
					
						
							|  |  |  |         inflateEnd(&c->zstream); | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 23:44:16 +00:00
										 |  |  | #if CONFIG_MSZH_DECODER
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | AVCodec mszh_decoder = { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     "mszh", | 
					
						
							| 
									
										
										
										
											2010-03-30 23:30:55 +00:00
										 |  |  |     AVMEDIA_TYPE_VIDEO, | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     CODEC_ID_MSZH, | 
					
						
							|  |  |  |     sizeof(LclDecContext), | 
					
						
							|  |  |  |     decode_init, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     decode_end, | 
					
						
							|  |  |  |     decode_frame, | 
					
						
							|  |  |  |     CODEC_CAP_DR1, | 
					
						
							| 
									
										
										
										
											2008-06-12 21:50:13 +00:00
										 |  |  |     .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-13 23:44:16 +00:00
										 |  |  | #if CONFIG_ZLIB_DECODER
 | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | AVCodec zlib_decoder = { | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     "zlib", | 
					
						
							| 
									
										
										
										
											2010-03-30 23:30:55 +00:00
										 |  |  |     AVMEDIA_TYPE_VIDEO, | 
					
						
							| 
									
										
										
										
											2007-07-12 22:55:35 +00:00
										 |  |  |     CODEC_ID_ZLIB, | 
					
						
							|  |  |  |     sizeof(LclDecContext), | 
					
						
							|  |  |  |     decode_init, | 
					
						
							|  |  |  |     NULL, | 
					
						
							|  |  |  |     decode_end, | 
					
						
							|  |  |  |     decode_frame, | 
					
						
							|  |  |  |     CODEC_CAP_DR1, | 
					
						
							| 
									
										
										
										
											2008-06-12 21:50:13 +00:00
										 |  |  |     .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), | 
					
						
							| 
									
										
										
										
											2007-07-12 22:40:33 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | #endif
 |