ctucx.git: nimexif

nim-wrapper for libexif

commit f5bf66a773f1fa49214df884aa12f285984d4959
parent 6543530ab3297bbc052deaffc710d6c301ccefbe
Author: Milan Pässler <milan@petabyte.dev>
Date: Sat, 13 Mar 2021 13:26:43 +0100

remove jpg functionality
6 files changed, 42 insertions(+), 159 deletions(-)
M
example.nim
|
13
++++++-------
D
exif.nim
|
24
------------------------
D
exif.nimble
|
14
--------------
A
exifnim.nim
|
24
++++++++++++++++++++++++
A
exifnim.nimble
|
12
++++++++++++
D
jpg.nim
|
114
-------------------------------------------------------------------------------
diff --git a/example.nim b/example.nim
@@ -1,7 +1,6 @@
 import os
-import jpg
-import asyncdispatch
-import asyncfile
+import exifnim
+import libexif
 import json
 
 var result: cint

@@ -12,12 +11,12 @@ if paramCount()  == 0:
 
 let path = paramStr(1)
 
-init_jpg()
+init_exif()
 
 if fileExists(path):
-  let file = openAsync(path)
-  echo pretty(%* (waitFor collect_jpg(file)))
+  let ed = exif_data_new_from_file(path)
+  echo pretty(%* ed.collect_exif_data())
 else:
   echo "Gimme an existing file pls"
 
-deinit_jpg()
+deinit_exif()
diff --git a/exif.nim b/exif.nim
@@ -1,24 +0,0 @@
-import libexif
-import tables
-
-var buf {.threadvar.}: cstring
-
-# MUST be called once per thread
-proc init_exif*() =
-  buf = cast[cstring](alloc(2001))
-
-proc deinit_exif*() =
-  dealloc(buf)
-
-proc collect_exif_data*(ed: ptr ExifData): Table[string, string] {.gcsafe.} =
-  proc process_entries(entry: ptr ExifEntry , callback_data: pointer) {.cdecl.} =
-    let name = exif_tag_get_name(entry.tag)
-    let val = exif_entry_get_value(entry, buf, 2000)
-    let result_table = cast[ptr Table[string, string]](callback_data)
-    result_table[][$name] = $val
-
-  proc process_contents(content: ptr ExifContent, callback_data: pointer) {.cdecl.} =
-    exif_content_foreach_entry(content, process_entries, callback_data)
-
-  exif_data_foreach_content(ed, process_contents, addr result)
-  exif_data_unref(ed)
diff --git a/exif.nimble b/exif.nimble
@@ -1,14 +0,0 @@
-# Package
-
-version       = "0.1.0"
-author        = "ctucx, Milan"
-description   = "Read exif data using libexif"
-license       = "GPL-3.0"
-srcDir        = "./"
-bin           = @["example"]
-
-
-
-# Dependencies
-requires "nim >= 1.4"
-requires "nimterop"
diff --git a/exifnim.nim b/exifnim.nim
@@ -0,0 +1,24 @@
+import libexif
+import tables
+
+var buf {.threadvar.}: cstring
+
+# MUST be called once per thread if any of the helper procs are used
+proc init_exif*() =
+  buf = cast[cstring](alloc(2001))
+
+proc deinit_exif*() =
+  dealloc(buf)
+
+proc collect_exif_data*(ed: ptr ExifData): Table[string, string] {.gcsafe.} =
+  proc process_entries(entry: ptr ExifEntry , callback_data: pointer) {.cdecl.} =
+    let name = exif_tag_get_name(entry.tag)
+    let val = exif_entry_get_value(entry, buf, 2000)
+    let result_table = cast[ptr Table[string, string]](callback_data)
+    result_table[][$name] = $val
+
+  proc process_contents(content: ptr ExifContent, callback_data: pointer) {.cdecl.} =
+    exif_content_foreach_entry(content, process_entries, callback_data)
+
+  exif_data_foreach_content(ed, process_contents, addr result)
+  exif_data_unref(ed)
diff --git a/exifnim.nimble b/exifnim.nimble
@@ -0,0 +1,12 @@
+# Package
+
+version       = "0.1.0"
+author        = "ctucx, Milan"
+description   = "Read exif data using libexif"
+license       = "GPL-3.0"
+srcDir        = "./"
+bin           = @["example"]
+
+# Dependencies
+requires "nim >= 1.4"
+requires "nimterop"
diff --git a/jpg.nim b/jpg.nim
@@ -1,114 +0,0 @@
-import os
-import strutils
-import asyncfile
-import asyncdispatch
-import libexif
-import exif
-import tables
-import parseutils
-import options
-import utils
-
-var buf {.threadvar.}: pointer
-
-# MUST be called once per thread
-proc init_jpg*() =
-  init_exif()
-  buf = alloc(65536)
-
-proc deinit_jpg*() =
-  deinit_exif()
-  dealloc(buf)
-
-const
-  MARKER_START = parseHexStr("FF")
-
-  # 0xCn SOFn
-
-  SOS   = parseHexStr("DA") # Start Of Scan (begins compressed data)
-  SOI   = parseHexStr("D8") # Start Of Image (beginning of datastream)
-  EOI   = parseHexStr("D9") # End Of Image (end of datastream)
-
-  EXIF  = parseHexStr("E1")
-  JFIF  = parseHexStr("E0")
-
-type SofData* = object
-  components*: uint8
-  precision*: uint8
-  height*: uint16
-  width*: uint16
-
-type JpgInfo* = object
-  exifData*: Option[Table[string, string]]
-  sofData*: Option[SofData]
-
-proc getSectionSize(file: AsyncFile): Future[uint16] {.async.} =
-  # FIXME consider endianness
-  var size: uint16
-  let val = toHex(file.read(2).await)
-  discard parseHex(val, size)
-  return size - uint16(2)
-
-proc skipSection(file: AsyncFile): Future[void] {.async.} =
-  let size = int64(file.getSectionSize().await)
-  debug("skipping ", size)
-  file.setFilePos(file.getFilePos() + size)
-
-proc expect(file: AsyncFile, expected: string): Future[void] {.async.} =
-  let byte = file.read(1).await
-  if byte != expected:
-    error("expected ", toHex(expected),", got ", toHex(byte))
-
-proc process_sof*(file: AsyncFile): Future[SofData] {.gcsafe,async.} =
-  discard parseHex(toHex(file.read(1).await), result.precision)
-  discard parseHex(toHex(file.read(2).await), result.height)
-  discard parseHex(toHex(file.read(2).await), result.width)
-  discard parseHex(toHex(file.read(1).await), result.components)
-
-proc collect_jpg*(file: AsyncFile): Future[JpgInfo] {.gcsafe,async.} =
-  var done = false
-  var byte: string
-
-  file.expect(MARKER_START).await
-  file.expect(SOI).await
-
-  while not done:
-    file.expect(MARKER_START).await
-
-    let marker = file.read(1).await
-
-    case marker:
-    of "":
-      error("unexpected end of file")
-    of SOS:
-      # Beginning of compressed data
-      done = true
-    of EOI:
-      # No compressed data? Okay...
-      done = true
-    of EXIF:
-      debug "found EXIF"
-      let size = int(file.getSectionSize().await)
-      discard file.readBuffer(buf, size).await
-      let ed = exif_data_new_from_data(cast[ptr[cuchar]](buf), cuint(size))
-      let ed_table = ed.collect_exif_data()
-      if result.exifData.isNone:
-        result.exifData = some(ed_table)
-      debug ed_table
-    of JFIF:
-      debug "found JFIF"
-      file.skipSection().await
-    else:
-      if toHex(marker).startsWith("C"):
-        debug "found SOF"
-        let section_start = file.getFilePos() + 2
-        let section_end = section_start + int64(file.getSectionSize().await)
-        let sd = file.process_sof().await
-        if result.sofData.isNone:
-          result.sofData = some(sd)
-        debug sd
-        file.setFilePos(section_end)
-        continue
-
-      debug("unknown section: ", toHex(marker))
-      file.skipSection().await