Some info on how to encode layer images back to a photon file.
A photon file is constructed as follows:
Header block
Preview block
Meta block for each layer (aka layerdef), containing layer height, image address, data length etc
Data block for each layer, containing a RLE encoded image
VoxelsOps do not effect the Header and Preview blocks. So only the meta block and data block for each image have to be reconstructed.
The start address of the first metablock is stored in the Header in 4 bytes from byte 64.
The number of layers (and thus metablocks and data blocks) is stored in the Header in 4 bytes from byte 68.
Each Meta block has the following struct:
- Layer height (mm), 4 bytes containing Float, "Height at which this layer should be printed."
- Exposure time (s), 4 bytes containing Float, "Exposure time for this layer."
- Off time (s), 4 bytes containing Float, "Off time for this layer."
- Datablock Address, 4 bytes containing Int, "Address where the raw image can be found."
- Data Length, 4 bytes containing Int, "Size (in bytes) of the raw image."
- Some padding, 16 bytes
For each metablock you should adjust the datablock address and data length after RLE encoding the layer image. The other data you can copy from the source file.
Each Data block is just a block of RLE encoded bytes without decoration or other info.
Some python code I used to encode the image to RLE data:
# Count number of pixels with same color up until 0x7D/125 repetitions
rleData = bytearray()
color = 0
black = 0
white = 1
nrOfColor = 0
prevColor=None
for y in range(height):
for x in range(width):
# print (imgsurf.get_at((x, y)))
(r, g, b, a) = imgsurf.get_at((x, y))
if ((r + g + b) // 3) < 128:
color = black
else:
color = white
if prevColor == None: prevColor = color
isLastPixel = (x == (width - 1) and y == (height - 1))
if color == prevColor and nrOfColor < 0x7D and not isLastPixel:
nrOfColor = nrOfColor + 1
else:
#print (color,nrOfColor,nrOfColor<<1)
encValue = (prevColor << 7) | nrOfColor # push color (B/W) to highest bit and repetitions to lowest 7 bits.
rleData.append(encValue)
prevColor = color
nrOfColor = 1
return bytes(rleData)
Some info on how to encode layer images back to a photon file. A photon file is constructed as follows:
VoxelsOps do not effect the Header and Preview blocks. So only the meta block and data block for each image have to be reconstructed.
The start address of the first metablock is stored in the Header in 4 bytes from byte 64. The number of layers (and thus metablocks and data blocks) is stored in the Header in 4 bytes from byte 68.
Each Meta block has the following struct:
For each metablock you should adjust the datablock address and data length after RLE encoding the layer image. The other data you can copy from the source file.
Each Data block is just a block of RLE encoded bytes without decoration or other info. Some python code I used to encode the image to RLE data: