image-in-browser
Version:
Package for encoding / decoding images, transforming images, applying filters, drawing primitives on images on the client side (no need for server Node.js)
130 lines • 4.17 kB
JavaScript
import { LibError } from '../../error/lib-error.js';
export class PsdChannel {
get id() {
return this._id;
}
get dataLength() {
return this._dataLength;
}
get data() {
return this._data;
}
constructor(id, dataLength) {
this._id = id;
this._dataLength = dataLength;
}
static read(opt) {
const obj = new PsdChannel(opt.id);
obj.readPlane({
input: opt.input,
width: opt.width,
height: opt.height,
bitDepth: opt.bitDepth,
compression: opt.compression,
lineLengths: opt.lineLengths,
planeNumber: opt.planeNumber,
});
return obj;
}
readLineLengths(input, height) {
const lineLengths = new Uint16Array(height);
for (let i = 0; i < height; ++i) {
lineLengths[i] = input.readUint16();
}
return lineLengths;
}
readPlaneUncompressed(input, width, height, bitDepth) {
let len = width * height;
if (bitDepth === 16) {
len *= 2;
}
if (len > input.length) {
this._data = new Uint8Array(len);
this._data.fill(255, 0, len);
return;
}
const imgData = input.readRange(len);
this._data = imgData.toUint8Array();
}
readPlaneRleCompressed(input, width, height, bitDepth, lineLengths, planeNum) {
let len = width * height;
if (bitDepth === 16) {
len *= 2;
}
this._data = new Uint8Array(len);
let pos = 0;
let lineIndex = planeNum * height;
if (lineIndex >= lineLengths.length) {
this._data.fill(255, 0, this._data.length);
return;
}
for (let i = 0; i < height; ++i) {
const len = lineLengths[lineIndex++];
const s = input.readRange(len);
this.decodeRLE(s, this._data, pos);
pos += width;
}
}
decodeRLE(src, dst, dstIndex) {
let _dstIndex = dstIndex;
while (!src.isEOS) {
let n = src.readInt8();
if (n < 0) {
n = 1 - n;
if (src.isEOS) {
break;
}
const b = src.read();
if (_dstIndex + n > dst.length) {
n = dst.length - _dstIndex;
}
for (let i = 0; i < n; ++i) {
dst[_dstIndex++] = b;
}
}
else {
n++;
if (_dstIndex + n > dst.length) {
n = dst.length - _dstIndex;
}
n = Math.min(n, src.length);
for (let i = 0; i < n; ++i) {
dst[_dstIndex++] = src.read();
}
}
}
}
readPlane(opt) {
var _a, _b, _c;
if (opt.input.length < 2) {
return;
}
const planeNumber = (_a = opt.planeNumber) !== null && _a !== void 0 ? _a : 0;
const compression = (_b = opt.compression) !== null && _b !== void 0 ? _b : opt.input.readUint16();
switch (compression) {
case PsdChannel.compressNone: {
this.readPlaneUncompressed(opt.input, opt.width, opt.height, opt.bitDepth);
break;
}
case PsdChannel.compressRle: {
const lineLengths = (_c = opt.lineLengths) !== null && _c !== void 0 ? _c : this.readLineLengths(opt.input, opt.height);
this.readPlaneRleCompressed(opt.input, opt.width, opt.height, opt.bitDepth, lineLengths, planeNumber);
break;
}
default:
throw new LibError('Unsupported compression: $compression');
}
}
}
PsdChannel.red = 0;
PsdChannel.green = 1;
PsdChannel.blue = 2;
PsdChannel.black = 3;
PsdChannel.alpha = -1;
PsdChannel.mask = -2;
PsdChannel.realMask = -3;
PsdChannel.compressNone = 0;
PsdChannel.compressRle = 1;
PsdChannel.compressZip = 2;
PsdChannel.compressZipPredictor = 3;
//# sourceMappingURL=psd-channel.js.map