Mercurial > libavcodec.hg
comparison lcldec.c @ 9756:ed55b61c8e45 libavcodec
Factor out zlib decompression code to avoid massive code duplication,
particularly due to error checks.
author | reimar |
---|---|
date | Sun, 31 May 2009 09:51:46 +0000 |
parents | bd5d76a5ffac |
children | 8e4d442554b3 |
comparison
equal
deleted
inserted
replaced
9755:bd5d76a5ffac | 9756:ed55b61c8e45 |
---|---|
113 | 113 |
114 return destptr - destptr_bak; | 114 return destptr - destptr_bak; |
115 } | 115 } |
116 | 116 |
117 | 117 |
118 /** | |
119 * \brief decompress a zlib-compressed data block into decomp_buf | |
120 * \param src compressed input buffer | |
121 * \param src_len data length in input buffer | |
122 * \param offset offset in decomp_buf | |
123 * \param expected expected decompressed length | |
124 */ | |
125 static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, int offset, int expected) | |
126 { | |
127 LclDecContext *c = avctx->priv_data; | |
128 int zret = inflateReset(&c->zstream); | |
129 if (zret != Z_OK) { | |
130 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); | |
131 return -1; | |
132 } | |
133 c->zstream.next_in = src; | |
134 c->zstream.avail_in = src_len; | |
135 c->zstream.next_out = c->decomp_buf + offset; | |
136 c->zstream.avail_out = c->decomp_size - offset; | |
137 zret = inflate(&c->zstream, Z_FINISH); | |
138 if (zret != Z_OK && zret != Z_STREAM_END) { | |
139 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); | |
140 return -1; | |
141 } | |
142 if (expected != (unsigned int)c->zstream.total_out) { | |
143 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", | |
144 expected, c->zstream.total_out); | |
145 return -1; | |
146 } | |
147 return c->zstream.total_out; | |
148 } | |
149 | |
118 | 150 |
119 /* | 151 /* |
120 * | 152 * |
121 * Decode a frame | 153 * Decode a frame |
122 * | 154 * |
135 unsigned int height = avctx->height; // Real image height | 167 unsigned int height = avctx->height; // Real image height |
136 unsigned int mszh_dlen; | 168 unsigned int mszh_dlen; |
137 unsigned char yq, y1q, uq, vq; | 169 unsigned char yq, y1q, uq, vq; |
138 int uqvq; | 170 int uqvq; |
139 unsigned int mthread_inlen, mthread_outlen; | 171 unsigned int mthread_inlen, mthread_outlen; |
140 #if CONFIG_ZLIB_DECODER | |
141 int zret; // Zlib return code | |
142 #endif | |
143 unsigned int len = buf_size; | 172 unsigned int len = buf_size; |
144 | 173 |
145 if(c->pic.data[0]) | 174 if(c->pic.data[0]) |
146 avctx->release_buffer(avctx, &c->pic); | 175 avctx->release_buffer(avctx, &c->pic); |
147 | 176 |
203 * gives a file with ZLIB fourcc, but frame is really uncompressed. | 232 * gives a file with ZLIB fourcc, but frame is really uncompressed. |
204 * To be sure that's true check also frame size */ | 233 * To be sure that's true check also frame size */ |
205 if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 && | 234 if (c->compression == COMP_ZLIB_NORMAL && c->imgtype == IMGTYPE_RGB24 && |
206 len == width * height * 3) | 235 len == width * height * 3) |
207 break; | 236 break; |
208 zret = inflateReset(&c->zstream); | |
209 if (zret != Z_OK) { | |
210 av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); | |
211 return -1; | |
212 } | |
213 if (c->flags & FLAG_MULTITHREAD) { | 237 if (c->flags & FLAG_MULTITHREAD) { |
238 int ret; | |
214 mthread_inlen = *(unsigned int*)encoded; | 239 mthread_inlen = *(unsigned int*)encoded; |
215 mthread_outlen = *(unsigned int*)(encoded+4); | 240 mthread_outlen = *(unsigned int*)(encoded+4); |
216 if (mthread_outlen > c->decomp_size) | 241 if (mthread_outlen > c->decomp_size) |
217 mthread_outlen = c->decomp_size; | 242 mthread_outlen = c->decomp_size; |
218 c->zstream.next_in = encoded + 8; | 243 ret = zlib_decomp(avctx, encoded + 8, mthread_inlen, 0, mthread_outlen); |
219 c->zstream.avail_in = mthread_inlen; | 244 if (ret < 0) return ret; |
220 c->zstream.next_out = c->decomp_buf; | 245 ret = zlib_decomp(avctx, encoded + 8 + mthread_inlen, len - mthread_inlen, |
221 c->zstream.avail_out = c->decomp_size; | 246 mthread_outlen, mthread_outlen); |
222 zret = inflate(&c->zstream, Z_FINISH); | 247 if (ret < 0) return ret; |
223 if (zret != Z_OK && zret != Z_STREAM_END) { | |
224 av_log(avctx, AV_LOG_ERROR, "Mthread1 inflate error: %d\n", zret); | |
225 return -1; | |
226 } | |
227 if (mthread_outlen != (unsigned int)c->zstream.total_out) { | |
228 av_log(avctx, AV_LOG_ERROR, "Mthread1 decoded size differs (%u != %lu)\n", | |
229 mthread_outlen, c->zstream.total_out); | |
230 return -1; | |
231 } | |
232 zret = inflateReset(&c->zstream); | |
233 if (zret != Z_OK) { | |
234 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate reset error: %d\n", zret); | |
235 return -1; | |
236 } | |
237 c->zstream.next_in = encoded + 8 + mthread_inlen; | |
238 c->zstream.avail_in = len - mthread_inlen; | |
239 c->zstream.next_out = c->decomp_buf + mthread_outlen; | |
240 c->zstream.avail_out = c->decomp_size - mthread_outlen; | |
241 zret = inflate(&c->zstream, Z_FINISH); | |
242 if (zret != Z_OK && zret != Z_STREAM_END) { | |
243 av_log(avctx, AV_LOG_ERROR, "Mthread2 inflate error: %d\n", zret); | |
244 return -1; | |
245 } | |
246 if (mthread_outlen != (unsigned int)c->zstream.total_out) { | |
247 av_log(avctx, AV_LOG_ERROR, "Mthread2 decoded size differs (%d != %lu)\n", | |
248 mthread_outlen, c->zstream.total_out); | |
249 return -1; | |
250 } | |
251 } else { | 248 } else { |
252 c->zstream.next_in = encoded; | 249 int ret = zlib_decomp(avctx, encoded, len, 0, c->decomp_size); |
253 c->zstream.avail_in = len; | 250 if (ret < 0) return ret; |
254 c->zstream.next_out = c->decomp_buf; | |
255 c->zstream.avail_out = c->decomp_size; | |
256 zret = inflate(&c->zstream, Z_FINISH); | |
257 if (zret != Z_OK && zret != Z_STREAM_END) { | |
258 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); | |
259 return -1; | |
260 } | |
261 if (c->decomp_size != (unsigned int)c->zstream.total_out) { | |
262 av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", | |
263 c->decomp_size, c->zstream.total_out); | |
264 return -1; | |
265 } | |
266 } | 251 } |
267 encoded = c->decomp_buf; | 252 encoded = c->decomp_buf; |
268 len = c->decomp_size; | 253 len = c->decomp_size; |
269 break; | 254 break; |
270 #endif | 255 #endif |