main.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. #include "../headers/pitmap.h"
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <string.h>
  6. uint8_t *file_buffer;
  7. int current_byte;
  8. int (*current_printf_function)(const char *__restrict __format, ...) = printf;
  9. // lsb, the least sig bit is first
  10. // 1 = 10000000
  11. char* lsb_byte_to_binary(uint32_t byte, uint8_t bits){
  12. char* string = malloc(sizeof(char) * (bits + 1));
  13. for (int i = 0; i < bits; i++){
  14. string[i] = ((byte >> i) & 1) + 0x30;
  15. }
  16. string[bits] = '\0';
  17. return string;
  18. }
  19. // MSB, most sig bit is first
  20. // 1 = 00000001
  21. char* msb_byte_to_binary(uint32_t byte, uint8_t bits){
  22. char* string = malloc(sizeof(char) * (bits + 1));
  23. for (int i = 0; i < bits; i++){
  24. string[bits - 1 - i] = ((byte >> i) & 1) + 0x30;
  25. }
  26. string[bits] = '\0';
  27. return string;
  28. }
  29. // MSB, most sig bit is first
  30. // 1 = 00000001
  31. uint16_t binary_to_int(char* binary, uint8_t number_of_bits){
  32. uint16_t final_value = 0;
  33. for (int i = 0; i < number_of_bits; i++){
  34. final_value += (1 << i) * (binary[number_of_bits - i - 1] - 0x30);
  35. }
  36. return final_value;
  37. }
  38. // return individial bit's value. Zero indexed
  39. // msb_get_bit(00100, 2) == 1
  40. uint8_t msb_get_bit(uint32_t data, uint8_t bit){
  41. return (data >> bit) & 1;
  42. }
  43. // byte reading funcs
  44. void skip(int bytes_to_skip){
  45. current_byte += bytes_to_skip;
  46. }
  47. int8_t get_1(){
  48. return file_buffer[current_byte++];
  49. }
  50. int16_t get_2(){
  51. return file_buffer[current_byte++] | file_buffer[current_byte++] << 8;
  52. }
  53. int32_t get_4(){
  54. return file_buffer[current_byte++] | file_buffer[current_byte++] << 8 | file_buffer[current_byte++] << 16 | file_buffer[current_byte++] << 24;
  55. }
  56. PM_image* PM_load_bitmap(unsigned char debug_mode){
  57. PM_image* image = malloc(sizeof(PM_image));
  58. current_byte = 0;
  59. // file header
  60. uint16_t header_field = get_2();
  61. if (header_field != 19778) {
  62. (*current_printf_function)("file is not a bitmap file or bitmap is damaged\n");
  63. return NULL;
  64. }
  65. uint32_t file_size = get_4();
  66. skip(4); // reserved
  67. uint32_t pixel_buffer_offset = get_4();
  68. // bitmap information header / DIB header
  69. // BITMAPINFOHEADER
  70. uint32_t header_size = get_4();
  71. uint32_t image_width = header_size == 12 ? (uint32_t)get_2() : (uint32_t)get_4();
  72. uint32_t image_height = header_size == 12 ? (uint32_t)get_2() : (uint32_t)get_4();
  73. skip(2); // color planes, always 1
  74. uint16_t bits_per_pixel = get_2();
  75. uint32_t compression_method = get_4();
  76. uint32_t image_size = get_4();
  77. int32_t horizontal_res = get_4(); // pixels per meter
  78. int32_t vertical_res = get_4();
  79. uint32_t number_of_colors_in_palette = get_4();
  80. skip(4); // number of important colors, ignored
  81. (*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);
  82. uint32_t* color_palette;
  83. if (number_of_colors_in_palette > 0) { // we've got a color palette!
  84. (*current_printf_function)("color palette exists and has %d colors\n", number_of_colors_in_palette);
  85. // skip to color palette
  86. current_byte = header_size + 14 + // skip the file header (14 bytes) and the DIB
  87. 12 * (compression_method == 3) + 16 * (compression_method == 6); // skip the bit fields if they exist
  88. color_palette = malloc(sizeof(uint32_t) * number_of_colors_in_palette);
  89. for (uint32_t i = 0; i < number_of_colors_in_palette; i++){
  90. // BGR0 -> RGB255
  91. unsigned char r = get_1();
  92. unsigned char g = get_1();
  93. unsigned char b = get_1();
  94. color_palette[i] = r << 24 | g << 16 | b << 8 | 255 << 0;
  95. skip(1);
  96. }
  97. }
  98. image->frame_buffer = malloc(sizeof(uint32_t) * image_width * image_height);
  99. image->frame_delays = NULL;
  100. image->frame_count = 1;
  101. image->frame_height = image_height;
  102. image->width = image_width;
  103. image->height = image_height;
  104. // pixel array
  105. current_byte = pixel_buffer_offset;
  106. int row_size = ceil((float)(bits_per_pixel * image_width) / (32)) * 4;
  107. (*current_printf_function)("%d bits per pixel\n", bits_per_pixel);
  108. switch (bits_per_pixel){
  109. case (32): { // RGBA 1 byte each
  110. for (int y = image_height - 1; y >= 0; y--){
  111. int current_byte_of_row = 0;
  112. for (uint32_t x = 0; x < image_width; x++){ // starting reversed becuase image data is backwards
  113. 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());
  114. current_byte_of_row += 4;
  115. }
  116. skip(row_size - current_byte_of_row);
  117. }
  118. break;
  119. }
  120. case (24): { // RGB -> RGBA 1 byte each
  121. for (int y = image_height - 1; y >= 0; y--){
  122. int current_byte_of_row = 0;
  123. for (uint32_t x = 0; x < image_width; x++){ // starting reversed becuase image data is backwards
  124. 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);
  125. current_byte_of_row += 3;
  126. }
  127. skip(row_size - current_byte_of_row);
  128. }
  129. break;
  130. }
  131. case (16): {
  132. (*current_printf_function)("16 BPP supporet not implemented");
  133. break;
  134. }
  135. case (8): { // paletted
  136. if (compression_method == 0){ // no compression
  137. for (int y = image_height - 1; y >= 0; y--){
  138. for (uint32_t x = 0; x < image_width; x++){ // starting reversed becuase image data is backwards
  139. uint8_t palette_index = get_1();
  140. // (*current_printf_function)("current pixel is %dx%d\npalette index is %d\n", x, y, palette_index);
  141. image->frame_buffer[y * image_width + x] = color_palette[palette_index];
  142. }
  143. }
  144. }
  145. else { // assume RLE
  146. uint16_t x = 0;
  147. uint16_t y = image_height - 1;
  148. unsigned char reading_file = 1;
  149. while (reading_file){
  150. uint8_t number_of_repetitions = get_1();
  151. uint8_t palette_index = get_1();
  152. if (number_of_repetitions > 0){
  153. for (uint8_t pixel = 0; pixel < number_of_repetitions; pixel++){
  154. // (*current_printf_function)("current pixel is %dx%d\npalette index is %d\n", x, y, palette_index);
  155. image->frame_buffer[y * image_width + x++] = color_palette[palette_index];
  156. }
  157. } else {
  158. if (palette_index == 0) { // end of a line
  159. x = 0;
  160. y--;
  161. } else if (palette_index == 1){ // end of image
  162. reading_file = 0;
  163. } else { // delta
  164. x += get_1();
  165. y -= get_1();
  166. }
  167. }
  168. }}
  169. break;
  170. }
  171. case (4): { // paletted
  172. (*current_printf_function)("4 BPP supporet not implemented");
  173. break;
  174. }
  175. case (1): {
  176. (*current_printf_function)("1 BPP supporet not implemented");
  177. break;
  178. }
  179. }
  180. return image;
  181. }
  182. PM_image* PM_load_gif(unsigned char debug_mode){
  183. PM_image* image = malloc(sizeof(PM_image));
  184. current_byte = 0;
  185. // magic number
  186. uint8_t is_87a = 0;
  187. if (get_1() != 0x47 || get_1() != 0x49 || get_1() != 0x46 || get_1() != 0x38 || get_1() != 0x39 || get_1() != 0x61){
  188. current_byte = 4;
  189. if (get_1() != 0x37){
  190. (*current_printf_function)("file is not a gif file, or gif is damaged\n");
  191. return NULL;
  192. } else {
  193. (*current_printf_function)("gif is verision 87a\n");
  194. is_87a = 1;
  195. }
  196. skip(1);
  197. } else {
  198. (*current_printf_function)("gif is verision 89a\n");
  199. }
  200. // image info
  201. uint16_t frame_count = 0;
  202. uint16_t image_width = get_2();
  203. uint16_t image_height = get_2();
  204. image->frame_height = image_height;
  205. image->frame_buffer = NULL;
  206. image->frame_delays = NULL;
  207. image->width = image_width;
  208. if (is_87a){ // 87a doesnt have GCE so just do everything that it would do
  209. frame_count++;
  210. image->height = image_height * frame_count;
  211. image->frame_buffer = realloc(image->frame_buffer, sizeof(uint32_t) * image_width * image_height);
  212. }
  213. uint16_t total_image_height = image_height;
  214. uint8_t color_table_info = get_1();
  215. uint8_t background_color = get_1();
  216. uint8_t pixel_aspect_ratio = get_1();
  217. (*current_printf_function)("color table info: %x\n", color_table_info);
  218. // value used for encoding actual size of color table
  219. uint8_t size_of_gct = (color_table_info & 0x07); // bit mask 0000 0111
  220. // 0 = unsorted, 1 = sorted by importance
  221. uint8_t color_table_sort_flag = (color_table_info & 0x08) >> 3; // bit mask 0000 1000
  222. // original color depth of the image when it was created, bits per color
  223. // doesn't matter (?)
  224. uint8_t color_resolution = ((color_table_info & 0x70) >> 4) + 1; // bit mask 0111 0000
  225. // 1 = gct exists
  226. uint8_t gct_flag = (color_table_info & 0x80) >> 7; // bit mask 1000 0000
  227. // total number of colors in gct
  228. uint16_t number_of_colors_in_gct = 1 << (size_of_gct + 1);
  229. (*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
  230. ,color_table_sort_flag
  231. ,color_resolution
  232. ,gct_flag
  233. ,number_of_colors_in_gct);
  234. uint32_t* global_color_table = malloc(sizeof(uint32_t) * number_of_colors_in_gct);
  235. // global color table (if present)
  236. if (gct_flag){
  237. (*current_printf_function)("started reading color table block at byte #%d\n", current_byte);
  238. for (int i = 0; i < number_of_colors_in_gct; i++){
  239. // just gonna assume 8bit
  240. unsigned char r = get_1();
  241. unsigned char g = get_1();
  242. unsigned char b = get_1();
  243. global_color_table[i] = b << 24 | g << 16 | r << 8 | 255 << 0;
  244. }
  245. // image->frame_buffer = global_color_table;
  246. // image->width = number_of_colors_in_gct + 1;
  247. // image->frame_buffer = realloc(image->frame_buffer, sizeof(uint32_t) * (number_of_colors_in_gct + 1));
  248. // image->frame_buffer[number_of_colors_in_gct] = 0xFF00FFFF;
  249. // image->height = 1;
  250. // return image;
  251. }
  252. uint8_t transparent_color_gct_index = 0;
  253. uint8_t has_transparency = 0;
  254. unsigned char still_reading_file = 1;
  255. while (still_reading_file){
  256. switch(get_1()){
  257. case 0x21: { // "!" graphics control extention
  258. if ((uint8_t)get_1() != (uint8_t)0xF9) break; // a different block denoted by "!", ignore
  259. (*current_printf_function)("started reading graphics control extention block at byte #%d\n", current_byte);
  260. frame_count++;
  261. image->height = image_height * frame_count;
  262. image->frame_buffer = realloc(image->frame_buffer, sizeof(uint32_t) * image_width * image_height * frame_count);
  263. uint8_t gce_size = get_1();
  264. uint8_t packed_field = get_1(); // bit field
  265. uint16_t delay_time = get_2();
  266. transparent_color_gct_index = get_1();
  267. skip(1);
  268. image->frame_delays = realloc(image->frame_delays, sizeof(uint16_t) * frame_count);
  269. image->frame_delays[frame_count - 1] = delay_time;
  270. // "disposal method" is the first variable in the packed field
  271. // we can ignore this because I think it's mostly for UI programs
  272. // next is "input method" and it doesn't rly make sense to me to
  273. // exist in the first place
  274. // transparency flag; transparency index is given
  275. (*current_printf_function)("transparency index: %d\n", transparent_color_gct_index);
  276. has_transparency = packed_field & 1;
  277. break;
  278. }
  279. case 0x2C: { // "," image descriptor
  280. (*current_printf_function)("started reading image descriptor block at byte #%d\n", current_byte - 1);
  281. uint16_t image_left_pos = get_2();
  282. uint16_t image_top_pos = get_2();
  283. uint16_t image_descriptor_width = get_2();
  284. uint16_t image_descriptor_height = get_2();
  285. (*current_printf_function)("width height %dx%d\n", image_descriptor_width, image_descriptor_height);
  286. uint8_t packed_field = get_1();
  287. uint8_t local_color_table_flag = (packed_field & 0x80) >> 7;
  288. uint8_t interlace_flag = (packed_field & 0x40) >> 6;
  289. uint8_t local_color_table_is_sorted_flag = (packed_field & 0x20) >> 5;
  290. uint16_t entries_of_local_color_table = 1 << ((packed_field & 7) + 1);
  291. uint32_t* local_color_table = NULL;
  292. if (local_color_table_flag){
  293. (*current_printf_function)("theres a local color table\n");
  294. local_color_table = malloc(sizeof(uint32_t) * entries_of_local_color_table);
  295. for (int i = 0; i < entries_of_local_color_table; i++){
  296. // just gonna assume 8bit again
  297. unsigned char r = get_1();
  298. unsigned char g = get_1();
  299. unsigned char b = get_1();
  300. local_color_table[i] = b << 24 | g << 16 | r << 8 | 255 << 0;
  301. }
  302. // image->frame_buffer = local_color_table;
  303. // image->width = sqrt(entries_of_local_color_table);
  304. // image->height = sqrt(entries_of_local_color_table);
  305. // return image;
  306. }
  307. (*current_printf_function)("started reading image data block at byte #%d\n", current_byte);
  308. uint8_t number_of_initial_lzw_bits = get_1(); // how many possible colors and also LZW size + 1 = how many bits you need
  309. uint8_t image_data_byte_length = get_1();
  310. uint16_t* decoded_color_codes = malloc(sizeof(uint16_t) * image_descriptor_width * image_descriptor_height);
  311. uint32_t decoded_color_code_count = 0;
  312. uint32_t* code_table = malloc(sizeof(uint32_t) * 4096 * 2);
  313. (*current_printf_function)("LZW initial bit size: %d\n", number_of_initial_lzw_bits);
  314. uint8_t* image_data_byte_array = NULL;
  315. uint32_t total_image_data_byte_length = 0;
  316. while (image_data_byte_length != 0){
  317. total_image_data_byte_length += image_data_byte_length;
  318. image_data_byte_array = realloc(image_data_byte_array, sizeof(uint8_t) * total_image_data_byte_length);
  319. for (int i = 0; i < image_data_byte_length; i++){
  320. image_data_byte_array[total_image_data_byte_length - image_data_byte_length + i] = get_1();
  321. (*current_printf_function)("%s ", lsb_byte_to_binary(image_data_byte_array[total_image_data_byte_length - image_data_byte_length + i], 8));
  322. }
  323. (*current_printf_function)("\n");
  324. image_data_byte_length = get_1();
  325. }
  326. uint8_t lzw_bit_count = number_of_initial_lzw_bits + 1;
  327. uint32_t current_bit = 0;
  328. uint8_t is_parsing = 1;
  329. uint32_t clear_code = 1 << number_of_initial_lzw_bits;
  330. uint32_t stop_code = clear_code + 1;
  331. uint32_t previous_code = stop_code;
  332. uint32_t current_highest_defined_code = stop_code;
  333. (*current_printf_function)("clear code: %d stop code: %d\n", clear_code, stop_code);
  334. while (is_parsing){
  335. uint32_t code = 0;
  336. if (current_bit < total_image_data_byte_length * 8){
  337. for (uint32_t i = current_bit; i < lzw_bit_count + current_bit; i++){
  338. uint32_t current_byte = floor(i / 8);
  339. uint32_t current_bit_in_byte = i % 8;
  340. code += msb_get_bit(image_data_byte_array[current_byte], current_bit_in_byte) * (1 << (i - current_bit));
  341. }
  342. current_bit += lzw_bit_count;
  343. } else {
  344. (*current_printf_function)("error: read past data length\n");
  345. exit(1);
  346. }
  347. (*current_printf_function)("parsing code %s (%d)\n", msb_byte_to_binary(code, lzw_bit_count), (int)code);
  348. if (code == clear_code){
  349. (*current_printf_function)("clear code!\n");
  350. for (int i = 0; i < 4096 * 2; i++){
  351. code_table[i] = (uint32_t)(0) - 1;
  352. }
  353. current_highest_defined_code = stop_code;
  354. lzw_bit_count = number_of_initial_lzw_bits + 1;
  355. }
  356. else if (code == stop_code){
  357. (*current_printf_function)("stop code!\n");
  358. is_parsing = 0;
  359. }
  360. else {
  361. uint32_t deconstructed_code = code;
  362. uint8_t can_standardly_add_code = 1;
  363. // add decoded values
  364. if (code < clear_code){
  365. (*current_printf_function)("literal!\n");
  366. decoded_color_codes[decoded_color_code_count++] = deconstructed_code;
  367. }
  368. else if (code_table[deconstructed_code * 2] == (uint32_t)(0) - 1){ // code is undefined
  369. (*current_printf_function)("undefined representative!\n");
  370. can_standardly_add_code = 0;
  371. uint32_t first_code = previous_code;
  372. while (first_code > clear_code){
  373. if (code_table[first_code * 2] == ((uint32_t)-1)){
  374. printf("error: code points to undefined code\n");
  375. exit(1);
  376. }
  377. first_code = code_table[first_code * 2];
  378. }
  379. code_table[++current_highest_defined_code * 2] = previous_code;
  380. code_table[current_highest_defined_code * 2 + 1] = first_code;
  381. if (current_highest_defined_code == (uint64_t)((1 << lzw_bit_count) - 1)){
  382. lzw_bit_count++;
  383. }
  384. uint16_t temp_decoded_color_count = 0;
  385. uint16_t cur_allocated_temps = 1000;
  386. uint32_t* temp_decoded_colors = malloc(sizeof(uint32_t) * cur_allocated_temps);
  387. uint32_t deconstructed_prev_code = previous_code;
  388. if (deconstructed_prev_code < clear_code) decoded_color_codes[decoded_color_code_count++] = previous_code;
  389. while (deconstructed_prev_code > clear_code){
  390. if (code_table[deconstructed_prev_code * 2] == (uint32_t)(0) - 1){
  391. printf("error: code points to undefined code\n");
  392. exit(1);
  393. }
  394. if (temp_decoded_color_count >= cur_allocated_temps){
  395. cur_allocated_temps += 1000;
  396. temp_decoded_colors = realloc(temp_decoded_colors, sizeof(uint32_t) * cur_allocated_temps);
  397. }
  398. temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_prev_code * 2 + 1]; // add the literal
  399. if (code_table[deconstructed_prev_code * 2] < clear_code)
  400. temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_prev_code * 2];
  401. deconstructed_prev_code = code_table[deconstructed_prev_code * 2];
  402. }
  403. for (int i = temp_decoded_color_count - 1; i >= 0; i--){
  404. decoded_color_codes[decoded_color_code_count++] = temp_decoded_colors[i];
  405. }
  406. free(temp_decoded_colors);
  407. decoded_color_codes[decoded_color_code_count++] = first_code;
  408. (*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);
  409. }
  410. else { // code is defined
  411. (*current_printf_function)("defined representative! code_table[%d * 2] == %d, %d\n", code, code_table[deconstructed_code * 2], code_table[deconstructed_code * 2 + 1]);
  412. uint16_t temp_decoded_color_count = 0;
  413. uint16_t cur_allocated_temps = 1000;
  414. uint32_t* temp_decoded_colors = malloc(sizeof(uint32_t) * cur_allocated_temps);
  415. while (deconstructed_code > clear_code){
  416. if (code_table[deconstructed_code * 2] == (uint32_t)(0) - 1){
  417. printf("error: code points to undefined code\n");
  418. exit(1);
  419. }
  420. if (temp_decoded_color_count >= cur_allocated_temps){
  421. cur_allocated_temps += 1000;
  422. temp_decoded_colors = realloc(temp_decoded_colors, sizeof(uint32_t) * cur_allocated_temps);
  423. }
  424. temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_code * 2 + 1]; // add the literal
  425. if (code_table[deconstructed_code * 2] < clear_code)
  426. temp_decoded_colors[temp_decoded_color_count++] = code_table[deconstructed_code * 2];
  427. deconstructed_code = code_table[deconstructed_code * 2];
  428. }
  429. for (int i = temp_decoded_color_count - 1; i >= 0; i--){
  430. decoded_color_codes[decoded_color_code_count++] = temp_decoded_colors[i];
  431. }
  432. free(temp_decoded_colors);
  433. }
  434. // create new code table entry
  435. if (can_standardly_add_code && previous_code != clear_code){
  436. uint32_t first_code = code;
  437. while (first_code > clear_code){
  438. if (code_table[first_code * 2] == (uint32_t)(0) - 1){
  439. printf("error: code points to undefined code\n");
  440. exit(1);
  441. }
  442. first_code = code_table[first_code * 2];
  443. }
  444. code_table[++current_highest_defined_code * 2] = previous_code;
  445. code_table[current_highest_defined_code * 2 + 1] = first_code;
  446. if (current_highest_defined_code == (uint64_t)((1 << lzw_bit_count) - 1)){
  447. lzw_bit_count++;
  448. }
  449. (*current_printf_function)("added new code (from standard branch): code_table[%d * 2] == %d, %d\n", current_highest_defined_code, previous_code, first_code);
  450. }
  451. }
  452. // for (uint32_t i = 0; i < decoded_color_code_count; i++){
  453. // if (!decoded_color_codes[i])(*current_printf_function)("██ ");
  454. // else (*current_printf_function)("░░ ");
  455. // if ((i + 1) % image_descriptor_width == 0) (*current_printf_function)("\n");
  456. // }
  457. (*current_printf_function)("\n");
  458. (*current_printf_function)("%d/%d colors decoded\n", decoded_color_code_count, image_descriptor_width * image_descriptor_height);
  459. previous_code = code;
  460. }
  461. if (decoded_color_code_count != image_descriptor_width * image_descriptor_height){
  462. printf("error: number of decoded pixels is not equal to number of total pixels\n");
  463. }
  464. (*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);
  465. if (frame_count > 1){
  466. for (int y = 0; y < image_height; y++){
  467. for (int x = 0; x < image_width; x++){
  468. uint32_t frame_offset_1 = image_height * (frame_count - 1);
  469. uint32_t frame_offset_2 = image_height * (frame_count - 2);
  470. image->frame_buffer[(y + frame_offset_1) * image_width + x] =
  471. image->frame_buffer[(y + frame_offset_2) * image_width + x];
  472. }
  473. }
  474. }
  475. for (int y = 0; y < image_descriptor_height; y++){
  476. for (int x = 0; x < image_descriptor_width; x++){
  477. if (has_transparency && decoded_color_codes[y * image_descriptor_width + x] == transparent_color_gct_index)
  478. continue;
  479. else{
  480. uint32_t frame_offset = image_height * (frame_count - 1);
  481. uint32_t color = local_color_table_flag ?
  482. local_color_table[decoded_color_codes[y * image_descriptor_width + x]] :
  483. global_color_table[decoded_color_codes[y * image_descriptor_width + x]];
  484. image->frame_buffer[(y + image_top_pos + frame_offset) * image_width + x + image_left_pos] = color;
  485. }
  486. }
  487. }
  488. break;
  489. }
  490. case 0x3B: { // ";" EOF
  491. (*current_printf_function)("EOF at byte #%d\n", current_byte - 1);
  492. still_reading_file = 0;
  493. break;
  494. }
  495. }
  496. }
  497. image->frame_count = frame_count;
  498. return image;
  499. }
  500. int printf_override(const char *__restrict __format, ...){
  501. return 0;
  502. }
  503. PM_image* PM_load_image(const char *filename, unsigned char debug_mode){
  504. FILE *fp = fopen(filename, "rb");
  505. if (fp == NULL){
  506. (*current_printf_function)("file does not exist !!!\n");
  507. return NULL;
  508. }
  509. fseek(fp, 0, SEEK_END);
  510. long size = ftell(fp);
  511. rewind(fp);
  512. file_buffer = malloc(size);
  513. fread(file_buffer, 1, size, fp);
  514. fclose(fp);
  515. // see what the file type is
  516. char* mutable_filename = malloc(sizeof(char) * (strlen(filename) + 1));
  517. strcpy(mutable_filename, filename);
  518. char *strtok_string = strtok(mutable_filename, ".");
  519. char *filetype_string;
  520. while(strtok_string != NULL) {
  521. filetype_string = strtok_string;
  522. strtok_string = strtok(NULL, ".");
  523. }
  524. // override (*current_printf_function) so there is no debug output
  525. if (!debug_mode){
  526. current_printf_function = printf_override;
  527. }
  528. if (!strcmp(filetype_string, "gif") || !strcmp(filetype_string, "GIF")){ // GIF file
  529. return PM_load_gif(debug_mode);
  530. } else
  531. if (!strcmp(filetype_string, "bmp") || !strcmp(filetype_string, "BMP")){ // BMP file
  532. return PM_load_bitmap(debug_mode);
  533. }
  534. (*current_printf_function)("file is unreadable by PitMap\n");
  535. return NULL;
  536. }
  537. void PM_free_image(PM_image* image){
  538. if (image){
  539. if (image->frame_buffer) free(image->frame_buffer);
  540. if (image->frame_delays) free(image->frame_delays);
  541. free(image);
  542. } else
  543. printf("can't free a NULL image!\n");
  544. }