ctucx.git: nimjpg

parse jpg file header

commit 7cfcb30c2f3ffc4e71df1445c99f2a9444d2cb86
parent eb52a606f9aa6d5317e2b9adc37dc92d79ca11c6
Author: Leah (ctucx) <leah@ctu.cx>
Date: Sat, 13 Mar 2021 16:01:44 +0100

rename to nimjpg
7 files changed, 141 insertions(+), 139 deletions(-)
M
.gitignore
|
6
++++--
M
example.nim
|
2
+-
M
example_sync.nim
|
2
+-
D
jpgnim.nim
|
122
-------------------------------------------------------------------------------
D
jpgnim.nimble
|
13
-------------
A
nimjpg.nim
|
122
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A
nimjpg.nimble
|
13
+++++++++++++
diff --git a/.gitignore b/.gitignore
@@ -4,4 +4,6 @@ test_c.o
 test_c
 get_metadata.o
 get_metadata
-exif.o-
\ No newline at end of file
+exif.o
+example
+example_sync+
\ No newline at end of file
diff --git a/example.nim b/example.nim
@@ -1,5 +1,5 @@
 import os
-import jpgnim
+import nimjpg
 import asyncdispatch
 import asyncfile
 import json
diff --git a/example_sync.nim b/example_sync.nim
@@ -1,5 +1,5 @@
 import os
-import jpgnim
+import nimjpg
 import asyncdispatch
 import asyncfile
 import json
diff --git a/jpgnim.nim b/jpgnim.nim
@@ -1,122 +0,0 @@
-import os
-import streams
-import strutils
-import asyncfile
-import asyncdispatch
-import exifnim/libexif
-import exifnim/helpers
-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: Stream | AsyncFile): Future[uint16] {.multisync.} =
-  # FIXME consider endianness
-  var size: uint16
-  let val = toHex(file.read(2).await)
-  discard parseHex(val, size)
-  echo val
-  return size - uint16(2)
-
-proc skipSection(file: Stream | AsyncFile): Future[int] {.multisync.} =
-  let size = int64(file.getSectionSize().await)
-  debug("skipping ", size)
-  file.setFilePos(file.getFilePos() + size)
-
-proc expect(file: Stream | AsyncFile, expected: string): Future[int] {.multisync.} =
-  let byte = file.read(1).await
-  if byte != expected:
-    error("expected ", toHex(expected),", got ", toHex(byte))
-
-proc process_sof*(file: Stream | AsyncFile): Future[SofData] {.multisync.} =
-  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: Stream | AsyncFile): Future[JpgInfo] {.multisync,gcsafe.} =
-  var done = false
-  var byte: string
-
-  discard file.expect(MARKER_START).await
-  discard file.expect(SOI).await
-
-  while not done:
-    discard 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"
-      discard 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))
-      discard file.skipSection().await
-
-proc collect_jpg*(file: File): JpgInfo =
-  let stream = newFileStream(file)
-  result = collect_jpg(stream)
-  stream.close()
diff --git a/jpgnim.nimble b/jpgnim.nimble
@@ -1,13 +0,0 @@
-# Package
-
-version       = "0.1.0"
-author        = "ctucx, Milan"
-description   = "Read jpg headers"
-license       = "GPL-3.0"
-srcDir        = "./"
-bin           = @["example", "example_sync"]
-installFiles  = @["jpgnim.nim", "utils.nim"]
-
-# Dependencies
-requires "nim >= 1.4"
-requires "https://cgit.ctu.cx/exifnim/#main"
diff --git a/nimjpg.nim b/nimjpg.nim
@@ -0,0 +1,122 @@
+import os
+import streams
+import strutils
+import asyncfile
+import asyncdispatch
+import nimexif/libexif
+import nimexif/helpers
+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: Stream | AsyncFile): Future[uint16] {.multisync.} =
+  # FIXME consider endianness
+  var size: uint16
+  let val = toHex(file.read(2).await)
+  discard parseHex(val, size)
+  echo val
+  return size - uint16(2)
+
+proc skipSection(file: Stream | AsyncFile): Future[int] {.multisync.} =
+  let size = int64(file.getSectionSize().await)
+  debug("skipping ", size)
+  file.setFilePos(file.getFilePos() + size)
+
+proc expect(file: Stream | AsyncFile, expected: string): Future[int] {.multisync.} =
+  let byte = file.read(1).await
+  if byte != expected:
+    error("expected ", toHex(expected),", got ", toHex(byte))
+
+proc process_sof*(file: Stream | AsyncFile): Future[SofData] {.multisync.} =
+  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: Stream | AsyncFile): Future[JpgInfo] {.multisync,gcsafe.} =
+  var done = false
+  var byte: string
+
+  discard file.expect(MARKER_START).await
+  discard file.expect(SOI).await
+
+  while not done:
+    discard 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"
+      discard 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))
+      discard file.skipSection().await
+
+proc collect_jpg*(file: File): JpgInfo =
+  let stream = newFileStream(file)
+  result = collect_jpg(stream)
+  stream.close()
diff --git a/nimjpg.nimble b/nimjpg.nimble
@@ -0,0 +1,13 @@
+# Package
+
+version       = "0.1.0"
+author        = "ctucx, Milan"
+description   = "Read jpg headers"
+license       = "GPL-3.0"
+srcDir        = "./"
+bin           = @["example", "example_sync"]
+installFiles  = @["nimjpg.nim", "utils.nim"]
+
+# Dependencies
+requires "nim >= 1.4"
+requires "https://cgit.ctu.cx/nimexif"