commit f5bf66a773f1fa49214df884aa12f285984d4959
parent 6543530ab3297bbc052deaffc710d6c301ccefbe
Author: Milan Pässler <milan@petabyte.dev>
Date: Sat, 13 Mar 2021 13:26:43 +0100
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(-)
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