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. ## Convert a straight alpha RGBA to a premultiplied alpha RGBA.
c.rgbx() 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*( proc decodeImageDimensions*(
data: string data: string
): ImageDimensions {.raises: [PixieError].} = ): ImageDimensions {.raises: [PixieError].} =
## Decodes an image's dimensions from memory. ## Decodes an image's dimensions from memory.
if data.len > 8 and data.readUint64(0) == cast[uint64](pngSignature): decodeImageDimensions(data.cstring, data.len)
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")
proc decodeImage*(data: string): Image {.raises: [PixieError].} = proc decodeImage*(data: string): Image {.raises: [PixieError].} =
## Loads an image from memory. ## Loads an image from memory.

View file

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