ptr+len decode image dimens

This commit is contained in:
Ryan Oldenburg 2023-05-29 00:07:29 -05:00
parent b6401baec1
commit 93ade8c889
3 changed files with 39 additions and 19 deletions

View file

@ -18,24 +18,36 @@ converter autoPremultipliedAlpha*(c: ColorRGBA): ColorRGBX {.inline, raises: [].
## Convert a straight alpha RGBA to a premultiplied alpha RGBA.
c.rgbx()
proc decodeImageDimensions*(
data: pointer, len: int
): ImageDimensions {.raises: [PixieError].} =
## Decodes an image's dimensions from memory.
if len > 8 and equalMem(data, pngSignature[0].unsafeAddr, 8):
decodePngDimensions(data, len)
elif len > 2 and equalMem(data, jpegStartOfImage[0].unsafeAddr, 2):
decodeJpegDimensions(data, len)
elif len > 2 and equalMem(data, bmpSignature.cstring, 2):
decodeBmpDimensions(data, len)
elif len > 6 and (
equalMem(data, gifSignatures[0].cstring, 6) or
equalMem(data, gifSignatures[1].cstring, 6)
):
decodeGifDimensions(data, len)
elif len > (14 + 8) and equalMem(data, qoiSignature.cstring, 4):
decodeQoiDimensions(data, len)
elif len > 9 and (
equalMem(data, ppmSignatures[0].cstring, 2) or
equalMem(data, ppmSignatures[1].cstring, 2)
):
decodePpmDimensions(data, len)
else:
raise newException(PixieError, "Unsupported image file format")
proc decodeImageDimensions*(
data: string
): ImageDimensions {.raises: [PixieError].} =
## Decodes an image's dimensions from memory.
if data.len > 8 and data.readUint64(0) == cast[uint64](pngSignature):
decodePngDimensions(data)
elif data.len > 2 and data.readUint16(0) == cast[uint16](jpegStartOfImage):
decodeJpegDimensions(data)
elif data.len > 2 and data.readStr(0, 2) == bmpSignature:
decodeBmpDimensions(data)
elif data.len > 6 and data.readStr(0, 6) in gifSignatures:
decodeGifDimensions(data)
elif data.len > (14+8) and data.readStr(0, 4) == qoiSignature:
decodeQoiDimensions(data)
elif data.len > 9 and data.readStr(0, 2) in ppmSignatures:
decodePpmDimensions(data)
else:
raise newException(PixieError, "Unsupported image file format")
decodeImageDimensions(data.cstring, data.len)
proc decodeImage*(data: string): Image {.raises: [PixieError].} =
## Loads an image from memory.

View file

@ -24,7 +24,6 @@ import chroma, flatty/binny, ../common, ../images, ../internal,
const
fastBits = 9
jpegStartOfImage* = [0xFF.uint8, 0xD8]
deZigZag = [
uint8 00, 01, 08, 16, 09, 02, 03, 10,
uint8 17, 24, 32, 25, 18, 11, 04, 05,
@ -40,6 +39,9 @@ const
1023, 2047, 4095, 8191, 16383, 32767, 65535
]
let
jpegStartOfImage* = [0xFF.uint8, 0xD8]
type
Huffman = object
codes: array[256, uint16]
@ -1155,13 +1157,13 @@ proc decodeJpeg*(data: string): Image {.raises: [PixieError].} =
state.buildImage()
proc decodeJpegDimensions*(
data: string
data: pointer, len: int
): ImageDimensions {.raises: [PixieError].} =
## Decodes the JPEG dimensions.
var state = DecoderState()
state.buffer = cast[ptr UncheckedArray[uint8]](data.cstring)
state.len = data.len
state.buffer = cast[ptr UncheckedArray[uint8]](data)
state.len = len
while true:
if state.readUint8() != 0xFF:
@ -1209,5 +1211,11 @@ proc decodeJpegDimensions*(
else:
failInvalid("invalid orientation")
proc decodeJpegDimensions*(
data: string
): ImageDimensions {.raises: [PixieError].} =
## Decodes the JPEG dimensions.
decodeJpegDimensions(data.cstring, data.len)
when defined(release):
{.pop.}

View file

@ -3,7 +3,7 @@ import chroma, flatty/binny, math, ../common, ../images, ../internal,
# See http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html
const
let
pngSignature* = [137.uint8, 80, 78, 71, 13, 10, 26, 10]
type