commit
a911e9d498
|
@ -1,4 +1,4 @@
|
||||||
version = "5.0.1"
|
version = "5.0.2"
|
||||||
author = "Andre von Houck and Ryan Oldenburg"
|
author = "Andre von Houck and Ryan Oldenburg"
|
||||||
description = "Full-featured 2d graphics library for Nim."
|
description = "Full-featured 2d graphics library for Nim."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import bumpy, chroma, vmath
|
import bumpy, chroma, vmath
|
||||||
|
|
||||||
type
|
type
|
||||||
PixieError* = object of ValueError ## Raised if an operation fails.
|
PixieError* = object of CatchableError ## Raised if an operation fails.
|
||||||
|
|
||||||
BlendMode* = enum
|
BlendMode* = enum
|
||||||
NormalBlend
|
NormalBlend
|
||||||
|
|
|
@ -575,22 +575,59 @@ proc encodePng*(
|
||||||
|
|
||||||
# Add IDAT
|
# Add IDAT
|
||||||
# Add room for 1 byte before each row for the filter type.
|
# Add room for 1 byte before each row for the filter type.
|
||||||
var filtered = newString(width * height * channels + height)
|
var
|
||||||
|
filtered = newString(width * height * channels + height)
|
||||||
|
upRow = newSeq[uint8](width * channels)
|
||||||
|
subRow = newSeq[uint8](width * channels)
|
||||||
|
avgRow = newSeq[uint8](width * channels)
|
||||||
for y in 0 ..< height:
|
for y in 0 ..< height:
|
||||||
filtered[y * width * channels + y] = 2.char # Up filter type
|
let rowStart = y * width * channels
|
||||||
for x in 0 ..< width * channels:
|
for x in 0 ..< width * channels:
|
||||||
# Move through the image data byte-by-byte
|
# Move through the image data byte-by-byte
|
||||||
let
|
let dataPos = rowStart + x
|
||||||
dataPos = y * width * channels + x
|
var left, up: uint8
|
||||||
filteredPos = y * width * channels + y + 1 + x
|
if x - channels >= 0:
|
||||||
var up: uint8
|
left = data[dataPos - channels]
|
||||||
if y - 1 >= 0:
|
if y - 1 >= 0:
|
||||||
up = data[(y - 1) * width * channels + x]
|
up = data[(y - 1) * width * channels + x]
|
||||||
filtered[filteredPos] = (data[dataPos] - up).char
|
upRow[x] = data[dataPos] - up.uint8
|
||||||
|
subRow[x] = data[dataPos] - left.uint8
|
||||||
|
let avg = ((left.int + up.int) div 2).uint8
|
||||||
|
avgRow[x] = data[dataPos] - avg
|
||||||
|
|
||||||
|
var upRowSum, subRowSum, avgRowSum: uint64
|
||||||
|
for i in 0 ..< upRow.len:
|
||||||
|
upRowSum += upRow[i]
|
||||||
|
subRowSum += subRow[i]
|
||||||
|
avgRowSum += avgRow[i]
|
||||||
|
|
||||||
|
let minRowSum = min(min(upRowSum, subRowSum), avgRowSum)
|
||||||
|
|
||||||
|
if upRowSum == minRowSum:
|
||||||
|
filtered[rowStart + y] = 2.char # Up filter type
|
||||||
|
copyMem(
|
||||||
|
filtered[rowStart + y + 1].addr,
|
||||||
|
upRow[0].addr,
|
||||||
|
upRow.len
|
||||||
|
)
|
||||||
|
elif subRowSum == minRowSum:
|
||||||
|
filtered[rowStart + y] = 1.char # Sub filter type
|
||||||
|
copyMem(
|
||||||
|
filtered[rowStart + y + 1].addr,
|
||||||
|
subRow[0].addr,
|
||||||
|
subRow.len
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
filtered[rowStart + y] = 3.char # Average filter type
|
||||||
|
copyMem(
|
||||||
|
filtered[rowStart + y + 1].addr,
|
||||||
|
avgRow[0].addr,
|
||||||
|
avgRow.len
|
||||||
|
)
|
||||||
|
|
||||||
let compressed =
|
let compressed =
|
||||||
try:
|
try:
|
||||||
compress(filtered, BestSpeed, dfZlib)
|
compress(filtered, DefaultCompression, dfZlib)
|
||||||
except ZippyError:
|
except ZippyError:
|
||||||
raise newException(
|
raise newException(
|
||||||
PixieError, "Unexpected error compressing PNG image data"
|
PixieError, "Unexpected error compressing PNG image data"
|
||||||
|
|
Loading…
Reference in a new issue