commit dac334837726ec9e8b7dc7aa666153119bb26989
parent 234c1fc04fef5848a205a7dea96bea29ba5d4e65
Author: Milan Pässler <milan@petabyte.dev>
Date: Sat, 13 Mar 2021 12:27:49 +0100
parent 234c1fc04fef5848a205a7dea96bea29ba5d4e65
Author: Milan Pässler <milan@petabyte.dev>
Date: Sat, 13 Mar 2021 12:27:49 +0100
return sof and exif data
3 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/example.nim b/example.nim @@ -2,6 +2,7 @@ import os import jpg import asyncdispatch import asyncfile +import json var result: cint @@ -15,7 +16,7 @@ init_jpg() if fileExists(path): let file = openAsync(path) - echo $(waitFor collect_jpg(file)) + echo pretty(%* (waitFor collect_jpg(file))) else: echo "Gimme an existing file pls"
diff --git a/exif.nim b/exif.nim @@ -10,7 +10,7 @@ proc init_exif*() = proc deinit_exif*() = dealloc(buf) -proc collect_exif*(ed: ptr ExifData): Table[string, string] {.gcsafe.} = +proc collect_exif_data*(ed: ptr ExifData): Table[string, string] {.gcsafe.} = #result = initTable[string, string]() proc process_entries(entry: ptr ExifEntry , callback_data: pointer) {.cdecl.} =
diff --git a/jpg.nim b/jpg.nim @@ -6,6 +6,8 @@ import libexif import exif import tables import parseutils +import options +import utils var buf {.threadvar.}: pointer @@ -30,9 +32,15 @@ const EXIF = parseHexStr("E1") JFIF = parseHexStr("E0") +type SofData* = object + components*: uint8 + precision*: uint8 + height*: uint16 + width*: uint16 + type JpgInfo* = object - exifInfo*: Table[string, string] - resolution*: tuple[x: int, y: int] + exifData*: Option[Table[string, string]] + sofData*: Option[SofData] proc getSectionSize(file: AsyncFile): Future[uint16] {.async.} = # FIXME consider endianness @@ -43,14 +51,19 @@ proc getSectionSize(file: AsyncFile): Future[uint16] {.async.} = proc skipSection(file: AsyncFile): Future[void] {.async.} = let size = int64(file.getSectionSize().await) - echo("skipping ", size) + 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: - echo("expected ", toHex(expected),", got ", toHex(byte)) - quit(1) + 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 @@ -66,8 +79,7 @@ proc collect_jpg*(file: AsyncFile): Future[JpgInfo] {.gcsafe,async.} = case marker: of "": - echo("unexpected end of file") - quit(1) + error("unexpected end of file") of SOS: # Beginning of compressed data done = true @@ -75,33 +87,28 @@ proc collect_jpg*(file: AsyncFile): Future[JpgInfo] {.gcsafe,async.} = # No compressed data? Okay... done = true of EXIF: - echo "found 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)) - echo ed.collect_exif() + let ed_table = ed.collect_exif_data() + if result.exifData.isNone: + result.exifData = some(ed_table) + debug ed_table of JFIF: - echo "found JFIF" + debug "found JFIF" file.skipSection().await else: if toHex(marker).startsWith("C"): - echo "found SOF" + debug "found SOF" let section_start = file.getFilePos() + 2 let section_end = section_start + int64(file.getSectionSize().await) - var precision, components: uint8 - var height, width: uint16 - discard parseHex(toHex(file.read(1).await), precision) - echo(" precision ", precision) - discard parseHex(toHex(file.read(2).await), height) - echo(" height ", height) - discard parseHex(toHex(file.read(2).await), width) - echo(" width ", width) - discard parseHex(toHex(file.read(1).await), components) - echo(" components ", components) + let sd = file.process_sof().await + if result.sofData.isNone: + result.sofData = some(sd) + debug sd file.setFilePos(section_end) continue - echo("unknown section: ", toHex(marker)) + debug("unknown section: ", toHex(marker)) file.skipSection().await - - return JpgInfo(exifInfo: initTable[string, string](), resolution: (0, 0))