From 76797125750f4d989f11dffa06482f6b145bf8da Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Thu, 6 Jan 2022 12:23:32 +0200 Subject: [PATCH 1/9] add PPM encoder --- src/pixie.nim | 10 ++++++++-- src/pixie/fileformats/ppm.nim | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/pixie/fileformats/ppm.nim diff --git a/src/pixie.nim b/src/pixie.nim index 6af2bc6..a3c0733 100644 --- a/src/pixie.nim +++ b/src/pixie.nim @@ -1,13 +1,13 @@ import bumpy, chroma, flatty/binny, os, pixie/common, pixie/contexts, pixie/fileformats/bmp, pixie/fileformats/gif, pixie/fileformats/jpg, - pixie/fileformats/png, pixie/fileformats/qoi, pixie/fileformats/svg, + pixie/fileformats/png, pixie/fileformats/ppm, pixie/fileformats/qoi, pixie/fileformats/svg, pixie/fonts, pixie/images, pixie/masks, pixie/paints, pixie/paths, strutils, vmath export bumpy, chroma, common, contexts, fonts, images, masks, paints, paths, vmath type FileFormat* = enum - ffPng, ffBmp, ffJpg, ffGif, ffQoi + ffPng, ffBmp, ffJpg, ffGif, ffQoi, ffPpm converter autoStraightAlpha*(c: ColorRGBX): ColorRGBA {.inline, raises: [].} = ## Convert a premultiplied alpha RGBA to a straight alpha RGBA. @@ -32,6 +32,8 @@ proc decodeImage*(data: string | seq[uint8]): Image {.raises: [PixieError].} = decodeGif(data) elif data.len > (14+8) and data.readStr(0, 4) == qoiSignature: decodeQoi(data) + elif data.len > 9 and data.readStr(0, 2) in ppmSignatures: + decodePpm(data) else: raise newException(PixieError, "Unsupported image file format") @@ -69,6 +71,8 @@ proc encodeImage*(image: Image, fileFormat: FileFormat): string {.raises: [Pixie image.encodeQoi() of ffGif: raise newException(PixieError, "Unsupported file format") + of ffPpm: + image.encodePpm() proc encodeMask*(mask: Mask, fileFormat: FileFormat): string {.raises: [PixieError].} = ## Encodes a mask into memory. @@ -85,6 +89,7 @@ proc writeFile*(image: Image, filePath: string) {.raises: [PixieError].} = of ".bmp": ffBmp of ".jpg", ".jpeg": ffJpg of ".qoi": ffQoi + of ".ppm": ffPpm else: raise newException(PixieError, "Unsupported file extension") @@ -100,6 +105,7 @@ proc writeFile*(mask: Mask, filePath: string) {.raises: [PixieError].} = of ".bmp": ffBmp of ".jpg", ".jpeg": ffJpg of ".qoi": ffQoi + of ".ppm": ffPpm else: raise newException(PixieError, "Unsupported file extension") diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim new file mode 100644 index 0000000..0dda673 --- /dev/null +++ b/src/pixie/fileformats/ppm.nim @@ -0,0 +1,35 @@ +import chroma, flatty/binny, pixie/common, pixie/images + +# See: http://netpbm.sourceforge.net/doc/ppm.html + +const ppmSignatures* = @["P3", "P6"] + +proc decodePpm*(data: string): Image {.raises: [PixieError].} = + ## Decodes Portable Pixel Map data into an Image. + result = newImage(0, 0) + +proc decodePpm*(data: seq[uint8]): Image {.inline, raises: [PixieError].} = + ## Decodes Portable Pixel Map data into an Image. + decodePpm(cast[string](data)) + +proc encodePpm*(image: Image): string {.raises: [].} = + ## Encodes an image into the PPM file format (version P6). + + # PPM header + result.add("P6") # The header field used to identify the PPM + result.add("\n") # Newline + result.add($image.width) + result.add(" ") # Space + result.add($image.height) + result.add("\n") # Newline + result.add("255") # Max color value + result.add("\n") # Newline + + # PPM image data + for y in 0 ..< image.height: + for x in 0 ..< image.width: + let rgb = image[x, y].rgba() + # alpha channel is ignored + result.addUint8(rgb.r) + result.addUint8(rgb.g) + result.addUint8(rgb.b) From 0139af545fe7f1b2fb4dd263ff2b70abd3fd2930 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Fri, 7 Jan 2022 12:29:23 +0200 Subject: [PATCH 2/9] add rudimentary PPM decoder --- src/pixie.nim | 5 +- src/pixie/fileformats/ppm.nim | 91 ++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 4 deletions(-) diff --git a/src/pixie.nim b/src/pixie.nim index a3c0733..28e4094 100644 --- a/src/pixie.nim +++ b/src/pixie.nim @@ -1,7 +1,8 @@ import bumpy, chroma, flatty/binny, os, pixie/common, pixie/contexts, pixie/fileformats/bmp, pixie/fileformats/gif, pixie/fileformats/jpg, - pixie/fileformats/png, pixie/fileformats/ppm, pixie/fileformats/qoi, pixie/fileformats/svg, - pixie/fonts, pixie/images, pixie/masks, pixie/paints, pixie/paths, strutils, vmath + pixie/fileformats/png, pixie/fileformats/ppm, pixie/fileformats/qoi, + pixie/fileformats/svg, pixie/fonts, pixie/images, pixie/masks, pixie/paints, + pixie/paths, strutils, vmath export bumpy, chroma, common, contexts, fonts, images, masks, paints, paths, vmath diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim index 0dda673..8861812 100644 --- a/src/pixie/fileformats/ppm.nim +++ b/src/pixie/fileformats/ppm.nim @@ -1,12 +1,99 @@ -import chroma, flatty/binny, pixie/common, pixie/images +import chroma, flatty/binny, pixie/common, pixie/images, std/strutils # See: http://netpbm.sourceforge.net/doc/ppm.html const ppmSignatures* = @["P3", "P6"] +type + PpmHeader = object + version: string + width, height, maxVal, dataOffset: int + +template failInvalid() = + raise newException(PixieError, "Invalid PPM data") + +proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = + if data.len <= 10: # Each part + whitespace + raise newException(PixieError, "Invalid PPM file header") + + var commentMode: bool + var i, readFields: int + var field: string + while readFields < 4: + let c = readUint8(data, i).char + if c == '#': + commentMode = true + elif c == '\n': + commentMode = false + if not commentMode: + if c in Whitespace: + readFields += 1 + try: + case readFields: + of 1: + result.version = field + of 2: + result.width = parseInt(field) + of 3: + result.height = parseInt(field) + of 4: + result.maxVal = parseInt(field) + else: + discard + except ValueError: failInvalid() + field = "" + else: + field.add(c) + i += 1 + + result.dataOffset = i + +proc decodeP6Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} = + let needsUint16 = maxVal > 0xFF + + result = newSeq[ColorRGBX](( + if needsUint16: data.len / 6 + else: data.len / 3 + ).int) + + # Let's calculate the real maximum value multiplier. + # 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 + let valueMultiplier = (0xFF / maxVal).uint8 + + # if comparison in for loops is expensive, so let's unroll it + if not needsUint16: + for i in 0 ..< result.len: + let + red = readUint8(data, i + (i * 2)) * valueMultiplier + green = readUint8(data, i + 1 + (i * 2)) * valueMultiplier + blue = readUint8(data, i + 2 + (i * 2)) * valueMultiplier + result[i] = rgbx(red, green, blue, 0xFF) + else: + for i in 0 ..< result.len: + let + red = readUint16(data, i + (i * 4)).uint8 * valueMultiplier + green = readUint16(data, i + 2 + (i * 4)).uint8 * valueMultiplier + blue = readUint16(data, i + 4 + (i * 4)).uint8 * valueMultiplier + result[i] = rgbx(red, green, blue, 0xFF) + +proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} = + result = newSeq[ColorRGBX](1) + proc decodePpm*(data: string): Image {.raises: [PixieError].} = ## Decodes Portable Pixel Map data into an Image. - result = newImage(0, 0) + + let header = decodeHeader(data) + + if not (header.version in ppmSignatures): failInvalid() + if 0 > header.maxVal or header.maxVal > 0xFFFF: failInvalid() + + result = newImage(header.width, header.height) + result.data = ( + if header.version == "P3": + decodeP3Data(data[header.dataOffset .. ^1], header.maxVal) + else: decodeP6Data(data[header.dataOffset .. ^1], header.maxVal) + ) proc decodePpm*(data: seq[uint8]): Image {.inline, raises: [PixieError].} = ## Decodes Portable Pixel Map data into an Image. From b136e5b4e259aac5b7697df4ac0a2687add3e118 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Fri, 7 Jan 2022 14:06:43 +0200 Subject: [PATCH 3/9] P3 support also fixes an issue with header decoder whitespace handling --- src/pixie/fileformats/ppm.nim | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim index 8861812..3e13fd5 100644 --- a/src/pixie/fileformats/ppm.nim +++ b/src/pixie/fileformats/ppm.nim @@ -16,7 +16,7 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = if data.len <= 10: # Each part + whitespace raise newException(PixieError, "Invalid PPM file header") - var commentMode: bool + var commentMode, readWhitespace: bool var i, readFields: int var field: string while readFields < 4: @@ -26,8 +26,9 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = elif c == '\n': commentMode = false if not commentMode: - if c in Whitespace: + if c in Whitespace and not readWhitespace: readFields += 1 + readWhitespace = true try: case readFields: of 1: @@ -42,8 +43,9 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = discard except ValueError: failInvalid() field = "" - else: + elif not (c in Whitespace): field.add(c) + readWhitespace = false i += 1 result.dataOffset = i @@ -77,8 +79,16 @@ proc decodeP6Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} = blue = readUint16(data, i + 4 + (i * 4)).uint8 * valueMultiplier result[i] = rgbx(red, green, blue, 0xFF) -proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} = - result = newSeq[ColorRGBX](1) +proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [PixieError].} = + var p6data = newStringOfCap(data.splitWhitespace.len) + try: + for line in data.splitLines(): + echo line + for sample in line.split('#', 1)[0].splitWhitespace(): + p6data.add(parseInt(sample).chr) + except ValueError: failInvalid() + + result = decodeP6Data(p6data, maxVal) proc decodePpm*(data: string): Image {.raises: [PixieError].} = ## Decodes Portable Pixel Map data into an Image. @@ -116,7 +126,7 @@ proc encodePpm*(image: Image): string {.raises: [].} = for y in 0 ..< image.height: for x in 0 ..< image.width: let rgb = image[x, y].rgba() - # alpha channel is ignored + # Alpha channel is ignored result.addUint8(rgb.r) result.addUint8(rgb.g) result.addUint8(rgb.b) From 6f654e32bca3b8bd14bef04b3dd446d0bd5105e8 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Fri, 7 Jan 2022 14:08:26 +0200 Subject: [PATCH 4/9] remove erroneous debug echo --- src/pixie/fileformats/ppm.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim index 3e13fd5..d11e28a 100644 --- a/src/pixie/fileformats/ppm.nim +++ b/src/pixie/fileformats/ppm.nim @@ -83,7 +83,6 @@ proc decodeP3Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [PixieErr var p6data = newStringOfCap(data.splitWhitespace.len) try: for line in data.splitLines(): - echo line for sample in line.split('#', 1)[0].splitWhitespace(): p6data.add(parseInt(sample).chr) except ValueError: failInvalid() From 158b279926474e2339f43946cfece867023e6390 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Fri, 7 Jan 2022 15:50:43 +0200 Subject: [PATCH 5/9] add dead simple tests for PPM files --- tests/all.nim | 1 + tests/fileformats/ppm/feep.p3.master.ppm | 8 ++++++++ tests/fileformats/ppm/feep.p3.ppm | Bin 0 -> 59 bytes tests/fileformats/ppm/feep.p6.master.ppm | Bin 0 -> 59 bytes tests/fileformats/ppm/feep.p6.ppm | Bin 0 -> 59 bytes tests/test_ppm.nim | 8 ++++++++ 6 files changed, 17 insertions(+) create mode 100644 tests/fileformats/ppm/feep.p3.master.ppm create mode 100644 tests/fileformats/ppm/feep.p3.ppm create mode 100644 tests/fileformats/ppm/feep.p6.master.ppm create mode 100644 tests/fileformats/ppm/feep.p6.ppm create mode 100644 tests/test_ppm.nim diff --git a/tests/all.nim b/tests/all.nim index 69850f8..03ecbcf 100644 --- a/tests/all.nim +++ b/tests/all.nim @@ -10,6 +10,7 @@ import test_paints, test_paths, test_png, + test_ppm, test_qoi, test_svg, ../examples/text, diff --git a/tests/fileformats/ppm/feep.p3.master.ppm b/tests/fileformats/ppm/feep.p3.master.ppm new file mode 100644 index 0000000..221e752 --- /dev/null +++ b/tests/fileformats/ppm/feep.p3.master.ppm @@ -0,0 +1,8 @@ +P3 +# feep.p3.master.ppm +4 4 +15 + 0 0 0 0 0 0 0 0 0 15 0 15 + 0 0 0 0 15 7 0 0 0 0 0 0 + 0 0 0 0 0 0 0 15 7 0 0 0 +15 0 15 0 0 0 0 0 0 0 0 0 diff --git a/tests/fileformats/ppm/feep.p3.ppm b/tests/fileformats/ppm/feep.p3.ppm new file mode 100644 index 0000000000000000000000000000000000000000..d2cbd0db64dd5ee88994b66dcf3fb4ed43c9c209 GIT binary patch literal 59 kcmWGA<1$e&;W9EcU&u0Wb~bLZ!e0013MYu>b%7 literal 0 HcmV?d00001 diff --git a/tests/fileformats/ppm/feep.p6.master.ppm b/tests/fileformats/ppm/feep.p6.master.ppm new file mode 100644 index 0000000000000000000000000000000000000000..d2cbd0db64dd5ee88994b66dcf3fb4ed43c9c209 GIT binary patch literal 59 kcmWGA<1$e&;W9EcU&u0Wb~bLZ!e0013MYu>b%7 literal 0 HcmV?d00001 diff --git a/tests/fileformats/ppm/feep.p6.ppm b/tests/fileformats/ppm/feep.p6.ppm new file mode 100644 index 0000000000000000000000000000000000000000..d2cbd0db64dd5ee88994b66dcf3fb4ed43c9c209 GIT binary patch literal 59 kcmWGA<1$e&;W9EcU&u0Wb~bLZ!e0013MYu>b%7 literal 0 HcmV?d00001 diff --git a/tests/test_ppm.nim b/tests/test_ppm.nim new file mode 100644 index 0000000..06256dd --- /dev/null +++ b/tests/test_ppm.nim @@ -0,0 +1,8 @@ +import pixie/fileformats/ppm + +block: + for format in @["p3", "p6"]: + let image = decodePpm(readFile( + "tests/fileformats/ppm/feep." & $format & ".master.ppm" + )) + writeFile("tests/fileformats/ppm/feep." & $format & ".ppm", encodePpm(image)) From 64cfad16fb008984f5727ca0c58ad80f5e32e0c3 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Fri, 7 Jan 2022 15:54:32 +0200 Subject: [PATCH 6/9] add PPM to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 32b57ce..b8be978 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ BMP | ✅ | ✅ | QOI | ✅ | ✅ | GIF | ✅ | | SVG | ✅ | | +PPM | ✅ | ✅ | ### Font file formats From 71016b868ebfd23d13bfc0aa3a399699443fc2cc Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Sun, 9 Jan 2022 17:37:03 +0200 Subject: [PATCH 7/9] remove incorrect rgba conversion --- src/pixie/fileformats/ppm.nim | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim index d11e28a..be9434b 100644 --- a/src/pixie/fileformats/ppm.nim +++ b/src/pixie/fileformats/ppm.nim @@ -27,7 +27,7 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = commentMode = false if not commentMode: if c in Whitespace and not readWhitespace: - readFields += 1 + inc readFields readWhitespace = true try: case readFields: @@ -46,22 +46,22 @@ proc decodeHeader(data: string): PpmHeader {.raises: [PixieError].} = elif not (c in Whitespace): field.add(c) readWhitespace = false - i += 1 + inc i result.dataOffset = i proc decodeP6Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} = let needsUint16 = maxVal > 0xFF - result = newSeq[ColorRGBX](( - if needsUint16: data.len / 6 - else: data.len / 3 - ).int) + result = newSeq[ColorRGBX]( + if needsUint16: data.len div 6 + else: data.len div 3 + ) # Let's calculate the real maximum value multiplier. # 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 - let valueMultiplier = (0xFF / maxVal).uint8 + let valueMultiplier = (0xFF div maxVal).uint8 # if comparison in for loops is expensive, so let's unroll it if not needsUint16: @@ -124,7 +124,7 @@ proc encodePpm*(image: Image): string {.raises: [].} = # PPM image data for y in 0 ..< image.height: for x in 0 ..< image.width: - let rgb = image[x, y].rgba() + let rgb = image[x, y] # Alpha channel is ignored result.addUint8(rgb.r) result.addUint8(rgb.g) From be26fe5193d3559260ad727394c567df5e254be2 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Mon, 10 Jan 2022 15:23:48 +0200 Subject: [PATCH 8/9] fix high-depth handling and add a test case --- src/pixie/fileformats/ppm.nim | 33 ++++++++++++------ .../ppm/feep.p3.hidepth.master.ppm | 8 +++++ tests/fileformats/ppm/feep.p3.hidepth.ppm | Bin 0 -> 59 bytes tests/test_ppm.nim | 5 +++ 4 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 tests/fileformats/ppm/feep.p3.hidepth.master.ppm create mode 100644 tests/fileformats/ppm/feep.p3.hidepth.ppm diff --git a/src/pixie/fileformats/ppm.nim b/src/pixie/fileformats/ppm.nim index be9434b..7562c18 100644 --- a/src/pixie/fileformats/ppm.nim +++ b/src/pixie/fileformats/ppm.nim @@ -61,30 +61,41 @@ proc decodeP6Data(data: string, maxVal: int): seq[ColorRGBX] {.raises: [].} = # Let's calculate the real maximum value multiplier. # 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 - let valueMultiplier = (0xFF div maxVal).uint8 + let valueMultiplier = 0xFF / maxVal # if comparison in for loops is expensive, so let's unroll it if not needsUint16: for i in 0 ..< result.len: let - red = readUint8(data, i + (i * 2)) * valueMultiplier - green = readUint8(data, i + 1 + (i * 2)) * valueMultiplier - blue = readUint8(data, i + 2 + (i * 2)) * valueMultiplier + red = (readUint8(data, i + (i * 2)).float * valueMultiplier + 0.5).uint8 + green = (readUint8(data, i + 1 + (i * 2)).float * valueMultiplier + 0.5).uint8 + blue = (readUint8(data, i + 2 + (i * 2)).float * valueMultiplier + 0.5).uint8 result[i] = rgbx(red, green, blue, 0xFF) else: for i in 0 ..< result.len: let - red = readUint16(data, i + (i * 4)).uint8 * valueMultiplier - green = readUint16(data, i + 2 + (i * 4)).uint8 * valueMultiplier - blue = readUint16(data, i + 4 + (i * 4)).uint8 * valueMultiplier + red = (readUint16(data, i + (i * 5)).swap.float * valueMultiplier + 0.5).uint8 + green = (readUint16(data, i + 2 + (i * 5)).swap.float * valueMultiplier + 0.5).uint8 + blue = (readUint16(data, i + 4 + (i * 5)).swap.float * valueMultiplier + 0.5).uint8 result[i] = rgbx(red, green, blue, 0xFF) 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: - for line in data.splitLines(): - for sample in line.split('#', 1)[0].splitWhitespace(): - p6data.add(parseInt(sample).chr) + if not needsUint16: + for line in data.splitLines(): + 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() result = decodeP6Data(p6data, maxVal) diff --git a/tests/fileformats/ppm/feep.p3.hidepth.master.ppm b/tests/fileformats/ppm/feep.p3.hidepth.master.ppm new file mode 100644 index 0000000..4678865 --- /dev/null +++ b/tests/fileformats/ppm/feep.p3.hidepth.master.ppm @@ -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 diff --git a/tests/fileformats/ppm/feep.p3.hidepth.ppm b/tests/fileformats/ppm/feep.p3.hidepth.ppm new file mode 100644 index 0000000000000000000000000000000000000000..d2cbd0db64dd5ee88994b66dcf3fb4ed43c9c209 GIT binary patch literal 59 kcmWGA<1$e&;W9EcU&u0Wb~bLZ!e0013MYu>b%7 literal 0 HcmV?d00001 diff --git a/tests/test_ppm.nim b/tests/test_ppm.nim index 06256dd..d84ec9a 100644 --- a/tests/test_ppm.nim +++ b/tests/test_ppm.nim @@ -6,3 +6,8 @@ block: "tests/fileformats/ppm/feep." & $format & ".master.ppm" )) 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)) From a7388a291d88d1a3f76f476a6e3af30521d99cc2 Mon Sep 17 00:00:00 2001 From: Rasmus Moorats Date: Tue, 11 Jan 2022 12:51:54 +0200 Subject: [PATCH 9/9] assert that generated images match P6 master --- tests/test_ppm.nim | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_ppm.nim b/tests/test_ppm.nim index d84ec9a..d041c12 100644 --- a/tests/test_ppm.nim +++ b/tests/test_ppm.nim @@ -11,3 +11,8 @@ block: "tests/fileformats/ppm/feep.p3.hidepth.master.ppm" )) writeFile("tests/fileformats/ppm/feep.p3.hidepth.ppm", encodePpm(image)) + + # produced output should be identical to P6 master + let p6Master = readFile("tests/fileformats/ppm/feep.p6.master.ppm") + for image in @["p3", "p6", "p3.hidepth"]: + doAssert readFile("tests/fileformats/ppm/feep." & $image & ".ppm") == p6Master