Mercurial > libavcodec.hg
annotate lcldec.c @ 10273:38147f0f94cc libavcodec
Specify maximum sample rate of MLP by defining the factor relative to 48000
instead of directly.
This makes clear that the code assumes the maximum sample rate to be
a multiple of 48000 and also removes the division from the MAX_BLOCKSIZE
macros, which causes an issue with the Solaris assembler where "/" is
a comment marker unless the --divide option is used.
author | reimar |
---|---|
date | Sat, 26 Sep 2009 16:04:35 +0000 |
parents | 21f3bbb20e42 |
children | d7ed9dcc78e3 |
rev | line source |
---|---|
1743 | 1 /* |
2 * LCL (LossLess Codec Library) Codec | |
3 * Copyright (c) 2002-2004 Roberto Togni | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
1743 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
1743 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
1743 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1743 | 20 */ |
21 | |
22 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8673
diff
changeset
|
23 * @file libavcodec/lcldec.c |
1743 | 24 * LCL (LossLess Codec Library) Video Codec |
25 * Decoder for MSZH and ZLIB codecs | |
26 * Experimental encoder for ZLIB RGB24 | |
27 * | |
28 * Fourcc: MSZH, ZLIB | |
29 * | |
30 * Original Win32 dll: | |
31 * Ver2.23 By Kenji Oshima 2000.09.20 | |
32 * avimszh.dll, avizlib.dll | |
33 * | |
34 * A description of the decoding algorithm can be found here: | |
35 * http://www.pcisys.net/~melanson/codecs | |
36 * | |
37 * Supports: BGR24 (RGB 24bpp) | |
38 * | |
39 */ | |
40 | |
41 #include <stdio.h> | |
42 #include <stdlib.h> | |
43 | |
4962
f99e40a7155b
Remove redundant #inclusion of common.h, avcodec.h already #includes it.
diego
parents:
4827
diff
changeset
|
44 #include "avcodec.h" |
9767
99d5a25c5895
Use bytestream_get_le16 to simplify offset/count calculation for mszh decompression.
reimar
parents:
9766
diff
changeset
|
45 #include "bytestream.h" |
5294 | 46 #include "lcl.h" |
9770
e883c3dab3ec
Pad the decompression buffer and use av_memcpy_backptr for the mszh decompression.
reimar
parents:
9769
diff
changeset
|
47 #include "libavutil/lzo.h" |
1743 | 48 |
9751
705efd6ddaab
lcldec.c: change #if CONFIG_ZLIB to #if CONFIG_ZLIB_DECODER.
reimar
parents:
9750
diff
changeset
|
49 #if CONFIG_ZLIB_DECODER |
1743 | 50 #include <zlib.h> |
51 #endif | |
52 | |
53 /* | |
54 * Decoder context | |
55 */ | |
5294 | 56 typedef struct LclDecContext { |
5297 | 57 AVFrame pic; |
1743 | 58 |
59 // Image type | |
60 int imgtype; | |
61 // Compression type | |
62 int compression; | |
63 // Flags | |
64 int flags; | |
65 // Decompressed data size | |
66 unsigned int decomp_size; | |
67 // Decompression buffer | |
68 unsigned char* decomp_buf; | |
9751
705efd6ddaab
lcldec.c: change #if CONFIG_ZLIB to #if CONFIG_ZLIB_DECODER.
reimar
parents:
9750
diff
changeset
|
69 #if CONFIG_ZLIB_DECODER |
1743 | 70 z_stream zstream; |
71 #endif | |
5294 | 72 } LclDecContext; |
1743 | 73 |
74 | |
9765
350826aae685
Document padding requirements of mszh_decomp srcptr buffer
reimar
parents:
9764
diff
changeset
|
75 /** |
9775
3fd46320ab12
Take advantage of available input padding to optimize mszh_decomp
reimar
parents:
9774
diff
changeset
|
76 * \param srcptr compressed source buffer, must be padded with at least 5 extra bytes |
9770
e883c3dab3ec
Pad the decompression buffer and use av_memcpy_backptr for the mszh decompression.
reimar
parents:
9769
diff
changeset
|
77 * \param destptr must be padded sufficiently for av_memcpy_backptr |
9765
350826aae685
Document padding requirements of mszh_decomp srcptr buffer
reimar
parents:
9764
diff
changeset
|
78 */ |
9769 | 79 static unsigned int mszh_decomp(const unsigned char * srcptr, int srclen, unsigned char * destptr, unsigned int destsize) |
1743 | 80 { |
81 unsigned char *destptr_bak = destptr; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
82 unsigned char *destptr_end = destptr + destsize; |
9769 | 83 const unsigned char *srcptr_end = srcptr + srclen; |
9776
18d149e8fc7f
Use int-size types instead of char where it makes no difference.
reimar
parents:
9775
diff
changeset
|
84 unsigned mask = *srcptr++; |
18d149e8fc7f
Use int-size types instead of char where it makes no difference.
reimar
parents:
9775
diff
changeset
|
85 unsigned maskbit = 0x80; |
2967 | 86 |
9764
dd6bcbec3c24
Use srcptr_end variable to avoid having to update both srcptr and srclen.
reimar
parents:
9763
diff
changeset
|
87 while (srcptr < srcptr_end && destptr < destptr_end) { |
9774 | 88 if (!(mask & maskbit)) { |
9762
3242ae563430
Simply use memcpy instead of AV_RN32/AV_WN32 combination.
reimar
parents:
9761
diff
changeset
|
89 memcpy(destptr, srcptr, 4); |
1743 | 90 destptr += 4; |
91 srcptr += 4; | |
92 } else { | |
9777 | 93 unsigned ofs = bytestream_get_le16(&srcptr); |
94 unsigned cnt = (ofs >> 11) + 1; | |
1743 | 95 ofs &= 0x7ff; |
9781
05b6cba2c95b
lcldec: ensure that the offset for av_memcpy_backptr is valid.
reimar
parents:
9780
diff
changeset
|
96 ofs = FFMIN(ofs, destptr - destptr_bak); |
1743 | 97 cnt *= 4; |
9771 | 98 cnt = FFMIN(cnt, destptr_end - destptr); |
9770
e883c3dab3ec
Pad the decompression buffer and use av_memcpy_backptr for the mszh decompression.
reimar
parents:
9769
diff
changeset
|
99 av_memcpy_backptr(destptr, ofs, cnt); |
e883c3dab3ec
Pad the decompression buffer and use av_memcpy_backptr for the mszh decompression.
reimar
parents:
9769
diff
changeset
|
100 destptr += cnt; |
1743 | 101 } |
9774 | 102 maskbit >>= 1; |
9775
3fd46320ab12
Take advantage of available input padding to optimize mszh_decomp
reimar
parents:
9774
diff
changeset
|
103 if (!maskbit) { |
3fd46320ab12
Take advantage of available input padding to optimize mszh_decomp
reimar
parents:
9774
diff
changeset
|
104 mask = *srcptr++; |
9782
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
105 while (!mask) { |
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
106 if (destptr_end - destptr < 32 || srcptr_end - srcptr < 32) break; |
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
107 memcpy(destptr, srcptr, 32); |
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
108 destptr += 32; |
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
109 srcptr += 32; |
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
110 mask = *srcptr++; |
66922728d7f7
mszh decompression: add a special case for an all-0 mask, i.e. 32 uncompressed
reimar
parents:
9781
diff
changeset
|
111 } |
9775
3fd46320ab12
Take advantage of available input padding to optimize mszh_decomp
reimar
parents:
9774
diff
changeset
|
112 maskbit = 0x80; |
3fd46320ab12
Take advantage of available input padding to optimize mszh_decomp
reimar
parents:
9774
diff
changeset
|
113 } |
1743 | 114 } |
115 | |
9736
405cbc435997
Remove useless () from lcldec for more consistency with "normal" FFmpeg coding style.
reimar
parents:
9730
diff
changeset
|
116 return destptr - destptr_bak; |
1743 | 117 } |
118 | |
119 | |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
120 /** |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
121 * \brief decompress a zlib-compressed data block into decomp_buf |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
122 * \param src compressed input buffer |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
123 * \param src_len data length in input buffer |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
124 * \param offset offset in decomp_buf |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
125 * \param expected expected decompressed length |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
126 */ |
9783
21f3bbb20e42
add #if CONFIG_ZLIB_DECODER around zlib_decomp function.
reimar
parents:
9782
diff
changeset
|
127 #if CONFIG_ZLIB_DECODER |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
128 static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
129 { |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
130 LclDecContext *c = avctx->priv_data; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
131 int zret = inflateReset(&c->zstream); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
132 if (zret != Z_OK) { |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
133 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
134 return -1; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
135 } |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
136 c->zstream.next_in = src; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
137 c->zstream.avail_in = src_len; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
138 c->zstream.next_out = c->decomp_buf + offset; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
139 c->zstream.avail_out = c->decomp_size - offset; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
140 zret = inflate(&c->zstream, Z_FINISH); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
141 if (zret != Z_OK && zret != Z_STREAM_END) { |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
142 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
143 return -1; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
144 } |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
145 if (expected != (unsigned int)c->zstream.total_out) { |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
146 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
147 expected, c->zstream.total_out); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
148 return -1; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
149 } |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
150 return c->zstream.total_out; |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
151 } |
9783
21f3bbb20e42
add #if CONFIG_ZLIB_DECODER around zlib_decomp function.
reimar
parents:
9782
diff
changeset
|
152 #endif |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
153 |
1743 | 154 |
155 /* | |
156 * | |
157 * Decode a frame | |
158 * | |
159 */ | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
160 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) |
1743 | 161 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
162 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
163 int buf_size = avpkt->size; |
5297 | 164 LclDecContext * const c = avctx->priv_data; |
165 unsigned char *encoded = (unsigned char *)buf; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
166 unsigned int pixel_ptr; |
1743 | 167 int row, col; |
168 unsigned char *outptr; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
169 uint8_t *y_out, *u_out, *v_out; |
1743 | 170 unsigned int width = avctx->width; // Real image width |
171 unsigned int height = avctx->height; // Real image height | |
172 unsigned int mszh_dlen; | |
173 unsigned char yq, y1q, uq, vq; | |
174 int uqvq; | |
175 unsigned int mthread_inlen, mthread_outlen; | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
176 unsigned int len = buf_size; |
1743 | 177 |
5297 | 178 if(c->pic.data[0]) |
179 avctx->release_buffer(avctx, &c->pic); | |
1743 | 180 |
5297 | 181 c->pic.reference = 0; |
182 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID; | |
183 if(avctx->get_buffer(avctx, &c->pic) < 0){ | |
184 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
185 return -1; | |
186 } | |
1743 | 187 |
188 outptr = c->pic.data[0]; // Output image pointer | |
189 | |
190 /* Decompress frame */ | |
191 switch (avctx->codec_id) { | |
5297 | 192 case CODEC_ID_MSZH: |
193 switch (c->compression) { | |
194 case COMP_MSZH: | |
1743 | 195 if (c->flags & FLAG_MULTITHREAD) { |
9761
b69de727fd7c
Fix decoding of multithread-encoded lcl files on big-endian.
reimar
parents:
9760
diff
changeset
|
196 mthread_inlen = AV_RL32(encoded); |
9758
8ebcc162db3d
Add sanity check for mthread_inlen, avoids crashes due to invalid reads.
reimar
parents:
9757
diff
changeset
|
197 mthread_inlen = FFMIN(mthread_inlen, len - 8); |
9761
b69de727fd7c
Fix decoding of multithread-encoded lcl files on big-endian.
reimar
parents:
9760
diff
changeset
|
198 mthread_outlen = AV_RL32(encoded+4); |
9757 | 199 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); |
5297 | 200 mszh_dlen = mszh_decomp(encoded + 8, mthread_inlen, c->decomp_buf, c->decomp_size); |
201 if (mthread_outlen != mszh_dlen) { | |
202 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%d != %d)\n", | |
203 mthread_outlen, mszh_dlen); | |
1743 | 204 return -1; |
205 } | |
9759 | 206 mszh_dlen = mszh_decomp(encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, |
5297 | 207 c->decomp_buf + mthread_outlen, c->decomp_size - mthread_outlen); |
208 if (mthread_outlen != mszh_dlen) { | |
209 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %d)\n", | |
210 mthread_outlen, mszh_dlen); | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
211 return -1; |
1743 | 212 } |
5297 | 213 encoded = c->decomp_buf; |
214 len = c->decomp_size; | |
215 } else { | |
216 mszh_dlen = mszh_decomp(encoded, len, c->decomp_buf, c->decomp_size); | |
217 if (c->decomp_size != mszh_dlen) { | |
218 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %d)\n", | |
219 c->decomp_size, mszh_dlen); | |
1743 | 220 return -1; |
221 } | |
5297 | 222 encoded = c->decomp_buf; |
223 len = mszh_dlen; | |
1743 | 224 } |
5297 | 225 break; |
226 case COMP_MSZH_NOCOMP: | |
1743 | 227 break; |
228 default: | |
5297 | 229 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); |
230 return -1; | |
231 } | |
232 break; | |
9752
f52c5d54ede5
Get rid of unreachable code: avctx->codec_id == CODEC_ID_ZLIB is not possible
reimar
parents:
9751
diff
changeset
|
233 #if CONFIG_ZLIB_DECODER |
5297 | 234 case CODEC_ID_ZLIB: |
235 /* Using the original dll with normal compression (-1) and RGB format | |
236 * gives a file with ZLIB fourcc, but frame is really uncompressed. | |
237 * To be sure that's true check also frame size */ | |
9736
405cbc435997
Remove useless () from lcldec for more consistency with "normal" FFmpeg coding style.
reimar
parents:
9730
diff
changeset
|
238 if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 && |
405cbc435997
Remove useless () from lcldec for more consistency with "normal" FFmpeg coding style.
reimar
parents:
9730
diff
changeset
|
239 len == width * height * 3) |
5297 | 240 break; |
241 if (c->flags & FLAG_MULTITHREAD) { | |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
242 int ret; |
9761
b69de727fd7c
Fix decoding of multithread-encoded lcl files on big-endian.
reimar
parents:
9760
diff
changeset
|
243 mthread_inlen = AV_RL32(encoded); |
9758
8ebcc162db3d
Add sanity check for mthread_inlen, avoids crashes due to invalid reads.
reimar
parents:
9757
diff
changeset
|
244 mthread_inlen = FFMIN(mthread_inlen, len - 8); |
9761
b69de727fd7c
Fix decoding of multithread-encoded lcl files on big-endian.
reimar
parents:
9760
diff
changeset
|
245 mthread_outlen = AV_RL32(encoded+4); |
9757 | 246 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size); |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
247 ret = zlib_decomp(avctx, encoded + 8, mthread_inlen, 0, mthread_outlen); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
248 if (ret < 0) return ret; |
9759 | 249 ret = zlib_decomp(avctx, encoded + 8 + mthread_inlen, len - 8 - mthread_inlen, |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
250 mthread_outlen, mthread_outlen); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
251 if (ret < 0) return ret; |
5297 | 252 } else { |
9756
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
253 int ret = zlib_decomp(avctx, encoded, len, 0, c->decomp_size); |
ed55b61c8e45
Factor out zlib decompression code to avoid massive code duplication,
reimar
parents:
9755
diff
changeset
|
254 if (ret < 0) return ret; |
5297 | 255 } |
256 encoded = c->decomp_buf; | |
6375 | 257 len = c->decomp_size; |
9752
f52c5d54ede5
Get rid of unreachable code: avctx->codec_id == CODEC_ID_ZLIB is not possible
reimar
parents:
9751
diff
changeset
|
258 break; |
5297 | 259 #endif |
260 default: | |
261 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in frame decoder compression switch.\n"); | |
262 return -1; | |
1743 | 263 } |
264 | |
265 | |
266 /* Apply PNG filter */ | |
9736
405cbc435997
Remove useless () from lcldec for more consistency with "normal" FFmpeg coding style.
reimar
parents:
9730
diff
changeset
|
267 if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) { |
1743 | 268 switch (c->imgtype) { |
5297 | 269 case IMGTYPE_YUV111: |
270 case IMGTYPE_RGB24: | |
271 for (row = 0; row < height; row++) { | |
272 pixel_ptr = row * width * 3; | |
273 yq = encoded[pixel_ptr++]; | |
274 uqvq = AV_RL16(encoded+pixel_ptr); | |
275 pixel_ptr += 2; | |
276 for (col = 1; col < width; col++) { | |
277 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
278 uqvq -= AV_RL16(encoded+pixel_ptr+1); | |
279 AV_WL16(encoded+pixel_ptr+1, uqvq); | |
280 pixel_ptr += 3; | |
1743 | 281 } |
5297 | 282 } |
283 break; | |
284 case IMGTYPE_YUV422: | |
285 for (row = 0; row < height; row++) { | |
286 pixel_ptr = row * width * 2; | |
287 yq = uq = vq =0; | |
288 for (col = 0; col < width/4; col++) { | |
289 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
290 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
291 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
292 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
293 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
294 encoded[pixel_ptr+5] = uq -= encoded[pixel_ptr+5]; | |
295 encoded[pixel_ptr+6] = vq -= encoded[pixel_ptr+6]; | |
296 encoded[pixel_ptr+7] = vq -= encoded[pixel_ptr+7]; | |
297 pixel_ptr += 8; | |
1743 | 298 } |
5297 | 299 } |
300 break; | |
301 case IMGTYPE_YUV411: | |
302 for (row = 0; row < height; row++) { | |
303 pixel_ptr = row * width / 2 * 3; | |
304 yq = uq = vq =0; | |
305 for (col = 0; col < width/4; col++) { | |
306 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
307 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
308 encoded[pixel_ptr+2] = yq -= encoded[pixel_ptr+2]; | |
309 encoded[pixel_ptr+3] = yq -= encoded[pixel_ptr+3]; | |
310 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
311 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
312 pixel_ptr += 6; | |
1743 | 313 } |
5297 | 314 } |
315 break; | |
316 case IMGTYPE_YUV211: | |
317 for (row = 0; row < height; row++) { | |
318 pixel_ptr = row * width * 2; | |
319 yq = uq = vq =0; | |
320 for (col = 0; col < width/2; col++) { | |
321 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
322 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
323 encoded[pixel_ptr+2] = uq -= encoded[pixel_ptr+2]; | |
324 encoded[pixel_ptr+3] = vq -= encoded[pixel_ptr+3]; | |
325 pixel_ptr += 4; | |
1743 | 326 } |
5297 | 327 } |
328 break; | |
329 case IMGTYPE_YUV420: | |
330 for (row = 0; row < height/2; row++) { | |
331 pixel_ptr = row * width * 3; | |
332 yq = y1q = uq = vq =0; | |
333 for (col = 0; col < width/2; col++) { | |
334 encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; | |
335 encoded[pixel_ptr+1] = yq -= encoded[pixel_ptr+1]; | |
336 encoded[pixel_ptr+2] = y1q -= encoded[pixel_ptr+2]; | |
337 encoded[pixel_ptr+3] = y1q -= encoded[pixel_ptr+3]; | |
338 encoded[pixel_ptr+4] = uq -= encoded[pixel_ptr+4]; | |
339 encoded[pixel_ptr+5] = vq -= encoded[pixel_ptr+5]; | |
340 pixel_ptr += 6; | |
1743 | 341 } |
5297 | 342 } |
343 break; | |
344 default: | |
345 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in pngfilter switch.\n"); | |
346 return -1; | |
1743 | 347 } |
348 } | |
349 | |
350 /* Convert colorspace */ | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
351 y_out = c->pic.data[0] + (height - 1) * c->pic.linesize[0]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
352 u_out = c->pic.data[1] + (height - 1) * c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
353 v_out = c->pic.data[2] + (height - 1) * c->pic.linesize[2]; |
1743 | 354 switch (c->imgtype) { |
5297 | 355 case IMGTYPE_YUV111: |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
356 for (row = 0; row < height; row++) { |
5297 | 357 for (col = 0; col < width; col++) { |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
358 y_out[col] = *encoded++; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
359 u_out[col] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
360 v_out[col] = *encoded++ + 128; |
1743 | 361 } |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
362 y_out -= c->pic.linesize[0]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
363 u_out -= c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
364 v_out -= c->pic.linesize[2]; |
5297 | 365 } |
366 break; | |
367 case IMGTYPE_YUV422: | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
368 for (row = 0; row < height; row++) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
369 for (col = 0; col < width - 3; col += 4) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
370 memcpy(y_out + col, encoded, 4); |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
371 encoded += 4; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
372 u_out[ col >> 1 ] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
373 u_out[(col >> 1) + 1] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
374 v_out[ col >> 1 ] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
375 v_out[(col >> 1) + 1] = *encoded++ + 128; |
1743 | 376 } |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
377 y_out -= c->pic.linesize[0]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
378 u_out -= c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
379 v_out -= c->pic.linesize[2]; |
5297 | 380 } |
381 break; | |
382 case IMGTYPE_RGB24: | |
383 for (row = height - 1; row >= 0; row--) { | |
384 pixel_ptr = row * c->pic.linesize[0]; | |
9738
d5929e456b07
Use memcpy instead of per-pixel copy loop for rgb lcl format
reimar
parents:
9736
diff
changeset
|
385 memcpy(outptr + pixel_ptr, encoded, 3 * width); |
d5929e456b07
Use memcpy instead of per-pixel copy loop for rgb lcl format
reimar
parents:
9736
diff
changeset
|
386 encoded += 3 * width; |
5297 | 387 } |
388 break; | |
389 case IMGTYPE_YUV411: | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
390 for (row = 0; row < height; row++) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
391 for (col = 0; col < width - 3; col += 4) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
392 memcpy(y_out + col, encoded, 4); |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
393 encoded += 4; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
394 u_out[col >> 2] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
395 v_out[col >> 2] = *encoded++ + 128; |
1743 | 396 } |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
397 y_out -= c->pic.linesize[0]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
398 u_out -= c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
399 v_out -= c->pic.linesize[2]; |
5297 | 400 } |
401 break; | |
402 case IMGTYPE_YUV211: | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
403 for (row = 0; row < height; row++) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
404 for (col = 0; col < width - 1; col += 2) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
405 memcpy(y_out + col, encoded, 2); |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
406 encoded += 2; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
407 u_out[col >> 1] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
408 v_out[col >> 1] = *encoded++ + 128; |
1743 | 409 } |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
410 y_out -= c->pic.linesize[0]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
411 u_out -= c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
412 v_out -= c->pic.linesize[2]; |
5297 | 413 } |
414 break; | |
415 case IMGTYPE_YUV420: | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
416 u_out = c->pic.data[1] + ((height >> 1) - 1) * c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
417 v_out = c->pic.data[2] + ((height >> 1) - 1) * c->pic.linesize[2]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
418 for (row = 0; row < height - 1; row += 2) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
419 for (col = 0; col < width - 1; col += 2) { |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
420 memcpy(y_out + col, encoded, 2); |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
421 encoded += 2; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
422 memcpy(y_out + col - c->pic.linesize[0], encoded, 2); |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
423 encoded += 2; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
424 u_out[col >> 1] = *encoded++ + 128; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
425 v_out[col >> 1] = *encoded++ + 128; |
1743 | 426 } |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
427 y_out -= c->pic.linesize[0] << 1; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
428 u_out -= c->pic.linesize[1]; |
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
429 v_out -= c->pic.linesize[2]; |
5297 | 430 } |
431 break; | |
432 default: | |
433 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); | |
434 return -1; | |
1743 | 435 } |
436 | |
437 *data_size = sizeof(AVFrame); | |
438 *(AVFrame*)data = c->pic; | |
439 | |
440 /* always report that the buffer was completely consumed */ | |
441 return buf_size; | |
442 } | |
443 | |
444 /* | |
445 * | |
446 * Init lcl decoder | |
447 * | |
448 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6375
diff
changeset
|
449 static av_cold int decode_init(AVCodecContext *avctx) |
1743 | 450 { |
5294 | 451 LclDecContext * const c = avctx->priv_data; |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
452 unsigned int basesize = avctx->width * avctx->height; |
9770
e883c3dab3ec
Pad the decompression buffer and use av_memcpy_backptr for the mszh decompression.
reimar
parents:
9769
diff
changeset
|
453 unsigned int max_basesize = FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) + AV_LZO_OUTPUT_PADDING; |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
454 unsigned int max_decomp_size; |
1743 | 455 |
456 if (avctx->extradata_size < 8) { | |
457 av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); | |
458 return 1; | |
459 } | |
460 | |
2429
4b350cc506a7
Use avcodec_check_dimensions instead of custom hack
rtognimp
parents:
2418
diff
changeset
|
461 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
462 return 1; |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
463 } |
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
464 |
2967 | 465 /* Check codec type */ |
9750
a87706453840
Get rid of extradata casts, it already has the right uint8_t * type
reimar
parents:
9749
diff
changeset
|
466 if ((avctx->codec_id == CODEC_ID_MSZH && avctx->extradata[7] != CODEC_MSZH) || |
a87706453840
Get rid of extradata casts, it already has the right uint8_t * type
reimar
parents:
9749
diff
changeset
|
467 (avctx->codec_id == CODEC_ID_ZLIB && avctx->extradata[7] != CODEC_ZLIB)) { |
1743 | 468 av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); |
469 } | |
470 | |
471 /* Detect image type */ | |
9750
a87706453840
Get rid of extradata casts, it already has the right uint8_t * type
reimar
parents:
9749
diff
changeset
|
472 switch (c->imgtype = avctx->extradata[4]) { |
5297 | 473 case IMGTYPE_YUV111: |
474 c->decomp_size = basesize * 3; | |
475 max_decomp_size = max_basesize * 3; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
476 avctx->pix_fmt = PIX_FMT_YUV444P; |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
477 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n"); |
5297 | 478 break; |
479 case IMGTYPE_YUV422: | |
480 c->decomp_size = basesize * 2; | |
481 max_decomp_size = max_basesize * 2; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
482 avctx->pix_fmt = PIX_FMT_YUV422P; |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
483 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); |
5297 | 484 break; |
485 case IMGTYPE_RGB24: | |
486 c->decomp_size = basesize * 3; | |
487 max_decomp_size = max_basesize * 3; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
488 avctx->pix_fmt = PIX_FMT_BGR24; |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
489 av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n"); |
5297 | 490 break; |
491 case IMGTYPE_YUV411: | |
492 c->decomp_size = basesize / 2 * 3; | |
493 max_decomp_size = max_basesize / 2 * 3; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
494 avctx->pix_fmt = PIX_FMT_YUV411P; |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
495 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n"); |
5297 | 496 break; |
497 case IMGTYPE_YUV211: | |
498 c->decomp_size = basesize * 2; | |
499 max_decomp_size = max_basesize * 2; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
500 avctx->pix_fmt = PIX_FMT_YUV422P; |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
501 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 2:1:1.\n"); |
5297 | 502 break; |
503 case IMGTYPE_YUV420: | |
504 c->decomp_size = basesize / 2 * 3; | |
505 max_decomp_size = max_basesize / 2 * 3; | |
9749
4a4192578b60
Make lcldec produce YUV output when the input file is coded like that, instead
reimar
parents:
9738
diff
changeset
|
506 avctx->pix_fmt = PIX_FMT_YUV420P; |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
507 av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:0.\n"); |
5297 | 508 break; |
509 default: | |
510 av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); | |
511 return 1; | |
1743 | 512 } |
513 | |
514 /* Detect compression method */ | |
9772
2771fff83016
100l, the compression field in lcl extradata must be interpreted as
reimar
parents:
9771
diff
changeset
|
515 c->compression = (int8_t)avctx->extradata[5]; |
1743 | 516 switch (avctx->codec_id) { |
5297 | 517 case CODEC_ID_MSZH: |
518 switch (c->compression) { | |
519 case COMP_MSZH: | |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
520 av_log(avctx, AV_LOG_DEBUG, "Compression enabled.\n"); |
1743 | 521 break; |
5297 | 522 case COMP_MSZH_NOCOMP: |
523 c->decomp_size = 0; | |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
524 av_log(avctx, AV_LOG_DEBUG, "No compression.\n"); |
1743 | 525 break; |
526 default: | |
5297 | 527 av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); |
1743 | 528 return 1; |
5297 | 529 } |
530 break; | |
9752
f52c5d54ede5
Get rid of unreachable code: avctx->codec_id == CODEC_ID_ZLIB is not possible
reimar
parents:
9751
diff
changeset
|
531 #if CONFIG_ZLIB_DECODER |
5297 | 532 case CODEC_ID_ZLIB: |
533 switch (c->compression) { | |
534 case COMP_ZLIB_HISPEED: | |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
535 av_log(avctx, AV_LOG_DEBUG, "High speed compression.\n"); |
5297 | 536 break; |
537 case COMP_ZLIB_HICOMP: | |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
538 av_log(avctx, AV_LOG_DEBUG, "High compression.\n"); |
5297 | 539 break; |
540 case COMP_ZLIB_NORMAL: | |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
541 av_log(avctx, AV_LOG_DEBUG, "Normal compression.\n"); |
5297 | 542 break; |
543 default: | |
9736
405cbc435997
Remove useless () from lcldec for more consistency with "normal" FFmpeg coding style.
reimar
parents:
9730
diff
changeset
|
544 if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) { |
5297 | 545 av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); |
546 return 1; | |
547 } | |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
548 av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); |
5297 | 549 } |
9752
f52c5d54ede5
Get rid of unreachable code: avctx->codec_id == CODEC_ID_ZLIB is not possible
reimar
parents:
9751
diff
changeset
|
550 break; |
5297 | 551 #endif |
552 default: | |
553 av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); | |
554 return 1; | |
1743 | 555 } |
556 | |
557 /* Allocate decompression buffer */ | |
558 if (c->decomp_size) { | |
2418
82af834636c2
Check pointers before writing to memory, fix possible integer overflows
rtognimp
parents:
2398
diff
changeset
|
559 if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { |
1743 | 560 av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); |
561 return 1; | |
562 } | |
563 } | |
2967 | 564 |
565 /* Detect flags */ | |
9750
a87706453840
Get rid of extradata casts, it already has the right uint8_t * type
reimar
parents:
9749
diff
changeset
|
566 c->flags = avctx->extradata[6]; |
1743 | 567 if (c->flags & FLAG_MULTITHREAD) |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
568 av_log(avctx, AV_LOG_DEBUG, "Multithread encoder flag set.\n"); |
1743 | 569 if (c->flags & FLAG_NULLFRAME) |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
570 av_log(avctx, AV_LOG_DEBUG, "Nullframe insertion flag set.\n"); |
9760 | 571 if (avctx->codec_id == CODEC_ID_ZLIB && (c->flags & FLAG_PNGFILTER)) |
9753
ddd880ab64c6
Make lcldec less annoyingly verbose, move messages from AV_LOG_INFO to AV_LOG_DEBUG.
reimar
parents:
9752
diff
changeset
|
572 av_log(avctx, AV_LOG_DEBUG, "PNG filter flag set.\n"); |
1743 | 573 if (c->flags & FLAGMASK_UNUSED) |
574 av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); | |
575 | |
576 /* If needed init zlib */ | |
9752
f52c5d54ede5
Get rid of unreachable code: avctx->codec_id == CODEC_ID_ZLIB is not possible
reimar
parents:
9751
diff
changeset
|
577 #if CONFIG_ZLIB_DECODER |
1743 | 578 if (avctx->codec_id == CODEC_ID_ZLIB) { |
9754
269e16268683
Move variable into block where it is used, avoiding a unused variable
reimar
parents:
9753
diff
changeset
|
579 int zret; |
1743 | 580 c->zstream.zalloc = Z_NULL; |
581 c->zstream.zfree = Z_NULL; | |
582 c->zstream.opaque = Z_NULL; | |
9736
405cbc435997
Remove useless () from lcldec for more consistency with "normal" FFmpeg coding style.
reimar
parents:
9730
diff
changeset
|
583 zret = inflateInit(&c->zstream); |
1743 | 584 if (zret != Z_OK) { |
585 av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); | |
9780
9f3ef4eea41a
Fix memleak due to c->decomp_buf never being freed.
reimar
parents:
9779
diff
changeset
|
586 av_freep(&c->decomp_buf); |
1743 | 587 return 1; |
588 } | |
9752
f52c5d54ede5
Get rid of unreachable code: avctx->codec_id == CODEC_ID_ZLIB is not possible
reimar
parents:
9751
diff
changeset
|
589 } |
1743 | 590 #endif |
591 | |
592 return 0; | |
593 } | |
594 | |
595 /* | |
596 * | |
597 * Uninit lcl decoder | |
598 * | |
599 */ | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6375
diff
changeset
|
600 static av_cold int decode_end(AVCodecContext *avctx) |
1743 | 601 { |
5297 | 602 LclDecContext * const c = avctx->priv_data; |
1743 | 603 |
9780
9f3ef4eea41a
Fix memleak due to c->decomp_buf never being freed.
reimar
parents:
9779
diff
changeset
|
604 av_freep(&c->decomp_buf); |
5297 | 605 if (c->pic.data[0]) |
606 avctx->release_buffer(avctx, &c->pic); | |
9751
705efd6ddaab
lcldec.c: change #if CONFIG_ZLIB to #if CONFIG_ZLIB_DECODER.
reimar
parents:
9750
diff
changeset
|
607 #if CONFIG_ZLIB_DECODER |
9779
4605c1f6e877
Only call inflateEnd when we were actually using the zlib code.
reimar
parents:
9778
diff
changeset
|
608 if (avctx->codec_id == CODEC_ID_ZLIB) |
4605c1f6e877
Only call inflateEnd when we were actually using the zlib code.
reimar
parents:
9778
diff
changeset
|
609 inflateEnd(&c->zstream); |
1743 | 610 #endif |
611 | |
5297 | 612 return 0; |
1743 | 613 } |
614 | |
8590 | 615 #if CONFIG_MSZH_DECODER |
1743 | 616 AVCodec mszh_decoder = { |
5297 | 617 "mszh", |
618 CODEC_TYPE_VIDEO, | |
619 CODEC_ID_MSZH, | |
620 sizeof(LclDecContext), | |
621 decode_init, | |
622 NULL, | |
623 decode_end, | |
624 decode_frame, | |
625 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
626 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) MSZH"), |
1743 | 627 }; |
3777 | 628 #endif |
1743 | 629 |
8590 | 630 #if CONFIG_ZLIB_DECODER |
1743 | 631 AVCodec zlib_decoder = { |
5297 | 632 "zlib", |
633 CODEC_TYPE_VIDEO, | |
634 CODEC_ID_ZLIB, | |
635 sizeof(LclDecContext), | |
636 decode_init, | |
637 NULL, | |
638 decode_end, | |
639 decode_frame, | |
640 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
641 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), |
1743 | 642 }; |
3777 | 643 #endif |