/* This reads the files mysha.pcx and allegro.pcx into a memory block as * binary data, and then uses the memory vtable to read the bitmaps out of * the memory block. */ static void memread_test(void) { PACKFILE *f; MEMREAD_INFO memread_info; BITMAP *bmp, *bmp2; unsigned char *block; int64_t l1, l2; PACKFILE *f1, *f2; l1 = file_size_ex("allegro.pcx"); l2 = file_size_ex("mysha.pcx"); block = malloc(l1 + l2); /* Read mysha.pcx into the memory block. */ f1 = pack_fopen("allegro.pcx", "rb"); CHECK(f1, "opening allegro.pcx"); pack_fread(block, l1, f1); pack_fclose(f1); /* Read allegro.pcx into the memory block. */ f2 = pack_fopen("mysha.pcx", "rb"); CHECK(f2, "opening mysha.pcx"); pack_fread(block + l1, l2, f2); pack_fclose(f2); /* Open the memory block as PACKFILE, using our memory vtable. */ memread_info.block = block; memread_info.length = l1 + l2; memread_info.offset = 0; f = pack_fopen_vtable(&memread_vtable, &memread_info); CHECK(f, "reading from memory block"); /* Read the bitmaps out of the memory block. */ bmp = load_pcx_pf(f, NULL); CHECK(bmp, "load_pcx_pf"); bmp2 = load_pcx_pf(f, NULL); CHECK(bmp2, "load_pcx_pf"); blit(bmp, screen, 0, 0, 0, 0, bmp->w, bmp->h); textprintf_ex(screen, font, bmp->w + 8, 8, -1, -1, "\"allegro.pcx\""); textprintf_ex(screen, font, bmp->w + 8, 8 + 20, -1, -1, "read out of a memory file"); blit(bmp2, screen, 0, 0, 0, bmp->h + 8, bmp2->w, bmp2->h); textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8, -1, -1, "\"mysha.pcx\""); textprintf_ex(screen, font, bmp2->w + 8, bmp->h + 8 + 20, -1, -1, "read out of a memory file"); destroy_bitmap(bmp); destroy_bitmap(bmp2); pack_fclose(f); next(); }
int eof_file_compare(char *file1, char *file2) { uint64_t filesize,ctr; int data1,data2; PACKFILE *fp1 = NULL,*fp2 = NULL; char result = 0; //The result is assumed to "files identical" until found otherwise eof_log("eof_file_compare() entered", 1); if((file1 == NULL) || (file2 == NULL)) { return 2; //Return error } filesize = file_size_ex(file1); //Get length of file1 if(filesize != file_size_ex(file2)) { //If file1 and file2 are different lengths return 1; //Return files don't match } fp1 = pack_fopen(file1, "r"); if(fp1 == NULL) { return 2; //Return error } fp2 = pack_fopen(file2, "r"); if(fp2 == NULL) { (void) pack_fclose(fp1); return 2; //Return error } for(ctr = 0;ctr < filesize; ctr++) { //For each byte in the files data1 = pack_getc(fp1); //Read one byte from each data2 = pack_getc(fp2); if((data1 == EOF) || (data2 == EOF)) { //If EOF was reached unexpectedly break; //Exit loop } if(data1 != data2) { result = 1; //Store a "non identical" result break; //Exit loop } } (void) pack_fclose(fp1); (void) pack_fclose(fp2); return result; }
void * eof_buffer_file(const char * fn, char appendnull) { // eof_log("eof_buffer_file() entered"); void * data = NULL; PACKFILE * fp = NULL; size_t filesize, buffersize; if(fn == NULL) return NULL; fp = pack_fopen(fn, "r"); if(fp == NULL) { return NULL; } filesize = buffersize = file_size_ex(fn); if(appendnull) { //If adding an extra NULL byte of padding to the end of the buffer buffersize++; //Allocate an extra byte for the padding } data = (char *)malloc(buffersize); if(data == NULL) return NULL; (void) pack_fread(data, (long)filesize, fp); if(appendnull) { //If adding an extra NULL byte of padding to the end of the buffer ((char *)data)[buffersize - 1] = 0; //Write a 0 byte at the end of the buffer } (void) pack_fclose(fp); return data; }
/* grab raw binary data */ static DATAFILE *grab_binary(int type, AL_CONST char *filename, DATAFILE_PROPERTY **prop, int depth) { void *mem; int64_t sz = file_size_ex(filename); PACKFILE *f; if (sz <= 0) return NULL; mem = malloc(sz); f = pack_fopen(filename, F_READ); if (!f) { free(mem); return NULL; } if (pack_fread(mem, sz, f) < sz) { pack_fclose(f); free(mem); return NULL; } pack_fclose(f); return datedit_construct(type, mem, sz, prop); }
SAMPLE *eof_mix_load_ogg_sample(char *fn) { // eof_log("eof_mix_load_ogg_sample() entered"); ALOGG_OGG * temp_ogg = NULL; char * buffer = NULL; SAMPLE *loadedsample = NULL; if(fn == NULL) { return NULL; } buffer = eof_buffer_file(fn, 0); if(buffer) { temp_ogg = alogg_create_ogg_from_buffer(buffer, file_size_ex(fn)); if(temp_ogg) { loadedsample = alogg_create_sample_from_ogg(temp_ogg); alogg_destroy_ogg(temp_ogg); } if(loadedsample == NULL) allegro_message("Couldn't load sample %s!",fn); free(buffer); } return loadedsample; }
static int copy_file(AL_CONST char *filename, AL_CONST char *dest_path) { char *buffer = NULL; char dest_file[1024]; PACKFILE *f; size_t size; if (!exists(filename)) return -1; buffer = malloc(size = file_size_ex(filename)); if (!buffer) return -1; append_filename(dest_file, dest_path, get_filename(filename), 1024); f = pack_fopen(filename, F_READ); if (!f) { free(buffer); return -1; } pack_fread(buffer, size, f); pack_fclose(f); f = pack_fopen(dest_file, F_WRITE); if (!f) { free(buffer); return -1; } pack_fwrite(buffer, size, f); pack_fclose(f); free(buffer); return 0; }
int eof_copy_file(const char * src, const char * dest) { PACKFILE * src_fp = NULL; PACKFILE * dest_fp = NULL; void *ptr = NULL; //Used to buffer memory unsigned long src_size = 0; unsigned long i; eof_log("eof_copy_file() entered", 1); if((src == NULL) || (dest == NULL)) return 0; if(!ustricmp(src,dest)) //Special case: The input and output file are the same return 0; //Return success without copying any files src_size = (unsigned long)file_size_ex(src); if(src_size > LONG_MAX) return 0; //Unable to validate I/O due to Allegro's usage of signed values src_fp = pack_fopen(src, "r"); if(!src_fp) { return 0; } dest_fp = pack_fopen(dest, "w"); if(!dest_fp) { (void) pack_fclose(src_fp); return 0; } //Attempt to buffer the input file into memory for faster read and write ptr = malloc((size_t)src_size); if(ptr != NULL) { //If a buffer large enough to store the input file was created long long_src_size = src_size; if((pack_fread(ptr, long_src_size, src_fp) != long_src_size) || (pack_fwrite(ptr, long_src_size, dest_fp) != long_src_size)) { //If there was an error reading from file or writing from memory free(ptr); //Release buffer return 0; //Return error } free(ptr); //Release buffer } else { //Otherwise copy the slow way (one byte at a time) for(i = 0; i < src_size; i++) { (void) pack_putc(pack_getc(src_fp), dest_fp); } } (void) pack_fclose(src_fp); (void) pack_fclose(dest_fp); return 1; }
/* loads a MSK file (Animator and Animator Pro format) */ Mask *load_msk_file(const char *filename) { #if (MAKE_VERSION(4, 2, 1) >= MAKE_VERSION(ALLEGRO_VERSION, \ ALLEGRO_SUB_VERSION, \ ALLEGRO_WIP_VERSION)) int orig_size = file_size(filename); #else int orig_size = file_size_ex(filename); #endif int i, c, u, v, byte, magic, size; Mask *mask = NULL; PACKFILE *f; f = pack_fopen(filename, F_READ); if (!f) return NULL; size = pack_igetl(f); magic = pack_igetw(f); /* Animator Pro MSK format */ if ((size == orig_size) && (magic == 0x9500)) { Image *image; int x, y; pack_fclose(f); /* just load an Animator Pro PIC file */ image = load_pic_file(filename, &x, &y, NULL); if ((!image) || (image->imgtype != IMAGE_BITMAP)) { if (image) image_free(image); } else { mask = mask_new(); mask->x = x; mask->y = y; mask->w = image->w; mask->h = image->h; mask->bitmap = image; } } /* Animator MSK format */ else if (orig_size == 8000) { mask = mask_new(); mask_replace(mask, 0, 0, 320, 200); u = v = 0; for (i=0; i<8000; i++) { byte = pack_getc (f); for (c=0; c<8; c++) { mask->bitmap->putpixel(u, v, byte & (1<<(7-c))); u++; if (u == 320) { u = 0; v++; } } } pack_fclose(f); } else { pack_fclose(f); } return mask; }
int eof_add_silence_recode(char * oggfn, unsigned long ms) { char sys_command[1024] = {0}; char backupfn[1024] = {0}; char wavfn[1024] = {0}; char soggfn[1024] = {0}; ALOGG_OGG *oggfile = NULL; SAMPLE *decoded = NULL, *combined = NULL; int bits; int stereo; int freq; unsigned long samples; int channels; unsigned long ctr,index; void * oggbuffer = NULL; int bitrate; eof_log("eof_add_silence_recode() entered", 1); if(!oggfn || (ms == 0) || eof_silence_loaded) { return 41; //Return failure: Invalid parameters } set_window_title("Adjusting Silence..."); /* back up original file */ (void) snprintf(backupfn, sizeof(backupfn) - 1, "%s.backup", oggfn); if(!exists(backupfn)) { (void) eof_copy_file(oggfn, backupfn); } /* Decode the OGG file into memory */ //Load OGG file into memory oggbuffer = eof_buffer_file(oggfn, 0); //Decode the OGG from buffer instead of from file because the latter cannot support special characters in the file path due to limitations with fopen() if(!oggbuffer) { (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tError reading OGG: \"%s\"", strerror(errno)); //Get the Operating System's reason for the failure eof_log(eof_log_string, 1); return 42; //Return failure: Could not buffer chart audio into memory } oggfile=alogg_create_ogg_from_buffer(oggbuffer, (int)file_size_ex(oggfn)); if(oggfile == NULL) { eof_log("ALOGG failed to open input audio file", 1); free(oggbuffer); return 43; //Return failure: Could not process buffered chart audio } //Decode OGG into memory decoded=alogg_create_sample_from_ogg(oggfile); if(decoded == NULL) { alogg_destroy_ogg(oggfile); free(oggbuffer); return 44; //Return failure: Could not decode chart audio to memory } /* Create a SAMPLE array large enough for the leading silence and the decoded OGG */ bits = alogg_get_wave_bits_ogg(oggfile); stereo = alogg_get_wave_is_stereo_ogg(oggfile); freq = alogg_get_wave_freq_ogg(oggfile); alogg_destroy_ogg(oggfile); //This is no longer needed oggfile = NULL; samples = msec_to_samples(ms); channels = stereo ? 2 : 1; combined = create_sample(bits,stereo,freq,samples+decoded->len); //Create a sample array long enough for the silence and the OGG file if(combined == NULL) { destroy_sample(decoded); return 45; //Return failure: Could not create a sample array for the combined audio } /* Add the PCM data for the silence */ if(bits == 8) { //Create 8 bit PCM data for(ctr=0,index=0;ctr < samples * channels;ctr++) { ((unsigned char *)(combined->data))[index++] = 0x80; } } else { //Create 16 bit PCM data for(ctr=0,index=0;ctr < samples * channels;ctr++) { ((unsigned short *)(combined->data))[index++] = 0x8000; } } /* Add the decoded OGG PCM data*/ if(bits == 8) { //Copy 8 bit PCM data for(ctr=0;ctr < decoded->len * channels;ctr++) { ((unsigned char *)(combined->data))[index++] = ((unsigned char *)(decoded->data))[ctr]; } } else { //Copy 16 bit PCM data for(ctr=0;ctr < decoded->len * channels;ctr++) { ((unsigned short *)(combined->data))[index++] = ((unsigned short *)(decoded->data))[ctr]; } } /* encode the audio */ destroy_sample(decoded); //This is no longer needed free(oggbuffer); (void) replace_filename(wavfn, eof_song_path, "encode.wav", 1024); (void) save_wav(wavfn, combined); destroy_sample(combined); //This is no longer needed (void) replace_filename(soggfn, eof_song_path, "encode.ogg", 1024); bitrate = alogg_get_bitrate_ogg(eof_music_track) / 1000; if(!bitrate) { //A user found that in an audio file with a really high sample rate (ie. 96KHz), alogg_get_bitrate_ogg() may return zero instead of an expected value bitrate = 256; //In case this happens, use a bitrate of 256Kbps, which should be good enough for a very high quality file } #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -b %d \"%s\"", soggfn, bitrate, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -b %d \"%s\"", soggfn, bitrate, wavfn); #endif (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows: %s", sys_command); eof_log(eof_log_string, 1); if(eof_system(sys_command)) { //If oggenc failed, retry again by specifying a quality level (specifying bitrate can fail in some circumstances) eof_log("\t\toggenc failed. Retrying by specifying a quality level instead of a target bitrate", 1); #ifdef ALLEGRO_WINDOWS (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc2 -o \"%s\" -q 9 \"%s\"", soggfn, wavfn); #else (void) uszprintf(sys_command, (int) sizeof(sys_command) - 1, "oggenc -o \"%s\" -q 9 \"%s\"", soggfn, wavfn); #endif (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tCalling oggenc as follows: %s", sys_command); eof_log(eof_log_string, 1); if(eof_system(sys_command)) { //If oggenc failed again char tempfname[30] = {0}; char redirect[35] = {0}; if(eof_validate_temp_folder()) { //Ensure the correct working directory and presence of the temporary folder eof_log("\tCould not validate working directory and temp folder", 1); return 46; //Return failure: Could not validate cwd and temp folder } (void) snprintf(tempfname, sizeof(tempfname) - 1, "%soggenc.log", eof_temp_path_s); (void) snprintf(redirect, sizeof(redirect) - 1, " 2> %s", tempfname); (void) ustrzcat(sys_command, (int) sizeof(sys_command) - 1, redirect); //Append a redirection to the command to capture the output of oggenc if(eof_system(sys_command)) { //Run one last time to catch the error output (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "\tOggenc failed. Please see %s for any errors it gave.", tempfname); eof_log(eof_log_string, 1); eof_fix_window_title(); return 47; //Return failure: Could not encode combined audio } } } /* replace the current OGG file with the new file */ (void) eof_copy_file(soggfn, oggfn); //Copy encode.ogg to the filename of the original OGG /* clean up */ (void) delete_file(soggfn); //Delete encode.ogg (void) delete_file(wavfn); //Delete encode.wav if(eof_load_ogg(oggfn, 0)) { //If the combined audio was loaded eof_fix_waveform_graph(); eof_fix_spectrogram(); eof_fix_window_title(); eof_chart_length = eof_music_length; return 0; //Return success } eof_fix_window_title(); return 48; //Return error: Could not load new audio }
struct wavestruct *eof_create_waveform(char *oggfilename, unsigned long slicelength) { ALOGG_OGG *oggstruct = NULL; SAMPLE *audio = NULL; void * oggbuffer = NULL; struct wavestruct *waveform = NULL; static struct wavestruct emptywaveform; //all variables in this auto initialize to value 0 char done = 0; //-1 on unsuccessful completion, 1 on successful completion unsigned long slicenum = 0; eof_log("\tGenerating waveform", 1); eof_log("eof_create_waveform() entered", 1); set_window_title("Generating Waveform Graph..."); if((oggfilename == NULL) || !slicelength) { eof_log("Waveform: Invalid parameters", 1); return NULL; } //Load OGG file into memory oggbuffer = eof_buffer_file(oggfilename, 0); if(!oggbuffer) { (void) snprintf(eof_log_string, sizeof(eof_log_string) - 1, "Waveform: Failed to open input audio file: %s",strerror(errno)); eof_log(eof_log_string, 1); return NULL; } oggstruct = alogg_create_ogg_from_buffer(oggbuffer, (int)file_size_ex(oggfilename)); if(oggstruct == NULL) { eof_log("Waveform: ALOGG failed to open input audio file", 1); free(oggbuffer); return NULL; } //Decode OGG into memory audio = alogg_create_sample_from_ogg(oggstruct); if(audio == NULL) { eof_log("Waveform: ALOGG failed to decode input audio file", 1); done = -1; } else if((audio->bits != 8) && (audio->bits != 16)) //This logic currently only supports 8 and 16 bit audio { eof_log("Waveform: Invalid sample size", 1); done = -1; } else { //Initialize waveform structure waveform = (struct wavestruct *)malloc(sizeof(struct wavestruct)); if(waveform == NULL) { eof_log("Waveform: Unable to allocate memory for the waveform structure", 1); done = -1; } else { *waveform = emptywaveform; //Set all variables to value zero waveform->slicelength = slicelength; if(alogg_get_wave_is_stereo_ogg(oggstruct)) //If this audio file has two audio channels waveform->is_stereo = 1; else waveform->is_stereo = 0; if(audio->bits == 8) waveform->zeroamp = 128; //128 represents amplitude 0 for unsigned 8 bit audio samples else waveform->zeroamp = 32768; //32768 represents amplitude 0 for unsigned 16 bit audio samples waveform->oggfilename = (char *)malloc(strlen(oggfilename)+1); if(waveform->oggfilename == NULL) { eof_log("Waveform: Unable to allocate memory for the audio filename string", 1); done = -1; } else { waveform->slicesize = audio->freq * slicelength / 1000; //Find the number of samples in each slice if((audio->freq * slicelength) % 1000) //If there was any remainder waveform->slicesize++; //Increment the size of the slice waveform->numslices = (double)audio->len / ((double)audio->freq * (double)slicelength / 1000.0); //Find the number of slices to process if(audio->len % waveform->numslices) //If there's any remainder waveform->numslices++; //Increment the number of slices strcpy(waveform->oggfilename,oggfilename); waveform->left.slices = (struct waveformslice *)malloc(sizeof(struct waveformslice) * waveform->numslices); if(waveform->left.slices == NULL) { eof_log("Waveform: Unable to allocate memory for the left channel waveform data", 1); done = -1; } else if(waveform->is_stereo) //If this OGG is stereo { //Allocate memory for the right channel waveform data waveform->right.slices = (struct waveformslice *)malloc(sizeof(struct waveformslice) * waveform->numslices); if(waveform->right.slices == NULL) { eof_log("Waveform: Unable to allocate memory for the right channel waveform data", 1); done = -1; } } } } } while(!done) { done = eof_process_next_waveform_slice(waveform, audio, slicenum++); } //Cleanup if(oggstruct != NULL) alogg_destroy_ogg(oggstruct); if(audio != NULL) destroy_sample(audio); if(oggbuffer) free(oggbuffer); if(done == -1) //Unsuccessful completion { if(waveform) { if(waveform->oggfilename) free(waveform->oggfilename); free(waveform); } allegro_message("Failed to generate waveform. See log for details"); return NULL; //Return error } //Cache the difference between each channel's zero amplitude and its maximum amplitude for optimized rendering if(waveform->left.maxamp > waveform->zeroamp) waveform->left.maxampoffset = waveform->left.maxamp - waveform->zeroamp; else waveform->left.maxampoffset = waveform->zeroamp - waveform->left.maxamp; if(waveform->is_stereo) { //If there is right channel waveform data if(waveform->right.maxamp > waveform->zeroamp) waveform->right.maxampoffset = waveform->right.maxamp - waveform->zeroamp; else waveform->right.maxampoffset = waveform->zeroamp - waveform->right.maxamp; } eof_log("\tWaveform generated", 1); return waveform; //Return waveform data }
uint64_t file_size_ex_password(const char *filename, const char *password) { packfile_password(password); uint64_t result = file_size_ex(filename); packfile_password(""); return result; }
void NormalGame::choose_new_ships() { STACKTRACE; char tmp[40]; int i; pause(); message.out("Selecting ships...", 1000); int *slot = new int[num_players]; //choose ships and send them across network for (i = 0; i < num_players; i += 1) { slot[i] = -2; if (player_control[i]->ship) { } else { // if (player_panel[i]) player_panel[i]->window->hide(); // player_panel[i] = NULL; sprintf (tmp, "Player%d", i+1); Fleet *fleet = player_fleet[i]; if (fleet->getSize() == 0) continue; char buffy[512]; if (strlen(fleet->getTitle()) != 0) sprintf(buffy, "%s\n%s\n", player_name[i], fleet->getTitle()); else sprintf(buffy, "%s\n", player_name[i]); slot[i] = player_control[i]->choose_ship(window, buffy, fleet); if (player_control[i]->channel != channel_none) { slot[i] = intel_ordering(slot[i]); log->buffer(player_control[i]->channel, &slot[i], sizeof(int)); log->flush(); //slot[i] = intel_ordering(slot[i]); } } } //recieve the ships that were chosen log->listen(); for (i = 0; i < num_players; i += 1) { if (slot[i] == -2) continue; if (player_control[i]->channel != channel_none) { log->unbuffer(player_control[i]->channel, &slot[i], sizeof(int)); slot[i] = intel_ordering(slot[i]); } } //create the ships that were chosen for (i = 0; i < num_players; i += 1) { if (slot[i] == -2) continue; sprintf (tmp, "Player%d", i+1); //fleet->load("./fleets.tmp", tmp); Fleet *fleet = player_fleet[i]; if (slot[i] == -1) slot[i] = random() % fleet->getSize(); if (slot[i] < 0 || slot[i] >= fleet->getSize()) {tw_error("trying to load invalid ship");} Ship *s = create_ship(fleet->getShipType(slot[i])->id, player_control[i], random(size), random(PI2), player_team[i]); if (!s) {tw_error("unable to create ship");} fleet->clear_slot(slot[i]); fleet->Sort(); //fleet->save("./fleets.tmp", tmp); s->locate(); add ( new WedgeIndicator ( s, 30, i+1 ) ); ShipPanel *panel = new ShipPanel(s); panel->window->init(window); panel->window->locate( 0, 0.9, 0, i * (100.0/480), 0, 0.1, 0, (100.0/480) ); add(panel); add(s->get_ship_phaser()); // add a healthbar for the ship, and also a team indicator. add(new HealthBar(s, &indhealthtoggle)); add(new TeamIndicator(s, &indteamtoggle)); // CHECK FILE SIZES !! to intercept desynch before they happen. int myfsize, otherfsize; myfsize = file_size_ex(s->type->data->file); otherfsize = myfsize; if (player_control[i]->channel != channel_none) { log_int(player_control[i]->channel, otherfsize); } if (otherfsize != myfsize) { // the player who loads the ship doesn't get this message, cause his own file is identical by default tw_error("DAT files have different size! This may cause a desynch. Press Retry to continue"); } } delete[] slot; message.out("Finished selecting ships...", 1500); unpause(); return; }
/* loads a COL file (Animator and Animator Pro format) */ Palette *load_col_file(const char *filename) { #if (MAKE_VERSION(4, 2, 1) >= MAKE_VERSION(ALLEGRO_VERSION, \ ALLEGRO_SUB_VERSION, \ ALLEGRO_WIP_VERSION)) int size = file_size(filename); #else int size = file_size_ex(filename); #endif int pro = (size == 768)? false: true; /* is Animator Pro format? */ div_t d = div(size-8, 3); Palette *pal = NULL; int c, r, g, b; FILE *f; if (!(size) || (pro && d.rem)) /* invalid format */ return NULL; f = fopen(filename, "rb"); if (!f) return NULL; /* Animator format */ if (!pro) { pal = new Palette(FrameNumber(0), 256); for (c=0; c<256; c++) { r = fgetc(f); g = fgetc(f); b = fgetc(f); if (ferror(f)) break; pal->setEntry(c, _rgba(_rgb_scale_6[MID(0, r, 63)], _rgb_scale_6[MID(0, g, 63)], _rgb_scale_6[MID(0, b, 63)], 255)); } } /* Animator Pro format */ else { int magic, version; fgetl(f); /* skip file size */ magic = fgetw(f); /* file format identifier */ version = fgetw(f); /* version file */ /* unknown format */ if (magic != PROCOL_MAGIC_NUMBER || version != 0) { fclose(f); return NULL; } pal = new Palette(FrameNumber(0), MIN(d.quot, 256)); for (c=0; c<pal->size(); c++) { r = fgetc(f); g = fgetc(f); b = fgetc(f); if (ferror(f)) break; pal->setEntry(c, _rgba(MID(0, r, 255), MID(0, g, 255), MID(0, b, 255), 255)); } } fclose(f); return pal; }