| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765 |
- #include "../headers/pitmap.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <string.h>
- uint8_t *file_buffer;
- int current_byte;
- int (*current_printf_function)(const char *__restrict __format, ...) = printf;
- // lsb, the least sig bit is first
- // 1 = 10000000
- char* lsb_byte_to_binary(uint32_t byte, uint8_t bits){
- char* string = malloc(sizeof(char) * (bits + 1));
- for (int i = 0; i < bits; i++){
- string[i] = ((byte >> i) & 1) + 0x30;
- }
- string[bits] = '\0';
- return string;
- }
- // MSB, most sig bit is first
- // 1 = 00000001
- char* msb_byte_to_binary(uint32_t byte, uint8_t bits){
- char* string = malloc(sizeof(char) * (bits + 1));
- for (int i = 0; i < bits; i++){
- string[bits - 1 - i] = ((byte >> i) & 1) + 0x30;
- }
- string[bits] = '\0';
- return string;
- }
- // MSB, most sig bit is first
- // 1 = 00000001
- uint16_t binary_to_int(char* binary, uint8_t number_of_bits){
- uint16_t final_value = 0;
- for (int i = 0; i < number_of_bits; i++){
- final_value += (1 << i) * (binary[number_of_bits - i - 1] - 0x30);
- }
- return final_value;
- }
- // return individial bit's value. Zero indexed
- // msb_get_bit(00100, 2) == 1
- uint8_t msb_get_bit(uint32_t data, uint8_t bit){
- return (data >> bit) & 1;
- }
- // byte reading funcs
- void skip(int bytes_to_skip){
- current_byte += bytes_to_skip;
- }
- int8_t get_1(){
- return file_buffer[current_byte++];
- }
- int16_t get_2(){
- return file_buffer[current_byte++] | file_buffer[current_byte++] << 8;
- }
- int32_t get_4(){
- return file_buffer[current_byte++] | file_buffer[current_byte++] << 8 | file_buffer[current_byte++] << 16 | file_buffer[current_byte++] << 24;
- }
- PM_image* PM_load_bitmap(unsigned char debug_mode){
- PM_image* image = malloc(sizeof(PM_image));
- current_byte = 0;
- // file header
- uint16_t header_field = get_2();
- if (header_field != 19778) {
- (*current_printf_function)("file is not a bitmap file or bitmap is damaged\n");
- return NULL;
- }
- uint32_t file_size = get_4();
- skip(4); // reserved
- uint32_t pixel_buffer_offset = get_4();
-
- // bitmap information header / DIB header
-
- // BITMAPINFOHEADER
- uint32_t header_size = get_4();
- uint32_t image_width = header_size == 12 ? (uint32_t)get_2() : (uint32_t)get_4();
- uint32_t image_height = header_size == 12 ? (uint32_t)get_2() : (uint32_t)get_4();
- skip(2); // color planes, always 1
- uint16_t bits_per_pixel = get_2();
- uint32_t compression_method = get_4();
- uint32_t image_size = get_4();
- int32_t horizontal_res = get_4(); // pixels per meter
- int32_t vertical_res = get_4();
- uint32_t number_of_colors_in_palette = get_4();
- skip(4); // number of important colors, ignored
- (*current_printf_function)("file size is %d bytes\nimage res is %dx%d\ncompression method is #%d\npixel buffer offset is %d\n", file_size, image_width, image_height, compression_method, pixel_buffer_offset);
-
- uint32_t* color_palette;
- if (number_of_colors_in_palette > 0) { // we've got a color palette!
- (*current_printf_function)("color palette exists and has %d colors\n", number_of_colors_in_palette);
-
- // skip to color palette
- current_byte = header_size + 14 + // skip the file header (14 bytes) and the DIB
- 12 * (compression_method == 3) + 16 * (compression_method == 6); // skip the bit fields if they exist
-
- color_palette = malloc(sizeof(uint32_t) * number_of_colors_in_palette);
-
- for (uint32_t i = 0; i < number_of_colors_in_palette; i++){
- // BGR0 -> RGB255
-
- unsigned char r = get_1();
- unsigned char g = get_1();
- unsigned char b = get_1();
-
- color_palette[i] = r << 24 | g << 16 | b << 8 | 255 << 0;
- skip(1);
- }
- }
-
- image->frame_buffer = malloc(sizeof(uint32_t) * image_width * image_height);
- image->frame_delays = NULL;
- image->frame_count = 1;
- image->frame_height = image_height;
- image->width = image_width;
- image->height = image_height;
- // pixel array
- current_byte = pixel_buffer_offset;
- int row_size = ceil((float)(bits_per_pixel * image_width) / (32)) * 4;
- (*current_printf_function)("%d bits per pixel\n", bits_per_pixel);
- switch (bits_per_pixel){
- case (32): { // RGBA 1 byte each
- for (int y = image_height - 1; y >= 0; y--){
- int current_byte_of_row = 0;
- for (uint32_t x = 0; x < image_width; x++){ // starting reversed becuase image data is backwards
- image->frame_buffer[y * image_width + x] = (uint32_t)((uint8_t)get_1() << 24 | (uint8_t)get_1() << 16 | (uint8_t)get_1() << 8 | (uint8_t)get_1());
- current_byte_of_row += 4;
- }
-
- skip(row_size - current_byte_of_row);
- }
- break;
- }
- case (24): { // RGB -> RGBA 1 byte each
- for (int y = image_height - 1; y >= 0; y--){
- int current_byte_of_row = 0;
- for (uint32_t x = 0; x < image_width; x++){ // starting reversed becuase image data is backwards
- image->frame_buffer[y * image_width + x] = (uint32_t)((uint8_t)get_1() << 24 | (uint8_t)get_1() << 16 | (uint8_t)get_1() << 8 | 255);
-
- current_byte_of_row += 3;
- }
-
- skip(row_size - current_byte_of_row);
- }
-
- break;
- }
- case (16): {
- (*current_printf_function)("16 BPP supporet not implemented");
- break;
- }
- case (8): { // paletted
- if (compression_method == 0){ // no compression
- for (int y = image_height - 1; y >= 0; y--){
- for (uint32_t x = 0; x < image_width; x++){ // starting reversed becuase image data is backwards
- uint8_t palette_index = get_1();
- // (*current_printf_function)("current pixel is %dx%d\npalette index is %d\n", x, y, palette_index);
-
- image->frame_buffer[y * image_width + x] = color_palette[palette_index];
- }
- }
- }
- else { // assume RLE
- uint16_t x = 0;
- uint16_t y = image_height - 1;
- unsigned char reading_file = 1;
-
- while (reading_file){
- uint8_t number_of_repetitions = get_1();
- uint8_t palette_index = get_1();
- if (number_of_repetitions > 0){
- for (uint8_t pixel = 0; pixel < number_of_repetitions; pixel++){
- // (*current_printf_function)("current pixel is %dx%d\npalette index is %d\n", x, y, palette_index);
- image->frame_buffer[y * image_width + x++] = color_palette[palette_index];
- }
- } else {
- if (palette_index == 0) { // end of a line
- x = 0;
- y--;
- } else if (palette_index == 1){ // end of image
- reading_file = 0;
- } else { // delta
- x += get_1();
- y -= get_1();
- }
- }
- }}
-
- break;
- }
- case (4): { // paletted
- (*current_printf_function)("4 BPP supporet not implemented");
-
- break;
- }
- case (1): {
- (*current_printf_function)("1 BPP supporet not implemented");
-
- break;
- }
- }
- return image;
- }
- PM_image* PM_load_gif(unsigned char debug_mode){
- PM_image* image = malloc(sizeof(PM_image));
- current_byte = 0;
- // magic number
- uint8_t is_87a = 0;
- if (get_1() != 0x47 || get_1() != 0x49 || get_1() != 0x46 || get_1() != 0x38 || get_1() != 0x39 || get_1() != 0x61){
- current_byte = 4;
- if (get_1() != 0x37){
- (*current_printf_function)("file is not a gif file, or gif is damaged\n");
- return NULL;
- } else {
- (*current_printf_function)("gif is verision 87a\n");
- is_87a = 1;
- }
-
- skip(1);
- } else {
- (*current_printf_function)("gif is verision 89a\n");
- }
-
- // image info
- uint16_t frame_count = 0;
-
- uint16_t image_width = get_2();
- uint16_t image_height = get_2();
-
- image->frame_height = image_height;
- image->frame_buffer = NULL;
- image->frame_delays = NULL;
- image->width = image_width;
- if (is_87a){ // 87a doesnt have GCE so just do everything that it would do
- frame_count++;
- image->height = image_height * frame_count;
- image->frame_buffer = realloc(image->frame_buffer, sizeof(uint32_t) * image_width * image_height);
- }
- uint16_t total_image_height = image_height;
- uint8_t color_table_info = get_1();
- uint8_t background_color = get_1();
- uint8_t pixel_aspect_ratio = get_1();
- (*current_printf_function)("color table info: %x\n", color_table_info);
- // value used for encoding actual size of color table
- uint8_t size_of_gct = (color_table_info & 0x07); // bit mask 0000 0111
- // 0 = unsorted, 1 = sorted by importance
- uint8_t color_table_sort_flag = (color_table_info & 0x08) >> 3; // bit mask 0000 1000
- // original color depth of the image when it was created, bits per color
- // doesn't matter (?)
- uint8_t color_resolution = ((color_table_info & 0x70) >> 4) + 1; // bit mask 0111 0000
- // 1 = gct exists
- uint8_t gct_flag = (color_table_info & 0x80) >> 7; // bit mask 1000 0000
- // total number of colors in gct
- uint16_t number_of_colors_in_gct = 1 << (size_of_gct + 1);
- (*current_printf_function)("size_of_gct: %d color_table_sort_flag: %d color_resolution: %d gct_flag: %d number_of_colors_in_gct: %d\n", size_of_gct
- ,color_table_sort_flag
- ,color_resolution
- ,gct_flag
- ,number_of_colors_in_gct);
- uint32_t* global_color_table = malloc(sizeof(uint32_t) * number_of_colors_in_gct);
- // global color table (if present)
- if (gct_flag){
- (*current_printf_function)("started reading color table block at byte #%d\n", current_byte);
-
- for (int i = 0; i < number_of_colors_in_gct; i++){
- // just gonna assume 8bit
- unsigned char r = get_1();
- unsigned char g = get_1();
- unsigned char b = get_1();
-
- global_color_table[i] = b << 24 | g << 16 | r << 8 | 255 << 0;
- }
- // image->frame_buffer = global_color_table;
- // image->width = number_of_colors_in_gct + 1;
- // image->frame_buffer = realloc(image->frame_buffer, sizeof(uint32_t) * (number_of_colors_in_gct + 1));
- // image->frame_buffer[number_of_colors_in_gct] = 0xFF00FFFF;
- // image->height = 1;
- // return image;
- }
- uint8_t transparent_color_gct_index = 0;
- uint8_t has_transparency = 0;
- unsigned char still_reading_file = 1;
- while (still_reading_file){
- switch(get_1()){
- case 0x21: { // "!" graphics control extention
- if ((uint8_t)get_1() != (uint8_t)0xF9) break; // a different block denoted by "!", ignore
-
- (*current_printf_function)("started reading graphics control extention block at byte #%d\n", current_byte);
- frame_count++;
- image->height = image_height * frame_count;
- image->frame_buffer = realloc(image->frame_buffer, sizeof(uint32_t) * image_width * image_height * frame_count);
- uint8_t gce_size = get_1();
- uint8_t packed_field = get_1(); // bit field
- uint16_t delay_time = get_2();
- transparent_color_gct_index = get_1();
- skip(1);
- image->frame_delays = realloc(image->frame_delays, sizeof(uint16_t) * frame_count);
- image->frame_delays[frame_count - 1] = delay_time;
- // "disposal method" is the first variable in the packed field
- // we can ignore this because I think it's mostly for UI programs
- // next is "input method" and it doesn't rly make sense to me to
- // exist in the first place
-
- // transparency flag; transparency index is given
- (*current_printf_function)("transparency index: %d\n", transparent_color_gct_index);
- has_transparency = packed_field & 1;
- break;
- }
- case 0x2C: { // "," image descriptor
- (*current_printf_function)("started reading image descriptor block at byte #%d\n", current_byte - 1);
- uint16_t image_left_pos = get_2();
- uint16_t image_top_pos = get_2();
- uint16_t image_descriptor_width = get_2();
- uint16_t image_descriptor_height = get_2();
- (*current_printf_function)("width height %dx%d\n", image_descriptor_width, image_descriptor_height);
- uint8_t packed_field = get_1();
- uint8_t local_color_table_flag = (packed_field & 0x80) >> 7;
- uint8_t interlace_flag = (packed_field & 0x40) >> 6;
- uint8_t local_color_table_is_sorted_flag = (packed_field & 0x20) >> 5;
- uint16_t entries_of_local_color_table = 1 << ((packed_field & 7) + 1);
- uint32_t* local_color_table = NULL;
- if (local_color_table_flag){
- (*current_printf_function)("theres a local color table\n");
- local_color_table = malloc(sizeof(uint32_t) * entries_of_local_color_table);
- for (int i = 0; i < entries_of_local_color_table; i++){
- // just gonna assume 8bit again
- unsigned char r = get_1();
- unsigned char g = get_1();
- unsigned char b = get_1();
-
- local_color_table[i] = b << 24 | g << 16 | r << 8 | 255 << 0;
- }
- // image->frame_buffer = local_color_table;
- // image->width = sqrt(entries_of_local_color_table);
- // image->height = sqrt(entries_of_local_color_table);
- // return image;
- }
- (*current_printf_function)("started reading image data block at byte #%d\n", current_byte);
- uint8_t number_of_initial_lzw_bits = get_1(); // how many possible colors and also LZW size + 1 = how many bits you need
-
- uint8_t image_data_byte_length = get_1();
- uint16_t* decoded_color_codes = malloc(sizeof(uint16_t) * image_descriptor_width * image_descriptor_height);
- uint32_t decoded_color_code_count = 0;
- uint32_t* code_table = malloc(sizeof(uint32_t) * 4096 * 2);
- (*current_printf_function)("LZW initial bit size: %d\n", number_of_initial_lzw_bits);
-
- uint8_t* image_data_byte_array = NULL;
- uint32_t total_image_data_byte_length = 0;
-
- while (image_data_byte_length != 0){
- total_image_data_byte_length += image_data_byte_length;
- image_data_byte_array = realloc(image_data_byte_array, sizeof(uint8_t) * total_image_data_byte_length);
-
- for (int i = 0; i < image_data_byte_length; i++){
- image_data_byte_array[total_image_data_byte_length - image_data_byte_length + i] = get_1();
- (*current_printf_function)("%s ", lsb_byte_to_binary(image_data_byte_array[total_image_data_byte_length - image_data_byte_length + i], 8));
- }
- (*current_printf_function)("\n");
- image_data_byte_length = get_1();
- }
- uint8_t lzw_bit_count = number_of_initial_lzw_bits + 1;
- uint32_t current_bit = 0;
- uint8_t is_parsing = 1;
- uint32_t clear_code = 1 << number_of_initial_lzw_bits;
- uint32_t stop_code = clear_code + 1;
- uint32_t previous_code = stop_code;
- uint32_t current_highest_defined_code = stop_code;
- (*current_printf_function)("clear code: %d stop code: %d\n", clear_code, stop_code);
- while (is_parsing){
- uint32_t code = 0;
-
- if (current_bit < total_image_data_byte_length * 8){
- for (uint32_t i = current_bit; i < lzw_bit_count + current_bit; i++){
- uint32_t current_byte = floor(i / 8);
- uint32_t current_bit_in_byte = i % 8;
-
- code += msb_get_bit(image_data_byte_array[current_byte], current_bit_in_byte) * (1 << (i - current_bit));
- }
- current_bit += lzw_bit_count;
- } else {
- (*current_printf_function)("error: read past data length\n");
- exit(1);
- }
- (*current_printf_function)("parsing code %s (%d)\n", msb_byte_to_binary(code, lzw_bit_count), (int)code);
- if (code == clear_code){
- (*current_printf_function)("clear code!\n");
- for (int i = 0; i < 4096 * 2; i++){
- code_table[i] = (uint32_t)(0) - 1;
- }
- current_highest_defined_code = stop_code;
- lzw_bit_count = number_of_initial_lzw_bits + 1;
- }
- else if (code == stop_code){
- (*current_printf_function)("stop code!\n");
- is_parsing = 0;
- }
- else {
- uint32_t deconstructed_code = code;
- uint8_t can_standardly_add_code = 1;
- // add decoded values
- if (code < clear_code){
- (*current_printf_function)("literal!\n");
- decoded_color_codes[decoded_color_code_count++] = deconstructed_code;
- }
- else if (code_table[deconstructed_code * 2] == (uint32_t)(0) - 1){ // code is undefined
- (*current_printf_function)("undefined representative!\n");
- can_standardly_add_code = 0;
- uint32_t first_code = previous_code;
- while (first_code > clear_code){
- if (code_table[first_code * 2] == ((uint32_t)-1)){
- printf("error: code points to undefined code\n");
- exit(1);
- }
- first_code = code_table[first_code * 2];
- }
- code_table[++current_highest_defined_code * 2] = previous_code;
- code_table[current_highest_defined_code * 2 + 1] = first_code;
- if (current_highest_defined_code == (uint64_t)((1 << lzw_bit_count) - 1)){
- lzw_bit_count++;
- }
- uint16_t temp_decoded_color_count = 0;
- uint16_t cur_allocated_temps = 1000;
- uint32_t* temp_decoded_colors = malloc(sizeof(uint32_t) * cur_allocated_temps);
- uint32_t deconstructed_prev_code = previous_code;
-
- if (deconstructed_prev_code < clear_code) decoded_color_codes[decoded_color_code_count++] = previous_code;
- while (deconstructed_prev_code > clear_code){
- if (code_table[deconstructed_prev_code * 2] == (uint32_t)(0) - 1){
- printf("error: code points to undefined code\n");
- exit(1);
- }
- if (temp_decoded_color_count >= cur_allocated_temps){
- cur_allocated_temps += 1000;
- temp_decoded_colors = realloc(temp_decoded_colors, sizeof(uint32_t) * cur_allocated_temps);
- }
- temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_prev_code * 2 + 1]; // add the literal
-
- if (code_table[deconstructed_prev_code * 2] < clear_code)
- temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_prev_code * 2];
- deconstructed_prev_code = code_table[deconstructed_prev_code * 2];
- }
- for (int i = temp_decoded_color_count - 1; i >= 0; i--){
- decoded_color_codes[decoded_color_code_count++] = temp_decoded_colors[i];
- }
- free(temp_decoded_colors);
- decoded_color_codes[decoded_color_code_count++] = first_code;
- (*current_printf_function)("added new code (from undefined code branch): code_table[%d * 2] == %d, %d\n", current_highest_defined_code, previous_code, first_code);
- }
- else { // code is defined
- (*current_printf_function)("defined representative! code_table[%d * 2] == %d, %d\n", code, code_table[deconstructed_code * 2], code_table[deconstructed_code * 2 + 1]);
- uint16_t temp_decoded_color_count = 0;
- uint16_t cur_allocated_temps = 1000;
- uint32_t* temp_decoded_colors = malloc(sizeof(uint32_t) * cur_allocated_temps);
- while (deconstructed_code > clear_code){
- if (code_table[deconstructed_code * 2] == (uint32_t)(0) - 1){
- printf("error: code points to undefined code\n");
- exit(1);
- }
- if (temp_decoded_color_count >= cur_allocated_temps){
- cur_allocated_temps += 1000;
- temp_decoded_colors = realloc(temp_decoded_colors, sizeof(uint32_t) * cur_allocated_temps);
- }
- temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_code * 2 + 1]; // add the literal
-
- if (code_table[deconstructed_code * 2] < clear_code)
- temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_code * 2];
- deconstructed_code = code_table[deconstructed_code * 2];
- }
- for (int i = temp_decoded_color_count - 1; i >= 0; i--){
- decoded_color_codes[decoded_color_code_count++] = temp_decoded_colors[i];
- }
- free(temp_decoded_colors);
- }
- // create new code table entry
- if (can_standardly_add_code && previous_code != clear_code){
- uint32_t first_code = code;
- while (first_code > clear_code){
- if (code_table[first_code * 2] == (uint32_t)(0) - 1){
- printf("error: code points to undefined code\n");
- exit(1);
- }
- first_code = code_table[first_code * 2];
- }
- code_table[++current_highest_defined_code * 2] = previous_code;
- code_table[current_highest_defined_code * 2 + 1] = first_code;
- if (current_highest_defined_code == (uint64_t)((1 << lzw_bit_count) - 1)){
- lzw_bit_count++;
- }
- (*current_printf_function)("added new code (from standard branch): code_table[%d * 2] == %d, %d\n", current_highest_defined_code, previous_code, first_code);
- }
- }
- // for (uint32_t i = 0; i < decoded_color_code_count; i++){
- // if (!decoded_color_codes[i])(*current_printf_function)("██ ");
- // else (*current_printf_function)("░░ ");
-
- // if ((i + 1) % image_descriptor_width == 0) (*current_printf_function)("\n");
- // }
- (*current_printf_function)("\n");
- (*current_printf_function)("%d/%d colors decoded\n", decoded_color_code_count, image_descriptor_width * image_descriptor_height);
-
- previous_code = code;
- }
- if (decoded_color_code_count != image_descriptor_width * image_descriptor_height){
- printf("error: number of decoded pixels is not equal to number of total pixels\n");
- }
- (*current_printf_function)("image descriptor is %dx%d, offset is %dx%d\n", image_descriptor_width, image_descriptor_height, image_left_pos, image_top_pos);
- if (frame_count > 1){
- for (int y = 0; y < image_height; y++){
- for (int x = 0; x < image_width; x++){
- uint32_t frame_offset_1 = image_height * (frame_count - 1);
- uint32_t frame_offset_2 = image_height * (frame_count - 2);
-
- image->frame_buffer[(y + frame_offset_1) * image_width + x] =
- image->frame_buffer[(y + frame_offset_2) * image_width + x];
- }
- }
- }
- for (int y = 0; y < image_descriptor_height; y++){
- for (int x = 0; x < image_descriptor_width; x++){
- if (has_transparency && decoded_color_codes[y * image_descriptor_width + x] == transparent_color_gct_index)
- continue;
- else{
- uint32_t frame_offset = image_height * (frame_count - 1);
- uint32_t color = local_color_table_flag ?
- local_color_table[decoded_color_codes[y * image_descriptor_width + x]] :
- global_color_table[decoded_color_codes[y * image_descriptor_width + x]];
- image->frame_buffer[(y + image_top_pos + frame_offset) * image_width + x + image_left_pos] = color;
- }
- }
- }
-
- break;
- }
- case 0x3B: { // ";" EOF
- (*current_printf_function)("EOF at byte #%d\n", current_byte - 1);
- still_reading_file = 0;
- break;
- }
- }
- }
- image->frame_count = frame_count;
- return image;
- }
- int printf_override(const char *__restrict __format, ...){
- return 0;
- }
- PM_image* PM_load_image(const char *filename, unsigned char debug_mode){
- FILE *fp = fopen(filename, "rb");
- if (fp == NULL){
- (*current_printf_function)("file does not exist !!!\n");
- return NULL;
- }
- fseek(fp, 0, SEEK_END);
- long size = ftell(fp);
- rewind(fp);
- file_buffer = malloc(size);
- fread(file_buffer, 1, size, fp);
- fclose(fp);
- // see what the file type is
- char* mutable_filename = malloc(sizeof(char) * (strlen(filename) + 1));
- strcpy(mutable_filename, filename);
- char *strtok_string = strtok(mutable_filename, ".");
- char *filetype_string;
-
- while(strtok_string != NULL) {
- filetype_string = strtok_string;
- strtok_string = strtok(NULL, ".");
- }
- // override (*current_printf_function) so there is no debug output
- if (!debug_mode){
- current_printf_function = printf_override;
- }
- if (!strcmp(filetype_string, "gif") || !strcmp(filetype_string, "GIF")){ // GIF file
- return PM_load_gif(debug_mode);
- } else
- if (!strcmp(filetype_string, "bmp") || !strcmp(filetype_string, "BMP")){ // BMP file
- return PM_load_bitmap(debug_mode);
- }
- (*current_printf_function)("file is unreadable by PitMap\n");
- return NULL;
- }
- void PM_free_image(PM_image* image){
- if (image){
- if (image->frame_buffer) free(image->frame_buffer);
- if (image->frame_delays) free(image->frame_delays);
- free(image);
- } else
- printf("can't free a NULL image!\n");
- }
|