FS2_Open
Open source remastering of the Freespace 2 engine
packunpack.cpp
Go to the documentation of this file.
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/animplay.h"
13 #include "anim/packunpack.h"
14 #include "bmpman/bmpman.h"
15 #include "graphics/2d.h"
16 
17 
19 const int transparent_code = 254;
20 
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 
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 
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 
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 
113 
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 
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 
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 
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 ) {
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 
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  }
305 
306  default:
307  Assert(0);
308  return -1;
309  break;
310  } // end switch
311 
312  return packed_size;
313 }
314 
326 int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
327 {
328  int pixel, last = -32768, count = 0, i;
329  long packed_size = 1;
330 
331  switch ( compress_type ) {
332  case PACKING_METHOD_RLE: // Hoffoss RLE regular frame
333  *save++ = PACKING_METHOD_RLE;
334  while (size--) {
335  if (*frame != *frame2++)
336  pixel = *frame;
337  else
338  pixel = transparent_code;
339 
340  if (pixel != last || count > 255) {
341  if (packed_size + 3 >= max)
342  return -1;
343 
344  if (count < 3) {
345  if (last == packer_code) {
346  *save++ = (ubyte)packer_code;
347  *save++ = (ubyte)(count - 1);
348  packed_size += 2;
349 
350  } else
351  while (count--) {
352  *save++ = (ubyte)last;
353  packed_size++;
354  }
355 
356  } else {
357  *save++ = (ubyte)packer_code;
358  *save++ = (ubyte)(count - 1);
359  *save++ = (ubyte)last;
360  packed_size += 3;
361  }
362 
363  count = 0;
364  last = pixel;
365  }
366 
367  frame++;
368  count++;
369  }
370 
371  if (packed_size + 3 >= max)
372  return -1;
373 
374  if (count < 3) {
375  if (last == packer_code) {
376  *save++ = (ubyte)packer_code;
377  *save++ = (ubyte)(count - 1);
378  packed_size += 2;
379 
380  } else
381  while (count--) {
382  *save++ = (ubyte)last;
383  packed_size++;
384  }
385 
386  } else {
387  *save++ = (ubyte)(packer_code);
388  *save++ = (ubyte)(count - 1);
389  *save++ = (ubyte)(last);
390  packed_size += 3;
391  }
392  break;
393 
394  case PACKING_METHOD_STD_RLE: { // high bit count regular RLE frame
395 
396  ubyte *dest_start;
397 
398  dest_start = save;
399  count = 1;
400 
401  if (*frame++ != *frame2++)
402  last = *frame;
403  else
404  last = transparent_code;
405 
406  *save++ = PACKING_METHOD_STD_RLE;
407  for (i=1; i < size; i++ ) {
408 
409  if (*frame != *frame2++)
410  pixel = *frame;
411  else
412  pixel = transparent_code;
413 
414  if ( pixel != last ) {
415  if ( count ) {
416 
417  if (packed_size + 2 >= max)
418  return -1;
419 
420  if ( (count == 1) && !(last & STD_RLE_CODE) ) {
421  *save++ = (ubyte)last;
422  packed_size++;
423  Assert( last != STD_RLE_CODE );
424  }
425  else {
426  count |= STD_RLE_CODE;
427  *save++ = (ubyte)count;
428  *save++ = (ubyte)last;
429  packed_size += 2;
430  }
431  }
432 
433  last = pixel;
434  count = 0;
435  }
436 
437  count++;
438  frame++;
439 
440  if ( count == 127 ) {
441  count |= STD_RLE_CODE;
442  *save++ = (ubyte)count;
443  *save++ = (ubyte)last;
444  packed_size += 2;
445  count = 0;
446  }
447  } // end for
448 
449  if (count) {
450 
451  if (packed_size + 2 >= max)
452  return -1;
453 
454  if ( (count == 1) && !(last & STD_RLE_CODE) ) {
455  *save++ = (ubyte)last;
456  packed_size++;
457  Assert( last != STD_RLE_CODE );
458  }
459  else {
460  count |= STD_RLE_CODE;
461  *save++ = (ubyte)count;
462  *save++ = (ubyte)last;
463  packed_size += 2;
464  }
465  }
466 
467  Assert(packed_size == (save-dest_start) );
468  return packed_size;
469  }
470 
471  default:
472  Assert(0);
473  return -1;
474  break;
475  } // end switch
476 
477  return packed_size;
478 }
479 
485 void convert_24_to_16(int bit_24, ushort *bit_16)
486 {
487  ubyte *pixel = (ubyte*)&bit_24;
488  ubyte alpha = 1;
489 
490  bm_set_components((ubyte*)bit_16, (ubyte*)&pixel[0], (ubyte*)&pixel[1], (ubyte*)&pixel[2], &alpha);
491 }
492 
497 int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
498 {
499  int bit_24;
500  ushort bit_16 = 0;
501  ubyte bit_8 = 0;
502  ubyte al = 0;
503  ubyte r, g, b;
504  int pixel_size = (bpp / 8);
505  anim *a = ai->parent;
506  Assert(a);
507 
508  // if this is an aabitmap, don't run through the palette
509  if(aabitmap){
510  switch(bpp){
511  case 16 :
512  bit_16 = (ushort)pix;
513  break;
514  case 8:
515  bit_8 = pix;
516  break;
517  default:
518  Int3();
519  }
520  } else {
521  // if the pixel value is 255, or is the xparent color, make it so
522  if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
523  if (pixel_size > 2) {
524  bit_24 = 0;
525  } else {
526  r = b = 0;
527  g = 255;
528 
529  bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
530  }
531  } else {
532  if (pixel_size > 2) {
533  ubyte pixel[4];
534  pixel[0] = ai->parent->palette[pix * 3 + 2];
535  pixel[1] = ai->parent->palette[pix * 3 + 1];
536  pixel[2] = ai->parent->palette[pix * 3];
537  pixel[3] = 255;
538  memcpy(&bit_24, pixel, sizeof(int));
539 
540  if (pixel_size == 4) {
541  bit_24 = INTEL_INT(bit_24);
542  }
543  } else {
544  // stuff the 24 bit value
545  memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
546 
547  // convert to 16 bit
548  convert_24_to_16(bit_24, &bit_16);
549  }
550  }
551  }
552 
553  // stuff the pixel
554  switch (bpp) {
555  case 32:
556  case 24:
557  memcpy(data, &bit_24, pixel_size);
558  break;
559 
560  case 16:
561  memcpy(data, &bit_16, pixel_size);
562  break;
563 
564  case 8:
565  *data = bit_8;
566  break;
567 
568  default:
569  Int3();
570  return 0;
571  }
572 
573  return pixel_size;
574 }
575 
580 int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0, int aabitmap = 0, int bpp = 8)
581 {
582  int bit_24;
583  int idx;
584  ubyte al = 0;
585  ushort bit_16 = 0;
586  ubyte bit_8 = 0;
587  anim *a = ai->parent;
588  int pixel_size = (bpp / 8);
589  ubyte r, g, b;
590  Assert(a);
591 
592  // if this is an aabitmap, don't run through the palette
593  if(aabitmap){
594  switch(bpp){
595  case 16 :
596  bit_16 = (ushort)pix;
597  break;
598  case 8 :
599  bit_8 = pix;
600  break;
601  default :
602  Int3();
603  }
604  } else {
605  // if the pixel value is 255, or is the xparent color, make it so
606  if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
607  if (pixel_size > 2) {
608  bit_24 = 0;
609  } else {
610  r = b = 0;
611  g = 255;
612 
613  bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
614  }
615  } else {
616  if (pixel_size > 2) {
617  ubyte pixel[4];
618  pixel[0] = ai->parent->palette[pix * 3 + 2];
619  pixel[1] = ai->parent->palette[pix * 3 + 1];
620  pixel[2] = ai->parent->palette[pix * 3];
621  pixel[3] = 255;
622  memcpy(&bit_24, pixel, sizeof(int));
623 
624  if (pixel_size == 4) {
625  bit_24 = INTEL_INT(bit_24);
626  }
627  } else {
628  // stuff the 24 bit value
629  memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
630 
631  // convert to 16 bit
632  convert_24_to_16(bit_24, &bit_16);
633  }
634  }
635  }
636 
637  // stuff the pixel
638  for (idx=0; idx<count; idx++) {
639  switch (bpp) {
640  case 32:
641  case 24:
642  memcpy(data + (idx * pixel_size), &bit_24, pixel_size);
643  break;
644 
645  case 16:
646  memcpy(data + (idx * pixel_size), &bit_16, pixel_size);
647  break;
648 
649  case 8:
650  *(data + idx) = bit_8;
651  break;
652  }
653  }
654 
655  return (pixel_size * count);
656 }
657 
669 ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
670 {
671  int xlate_pal, value, count = 0;
672  int stuffed;
673  int pixel_size = (bpp / 8);
674 
675  if ( pal_translate == NULL ) {
676  xlate_pal = 0;
677  }
678  else {
679  xlate_pal = 1;
680  }
681 
682  if (*ptr == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
683  ptr++;
684  while (size > 0) {
685  value = *ptr++;
686  if (value != packer_code) {
687  if ( xlate_pal ){
688  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
689  } else {
690  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
691  }
692  frame += stuffed;
693  size--;
694  } else {
695  count = *ptr++;
696  if (count < 2){
697  value = packer_code;
698  } else {
699  value = *ptr++;
700  }
701 
702  if (++count > size){
703  count = size;
704  }
705 
706  if ( xlate_pal ){
707  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
708  } else {
709  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
710  }
711 
712  frame += stuffed;
713  size -= count;
714  }
715  }
716  }
717  else if ( *ptr == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
718  ptr++;
719  while (size > 0) {
720  value = *ptr++;
721  if ( !(value & STD_RLE_CODE) ) {
722  if ( xlate_pal ){
723  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
724  } else {
725  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
726  }
727 
728  frame += stuffed;
729  size--;
730  } else {
731  count = value & (~STD_RLE_CODE);
732  value = *ptr++;
733 
734  if (count > size)
735  count = size;
736 
737  size -= count;
738  Assert(size >= 0);
739 
740  if ( xlate_pal ){
741  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
742  } else {
743  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
744  }
745 
746  frame += stuffed;
747  }
748  }
749  }
750  else if (*ptr == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
751 
752  ptr++;
753  while (size > 0) {
754  value = *ptr++;
755  if (value != packer_code) {
756  if (value != transparent_code) {
757  if ( xlate_pal ){
758  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
759  } else {
760  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
761  }
762  } else {
763  // temporary pixel
764  stuffed = pixel_size;
765  }
766 
767  frame += stuffed;
768  size--;
769  } else {
770  count = *ptr++;
771  if (count < 2){
772  value = packer_code;
773  } else {
774  value = *ptr++;
775  }
776 
777  if (++count > size){
778  count = size;
779  }
780 
781  size -= count;
782  Assert(size >= 0);
783 
784  if (value != transparent_code ) {
785  if ( xlate_pal ) {
786  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
787  } else {
788  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
789  }
790  } else {
791  stuffed = count * pixel_size;
792  }
793 
794  frame += stuffed;
795  }
796  }
797 
798  }
799  else if ( *ptr == PACKING_METHOD_STD_RLE) { // normal frame, with high bit as count
800  ptr++;
801  while (size > 0) {
802  value = *ptr++;
803  if ( !(value & STD_RLE_CODE) ) {
804  if (value != transparent_code) {
805  if ( xlate_pal ){
806  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
807  } else {
808  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
809  }
810  } else {
811  stuffed = pixel_size;
812  }
813 
814  frame += stuffed;
815  size--;
816  } else {
817  count = value & (~STD_RLE_CODE);
818  value = *ptr++;
819 
820  if (count > size)
821  count = size;
822 
823  size -= count;
824  Assert(size >= 0);
825 
826  if (value != transparent_code) {
827  if ( xlate_pal ){
828  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
829  } else {
830  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
831  }
832  } else {
833  stuffed = pixel_size * count;
834  }
835 
836  frame += stuffed;
837  }
838  }
839  }
840  else {
841  // unknown packing method
842  return NULL;
843  }
844 
845  return ptr;
846 }
847 
858 int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
859 {
860  int xlate_pal, value, count = 0;
861  int offset = 0;
862  int stuffed;
863  int pixel_size = (bpp / 8);
864 
865  if ( pal_translate == NULL ) {
866  xlate_pal = 0;
867  }
868  else {
869  xlate_pal = 1;
870  }
871 
872  if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
873  offset++;
874  while (size > 0) {
875  value = anim_instance_get_byte(ai,offset);
876  offset++;
877  if (value != packer_code) {
878  if ( xlate_pal ){
879  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
880  } else {
881  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
882  }
883 
884  frame += stuffed;
885  size--;
886  } else {
887  count = anim_instance_get_byte(ai,offset);
888  offset++;
889  if (count < 2) {
890  value = packer_code;
891  } else {
892  value = anim_instance_get_byte(ai,offset);
893  offset++;
894  }
895 
896  if (++count > size){
897  count = size;
898  }
899 
900  if ( xlate_pal ){
901  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
902  } else {
903  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
904  }
905 
906  frame += stuffed;
907  size -= count;
908  }
909  }
910  }
911  else if ( anim_instance_get_byte(ai,offset) == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
912  offset++;
913  while (size > 0) {
914  value = anim_instance_get_byte(ai,offset);
915  offset++;
916  if ( !(value & STD_RLE_CODE) ) {
917  if ( xlate_pal ){
918  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
919  } else {
920  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
921  }
922 
923  frame += stuffed;
924  size--;
925  } else {
926  count = value & (~STD_RLE_CODE);
927  value = anim_instance_get_byte(ai,offset);
928  offset++;
929 
930  if (count > size)
931  count = size;
932 
933  size -= count;
934  Assert(size >= 0);
935 
936  if ( xlate_pal ){
937  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
938  } else {
939  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
940  }
941 
942  frame += stuffed;
943  }
944  }
945  }
946  else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
947 
948  offset++;
949  while (size > 0) {
950  value = anim_instance_get_byte(ai,offset);
951  offset++;
952  if (value != packer_code) {
953  if (value != transparent_code) {
954  if ( xlate_pal ){
955  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
956  } else {
957  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
958  }
959  } else {
960  stuffed = pixel_size;
961  }
962 
963  frame += stuffed;
964  size--;
965  } else {
966  count = anim_instance_get_byte(ai,offset);
967  offset++;
968 
969  if (count < 2) {
970  value = packer_code;
971  } else {
972  value = anim_instance_get_byte(ai,offset);
973  offset++;
974  }
975  if (++count > size){
976  count = size;
977  }
978 
979  size -= count;
980  Assert(size >= 0);
981 
982  if (value != transparent_code ) {
983  if ( xlate_pal ) {
984  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
985  } else {
986  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
987  }
988  } else {
989  stuffed = pixel_size * count;
990  }
991 
992  frame += stuffed;
993  }
994  }
995 
996  }
997  else if ( anim_instance_get_byte(ai,offset) ) { // normal frame, with high bit as count
998  offset++;
999  while (size > 0) {
1000  value = anim_instance_get_byte(ai,offset);
1001  offset++;
1002  if ( !(value & STD_RLE_CODE) ) {
1003  if (value != transparent_code) {
1004  if ( xlate_pal ){
1005  stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
1006  } else {
1007  stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
1008  }
1009  } else {
1010  stuffed = pixel_size;
1011  }
1012 
1013  frame += stuffed;
1014  size--;
1015  } else {
1016  count = value & (~STD_RLE_CODE);
1017  value = anim_instance_get_byte(ai,offset);
1018  offset++;
1019 
1020  if (count > size)
1021  count = size;
1022 
1023  size -= count;
1024  Assert(size >= 0);
1025 
1026  if (value != transparent_code) {
1027  if ( xlate_pal ){
1028  stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
1029  } else {
1030  stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
1031  }
1032  } else {
1033  stuffed = pixel_size * count;
1034  }
1035 
1036  frame += stuffed;
1037  }
1038  }
1039  }
1040  else {
1041  // unknown packing method
1042  return -1;
1043  }
1044 
1045  return ai->file_offset + offset;
1046 }
1047 
1048 
1054 {
1055  int i, xparent_found = 0;
1056 
1057  // create the palette translation look-up table
1058  for ( i = 0; i < 256; i++ ) {
1059  ptr->palette_translation[i] = (ubyte)i;
1060  }
1061 
1062  if ( xparent_found ) {
1063  ptr->flags |= ANF_XPARENT;
1064  }
1065  else {
1066  ptr->flags &= ~ANF_XPARENT;
1067  }
1068 }
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
Unpack frame from file.
Definition: packunpack.cpp:858
int height
Definition: packunpack.h:44
int i
Definition: multi_pxo.cpp:466
#define vm_free(ptr)
Definition: pstypes.h:548
int last_frame_num
Definition: packunpack.h:78
int instance_count
Definition: packunpack.h:46
GLsizei const GLfloat * value
Definition: Glext.h:5646
#define PACKING_METHOD_STD_RLE
Definition: packunpack.h:24
Assert(pm!=NULL)
ubyte * frame
Definition: packunpack.h:81
void anim_set_palette(anim *ptr)
Set animation palette.
int total_frames
Definition: packunpack.h:45
void * aa_color
Definition: packunpack.h:91
ubyte xparent_g
Definition: packunpack.h:58
int flags
Definition: packunpack.h:60
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
Pack key frame.
Definition: packunpack.cpp:175
ubyte palette_translation[256]
Definition: packunpack.h:52
GLsizeiptr size
Definition: Glext.h:5496
#define Int3()
Definition: pstypes.h:292
unsigned char anim_instance_get_byte(anim_instance *ai, int offset)
Definition: animplay.cpp:1073
void free_anim_instance(anim_instance *inst)
Definition: packunpack.cpp:68
void BM_SELECT_TEX_FORMAT()
Sets bm_set_components and bm_get_components to reference texture format functions.
Definition: bmpman.cpp:2745
#define BMP_AABITMAP
antialiased bitmap
Definition: bmpman.h:52
uint signature
Definition: 2d.h:359
ubyte xparent_r
Definition: packunpack.h:57
GLintptr offset
Definition: Glext.h:5497
GLdouble GLdouble GLdouble r
Definition: Glext.h:5337
void(* bm_set_components)(ubyte *pixel, ubyte *r, ubyte *g, ubyte *b, ubyte *a)
Functional pointer that references any of the bm_set_components functions.
Definition: bmpman.cpp:76
GLboolean GLboolean g
Definition: Glext.h:5781
int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
Unpack a pixel given the passed index and the anim_instance's palette.
Definition: packunpack.cpp:497
ubyte * data
Definition: packunpack.h:80
GLboolean GLboolean GLboolean GLboolean a
Definition: Glext.h:5781
#define STD_RLE_CODE
Definition: packunpack.h:27
void convert_24_to_16(int bit_24, ushort *bit_16)
Convert a 24 bit value to a 16 bit value.
Definition: packunpack.cpp:485
ubyte xparent_b
Definition: packunpack.h:59
int width
Definition: packunpack.h:43
#define PACKING_METHOD_RLE
Definition: packunpack.h:22
const int packer_code
Definition: packunpack.cpp:18
#define PACKER_CODE
Definition: packunpack.h:21
ubyte * unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
Unpack frame.
Definition: packunpack.cpp:669
int idx
Definition: multiui.cpp:761
unsigned char ubyte
Definition: pstypes.h:62
int bm_create(int bpp, int w, int h, void *data, int flags)
Definition: bmpman.cpp:469
#define vm_malloc(size)
Definition: pstypes.h:547
#define INTEL_INT(x)
Definition: pstypes.h:388
GLboolean GLboolean GLboolean b
Definition: Glext.h:5781
ubyte * anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
Definition: packunpack.cpp:127
#define PACKING_METHOD_STD_RLE_KEY
Definition: packunpack.h:25
#define ANF_XPARENT
Definition: packunpack.h:36
screen gr_screen
Definition: 2d.cpp:46
unsigned short ushort
Definition: pstypes.h:63
int file_offset
Definition: packunpack.h:62
int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count=0, int aabitmap=0, int bpp=8)
Unpack a pixel given the passed index and the anim_instance's palette.
Definition: packunpack.cpp:580
ubyte * data
Definition: packunpack.h:53
GLenum GLsizei GLenum GLenum const GLvoid * data
Definition: Gl.h:1509
#define ANF_STREAMED
Definition: packunpack.h:35
int anim_instance_is_streamed(anim_instance *ai)
Definition: animplay.cpp:1067
uint screen_sig
Definition: packunpack.h:61
GLint GLsizei count
Definition: Gl.h:1491
#define PACKING_METHOD_RLE_KEY
Definition: packunpack.h:23
anim_instance * init_anim_instance(anim *ptr, int bpp)
Definition: packunpack.cpp:28
int anim_get_next_frame(anim_instance *inst)
Definition: packunpack.cpp:81
int bm_unload(int handle, int clear_render_targets, bool nodebug)
Unloads a bitmap's data, but not the bitmap info.
Definition: bmpman.cpp:2890
GLclampf GLclampf GLclampf alpha
Definition: Glext.h:5177
const int transparent_code
Definition: packunpack.cpp:19
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
Pack frame.
Definition: packunpack.cpp:326
#define FALSE
Definition: pstypes.h:400
anim * parent
Definition: packunpack.h:79
ubyte palette[768]
Definition: packunpack.h:51
void anim_check_for_palette_change(anim_instance *instance)
Definition: packunpack.cpp:21