Skip to content
Merged

3.1.3 #369

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
nim-version: ['1.4.x', 'stable']
include:
- nim-version: '1.4.x'
- nim-version: 'stable'

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- uses: jiro4989/setup-nim-action@v1
with:
nim-version: ${{ matrix.nim-version }}
- run: nimble test -d:release -y
- run: nimble test -d:release -d:pixieNoSimd -y
- run: nimble test --gc:orc -d:release -y
Expand Down
6 changes: 3 additions & 3 deletions pixie.nimble
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
version = "3.1.2"
version = "3.1.3"
author = "Andre von Houck and Ryan Oldenburg"
description = "Full-featured 2d graphics library for Nim."
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"
Expand Down
9 changes: 6 additions & 3 deletions src/pixie/fileformats/gif.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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]

Expand Down
30 changes: 23 additions & 7 deletions src/pixie/fileformats/png.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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.
Expand Down
49 changes: 40 additions & 9 deletions src/pixie/fileformats/svg.nim
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,11 @@ proc draw(img: Image, node: XmlNode, ctxStack: var seq[Ctx]) =
raise currentExceptionAsPixieError()

proc decodeSvg*(
root: XmlNode, width = 0, height = 0
data: string, width = 0, height = 0
): Image {.raises: [PixieError].} =
## Render SVG XML and return the image. Defaults to the SVG's view box size.
try:
let root = parseXml(data)
if root.tag != "svg":
failInvalid()

Expand Down Expand Up @@ -602,12 +603,42 @@ proc decodeSvg*(
raise newException(PixieError, "Unable to load SVG")

proc decodeSvg*(
data: string, width = 0, height = 0
root: XmlNode, width = 0, height = 0
): Image {.raises: [PixieError].} =
## Render SVG data and return the image. Defaults to the SVG's view box size.
let root =
try:
parseXml(data)
except:
raise currentExceptionAsPixieError()
decodeSvg(root)
## Render SVG XML and return the image. Defaults to the SVG's view box size.
try:
if root.tag != "svg":
failInvalid()

let
viewBox = root.attr("viewBox")
box = viewBox.split(" ")
viewBoxMinX = parseInt(box[0])
viewBoxMinY = parseInt(box[1])
viewBoxWidth = parseInt(box[2])
viewBoxHeight = parseInt(box[3])

var rootCtx = initCtx()
rootCtx = decodeCtx(rootCtx, root)

if viewBoxMinX != 0 or viewBoxMinY != 0:
let viewBoxMin = vec2(-viewBoxMinX.float32, -viewBoxMinY.float32)
rootCtx.transform = rootCtx.transform * translate(viewBoxMin)

if width == 0 and height == 0: # Default to the view box size
result = newImage(viewBoxWidth, viewBoxHeight)
else:
result = newImage(width, height)

let
scaleX = width.float32 / viewBoxWidth.float32
scaleY = height.float32 / viewBoxHeight.float32
rootCtx.transform = rootCtx.transform * scale(vec2(scaleX, scaleY))

var ctxStack = @[rootCtx]
for node in root:
result.draw(node, ctxStack)
except PixieError as e:
raise e
except:
raise newException(PixieError, "Unable to load SVG")
Binary file modified tests/fileformats/svg/diffs/dragon2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/emojitwo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/flat-color-icons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/ionicons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/noto-emoji.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/openmoji.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/rendered/dragon2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/simple-icons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/tabler-icons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/twbs-icons.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/fileformats/svg/twemoji.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.