feature. See also
. The project being documented here (as the example) is the Zig library itself.
bmp.read
pub fn read(reader: *std.Io.Reader, max_size: u64) ReadError!BitmapInfo
File
Code
pub fn read(reader: *std.Io.Reader, max_size: u64) ReadError!BitmapInfo {
var bitmap_info: BitmapInfo = undefined;
const file_header = reader.takeArray(file_header_len) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEOF,
else => |e| return e,
};
const id = std.mem.readInt(u16, file_header[0..2], native_endian);
if (id != windows_format_id) return error.InvalidFileHeader;
bitmap_info.pixel_data_offset = std.mem.readInt(u32, file_header[10..14], .little);
if (bitmap_info.pixel_data_offset > max_size) return error.ImpossiblePixelDataOffset;
bitmap_info.dib_header_size = reader.takeInt(u32, .little) catch return error.UnexpectedEOF;
if (bitmap_info.pixel_data_offset < file_header_len + bitmap_info.dib_header_size) return error.ImpossiblePixelDataOffset;
const dib_version = BitmapHeader.Version.get(bitmap_info.dib_header_size);
switch (dib_version) {
.@"nt3.1", .@"nt4.0", .@"nt5.0" => {
var dib_header_buf: [@sizeOf(BITMAPINFOHEADER)]u8 align(@alignOf(BITMAPINFOHEADER)) = undefined;
std.mem.writeInt(u32, dib_header_buf[0..4], bitmap_info.dib_header_size, .little);
reader.readSliceAll(dib_header_buf[4..]) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEOF,
error.ReadFailed => |e| return e,
};
var dib_header: *BITMAPINFOHEADER = @ptrCast(&dib_header_buf);
structFieldsLittleToNative(BITMAPINFOHEADER, dib_header);
bitmap_info.colors_in_palette = try dib_header.numColorsInTable();
bitmap_info.bytes_per_color_palette_element = 4;
bitmap_info.compression = @fromBackingInt(@intCast(dib_header.biCompression));
if (bitmap_info.getByteLenBetweenHeadersAndPixels() < bitmap_info.getBitmasksByteLen()) {
return error.MissingBitfieldMasks;
}
},
.@"win2.0" => {
var dib_header_buf: [@sizeOf(BITMAPCOREHEADER)]u8 align(@alignOf(BITMAPCOREHEADER)) = undefined;
std.mem.writeInt(u32, dib_header_buf[0..4], bitmap_info.dib_header_size, .little);
reader.readSliceAll(dib_header_buf[4..]) catch |err| switch (err) {
error.EndOfStream => return error.UnexpectedEOF,
error.ReadFailed => |e| return e,
};
const dib_header: *BITMAPCOREHEADER = @ptrCast(&dib_header_buf);
structFieldsLittleToNative(BITMAPCOREHEADER, dib_header);
// > The color palette has 2, 16, 256, or 0 entries for a BitsPerPixel of
// > 1, 4, 8, and 24, respectively.
bitmap_info.colors_in_palette = switch (dib_header.bcBitCount) {
inline 1, 4, 8 => |bit_count| 1 << bit_count,
24 => 0,
else => return error.InvalidBitsPerPixel,
};
bitmap_info.bytes_per_color_palette_element = 3;
bitmap_info.compression = .BI_RGB;
},
.unknown => return error.UnknownBitmapVersion,
}
return bitmap_info;
}