I'm implementing decoding photoshop (PSD) files. They have the format mostly documented, but not all. In newer versions of photoshop you can have video layers. And the video layer data is stored within a 'PxSD' tag (the contents are not documented). I have managed to reverse engineer some of the metadata with the following code:
case "PxSD": {
// Raw data for 3D or video layers.
var length = stream.readUint64();
var layer_id = stream.readUint32(); // id of video layer
var unknown1 = stream.readUint32(); // = 2
var unknown2 = stream.readUint32(); // = 2
var size = stream.readUint64(); // remaining size
var numFrames = stream.readUint32();
for (var nframe = 0; nframe < numFrames; ++nframe)
{
var size2 = stream.readUint64();
var absFrame = stream.readUint32();
var layerTop = stream.readUint32();
var layerLeft = stream.readUint32();
// TODO: mode, 1 for grayscale image, 3 = RGB image
// They are always same?
var mode = stream.readUint32();
var mode2 = stream.readUint32();
// TODO: numChannels
// 4 if painting on a frame from blank video layer
// 6 if painting on top of an imported RGB video
var channels = 4;
for (var ch = 0; ch < channels; ++ch)
{
var depth = stream.readUint32(); // 8
var top = stream.readInt32(); // layer dimensions
var left = stream.readInt32();
var bottom = stream.readInt32();
var right = stream.readInt32();
var unknown3 = stream.readUint32();
let sz = stream.readUint32();
var dt = new Uint8Array(sz);
stream.readUint8Array(dt);
console.log(dt);
}
}
break;
}
A few examples of the contents of the actual compressed data
width: 1, height: 1 - Entirely black (0) channel
[0, 3, 72, 137, 250, 15, 16, 96, 0, 1, 0, 1, 0, 0, 0, 0] (length=16)
width: 1, height: 1 - Entirely white (255) channel
[0, 3, 72, 137, 98, 0, 8, 48, 0, 0, 1, 0, 1, 0, 0, 0] (length=16)
width: 96, height: 8 - Entirely black (0) channel
[0, 3, 72, 137, 250, 207, 64, 91, 240, 127, 212, 252, 81, 243, 7, 177, 249, 0, 1, 6, 0, 118, 67, 7, 249, 0, 0, 0]
width: 96, height: 8 - Entirely white (255) channel
[0, 3, 72, 137, 98, 96, 24, 5, 163, 96, 228, 2, 128, 0, 3, 0, 3, 0, 0, 1]
width: 96, height: 7 - Entirely black (0) channel
[0, 3, 72, 137, 250, 207, 64, 91, 240, 127, 212, 252, 81, 243, 41, 0, 0, 1, 6, 0, 120, 182, 6, 250]
Does anyone have any thoughts of what kind of compression is used ? (it is most certainly lossless) (are they using macroblocks, some kind of lossless JPEG?, is it just zlib?) anyone point me in right direction? what does it look like? Ideas?
Thank you
Ok, it seems like the first 2 bytes in the data is the compression
0=uncompressed
1=RLE
2=ZLIB
3=ZLIB with prediction
Haven't thoroughly tested yet