From 05cce9b58f7f996806542b290267ae952557fcae Mon Sep 17 00:00:00 2001 From: andri lim Date: Fri, 24 Nov 2017 12:40:33 +0700 Subject: [PATCH] apng minor adjusment --- nimPNG.nim | 152 +++++++++++++++++++++++++++++++---------------------- readme.md | 2 +- 2 files changed, 91 insertions(+), 63 deletions(-) diff --git a/nimPNG.nim b/nimPNG.nim index 4724706..0b85ca6 100644 --- a/nimPNG.nim +++ b/nimPNG.nim @@ -181,6 +181,8 @@ type blendOp*: APNG_BLEND_OP APNGFrameData = ref object of APNGFrameChunk + # during decoding frameDataPos points to chunk.data[pos] + # during encoding frameDataPos points to png.apngPixels[pos] and png.apngChunks[pos] frameDataPos: int PNGPass = object @@ -214,9 +216,13 @@ type second*: int #range[0..60] #to allow for leap seconds PNG* = ref object + # during encoding, settings is PNGEncoder + # during decoding, settings is PNGDecoder settings*: PNGSettings chunks*: seq[PNGChunk] pixels*: string + # during encoding, apngChunks contains only fcTL chunks + # during decoding, apngChunks contains both fcTL and fdAT chunks apngChunks*: seq[APNGFrameChunk] firstFrameIsDefaultImage*: bool isAPNG*: bool @@ -1912,90 +1918,108 @@ proc toString(chunk: APNGFrameData): string = result = newString(fdatLen) copyMem(result[0].addr, fdatAddr, fdatLen) +type + APNG = ref object + png: PNG + result: PNGResult + +proc processingAPNG(apng: APNG, colorType: PNGcolorType, bitDepth: int) = + let header = PNGHeader(apng.png.getChunk(IHDR)) + var + actl = APNGAnimationControl(apng.png.getChunk(acTL)) + frameControl = newSeqOfCap[APNGFrameControl](actl.numFrames) + frameData = newSeqOfCap[string](actl.numFrames) + numFrames = 0 + lastChunkType = PNGChunkType(0) + start = 0 + + if apng.png.firstFrameIsDefaultImage: + start = 1 + # IDAT already processed, so we add a dummy here + frameData.add string(nil) + + for x in apng.png.apngChunks: + if x.chunkType == fcTL: + frameControl.add APNGFrameControl(x) + inc numFrames + lastChunkType = fcTL + else: + let y = APNGFrameData(x) + if lastChunkType == fdAT: + frameData[^1].add y.toString() + else: + frameData.add y.toString() + lastChunkType = fdAT + + if actl.numFrames == 0 or actl.numFrames != numFrames or actl.numFrames != frameData.len: + raise PNGError("animation numFrames error") + + apng.png.apngPixels = newSeqOfCap[string](numFrames) + + if apng.result != nil: + apng.result.frames = newSeqOfCap[APNGFrame](numFrames) + + if apng.png.firstFrameIsDefaultImage: + let ctl = frameControl[0] + if ctl.width != header.width or ctl.height != header.height: + raise PNGError("animation control error: dimension") + if ctl.xOffset != 0 or ctl.xOffset != 0: + raise PNGError("animation control error: offset") + + if apng.result != nil: + var frame = new(APNGFrame) + frame.ctl = ctl + frame.data = apng.result.data + apng.result.frames.add frame + + for i in start..