add PPM encoder
This commit is contained in:
parent
8e64260b70
commit
7679712575
2 changed files with 43 additions and 2 deletions
|
@ -1,13 +1,13 @@
|
||||||
import bumpy, chroma, flatty/binny, os, pixie/common, pixie/contexts,
|
import bumpy, chroma, flatty/binny, os, pixie/common, pixie/contexts,
|
||||||
pixie/fileformats/bmp, pixie/fileformats/gif, pixie/fileformats/jpg,
|
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
|
pixie/fonts, pixie/images, pixie/masks, pixie/paints, pixie/paths, strutils, vmath
|
||||||
|
|
||||||
export bumpy, chroma, common, contexts, fonts, images, masks, paints, paths, vmath
|
export bumpy, chroma, common, contexts, fonts, images, masks, paints, paths, vmath
|
||||||
|
|
||||||
type
|
type
|
||||||
FileFormat* = enum
|
FileFormat* = enum
|
||||||
ffPng, ffBmp, ffJpg, ffGif, ffQoi
|
ffPng, ffBmp, ffJpg, ffGif, ffQoi, ffPpm
|
||||||
|
|
||||||
converter autoStraightAlpha*(c: ColorRGBX): ColorRGBA {.inline, raises: [].} =
|
converter autoStraightAlpha*(c: ColorRGBX): ColorRGBA {.inline, raises: [].} =
|
||||||
## Convert a premultiplied alpha RGBA to a straight alpha RGBA.
|
## 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)
|
decodeGif(data)
|
||||||
elif data.len > (14+8) and data.readStr(0, 4) == qoiSignature:
|
elif data.len > (14+8) and data.readStr(0, 4) == qoiSignature:
|
||||||
decodeQoi(data)
|
decodeQoi(data)
|
||||||
|
elif data.len > 9 and data.readStr(0, 2) in ppmSignatures:
|
||||||
|
decodePpm(data)
|
||||||
else:
|
else:
|
||||||
raise newException(PixieError, "Unsupported image file format")
|
raise newException(PixieError, "Unsupported image file format")
|
||||||
|
|
||||||
|
@ -69,6 +71,8 @@ proc encodeImage*(image: Image, fileFormat: FileFormat): string {.raises: [Pixie
|
||||||
image.encodeQoi()
|
image.encodeQoi()
|
||||||
of ffGif:
|
of ffGif:
|
||||||
raise newException(PixieError, "Unsupported file format")
|
raise newException(PixieError, "Unsupported file format")
|
||||||
|
of ffPpm:
|
||||||
|
image.encodePpm()
|
||||||
|
|
||||||
proc encodeMask*(mask: Mask, fileFormat: FileFormat): string {.raises: [PixieError].} =
|
proc encodeMask*(mask: Mask, fileFormat: FileFormat): string {.raises: [PixieError].} =
|
||||||
## Encodes a mask into memory.
|
## Encodes a mask into memory.
|
||||||
|
@ -85,6 +89,7 @@ proc writeFile*(image: Image, filePath: string) {.raises: [PixieError].} =
|
||||||
of ".bmp": ffBmp
|
of ".bmp": ffBmp
|
||||||
of ".jpg", ".jpeg": ffJpg
|
of ".jpg", ".jpeg": ffJpg
|
||||||
of ".qoi": ffQoi
|
of ".qoi": ffQoi
|
||||||
|
of ".ppm": ffPpm
|
||||||
else:
|
else:
|
||||||
raise newException(PixieError, "Unsupported file extension")
|
raise newException(PixieError, "Unsupported file extension")
|
||||||
|
|
||||||
|
@ -100,6 +105,7 @@ proc writeFile*(mask: Mask, filePath: string) {.raises: [PixieError].} =
|
||||||
of ".bmp": ffBmp
|
of ".bmp": ffBmp
|
||||||
of ".jpg", ".jpeg": ffJpg
|
of ".jpg", ".jpeg": ffJpg
|
||||||
of ".qoi": ffQoi
|
of ".qoi": ffQoi
|
||||||
|
of ".ppm": ffPpm
|
||||||
else:
|
else:
|
||||||
raise newException(PixieError, "Unsupported file extension")
|
raise newException(PixieError, "Unsupported file extension")
|
||||||
|
|
||||||
|
|
35
src/pixie/fileformats/ppm.nim
Normal file
35
src/pixie/fileformats/ppm.nim
Normal file
|
@ -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)
|
Loading…
Reference in a new issue