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