Skip to content

Instantly share code, notes, and snippets.

@aNNiMON
Last active September 19, 2024 13:24
Show Gist options
  • Save aNNiMON/c6b79f13e004dcfc415324c9f1cc6762 to your computer and use it in GitHub Desktop.
Save aNNiMON/c6b79f13e004dcfc415324c9f1cc6762 to your computer and use it in GitHub Desktop.
LutGen Nim

LutGen Nim

LutGen — a tool for generating LUT palettes and *.cube files

import std/strformat
import std/os
import pixie
const
LUT_SIZE = 64
BLOCKS_PER_LINE = 8
IMG_SIZE = LUT_SIZE * BLOCKS_PER_LINE
GREY = rgba(128, 128, 128, 255)
iterator blockRows(rowSize: int): int =
var bx, by = 0
let yMaxSize = LUT_SIZE * rowSize
let maxSize = IMG_SIZE * rowSize
while by < maxSize:
let i = by + bx
var y = 0
while y < yMaxSize:
yield i + y
y += rowSize
bx += LUT_SIZE
if bx >= IMG_SIZE:
bx = 0
by += yMaxSize
proc generateLUT(img: Image, targetFile: string) =
let f = open(targetFile, fmWrite)
defer: f.close()
f.writeLine(r"TITLE ""LutGen Nim""")
f.writeLine(fmt"LUT_3D_SIZE {LUT_SIZE}")
f.writeLine("DOMAIN_MIN 0 0 0")
f.writeLine("DOMAIN_MAX 1.0 1.0 1.0")
f.writeLine("")
for di in blockRows(img.width):
for i in 0 ..< LUT_SIZE:
let rgbx = img.data[di + i.int]
let r = rgbx.r.float / 255.0
let g = rgbx.g.float / 255.0
let b = rgbx.b.float / 255.0
f.writeLine(fmt"{r:.4f} {g:.4f} {b:.4f}")
proc drawPalette(img: Image, size: uint) =
var g, b = 0.uint
let m = 255.0 / (size.float - 1.0)
for di in blockRows(img.width):
let cg = uint8(g.float * m)
let cb = uint8(b.float * m)
for i in 0 ..< size:
let cr = uint8(i.float * m)
img.data[di + i.int] = rgba(cr, cg, cb, 255)
inc g
if g >= size:
g = 0; inc b
if b >= size:
break
proc createPaletteImage(size: uint): Image =
let dstImage = newImage(IMG_SIZE, IMG_SIZE)
dstImage.fill(GREY)
dstImage.drawPalette(size)
dstImage
proc extendImageWithPalette(srcImage: Image, size: uint): Image =
let dstImage = newImage(IMG_SIZE + srcImage.width, max(IMG_SIZE, srcImage.height))
dstImage.fill(GREY)
dstImage.draw(srcImage, translate(vec2(IMG_SIZE, 0)))
dstImage.drawPalette(size)
dstImage
proc help() =
echo "LutGen — a tool for generating LUT palettes and *.cube files"
echo "Usage:"
echo " lutgen -i [imagefile] — extend image with LUT palette"
echo " lutgen -n — generate new LUT palette"
echo " lutgen -g — generate *.cube file"
const LUT_PNG = "lut.png"
const LUT_CUBE = "lut.cube"
when isMainModule:
case paramCount():
of 1:
case paramStr(1):
of "-n":
createPaletteImage(LUT_SIZE).writeFile(LUT_PNG)
echo fmt"[DONE] {LUT_PNG} with palette generated"
quit(QuitSuccess)
of "-g":
if fileExists(LUT_PNG):
readImage(LUT_PNG).generateLUT(LUT_CUBE)
echo fmt"[DONE] {LUT_CUBE} generated from {LUT_PNG}. Usage: -vf lut3d={LUT_CUBE} -pix_fmt yuv420p"
quit(QuitSuccess)
else:
echo fmt"[ERROR] No {LUT_PNG} exists. Aborting"
quit(QuitFailure)
else: help()
of 2:
case paramStr(1):
of "-i":
let imagefile = paramStr(2)
if fileExists(imagefile):
let srcImage = readImage(imagefile)
let dstImage = srcImage.extendImageWithPalette(LUT_SIZE)
dstImage.writeFile(LUT_PNG)
echo fmt"[DONE] {LUT_PNG} with palette generated"
quit(QuitSuccess)
else:
echo fmt"[ERROR] image file {imagefile} not exists. Aborting"
quit(QuitFailure)
else: help()
else: help()
# Package
version = "0.1.1"
author = "aNNiMON"
description = "LUT *.cube generator"
license = "MIT"
binDir = "bin"
bin = @["lutgen"]
# Dependencies
requires "nim >= 2.0.0"
requires "pixie >= 5.0.7"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment