jangko / nimpng Goto Github PK
View Code? Open in Web Editor NEWPNG (Portable Network Graphics) decoder and encoder written in Nim
License: MIT License
PNG (Portable Network Graphics) decoder and encoder written in Nim
License: MIT License
Someone brought up in the realtime chat that import nimPNG
triggers this Error: undeclared identifier: 'shallowCopy'
on Nim version 2.0.0. I told them to just use --gc:refc
for now, but this should probably be fixed.
Nim Compiler Version 1.6.0 [Windows: amd64]
savePNG(filename, data, LCT_RGBA, 32, swCanvas32.w, swCanvas32.h)
results in:
C:\Users\user\git\nico\nico\backends\sdl2.nim(807, 10) template/generic instantiation of `savePNG` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(3131, 18) template/generic instantiation of `savePNGImpl` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(3002, 26) template/generic instantiation of `encodePNG` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(2967, 21) template/generic instantiation of `encodePNG` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(2954, 17) template/generic instantiation of `encoderCore` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(2873, 18) template/generic instantiation of `frameConvert` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(2833, 24) template/generic instantiation of `preProcessScanLines` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(2642, 13) template/generic instantiation of `filter` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG.nim(2620, 30) template/generic instantiation of `filterMinsum` from here
C:\Users\user\.nimble\pkgs\nimPNG-#head\nimPNG\filters.nim(138, 31) Error: template instantiation too nested
i want to loop through all the pixel and want to do like this if color == white: color = transparent
please make an example folder and provide some basic examples. thank you.
Essentially it would be nice if nimPNG could parse a 16-bit greyscale into a seq[uint16]
for example, and similarly write this data. This shouldn't be too hard to implement, although might add a bit of complexity when handling byte ordering, but it would make it much easier to use nimPNG.
we still don't have adequate documentation about PNG encoder settings.
and if we do implement #69, we also need to add compression library settings into the doc.
As claried by nim-lang/Nim#22555
newString returns a new string of length
len
but with uninitialized
A potential solution is to define a newStringWithDefault
function:
proc newStringWithDefault(x: int): string =
result = newString(0)
setLen(result, x)
Or find all the unexpected cases.
Thanks for the useful library!
Is there any way to create animated PNGs?
import nimPNG
proc main()=
var rawData = readFile("pngData")
discard savePNG32("bad_png.png", rawData, 2000, 2000)
echo "DONE"
main()
Hello janko
first:
I like your repository and the simplicity of the api very much.
Questions:
Is it possible to implement a compiletime decoder as well? Are there any known hurdles or problems? Have you ever tried this?
possible new API could be:
const png = loadStaticPNG32("image.png")
savePNG
has some cases for openarray
, but it only works for seq
. This is what I was trying to do:
import nimPNG
var data: array[100, array[100, uint32]]
for x in 0..<50:
for y in 0..<50:
data[y][x] = 0xFF0000FF'u32
for x in 50..<100:
for y in 0..<50:
data[y][x] = 0x00FF00FF'u32
for x in 0..<50:
for y in 50..<100:
data[y][x] = 0x0000FFFF'u32
for x in 50..<100:
for y in 50..<100:
data[y][x] = 0x000000FF'u32
echo savePng("image.png", cast[array[data.len*data[0].len*4, uint8]](data), LCT_RGBA, 8, data.len, data[0].len)
But I get this error:
/tmp/png.nim(22, 13) template/generic instantiation of `savePNG` from here
/home/peter/.nimble/pkgs/nimPNG-#head/nimPNG.nim(3131, 18) template/generic instantiation of `savePNGImpl` from here
/home/peter/.nimble/pkgs/nimPNG-#head/nimPNG.nim(3002, 26) template/generic instantiation of `encodePNG` from here
/home/peter/.nimble/pkgs/nimPNG-#head/nimPNG.nim(2967, 21) template/generic instantiation of `encodePNG` from here
/home/peter/.nimble/pkgs/nimPNG-#head/nimPNG.nim(2954, 17) template/generic instantiation of `encoderCore` from here
/home/peter/.nimble/pkgs/nimPNG-#head/nimPNG.nim(2870, 54) template/generic instantiation of `newStorage` from here
/home/peter/.nimble/pkgs/nimPNG-#head/nimPNG.nim(282, 32) Error: type mismatch: got <array[0..39999, uint8]>
but expected one of:
template getUnderlyingType[T](_: seq[T]): untyped
first type mismatch at position: 1
required type for _: seq[T]
but expression 'T' is of type: array[0..39999, uint8]
expression: getUnderlyingType(T)
On the head branch, and this on the latest tagged version:
/tmp/png.nim(22, 13) template/generic instantiation of `savePNG` from here
/home/peter/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(3127, 18) template/generic instantiation of `savePNGImpl` from here
/home/peter/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(2998, 26) template/generic instantiation of `encodePNG` from here
/home/peter/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(2963, 21) template/generic instantiation of `encodePNG` from here
/home/peter/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(2950, 17) template/generic instantiation of `encoderCore` from here
/home/peter/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(2866, 54) template/generic instantiation of `newStorage` from here
/home/peter/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(280, 18) Error: type mismatch: got <seq[uint8]> but expected 'array[0..39999, uint8]'
The following code, which just loads and saves a PNG produces artifacts with image attached:
let png = loadPNG32(original_path)
discard savePNG32(output_path, png.data, png.width, png.height)
Original image: edit: removed
Output image: edit: removed
I'm new to Nim and trying out nimPNG. I'm using the following code:
import nimPNG
let width = 5
let height = 10
var grey = newString(width * height)
var i = 0
grey[i] = 120.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 85.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 120.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 60.char; i += 1
grey[i] = 42.char; i += 1
grey[i] = 60.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 85.char; i += 1
grey[i] = 42.char; i += 1
grey[i] = 0.char; i += 1
grey[i] = 38.char; i += 1
grey[i] = 76.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 57.char; i += 1
grey[i] = 19.char; i += 1
grey[i] = 19.char; i += 1
grey[i] = 57.char; i += 1
grey[i] = 114.char; i += 1
grey[i] = 76.char; i += 1
grey[i] = 38.char; i += 1
grey[i] = 0.char; i += 1
grey[i] = 38.char; i += 1
grey[i] = 133.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 57.char; i += 1
grey[i] = 19.char; i += 1
grey[i] = 19.char; i += 1
grey[i] = 152.char; i += 1
grey[i] = 114.char; i += 1
grey[i] = 76.char; i += 1
grey[i] = 38.char; i += 1
grey[i] = 0.char; i += 1
grey[i] = 171.char; i += 1
grey[i] = 133.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 60.char; i += 1
grey[i] = 42.char; i += 1
grey[i] = 190.char; i += 1
grey[i] = 153.char; i += 1
grey[i] = 120.char; i += 1
grey[i] = 95.char; i += 1
grey[i] = 85.char; i += 1
# These lines cause a "value out of range: -25" error
grey[i] = 212.char; i += 1
grey[i] = 180.char; i += 1
grey[i] = 153.char; i += 1
grey[i] = 134.char; i += 1
grey[i] = 127.char; i += 1
# These lines will work fine. (Values up to 10, in fact)
#grey[i] = 0.char; i += 1
#grey[i] = 0.char; i += 1
#grey[i] = 0.char; i += 1
#grey[i] = 0.char; i += 1
#grey[i] = 0.char; i += 1
if not savePNG("/tmp/out.png", grey, LCT_GREY, 8, width, height):
echo "Could not write to /tmp/out.png"
This code gives a "value out of range: -25" message printed out, and savePNG() returns false. The strange thing is that any values greater than 10, I think, for the bottom row will give some form of this error (the actual number complained about varies). I also tried LCT_RGB with the string 3 times as large, writing the value 3 times each time, and got exactly the same error. I also couldn't find the error string anywhere in the nimPNG code, so I'm not sure if this is a bug in nimPNG or Nim 1.0 or my code. I'd assume my code, but I can't figure out what would be wrong. Especially since the following code works:
for i in 0 ..< width * height:
grey[i] = 255.char
if not savePNG("/tmp/out.png", grey, LCT_GREY, 8, width, height):
echo "Could not write to /tmp/out.png"
When trying to parse large base64-string's I get the error:
Error: unhandled exception: cannot read from stream [IOError]
The base64-string origins from photos taken with iPhones, which then is converted to base64 in the browser. I can't reproduce exactly when this happens, so my guessing is, that it might be due to the details in the photo (?).
I have the base64-strings which works flawless with online converters and linux own base64 -d p.txt >> p.png
. I have also validated the base64-string, and it is valid base64.
Test code:
import base64, streams
import nimPNG
const b = """loooong base64"""
proc fromBase64(input: string): string =
result = base64.decode(input)
proc base64ToPng*(b64: string, path: string): bool =
let
s = newStringStream(fromBase64(b64))
decoded = s.decodePNG(LCT_RGBA, 8) # <== This one, line 12
result = (savePNG32(path, decoded.data, decoded.width, decoded.height))
echo base64ToPng(b, "debug.png")
GH does not like the long base64 string so here is a Gist with it: https://gist.github.com/ThomasTJdev/7a14a8b8309d67a7188c3cfe61eff869
The error message is:
/home/user/tmp/nim/image/base64debug.nim(22) base64debug
/home/user/tmp/nim/image/base64debug.nim(17) base64ToPng
/home/user/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(1917) decodePNG
/home/user/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(1842) decodePNG
/home/user/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(939) parsePNG
/home/user/.nimble/pkgs/nimPNG-0.3.1/nimPNG.nim(387) readInt32BE
/home/user/.choosenim/toolchains/nim-1.2.6/lib/pure/streams.nim(570) readInt32
/home/user/.choosenim/toolchains/nim-1.2.6/lib/pure/streams.nim(382) read
Error: unhandled exception: cannot read from stream [IOError]
For instance, if I try to run the code from #9 on the image posted there, I get an assertion failure.
import nimPNG
let data = loadPNG32("sample.png")
assert(not data.isNil)
djerzinski:nim andrea$ nim c -r example
...
example.nim(7) example
system.nim(3788) failedAssertImpl
system.nim(3781) raiseAssert
system.nim(2843) sysFatal
Error: unhandled exception: not isNil(data) [AssertionError]
But if I run the same code with -d:release
, everything seems to work fine :-?
The nimPNG repo includes a tests
folder which is quite large. Also, some of the links in the tests are very inappropriate. I don't want kids using my game engine (which depends on nimPNG) to see that π
If you install via Nimble, the test files don't get copied to the pkgs directory. However, they do remain if you are using Atlas or simply managing your own dependencies via git submodules.
Therefore I think it would be best to move the tests to another repo.
due to a type mismatch.
Here's the error message:
/home/daknus/Coding/Nim/aglet/tests/tcloud.nim(145, 29) template/generic instantiation of `savePNG32` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(3104, 20) template/generic instantiation of `savePNG32Impl` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2980, 16) template/generic instantiation of `savePNGImpl` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2971, 26) template/generic instantiation of `encodePNG` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2942, 21) template/generic instantiation of `encodePNG` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2929, 17) template/generic instantiation of `encoderCore` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2838, 8) template/generic instantiation of `autoChooseColor` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2518, 17) template/generic instantiation of `getColorProfile` from here
/home/daknus/.nimble/pkgs/nimPNG-0.3.0/nimPNG.nim(2503, 24) Error: type mismatch: got <seq[uint8], int, int, PNGColorMode, PNGColorProfile, Table[nimPNG.RGBA8, system.int]>
but expected one of:
proc calculateColorProfile(input: string; w, h: int; mode: PNGColorMode;
prof: PNGColorProfile; tree: var Table[RGBA8, int])
first type mismatch at position: 1
required type for input: string
but expression 'png.pixels' is of type: seq[uint8]
expression: calculateColorProfile(png.pixels, png.width, png.height, mode, prof, tree)
Hi. Since I haven't been able to find many easy PNG libraries out there, this has been already useful to me, but I have this question? How come I can't write 32 bit unsigned integers. Here is my sample code:
import nimPNG
var
# This works:
# data = @[
# 0xFF.uint8, 0xFF.uint8, 0xFF.uint8, 0x80.uint8, # 50% white
# 0xFF.uint8, 0x00.uint8, 0x00.uint8, 0xFF.uint8, # red
# 0x00.uint8, 0xFF.uint8, 0x00.uint8, 0xFF.uint8, # green
# 0x00.uint8, 0x00.uint8, 0xFF.uint8, 0xFF.uint8 # blue
# ]
# But this doesn't:
data = @[
0xFFFFFF80.uint32, # 50% white
0xFF0000FF.uint32, # red
0x00FF00FF.uint32, # green
0x0000FFFF.uint32 # blue
]
pixels: string = cast[string](data)
echo "saved: " & $savePNG32("test.png", pixels, 2, 2)
On the terminal, I'm also getting the message: "not enough input to encode". What's going on? the byte size of both things should be the same.
Hi and thanks for the great library. I just wanted to create an issue to track --gc:arc support.
--gc:arc info: https://forum.nim-lang.org/t/5734
To verify the issue, simply add --gc:arc to the compile cmds in the nimble file. For example exec "nim c --gc:arc -r test.nim"
in Nim 2.0, shallowCopy
will be removed. This means every occurrence of shallowCopy
in the library must be replaced by something else.
See: nim-lang/Nim#20017
For simple situations, sink
may be good enough:
e.g.
proc init*[T](b: var Buffer[T], d: T) =
shallowCopy(b.data, d)
b.offset = 0
becomes
proc init*[T](b: var Buffer[T], d: sink T) =
b.data = d
b.offset = 0
The compiler will then decide whether to move or copy the data depending on whether it can prove that buf.init(s)
is the last usage of s
or not.
However, there are some problems:
If the compiler decides to copy, then there will be a performance hit. To keep good performance in this case, I believe some sort of buffer-via-pointer is needed, e.g. trick's View or collections' View or Nim's experimental view types.
There are some uses of shallowCopy
in the codebase that don't neatly fit the sink
pattern, e.g.
shallowCopy(png.apngPixels[0], png.pixels)
frameConvert[T](png, modeIn, modeOut, png.width, png.height, 0, state)
shallowCopy(png.pixels, png.apngPixels[0])
(edit, maybe they can be solved like this?)
png.apngPixels[0] = move(png.pixels)
frameConvert[T](png, modeIn, modeOut, png.width, png.height, 0, state)
png.pixels = move(png.apngPixels[0])
Providing a good error message for the end user is important, especially in GUI applications. For a typical Windows app user, they're not going to look in the console, they'll expect a nice error message stating that the image could not be loaded.
The current way nimPNG handles exceptions is func
-friendly, but fundamentally wrong, because Nim's error handling mechanism inherently has side effects. Unless a Result[T, E]
is introduced to the stdlib, debugEcho
is only a way of mitigating the problem and does not solve anything except frustrate the library users because their stdout is trashed and they don't have an easy way of providing an error message to the end user.
Proposal: Raise IoError
s instead of echoing errors to stdout.
Nim 1.6.2:
C:\Users\User\AppData\Roaming\Sublime Text\Packages\Theme - One\test.nim(3, 21) template/generic instantiation of `loadPNG32` from here
C:\Users\User\.nimble\pkgs\nimPNG-0.3.2\nimPNG.nim(1888, 12) template/generic instantiation of `loadPNG` from here
C:\Users\User\.nimble\pkgs\nimPNG-0.3.2\nimPNG.nim(1882, 26) template/generic instantiation of `decodePNG` from here
C:\Users\User\.nimble\pkgs\nimPNG-0.3.2\nimPNG.nim(1846, 24) template/generic instantiation of `parsePNG` from here
C:\Users\User\.nimble\pkgs\nimPNG-0.3.2\nimPNG.nim(950, 19) template/generic instantiation of `parseChunk` from here
C:\Users\User\.nimble\pkgs\nimPNG-0.3.2\nimPNG.nim(892, 31) template/generic instantiation of `parseChunk` from here
C:\Users\User\.nimble\pkgs\nimPNG-0.3.2\nimPNG.nim(457, 26) Warning: conversion to enum with holes is unsafe: PNGColorType(typ`gensym14) [HoleEnumConv]
import nimPNG
let png = loadPNG("0.png", LCT_GREY, 8)
img_test.nim(3, 18) Error: type mismatch: got <string, PNGColorType, int literal(8)>
but expected one of:
proc loadPNG(fileName: string; colorType: PNGColorType; bitDepth: int;
settings: PNGDecoder): PNGResult
first type mismatch at position: 4
required type: PNGDecoder
expression: loadPNG("0.png", LCT_GREY, 8)
the underlying compression library nimz
actually have some configurable parameters but not exposed to user.
but it is good to let user fine tuning these parameters for special use case.
I am trying to use nimPNG with Nim 1.0.0 but I am having lots of issues while compiling (on MacOS).
Normally, I'd try to debug this myself, but I am at a loss here. Here is the output of tests on my Mac:
# nim c -r tester/test.nim
/Users/andrea/esperimenti/nimPNG/tester/test.nim(103) test
/Users/andrea/esperimenti/nimPNG/tester/test.nim(99) main
/Users/andrea/.mynim/devel/lib/system/assertions.nim(27) failedAssertImpl
/Users/andrea/.mynim/devel/lib/system/assertions.nim(20) raiseAssert
/Users/andrea/.mynim/devel/lib/system/fatal.nim(39) sysFatal
Error: unhandled exception: /Users/andrea/esperimenti/nimPNG/tester/test.nim(99, 9) `not data.isNil` [AssertionError]
# nim c -r tester/testCodec.nim
codec test 1 1
codec test 2 2
codec test 1 1
codec test 7 7
codec test 127 127
codec test 127 127
codec other pattern 1
/Users/andrea/esperimenti/nimPNG/tester/testCodec.nim(1197) testCodec
/Users/andrea/esperimenti/nimPNG/tester/testCodec.nim(1176) doMain
/Users/andrea/esperimenti/nimPNG/tester/testCodec.nim(240) testPNGCodec
/Users/andrea/esperimenti/nimPNG/tester/testCodec.nim(116) testOtherPattern1
/Users/andrea/esperimenti/nimPNG/tester/testCodec.nim(83) doCodecTest
/Users/andrea/esperimenti/nimPNG/tester/testCodec.nim(62) doCodecTest
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(3262) encodePNG
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(3249) encodePNG
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(3168) encoderCore
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(3135) frameConvert
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(2963) preProcessScanLines
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(2903) filter
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(2751) filterMinsum
/Users/andrea/esperimenti/nimPNG/nimPNG.nim(2685) filterScanLine
/Users/andrea/.mynim/devel/lib/system/fatal.nim(48) sysFatal
Error: unhandled exception: value out of range: -2 [RangeError]
# nim c -r tester/testSuite.nim
CC: stdlib_assertions.nim
CC: stdlib_dollars.nim
CC: stdlib_io.nim
CC: stdlib_system.nim
CC: stdlib_streams.nim
CC: stdlib_math.nim
CC: stdlib_strutils.nim
CC: stdlib_pathnorm.nim
CC: stdlib_posix.nim
CC: stdlib_times.nim
CC: stdlib_os.nim
CC: stdlib_tables.nim
CC: ../nimPNG/buffer.nim
CC: ../nimPNG/nimz.nim
CC: ../nimPNG.nim
CC: minibmp.nim
CC: testSuite.nim
Error: execution of an external compiler program 'clang -c -w -I/Users/andrea/.mynim/devel/lib -I/Users/andrea/esperimenti/nimPNG/tester -o /Users/andrea/.cache/nim/testSuite_d/@[email protected] /Users/andrea/.cache/nim/testSuite_d/@[email protected]' failed with exit code: 1
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8627:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_500)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.r) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8633:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_502)] = ((NIM_CHAR)chckRange((mode_t)(p.r & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8659:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_505)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.r) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8665:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_507)] = ((NIM_CHAR)chckRange((mode_t)(p.r & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8671:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_509)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.g) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8677:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_511)] = ((NIM_CHAR)chckRange((mode_t)(p.g & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8683:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_513)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.b) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8689:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_515)] = ((NIM_CHAR)chckRange((mode_t)(p.b & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8711:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_518)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.r) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8717:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_520)] = ((NIM_CHAR)chckRange((mode_t)(p.r & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8723:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_522)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.a) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8729:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_524)] = ((NIM_CHAR)chckRange((mode_t)(p.a & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8759:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_527)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.r) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8765:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_529)] = ((NIM_CHAR)chckRange((mode_t)(p.r & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8771:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_531)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.g) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8777:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_533)] = ((NIM_CHAR)chckRange((mode_t)(p.g & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8783:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_535)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.b) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8789:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_537)] = ((NIM_CHAR)chckRange((mode_t)(p.b & ((NI) 255)), 0, 255));
^
/Users/andrea/.cache/nim/testSuite_d/@[email protected]:8795:86: error: use of undeclared identifier 'mode_t'
(*output).data->data[(NI)(TM__CaabljTnIulNq49cYzoUYeQ_539)] = ((NIM_CHAR)chckRange((mode_t)((NU16)((NU16)(p.a) >> (NU64)(((NI) 8))) & ((NI) 255)), 0, 255));
^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
Would a PR to resize images be accepted here? Or is that beyond the scope of this module?
Edit: I should add that I have no idea how to do it. But I may be motivated enough to figure it out. :)
expect: LCT_RGBA
import os
import streams
import nimPNG
createDir("outputs")
# 2 * 2
let data: seq[uint8] = @[
uint8(255), 255, 255, 255,
0, 0, 0, 255, # <--- black
0, 0, 0, 255,
255, 255, 255, 255,
]
discard savePNG32("outputs/test.png", data, 2, 2)
let png = decodePNG(newStringStream(readFile("outputs/test.png")))
let pngInfo = getInfo(png)
echo pngInfo.mode.colorType
output: LCT_GREY
import os
import streams
import nimPNG
createDir("outputs")
# 2 * 2
let data: seq[uint8] = @[
uint8(255), 255, 255, 255,
255, 0, 0, 255, # <--- red
255, 0, 0, 255,
255, 255, 255, 255,
]
discard savePNG32("outputs/test.png", data, 2, 2)
let png = decodePNG(newStringStream(readFile("outputs/test.png")))
let pngInfo = getInfo(png)
echo pngInfo.mode.colorType
output: LCT_RGB
Hi, I want to remove all unnecessary data from a png image, I usualy open the image in gimp and export with all options disabled.
But now I need to do this for ~200 images, so I wanted to automate this, and I thought about this package.
How can I get the equivalent of gimp's exported png ?
Thank you π
I have profiled nimPNG code saving with VTune and 45% of the time is spent on this line:
Line 2358 in 676bca4
This line is in calculateColorProfile ... should it just be computed once? It seems like a very slow operation with the hashing taking up most of the time. Is there a way to compute calculateColorProfile only once?
I used vTune with nim c -d:release --debugger:native
to produce this.
Installing this library using nimble
and simply trying to import it from any file results in the following error message:
../.nimble/pkgs/nimPNG-0.2.3/nimPNG.nim(29, 15) Error: cannot open file: private/buffer
Tested with Nim 0.19.0 Windows and Linux, the former installed from the official installer and the latter installed from choosenim.
Currently nimPNG parser and decoder works in 'strict' mode. It will reject any invalid input. But there are some classes of invalid input that can be just ignored or skipped. This 'relaxed' decoding mode of course will probably produce incomplete image, but in certain situation this is acceptable or even desired.
In the future perhaps we can add more relaxation. Right now we can focus to implement invalid chunk skipper.
This relaxed mode and any other future relaxation should be accessible via decoder flags/settings/configuration and not forced to user. User should be able to select how much data or which recovery algorithm they wanted. And user should be able to stick with 'strict' parsing mode if there is no room for corrupted/incomplete input.
see also issue #55.
Due the changes in nim handling, I get the following error:
/Users/andrea/.nimble/pkgs/nimPNG-#head/nimPNG.nim(333, 18) template/generic instantiation from here
lib/system.nim(408, 10) Error: type mismatch: got <seq[RGBA8], nil>
but expected one of:
proc `==`[Enum: enum](x, y: Enum): bool
first type mismatch at position: 1
required type: Enum: enum
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: pointer): bool
first type mismatch at position: 1
required type: pointer
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: string): bool
first type mismatch at position: 1
required type: string
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: char): bool
first type mismatch at position: 1
required type: char
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: bool): bool
first type mismatch at position: 1
required type: bool
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T](x, y: set[T]): bool
first type mismatch at position: 1
required type: set[T]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T](x, y: ref T): bool
first type mismatch at position: 1
required type: ref T
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T](x, y: ptr T): bool
first type mismatch at position: 1
required type: ptr T
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T: proc](x, y: T): bool
first type mismatch at position: 1
required type: T: proc
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(a, b: PNGChunkType): bool
first type mismatch at position: 1
required type: PNGChunkType
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x: type(nil); y: string): bool
first type mismatch at position: 1
required type: nil
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x: string; y: type(nil)): bool
first type mismatch at position: 1
required type: string
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: int8): bool
first type mismatch at position: 1
required type: int8
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: int): bool
first type mismatch at position: 1
required type: int
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: int16): bool
first type mismatch at position: 1
required type: int16
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: int32): bool
first type mismatch at position: 1
required type: int32
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[I, T](x, y: array[I, T]): bool
first type mismatch at position: 1
required type: array[I, T]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T](x, y: seq[T]): bool
first type mismatch at position: 2
required type: seq[T]
but expression 'nil' is of type: nil
proc `==`(x, y: cstring): bool
first type mismatch at position: 1
required type: cstring
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: float): bool
first type mismatch at position: 1
required type: float
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: int64): bool
first type mismatch at position: 1
required type: int64
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T: SomeUnsignedInt](x, y: T): bool
first type mismatch at position: 1
required type: T: SomeUnsignedInt
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[T: tuple |
object](x, y: T): bool
first type mismatch at position: 1
required type: T: tuple or object
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`(x, y: float32): bool
first type mismatch at position: 1
required type: float32
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[A, B](s, t: OrderedTableRef[A, B]): bool
first type mismatch at position: 1
required type: OrderedTableRef[==.A, ==.B]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[A, B](s, t: Table[A, B]): bool
first type mismatch at position: 1
required type: Table[==.A, ==.B]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[A, B](s, t: OrderedTable[A, B]): bool
first type mismatch at position: 1
required type: OrderedTable[==.A, ==.B]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[A, B](s, t: TableRef[A, B]): bool
first type mismatch at position: 1
required type: TableRef[==.A, ==.B]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[A](s, t: CountTableRef[A]): bool
first type mismatch at position: 1
required type: CountTableRef[==.A]
but expression 'src.palette' is of type: seq[RGBA8]
proc `==`[A](s, t: CountTable[A]): bool
first type mismatch at position: 1
required type: CountTable[==.A]
but expression 'src.palette' is of type: seq[RGBA8]
expression: src.palette == nil
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.