Files
fs2open.github.com/code/anim/packunpack.cpp
T

1069 lines
23 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#include "anim/animplay.h"
#include "anim/packunpack.h"
#include "bmpman/bmpman.h"
#include "graphics/2d.h"
const int packer_code = PACKER_CODE;
const int transparent_code = 254;
void anim_check_for_palette_change(anim_instance *instance) {
if ( instance->parent->screen_sig != gr_screen.signature ) {
instance->parent->screen_sig = gr_screen.signature;
anim_set_palette(instance->parent);
}
}
anim_instance *init_anim_instance(anim *ptr, int bpp)
{
anim_instance *inst;
if (!ptr) {
Int3();
return NULL;
}
if ( ptr->flags & ANF_STREAMED ) {
if ( ptr->file_offset < 0 ) {
Int3();
return NULL;
}
} else {
if ( !ptr->data ) {
Int3();
return NULL;
}
}
ptr->instance_count++;
inst = (anim_instance *) vm_malloc(sizeof(anim_instance));
Assert(inst);
memset(inst, 0, sizeof(anim_instance));
inst->frame_num = -1;
inst->last_frame_num = -1;
inst->parent = ptr;
inst->data = ptr->data;
inst->file_offset = ptr->file_offset;
inst->stop_now = FALSE;
inst->aa_color = NULL;
inst->frame = (ubyte *) vm_malloc(inst->parent->width * inst->parent->height * (bpp >> 3));
Assert( inst->frame != NULL );
memset( inst->frame, 0, inst->parent->width * inst->parent->height * (bpp >> 3) );
return inst;
}
void free_anim_instance(anim_instance *inst)
{
Assert(inst->frame);
vm_free(inst->frame);
inst->frame = NULL;
inst->parent->instance_count--;
inst->parent = NULL;
inst->data = NULL;
inst->file_offset = -1;
vm_free(inst);
}
int anim_get_next_frame(anim_instance *inst)
{
int bm, bitmap_flags;
int aabitmap = 0;
int bpp = 16;
if ( anim_instance_is_streamed(inst) ) {
if ( inst->file_offset <= 0 ) {
return -1;
}
} else {
if (!inst->data)
return -1;
}
inst->frame_num++;
if (inst->frame_num >= inst->parent->total_frames) {
inst->data = NULL;
inst->file_offset = inst->parent->file_offset;
return -1;
}
bitmap_flags = 0;
bpp = 16;
if(inst->aa_color != NULL){
bitmap_flags |= BMP_AABITMAP;
aabitmap = 1;
bpp = 8;
}
anim_check_for_palette_change(inst);
BM_SELECT_TEX_FORMAT();
if ( anim_instance_is_streamed(inst) ) {
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
} else {
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
}
bm = bm_create(bpp, inst->parent->width, inst->parent->height, inst->frame, bitmap_flags);
bm_unload(bm);
return bm;
}
ubyte *anim_get_next_raw_buffer(anim_instance *inst, int xlate_pal, int aabitmap, int bpp)
{
if ( anim_instance_is_streamed(inst) ) {
if ( inst->file_offset < 0 ) {
return NULL;
}
} else {
if (!inst->data){
return NULL;
}
}
inst->frame_num++;
if (inst->frame_num >= inst->parent->total_frames) {
inst->data = NULL;
inst->file_offset = inst->parent->file_offset;
return NULL;
}
anim_check_for_palette_change(inst);
if ( anim_instance_is_streamed(inst) ) {
if ( xlate_pal ){
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
} else {
inst->file_offset = unpack_frame_from_file(inst, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
}
} else {
if ( xlate_pal ){
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, inst->parent->palette_translation, aabitmap, bpp);
} else {
inst->data = unpack_frame(inst, inst->data, inst->frame, inst->parent->width*inst->parent->height, NULL, aabitmap, bpp);
}
}
return inst->frame;
}
/**
* @brief Pack key frame
*
* @param frame Frame pixel data to pack
* @param save Memory to store packed data to
* @param size Number of bytes to pack
* @param max Maximum number of packed bytes (size of buffer)
* @param compress_type Compress type
* @return Actual number of bytes data packed to or -1 if error
*/
int pack_key_frame(ubyte *frame, ubyte *save, long size, long max, int compress_type)
{
int last = -32768, count = 0;
long packed_size = 1;
switch ( compress_type ) {
case PACKING_METHOD_RLE_KEY:
*save++ = PACKING_METHOD_RLE_KEY;
while (size--) {
if (*frame != last || count > 255) {
if (packed_size + 3 >= max)
return -1;
if (count < 3) {
if (last == packer_code) {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
packed_size += 2;
} else
while (count--) {
*save++ = (ubyte)last;
packed_size++;
}
} else {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
*save++ = (ubyte)last;
packed_size += 3;
}
count = 0;
last = *frame;
}
count++;
frame++;
}
if (packed_size + 3 >= max)
return -1;
if (count < 3) {
if (last == packer_code) {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
packed_size += 2;
} else
while (count--) {
*save++ = (ubyte)last;
packed_size++;
}
} else {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
*save++ = (ubyte)last;
packed_size += 3;
}
break;
case PACKING_METHOD_STD_RLE_KEY: {
ubyte *dest_start;
int i;
dest_start = save;
count = 1;
last = *frame++;
*save++ = PACKING_METHOD_STD_RLE_KEY;
for (i=1; i < size; i++ ) {
if ( *frame != last ) {
if ( count ) {
if (packed_size + 2 >= max)
return -1;
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
*save++ = (ubyte)last;
packed_size++;
Assert( last != STD_RLE_CODE );
}
else {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
}
}
last = *frame;
count = 0;
}
count++;
frame++;
if ( count == 127 ) {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
count = 0;
}
} // end for
if (count) {
if (packed_size + 2 >= max)
return -1;
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
*save++ = (ubyte)last;
packed_size++;
Assert( last != STD_RLE_CODE );
}
else {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
}
}
Assert(packed_size == (save-dest_start) );
return packed_size;
}
default:
Assert(0);
return -1;
break;
} // end switch
return packed_size;
}
/**
* @brief Pack frame
*
* @param frame Frame pixel data to pack
* @param frame2 Previous frame's pixel data
* @param save Memory to store packed data to
* @param size Number of bytes to pack
* @param max Maximum number of packed bytes (size of buffer)
* @param compress_type Compress type
* @return Actual number of bytes data packed to or -1 if error
*/
int pack_frame(ubyte *frame, ubyte *frame2, ubyte *save, long size, long max, int compress_type)
{
int pixel, last = -32768, count = 0, i;
long packed_size = 1;
switch ( compress_type ) {
case PACKING_METHOD_RLE: // Hoffoss RLE regular frame
*save++ = PACKING_METHOD_RLE;
while (size--) {
if (*frame != *frame2++)
pixel = *frame;
else
pixel = transparent_code;
if (pixel != last || count > 255) {
if (packed_size + 3 >= max)
return -1;
if (count < 3) {
if (last == packer_code) {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
packed_size += 2;
} else
while (count--) {
*save++ = (ubyte)last;
packed_size++;
}
} else {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
*save++ = (ubyte)last;
packed_size += 3;
}
count = 0;
last = pixel;
}
frame++;
count++;
}
if (packed_size + 3 >= max)
return -1;
if (count < 3) {
if (last == packer_code) {
*save++ = (ubyte)packer_code;
*save++ = (ubyte)(count - 1);
packed_size += 2;
} else
while (count--) {
*save++ = (ubyte)last;
packed_size++;
}
} else {
*save++ = (ubyte)(packer_code);
*save++ = (ubyte)(count - 1);
*save++ = (ubyte)(last);
packed_size += 3;
}
break;
case PACKING_METHOD_STD_RLE: { // high bit count regular RLE frame
ubyte *dest_start;
dest_start = save;
count = 1;
if (*frame++ != *frame2++)
last = *frame;
else
last = transparent_code;
*save++ = PACKING_METHOD_STD_RLE;
for (i=1; i < size; i++ ) {
if (*frame != *frame2++)
pixel = *frame;
else
pixel = transparent_code;
if ( pixel != last ) {
if ( count ) {
if (packed_size + 2 >= max)
return -1;
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
*save++ = (ubyte)last;
packed_size++;
Assert( last != STD_RLE_CODE );
}
else {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
}
}
last = pixel;
count = 0;
}
count++;
frame++;
if ( count == 127 ) {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
count = 0;
}
} // end for
if (count) {
if (packed_size + 2 >= max)
return -1;
if ( (count == 1) && !(last & STD_RLE_CODE) ) {
*save++ = (ubyte)last;
packed_size++;
Assert( last != STD_RLE_CODE );
}
else {
count |= STD_RLE_CODE;
*save++ = (ubyte)count;
*save++ = (ubyte)last;
packed_size += 2;
}
}
Assert(packed_size == (save-dest_start) );
return packed_size;
}
default:
Assert(0);
return -1;
break;
} // end switch
return packed_size;
}
/**
* @brief Convert a 24 bit value to a 16 bit value
* @param bit_24 24 bit value
* @param bit_16 16 bit value (output)
*/
void convert_24_to_16(int bit_24, ushort *bit_16)
{
ubyte *pixel = (ubyte*)&bit_24;
ubyte alpha = 1;
bm_set_components((ubyte*)bit_16, (ubyte*)&pixel[0], (ubyte*)&pixel[1], (ubyte*)&pixel[2], &alpha);
}
/**
* @brief Unpack a pixel given the passed index and the anim_instance's palette
* @return Bytes stuffed
*/
int unpack_pixel(anim_instance *ai, ubyte *data, ubyte pix, int aabitmap, int bpp)
{
int bit_24;
ushort bit_16 = 0;
ubyte bit_8 = 0;
ubyte al = 0;
ubyte r, g, b;
int pixel_size = (bpp / 8);
anim *a = ai->parent;
Assert(a);
// if this is an aabitmap, don't run through the palette
if(aabitmap){
switch(bpp){
case 16 :
bit_16 = (ushort)pix;
break;
case 8:
bit_8 = pix;
break;
default:
Int3();
}
} else {
// if the pixel value is 255, or is the xparent color, make it so
if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
if (pixel_size > 2) {
bit_24 = 0;
} else {
r = b = 0;
g = 255;
bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
}
} else {
if (pixel_size > 2) {
ubyte pixel[4];
pixel[0] = ai->parent->palette[pix * 3 + 2];
pixel[1] = ai->parent->palette[pix * 3 + 1];
pixel[2] = ai->parent->palette[pix * 3];
pixel[3] = 255;
memcpy(&bit_24, pixel, sizeof(int));
if (pixel_size == 4) {
bit_24 = INTEL_INT(bit_24);
}
} else {
// stuff the 24 bit value
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
// convert to 16 bit
convert_24_to_16(bit_24, &bit_16);
}
}
}
// stuff the pixel
switch (bpp) {
case 32:
case 24:
memcpy(data, &bit_24, pixel_size);
break;
case 16:
memcpy(data, &bit_16, pixel_size);
break;
case 8:
*data = bit_8;
break;
default:
Int3();
return 0;
}
return pixel_size;
}
/**
* @brief Unpack a pixel given the passed index and the anim_instance's palette
* @return Bytes stuffed
*/
int unpack_pixel_count(anim_instance *ai, ubyte *data, ubyte pix, int count = 0, int aabitmap = 0, int bpp = 8)
{
int bit_24;
int idx;
ubyte al = 0;
ushort bit_16 = 0;
ubyte bit_8 = 0;
anim *a = ai->parent;
int pixel_size = (bpp / 8);
ubyte r, g, b;
Assert(a);
// if this is an aabitmap, don't run through the palette
if(aabitmap){
switch(bpp){
case 16 :
bit_16 = (ushort)pix;
break;
case 8 :
bit_8 = pix;
break;
default :
Int3();
}
} else {
// if the pixel value is 255, or is the xparent color, make it so
if(((a->palette[pix*3] == a->xparent_r) && (a->palette[pix*3+1] == a->xparent_g) && (a->palette[pix*3+2] == a->xparent_b)) ){
if (pixel_size > 2) {
bit_24 = 0;
} else {
r = b = 0;
g = 255;
bm_set_components((ubyte*)&bit_16, &r, &g, &b, &al);
}
} else {
if (pixel_size > 2) {
ubyte pixel[4];
pixel[0] = ai->parent->palette[pix * 3 + 2];
pixel[1] = ai->parent->palette[pix * 3 + 1];
pixel[2] = ai->parent->palette[pix * 3];
pixel[3] = 255;
memcpy(&bit_24, pixel, sizeof(int));
if (pixel_size == 4) {
bit_24 = INTEL_INT(bit_24);
}
} else {
// stuff the 24 bit value
memcpy(&bit_24, &ai->parent->palette[pix * 3], 3); //-V512
// convert to 16 bit
convert_24_to_16(bit_24, &bit_16);
}
}
}
// stuff the pixel
for (idx=0; idx<count; idx++) {
switch (bpp) {
case 32:
case 24:
memcpy(data + (idx * pixel_size), &bit_24, pixel_size);
break;
case 16:
memcpy(data + (idx * pixel_size), &bit_16, pixel_size);
break;
case 8:
*(data + idx) = bit_8;
break;
}
}
return (pixel_size * count);
}
/**
* @brief Unpack frame
*
* @param ai Animation instance
* @param ptr Packed data to unpack
* @param frame Where to store unpacked data to
* @param size Total number of unpacked pixels requested
* @param pal_translate Color translation lookup table (NULL if no palette translation desired)
* @param aabitmap
* @param bpp
*/
ubyte *unpack_frame(anim_instance *ai, ubyte *ptr, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
{
int xlate_pal, value, count = 0;
int stuffed;
int pixel_size = (bpp / 8);
if ( pal_translate == NULL ) {
xlate_pal = 0;
}
else {
xlate_pal = 1;
}
if (*ptr == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
ptr++;
while (size > 0) {
value = *ptr++;
if (value != packer_code) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
frame += stuffed;
size--;
} else {
count = *ptr++;
if (count < 2){
value = packer_code;
} else {
value = *ptr++;
}
if (++count > size){
count = size;
}
if ( xlate_pal ){
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
frame += stuffed;
size -= count;
}
}
}
else if ( *ptr == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
ptr++;
while (size > 0) {
value = *ptr++;
if ( !(value & STD_RLE_CODE) ) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
frame += stuffed;
size--;
} else {
count = value & (~STD_RLE_CODE);
value = *ptr++;
if (count > size)
count = size;
size -= count;
Assert(size >= 0);
if ( xlate_pal ){
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
frame += stuffed;
}
}
}
else if (*ptr == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
ptr++;
while (size > 0) {
value = *ptr++;
if (value != packer_code) {
if (value != transparent_code) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
} else {
// temporary pixel
stuffed = pixel_size;
}
frame += stuffed;
size--;
} else {
count = *ptr++;
if (count < 2){
value = packer_code;
} else {
value = *ptr++;
}
if (++count > size){
count = size;
}
size -= count;
Assert(size >= 0);
if (value != transparent_code ) {
if ( xlate_pal ) {
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
} else {
stuffed = count * pixel_size;
}
frame += stuffed;
}
}
}
else if ( *ptr == PACKING_METHOD_STD_RLE) { // normal frame, with high bit as count
ptr++;
while (size > 0) {
value = *ptr++;
if ( !(value & STD_RLE_CODE) ) {
if (value != transparent_code) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
} else {
stuffed = pixel_size;
}
frame += stuffed;
size--;
} else {
count = value & (~STD_RLE_CODE);
value = *ptr++;
if (count > size)
count = size;
size -= count;
Assert(size >= 0);
if (value != transparent_code) {
if ( xlate_pal ){
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
} else {
stuffed = pixel_size * count;
}
frame += stuffed;
}
}
}
else {
// unknown packing method
return NULL;
}
return ptr;
}
/**
* @brief Unpack frame from file
*
* @param ai Animation instance
* @param frame Where to store unpacked data to
* @param size Total number of unpacked pixels requested
* @param pal_translate Color translation lookup table (NULL if no palette translation desired)
* @param aabitmap
* @param bpp
*/
int unpack_frame_from_file(anim_instance *ai, ubyte *frame, int size, ubyte *pal_translate, int aabitmap, int bpp)
{
int xlate_pal, value, count = 0;
int offset = 0;
int stuffed;
int pixel_size = (bpp / 8);
if ( pal_translate == NULL ) {
xlate_pal = 0;
}
else {
xlate_pal = 1;
}
if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE_KEY) { // key frame, Hoffoss's RLE format
offset++;
while (size > 0) {
value = anim_instance_get_byte(ai,offset);
offset++;
if (value != packer_code) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
frame += stuffed;
size--;
} else {
count = anim_instance_get_byte(ai,offset);
offset++;
if (count < 2) {
value = packer_code;
} else {
value = anim_instance_get_byte(ai,offset);
offset++;
}
if (++count > size){
count = size;
}
if ( xlate_pal ){
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
frame += stuffed;
size -= count;
}
}
}
else if ( anim_instance_get_byte(ai,offset) == PACKING_METHOD_STD_RLE_KEY) { // key frame, with high bit as count
offset++;
while (size > 0) {
value = anim_instance_get_byte(ai,offset);
offset++;
if ( !(value & STD_RLE_CODE) ) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
frame += stuffed;
size--;
} else {
count = value & (~STD_RLE_CODE);
value = anim_instance_get_byte(ai,offset);
offset++;
if (count > size)
count = size;
size -= count;
Assert(size >= 0);
if ( xlate_pal ){
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
frame += stuffed;
}
}
}
else if (anim_instance_get_byte(ai,offset) == PACKING_METHOD_RLE) { // normal frame, Hoffoss's RLE format
offset++;
while (size > 0) {
value = anim_instance_get_byte(ai,offset);
offset++;
if (value != packer_code) {
if (value != transparent_code) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
} else {
stuffed = pixel_size;
}
frame += stuffed;
size--;
} else {
count = anim_instance_get_byte(ai,offset);
offset++;
if (count < 2) {
value = packer_code;
} else {
value = anim_instance_get_byte(ai,offset);
offset++;
}
if (++count > size){
count = size;
}
size -= count;
Assert(size >= 0);
if (value != transparent_code ) {
if ( xlate_pal ) {
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
} else {
stuffed = pixel_size * count;
}
frame += stuffed;
}
}
}
else if ( anim_instance_get_byte(ai,offset) ) { // normal frame, with high bit as count
offset++;
while (size > 0) {
value = anim_instance_get_byte(ai,offset);
offset++;
if ( !(value & STD_RLE_CODE) ) {
if (value != transparent_code) {
if ( xlate_pal ){
stuffed = unpack_pixel(ai, frame, pal_translate[value], aabitmap, bpp);
} else {
stuffed = unpack_pixel(ai, frame, (ubyte)value, aabitmap, bpp);
}
} else {
stuffed = pixel_size;
}
frame += stuffed;
size--;
} else {
count = value & (~STD_RLE_CODE);
value = anim_instance_get_byte(ai,offset);
offset++;
if (count > size)
count = size;
size -= count;
Assert(size >= 0);
if (value != transparent_code) {
if ( xlate_pal ){
stuffed = unpack_pixel_count(ai, frame, pal_translate[value], count, aabitmap, bpp);
} else {
stuffed = unpack_pixel_count(ai, frame, (ubyte)value, count, aabitmap, bpp);
}
} else {
stuffed = pixel_size * count;
}
frame += stuffed;
}
}
}
else {
// unknown packing method
return -1;
}
return ai->file_offset + offset;
}
/**
* @brief Set animation palette
* @todo Actually convert the frame data to correct palette at this point
*/
void anim_set_palette(anim *ptr)
{
int i, xparent_found = 0;
// create the palette translation look-up table
for ( i = 0; i < 256; i++ ) {
ptr->palette_translation[i] = (ubyte)i;
}
if ( xparent_found ) {
ptr->flags |= ANF_XPARENT;
}
else {
ptr->flags &= ~ANF_XPARENT;
}
}