From b6401baec11860c1cbb3ed47c1d306ca72d55ed9 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Sun, 28 May 2023 23:54:43 -0500 Subject: [PATCH] qoi, ppm ptr+len decode dimens --- src/pixie/fileformats/ppm.nim | 27 ++++++++++++++++++++------- src/pixie/fileformats/qoi.nim | 12 ++++++++++-- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim index 401c218..c81e6f7 100644 --- a/src/pixie/fileformats/ppm.nim +++ b/src/pixie/fileformats/ppm.nim @@ -12,8 +12,10 @@ type template failInvalid() = raise newException(PixieError, "Invalid PPM data") -proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = - if data.len <= 10: # Each part + whitespace +proc decodeHeader( + data: ptr UncheckedArray[uint8], len: int +): PpmHeader {.raises: [PixieError].} = + if len <= 10: # Each part + whitespace raise newException(PixieError, "Invalid PPM file header") var @@ -21,7 +23,7 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = i, readFields: int field: string while readFields < 4: - let c = readUint8(data, i).char + let c = data[i].char if c == '#': commentMode = true elif c == '\n': @@ -120,7 +122,10 @@ proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [PixieErr proc decodePpm*(data: string): Image {.raises: [PixieError].} = ## Decodes Portable Pixel Map data into an Image. - let header = decodeHeader(data) + let header = decodeHeader( + cast[ptr UncheckedArray[uint8]](data.cstring), + data.len + ) if not (header.version in ppmSignatures): failInvalid() @@ -135,13 +140,21 @@ proc decodePpm*(data: string): Image {.raises: [PixieError].} = else: decodeP6Data(data[header.dataOffset .. ^1], header.maxVal) +proc decodePpmDimensions*( + data: pointer, len: int +): ImageDimensions {.raises: [PixieError].} = + ## Decodes the PPM dimensions. + let + data = cast[ptr UncheckedArray[uint8]](data) + header = decodeHeader(data, len) + result.width = header.width + result.height = header.height + proc decodePpmDimensions*( data: string ): ImageDimensions {.raises: [PixieError].} = ## Decodes the PPM dimensions. - let header = decodeHeader(data) - result.width = header.width - result.height = header.height + decodePpmDimensions(data.cstring, data.len) proc encodePpm*(image: Image): string {.raises: [].} = ## Encodes an image into the PPM file format (version P6). diff --git a/src/pixie/fileformats/qoi.nim b/src/pixie/fileformats/qoi.nim index 6e97083..c7d65d9 100644 --- a/src/pixie/fileformats/qoi.nim +++ b/src/pixie/fileformats/qoi.nim @@ -136,15 +136,23 @@ proc decodeQoi*(data: string): Qoi {.raises: [PixieError].} = inc(p) proc decodeQoiDimensions*( - data: string + data: pointer, len: int ): ImageDimensions {.raises: [PixieError].} = ## Decodes the QOI dimensions. - if data.len <= 12 or data[0 .. 3] != qoiSignature: + if len <= 12 or not equalMem(data, qoiSignature.cstring, 4): raise newException(PixieError, "Invalid QOI header") + let data = cast[ptr UncheckedArray[uint8]](data) + result.width = data.readUint32(4).swap().int result.height = data.readUint32(8).swap().int +proc decodeQoiDimensions*( + data: string +): ImageDimensions {.raises: [PixieError].} = + ## Decodes the QOI dimensions. + decodeQoiDimensions(data.cstring, data.len) + proc encodeQoi*(qoi: Qoi): string {.raises: [PixieError].} = ## Encodes raw QOI pixels to the QOI file format.