forked from AbleOS/ableos
103 lines
2.6 KiB
Plaintext
103 lines
2.6 KiB
Plaintext
.{Color, Surface, new_surface} := @use("./lib.hb");
|
|
.{log, memory} := @use("../../stn/src/lib.hb")
|
|
|
|
BitmapFileHeader := packed struct {
|
|
img_type: u16,
|
|
size: u32,
|
|
reserved_1: u16,
|
|
reserved_2: u16,
|
|
offset: u32,
|
|
}
|
|
|
|
BitmapInfoHeader := packed struct {
|
|
size: u32,
|
|
width: i32,
|
|
height: i32,
|
|
planes: u16,
|
|
bits: u16,
|
|
compression: u32,
|
|
image_size: u32,
|
|
x_resolution: i32,
|
|
y_resolution: i32,
|
|
n_colours: u32,
|
|
important_colours: u32,
|
|
}
|
|
|
|
BitmapColorHeader := packed struct {
|
|
red_mask: u32,
|
|
green_mask: u32,
|
|
blue_mask: u32,
|
|
alpha_mask: u32,
|
|
color_space_type: u32,
|
|
unused: u32,
|
|
}
|
|
|
|
surface_from_bmp := fn(bmp: ^u8): Surface {
|
|
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
|
if file_header.img_type != 0x4D42 {
|
|
log.error("failed to load bmp image: not a bmp image, idiot\0")
|
|
return @as(Surface, idk)
|
|
}
|
|
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
|
bmp += file_header.offset
|
|
|
|
a := 0
|
|
px := info_header.width * info_header.height
|
|
ptr := @as(^Color, @bitcast(bmp))
|
|
tmp := @as(Color, idk)
|
|
row := 0
|
|
|
|
loop if row == info_header.height / 2 break else {
|
|
col := 0
|
|
loop if col == info_header.width break else {
|
|
top_index := row * info_header.width + col
|
|
bottom_index := (info_header.height - 1 - row) * info_header.width + col
|
|
|
|
tmp = *(ptr + top_index);
|
|
*(ptr + top_index) = *(ptr + bottom_index);
|
|
*(ptr + bottom_index) = tmp
|
|
|
|
col += 1
|
|
}
|
|
row += 1
|
|
}
|
|
|
|
return .(@bitcast(bmp), @intcast(info_header.width), @intcast(info_header.height))
|
|
}
|
|
|
|
new_surface_from_bmp := fn(bmp: ^u8): Surface {
|
|
file_header := @as(^BitmapFileHeader, @bitcast(bmp))
|
|
if file_header.img_type != 0x4D42 {
|
|
log.error("failed to load bmp image: not a bmp image, idiot\0")
|
|
return @as(Surface, idk)
|
|
}
|
|
info_header := @as(^BitmapInfoHeader, @bitcast(bmp + @sizeof(BitmapFileHeader)))
|
|
bmp += file_header.offset
|
|
|
|
width := @as(int, @intcast(info_header.width))
|
|
height := @as(int, @intcast(info_header.height))
|
|
|
|
surface := new_surface(width, height)
|
|
top_start_idx := surface.buf
|
|
bottom_start_idx := surface.buf + width * (height - 1)
|
|
rows_to_copy := height
|
|
top_cursor := @as(^Color, @bitcast(bmp))
|
|
bottom_cursor := top_cursor + width * (height - 1)
|
|
|
|
loop if rows_to_copy <= 1 break else {
|
|
@inline(memory.copy, Color, top_cursor, bottom_start_idx, @bitcast(width))
|
|
@inline(memory.copy, Color, bottom_cursor, top_start_idx, @bitcast(width))
|
|
|
|
top_start_idx += surface.width
|
|
bottom_start_idx -= surface.width
|
|
top_cursor += width
|
|
bottom_cursor -= width
|
|
rows_to_copy -= 2
|
|
}
|
|
|
|
if rows_to_copy == 1 {
|
|
@inline(memory.copy, Color, top_cursor, top_start_idx, @bitcast(width))
|
|
}
|
|
|
|
return surface
|
|
} |