.{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 }