diff --git a/PWS/README.md b/PWS/README.md new file mode 100644 index 0000000..eb47cf7 --- /dev/null +++ b/PWS/README.md @@ -0,0 +1,88 @@ +# AnyCubic Photon S - PWS File Format + +## Introduction + +AnyCubic introduced a new PWS File Format with printer firmware version P_V341 and slicing software Photon_WorkShop_V2.0.23 in early August 2019. +This document records the results of trying to reverse engineer the new file format. + +## File Structure + +The binary file seems to be divided into five sections FileHeader, Header, Preview, LayerDef each marked with a magic text value; and then the RLE encoded layer image data. + +The text values used for section magics could be 12 bytes with zero byte padding, or 8 bytes with zero padded and a zero 4 byte value. +Integer and Float values have little-endian byte order. + +Note: Fields with unknown usage are named and numbered from the offset in bytes from the beginning of the section magic value. + +| Name | Length | Type | Value from R_E_R_F.pws | Note | +| --- | --- | --- | --- | --- | +| FileHeaderMagic | 12 | Text | ANYCUBIC | | +| FileHeaderUnknown12 | 4 | Unknown | 0x01000000 | | +| FileHeaderUnknown16 | 4 | Unknown | 0x04000000 | | +| FileHeaderUnknown20 | 4 | Unknown | 0x30000000 | | +| FileHeaderUnknown24 | 4 | Unknown | 0x00000000 | | +| FileHeaderUnknown28 | 4 | Unknown | 0x90000000 | | +| FileHeaderUnknown32 | 4 | Unknown | 0x00000000 | | +| FileHeaderUnknown36 | 4 | Int | 0xac260100 | Layerdef file position.| +| FileHeaderUnknown40 | 4 | Unknown | 0x00000000 | | +| FileHeaderUnknown44 | 4 | Int | 0xc04a0100 | LayerImage file position. | +| HeaderMagic | 12 | Text | HEADER | | +| HeaderLength | 4 | Int | 80 | | +| HeaderUnknown16 | 4 | Float | 0x00003d42, 47.25 | Pixel size? | +| HeaderUnknown20 | 4 | Float | 0xcdcc4c3d, 0.05 | Layer height? | +| HeaderUnknown24 | 4 | Float | 0x00008040, 4.0 | | +| HeaderUnknown28 | 4 | Float | 0x0000803f, 1.0 | | +| HeaderUnknown32 | 4 | Float | 0x00007042, 60.0 | | +| HeaderUnknown36 | 4 | Float | 0x00004040, 3.0 | | +| HeaderUnknown40 | 4 | Float | 0x0000c040, 6.0 | | +| HeaderUnknown44 | 4 | Float | 0x00004040, 3.0 | | +| HeaderUnknown48 | 4 | Float | 0x00004040, 3.0 | | +| HeaderUnknown52 | 4 | Unknown | 0x531bac41 | | +| HeaderUnknown56 | 4 | Unknown | 0x01000000 | | +| HeaderLayerX | 4 | Int | 1440 | | +| HeaderLayerY | 4 | Int | 2560 | | +| HeaderUnknown68 | 4 | Unknown | 0x531bac41 | | +| HeaderUnknown72 | 4 | Unknown | 0x531bac41 | | +| HeaderUnknown76 | 4 | Unknown | 0x00000000 | | +| HeaderUnknown80 | 4 | Unknown | 0x00000000 | | +| HeaderUnknown84 | 4 | Unknown | 0x00000000 | | +| HeaderUnknown88 | 4 | Unknown | 0x00000000 | | +| HeaderUnknown92 | 4 | Unknown | 0x00000000 | | +| PreviewMagic | 12 | Text | PREVIEW | | +| PreviewLength | 4 | Int | 75276 | | +| PreviewWidth | 4 | Int | 224 | | +| PreviewUnknown20 | 4 | Unknown | 0x2a000000 | | +| PreviewHeight | 4 | Int | 168 | | +| PreviewImage | PreviewWidth * PreviewHeight * 2 | Image | | 16-bit RGB565 or RGB555 color image. | +| LayerdefMagic | 12 | Text | LAYERDEF | | +| LayerdefLength | 4 | Int | 9220 | | +| LayerdefCount | 4 | Int | 288 | | +| Layerdef | LayerdefCount * 32 | Binary | 0xc04a01005c8900000000c0400000404000007042000000000000000000000000 0x1cd401005c8900000000c0400000404000007042000000000000000000000000 ... | TODO | +| LayerImages | Variable | Binary | 0x7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d ... | Bit-level RLE (0x7d gives 125 zero bits and 0xfd gives 125 one bits). Decode HeaderLayerX bits to produce a layer image line then repeat HeaderLayerY times to produce a 2-bit layer image. | + +### Layerdef + +| Name | Length | Type | Value from R_E_R_F.pws first layer | Note | +| --- | --- | --- | --- | --- | +| LayerdefUnknown0 | 4 | Int | 0xc04a0100 | Layer file position. | +| LayerdefUnknown4 | 4 | Int | 0x5c890000 | Layer length| +| LayerdefUnknown8 | 4 | Float | 0x0000c040, 6.0 | | +| LayerdefUnknown12 | 4 | Float | 0x00004040, 3.0 | | +| LayerdefUnknown16 | 4 | Float | 0x00007042, 60.0 | | +| LayerdefUnknown20 | 4 | Unknown | 0x00000000 | | +| LayerdefUnknown24 | 4 | Unknown | 0x00000000 | | +| LayerdefUnknown28 | 4 | Unknown | 0x00000000 | | + +## Tools Used + +AnyCubic has only released Windows and Mac builds of it's new slicer, and the Windows build of Photon_WorkShop_V2.0.23 crashes when trying to use it with Wine on Linux. +Vim and bvi were used for some initial exploration of the R_E_R_F.pws file. +The trial version of [Hexinator](https://hexinator.com/) helped with identifying some of the interdependency between sections. +A simple Java program was written to dump the file contents and extract preview and layer images. + +## TODO + +* Get more sample pws files with known settings. +* Reverse engineer Layerdef values. +* Maybe release Java dump tool. + diff --git a/PWS/R_E_R_F.layer.020.png b/PWS/R_E_R_F.layer.020.png new file mode 100644 index 0000000..d4d7514 Binary files /dev/null and b/PWS/R_E_R_F.layer.020.png differ diff --git a/PWS/R_E_R_F.preview.png b/PWS/R_E_R_F.preview.png new file mode 100644 index 0000000..613356f Binary files /dev/null and b/PWS/R_E_R_F.preview.png differ