mirror of
https://github.com/status-im/nimPNG.git
synced 2025-01-27 12:54:52 +00:00
fixed 64bit compilation error
This commit is contained in:
parent
a45c550e1c
commit
6f3e270cdc
44
nimPNG.nim
44
nimPNG.nim
@ -760,8 +760,8 @@ proc parsePNG(s: Stream, settings: PNGDecoder): PNG =
|
||||
let data = s.readStr(length)
|
||||
let crc = cast[uint32](s.readInt32BE())
|
||||
let calculatedCRC = crc32(crc32(0, $chunkType), data)
|
||||
#if calculatedCRC != crc and not PNGDecoder(png.settings).ignoreCRC:
|
||||
#raise PNGError("wrong crc for: " & $chunkType)
|
||||
if calculatedCRC != crc and not PNGDecoder(png.settings).ignoreCRC:
|
||||
raise PNGError("wrong crc for: " & $chunkType)
|
||||
var chunk = png.createChunk(chunkType, data, crc)
|
||||
|
||||
if chunkType != IDAT and chunk != nil:
|
||||
@ -1224,11 +1224,12 @@ proc RGBAFromGrey124(output: var cstring, input: cstring, numPixels: int, mode:
|
||||
var highest = ((1 shl mode.bitDepth) - 1) #highest possible value for this bit depth
|
||||
var obp = 0
|
||||
for i in 0..numPixels-1:
|
||||
let val = chr((readBitsFromReversedStream(obp, input, mode.bitDepth) * 255) div highest)
|
||||
let val = readBitsFromReversedStream(obp, input, mode.bitDepth)
|
||||
let value = chr((val * 255) div highest)
|
||||
let x = i * 4
|
||||
output[x] = val
|
||||
output[x+1] = val
|
||||
output[x+2] = val
|
||||
output[x] = value
|
||||
output[x+1] = value
|
||||
output[x+2] = value
|
||||
if mode.keyDefined and (ord(val) == mode.keyR): output[x+3] = chr(0)
|
||||
else: output[x+3] = chr(255)
|
||||
|
||||
@ -1361,10 +1362,11 @@ proc RGBA8FromGrey16(p: var RGBA8, input: cstring, px: int, mode: PNGColorMode)
|
||||
proc RGBA8FromGrey124(p: var RGBA8, input: cstring, px: int, mode: PNGColorMode) =
|
||||
let highest = ((1 shl mode.bitDepth) - 1) #highest possible value for this bit depth
|
||||
var obp = px * mode.bitDepth
|
||||
let val = chr((readBitsFromReversedStream(obp, input, mode.bitDepth) * 255) div highest)
|
||||
p.r = val
|
||||
p.g = val
|
||||
p.b = val
|
||||
let val = readBitsFromReversedStream(obp, input, mode.bitDepth)
|
||||
let value = chr((val * 255) div highest)
|
||||
p.r = value
|
||||
p.g = value
|
||||
p.b = value
|
||||
if mode.keyDefined and (ord(val) == mode.keyR): p.a = chr(0)
|
||||
else: p.a = chr(255)
|
||||
|
||||
@ -2829,10 +2831,12 @@ proc PNGEncode*(input: string, w, h: int, settings = PNGEncoder(nil)): PNG =
|
||||
(modeOut.paletteSize == 0 or modeOut.paletteSize > 256):
|
||||
raise PNGError("invalid palette size, it is only allowed to be 1-256")
|
||||
|
||||
let inputSize = getRawSize(w, h, modeIn)
|
||||
if input.len < inputSize:
|
||||
raise PNGError("not enough input to encode")
|
||||
|
||||
if state.autoConvert:
|
||||
autoChooseColor(modeOut, input, w, h, modeIn)
|
||||
#modeOut.show
|
||||
#modeIn.show
|
||||
|
||||
if state.interlaceMethod notin {IM_NONE, IM_INTERLACED}:
|
||||
raise PNGError("unexisting interlace mode")
|
||||
@ -2910,6 +2914,12 @@ proc PNGEncode*(input: string, colorType: PNGcolorType, bitDepth, w, h: int, set
|
||||
state.modeIn.bitDepth = bitDepth
|
||||
result = PNGEncode(input, w, h, state)
|
||||
|
||||
proc PNGEncode32*(input: string, w, h: int): PNG =
|
||||
result = PNGEncode(input, LCT_RGBA, 8, w, h)
|
||||
|
||||
proc PNGEncode24*(input: string, w, h: int): PNG =
|
||||
result = PNGEncode(input, LCT_RGB, 8, w, h)
|
||||
|
||||
proc writeChunks*(png: PNG, s: Stream) =
|
||||
s.write PNGSignature
|
||||
|
||||
@ -2924,6 +2934,16 @@ proc writeChunks*(png: PNG, s: Stream) =
|
||||
s.write chunk.data
|
||||
s.writeInt32BE cast[int](chunk.crc)
|
||||
|
||||
proc savePNG32*(fileName, input: string, w, h: int) =
|
||||
var png = PNGEncode(input, LCT_RGBA, 8, w, h)
|
||||
var s = newFileStream(fileName, fmWrite)
|
||||
png.writeChunks s
|
||||
|
||||
proc savePNG24*(fileName, input: string, w, h: int) =
|
||||
var png = PNGEncode(input, LCT_RGB, 8, w, h)
|
||||
var s = newFileStream(fileName, fmWrite)
|
||||
png.writeChunks s
|
||||
|
||||
proc getFilterTypesInterlaced(png: PNG): seq[string] =
|
||||
var header = PNGHeader(png.getChunk(IHDR))
|
||||
var idat = PNGData(png.getChunk(IDAT))
|
||||
|
@ -1,6 +1,6 @@
|
||||
#nimPNG
|
||||
Portable Network Graphics Encoder and Decoder written in Nim
|
||||
store lossless image with godd compression
|
||||
store lossless image with good compression
|
||||
|
||||
all PNG standard color mode are supported:
|
||||
|
||||
@ -41,4 +41,7 @@ Supported color conversions:
|
||||
- any grey or grey+alpha, to grey or grey+alpha
|
||||
- anything to a palette, as long as the palette has the requested colors in it
|
||||
- removing alpha channel
|
||||
- higher to smaller bitdepth, and vice versa
|
||||
- higher to smaller bitdepth, and vice versa
|
||||
|
||||
###Feature planned:
|
||||
- streaming for progressive loading
|
||||
|
109
testCodec.nim
109
testCodec.nim
@ -1,4 +1,4 @@
|
||||
import nimPNG, streams, math, unsigned, strutils, tables
|
||||
import nimPNG, streams, math, unsigned, strutils, tables, base64
|
||||
|
||||
type
|
||||
Image = ref object
|
||||
@ -7,25 +7,8 @@ type
|
||||
colorType: PNGcolorType
|
||||
bitDepth: int
|
||||
|
||||
proc fromBase64(v: int): int =
|
||||
if(v >= ord('A')) and (v <= ord('Z')): return (v - ord('A'))
|
||||
if(v >= ord('a')) and (v <= ord('z')): return (v - ord('a') + 26)
|
||||
if(v >= ord('0')) and (v <= ord('9')): return (v - ord('0') + 52)
|
||||
if v == ord('+'): return 62
|
||||
if v == ord('/'): return 63
|
||||
result = 0 #v == '='
|
||||
|
||||
proc fromBase64(input: string): string =
|
||||
var i = 0
|
||||
result = ""
|
||||
while (i + 3) < input.len:
|
||||
let v = 262144 * fromBase64(input[i].int) +
|
||||
4096 * fromBase64(input[i + 1].int) +
|
||||
64 * fromBase64(input[i + 2].int) + fromBase64(input[i + 3].int)
|
||||
result.add chr((v shr 16) and 0xff)
|
||||
if input[i + 3] != '=': result.add chr((v shr 8) and 0xff)
|
||||
if input[i + 2] != '=': result.add chr((v shr 0) and 0xff)
|
||||
inc(i, 4)
|
||||
result = base64.decode(input)
|
||||
|
||||
proc assertEquals[T, U](expected: T, actual: U, message = "") =
|
||||
if expected != actual.T:
|
||||
@ -33,11 +16,6 @@ proc assertEquals[T, U](expected: T, actual: U, message = "") =
|
||||
"Message: ", message
|
||||
quit()
|
||||
|
||||
proc assertTrue(value: bool, message = "") =
|
||||
if not value:
|
||||
echo "Error: expected true. Message: ", message
|
||||
quit()
|
||||
|
||||
proc getNumColorChannels(colorType: PNGcolorType): int =
|
||||
case colorType
|
||||
of LCT_GREY: result = 1
|
||||
@ -223,10 +201,10 @@ proc testColor(r, g, b, a: int) =
|
||||
doCodecTest(image3)
|
||||
|
||||
#a 256th color
|
||||
image.data[255 * 4 + 0] = 255.chr
|
||||
image.data[255 * 4 + 1] = 255.chr
|
||||
image.data[255 * 4 + 2] = 255.chr
|
||||
image.data[255 * 4 + 3] = 255.chr
|
||||
image3.data[255 * 4 + 0] = 255.chr
|
||||
image3.data[255 * 4 + 1] = 255.chr
|
||||
image3.data[255 * 4 + 2] = 255.chr
|
||||
image3.data[255 * 4 + 3] = 255.chr
|
||||
|
||||
doCodecTest(image3)
|
||||
|
||||
@ -334,6 +312,7 @@ proc doPngSuiteEqualTest(b64a, b64b: string) =
|
||||
|
||||
proc testPngSuiteTiny() =
|
||||
echo "testPngSuiteTiny"
|
||||
|
||||
doPngSuiteTinyTest("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAFS3GZcAAAABGdBTUEAAYagMeiWXwAAAANzQklU" &
|
||||
"BAQEd/i1owAAAANQTFRFAAD/injSVwAAAApJREFUeJxjYAAAAAIAAUivpHEAAAAASUVORK5CYII=",
|
||||
1, 1, 0, 0, 255, 255) #s01n3p01.png
|
||||
@ -883,7 +862,7 @@ proc testAutoColorModel(colors: string, inbitDepth: int, colorType: PNGcolorType
|
||||
s.setPosition 0
|
||||
var raw = s.PNGDecode()
|
||||
var info = raw.getInfo()
|
||||
var decoded = png.convert(colorType, inbitDepth)
|
||||
var decoded = raw.convert(LCT_RGBA, inbitdepth)
|
||||
|
||||
assert num == info.width
|
||||
assert 1 == info.height
|
||||
@ -891,15 +870,20 @@ proc testAutoColorModel(colors: string, inbitDepth: int, colorType: PNGcolorType
|
||||
assert bitDepth == info.mode.bitDepth
|
||||
assert key == info.mode.keyDefined
|
||||
|
||||
if inbitDepth == 8:
|
||||
colors.toHex
|
||||
colors2.toHex
|
||||
for i in 0..colors.high:
|
||||
assert colors[i] == decoded.data[i]
|
||||
else :
|
||||
let len = colors.len div 2
|
||||
for i in 0.. <len:
|
||||
assert colors[i * 2] == decoded.data[i]
|
||||
#if inbitDepth == 8:
|
||||
for i in 0..colors.high:
|
||||
if colors[i] != decoded.data[i]:
|
||||
colors.toHex
|
||||
echo "ONE"
|
||||
decoded.data.substr(0, colors.len * 2).toHex
|
||||
assert colors[i] == decoded.data[i]
|
||||
#else :
|
||||
#
|
||||
|
||||
#
|
||||
# let len = colors.len div 2
|
||||
# for i in 0.. <len:
|
||||
# assert colors[i * 2] == decoded.data[i]
|
||||
|
||||
proc addColor(colors: var string, r, g, b, a: int) =
|
||||
colors.add r.chr
|
||||
@ -921,23 +905,23 @@ proc testAutoColorModels() =
|
||||
var grey1 = ""
|
||||
for i in 0..1: addColor(grey1, i * 255, i * 255, i * 255, 255)
|
||||
testAutoColorModel(grey1, 8, LCT_GREY, 1, false)
|
||||
|
||||
|
||||
var grey2 = ""
|
||||
for i in 0..3: addColor(grey2, i * 85, i * 85, i * 85, 255)
|
||||
testAutoColorModel(grey2, 8, LCT_GREY, 2, false)
|
||||
|
||||
|
||||
var grey4 = ""
|
||||
for i in 0..15: addColor(grey4, i * 17, i * 17, i * 17, 255)
|
||||
testAutoColorModel(grey4, 8, LCT_GREY, 4, false)
|
||||
|
||||
|
||||
var grey8 = ""
|
||||
for i in 0..255: addColor(grey8, i, i, i, 255)
|
||||
testAutoColorModel(grey8, 8, LCT_GREY, 8, false)
|
||||
|
||||
|
||||
var grey16 = ""
|
||||
for i in 0..256: addColor16(grey16, i, i, i, 65535)
|
||||
testAutoColorModel(grey16, 16, LCT_GREY, 16, false)
|
||||
|
||||
|
||||
var palette = ""
|
||||
addColor(palette, 0, 0, 1, 255)
|
||||
testAutoColorModel(palette, 8, LCT_PALETTE, 1, false)
|
||||
@ -953,23 +937,23 @@ proc testAutoColorModels() =
|
||||
testAutoColorModel(palette, 8, LCT_PALETTE, 8, false)
|
||||
addColor(palette, 0, 0, 18, 1) #translucent
|
||||
testAutoColorModel(palette, 8, LCT_PALETTE, 8, false)
|
||||
|
||||
|
||||
var rgb = grey8
|
||||
addColor(rgb, 255, 0, 0, 255)
|
||||
testAutoColorModel(rgb, 8, LCT_RGB, 8, false)
|
||||
|
||||
|
||||
var rgb_key = rgb
|
||||
addColor(rgb_key, 128, 0, 0, 0)
|
||||
testAutoColorModel(rgb_key, 8, LCT_RGB, 8, true)
|
||||
|
||||
|
||||
var rgb_key2 = rgb_key
|
||||
addColor(rgb_key2, 128, 0, 0, 255) #same color but opaque ==> no more key
|
||||
testAutoColorModel(rgb_key2, 8, LCT_RGBA, 8, false)
|
||||
|
||||
|
||||
var rgb_key3 = rgb_key
|
||||
addColor(rgb_key3, 128, 0, 0, 255) #semi-translucent ==> no more key
|
||||
testAutoColorModel(rgb_key3, 8, LCT_RGBA, 8, false)
|
||||
|
||||
|
||||
var rgb_key4 = rgb_key
|
||||
addColor(rgb_key4, 128, 0, 0, 255)
|
||||
addColor(rgb_key4, 129, 0, 0, 255) #two different transparent colors ==> no more key
|
||||
@ -1008,19 +992,18 @@ proc testAutoColorModels() =
|
||||
testAutoColorModel(alpha16, 16, LCT_RGBA, 16, false)
|
||||
|
||||
proc doMain() =
|
||||
#testPNGCodec()
|
||||
#testPngSuiteTiny()
|
||||
#testPaletteFilterTypesZero()
|
||||
#testComplexPNG()
|
||||
#testPredefinedFilters()
|
||||
#testColorKeyConvert()
|
||||
#testColorConvert()
|
||||
#testColorConvert2()
|
||||
#testPaletteToPaletteConvert()
|
||||
#testRGBToPaletteConvert()
|
||||
#test16bitColorEndianness();
|
||||
#testNoAutoConvert();
|
||||
testPNGCodec()
|
||||
testPngSuiteTiny()
|
||||
testPaletteFilterTypesZero()
|
||||
testComplexPNG()
|
||||
testPredefinedFilters()
|
||||
testColorKeyConvert()
|
||||
testColorConvert()
|
||||
testColorConvert2()
|
||||
testPaletteToPaletteConvert()
|
||||
testRGBToPaletteConvert()
|
||||
test16bitColorEndianness();
|
||||
testNoAutoConvert();
|
||||
testAutoColorModels();
|
||||
|
||||
echo getTotalMem()
|
||||
doMain()
|
||||
|
||||
doMain()
|
||||
|
@ -6,11 +6,12 @@ type
|
||||
data: string
|
||||
|
||||
proc writeWORD(s: Stream, val: int) =
|
||||
let word = int16(val)
|
||||
let word = val.int16
|
||||
s.write(word)
|
||||
|
||||
proc writeDWORD(s: Stream, val: int) =
|
||||
s.write(val)
|
||||
let dword = val.int32
|
||||
s.write(dword)
|
||||
|
||||
proc newBMP(w, h: int): BMP =
|
||||
new(result)
|
||||
@ -49,7 +50,7 @@ proc write(s: Stream, bmp: BMP) =
|
||||
if paddingLen > 0: s.write(padding)
|
||||
|
||||
proc loadPNG(fileName: string): BMP =
|
||||
var settings = makeDefaultPNGDecoderSettings()
|
||||
var settings = makePNGDecoder()
|
||||
settings.readTextChunks = true
|
||||
var png = loadPNG24(fileName, settings)
|
||||
if png == nil: return nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user