about summary refs log tree commit diff stats
path: root/adapter/img/stbi.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-06-20 21:28:23 +0200
committerbptato <nincsnevem662@gmail.com>2024-06-20 22:38:33 +0200
commit7f66b5ebc88936db974e3320d77c7ec9d4ab85e6 (patch)
tree669b2c307e2ea84476d6bbfd46ef127c0fc1c6f9 /adapter/img/stbi.nim
parent2ab1e53b4bc15af3319994fdb25bb739b4b8e6db (diff)
downloadchawan-7f66b5ebc88936db974e3320d77c7ec9d4ab85e6.tar.gz
img: use stb_image, drop zlib as dependency
Now we have decoders for gif, jpeg, bmp. Also, the in-house PNG decoder
has been replaced in favor of the stbi implementation; this means we
no longer depend on zlib, since stbi comes with a built in inflate
implementation.
Diffstat (limited to 'adapter/img/stbi.nim')
-rw-r--r--adapter/img/stbi.nim57
1 files changed, 57 insertions, 0 deletions
diff --git a/adapter/img/stbi.nim b/adapter/img/stbi.nim
new file mode 100644
index 00000000..35ef8f64
--- /dev/null
+++ b/adapter/img/stbi.nim
@@ -0,0 +1,57 @@
+import std/os
+
+import utils/sandbox
+import utils/twtstr
+
+{.compile: "stb_image.c".}
+
+type stbi_io_callbacks = object
+  read: proc(user: pointer; data: ptr uint8; size: cint): cint {.cdecl.}
+  skip: proc(user: pointer; n: cint) {.cdecl.}
+  eof: proc(user: pointer): cint {.cdecl.}
+
+proc stbi_load_from_callbacks(clbk: ptr stbi_io_callbacks; user: pointer;
+  x, y, channels_in_file: var cint; desired_channels: cint):
+  ptr UncheckedArray[uint8] {.importc.}
+
+proc stbi_failure_reason(): cstring {.importc.}
+
+proc myRead(user: pointer; data: ptr uint8; size: cint): cint {.cdecl.} =
+  return cint(stdin.readBuffer(data, size))
+
+proc mySkip(user: pointer; n: cint) {.cdecl.} =
+  var data: array[4096, uint8]
+  let n = int(n)
+  var i = 0
+  while i < n:
+    let j = stdin.readBuffer(addr data[0], n - i)
+    if j < data.len:
+      break
+    i += j
+
+proc myEof(user: pointer): cint {.cdecl.} =
+  return cint(stdin.endOfFile())
+
+proc main() =
+  enterNetworkSandbox()
+  let scheme = getEnv("MAPPED_URI_SCHEME")
+  let f = scheme.after('+')
+  if f notin ["jpeg", "gif", "bmp", "png"]:
+    stdout.write("Cha-Control: ConnectionError 1 wrong format " & f)
+  var x: cint
+  var y: cint
+  var channels_in_file: cint
+  var clbk = stbi_io_callbacks(
+    read: myRead,
+    skip: mySkip,
+    eof: myEof
+  )
+  let p = stbi_load_from_callbacks(addr clbk, nil, x, y, channels_in_file, 4)
+  if p == nil:
+    stdout.write("Cha-Control: ConnectionError 1 stbi error " &
+      $stbi_failure_reason())
+    return
+  stdout.write("Cha-Image-Dimensions: " & $x & "x" & $y & "\n\n")
+  discard stdout.writeBuffer(p, x * y * 4)
+
+main()