Mercurial > libavcodec.hg
comparison zmbv.c @ 3134:03af25454cc3 libavcodec
ZMBV 15-/16-/32-bit decoding. 24-bit mode is disabled because it's not
implemented in the DosBox/ZMBV codec either.
patch by Konstantin "Kostya" Shishkov
author | diego |
---|---|
date | Mon, 20 Feb 2006 23:22:02 +0000 |
parents | d57bf6a15b04 |
children | 8765ee4eaa45 |
comparison
equal
deleted
inserted
replaced
3133:7dcdc73c1631 | 3134:03af25454cc3 |
---|---|
147 if(src - c->decomp_buf != c->decomp_len) | 147 if(src - c->decomp_buf != c->decomp_len) |
148 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); | 148 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); |
149 return 0; | 149 return 0; |
150 } | 150 } |
151 | 151 |
152 /** | |
153 * Decode XOR'ed frame - 15bpp and 16bpp version | |
154 */ | |
155 | |
156 static int zmbv_decode_xor_16(ZmbvContext *c) | |
157 { | |
158 uint8_t *src = c->decomp_buf; | |
159 uint16_t *output, *prev; | |
160 int8_t *mvec; | |
161 int x, y; | |
162 int d, dx, dy, bw2, bh2; | |
163 int block; | |
164 int i, j; | |
165 int mx, my; | |
166 | |
167 output = (uint16_t*)c->cur; | |
168 prev = (uint16_t*)c->prev; | |
169 | |
170 mvec = (int8_t*)src; | |
171 src += ((c->bx * c->by * 2 + 3) & ~3); | |
172 | |
173 block = 0; | |
174 for(y = 0; y < c->height; y += c->bh) { | |
175 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); | |
176 for(x = 0; x < c->width; x += c->bw) { | |
177 uint16_t *out, *tprev; | |
178 | |
179 d = mvec[block] & 1; | |
180 dx = mvec[block] >> 1; | |
181 dy = mvec[block + 1] >> 1; | |
182 block += 2; | |
183 | |
184 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); | |
185 | |
186 /* copy block - motion vectors out of bounds are used to zero blocks */ | |
187 out = output + x; | |
188 tprev = prev + x + dx + dy * c->width; | |
189 mx = x + dx; | |
190 my = y + dy; | |
191 for(j = 0; j < bh2; j++){ | |
192 if((my + j < 0) || (my + j >= c->height)) { | |
193 memset(out, 0, bw2 * 2); | |
194 } else { | |
195 for(i = 0; i < bw2; i++){ | |
196 if((mx + i < 0) || (mx + i >= c->width)) | |
197 out[i] = 0; | |
198 else | |
199 out[i] = tprev[i]; | |
200 } | |
201 } | |
202 out += c->width; | |
203 tprev += c->width; | |
204 } | |
205 | |
206 if(d) { /* apply XOR'ed difference */ | |
207 out = output + x; | |
208 for(j = 0; j < bh2; j++){ | |
209 for(i = 0; i < bw2; i++) { | |
210 out[i] ^= *((uint16_t*)src); | |
211 src += 2; | |
212 } | |
213 out += c->width; | |
214 } | |
215 } | |
216 } | |
217 output += c->width * c->bh; | |
218 prev += c->width * c->bh; | |
219 } | |
220 if(src - c->decomp_buf != c->decomp_len) | |
221 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); | |
222 return 0; | |
223 } | |
224 | |
225 #ifdef ZMBV_ENABLE_24BPP | |
152 /** | 226 /** |
153 * Decode XOR'ed frame - 24bpp version | 227 * Decode XOR'ed frame - 24bpp version |
154 */ | 228 */ |
155 | 229 |
156 static int zmbv_decode_xor_24(ZmbvContext *c) | 230 static int zmbv_decode_xor_24(ZmbvContext *c) |
227 } | 301 } |
228 if(src - c->decomp_buf != c->decomp_len) | 302 if(src - c->decomp_buf != c->decomp_len) |
229 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); | 303 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); |
230 return 0; | 304 return 0; |
231 } | 305 } |
306 #endif //ZMBV_ENABLE_24BPP | |
307 | |
308 /** | |
309 * Decode XOR'ed frame - 32bpp version | |
310 */ | |
311 | |
312 static int zmbv_decode_xor_32(ZmbvContext *c) | |
313 { | |
314 uint8_t *src = c->decomp_buf; | |
315 uint32_t *output, *prev; | |
316 int8_t *mvec; | |
317 int x, y; | |
318 int d, dx, dy, bw2, bh2; | |
319 int block; | |
320 int i, j; | |
321 int mx, my; | |
322 | |
323 output = (uint32_t*)c->cur; | |
324 prev = (uint32_t*)c->prev; | |
325 | |
326 mvec = (int8_t*)src; | |
327 src += ((c->bx * c->by * 2 + 3) & ~3); | |
328 | |
329 block = 0; | |
330 for(y = 0; y < c->height; y += c->bh) { | |
331 bh2 = ((c->height - y) > c->bh) ? c->bh : (c->height - y); | |
332 for(x = 0; x < c->width; x += c->bw) { | |
333 uint32_t *out, *tprev; | |
334 | |
335 d = mvec[block] & 1; | |
336 dx = mvec[block] >> 1; | |
337 dy = mvec[block + 1] >> 1; | |
338 block += 2; | |
339 | |
340 bw2 = ((c->width - x) > c->bw) ? c->bw : (c->width - x); | |
341 | |
342 /* copy block - motion vectors out of bounds are used to zero blocks */ | |
343 out = output + x; | |
344 tprev = prev + x + dx + dy * c->width; | |
345 mx = x + dx; | |
346 my = y + dy; | |
347 for(j = 0; j < bh2; j++){ | |
348 if((my + j < 0) || (my + j >= c->height)) { | |
349 memset(out, 0, bw2 * 4); | |
350 } else { | |
351 for(i = 0; i < bw2; i++){ | |
352 if((mx + i < 0) || (mx + i >= c->width)) | |
353 out[i] = 0; | |
354 else | |
355 out[i] = tprev[i]; | |
356 } | |
357 } | |
358 out += c->width; | |
359 tprev += c->width; | |
360 } | |
361 | |
362 if(d) { /* apply XOR'ed difference */ | |
363 out = output + x; | |
364 for(j = 0; j < bh2; j++){ | |
365 for(i = 0; i < bw2; i++) { | |
366 out[i] ^= *((uint32_t*)src); | |
367 src += 4; | |
368 } | |
369 out += c->width; | |
370 } | |
371 } | |
372 } | |
373 output += c->width * c->bh; | |
374 prev += c->width * c->bh; | |
375 } | |
376 if(src - c->decomp_buf != c->decomp_len) | |
377 av_log(c->avctx, AV_LOG_ERROR, "Used %i of %i bytes\n", src-c->decomp_buf, c->decomp_len); | |
378 return 0; | |
379 } | |
232 | 380 |
233 /** | 381 /** |
234 * Decode intraframe | 382 * Decode intraframe |
235 */ | 383 */ |
236 static int zmbv_decode_intra(ZmbvContext *c) | 384 static int zmbv_decode_intra(ZmbvContext *c) |
292 } | 440 } |
293 if(c->comp != 0 && c->comp != 1) { | 441 if(c->comp != 0 && c->comp != 1) { |
294 av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp); | 442 av_log(avctx, AV_LOG_ERROR, "Unsupported compression type %i\n", c->comp); |
295 return -1; | 443 return -1; |
296 } | 444 } |
297 if(c->fmt != ZMBV_FMT_8BPP && c->fmt != ZMBV_FMT_24BPP) { | 445 |
446 switch(c->fmt) { | |
447 case ZMBV_FMT_8BPP: | |
448 c->bpp = 8; | |
449 c->decode_intra = zmbv_decode_intra; | |
450 c->decode_xor = zmbv_decode_xor_8; | |
451 break; | |
452 case ZMBV_FMT_15BPP: | |
453 case ZMBV_FMT_16BPP: | |
454 c->bpp = 16; | |
455 c->decode_intra = zmbv_decode_intra; | |
456 c->decode_xor = zmbv_decode_xor_16; | |
457 break; | |
458 #ifdef ZMBV_ENABLE_24BPP | |
459 case ZMBV_FMT_24BPP: | |
460 c->bpp = 24; | |
461 c->decode_intra = zmbv_decode_intra; | |
462 c->decode_xor = zmbv_decode_xor_24; | |
463 break; | |
464 #endif //ZMBV_ENABLE_24BPP | |
465 case ZMBV_FMT_32BPP: | |
466 c->bpp = 32; | |
467 c->decode_intra = zmbv_decode_intra; | |
468 c->decode_xor = zmbv_decode_xor_32; | |
469 break; | |
470 default: | |
471 c->decode_intra = NULL; | |
472 c->decode_xor = NULL; | |
298 av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt); | 473 av_log(avctx, AV_LOG_ERROR, "Unsupported (for now) format %i\n", c->fmt); |
299 return -1; | 474 return -1; |
300 } | 475 } |
301 #ifdef CONFIG_ZLIB | 476 #ifdef CONFIG_ZLIB |
302 zret = inflateReset(&c->zstream); | 477 zret = inflateReset(&c->zstream); |
306 } | 481 } |
307 #else | 482 #else |
308 av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); | 483 av_log(avctx, AV_LOG_ERROR, "BUG! Zlib support not compiled in frame decoder.\n"); |
309 return -1; | 484 return -1; |
310 #endif /* CONFIG_ZLIB */ | 485 #endif /* CONFIG_ZLIB */ |
311 if(c->fmt == ZMBV_FMT_8BPP) { | |
312 c->bpp = 8; | |
313 c->decode_intra = zmbv_decode_intra; | |
314 c->decode_xor = zmbv_decode_xor_8; | |
315 } else { | |
316 c->bpp = 24; | |
317 c->decode_intra = zmbv_decode_intra; | |
318 c->decode_xor = zmbv_decode_xor_24; | |
319 } | |
320 c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8)); | 486 c->cur = av_realloc(c->cur, avctx->width * avctx->height * (c->bpp / 8)); |
321 c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8)); | 487 c->prev = av_realloc(c->prev, avctx->width * avctx->height * (c->bpp / 8)); |
322 c->bx = (c->width + c->bw - 1) / c->bw; | 488 c->bx = (c->width + c->bw - 1) / c->bw; |
323 c->by = (c->height+ c->bh - 1) / c->bh; | 489 c->by = (c->height+ c->bh - 1) / c->bh; |
324 } | 490 } |
325 | 491 |
326 if(c->fmt == 0) { | 492 if(c->decode_intra == NULL) { |
327 av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n"); | 493 av_log(avctx, AV_LOG_ERROR, "Error! Got no format or no keyframe!\n"); |
328 return -1; | 494 return -1; |
329 } | 495 } |
330 | 496 |
331 if(c->comp == 0) { //Uncompressed data | 497 if(c->comp == 0) { //Uncompressed data |
360 uint8_t *out, *src; | 526 uint8_t *out, *src; |
361 int i, j; | 527 int i, j; |
362 | 528 |
363 out = c->pic.data[0]; | 529 out = c->pic.data[0]; |
364 src = c->cur; | 530 src = c->cur; |
365 for(j = 0; j < c->height; j++) { | 531 switch(c->fmt) { |
366 for(i = 0; i < c->width; i++) { | 532 case ZMBV_FMT_8BPP: |
367 out[i * 3 + 0] = c->pal[(*src) * 3 + 0]; | 533 for(j = 0; j < c->height; j++) { |
368 out[i * 3 + 1] = c->pal[(*src) * 3 + 1]; | 534 for(i = 0; i < c->width; i++) { |
369 out[i * 3 + 2] = c->pal[(*src) * 3 + 2]; | 535 out[i * 3 + 0] = c->pal[(*src) * 3 + 0]; |
370 *src++; | 536 out[i * 3 + 1] = c->pal[(*src) * 3 + 1]; |
371 } | 537 out[i * 3 + 2] = c->pal[(*src) * 3 + 2]; |
372 out += c->pic.linesize[0]; | 538 *src++; |
373 } | 539 } |
374 memcpy(c->prev, c->cur, c->width * c->height); | 540 out += c->pic.linesize[0]; |
541 } | |
542 break; | |
543 case ZMBV_FMT_15BPP: | |
544 for(j = 0; j < c->height; j++) { | |
545 for(i = 0; i < c->width; i++) { | |
546 uint16_t tmp = LE_16(src); | |
547 src += 2; | |
548 out[i * 3 + 0] = (tmp & 0x7C00) >> 7; | |
549 out[i * 3 + 1] = (tmp & 0x03E0) >> 2; | |
550 out[i * 3 + 2] = (tmp & 0x001F) << 3; | |
551 } | |
552 out += c->pic.linesize[0]; | |
553 } | |
554 break; | |
555 case ZMBV_FMT_16BPP: | |
556 for(j = 0; j < c->height; j++) { | |
557 for(i = 0; i < c->width; i++) { | |
558 uint16_t tmp = LE_16(src); | |
559 src += 2; | |
560 out[i * 3 + 0] = (tmp & 0xF800) >> 8; | |
561 out[i * 3 + 1] = (tmp & 0x07E0) >> 3; | |
562 out[i * 3 + 2] = (tmp & 0x001F) << 3; | |
563 } | |
564 out += c->pic.linesize[0]; | |
565 } | |
566 break; | |
567 #ifdef ZMBV_ENABLE_24BPP | |
568 case ZMBV_FMT_24BPP: | |
569 for(j = 0; j < c->height; j++) { | |
570 memcpy(out, src, c->width * 3); | |
571 src += c->width * 3; | |
572 out += c->pic.linesize[0]; | |
573 } | |
574 break; | |
575 #endif //ZMBV_ENABLE_24BPP | |
576 case ZMBV_FMT_32BPP: | |
577 for(j = 0; j < c->height; j++) { | |
578 for(i = 0; i < c->width; i++) { | |
579 uint32_t tmp = LE_32(src); | |
580 src += 4; | |
581 out[i * 3 + 0] = tmp >> 16; | |
582 out[i * 3 + 1] = tmp >> 8; | |
583 out[i * 3 + 2] = tmp >> 0; | |
584 } | |
585 out += c->pic.linesize[0]; | |
586 } | |
587 break; | |
588 default: | |
589 av_log(avctx, AV_LOG_ERROR, "Cannot handle format %i\n", c->fmt); | |
590 } | |
591 memcpy(c->prev, c->cur, c->width * c->height * (c->bpp / 8)); | |
375 } | 592 } |
376 *data_size = sizeof(AVFrame); | 593 *data_size = sizeof(AVFrame); |
377 *(AVFrame*)data = c->pic; | 594 *(AVFrame*)data = c->pic; |
378 | 595 |
379 /* always report that the buffer was completely consumed */ | 596 /* always report that the buffer was completely consumed */ |