fix high-depth handling and add a test case
This commit is contained in:
parent
71016b868e
commit
be26fe5193
4 changed files with 35 additions and 11 deletions
|
@ -61,30 +61,41 @@ proc decodeP6Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} =
|
||||||
# Let's calculate the real maximum value multiplier.
|
# Let's calculate the real maximum value multiplier.
|
||||||
# rgbx() accepts a maximum value of 0xFF. Most of the time,
|
# rgbx() accepts a maximum value of 0xFF. Most of the time,
|
||||||
# maxVal is set to 0xFF as well, so in most cases it is 1
|
# maxVal is set to 0xFF as well, so in most cases it is 1
|
||||||
let valueMultiplier = (0xFF div maxVal).uint8
|
let valueMultiplier = 0xFF / maxVal
|
||||||
|
|
||||||
# if comparison in for loops is expensive, so let's unroll it
|
# if comparison in for loops is expensive, so let's unroll it
|
||||||
if not needsUint16:
|
if not needsUint16:
|
||||||
for i in 0 ..< result.len:
|
for i in 0 ..< result.len:
|
||||||
let
|
let
|
||||||
red = readUint8(data, i + (i * 2)) * valueMultiplier
|
red = (readUint8(data, i + (i * 2)).float * valueMultiplier + 0.5).uint8
|
||||||
green = readUint8(data, i + 1 + (i * 2)) * valueMultiplier
|
green = (readUint8(data, i + 1 + (i * 2)).float * valueMultiplier + 0.5).uint8
|
||||||
blue = readUint8(data, i + 2 + (i * 2)) * valueMultiplier
|
blue = (readUint8(data, i + 2 + (i * 2)).float * valueMultiplier + 0.5).uint8
|
||||||
result[i] = rgbx(red, green, blue, 0xFF)
|
result[i] = rgbx(red, green, blue, 0xFF)
|
||||||
else:
|
else:
|
||||||
for i in 0 ..< result.len:
|
for i in 0 ..< result.len:
|
||||||
let
|
let
|
||||||
red = readUint16(data, i + (i * 4)).uint8 * valueMultiplier
|
red = (readUint16(data, i + (i * 5)).swap.float * valueMultiplier + 0.5).uint8
|
||||||
green = readUint16(data, i + 2 + (i * 4)).uint8 * valueMultiplier
|
green = (readUint16(data, i + 2 + (i * 5)).swap.float * valueMultiplier + 0.5).uint8
|
||||||
blue = readUint16(data, i + 4 + (i * 4)).uint8 * valueMultiplier
|
blue = (readUint16(data, i + 4 + (i * 5)).swap.float * valueMultiplier + 0.5).uint8
|
||||||
result[i] = rgbx(red, green, blue, 0xFF)
|
result[i] = rgbx(red, green, blue, 0xFF)
|
||||||
|
|
||||||
proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [PixieError].} =
|
proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [PixieError].} =
|
||||||
var p6data = newStringOfCap(data.splitWhitespace.len)
|
let needsUint16 = maxVal > 0xFF
|
||||||
|
let maxLen = (
|
||||||
|
if needsUint16: data.splitWhitespace.len * 2
|
||||||
|
else: data.splitWhitespace.len
|
||||||
|
)
|
||||||
|
var p6data = newStringOfCap(maxLen)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for line in data.splitLines():
|
if not needsUint16:
|
||||||
for sample in line.split('#', 1)[0].splitWhitespace():
|
for line in data.splitLines():
|
||||||
p6data.add(parseInt(sample).chr)
|
for sample in line.split('#', 1)[0].splitWhitespace():
|
||||||
|
p6data.add(parseInt(sample).chr)
|
||||||
|
else:
|
||||||
|
for line in data.splitLines():
|
||||||
|
for sample in line.split('#', 1)[0].splitWhitespace():
|
||||||
|
p6data.addUint16(parseInt(sample).uint16.swap)
|
||||||
except ValueError: failInvalid()
|
except ValueError: failInvalid()
|
||||||
|
|
||||||
result = decodeP6Data(p6data, maxVal)
|
result = decodeP6Data(p6data, maxVal)
|
||||||
|
|
8
tests/fileformats/ppm/feep.p3.hidepth.master.ppm
Normal file
8
tests/fileformats/ppm/feep.p3.hidepth.master.ppm
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
P3
|
||||||
|
# feep.p3.hidepth.master.ppm
|
||||||
|
4 4
|
||||||
|
7919 # prime number chosen for test purposes
|
||||||
|
0 0 0 0 0 0 0 0 0 7919 0 7919
|
||||||
|
0 0 0 0 7919 3695 0 0 0 0 0 0
|
||||||
|
0 0 0 0 0 0 0 7919 3695 0 0 0
|
||||||
|
7919 0 7919 0 0 0 0 0 0 0 0 0
|
BIN
tests/fileformats/ppm/feep.p3.hidepth.ppm
Normal file
BIN
tests/fileformats/ppm/feep.p3.hidepth.ppm
Normal file
Binary file not shown.
|
@ -6,3 +6,8 @@ block:
|
||||||
"tests/fileformats/ppm/feep." & $format & ".master.ppm"
|
"tests/fileformats/ppm/feep." & $format & ".master.ppm"
|
||||||
))
|
))
|
||||||
writeFile("tests/fileformats/ppm/feep." & $format & ".ppm", encodePpm(image))
|
writeFile("tests/fileformats/ppm/feep." & $format & ".ppm", encodePpm(image))
|
||||||
|
|
||||||
|
let image = decodePpm(readFile(
|
||||||
|
"tests/fileformats/ppm/feep.p3.hidepth.master.ppm"
|
||||||
|
))
|
||||||
|
writeFile("tests/fileformats/ppm/feep.p3.hidepth.ppm", encodePpm(image))
|
||||||
|
|
Loading…
Reference in a new issue