Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

read

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 size of the color palette is calculated from the BitsPerPixel value.
            // > 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;
}