package core:image

⌘K
Ctrl+K
or
/

    Types

    Alpha_Key ¶

    Alpha_Key :: union {
    	[2]u8, 
    	[4]u8, 
    	[2]u16, 
    	[4]u16, 
    }
    Related Procedures With Parameters

    Channel ¶

    Channel :: enum u8 {
    	R = 1, 
    	G = 2, 
    	B = 3, 
    	A = 4, 
    }
    Related Procedures With Parameters

    Destroy_Proc ¶

    Destroy_Proc :: proc(img: ^Image)
    Related Procedures With Parameters

    Error ¶

    Error :: union {
    	General_Image_Error, 
    	Netpbm_Error, 
    	PNG_Error, 
    	QOI_Error, 
    	compress.Error, 
    	compress.General_Error, 
    	compress.Deflate_Error, 
    	compress.ZLIB_Error, 
    	runtime.Allocator_Error, 
    }
    Related Procedures With Returns

    GA_Pixel ¶

    GA_Pixel :: [2]u8

    GA_Pixel_16 ¶

    GA_Pixel_16 :: [2]u16

    G_Pixel ¶

    G_Pixel :: [1]u8
     

    Grayscale

    G_Pixel_16 ¶

    G_Pixel_16 :: [1]u16

    General_Image_Error ¶

    General_Image_Error :: enum int {
    	None                          = 0, 
    	Unsupported_Option, 
    	// File I/O
    	Unable_To_Read_File, 
    	Unable_To_Write_File, 
    	// Invalid
    	Unsupported_Format, 
    	Invalid_Signature, 
    	Invalid_Input_Image, 
    	Image_Dimensions_Too_Large, 
    	Invalid_Image_Dimensions, 
    	Invalid_Number_Of_Channels, 
    	Image_Does_Not_Adhere_to_Spec, 
    	Invalid_Image_Depth, 
    	Invalid_Bit_Depth, 
    	Invalid_Color_Space, 
    	// More data than pixels to decode into, for example.
    	Corrupt, 
    	// Output buffer is the wrong size
    	Invalid_Output, 
    	// Allocation
    	Unable_To_Allocate_Or_Resize, 
    }

    Image ¶

    Image :: struct {
    	width:      int,
    	height:     int,
    	channels:   int,
    	depth:      int,
    	// Channel depth in bits, typically 8 or 16
    	pixels:     bytes.Buffer "fmt:\"-\"",
    	// 		Some image loaders/writers can return/take an optional background color.
    	// 		For convenience, we return them as u16 so we don't need to switch on the type
    	// 		in our viewer, and can just test against nil.
    	background: runtime.Maybe($T=[3]u16),
    	metadata:   Image_Metadata,
    	which:      Which_File_Type,
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    Image_Metadata ¶

    Image_Metadata :: union {
    	^Netpbm_Info, 
    	^PNG_Info, 
    	^QOI_Info, 
    	^TGA_Info, 
    }

    Loader_Proc ¶

    Loader_Proc :: proc(data: []u8, options: Options, allocator: runtime.Allocator) -> (img: ^Image, err: Error)
    Related Procedures With Parameters

    Netpbm_Error ¶

    Netpbm_Error :: enum int {
    	None                           = 0, 
    	// reading
    	Invalid_Header_Token_Character, 
    	Incomplete_Header, 
    	Invalid_Header_Value, 
    	Duplicate_Header_Field, 
    	Buffer_Too_Small, 
    	Invalid_Buffer_ASCII_Token, 
    	Invalid_Buffer_Value, 
    	// writing
    	Invalid_Format, 
    }

    Netpbm_Format ¶

    Netpbm_Format :: enum int {
    	P1, 
    	P2, 
    	P3, 
    	P4, 
    	P5, 
    	P6, 
    	P7, 
    	Pf, 
    	PF, 
    }
     

    Netpbm-specific definitions

    Netpbm_Header ¶

    Netpbm_Header :: struct {
    	format:        Netpbm_Format,
    	width:         int,
    	height:        int,
    	channels:      int,
    	depth:         int,
    	maxval:        int,
    	tupltype:      string,
    	scale:         f32,
    	little_endian: bool,
    }

    Netpbm_Info ¶

    Netpbm_Info :: struct {
    	header: Netpbm_Header,
    }

    Option ¶

    Option :: enum int {
    	// LOAD OPTIONS
    	info                    = 0, 
    	do_not_decompress_image, 
    	return_header, 
    	return_metadata, 
    	alpha_add_if_missing,        // Ignored for QOI. Always returns RGBA8.
    	alpha_drop_if_present,       // Unimplemented for QOI. Returns error.
    	alpha_premultiply,           // Unimplemented for QOI. Returns error.
    	blend_background,            // Ignored for non-PNG formats
    	// Unimplemented
    	do_not_expand_grayscale, 
    	do_not_expand_indexed, 
    	do_not_expand_channels, 
    	// SAVE OPTIONS
    	qoi_all_channels_linear,     // QOI, informative only. If not set, defaults to sRGB with linear alpha.
    }

    Options ¶

    Options :: distinct bit_set[Option]
    Related Procedures With Parameters

    PNG_Chunk ¶

    PNG_Chunk :: struct #packed {
    	header: PNG_Chunk_Header,
    	data:   []u8,
    	crc:    u32be,
    }

    PNG_Chunk_Header ¶

    PNG_Chunk_Header :: struct #packed {
    	length: u32be,
    	type:   PNG_Chunk_Type,
    }

    PNG_Chunk_Type ¶

    PNG_Chunk_Type :: enum u32be {
    	// IHDR must come first in a file
    	IHDR = 1229472850, 
    	// PLTE must precede the first IDAT chunk
    	PLTE = 1347179589, 
    	bKGD = 1649100612, 
    	tRNS = 1951551059, 
    	IDAT = 1229209940, 
    	iTXt = 1767135348, 
    	tEXt = 1950701684, 
    	zTXt = 2052348020, 
    	iCCP = 1766015824, 
    	pHYs = 1883789683, 
    	gAMA = 1732332865, 
    	tIME = 1950960965, 
    	sPLT = 1934642260, 
    	sRGB = 1934772034, 
    	hIST = 1749635924, 
    	cHRM = 1665684045, 
    	sBIT = 1933723988, 
    	// 		eXIf tags are not part of the core spec, but have been ratified
    	// 		in v1.5.0 of the PNG Ext register.
    	// 
    	// 		We will provide unprocessed chunks to the caller if `.return_metadata` is set.
    	// 		Applications are free to implement an Exif decoder.
    	eXIf = 1700284774, 
    	// PNG files must end with IEND
    	IEND = 1229278788, 
    	// 		XCode sometimes produces "PNG" files that don't adhere to the PNG spec.
    	// 		We recognize them only in order to avoid doing further work on them.
    	// 
    	// 		Some tools like PNG Defry may be able to repair them, but we're not
    	// 		going to reward Apple for producing proprietary broken files purporting
    	// 		to be PNGs by supporting them.
    	iDOT = 1766084436, 
    	CgBI = 1130840649, 
    }

    PNG_Color_Type ¶

    PNG_Color_Type :: distinct bit_set[PNG_Color_Value; u8]

    PNG_Color_Value ¶

    PNG_Color_Value :: enum u8 {
    	Paletted = 0, // 1 << 0 = 1
    	Color    = 1, // 1 << 1 = 2
    	Alpha    = 2, // 1 << 2 = 4
    }

    PNG_Error ¶

    PNG_Error :: enum int {
    	None                          = 0, 
    	IHDR_Not_First_Chunk, 
    	IHDR_Corrupt, 
    	IDAT_Missing, 
    	IDAT_Must_Be_Contiguous, 
    	IDAT_Corrupt, 
    	IDAT_Size_Too_Large, 
    	PLTE_Encountered_Unexpectedly, 
    	PLTE_Invalid_Length, 
    	PLTE_Missing, 
    	TRNS_Encountered_Unexpectedly, 
    	TNRS_Invalid_Length, 
    	BKGD_Invalid_Length, 
    	Unknown_Color_Type, 
    	Invalid_Color_Bit_Depth_Combo, 
    	Unknown_Filter_Method, 
    	Unknown_Interlace_Method, 
    	Requested_Channel_Not_Present, 
    	Post_Processing_Error, 
    	Invalid_Chunk_Length, 
    }
     

    PNG-specific definitions

    PNG_IHDR ¶

    PNG_IHDR :: struct #packed {
    	width:              u32be,
    	height:             u32be,
    	bit_depth:          u8,
    	color_type:         PNG_Color_Type,
    	compression_method: u8,
    	filter_method:      u8,
    	interlace_method:   PNG_Interlace_Method,
    }

    PNG_Info ¶

    PNG_Info :: struct {
    	header: PNG_IHDR,
    	chunks: [dynamic]PNG_Chunk,
    }

    PNG_Interlace_Method ¶

    PNG_Interlace_Method :: enum u8 {
    	None  = 0, 
    	Adam7 = 1, 
    }

    QOI_Color_Space ¶

    QOI_Color_Space :: enum u8 {
    	sRGB   = 0, 
    	Linear = 1, 
    }

    QOI_Error ¶

    QOI_Error :: enum int {
    	None                       = 0, 
    	Missing_Or_Corrupt_Trailer,     // Image seemed to have decoded okay, but trailer is missing or corrupt.
    }
     

    QOI-specific definitions

    QOI_Header ¶

    QOI_Header :: struct #packed {
    	magic:       u32be,
    	width:       u32be,
    	height:      u32be,
    	channels:    u8,
    	color_space: QOI_Color_Space,
    }

    QOI_Info ¶

    QOI_Info :: struct {
    	header: QOI_Header,
    }

    RGBA_Pixel ¶

    RGBA_Pixel :: [4]u8

    RGBA_Pixel_16 ¶

    RGBA_Pixel_16 :: [4]u16

    RGB_Pixel ¶

    RGB_Pixel :: [3]u8
     

    Color

    RGB_Pixel_16 ¶

    RGB_Pixel_16 :: [3]u16

    TGA_Alpha_Kind ¶

    TGA_Alpha_Kind :: enum u8 {
    	None, 
    	Undefined_Ignore, 
    	Undefined_Retain, 
    	Useful, 
    	Premultiplied, 
    }

    TGA_Data_Type ¶

    TGA_Data_Type :: enum u8 {
    	No_Image_Data             = 0, 
    	Uncompressed_Color_Mapped = 1, 
    	Uncompressed_RGB          = 2, 
    	Uncompressed_Black_White  = 3, 
    	Compressed_Color_Mapped   = 9, 
    	Compressed_RGB            = 10, 
    	Compressed_Black_White    = 11, 
    }

    TGA_Extension ¶

    TGA_Extension :: struct #packed {
    	extension_size:          u16le,
    	// Size of this struct. If not 495 bytes it means it's an unsupported version.
    	author_name:             [41]u8 "fmt:\"s,0\"",
    	// Author name, ASCII. Zero-terminated
    	author_comments:         [324]u8 "fmt:\"s,0\"",
    	// Author comments, formatted as 4 lines of 80 character lines, each zero terminated.
    	datetime:                struct {
    		month:  u16le,
    		day:    u16le,
    		year:   u16le,
    		hour:   u16le,
    		minute: u16le,
    		second: u16le,
    	},
    	job_name:                [41]u8 "fmt:\"s,0\"",
    	// Author name, ASCII. Zero-terminated
    	job_time:                struct {
    		hour:   u16le,
    		minute: u16le,
    		second: u16le,
    	},
    	software_id:             [41]u8 "fmt:\"s,0\"",
    	// Software ID name, ASCII. Zero-terminated
    	software_version:        struct #packed {
    		number: u16le,
    		// Version number * 100
    		letter: u8 "fmt:\"r\"",
    	},
    	key_color:               [4]u8,
    	// ARGB key color used at time of production
    	aspect_ratio:            [2]u16le,
    	// Numerator / Denominator
    	gamma:                   [2]u16le,
    	// Numerator / Denominator, range should be 0.0..10.0
    	color_correction_offset: u32le,
    	// 0 if no color correction information
    	postage_stamp_offset:    u32le,
    	// 0 if no thumbnail
    	scanline_offset:         u32le,
    	// 0 if no scanline table
    	attributes:              TGA_Alpha_Kind,
    }
    TGA_Footer :: struct #packed {
    	extension_area_offset:      u32le,
    	developer_directory_offset: u32le,
    	signature:                  [18]u8 "fmt:\"s,0\"",
    }

    TGA_Header ¶

    TGA_Header :: struct #packed {
    	id_length:        u8,
    	color_map_type:   u8,
    	data_type_code:   TGA_Data_Type,
    	color_map_origin: u16le,
    	color_map_length: u16le,
    	color_map_depth:  u8,
    	origin:           [2]u16le,
    	dimensions:       [2]u16le,
    	bits_per_pixel:   u8,
    	image_descriptor: u8,
    }

    TGA_Info ¶

    TGA_Info :: struct {
    	header:    TGA_Header,
    	image_id:  string,
    	footer:    runtime.Maybe($T=TGA_Footer),
    	extension: runtime.Maybe($T=TGA_Extension),
    }

    Which_File_Type ¶

    Which_File_Type :: enum int {
    	Unknown, 
    	BMP, 
    	DjVu,      // AT&T DjVu file format
    	EXR, 
    	FLIF, 
    	GIF, 
    	HDR,       // Radiance RGBE HDR
    	ICNS,      // Apple Icon Image
    	JPEG, 
    	JPEG_2000, 
    	JPEG_XL, 
    	NetPBM,    // NetPBM family
    	PIC,       // Softimage PIC
    	PNG,       // Portable Network Graphics
    	PSD,       // Photoshop PSD
    	QOI,       // Quite Okay Image
    	SGI_RGB,   // Silicon Graphics Image RGB file format
    	Sun_Rast,  // Sun Raster Graphic
    	TGA,       // Targa Truevision
    	TIFF,      // Tagged Image File Format
    	WebP, 
    	XBM,       // X BitMap
    }
    Related Procedures With Parameters
    Related Procedures With Returns

    Constants

    MAX_DIMENSIONS ¶

    MAX_DIMENSIONS :: min(#config(MAX_DIMENSIONS, 8192 * 8192), 65535 * 65535)
     

    67_108_864 pixels max by default.

    For QOI, the Worst case scenario means all pixels will be encoded as RGBA literals, costing 5 bytes each.
    This caps memory usage at 320 MiB.
    
    The tunable is limited to 4_294_836_225 pixels maximum, or 4 GiB per 8-bit channel.
    It is not advised to tune it this large.
    
    The 64 Megapixel default is considered to be a decent upper bound you won't run into in practice,
    except in very specific circumstances.
    

    New_TGA_Signature ¶

    New_TGA_Signature :: "TRUEVISION-XFILE.\x00"

    PNG_IHDR_SIZE ¶

    PNG_IHDR_SIZE :: size_of(PNG_IHDR)

    QOI_Magic ¶

    QOI_Magic :: u32be(0x716f6966)
     

    "qoif"

    Variables

    This section is empty.

    Procedures

    alpha_add_if_missing ¶

    alpha_add_if_missing :: proc(img: ^Image, alpha_key: Alpha_Key = Alpha_Key{}, allocator := context.allocator) -> (ok: bool) {…}
     

    Add alpha channel if missing, in-place.

    Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
    Any other number of channels will be considered an error, returning `false` without modifying the image.
    If the input image already has an alpha channel, it'll return `true` early (without considering optional keyed alpha).
    
    If an image doesn't already have an alpha channel:
    If the optional `alpha_key` is provided, it will be resolved as follows:
    	- For RGB,  if pix = key.rgb -> pix = {0, 0, 0, key.a}
    	- For Gray, if pix = key.r  -> pix = {0, key.g}
    Otherwise, an opaque alpha channel will be added.
    

    alpha_apply_keyed_alpha ¶

    alpha_apply_keyed_alpha :: alpha_add_if_missing
     

    Add alpha channel if missing, in-place.

    Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
    Any other number of channels will be considered an error, returning `false` without modifying the image.
    If the input image already has an alpha channel, it'll return `true` early (without considering optional keyed alpha).
    
    If an image doesn't already have an alpha channel:
    If the optional `alpha_key` is provided, it will be resolved as follows:
    	- For RGB,  if pix = key.rgb -> pix = {0, 0, 0, key.a}
    	- For Gray, if pix = key.r  -> pix = {0, key.g}
    Otherwise, an opaque alpha channel will be added.
    

    alpha_drop_if_present ¶

    alpha_drop_if_present :: proc(img: ^Image, options: Options = Options{}, alpha_key: Alpha_Key = Alpha_Key{}, allocator := context.allocator) -> (ok: bool) {…}
     

    Drop alpha channel if present, in-place.

    Expects 1..4 channels (Gray, Gray + Alpha, RGB, RGBA).
    Any other number of channels will be considered an error, returning `false` without modifying the image.
    
    Of the `options`, the following are considered:
    `.alpha_premultiply`
    	If the image has an alpha channel, returns image data as follows:
    		RGB *= A, Gray = Gray *= A
    
    `.blend_background`
    	If `img.background` is set, it'll be blended in like this:
    		RGB = (1 - A) * Background + A * RGB
    
    If an image has 1 (Gray) or 3 (RGB) channels, it'll return early without modifying the image,
    with one exception: `alpha_key` and `img.background` are present, and `.blend_background` is set.
    
    In this case a keyed alpha pixel will be replaced with the background color.
    

    apply_palette_rgb ¶

    apply_palette_rgb :: proc(img: ^Image, palette: [256][3]u8, allocator := context.allocator) -> (ok: bool) {…}
     

    Apply palette to 8-bit single-channel image and return an 8-bit RGB image, in-place. If the image given is not a valid 8-bit single channel image, the procedure will return false early.

    apply_palette_rgba ¶

    apply_palette_rgba :: proc(img: ^Image, palette: [256][4]u8, allocator := context.allocator) -> (ok: bool) {…}
     

    Apply palette to 8-bit single-channel image and return an 8-bit RGBA image, in-place. If the image given is not a valid 8-bit single channel image, the procedure will return false early.

    compute_buffer_size ¶

    compute_buffer_size :: proc(width, height, channels, depth: int, extra_row_bytes: int = int(0)) -> (size: int) {…}
     

    Function to help with image buffer calculations

    destroy ¶

    destroy :: proc(img: ^Image, allocator := context.allocator) {…}

    expand_grayscale ¶

    expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bool) {…}
     

    Replicates grayscale values into RGB(A) 8- or 16-bit images as appropriate. Returns early with false if already an RGB(A) image.

    is_valid_color_image ¶

    is_valid_color_image :: proc(img: ^Image) -> (ok: bool) {…}
     

    Does the image have 3 or 4 channels, a valid bit depth (8 or 16), Is the pointer valid, are the dimensions valid?

    is_valid_grayscale_image ¶

    is_valid_grayscale_image :: proc(img: ^Image) -> (ok: bool) {…}
     

    Does the image have 1 or 2 channels, a valid bit depth (8 or 16), Is the pointer valid, are the dimensions valid?

    is_valid_image ¶

    is_valid_image :: proc(img: ^Image) -> (ok: bool) {…}
     

    Does the image have 1..4 channels, a valid bit depth (8 or 16), Is the pointer valid, are the dimensions valid?

    load_from_bytes ¶

    load_from_bytes :: proc(data: []u8, options: Options, allocator: runtime.Allocator) -> (img: ^Image, err: Error) {…}

    load_from_file ¶

    load_from_file :: proc(filename: string, options: Options = Options{}, allocator := context.allocator) -> (img: ^Image, err: Error) {…}

    read_data ¶

    read_data :: proc(z: $T, $T: typeid) -> (res: typeid, err: compress.General_Error) {…}
     

    Helper functions to read and write data from/to a Context, etc.

    read_u8 ¶

    read_u8 :: proc(z: $T) -> (res: u8, err: compress.General_Error) {…}

    register ¶

    register :: proc(kind: Which_File_Type, loader: Loader_Proc, destroyer: Destroy_Proc) {…}

    return_single_channel ¶

    return_single_channel :: proc(img: ^Image, channel: Channel) -> (res: ^Image, ok: bool) {…}
     

    When you have an RGB(A) image, but want a particular channel.

    which_bytes ¶

    which_bytes :: proc(data: []u8) -> Which_File_Type {…}

    which_file ¶

    which_file :: proc(path: string) -> Which_File_Type {…}

    write_bytes ¶

    write_bytes :: proc(buf: ^bytes.Buffer, data: []u8) -> (err: compress.General_Error) {…}

    Procedure Groups

    Source Files

    Generation Information

    Generated with odin version dev-2024-03 (vendor "odin") Windows_amd64 @ 2024-03-28 21:09:25.967635800 +0000 UTC