Browse Source

added support for 8bit RLE encoding, added gordon textures

Iver 1 month ago
parent
commit
acdf36254a
7 changed files with 127 additions and 33 deletions
  1. BIN
      builds/libpitmap.so
  2. BIN
      builds/main.bin
  3. BIN
      image.tga
  4. BIN
      images/gordon_body.bmp
  5. BIN
      images/gordon_face.bmp
  6. 43 1
      src/launch_program/main.c
  7. 84 32
      src/library/main.c

BIN
builds/libpitmap.so


BIN
builds/main.bin


BIN
image.tga


BIN
images/gordon_body.bmp


BIN
images/gordon_face.bmp


+ 43 - 1
src/launch_program/main.c

@@ -1,7 +1,49 @@
 #include "../headers/pitmap.h"
+#include <stdio.h>
+int write_tga(const char* path, const PM_image* img) {
+    if (!img || !img->frame_buffer || img->width <= 0 || img->height <= 0)
+        return -1;
+
+    FILE* f = fopen(path, "wb");
+    if (!f)
+        return -2;
+
+    unsigned char header[18] = {0};
+
+    header[2]  = 2;                           // Uncompressed true-color image
+    header[12] = img->width & 0xFF;
+    header[13] = (img->width >> 8) & 0xFF;
+    header[14] = img->height & 0xFF;
+    header[15] = (img->height >> 8) & 0xFF;
+    header[16] = 32;                          // 32 bits per pixel (RGBA)
+    header[17] = 0x20;                        // Image origin: top-left
+
+    fwrite(header, 1, 18, f);
+
+    int total = img->width * img->height;
+
+    // TGA expects BGRA, so we must swizzle R and B.
+    // If your buffer is already BGRA, tell me and I'll remove this.
+    for (int i = 0; i < total; i++) {
+        uint32_t px = img->frame_buffer[i];
+
+        uint8_t r = (px >> 24) & 0xFF;
+        uint8_t g = (px >> 16) & 0xFF;
+        uint8_t b = (px >> 8)  & 0xFF;
+        uint8_t a = (px >> 0)  & 0xFF;
+
+        uint8_t out[4] = { r, g, b, a };      // TGA = BGRA
+        fwrite(out, 1, 4, f);
+    }
+
+    fclose(f);
+    return 0;
+}
 
 int main(){
-    PM_load_image("images/test_texture.bmp");
+    write_tga("./image.tga", PM_load_image("images/gordon_face.bmp"));
+
+    
 
     return 0;
 }

+ 84 - 32
src/library/main.c

@@ -58,6 +58,27 @@ PM_image* PM_load_bitmap(){
     uint32_t number_of_colors_in_palette = get_4();
     skip(4); // number of important colors, ignored
 
+    current_byte = header_size + 14;
+
+    uint32_t* color_palette;
+    
+    if (number_of_colors_in_palette > 0) { // we've got a color palette!
+        color_palette = malloc(sizeof(uint32_t) * number_of_colors_in_palette);
+        
+        for (int 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);
+
+            printf("#%d, %x\n", i, color_palette[i]);
+        }
+    }
+    
     image->frame_buffer = malloc(sizeof(uint32_t) * image_width * image_height);
     image->width = image_width;
     image->height = image_height;
@@ -80,54 +101,85 @@ PM_image* PM_load_bitmap(){
         return NULL;
     }
 
-    for (uint32_t y = 0; y < image_height; y++){
-        int current_byte_of_row = 0;
+    switch (bits_per_pixel){
+        case (32): { // RGBA 1 byte each
+            for (uint32_t y = 0; y < image_height; y++){
+                int current_byte_of_row = 0;
 
-        for (int x = image_width - 1; x >= 0; x--){ // starting reversed becuase image data is backwards
-            switch (bits_per_pixel){
-                case (32): { // RGBA 1 byte each
-                    image->frame_buffer[y * image_height + x] = (uint32_t)((uint8_t)get_1() << 24 | (uint8_t)get_1() << 16 | (uint8_t)get_1() << 8 | (uint8_t)get_1());
+                for (int x = image_width - 1; x >= 0; 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;
-
-                    break;
                 }
+            
+                skip(row_size - current_byte_of_row);
+            }
 
-                case (24): { // RGB -> RGBA 1 byte each
-                    image->frame_buffer[y * image_height + x] = (uint32_t)((uint8_t)get_1() << 24 | (uint8_t)get_1() << 16 | (uint8_t)get_1() << 8 | 255);
-                    
-                    current_byte_of_row += 3;
-
-                    break;
-                }
+            break;
+        }
 
-                case (16): {
+        case (24): { // RGB -> RGBA 1 byte each
+            for (uint32_t y = 0; y < image_height; y++){
+                int current_byte_of_row = 0;
 
-                        
-                    break;
+                for (int x = image_width - 1; x >= 0; 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 (8): {
+        case (16): {
+                
+            break;
+        }
 
-                        
-                    break;
+        case (8): { // paletted
+            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++){
+                        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): {
+        case (4): { // paletted
 
-                        
-                    break;
-                }
+                
+            break;
+        }
 
-                case (1): {
+        case (1): {
 
-                        
-                    break;
-                }
-            }
+                
+            break;
         }
-
-        skip(row_size - current_byte_of_row);
     }
 
     return image;