myou-engine/libs/tinyexr/tinyexr_c.nim
Alberto Torres 9af1322937 First commit.
* Incomplete port of myou-engine-js to nimskull, after many months of work, and
  a few extra features that weren't exactly necessary for a "first commit" to
  work. Excuse the lack of commit history up to this point.
* Bare bones structure of the documentation and the process to update it.
* Restructure of the whole project to have a more sensible organization.
* Making submodules of forks of larger libraries.
* README, licenses, AUTHORS.md.
2024-08-20 13:08:19 +02:00

435 lines
19 KiB
Nim

# from std/os import splitPath
# {.passC:"-I" & currentSourcePath().splitPath.head .}
type const_cstring* {.importc:"const char*".} = cstring
const
TINYEXR_SUCCESS* = (0)
TINYEXR_ERROR_INVALID_MAGIC_NUMBER* = (-1)
TINYEXR_ERROR_INVALID_EXR_VERSION* = (-2)
TINYEXR_ERROR_INVALID_ARGUMENT* = (-3)
TINYEXR_ERROR_INVALID_DATA* = (-4)
TINYEXR_ERROR_INVALID_FILE* = (-5)
TINYEXR_ERROR_INVALID_PARAMETER* = (-6)
TINYEXR_ERROR_CANT_OPEN_FILE* = (-7)
TINYEXR_ERROR_UNSUPPORTED_FORMAT* = (-8)
TINYEXR_ERROR_INVALID_HEADER* = (-9)
TINYEXR_ERROR_UNSUPPORTED_FEATURE* = (-10)
TINYEXR_ERROR_CANT_WRITE_FILE* = (-11)
TINYEXR_ERROR_SERIALIZATION_FAILED* = (-12)
TINYEXR_ERROR_LAYER_NOT_FOUND* = (-13)
TINYEXR_ERROR_DATA_TOO_LARGE* = (-14)
## @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf }
## pixel type: possible values are: UINT = 0 HALF = 1 FLOAT = 2
const
TINYEXR_PIXELTYPE_UINT* = (0)
TINYEXR_PIXELTYPE_HALF* = (1)
TINYEXR_PIXELTYPE_FLOAT* = (2)
TINYEXR_MAX_HEADER_ATTRIBUTES* = (1024)
TINYEXR_MAX_CUSTOM_ATTRIBUTES* = (128)
TINYEXR_COMPRESSIONTYPE_NONE* = (0)
TINYEXR_COMPRESSIONTYPE_RLE* = (1)
TINYEXR_COMPRESSIONTYPE_ZIPS* = (2)
TINYEXR_COMPRESSIONTYPE_ZIP* = (3)
TINYEXR_COMPRESSIONTYPE_PIZ* = (4)
TINYEXR_COMPRESSIONTYPE_ZFP* = (128) ## TinyEXR extension
TINYEXR_ZFP_COMPRESSIONTYPE_RATE* = (0)
TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION* = (1)
TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY* = (2)
TINYEXR_TILE_ONE_LEVEL* = (0)
TINYEXR_TILE_MIPMAP_LEVELS* = (1)
TINYEXR_TILE_RIPMAP_LEVELS* = (2)
TINYEXR_TILE_ROUND_DOWN* = (0)
TINYEXR_TILE_ROUND_UP* = (1)
type
EXRVersion* {.pure, bycopy.} = object
version*: cint
## this must be 2
## tile format image;
## not zero for only a single-part "normal" tiled file (according to spec.)
tiled*: cint
long_name*: cint
## long name attribute
## deep image(EXR 2.0);
## for a multi-part file, indicates that at least one part is of type deep* (according to spec.)
non_image*: cint
multipart*: cint
## multi-part(EXR 2.0)
EXRAttribute* {.pure, bycopy.} = object
name*: array[256, char]
## name and type are up to 255 chars long.
`type`*: array[256, char]
value*: ptr uint8
## uint8_t*
size*: cint
pad0*: cint
EXRChannelInfo* {.pure, bycopy.} = object
name*: array[256, char]
## less than 255 bytes long
pixel_type*: cint
x_sampling*: cint
y_sampling*: cint
p_linear*: uint8
pad*: array[3, uint8]
EXRTile* {.pure, bycopy.} = object
offset_x*: cint
offset_y*: cint
level_x*: cint
level_y*: cint
width*: cint
## actual width in a tile.
height*: cint
## actual height int a tile.
images*: ptr ptr uint8
## image[channels][pixels]
EXRBox2i* {.pure, bycopy.} = object
min_x*: cint
min_y*: cint
max_x*: cint
max_y*: cint
EXRHeader* {.pure, bycopy.} = object
pixel_aspect_ratio*: cfloat
line_order*: cint
data_window*: EXRBox2i
display_window*: EXRBox2i
screen_window_center*: array[2, cfloat]
screen_window_width*: cfloat
chunk_count*: cint
## Properties for tiled format(`tiledesc`).
tiled*: cint
tile_size_x*: cint
tile_size_y*: cint
tile_level_mode*: cint
tile_rounding_mode*: cint
long_name*: cint
## for a single-part file, agree with the version field bit 11
## for a multi-part file, it is consistent with the type of part
non_image*: cint
multipart*: cint
header_len*: cuint
## Custom attributes(exludes required attributes(e.g. `channels`,
## `compression`, etc)
num_custom_attributes*: cint
custom_attributes*: ptr EXRAttribute
## array of EXRAttribute. size =
## `num_custom_attributes`.
channels*: ptr EXRChannelInfo
## [num_channels]
pixel_types*: ptr cint
## Loaded pixel type(TINYEXR_PIXELTYPE_*) of `images` for
## each channel. This is overwritten with `requested_pixel_types` when
## loading.
num_channels*: cint
compression_type*: cint
## compression type(TINYEXR_COMPRESSIONTYPE_*)
requested_pixel_types*: ptr cint
## Filled initially by
## ParseEXRHeaderFrom(Meomory|File), then users
## can edit it(only valid for HALF pixel type
## channel)
## name attribute required for multipart files;
## must be unique and non empty (according to spec.);
## use EXRSetNameAttr for setting value;
## max 255 character allowed - excluding terminating zero
name*: array[256, char]
EXRMultiPartHeader* {.pure, bycopy.} = object
num_headers*: cint
headers*: ptr EXRHeader
EXRImage* {.pure, bycopy.} = object
tiles*: ptr EXRTile
## Tiled pixel data. The application must reconstruct image
## from tiles manually. NULL if scanline format.
next_level*: ptr EXRImage
## NULL if scanline format or image is the last level.
level_x*: cint
## x level index
level_y*: cint
## y level index
images*: ptr ptr uint8
## image[channels][pixels]. NULL if tiled format.
width*: cint
height*: cint
num_channels*: cint
## Properties for tile format.
num_tiles*: cint
EXRMultiPartImage* {.pure, bycopy.} = object
num_images*: cint
images*: ptr EXRImage
DeepImage* {.pure, bycopy.} = object
channel_names*: cstringArray
image*: ptr ptr ptr cfloat
## image[channels][scanlines][samples]
offset_table*: ptr ptr cint
## offset_table[scanline][offsets]
num_channels*: cint
width*: cint
height*: cint
pad0*: cint
## @deprecated { For backward compatibility. Not recommended to use. }
## Loads single-frame OpenEXR image. Assume EXR image contains A(single channel
## alpha) or RGB(A) channels.
## Application must free image data as returned by `out_rgba`
## Result image format is: float x RGBA x width x hight
## Returns negative value and may set error string in `err` when there's an
## error
proc LoadEXR*(out_rgba: var ptr UncheckedArray[cfloat]; width: var cint; height: var cint;
filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Loads single-frame OpenEXR image by specifying layer name. Assume EXR image
## contains A(single channel alpha) or RGB(A) channels. Application must free
## image data as returned by `out_rgba` Result image format is: float x RGBA x
## width x hight Returns negative value and may set error string in `err` when
## there's an error When the specified layer name is not found in the EXR file,
## the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
proc LoadEXRWithLayer*(out_rgba: var ptr UncheckedArray[cfloat]; width: var cint; height: var cint;
filename: cstring; layer_name: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
##
## Get layer infos from EXR file.
##
## @param[out] layer_names List of layer names. Application must free memory
## after using this.
## @param[out] num_layers The number of layers
## @param[out] err Error string(will be filled when the function returns error
## code). Free it using FreeEXRErrorMessage after using this value.
##
## @return TINYEXR_SUCCEES upon success.
##
proc EXRLayers*(filename: cstring; layer_names: ptr cstringArray;
num_layers: ptr cint; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## @deprecated
## Simple wrapper API for ParseEXRHeaderFromFile.
## checking given file is a EXR file(by just look up header)
## @return TINYEXR_SUCCEES for EXR image, TINYEXR_ERROR_INVALID_HEADER for
## others
proc IsEXR*(filename: cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Simple wrapper API for ParseEXRHeaderFromMemory.
## Check if given data is a EXR image(by just looking up a header section)
## @return TINYEXR_SUCCEES for EXR image, TINYEXR_ERROR_INVALID_HEADER for
## others
proc IsEXRFromMemory*(memory: pointer; size: csize_t): cint {.cdecl, importc, raises: [], gcsafe.}
## @deprecated
## Saves single-frame OpenEXR image to a buffer. Assume EXR image contains RGB(A) channels.
## components must be 1(Grayscale), 3(RGB) or 4(RGBA).
## Input image format is: `float x width x height`, or `float x RGB(A) x width x
## hight`
## Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero
## value.
## Save image as fp32(FLOAT) format when `save_as_fp16` is 0.
## Use ZIP compression by default.
## `buffer` is the pointer to write EXR data.
## Memory for `buffer` is allocated internally in SaveEXRToMemory.
## Returns the data size of EXR file when the value is positive(up to 2GB EXR data).
## Returns negative value and may set error string in `err` when there's an
## error
proc SaveEXRToMemory*(data: ptr cfloat; width: cint; height: cint; components: cint;
save_as_fp16: cint; buffer: ptr ptr uint8; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## @deprecated { Not recommended, but handy to use. }
## Saves single-frame OpenEXR image to a buffer. Assume EXR image contains RGB(A) channels.
## components must be 1(Grayscale), 3(RGB) or 4(RGBA).
## Input image format is: `float x width x height`, or `float x RGB(A) x width x
## hight`
## Save image as fp16(HALF) format when `save_as_fp16` is positive non-zero
## value.
## Save image as fp32(FLOAT) format when `save_as_fp16` is 0.
## Use ZIP compression by default.
## Returns TINYEXR_SUCCEES(0) when success.
## Returns negative value and may set error string in `err` when there's an
## error
proc SaveEXR*(data: ptr cfloat; width: cint; height: cint; components: cint;
save_as_fp16: cint; filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Returns the number of resolution levels of the image (including the base)
proc EXRNumLevels*(exr_image: var EXRImage): cint {.cdecl, importc, raises: [], gcsafe.}
## Initialize EXRHeader struct
proc InitEXRHeader*(exr_header: var EXRHeader) {.cdecl, importc, raises: [], gcsafe.}
## Set name attribute of EXRHeader struct (it makes a copy)
proc EXRSetNameAttr*(exr_header: var EXRHeader; name: cstring) {.cdecl, importc, raises: [], gcsafe.}
## Initialize EXRImage struct
proc InitEXRImage*(exr_image: var EXRImage) {.cdecl, importc, raises: [], gcsafe.}
## Frees internal data of EXRHeader struct
proc FreeEXRHeader*(exr_header: var EXRHeader): cint {.cdecl, importc, raises: [], gcsafe.}
## Frees internal data of EXRImage struct
proc FreeEXRImage*(exr_image: var EXRImage): cint {.cdecl, importc, raises: [], gcsafe.}
## Frees error message
proc FreeEXRErrorMessage*(msg: cstring) {.cdecl, importc, raises: [], gcsafe.}
## Parse EXR version header of a file.
proc ParseEXRVersionFromFile*(version: var EXRVersion; filename: cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Parse EXR version header from memory-mapped EXR data.
proc ParseEXRVersionFromMemory*(version: var EXRVersion; memory: pointer;
size: csize_t): cint {.cdecl, importc, raises: [], gcsafe.}
## Parse single-part OpenEXR header from a file and initialize `EXRHeader`.
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc ParseEXRHeaderFromFile*(header: var EXRHeader; version: var EXRVersion;
filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Parse single-part OpenEXR header from a memory and initialize `EXRHeader`.
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc ParseEXRHeaderFromMemory*(header: var EXRHeader; version: var EXRVersion;
memory: pointer; size: csize_t; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Parse multi-part OpenEXR headers from a file and initialize `EXRHeader*`
## array.
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc ParseEXRMultipartHeaderFromFile*(headers: var ptr ptr EXRHeader;
num_headers: var cint;
version: var EXRVersion; filename: cstring;
err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Parse multi-part OpenEXR headers from a memory and initialize `EXRHeader*`
## array
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc ParseEXRMultipartHeaderFromMemory*(headers: var ptr ptr EXRHeader;
num_headers: var cint;
version: var EXRVersion; memory: pointer;
size: csize_t; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Loads single-part OpenEXR image from a file.
## Application must setup `ParseEXRHeaderFromFile` before calling this function.
## Application can free EXRImage using `FreeEXRImage`
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc LoadEXRImageFromFile*(image: var EXRImage; header: var EXRHeader;
filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Loads single-part OpenEXR image from a memory.
## Application must setup `EXRHeader` with
## `ParseEXRHeaderFromMemory` before calling this function.
## Application can free EXRImage using `FreeEXRImage`
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc LoadEXRImageFromMemory*(image: var EXRImage; header: var EXRHeader;
memory: pointer; size: csize_t; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Loads multi-part OpenEXR image from a file.
## Application must setup `ParseEXRMultipartHeaderFromFile` before calling this
## function.
## Application can free EXRImage using `FreeEXRImage`
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc LoadEXRMultipartImageFromFile*(images: var EXRImage;
headers: var ptr EXRHeader; num_parts: cuint;
filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Loads multi-part OpenEXR image from a memory.
## Application must setup `EXRHeader*` array with
## `ParseEXRMultipartHeaderFromMemory` before calling this function.
## Application can free EXRImage using `FreeEXRImage`
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc LoadEXRMultipartImageFromMemory*(images: var EXRImage;
headers: var ptr EXRHeader; num_parts: cuint;
memory: pointer; size: csize_t;
err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Saves multi-channel, single-frame OpenEXR image to a file.
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc SaveEXRImageToFile*(image: var EXRImage; exr_header: var EXRHeader;
filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Saves multi-channel, single-frame OpenEXR image to a memory.
## Image is compressed using EXRImage.compression value.
## Return the number of bytes if success.
## Return zero and will set error string in `err` when there's an
## error.
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc SaveEXRImageToMemory*(image: var EXRImage; exr_header: var EXRHeader;
memory: var ptr uint8; err: var const_cstring): csize_t {.cdecl, importc, raises: [], gcsafe.}
## Saves multi-channel, multi-frame OpenEXR image to a memory.
## Image is compressed using EXRImage.compression value.
## File global attributes (eg. display_window) must be set in the first header.
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc SaveEXRMultipartImageToFile*(images: var EXRImage;
exr_headers: var ptr EXRHeader; num_parts: cuint;
filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## Saves multi-channel, multi-frame OpenEXR image to a memory.
## Image is compressed using EXRImage.compression value.
## File global attributes (eg. display_window) must be set in the first header.
## Return the number of bytes if success.
## Return zero and will set error string in `err` when there's an
## error.
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc SaveEXRMultipartImageToMemory*(images: var EXRImage;
exr_headers: var ptr EXRHeader; num_parts: cuint;
memory: var ptr uint8; err: var const_cstring): csize_t {.cdecl, importc, raises: [], gcsafe.}
## Loads single-frame OpenEXR deep image.
## Application must free memory of variables in DeepImage(image, offset_table)
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc LoadDeepEXR*(out_image: var DeepImage; filename: cstring; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}
## NOT YET IMPLEMENTED:
## Saves single-frame OpenEXR deep image.
## Returns negative value and may set error string in `err` when there's an
## error
## extern int SaveDeepEXR(const DeepImage *in_image, const char *filename,
## const char **err);
## NOT YET IMPLEMENTED:
## Loads multi-part OpenEXR deep image.
## Application must free memory of variables in DeepImage(image, offset_table)
## extern int LoadMultiPartDeepEXR(DeepImage **out_image, int num_parts, const
## char *filename,
## const char **err);
## For emscripten.
## Loads single-frame OpenEXR image from memory. Assume EXR image contains
## RGB(A) channels.
## Returns negative value and may set error string in `err` when there's an
## error
## When there was an error message, Application must free `err` with
## FreeEXRErrorMessage()
proc LoadEXRFromMemory*(out_rgba: var ptr UncheckedArray[cfloat]; width: var cint; height: var cint;
memory: pointer; size: csize_t; err: var const_cstring): cint {.cdecl, importc, raises: [], gcsafe.}