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 
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_raw_buffer(anim_instance * inst,int xlate_pal,int aabitmap,int bpp)81 ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
82 {
83 	if ( anim_instance_is_streamed(inst) ) {
84 		if ( inst->file_offset < 0 ) {
85 			return NULL;
86 		}
87 	} else {
88 		if (!inst->data){
89 			return NULL;
90 		}
91 	}
92 
93 	inst->frame_num++;
94 	if (inst->frame_num >= inst->parent->total_frames) {
95 		inst->data = NULL;
96 		inst->file_offset = inst->parent->file_offset;
97 		return NULL;
98 	}
99 
100 	anim_check_for_palette_change(inst);
101 
102 	if ( anim_instance_is_streamed(inst) ) {
103 		if ( xlate_pal ){
104 			inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
105 		} else {
106 			inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
107 		}
108 	} else {
109 		if ( xlate_pal ){
110 			inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
111 		} else {
112 			inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
113 		}
114 	}
115 
116 	return inst->frame;
117 }
118 
119 /**
120  * @brief Convert a 24 bit value to a 16 bit value
121  * @param bit_24 24 bit value
122  * @param bit_16 16 bit value (output)
123  */
convert_24_to_16(int bit_24,ushort * bit_16)124 void convert_24_to_16(int bit_24, ushort *bit_16)
125 {
126 	ubyte *pixel = (ubyte*)&bit_24;
127 	ubyte alpha = 1;
128 
129 	bm_set_components((ubyte*)bit_16, (ubyte*)&pixel[0], (ubyte*)&pixel[1], (ubyte*)&pixel[2], &alpha);
130 }
131 
132 /**
133  * @brief Unpack a pixel given the passed index and the anim_instance's palette
134  * @return Bytes stuffed
135  */
unpack_pixel(anim_instance * ai,ubyte * data,ubyte pix,int aabitmap,int bpp)136 int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
137 {
138 	int bit_24;
139 	ushort bit_16 = 0;
140 	ubyte bit_8 = 0;
141 	ubyte al = 0;
142 	ubyte r, g, b;
143 	int pixel_size = (bpp / 8);
144 	anim *a = ai->parent;
145 	Assert(a);
146 
147 	// if this is an aabitmap, don't run through the palette
148 	if(aabitmap){
149 		switch(bpp){
150 		case 16 :
151 			bit_16 = (ushort)pix;
152 			break;
153 		case 8:
154 			// 8 bit-per-pixel aa bitmaps are a bit special since they only use a palette index value in the range [0, 15]. These
155 			// palette indexes must be remapped to alpha values between [0, 255] which is what graphics code expects. Palette
156 			// range [0, 14] is a gradient from black to white, and palette index 15 is a special color which indicates the background
157 			// area of a HUD gauge. Retail code uses the final alpha value for index 1 for this special index to give gauges a dark
158 			// transparent background.
159 			if (pix > 15) {
160 				bit_8 = 255;
161 			}
162 			else if (pix == 15) {
163 				bit_8 = 18;
164 			}
165 			else {
166 				bit_8 = (ubyte)(pix * 18);
167 			}
168 
169 			break;
170 		default:
171 			Int3();
172 		}
173 	} else {
174 		// if the pixel value is 255, or is the xparent color, make it so
175 		if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
176 			if (pixel_size > 2) {
177 				bit_24 = 0;
178 			} else {
179 				r = b = 0;
180 				g = 255;
181 
182 				bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
183 			}
184 		} else {
185 			if (pixel_size > 2) {
186 				ubyte pixel[4];
187 				pixel[0] = ai->parent->palette[pix * 3 + 2];
188 				pixel[1] = ai->parent->palette[pix * 3 + 1];
189 				pixel[2] = ai->parent->palette[pix * 3];
190 				pixel[3] = 255;
191 				memcpy(&bit_24, pixel, sizeof(int));
192 
193 				if (pixel_size == 4) {
194 					bit_24 = INTEL_INT(bit_24);
195 				}
196 			} else {
197 				// stuff the 24 bit value
198 				memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
199 
200 				// convert to 16 bit
201 				convert_24_to_16(bit_24, &bit_16);
202 			}
203 		}
204 	}
205 
206 	// stuff the pixel
207 	switch (bpp) {
208 		case 32:
209 		case 24:
210 			memcpy(data, &bit_24, pixel_size);
211 			break;
212 
213 		case 16:
214 			memcpy(data, &bit_16, pixel_size);
215 			break;
216 
217 		case 8:
218 			*data = bit_8;
219 			break;
220 
221 		default:
222 			Int3();
223 			return 0;
224 	}
225 
226 	return pixel_size;
227 }
228 
229 /**
230  * @brief Unpack a pixel given the passed index and the anim_instance's palette
231  * @return Bytes stuffed
232  */
unpack_pixel_count(anim_instance * ai,ubyte * data,ubyte pix,int count=0,int aabitmap=0,int bpp=8)233 int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0, int aabitmap = 0, int bpp = 8)
234 {
235 	int bit_24;
236 	int idx;
237 	ubyte al = 0;
238 	ushort bit_16 = 0;
239 	ubyte bit_8 = 0;
240 	anim *a = ai->parent;
241 	int pixel_size = (bpp / 8);
242 	ubyte r, g, b;
243 	Assert(a);
244 
245 	// if this is an aabitmap, don't run through the palette
246 	if(aabitmap){
247 		switch(bpp){
248 		case 16 :
249 			bit_16 = (ushort)pix;
250 			break;
251 		case 8 :
252 			// 8 bit-per-pixel aa bitmaps are a bit special since they only use a palette index value in the range [0, 15]. These
253 			// palette indexes must be remapped to alpha values between [0, 255] which is what graphics code expects. Palette
254 			// range [0, 14] is a gradient from black to white, and palette index 15 is a special color which indicates the background
255 			// area of a HUD gauge. Retail code uses the final alpha value for index 1 for this special index to give gauges a dark
256 			// transparent background.
257 			if (pix > 15) {
258 				bit_8 = 255;
259 			}
260 			else if (pix == 15) {
261 				bit_8 = 18;
262 			}
263 			else {
264 				bit_8 = (ubyte)(pix * 18);
265 			}
266 
267 			break;
268 		default :
269 			Int3();
270 		}
271 	} else {
272 		// if the pixel value is 255, or is the xparent color, make it so
273 		if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
274 			if (pixel_size > 2) {
275 				bit_24 = 0;
276 			} else {
277 				r = b = 0;
278 				g = 255;
279 
280 				bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
281 			}
282 		} else {
283 			if (pixel_size > 2) {
284 				ubyte pixel[4];
285 				pixel[0] = ai->parent->palette[pix * 3 + 2];
286 				pixel[1] = ai->parent->palette[pix * 3 + 1];
287 				pixel[2] = ai->parent->palette[pix * 3];
288 				pixel[3] = 255;
289 				memcpy(&bit_24, pixel, sizeof(int));
290 
291 				if (pixel_size == 4) {
292 					bit_24 = INTEL_INT(bit_24);
293 				}
294 			} else {
295 				// stuff the 24 bit value
296 				memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
297 
298 				// convert to 16 bit
299 				convert_24_to_16(bit_24, &bit_16);
300 			}
301 		}
302 	}
303 
304 	// stuff the pixel
305 	for (idx=0; idx<count; idx++) {
306 		switch (bpp) {
307 			case 32:
308 			case 24:
309 				memcpy(data + (idx * pixel_size), &bit_24, pixel_size);
310 				break;
311 
312 			case 16:
313 				memcpy(data + (idx * pixel_size), &bit_16, pixel_size);
314 				break;
315 
316 			case 8:
317 				*(data + idx) = bit_8;
318 				break;
319 			}
320 	}
321 
322 	return (pixel_size * count);
323 }
324 
325 /**
326  * @brief Unpack frame
327  *
328  * @param ai Animation instance
329  * @param ptr Packed data to unpack
330  * @param frame Where to store unpacked data to
331  * @param size Total number of unpacked pixels requested
332  * @param pal_translate Color translation lookup table (NULL if no palette translation desired)
333  * @param aabitmap
334  * @param bpp
335  */
unpack_frame(anim_instance * ai,ubyte * ptr,ubyte * frame,int size,ubyte * pal_translate,int aabitmap,int bpp)336 ubyte	*unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
337 {
338 	int	xlate_pal, value, count = 0;
339 	int stuffed;
340 	int pixel_size = (bpp / 8);
341 
342 	if ( pal_translate == NULL ) {
343 		xlate_pal = 0;
344 	}
345 	else {
346 		xlate_pal = 1;
347 	}
348 
349 	if (*ptr == PACKING_METHOD_RLE_KEY) {  // key frame, Hoffoss's RLE format
350 		ptr++;
351 		while (size > 0) {
352 			value = *ptr++;
353 			if (value != packer_code) {
354 				if ( xlate_pal ){
355 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
356 				} else {
357 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
358 				}
359 				frame += stuffed;
360 				size--;
361 			} else {
362 				count = *ptr++;
363 				if (count < 2){
364 					value = packer_code;
365 				} else {
366 					value = *ptr++;
367 				}
368 
369 				if (++count > size){
370 					count = size;
371 				}
372 
373 				if ( xlate_pal ){
374 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
375 				} else {
376 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
377 				}
378 
379 				frame += stuffed;
380 				size -= count;
381 			}
382 		}
383 	}
384 	else if ( *ptr == PACKING_METHOD_STD_RLE_KEY) {	// key frame, with high bit as count
385 		ptr++;
386 		while (size > 0) {
387 			value = *ptr++;
388 			if ( !(value & STD_RLE_CODE) ) {
389 				if ( xlate_pal ){
390 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
391 				} else {
392 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
393 				}
394 
395 				frame += stuffed;
396 				size--;
397 			} else {
398 				count = value & (~STD_RLE_CODE);
399 				value = *ptr++;
400 
401 				if (count > size)
402 					count = size;
403 
404 				size -= count;
405 				Assert(size >= 0);
406 
407 				if ( xlate_pal ){
408 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
409 				} else {
410 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
411 				}
412 
413 				frame += stuffed;
414 			}
415 		}
416 	}
417 	else if (*ptr == PACKING_METHOD_RLE) {  // normal frame, Hoffoss's RLE format
418 
419 		ptr++;
420 		while (size > 0) {
421 			value = *ptr++;
422 			if (value != packer_code) {
423 				if (value != transparent_code) {
424 					if ( xlate_pal ){
425 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
426 					} else {
427 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
428 					}
429 				} else {
430 					// temporary pixel
431 					stuffed = pixel_size;
432 				}
433 
434 				frame += stuffed;
435 				size--;
436 			} else {
437 				count = *ptr++;
438 				if (count < 2){
439 					value = packer_code;
440 				} else {
441 					value = *ptr++;
442 				}
443 
444 				if (++count > size){
445 					count = size;
446 				}
447 
448 				size -= count;
449 				Assert(size >= 0);
450 
451 				if (value != transparent_code ) {
452 					if ( xlate_pal ) {
453 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
454 					} else {
455 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
456 					}
457 				} else {
458 					stuffed = count * pixel_size;
459 				}
460 
461 				frame += stuffed;
462 			}
463 		}
464 
465 	}
466 	else if ( *ptr == PACKING_METHOD_STD_RLE) {	// normal frame, with high bit as count
467 		ptr++;
468 		while (size > 0) {
469 			value = *ptr++;
470 			if ( !(value & STD_RLE_CODE) ) {
471 				if (value != transparent_code) {
472 					if ( xlate_pal ){
473 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
474 					} else {
475 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
476 					}
477 				} else {
478 					stuffed = pixel_size;
479 				}
480 
481 				frame += stuffed;
482 				size--;
483 			} else {
484 				count = value & (~STD_RLE_CODE);
485 				value = *ptr++;
486 
487 				if (count > size)
488 					count = size;
489 
490 				size -= count;
491 				Assert(size >= 0);
492 
493 				if (value != transparent_code) {
494 					if ( xlate_pal ){
495 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
496 					} else {
497 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
498 					}
499 				} else {
500 					stuffed = pixel_size * count;
501 				}
502 
503 				frame += stuffed;
504 			}
505 		}
506 	}
507 	else {
508 		// unknown packing method
509 		return NULL;
510 	}
511 
512 	return ptr;
513 }
514 
515 /**
516  * @brief Unpack frame from file
517  *
518  * @param ai Animation instance
519  * @param frame Where to store unpacked data to
520  * @param size Total number of unpacked pixels requested
521  * @param pal_translate Color translation lookup table (NULL if no palette translation desired)
522  * @param aabitmap
523  * @param bpp
524  */
unpack_frame_from_file(anim_instance * ai,ubyte * frame,int size,ubyte * pal_translate,int aabitmap,int bpp)525 int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
526 {
527 	int	xlate_pal, value, count = 0;
528 	int	offset = 0;
529 	int stuffed;
530 	int pixel_size = (bpp / 8);
531 
532 	if ( pal_translate == NULL ) {
533 		xlate_pal = 0;
534 	}
535 	else {
536 		xlate_pal = 1;
537 	}
538 
539 	if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE_KEY) {  // key frame, Hoffoss's RLE format
540 		offset++;
541 		while (size > 0) {
542 			value = anim_instance_get_byte(ai,offset);
543 			offset++;
544 			if (value != packer_code) {
545 				if ( xlate_pal ){
546 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
547 				} else {
548 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
549 				}
550 
551 				frame += stuffed;
552 				size--;
553 			} else {
554 				count = anim_instance_get_byte(ai,offset);
555 				offset++;
556 				if (count < 2) {
557 					value = packer_code;
558 				} else {
559 					value = anim_instance_get_byte(ai,offset);
560 					offset++;
561 				}
562 
563 				if (++count > size){
564 					count = size;
565 				}
566 
567 				if ( xlate_pal ){
568 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
569 				} else {
570 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
571 				}
572 
573 				frame += stuffed;
574 				size -= count;
575 			}
576 		}
577 	}
578 	else if ( anim_instance_get_byte(ai,offset) == PACKING_METHOD_STD_RLE_KEY) {	// key frame, with high bit as count
579 		offset++;
580 		while (size > 0) {
581 			value = anim_instance_get_byte(ai,offset);
582 			offset++;
583 			if ( !(value & STD_RLE_CODE) ) {
584 				if ( xlate_pal ){
585 					stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
586 				} else {
587 					stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
588 				}
589 
590 				frame += stuffed;
591 				size--;
592 			} else {
593 				count = value & (~STD_RLE_CODE);
594 				value = anim_instance_get_byte(ai,offset);
595 				offset++;
596 
597 				if (count > size)
598 					count = size;
599 
600 				size -= count;
601 				Assert(size >= 0);
602 
603 				if ( xlate_pal ){
604 					stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
605 				} else {
606 					stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
607 				}
608 
609 				frame += stuffed;
610 			}
611 		}
612 	}
613 	else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) {  // normal frame, Hoffoss's RLE format
614 
615 		offset++;
616 		while (size > 0) {
617 			value = anim_instance_get_byte(ai,offset);
618 			offset++;
619 			if (value != packer_code) {
620 				if (value != transparent_code) {
621 					if ( xlate_pal ){
622 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
623 					} else {
624 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
625 					}
626 				} else {
627 					stuffed = pixel_size;
628 				}
629 
630 				frame += stuffed;
631 				size--;
632 			} else {
633 				count = anim_instance_get_byte(ai,offset);
634 				offset++;
635 
636 				if (count < 2) {
637 					value = packer_code;
638 				} else {
639 					value = anim_instance_get_byte(ai,offset);
640 					offset++;
641 				}
642 				if (++count > size){
643 					count = size;
644 				}
645 
646 				size -= count;
647 				Assert(size >= 0);
648 
649 				if (value != transparent_code ) {
650 					if ( xlate_pal ) {
651 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
652 					} else {
653 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
654 					}
655 				} else {
656 					stuffed = pixel_size * count;
657 				}
658 
659 				frame += stuffed;
660 			}
661 		}
662 
663 	}
664 	else if ( anim_instance_get_byte(ai,offset) ) {	// normal frame, with high bit as count
665 		offset++;
666 		while (size > 0) {
667 			value = anim_instance_get_byte(ai,offset);
668 			offset++;
669 			if ( !(value & STD_RLE_CODE) ) {
670 				if (value != transparent_code) {
671 					if ( xlate_pal ){
672 						stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
673 					} else {
674 						stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
675 					}
676 				} else {
677 					stuffed = pixel_size;
678 				}
679 
680 				frame += stuffed;
681 				size--;
682 			} else {
683 				count = value & (~STD_RLE_CODE);
684 				value = anim_instance_get_byte(ai,offset);
685 				offset++;
686 
687 				if (count > size)
688 					count = size;
689 
690 				size -= count;
691 				Assert(size >= 0);
692 
693 				if (value != transparent_code) {
694 					if ( xlate_pal ){
695 						stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
696 					} else {
697 						stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
698 					}
699 				} else {
700 					stuffed = pixel_size * count;
701 				}
702 
703 				frame += stuffed;
704 			}
705 		}
706 	}
707 	else {
708 		// unknown packing method
709 		return -1;
710 	}
711 
712 	return ai->file_offset + offset;
713 }
714 
715 
716 /**
717  * @brief Set animation palette
718  * @todo Actually convert the frame data to correct palette at this point
719  */
anim_set_palette(anim * ptr)720 void anim_set_palette(anim *ptr)
721 {
722 	int i, xparent_found = 0;
723 
724 	// create the palette translation look-up table
725 	for ( i = 0; i < 256; i++ ) {
726 		ptr->palette_translation[i] = (ubyte)i;
727 	}
728 
729 	if ( xparent_found ) {
730 		ptr->flags |= ANF_XPARENT;
731 	}
732 	else {
733 		ptr->flags &= ~ANF_XPARENT;
734 	}
735 }
736