# image_loader.h ## Overview
Defines an image loader interface `tm_image_loader_i` for objects that are capable of loading image data from files (JPEG, PNG, ...) as well as an image loader API `tm_image_loader_api` that can be used to add and remove such loaders. !!! TODO: API-REVIEW: Use API registry instead of `add_loader()`? Should we use the standard `tm_api_registry_api->add_implementation()` mechanism to add image loaders instead of `tm_image_loader_api->add_loader()`?
## Index
`enum tm_image_type`
`struct tm_image_t`
`tm_image_archive_o`

`struct tm_image_archive_i`
`inst`
`read()`
`size()`

`tm_image_loader_o`

`struct tm_image_loader_i`
`inst`
`extensions_string()`
`description_string()`
`support_from_archive()`
`support_from_extension()`
`load_image()`

`tm_image_loader_i_version`

`struct tm_image_loader_api`
`add_loader()`
`remove_loader()`
`loader_from_archive()`
`loader_from_extension()`
`loaders()`

`tm_image_loader_api_version`
## API
### `enum tm_image_type`
Describes the type of an image. ~~~c enum tm_image_type { // Image is one dimensional. TM_IMAGE_TYPE_1D, // Image is two dimensional. TM_IMAGE_TYPE_2D, // Image is three dimensional / volume. TM_IMAGE_TYPE_3D, // Image is a cube map. TM_IMAGE_TYPE_CUBE, }; ~~~
### `struct tm_image_t`
Image information. ~~~c typedef struct tm_image_t { // One of [[enum tm_image_type]]. uint32_t type; // Buffer format UID, use [[tm_buffer_format_api]] to interpret. uint32_t pixel_format; // Width of image in pixels. uint32_t width; // Height of image in pixels. uint32_t height; // Depth of image in pixels, always 1 unless `type == TM_IMAGE_TYPE_3D`. uint32_t depth; // Number of mip levels in image. uint32_t mip_levels; // If layers > 1, the image is a texture array. uint32_t layers; // Size of image in bytes. uint32_t size; } tm_image_t; ~~~
### `tm_image_archive_o`
~~~c typedef struct tm_image_archive_o tm_image_archive_o; ~~~ Abstract object representing an "archive" -- a stored image.
### `struct tm_image_archive_i`
Abstract interface used by image loaders for loading image data from an archive. #### `inst` ~~~c tm_image_archive_o *inst; ~~~ #### `read()` ~~~c uint32_t (*read)(tm_image_archive_o *inst, void *buffer, uint64_t offset, uint32_t size); ~~~ Attempts to read `size` of bytes into `buffer` starting at `offset`, returns number of bytes actually read. #### `size()` ~~~c uint64_t (*size)(tm_image_archive_o *inst); ~~~ Returns the size of the archive.
### `tm_image_loader_o`
~~~c typedef struct tm_image_loader_o tm_image_loader_o; ~~~ Abstract object representing an image loader.
### `struct tm_image_loader_i`
Interface for an "image loader" that can load images from an archive. #### `inst` ~~~c tm_image_loader_o *inst; ~~~ #### `extensions_string()` ~~~c void (*extensions_string)(struct tm_image_loader_o *inst, char **output, struct tm_temp_allocator_i *ta, const char *separator); ~~~ Appends a string with all supported file extensions the image loader interface can load to the carray `output`. Each file extension is separated by the `separator` string. !!! TODO: API-REVIEW Use a regular array instead? #### `description_string()` ~~~c void (*description_string)(struct tm_image_loader_o *inst, char **output, struct tm_temp_allocator_i *ta, const char *separator); ~~~ Appends a string with all supported file descriptions the image loader interface can load to the carray `output`. Each file extension is separated by the `separator` string. !!! TODO: API-REVIEW Make this optional. #### `support_from_archive()` ~~~c bool (*support_from_archive)(tm_image_loader_o *inst, tm_image_archive_i *image_archive); ~~~ Returns `true` if this loader supports loading an image from `image_archive`. Implemented by peeking into the archive header to determine the file type. #### `support_from_extension()` ~~~c bool (*support_from_extension)(tm_image_loader_o *inst, const char *extension); ~~~ Returns `true` if loader supports loading archives with file extension `extension`. Typically faster than `support_from_archive()` since it just needs to compare `extension` against a known list of supported extensions. `extension` should include the leading dot, e.g `.dds`, `.tga`, ... #### `load_image()` ~~~c bool (*load_image)(tm_image_loader_o *inst, tm_image_archive_i *image_archive, tm_image_t *image, uint8_t *bits); ~~~ Attempts to load an image from `image_archive` into the descriptor `image` and the data array `bits`. Returns `true` if the image was successfully loaded. If `bits` is `NULL`, only the image descriptor will be parsed. Use this and `image->size` to determine the amount of memory to allocate for `bits`.
### `tm_image_loader_i_version`
~~~c #define tm_image_loader_i_version TM_VERSION(1, 0, 0) ~~~ Current version of `tm_image_loader_i` to use with `tm_add_or_remove_implementation()`.
### `struct tm_image_loader_api`
API for adding and removing image loaders. !!! TODO: API-REVIEW: Use API registry instead of `add_loader()`? Remove this API and use `tm_api_registry_api->add_implementation()` instead? #### `add_loader()` ~~~c void (*add_loader)(tm_image_loader_i *loader); ~~~ Adds a new image loader into the registry. #### `remove_loader()` ~~~c void (*remove_loader)(tm_image_loader_i *loader); ~~~ Removes an image loader from the registry. #### `loader_from_archive()` ~~~c tm_image_loader_i *(*loader_from_archive)(tm_image_archive_i *image_archive); ~~~ Returns the first image loader from the registry that supports loading the image pointed to by `image_archive`. If no loader is found, 0 is returned. #### `loader_from_extension()` ~~~c tm_image_loader_i *(*loader_from_extension)(const char *extension); ~~~ Returns the first image loader from the registry that supports loading the image with the file `extension`. Typically faster than `loader_from_archive()` if the file extension is known. If no loader is found, 0 is returned. #### `loaders()` ~~~c uint32_t (*loaders)(tm_image_loader_i **loaders); ~~~ Returns all registered image loader interfaces in `loaders`, pass `NULL` for `loaders` to query the number of active loaders.
### `tm_image_loader_api_version`
~~~c #define tm_image_loader_api_version TM_VERSION(1, 0, 0) ~~~