commit 27962884cc72f5136c74fb125d8c97e8c9e04ebc
parent ccdb9723373b4dfee6cb0b97aef5392a07cc973a
Author: amin <dev@aminmesbah.com>
Date: Fri, 5 Jul 2019 23:07:54 +0000
Clean up image loading code
FossilOrigin-Name: 0fb7a63c65b43f90dc500f21d3fd7d387760ecf8cb48387da0372d467d55b04b
Diffstat:
M | src/game.c | | | 78 | ++++++++++++++++++++++++++++++++++++++++++++---------------------------------- |
1 file changed, 44 insertions(+), 34 deletions(-)
diff --git a/src/game.c b/src/game.c
@@ -31,7 +31,7 @@ struct ImgTgaHeader
#pragma pack(pop)
static_assert(sizeof(struct ImgTgaHeader) == 18, "");
-void img_tga_header_print(struct ImgTgaHeader h)
+internal void img_tga_header_print(struct ImgTgaHeader h)
{
printf("id_length: %u\n", h.id_length);
printf("color_map_type: %u\n", h.color_map_type);
@@ -47,13 +47,25 @@ void img_tga_header_print(struct ImgTgaHeader h)
printf("image_descriptor: %u\n", h.image_descriptor);
}
+internal u8 img_consume_byte(u8 **buffer, uintptr_t end_address)
+{
+ u8 byte = 0;
+ if ((uintptr_t)*buffer < end_address)
+ {
+ byte = **buffer;
+ (*buffer)++;
+ }
+ return byte;
+}
+
internal u8 *img_load_from_memory(u8 *buffer, size_t len, i32 *out_width, i32 *out_height, struct StackAllocator *allocator)
{
assert(buffer);
- u8 *one_past_last = buffer + (len * sizeof(u8));
+ uintptr_t buf_end = (uintptr_t)buffer + (len * sizeof(u8));
assert(len >= sizeof(struct ImgTgaHeader));
struct ImgTgaHeader h = *(struct ImgTgaHeader *)buffer;
+ buffer += sizeof(struct ImgTgaHeader);
img_tga_header_print(h);
// Image descriptor not currently accounted for
@@ -62,6 +74,7 @@ internal u8 *img_load_from_memory(u8 *buffer, size_t len, i32 *out_width, i32 *o
assert(h.color_map_type == 0);
// Only RGB is supported
assert(h.data_type_code == 2 || h.data_type_code == 10);
+ assert(h.bits_per_pixel <= 32);
if (out_width)
{
@@ -72,74 +85,71 @@ internal u8 *img_load_from_memory(u8 *buffer, size_t len, i32 *out_width, i32 *o
*out_height = h.height;
}
- buffer += sizeof(struct ImgTgaHeader);
-
u8 bytes_per_pixel = h.bits_per_pixel / 8;
- size_t pixel_buffer_length = h.width * h.height * bytes_per_pixel;
- u8 *pixels = mem_st_alloc_buffer(allocator, u8, pixel_buffer_length);
- assert(pixels);
+ size_t bytes_per_row = h.width * bytes_per_pixel;
+ size_t img_data_buf_len = h.height * bytes_per_row;
+ u8 *img_data = mem_st_alloc_buffer(allocator, u8, img_data_buf_len);
+ assert(img_data);
if (h.data_type_code == 2)
{
- for (size_t i = 0; i < pixel_buffer_length; i++)
+ // uncompressed RGB
+ for (size_t b = 0; b < img_data_buf_len; b++)
{
- pixels[i] = *buffer++;
+ img_data[b] = img_consume_byte(&buffer, buf_end);
}
}
else if (h.data_type_code == 10)
{
- size_t pixel_bytes_read = 0;
- while (pixel_bytes_read < pixel_buffer_length)
+ // Run Length Encoded RGB
+ size_t img_bytes_read = 0;
+ while (img_bytes_read < img_data_buf_len)
{
- u8 packet_header = *buffer++;
- printf("h: %X --- ", packet_header);
-
+ u8 packet_header = img_consume_byte(&buffer, buf_end);
u8 run_length_header_bit = packet_header >> 7;
- u8 run_count = (packet_header & (~(1 << 7))) + 1;
+ u32 run_count = (packet_header & (~(1 << 7))) + 1;
assert(run_count <= 128);
- printf("run_count: %u\n", run_count);
+ u32 run_length_in_bytes = run_count * bytes_per_pixel;
+
if (run_length_header_bit)
{
- printf("rl\n");
u8 pixel[4] = {0};
- for (u8 i = 0; i < bytes_per_pixel; i++)
+ for (u32 b = 0; b < bytes_per_pixel; b++)
{
- pixel[i] = *buffer++;
+ pixel[b] = img_consume_byte(&buffer, buf_end);
}
- for (u8 i = 0; i < run_count * bytes_per_pixel; i++)
+ for (u32 b = 0; b < run_length_in_bytes; b++)
{
- pixels[pixel_bytes_read + i] = pixel[i % bytes_per_pixel];
+ img_data[img_bytes_read + b] = pixel[b % bytes_per_pixel];
}
- pixel_bytes_read += run_count * bytes_per_pixel;
+ img_bytes_read += run_length_in_bytes;
}
else
{
- printf("raw\n");
- for (u8 i = 0; i < run_count * bytes_per_pixel; i++)
+ for (u32 b = 0; b < run_length_in_bytes; b++)
{
- pixels[pixel_bytes_read + i] = *buffer++;
+ img_data[img_bytes_read + b] = img_consume_byte(&buffer, buf_end);
}
- pixel_bytes_read += run_count * bytes_per_pixel;
+ img_bytes_read += run_length_in_bytes;
}
}
}
- u32 bytes_per_row = h.width * bytes_per_pixel;
// NOTE(amin): Intentional truncating division. If height is odd, we want
// our last row offset to be 1 less than the middle row.
u32 half_height = h.height / 2;
for (size_t row_offset = 0; row_offset < half_height; row_offset++)
{
- u8 *top_row = &pixels[row_offset * bytes_per_row];
- u8 *bot_row = &pixels[(h.height - row_offset - 1) * bytes_per_row];
- for (size_t i = 0; i < bytes_per_row; i++)
+ u8 *top_row = &img_data[row_offset * bytes_per_row];
+ u8 *bot_row = &img_data[(h.height - row_offset - 1) * bytes_per_row];
+ for (size_t b = 0; b < bytes_per_row; b++)
{
- u8 temp = top_row[i];
- top_row[i] = bot_row[i];
- bot_row[i] = temp;
+ u8 temp = top_row[b];
+ top_row[b] = bot_row[b];
+ bot_row[b] = temp;
}
}
- return pixels;
+ return img_data;
}
internal void move_mode_print(enum MoveMode s)