File-To-Video-Encoder/tensorCeral.nim
2022-09-02 12:09:27 -04:00

154 lines
4.7 KiB
Nim

import strutils
import sugar
import sequtils
import arraymancer
import streams
import os
# CERIALIZATION OPERATIONS
proc serializeTensor*(outy : Stream, dim : array[3, Metadata], data : array[3, seq[byte]], close = true) =
## Takes in a Tensor made of pallete, originalFileColorEncoding, outputData
## This is for training purposes, and is useful for machine learning
for x in 0 .. 2:
outy.write(dim[x][0].uint32)
outy.write(dim[x][1].uint32)
outy.write(len(data[x]).uint32)
for x in 0 .. 2:
for x in data[x]:
outy.write(x.char)
outy.flush()
if not close:
outy.setPosition(0)
else:
outy.close()
proc serializeColorPallete*(a : Tensor[byte] | Tensor[float32], output : Stream) =
##takes a pallete, makes it into a little file for your transport
doAssert(a.shape == [256, 3], "must be a valid shape for a pallete")
for x in a:
when a is Tensor[float32]:
output.write(x.byte)
else:
output.write(x)
output.flush()
proc deSerializeColorPallate*(inny : Stream) : Tensor[byte] =
##the inverse of serializeColorPallete
var buffer = newSeq[byte](256*3)
discard inny.readData(addr buffer[0], len(buffer))
return buffer.toTensor().reshape(256, 3)
proc deSerializeTensors*(outy : Stream) : (Tensor[float32], Tensor[float32], Tensor[float32]) =
## Takes in a Tensor made of pallete, originalFileColorEncoding, outputData
## This is for training purposes, and is useful for machine learning
## Organizes from disk, of arbitrary size
var id : seq[(uint32,uint32,uint32)]
outy.setPosition(0)
for x in 1 .. 3:
var temp : seq[uint32]
var buffersize = sizeof(uint32)
var buffer = newSeq[uint32](sizeof(uint32))
for x in 1 .. 3:
discard outy.readData(buffer[0].addr, buffersize)
temp.add(buffer[0])
id.add((temp[0], temp[1], temp[2]))
for x in 0 .. 2:
var buffersize = id[x][2]
var buffer = newSeq[byte](id[x][2])
#i suspect that this code sometimes crashes if its too big
#to resolve this, simply do buffersize/10 then do it in a 10th
discard outy.readData(buffer[0].addr, buffersize.int)
let final = (buffer.map(x=>float32(x)).toTensor.reshape(id[x][0].int, id[x][1].int))
case x:
of 0:
result[0] = final
of 1:
result[1] = final
of 2:
result[2] = final
else:
echo "imposibru"
template arrangeIo(a,b : string) =
##Arranges io in the binary functions
##allows for smooth stdin stdout management
var input {.inject.} : FileStream
var output {.inject.} : FileStream
case a:
of "", "-":
input = newFileStream(stdin)
else:
input = newFileStream(a, fmRead)
case b:
of "", "-":
output = newFileStream(stdout)
else:
output = newFileStream(b, fmWrite)
proc convertFileToBinary*(a,b = "") =
##This is used in the shell script for LDPC, because of the whacky
##Mandatory binary input output
#repeated code
arrangeIo(a,b)
while not input.atEnd():
let current = input.readChar()
let converted = toBin(int(current), 8)
output.write(converted)
output.flush()
proc convertFileToHex*(a,b = "") =
##This is used in the shell script for LDPC, because of the whacky
##Mandatory binary input output
arrangeIo(a,b)
var buffer = newSeq[char](8)
while not input.atEnd():
discard input.readData(buffer[0].addr, 8)
let converted = char parseBinInt(buffer.join(""))
output.write(converted)
output.flush()
proc diffCheck*(a : Stream, b : Stream) =
##diffchecks the streams
##used at the end to compare files
var incorrect = 0
var total = 0
var best = 100.0
for x in 0 .. 40 :
b.setPosition(x)
a.setPosition(0)
while not a.atEnd():
total+=1
if a.readChar() != b.readChar():
incorrect += 1
if best > (incorrect / total ) * 100:
best = (incorrect / total ) * 100
stderr.writeLine best
when isMainModule:
var params = commandLineParams()
var command = ""
if params.len() == 0:
quit(1)
else:
command = params[0]
params.setlen(3)
if params[0] == "-b":
convertFileToBinary(params[1],params[2])
elif params[0] == "-e":
convertFileToHex(params[1],params[2])
elif command == "-d":
diffCheck(newFileStream(params[1]), newFileStream(params[2]))