pixie/src/pixie.nim

117 lines
4 KiB
Nim
Raw Normal View History

2021-12-13 07:23:14 +00:00
import bumpy, chroma, flatty/binny, os, pixie/common, pixie/contexts,
pixie/fileformats/bmp, pixie/fileformats/gif, pixie/fileformats/jpg,
2022-01-07 10:29:23 +00:00
pixie/fileformats/png, pixie/fileformats/ppm, pixie/fileformats/qoi,
pixie/fileformats/svg, pixie/fonts, pixie/images, pixie/masks, pixie/paints,
pixie/paths, strutils, vmath
2020-11-21 04:34:57 +00:00
2021-12-13 07:23:14 +00:00
export bumpy, chroma, common, contexts, fonts, images, masks, paints, paths, vmath
2020-11-20 03:44:24 +00:00
2020-11-21 04:34:57 +00:00
type
FileFormat* = enum
2022-02-12 18:05:05 +00:00
FormatPng, FormatBmp, FormatJpg, FormatGif, FormatQoi, FormatPpm
2020-11-21 04:34:57 +00:00
2021-08-18 04:14:30 +00:00
converter autoStraightAlpha*(c: ColorRGBX): ColorRGBA {.inline, raises: [].} =
## Convert a premultiplied alpha RGBA to a straight alpha RGBA.
2021-03-03 18:37:15 +00:00
c.rgba()
2021-08-18 04:14:30 +00:00
converter autoPremultipliedAlpha*(c: ColorRGBA): ColorRGBX {.inline, raises: [].} =
2021-03-03 18:37:15 +00:00
## Convert a straight alpha RGBA to a premultiplied alpha RGBA.
c.rgbx()
2021-08-18 04:14:30 +00:00
proc decodeImage*(data: string | seq[uint8]): Image {.raises: [PixieError].} =
2021-06-25 00:09:54 +00:00
## Loads an image from memory.
2020-11-21 23:45:02 +00:00
if data.len > 8 and data.readUint64(0) == cast[uint64](pngSignature):
decodePng(data)
elif data.len > 2 and data.readUint16(0) == cast[uint16](jpgStartOfImage):
decodeJpg(data)
2020-12-04 16:17:03 +00:00
elif data.len > 2 and data.readStr(0, 2) == bmpSignature:
2020-11-21 23:45:02 +00:00
decodeBmp(data)
2021-02-23 04:35:08 +00:00
elif data.len > 5 and
(data.readStr(0, 5) == xmlSignature or data.readStr(0, 4) == svgSignature):
decodeSvg(data)
2021-03-01 16:53:15 +00:00
elif data.len > 6 and data.readStr(0, 6) in gifSignatures:
decodeGif(data)
2022-01-01 22:50:23 +00:00
elif data.len > (14+8) and data.readStr(0, 4) == qoiSignature:
decodeQoi(data)
2022-01-06 10:23:32 +00:00
elif data.len > 9 and data.readStr(0, 2) in ppmSignatures:
decodePpm(data)
2020-11-21 23:45:02 +00:00
else:
raise newException(PixieError, "Unsupported image file format")
2020-11-21 04:34:57 +00:00
2021-08-18 04:14:30 +00:00
proc decodeMask*(data: string | seq[uint8]): Mask {.raises: [PixieError].} =
2021-06-25 00:09:54 +00:00
## Loads a mask from memory.
if data.len > 8 and data.readUint64(0) == cast[uint64](pngSignature):
newMask(decodePng(data))
else:
raise newException(PixieError, "Unsupported mask file format")
2021-08-18 04:14:30 +00:00
proc readImage*(filePath: string): Image {.inline, raises: [PixieError].} =
2020-11-21 04:34:57 +00:00
## Loads an image from a file.
2021-08-18 04:14:30 +00:00
try:
decodeImage(readFile(filePath))
except IOError as e:
raise newException(PixieError, e.msg, e)
2020-11-21 04:34:57 +00:00
2021-08-18 04:14:30 +00:00
proc readMask*(filePath: string): Mask {.raises: [PixieError].} =
2021-06-25 00:09:54 +00:00
## Loads a mask from a file.
2021-08-18 04:14:30 +00:00
try:
decodeMask(readFile(filePath))
except IOError as e:
raise newException(PixieError, e.msg, e)
2021-06-25 00:09:54 +00:00
2021-08-18 04:14:30 +00:00
proc encodeImage*(image: Image, fileFormat: FileFormat): string {.raises: [PixieError].} =
2020-11-21 23:45:02 +00:00
## Encodes an image into memory.
2020-11-21 04:34:57 +00:00
case fileFormat:
2022-02-12 18:05:05 +00:00
of FormatPng:
2020-11-21 04:34:57 +00:00
image.encodePng()
2022-02-12 18:05:05 +00:00
of FormatJpg:
2020-11-21 23:45:02 +00:00
image.encodeJpg()
2022-02-12 18:05:05 +00:00
of FormatBmp:
2020-11-21 04:34:57 +00:00
image.encodeBmp()
2022-02-12 18:05:05 +00:00
of FormatQoi:
2022-01-01 22:50:23 +00:00
image.encodeQoi()
2022-02-12 18:05:05 +00:00
of FormatGif:
2021-06-25 00:09:54 +00:00
raise newException(PixieError, "Unsupported file format")
2022-02-12 18:05:05 +00:00
of FormatPpm:
2022-01-06 10:23:32 +00:00
image.encodePpm()
2021-06-25 00:09:54 +00:00
2021-08-18 04:14:30 +00:00
proc encodeMask*(mask: Mask, fileFormat: FileFormat): string {.raises: [PixieError].} =
2021-06-25 00:09:54 +00:00
## Encodes a mask into memory.
case fileFormat:
2022-02-12 18:05:05 +00:00
of FormatPng:
2021-06-25 00:09:54 +00:00
mask.encodePng()
else:
raise newException(PixieError, "Unsupported file format")
2020-11-21 04:34:57 +00:00
2021-08-18 04:14:30 +00:00
proc writeFile*(image: Image, filePath: string) {.raises: [PixieError].} =
2020-11-21 18:34:57 +00:00
## Writes an image to a file.
2021-04-27 06:52:05 +00:00
let fileFormat = case splitFile(filePath).ext.toLowerAscii():
2022-02-12 18:05:05 +00:00
of ".png": FormatPng
of ".bmp": FormatBmp
of ".jpg", ".jpeg": FormatJpg
of ".qoi": FormatQoi
of ".ppm": FormatPpm
2020-11-21 23:45:02 +00:00
else:
2021-06-25 00:09:54 +00:00
raise newException(PixieError, "Unsupported file extension")
2021-08-18 04:14:30 +00:00
try:
writeFile(filePath, image.encodeImage(fileFormat))
except IOError as e:
raise newException(PixieError, e.msg, e)
proc writeFile*(mask: Mask, filePath: string) {.raises: [PixieError].} =
2021-06-25 00:09:54 +00:00
## Writes a mask to a file.
let fileFormat = case splitFile(filePath).ext.toLowerAscii():
2022-02-12 18:05:05 +00:00
of ".png": FormatPng
of ".bmp": FormatBmp
of ".jpg", ".jpeg": FormatJpg
of ".qoi": FormatQoi
of ".ppm": FormatPpm
2021-06-25 00:09:54 +00:00
else:
raise newException(PixieError, "Unsupported file extension")
2021-08-18 04:14:30 +00:00
try:
writeFile(filePath, mask.encodeMask(fileFormat))
except IOError as e:
raise newException(PixieError, e.msg, e)