Coder Social home page Coder Social logo

nimpng's Issues

Doesn't work by default on Nim v2.0.0

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 1.6.0 savePNG results in too nested template instantiation

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

Allow parsing into different data types

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.

nimPNG relies on bugs of `newString` to work

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.

compiletime decoder

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 doesn't work for arrays

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]'

Png is loaded incorrectly

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

"value out of range" error when writing PNG

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"

Error: unhandled exception: cannot read from stream [IOError]

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]

nimPNG always fails unless in release mode

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 :-?

Move tests to another repo

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 πŸ™ˆ

image

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.

New API – can't savePNG32 with a seq[uint8]

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)

Can't write 32 bit unsigned ints

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.

Doesn't compile on Nim devel due to `shallowCopy` being removed from the language.

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:

  1. 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.

  2. 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])

Throw exceptions on errors instead of writing to stdout

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 IoErrors instead of echoing errors to stdout.

Warning: conversion to enum with holes is unsafe: PNGColorType(typ`gensym14) [HoleEnumConv]

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]

wrong readme. how to use loadPNG?

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)

Compatibility with Nim 1.0.0

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=]

Resize image?

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. :)

`decodePNG` colorType unexpected

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

How to remove all unnecessary data

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 ?
image
Thank you πŸ™‚

This hash look up in calculateColorProfile is the slowest part of saving an image.

I have profiled nimPNG code saving with VTune and 45% of the time is spent on this line:

nimPNG/nimPNG.nim

Line 2358 in 676bca4

if not tree.hasKey(p):

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?

image

image

I used vTune with nim c -d:release --debugger:native to produce this.

Does not work with Nim 0.19.0 when installed from nimble

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.

Improve chunk parser flexibility when decoding incomplete input data.

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.

Cannot compile on Nim devel

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.