1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 #include "anim/packunpack.h"
13 #include "bmpman/bmpman.h"
14 #include "graphics/2d.h"
15 #include "anim/animplay.h"
16 
17 
18 const int packer_code = PACKER_CODE;
19 const int transparent_code = 254;
20 
anim_check_for_palette_change(anim_instance * instance)21 void anim_check_for_palette_change(anim_instance *instance) {
22 	if ( instance->parent->screen_sig != gr_screen.signature ) {
23 		instance->parent->screen_sig = gr_screen.signature;
24 		anim_set_palette(instance->parent);
25 	}
26 }
27 
init_anim_instance(anim * ptr,int bpp)28 anim_instance *init_anim_instance(anim *ptr, int bpp)
29 {
30 	anim_instance *inst;
31 
32 	if (!ptr) {
33 		Int3();
34 		return NULL;
35 	}
36 
37 	if ( ptr->flags & ANF_STREAMED ) {
38 		if ( ptr->file_offset < 0 ) {
39 			Int3();
40 			return NULL;
41 		}
42 	} else {
43 		if ( !ptr->data ) {
44 			Int3();
45 			return NULL;
46 		}
47 	}
48 
49 	ptr->instance_count++;
50 	inst = (anim_instance *) vm_malloc(sizeof(anim_instance));
51 	Assert(inst);
52 	memset(inst, 0, sizeof(anim_instance));
53 	inst->frame_num = -1;
54 	inst->last_frame_num = -1;
55 	inst->parent = ptr;
56 	inst->data = ptr->data;
57 	inst->file_offset = ptr->file_offset;
58 	inst->stop_now = FALSE;
59 	inst->aa_color = NULL;
60 
61 	inst->frame = (ubyte *) vm_malloc(inst->parent->width * inst->parent->height * (bpp >> 3));
62 	Assert( inst->frame != NULL );
63 	memset( inst->frame, 0, inst->parent->width * inst->parent->height * (bpp >> 3) );
64 
65 	return inst;
66 }
67 
free_anim_instance(anim_instance * inst)68 void free_anim_instance(anim_instance *inst)
69 {
70 	Assert(inst->frame);
71 	vm_free(inst->frame);
72 	inst->frame = NULL;
73 	inst->parent->instance_count--;
74 	inst->parent = NULL;
75 	inst->data = NULL;
76 	inst->file_offset = -1;
77 
78 	vm_free(inst);
79 }
80 
anim_get_next_frame(anim_instance * inst)81 int anim_get_next_frame(anim_instance *inst)
82 {
83 	int bm, bitmap_flags;
84 	int aabitmap = 0;
85 	int bpp = 16;
86 
87 	if ( anim_instance_is_streamed(inst) ) {
88 		if ( inst->file_offset <= 0 ) {
89 			return -1;
90 		}
91 	} else {
92 		if (!inst->data)
93 			return -1;
94 	}
95 
96 	inst->frame_num++;
97 	if (inst->frame_num >= inst->parent->total_frames) {
98 		inst->data = NULL;
99 		inst->file_offset = inst->parent->file_offset;
100 		return -1;
101 	}
102 
103 	bitmap_flags = 0;
104 
105 	bpp = 16;
106 	if(inst->aa_color != NULL){
107 		bitmap_flags |= BMP_AABITMAP;
108 		aabitmap = 1;
109 		bpp = 8;
110 	}
111 
112 	anim_check_for_palette_change(inst);
113 
114 	BM_SELECT_TEX_FORMAT();
115 
116 	if ( anim_instance_is_streamed(inst) ) {
117 		inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
118 	} else {
119 		inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
120 	}
121 
122 	bm = bm_create(bpp, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
123 	bm_unload(bm);
124 	return bm;
125 }
126 
anim_get_next_raw_buffer(anim_instance * inst,int xlate_pal,int aabitmap,int bpp)127 ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
128 {
129 	if ( anim_instance_is_streamed(inst) ) {
130 		if ( inst->file_offset < 0 ) {
131 			return NULL;
132 		}
133 	} else {
134 		if (!inst->data){
135 			return NULL;
136 		}
137 	}
138 
139 	inst->frame_num++;
140 	if (inst->frame_num >= inst->parent->total_frames) {
141 		inst->data = NULL;
142 		inst->file_offset = inst->parent->file_offset;
143 		return NULL;
144 	}
145 
146 	anim_check_for_palette_change(inst);
147 
148 	if ( anim_instance_is_streamed(inst) ) {
149 		if ( xlate_pal ){
150 			inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
151 		} else {
152 			inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
153 		}
154 	} else {
155 		if ( xlate_pal ){
156 			inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
157 		} else {
158 			inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
159 		}
160 	}
161 
162 	return inst->frame;
163 }
164 
165 /**
166  * @brief Pack key frame
167  *
168  * @param frame Frame pixel data to pack
169  * @param save Memory to store packed data to
170  * @param size Number of bytes to pack
171  * @param max Maximum number of packed bytes (size of buffer)
172  * @param compress_type Compress type
173  * @return Actual number of bytes data packed to or -1 if error
174  */
pack_key_frame(ubyte * frame,ubyte * save,long size,long max,int compress_type)175 int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
176 {
177 	int last = -32768, count = 0;
178 	long packed_size = 1;
179 
180 	switch ( compress_type ) {
181 		case PACKING_METHOD_RLE_KEY:
182 			*save++ = PACKING_METHOD_RLE_KEY;
183 			while (size--) {
184 				if (*frame != last || count > 255) {
185 					if (packed_size + 3 >= max)
186 						return -1;
187 
188 					if (count < 3) {
189 						if (last == packer_code) {
190 							*save++ = (ubyte)packer_code;
191 							*save++ = (ubyte)(count - 1);
192 							packed_size += 2;
193 
194 						} else
195 							while (count--) {
196 								*save++ = (ubyte)last;
197 								packed_size++;
198 							}
199 
200 					} else {
201 						*save++ = (ubyte)packer_code;
202 						*save++ = (ubyte)(count - 1);
203 						*save++ = (ubyte)last;
204 						packed_size += 3;
205 					}
206 
207 					count = 0;
208 					last = *frame;
209 				}
210 
211 				count++;
212 				frame++;
213 			}
214 
215 			if (packed_size + 3 >= max)
216 				return -1;
217 
218 			if (count < 3) {
219 				if (last == packer_code) {
220 					*save++ = (ubyte)packer_code;
221 					*save++ = (ubyte)(count - 1);
222 					packed_size += 2;
223 
224 				} else
225 					while (count--) {
226 						*save++ = (ubyte)last;
227 						packed_size++;
228 					}
229 
230 			} else {
231 				*save++ = (ubyte)packer_code;
232 				*save++ = (ubyte)(count - 1);
233 				*save++ = (ubyte)last;
234 				packed_size += 3;
235 			}
236 			break;
237 
238 		case PACKING_METHOD_STD_RLE_KEY: {
239 			ubyte *dest_start;
240 			int i;
241 
242 			dest_start = save;
243 			count = 1;
244 
245 			last = *frame++;
246 			*save++ = PACKING_METHOD_STD_RLE_KEY;
247 			for (i=1; i < size; i++ )	{
248 
249 				if ( *frame != last ) {
250 					if ( count ) {
251 
252 						if (packed_size + 2 >= max)
253 							return -1;
254 
255 						if ( (count == 1) && !(last & STD_RLE_CODE) ) {
256 							*save++ = (ubyte)last;
257 							packed_size++;
258 							Assert( last != STD_RLE_CODE );
259 						}
260 						else {
261 							count |= STD_RLE_CODE;
262 							*save++ = (ubyte)count;
263 							*save++ = (ubyte)last;
264 							packed_size += 2;
265 						}
266 					}
267 
268 					last = *frame;
269 					count = 0;
270 				}
271 
272 				count++;
273 				frame++;
274 
275 				if ( count == 127 ) {
276 					count |= STD_RLE_CODE;
277 					*save++ = (ubyte)count;
278 					*save++ = (ubyte)last;
279 					packed_size += 2;
280 					count = 0;
281 				}
282 			}	// end for
283 
284 			if (count)	{
285 
286 				if (packed_size + 2 >= max)
287 					return -1;
288 
289 				if ( (count == 1) && !(last & STD_RLE_CODE) ) {
290 					*save++ = (ubyte)last;
291 					packed_size++;
292 					Assert( last != STD_RLE_CODE );
293 				}
294 				else {
295 					count |= STD_RLE_CODE;
296 					*save++ = (ubyte)count;
297 					*save++ = (ubyte)last;
298 					packed_size += 2;
299 				}
300 			}
301 
302 			Assert(packed_size == (save-dest_start) );
303 			return packed_size;
304 			break;
305 			}
306 
307 		default:
308 			Assert(0);
309 			return -1;
310 			break;
311 	} // end switch
312 
313 	return packed_size;
314 }
315 
316 /**
317  * @brief Pack frame
318  *
319  * @param frame Frame pixel data to pack
320  * @param frame2 Previous frame's pixel data
321  * @param save Memory to store packed data to
322  * @param size Number of bytes to pack
323  * @param max Maximum number of packed bytes (size of buffer)
324  * @param compress_type Compress type
325  * @return Actual number of bytes data packed to or -1 if error
326  */
pack_frame(ubyte * frame,ubyte * frame2,ubyte * save,long size,long max,int compress_type)327 int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
328 {
329 	int pixel, last = -32768, count = 0, i;
330 	long packed_size = 1;
331 
332 	switch ( compress_type ) {
333 		case PACKING_METHOD_RLE:					// Hoffoss RLE regular frame
334 			*save++ = PACKING_METHOD_RLE;
335 			while (size--) {
336 				if (*frame != *frame2++)
337 					pixel = *frame;
338 				else
339 					pixel = transparent_code;
340 
341 				if (pixel != last || count > 255) {
342 					if (packed_size + 3 >= max)
343 						return -1;
344 
345 					if (count < 3) {
346 						if (last == packer_code) {
347 							*save++ = (ubyte)packer_code;
348 							*save++ = (ubyte)(count - 1);
349 							packed_size += 2;
350 
351 						} else
352 							while (count--) {
353 								*save++ = (ubyte)last;
354 								packed_size++;
355 							}
356 
357 					} else {
358 						*save++ = (ubyte)packer_code;
359 						*save++ = (ubyte)(count - 1);
360 						*save++ = (ubyte)last;
361 						packed_size += 3;
362 					}
363 
364 					count = 0;
365 					last = pixel;
366 				}
367 
368 				frame++;
369 				count++;
370 			}
371 
372 			if (packed_size + 3 >= max)
373 				return -1;
374 
375 			if (count < 3) {
376 				if (last == packer_code) {
377 					*save++ = (ubyte)packer_code;
378 					*save++ = (ubyte)(count - 1);
379 					packed_size += 2;
380 
381 				} else
382 					while (count--) {
383 						*save++ = (ubyte)last;
384 						packed_size++;
385 					}
386 
387 			} else {
388 				*save++ = (ubyte)(packer_code);
389 				*save++ = (ubyte)(count - 1);
390 				*save++ = (ubyte)(last);
391 				packed_size += 3;
392 			}
393 			break;
394 
395 		case PACKING_METHOD_STD_RLE: {		// high bit count regular RLE frame
396 
397 			ubyte *dest_start;
398 
399 			dest_start = save;
400 			count = 1;
401 
402 			if (*frame++ != *frame2++)
403 				last = *frame;
404 			else
405 				last = transparent_code;
406 
407 			*save++ = PACKING_METHOD_STD_RLE;
408 			for (i=1; i < size; i++ )	{
409 
410 				if (*frame != *frame2++)
411 					pixel = *frame;
412 				else
413 					pixel = transparent_code;
414 
415 				if ( pixel != last ) {
416 					if ( count ) {
417 
418 						if (packed_size + 2 >= max)
419 							return -1;
420 
421 						if ( (count == 1) && !(last & STD_RLE_CODE) ) {
422 							*save++ = (ubyte)last;
423 							packed_size++;
424 							Assert( last != STD_RLE_CODE );
425 						}
426 						else {
427 							count |= STD_RLE_CODE;
428 							*save++ = (ubyte)count;
429 							*save++ = (ubyte)last;
430 							packed_size += 2;
431 						}
432 					}
433 
434 					last = pixel;
435 					count = 0;
436 				}
437 
438 				count++;
439 				frame++;
440 
441 				if ( count == 127 ) {
442 					count |= STD_RLE_CODE;
443 					*save++ = (ubyte)count;
444 					*save++ = (ubyte)last;
445 					packed_size += 2;
446 					count = 0;
447 				}
448 			}	// end for
449 
450 			if (count)	{
451 
452 				if (packed_size + 2 >= max)
453 					return -1;
454 
455 				if ( (count == 1) && !(last & STD_RLE_CODE) ) {
456 					*save++ = (ubyte)last;
457 					packed_size++;
458 					Assert( last != STD_RLE_CODE );
459 				}
460 				else {
461 					count |= STD_RLE_CODE;
462 					*save++ = (ubyte)count;
463 					*save++ = (ubyte)last;
464 					packed_size += 2;
465 				}
466 			}
467 
468 			Assert(packed_size == (save-dest_start) );
469 			return packed_size;
470 			break;
471 			}
472 
473 		default:
474 			Assert(0);
475 			return -1;
476 			break;
477 	} // end switch
478 
479 	return packed_size;
480 }
481 
482 /**
483  * @brief Convert a 24 bit value to a 16 bit value
484  * @param bit_24 24 bit value
485  * @param bit_16 16 bit value (output)
486  */
convert_24_to_16(int bit_24,ushort * bit_16)487 void convert_24_to_16(int bit_24, ushort *bit_16)
488 {
489 	ubyte *pixel = (ubyte*)&bit_24;
490 	ubyte alpha = 1;
491 
492 	bm_set_components((ubyte*)bit_16, (ubyte*)&pixel[0], (ubyte*)&pixel[1], (ubyte*)&pixel[2], &alpha);
493 }
494 
495 /**
496  * @brief Unpack a pixel given the passed index and the anim_instance's palette
497  * @return Bytes stuffed
498  */
unpack_pixel(anim_instance * ai,ubyte * data,ubyte pix,int aabitmap,int bpp)499 int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
500 {
501 	int bit_24;
502 	ushort bit_16 = 0;
503 	ubyte bit_8 = 0;
504 	ubyte al = 0;
505 	ubyte r, g, b;
506 	int pixel_size = (bpp / 8);
507 	anim *a = ai->parent;
508 	Assert(a);
509 
510 	// if this is an aabitmap, don't run through the palette
511 	if(aabitmap){
512 		switch(bpp){
513 		case 16 :
514 			bit_16 = (ushort)pix;
515 			break;
516 		case 8:
517 			bit_8 = pix;
518 			break;
519 		default:
520 			Int3();
521 		}
522 	} else {
523 		// if the pixel value is 255, or is the xparent color, make it so
524 		if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
525 			if (pixel_size > 2) {
526 				bit_24 = 0;
527 			} else {
528 				r = b = 0;
529 				g = 255;
530 
531 				bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
532 			}
533 		} else {
534 			if (pixel_size > 2) {
535 				ubyte pixel[4];
536 				pixel[0] = ai->parent->palette[pix * 3 + 2];
537 				pixel[1] = ai->parent->palette[pix * 3 + 1];
538 				pixel[2] = ai->parent->palette[pix * 3];
539 				pixel[3] = 255;
540 				memcpy(&bit_24, pixel, sizeof(int));
541 
542 				if (pixel_size == 4) {
543 					bit_24 = INTEL_INT(bit_24);
544 				}
545 			} else {
546 				// stuff the 24 bit value
547 				memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
548 
549 				// convert to 16 bit
550 				convert_24_to_16(bit_24, &bit_16);
551 			}
552 		}
553 	}
554 
555 	// stuff the pixel
556 	switch (bpp) {
557 		case 32:
558 		case 24:
559 			memcpy(data, &bit_24, pixel_size);
560 			break;
561 
562 		case 16:
563 			memcpy(data, &bit_16, pixel_size);
564 			break;
565 
566 		case 8:
567 			*data = bit_8;
568 			break;
569 
570 		default:
571 			Int3();
572 			return 0;
573 	}
574 
575 	return pixel_size;
576 }
577 
578 /**
579  * @brief Unpack a pixel given the passed index and the anim_instance's palette
580  * @return Bytes stuffed
581  */
unpack_pixel_count(anim_instance * ai,ubyte * data,ubyte pix,int count=0,int aabitmap=0,int bpp=8)582 int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0, int aabitmap = 0, int bpp = 8)
583 {
584 	int bit_24;
585 	int idx;
586 	ubyte al = 0;
587 	ushort bit_16 = 0;
588 	ubyte bit_8 = 0;
589 	anim *a = ai->parent;
590 	int pixel_size = (bpp / 8);
591 	ubyte r, g, b;
592 	Assert(a);
593 
594 	// if this is an aabitmap, don't run through the palette
595 	if(aabitmap){
596 		switch(bpp){
597 		case 16 :
598 			bit_16 = (ushort)pix;
599 			break;
600 		case 8 :
601 			bit_8 = pix;
602 			break;
603 		default :
604 			Int3();
605 		}
606 	} else {
607 		// if the pixel value is 255, or is the xparent color, make it so
608 		if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
609 			if (pixel_size > 2) {
610 				bit_24 = 0;
611 			} else {
612 				r = b = 0;
613 				g = 255;
614 
615 				bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
616 			}
617 		} else {
618 			if (pixel_size > 2) {
619 				ubyte pixel[4];
620 				pixel[0] = ai->parent->palette[pix * 3 + 2];
621 				pixel[1] = ai->parent->palette[pix * 3 + 1];
622 				pixel[2] = ai->parent->palette[pix * 3];
623 				pixel[3] = 255;
624 				memcpy(&bit_24, pixel, sizeof(int));
625 
626 				if (pixel_size == 4) {
627 					bit_24 = INTEL_INT(bit_24);
628 				}
629 			} else {
630 				// stuff the 24 bit value
631 				memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
632 
633 				// convert to 16 bit
634 				convert_24_to_16(bit_24, &bit_16);
635 			}
636 		}
637 	}
638 
639 	// stuff the pixel
640 	for (idx=0; idx<count; idx++) {
641 		switch (bpp) {
642 			case 32:
643 			case 24:
644 				memcpy(data + (idx * pixel_size), &bit_24, pixel_size);
645 				break;
646 
647 			case 16:
648 				memcpy(data + (idx * pixel_size), &bit_16, pixel_size);
649 				break;
650 
651 			case 8:
652 				*(data + idx) = bit_8;
653 				break;
654 			}
655 	}
656 
657 	return (pixel_size * count);
658 }
659 
660 /**
661  * @brief Unpack frame
662  *
663  * @param ai Animation instance
664  * @param ptr Packed data to unpack
665  * @param frame Where to store unpacked data to
666  * @param size Total number of unpacked pixels requested
667  * @param pal_translate Color translation lookup table (NULL if no palette translation desired)
668  * @param aabitmap
669  * @param bpp
670  */
unpack_frame(anim_instance * ai,ubyte * ptr,ubyte * frame,int size,ubyte * pal_translate,int aabitmap,int bpp)671 ubyte	*unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
672 {
673 	int	xlate_pal, value, count = 0;
674 	int stuffed;
675 	int pixel_size = (bpp / 8);
676 
677 	if ( pal_translate == NULL ) {
678 		xlate_pal = 0;
679 	}
680 	else {
681 		xlate_pal = 1;
682 	}
683 
684 	if (*ptr == PACKING_METHOD_RLE_KEY) {  // key frame, Hoffoss's RLE format
685 		ptr++;
686 		while (size > 0) {
687 			value = *ptr++;
688 			if (value != packer_code) {
689 				if ( xlate_pal ){
690 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
691 				} else {
692 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
693 				}
694 				frame += stuffed;
695 				size--;
696 			} else {
697 				count = *ptr++;
698 				if (count < 2){
699 					value = packer_code;
700 				} else {
701 					value = *ptr++;
702 				}
703 
704 				if (++count > size){
705 					count = size;
706 				}
707 
708 				if ( xlate_pal ){
709 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
710 				} else {
711 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
712 				}
713 
714 				frame += stuffed;
715 				size -= count;
716 			}
717 		}
718 	}
719 	else if ( *ptr == PACKING_METHOD_STD_RLE_KEY) {	// key frame, with high bit as count
720 		ptr++;
721 		while (size > 0) {
722 			value = *ptr++;
723 			if ( !(value & STD_RLE_CODE) ) {
724 				if ( xlate_pal ){
725 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
726 				} else {
727 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
728 				}
729 
730 				frame += stuffed;
731 				size--;
732 			} else {
733 				count = value & (~STD_RLE_CODE);
734 				value = *ptr++;
735 
736 				if (count > size)
737 					count = size;
738 
739 				size -= count;
740 				Assert(size >= 0);
741 
742 				if ( xlate_pal ){
743 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
744 				} else {
745 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
746 				}
747 
748 				frame += stuffed;
749 			}
750 		}
751 	}
752 	else if (*ptr == PACKING_METHOD_RLE) {  // normal frame, Hoffoss's RLE format
753 
754 		ptr++;
755 		while (size > 0) {
756 			value = *ptr++;
757 			if (value != packer_code) {
758 				if (value != transparent_code) {
759 					if ( xlate_pal ){
760 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
761 					} else {
762 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
763 					}
764 				} else {
765 					// temporary pixel
766 					stuffed = pixel_size;
767 				}
768 
769 				frame += stuffed;
770 				size--;
771 			} else {
772 				count = *ptr++;
773 				if (count < 2){
774 					value = packer_code;
775 				} else {
776 					value = *ptr++;
777 				}
778 
779 				if (++count > size){
780 					count = size;
781 				}
782 
783 				size -= count;
784 				Assert(size >= 0);
785 
786 				if (value != transparent_code ) {
787 					if ( xlate_pal ) {
788 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
789 					} else {
790 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
791 					}
792 				} else {
793 					stuffed = count * pixel_size;
794 				}
795 
796 				frame += stuffed;
797 			}
798 		}
799 
800 	}
801 	else if ( *ptr == PACKING_METHOD_STD_RLE) {	// normal frame, with high bit as count
802 		ptr++;
803 		while (size > 0) {
804 			value = *ptr++;
805 			if ( !(value & STD_RLE_CODE) ) {
806 				if (value != transparent_code) {
807 					if ( xlate_pal ){
808 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
809 					} else {
810 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
811 					}
812 				} else {
813 					stuffed = pixel_size;
814 				}
815 
816 				frame += stuffed;
817 				size--;
818 			} else {
819 				count = value & (~STD_RLE_CODE);
820 				value = *ptr++;
821 
822 				if (count > size)
823 					count = size;
824 
825 				size -= count;
826 				Assert(size >= 0);
827 
828 				if (value != transparent_code) {
829 					if ( xlate_pal ){
830 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
831 					} else {
832 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
833 					}
834 				} else {
835 					stuffed = pixel_size * count;
836 				}
837 
838 				frame += stuffed;
839 			}
840 		}
841 	}
842 	else {
843 		// unknown packing method
844 		return NULL;
845 	}
846 
847 	return ptr;
848 }
849 
850 /**
851  * @brief Unpack frame from file
852  *
853  * @param ai Animation instance
854  * @param frame Where to store unpacked data to
855  * @param size Total number of unpacked pixels requested
856  * @param pal_translate Color translation lookup table (NULL if no palette translation desired)
857  * @param aabitmap
858  * @param bpp
859  */
unpack_frame_from_file(anim_instance * ai,ubyte * frame,int size,ubyte * pal_translate,int aabitmap,int bpp)860 int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
861 {
862 	int	xlate_pal, value, count = 0;
863 	int	offset = 0;
864 	int stuffed;
865 	int pixel_size = (bpp / 8);
866 
867 	if ( pal_translate == NULL ) {
868 		xlate_pal = 0;
869 	}
870 	else {
871 		xlate_pal = 1;
872 	}
873 
874 	if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE_KEY) {  // key frame, Hoffoss's RLE format
875 		offset++;
876 		while (size > 0) {
877 			value = anim_instance_get_byte(ai,offset);
878 			offset++;
879 			if (value != packer_code) {
880 				if ( xlate_pal ){
881 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
882 				} else {
883 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
884 				}
885 
886 				frame += stuffed;
887 				size--;
888 			} else {
889 				count = anim_instance_get_byte(ai,offset);
890 				offset++;
891 				if (count < 2) {
892 					value = packer_code;
893 				} else {
894 					value = anim_instance_get_byte(ai,offset);
895 					offset++;
896 				}
897 
898 				if (++count > size){
899 					count = size;
900 				}
901 
902 				if ( xlate_pal ){
903 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
904 				} else {
905 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
906 				}
907 
908 				frame += stuffed;
909 				size -= count;
910 			}
911 		}
912 	}
913 	else if ( anim_instance_get_byte(ai,offset) == PACKING_METHOD_STD_RLE_KEY) {	// key frame, with high bit as count
914 		offset++;
915 		while (size > 0) {
916 			value = anim_instance_get_byte(ai,offset);
917 			offset++;
918 			if ( !(value & STD_RLE_CODE) ) {
919 				if ( xlate_pal ){
920 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
921 				} else {
922 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
923 				}
924 
925 				frame += stuffed;
926 				size--;
927 			} else {
928 				count = value & (~STD_RLE_CODE);
929 				value = anim_instance_get_byte(ai,offset);
930 				offset++;
931 
932 				if (count > size)
933 					count = size;
934 
935 				size -= count;
936 				Assert(size >= 0);
937 
938 				if ( xlate_pal ){
939 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
940 				} else {
941 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
942 				}
943 
944 				frame += stuffed;
945 			}
946 		}
947 	}
948 	else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) {  // normal frame, Hoffoss's RLE format
949 
950 		offset++;
951 		while (size > 0) {
952 			value = anim_instance_get_byte(ai,offset);
953 			offset++;
954 			if (value != packer_code) {
955 				if (value != transparent_code) {
956 					if ( xlate_pal ){
957 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
958 					} else {
959 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
960 					}
961 				} else {
962 					stuffed = pixel_size;
963 				}
964 
965 				frame += stuffed;
966 				size--;
967 			} else {
968 				count = anim_instance_get_byte(ai,offset);
969 				offset++;
970 
971 				if (count < 2) {
972 					value = packer_code;
973 				} else {
974 					value = anim_instance_get_byte(ai,offset);
975 					offset++;
976 				}
977 				if (++count > size){
978 					count = size;
979 				}
980 
981 				size -= count;
982 				Assert(size >= 0);
983 
984 				if (value != transparent_code ) {
985 					if ( xlate_pal ) {
986 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
987 					} else {
988 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
989 					}
990 				} else {
991 					stuffed = pixel_size * count;
992 				}
993 
994 				frame += stuffed;
995 			}
996 		}
997 
998 	}
999 	else if ( anim_instance_get_byte(ai,offset) ) {	// normal frame, with high bit as count
1000 		offset++;
1001 		while (size > 0) {
1002 			value = anim_instance_get_byte(ai,offset);
1003 			offset++;
1004 			if ( !(value & STD_RLE_CODE) ) {
1005 				if (value != transparent_code) {
1006 					if ( xlate_pal ){
1007 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1008 					} else {
1009 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1010 					}
1011 				} else {
1012 					stuffed = pixel_size;
1013 				}
1014 
1015 				frame += stuffed;
1016 				size--;
1017 			} else {
1018 				count = value & (~STD_RLE_CODE);
1019 				value = anim_instance_get_byte(ai,offset);
1020 				offset++;
1021 
1022 				if (count > size)
1023 					count = size;
1024 
1025 				size -= count;
1026 				Assert(size >= 0);
1027 
1028 				if (value != transparent_code) {
1029 					if ( xlate_pal ){
1030 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1031 					} else {
1032 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1033 					}
1034 				} else {
1035 					stuffed = pixel_size * count;
1036 				}
1037 
1038 				frame += stuffed;
1039 			}
1040 		}
1041 	}
1042 	else {
1043 		// unknown packing method
1044 		return -1;
1045 	}
1046 
1047 	return ai->file_offset + offset;
1048 }
1049 
1050 
1051 /**
1052  * @brief Set animation palette
1053  * @todo Actually convert the frame data to correct palette at this point
1054  */
anim_set_palette(anim * ptr)1055 void anim_set_palette(anim *ptr)
1056 {
1057 	int i, xparent_found = 0;
1058 
1059 	// create the palette translation look-up table
1060 	for ( i = 0; i < 256; i++ ) {
1061 		ptr->palette_translation[i] = (ubyte)i;
1062 	}
1063 
1064 	if ( xparent_found ) {
1065 		ptr->flags |= ANF_XPARENT;
1066 	}
1067 	else {
1068 		ptr->flags &= ~ANF_XPARENT;
1069 	}
1070 }
1071