qoi, ppm ptr+len decode dimens

This commit is contained in:
Ryan Oldenburg 2023-05-28 23:54:43 -05:00
parent 4b7a9d1bb4
commit b6401baec1
2 changed files with 30 additions and 9 deletions

View file

@ -12,8 +12,10 @@ type
template failInvalid() = template failInvalid() =
raise newException(PixieError, "Invalid PPM data") raise newException(PixieError, "Invalid PPM data")
proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = proc decodeHeader(
if data.len <= 10: # Each part + whitespace data: ptr UncheckedArray[uint8], len: int
): PpmHeader {.raises: [PixieError].} =
if len <= 10: # Each part + whitespace
raise newException(PixieError, "Invalid PPM file header") raise newException(PixieError, "Invalid PPM file header")
var var
@ -21,7 +23,7 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} =
i, readFields: int i, readFields: int
field: string field: string
while readFields < 4: while readFields < 4:
let c = readUint8(data, i).char let c = data[i].char
if c == '#': if c == '#':
commentMode = true commentMode = true
elif c == '\n': elif c == '\n':
@ -120,7 +122,10 @@ proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [PixieErr
proc decodePpm*(data: string): Image {.raises: [PixieError].} = proc decodePpm*(data: string): Image {.raises: [PixieError].} =
## Decodes Portable Pixel Map data into an Image. ## 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): if not (header.version in ppmSignatures):
failInvalid() failInvalid()
@ -135,13 +140,21 @@ proc decodePpm*(data: string): Image {.raises: [PixieError].} =
else: else:
decodeP6Data(data[header.dataOffset .. ^1], header.maxVal) 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*( proc decodePpmDimensions*(
data: string data: string
): ImageDimensions {.raises: [PixieError].} = ): ImageDimensions {.raises: [PixieError].} =
## Decodes the PPM dimensions. ## Decodes the PPM dimensions.
let header = decodeHeader(data) decodePpmDimensions(data.cstring, data.len)
result.width = header.width
result.height = header.height
proc encodePpm*(image: Image): string {.raises: [].} = proc encodePpm*(image: Image): string {.raises: [].} =
## Encodes an image into the PPM file format (version P6). ## Encodes an image into the PPM file format (version P6).

View file

@ -136,15 +136,23 @@ proc decodeQoi*(data: string): Qoi {.raises: [PixieError].} =
inc(p) inc(p)
proc decodeQoiDimensions*( proc decodeQoiDimensions*(
data: string data: pointer, len: int
): ImageDimensions {.raises: [PixieError].} = ): ImageDimensions {.raises: [PixieError].} =
## Decodes the QOI dimensions. ## 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") raise newException(PixieError, "Invalid QOI header")
let data = cast[ptr UncheckedArray[uint8]](data)
result.width = data.readUint32(4).swap().int result.width = data.readUint32(4).swap().int
result.height = data.readUint32(8).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].} = proc encodeQoi*(qoi: Qoi): string {.raises: [PixieError].} =
## Encodes raw QOI pixels to the QOI file format. ## Encodes raw QOI pixels to the QOI file format.