png decode perf improvement

This commit is contained in:
Ryan Oldenburg 2021-04-11 13:09:16 -05:00
parent 75915ab05f
commit 8dbb78c387

View file

@ -102,33 +102,44 @@ proc unfilter(
# Unfilter the image data # Unfilter the image data
for y in 0 ..< height: for y in 0 ..< height:
let filterType = uncompressed[uncompressedIdx(0, y)] let filterType = uncompressed[uncompressedIdx(0, y)]
for x in 0 ..< rowBytes:
var value = uncompressed[uncompressedIdx(x + 1, y)]
case filterType: case filterType:
of 0: # None of 0: # None
discard discard
of 1: # Sub of 1: # Sub
for x in 0 ..< rowBytes:
var value = uncompressed[uncompressedIdx(x + 1, y)]
if x - bpp >= 0: if x - bpp >= 0:
value += result[unfiteredIdx(x - bpp, y)] value += result[unfiteredIdx(x - bpp, y)]
result[unfiteredIdx(x, y)] = value
of 2: # Up of 2: # Up
for x in 0 ..< rowBytes:
var value = uncompressed[uncompressedIdx(x + 1, y)]
if y - 1 >= 0: if y - 1 >= 0:
value += result[unfiteredIdx(x, y - 1)] value += result[unfiteredIdx(x, y - 1)]
result[unfiteredIdx(x, y)] = value
of 3: # Average of 3: # Average
var left, up: int for x in 0 ..< rowBytes:
var
value = uncompressed[uncompressedIdx(x + 1, y)]
left, up: int
if x - bpp >= 0: if x - bpp >= 0:
left = result[unfiteredIdx(x - bpp, y)].int left = result[unfiteredIdx(x - bpp, y)].int
if y - 1 >= 0: if y - 1 >= 0:
up = result[unfiteredIdx(x, y - 1)].int up = result[unfiteredIdx(x, y - 1)].int
value += ((left + up) div 2).uint8 value += ((left + up) div 2).uint8
result[unfiteredIdx(x, y)] = value
of 4: # Paeth of 4: # Paeth
var left, up, upLeft: int for x in 0 ..< rowBytes:
var
value = uncompressed[uncompressedIdx(x + 1, y)]
left, up, upLeft: int
if x - bpp >= 0: if x - bpp >= 0:
left = result[unfiteredIdx(x - bpp, y)].int left = result[unfiteredIdx(x - bpp, y)].int
if y - 1 >= 0: if y - 1 >= 0:
up = result[unfiteredIdx(x, y - 1)].int up = result[unfiteredIdx(x, y - 1)].int
if x - bpp >= 0 and y - 1 >= 0: if x - bpp >= 0 and y - 1 >= 0:
upLeft = result[unfiteredIdx(x - bpp, y - 1)].int upLeft = result[unfiteredIdx(x - bpp, y - 1)].int
proc paethPredictor(a, b, c: int): int {.inline.} = template paethPredictor(a, b, c: int): int =
let let
p = a + b - c p = a + b - c
pa = abs(p - a) pa = abs(p - a)
@ -141,11 +152,10 @@ proc unfilter(
else: else:
c c
value += paethPredictor(up, left, upLeft).uint8 value += paethPredictor(up, left, upLeft).uint8
result[unfiteredIdx(x, y)] = value
else: else:
discard # Not possible, parseHeader validates discard # Not possible, parseHeader validates
result[unfiteredIdx(x, y)] = value
proc decodeImageData( proc decodeImageData(
header: PngHeader, header: PngHeader,
palette: seq[ColorRGB], palette: seq[ColorRGB],