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