ag-psd
Version:
Library for reading and writing PSD files
93 lines (66 loc) • 2.83 kB
Markdown
- writing 1, 16, 32 bit documents
'pths'
- split decoding layer data from reading the document
- writing paletted documents
- cleanup errors from tests (make list of drawings that should ignore those errors)
- writing zip/zip with prediction
- can we remove sectionDivider property ?
- can we remove nameSource property ?
- improve vector fill / stroke help sections
check: https://github.com/psd-tools/psd-tools
check: https://github.com/TheNicker/libpsd
- zip with prediction: https://github.com/TheNicker/libpsd/blob/master/src/psd_zip.c
- also support saving with zip compression ?
- decompress image data in FEid section
```ts
if (!channelLength) throw new Error('filterEffect: Empty channel');
const compression = readUint16(reader);
const data = createImageDataBitDepth(right - left, bottom - top, depth, 1);
const end = reader.offset + channelLength - 2;
readData(reader, channelLength - 2, data, compression, data.width, data.height, depth, 0, false, 1);
if (reader.offset != end) throw new Error(`Invalid offset after readData ${reader.offset} ${end}`);
channels.push(data);
const top = readInt32(reader);
const left = readInt32(reader);
const bottom = readInt32(reader);
const right = readInt32(reader);
if (readUint32(reader)) throw new Error('filterEffect: 64 bit length is not supported');
const extraLength = readUint32(reader);
const compression = readUint16(reader);
const data = createImageDataBitDepth(right - left, bottom - top, depth, 1);
readData(reader, extraLength - 2, data, compression, data.width, data.height, depth, 0, false, 1);
target.filterEffectsMasks[target.filterEffectsMasks.length - 1].extra = { top, left, bottom, right, data };
```
```ts
export function decodeUtf16String(buffer: Uint8Array) {
let result = '';
for (let i = 0; i < buffer.byteLength;) {
const w1 = (buffer[i++] << 8) | buffer[i++];
if ((w1 & 0xF800) !== 0xD800) { // w1 < 0xD800 || w1 > 0xDFFF
result += String.fromCharCode(w1);
continue;
}
if ((w1 & 0xFC00) === 0xD800) { // w1 >= 0xD800 && w1 <= 0xDBFF
throw new Error('Invalid utf-16');
}
if (i === buffer.byteLength) {
throw new Error('Invalid utf-16');
}
const w2 = (buffer[i++] << 8) | buffer[i++];
if ((w2 & 0xFC00) !== 0xDC00) { // w2 < 0xDC00 || w2 > 0xDFFF)
throw new Error('Invalid utf-16');
}
result += String.fromCharCode(((w1 & 0x3ff) << 10) + (w2 & 0x3ff) + 0x10000);
}
return result;
}
export function encodeUtf16String(value: string) {
const buffer = new Uint8Array(value.length * 2);
for (let i = 0, j = 0; i < value.length; i++, j += 2) {
const word = value.charCodeAt(i);
buffer[j] = (word >> 8) & 0xff;
buffer[j + 1] = word & 0xff;
}
return buffer;
}
```