Browse Source

can decode 32 RGBA and 24 RGB with no compression

Iver 1 month ago
parent
commit
57dcab496d

+ 6 - 0
.vscode/settings.json

@@ -0,0 +1,6 @@
+{
+    "files.associations": {
+        "*.cl": "opencl",
+        "pitmap.h": "c"
+    }
+}

+ 13 - 0
Makefile

@@ -0,0 +1,13 @@
+COMPILER=gcc
+FLAGS_ALL=-g -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-sequence-point
+FLAGS_EXAMPLE=-Lbuilds/ -lpitmap -Wl,-rpath=builds/
+FLAGS_LIB=-lm -shared -fPIC
+
+main.bin: pitmap.so
+	$(COMPILER) $(FLAGS_ALL) src/launch_program/main.c -o builds/main.bin $(FLAGS_EXAMPLE) 
+
+pitmap.so:
+	$(COMPILER) $(FLAGS_ALL) src/library/main.c -o builds/libpitmap.so $(FLAGS_LIB) 
+
+clean:
+	rm build/*

BIN
builds/libpitmap.so


BIN
builds/main.bin


BIN
images/8bitgrad24bit.bmp


BIN
images/8bitgrad32bitA128.bmp


BIN
images/8bitgrad32bitA255.bmp


+ 1 - 0
images/notabitmap.bmp

@@ -0,0 +1 @@
+hello im not a bitmap

BIN
images/test_square_24bit.bmp


BIN
images/test_square_32bit.bmp


BIN
images/test_texture.bmp


+ 0 - 6
src/headers/functions.h

@@ -1,6 +0,0 @@
-#ifndef FUNCTIONS_H
-#define FUNCTIONS_H
-
-
-
-#endif 

+ 8 - 2
src/headers/pitmap.h

@@ -1,7 +1,13 @@
 #ifndef PITMAP_H
 #define PITMAP_H
 
-#include "functions.h"
-#include "types.h"
+#include <stdint.h>
+
+typedef struct {
+    uint32_t* frame_buffer;
+    int width, height;
+} PM_image;
+
+PM_image* PM_load_image(char* filename);
 
 #endif

+ 0 - 0
src/headers/types.h


+ 7 - 0
src/launch_program/main.c

@@ -0,0 +1,7 @@
+#include "../headers/pitmap.h"
+
+int main(){
+    PM_load_image("images/test_texture.bmp");
+
+    return 0;
+}

+ 162 - 0
src/library/main.c

@@ -0,0 +1,162 @@
+#include "../headers/pitmap.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+uint8_t *file_buffer;
+int current_byte;
+
+// byte 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(){
+    PM_image* image = malloc(sizeof(PM_image));
+
+    current_byte = 0;
+
+    // file header
+
+    uint16_t header_field = get_2();
+
+    if (header_field != 19778) {
+        printf("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
+
+    image->frame_buffer = malloc(sizeof(uint32_t) * image_width * image_height);
+    image->width = image_width;
+    image->height = image_height;
+
+    // extra bit masks not implemented
+
+    // color table not implemented
+    
+    // icc color profile not implemented
+
+    // pixel array
+
+    current_byte = pixel_buffer_offset;
+
+    int row_size = ceil((float)(bits_per_pixel * image_width) / (32)) * 4;
+
+    printf("%d\n", row_size);
+
+    if (bits_per_pixel < 8) {
+        printf("under 8 bits per pixel not implemented");
+    
+        return NULL;
+    }
+
+    for (int y = image_height - 1; y >= 0; y--){ // starting at the bottom of the image becuase data is backwards
+        int current_byte_of_row = 0;
+
+        for (int x = 0; x < image_width; x++){
+            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());
+
+                    current_byte_of_row += 4;
+
+                    break;
+                }
+
+                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;
+                }
+
+                case (16): {
+
+                        
+                    break;
+                }
+
+                case (8): {
+
+                        
+                    break;
+                }
+
+                case (4): {
+
+                        
+                    break;
+                }
+
+                case (1): {
+
+                        
+                    break;
+                }
+            }
+        }
+
+        skip(row_size - current_byte_of_row);
+    }
+
+    printf("\n\ndone\n");
+
+
+    write_tga("./image.tga", image);
+
+    return image;
+}
+
+PM_image* PM_load_image(char *filename){
+    FILE *fp = fopen(filename, "rb");
+
+    if (fp == NULL){
+        printf("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);
+
+    return PM_load_bitmap();
+}