myou-engine/libs/tinyexr/tinyexr.nim
Alberto Torres cea7df6947 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

65 lines
2.2 KiB
Nim

# License of this file:
# Consider this file an extension of tinyexr.h (3-clause BSD)
# import memfiles
import tinyexr_c
import arr_ref
import ../float16/float16
# import std/strutils
{.compile: "miniz.c".}
# Can't include implementation because it's cpp, we'll compile it separately
{.compile("impl.cpp", "-std=c++11 -I.").}
{.passL:"-lstdc++".}
proc free(p: pointer) {.header: "stdlib.h", importc, nodecl, raises: [], gcsafe.}
proc isEXR*(p: pointer, len: int): bool =
IsEXRFromMemory(p, len.csize_t) == TINYEXR_SUCCESS
proc getEXRDimensions*(p: pointer, len: int): (int, int) =
var version: EXRVersion
var ret = ParseEXRVersionFromMemory(version, p, len.csize_t)
assert ret == TINYEXR_SUCCESS, "Can't read EXR version"
var header: EXRHeader
header.InitEXRHeader
var err: const_cstring
ret = ParseEXRHeaderFromMemory(header, version, p, len.csize_t, err)
if ret != TINYEXR_SUCCESS:
if err != nil:
echo "error: " & $err
FreeEXRErrorMessage(err)
else:
echo "undefined exr error"
else:
let width = 1 + header.data_window.max_x - header.data_window.min_x
let height = 1 + header.data_window.max_y - header.data_window.min_y
discard header.FreeEXRHeader
return (width.int, height.int)
proc decodeEXR*(p: pointer, len: int): (int, int, ArrRef[uint16]) =
# TODO: avoid copying by using the internal API directly
# TODO: decode float16 directly
# TODO: why can't I use "float16" on the type?
var img: ptr UncheckedArray[float32]
var width: int32
var height: int32
var err: const_cstring
let ret = LoadEXRFromMemory(img, width, height, p, len.csize_t, err)
if ret != TINYEXR_SUCCESS:
if err != nil:
let errs = $err
FreeEXRErrorMessage(err)
raise newException(ValueError, errs)
else:
raise newException(ValueError, "Undefined tinyEXR error")
var imglen = width*height*4
var pixels = newArrRef[uint16](imglen)
# pixels[0].addr.copyMem(img, imglen*sizeof(Float16))
for i in 0 ..< imglen:
pixels[i] = img[i].tofloat16(clamp=true).uint16
free(img)
return (width.int, height.int, pixels)