From d65fd681617ca30d7568b14eb518ea7a67e074e3 Mon Sep 17 00:00:00 2001 From: Ryan Oldenburg Date: Tue, 25 Jan 2022 16:48:01 -0600 Subject: [PATCH] zippy 0.8.1 --- pixie.nimble | 4 ++-- src/pixie/fileformats/gif.nim | 9 ++++++--- src/pixie/fileformats/png.nim | 30 +++++++++++++++++++++++------- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/pixie.nimble b/pixie.nimble index d8cf7b3..66a5c04 100644 --- a/pixie.nimble +++ b/pixie.nimble @@ -5,10 +5,10 @@ license = "MIT" srcDir = "src" -requires "nim >= 1.4.0" +requires "nim >= 1.4.8" requires "vmath >= 1.1.0" requires "chroma >= 0.2.5" -requires "zippy >= 0.7.4" +requires "zippy >= 0.8.1" requires "flatty >= 0.2.2" requires "nimsimd >= 1.0.0" requires "bumpy >= 1.0.3" diff --git a/src/pixie/fileformats/gif.nim b/src/pixie/fileformats/gif.nim index b2ee795..1b89302 100644 --- a/src/pixie/fileformats/gif.nim +++ b/src/pixie/fileformats/gif.nim @@ -101,7 +101,10 @@ proc decodeGif*(data: string): Image {.raises: [PixieError].} = # Turn full lzw data into bit stream. var - bs = initBitStream(lzwData) + bs = BitStreamReader( + src: cast[ptr UncheckedArray[uint8]](lzwData[0].addr), + len: lzwData.len + ) bitSize = lzwMinBitSize + 1 currentCodeTableMax = (1 shl (bitSize)) - 1 codeLast: int = -1 @@ -110,10 +113,10 @@ proc decodeGif*(data: string): Image {.raises: [PixieError].} = # Main decode loop. while codeLast != endCode: - if bs.pos + bitSize.int > bs.data.len * 8: failInvalid() + if bs.pos + bitSize.int > bs.len * 8: failInvalid() var # Read variable bits out of the table. - codeId = bs.readBits(bitSize).int + codeId = bs.readBits(bitSize.int).int # Some time we need to carry over table information. carryOver: seq[int] diff --git a/src/pixie/fileformats/png.nim b/src/pixie/fileformats/png.nim index cfd65a2..fb96177 100644 --- a/src/pixie/fileformats/png.nim +++ b/src/pixie/fileformats/png.nim @@ -165,14 +165,31 @@ proc unfilter( discard # Not possible, parseHeader validates proc decodeImageData( + data: string, header: PngHeader, palette: seq[ColorRGB], - transparency, data: string + transparency: string, + idats: seq[(int, int)] ): seq[ColorRGBA] = + if idats.len == 0: + failInvalid() + result.setLen(header.width * header.height) let - uncompressed = try: uncompress(data) except ZippyError: failInvalid() + uncompressed = + if idats.len > 1: + var imageData: string + for (start, len) in idats: + let op = imageData.len + imageData.setLen(imageData.len + len) + copyMem(imageData[op].addr, data[start].unsafeAddr, len) + try: uncompress(imageData) except ZippyError: failInvalid() + else: + let + (start, len) = idats[0] + p = data[start].unsafeAddr + try: uncompress(p, len) except ZippyError: failInvalid() valuesPerPixel = case header.colorType: of 0: 1 @@ -340,7 +357,8 @@ proc decodePngRaw*(data: string): Png {.raises: [PixieError].} = counts = ChunkCounts() header: PngHeader palette: seq[ColorRGB] - transparency, imageData: string + transparency: string + idats: seq[(int, int)] prevChunkType: string # First chunk must be IHDR @@ -402,9 +420,7 @@ proc decodePngRaw*(data: string): Png {.raises: [PixieError].} = failInvalid() if header.colorType == 3 and counts.PLTE == 0: failInvalid() - let op = imageData.len - imageData.setLen(imageData.len + chunkLen) - copyMem(imageData[op].addr, data[pos].unsafeAddr, chunkLen) + idats.add((pos, chunkLen)) of "IEND": if chunkLen != 0: failInvalid() @@ -432,7 +448,7 @@ proc decodePngRaw*(data: string): Png {.raises: [PixieError].} = result.width = header.width result.height = header.height result.channels = 4 - result.data = decodeImageData(header, palette, transparency, imageData) + result.data = decodeImageData(data, header, palette, transparency, idats) proc decodePng*(data: string): Image {.raises: [PixieError].} = ## Decodes the PNG data into an Image.