ag-psd 14.2.0 → 14.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +2 -1
- package/dist/abr.js +3 -3
- package/dist/additionalInfo.js +23 -12
- package/dist/bundle.js +245 -135
- package/dist/descriptor.js +5 -1
- package/dist/engineData.js +2 -2
- package/dist/helpers.d.ts +6 -5
- package/dist/helpers.js +13 -11
- package/dist/imageResources.js +3 -1
- package/dist/psd.d.ts +3 -0
- package/dist/psd.js +1 -1
- package/dist/psdReader.js +197 -106
- package/dist/psdWriter.js +9 -9
- package/dist-es/abr.js +3 -3
- package/dist-es/additionalInfo.js +23 -12
- package/dist-es/descriptor.js +5 -1
- package/dist-es/engineData.js +2 -2
- package/dist-es/helpers.d.ts +6 -5
- package/dist-es/helpers.js +13 -11
- package/dist-es/imageResources.js +3 -1
- package/dist-es/psd.d.ts +3 -0
- package/dist-es/psd.js +1 -1
- package/dist-es/psdReader.js +197 -106
- package/dist-es/psdWriter.js +9 -9
- package/package.json +1 -1
package/dist/bundle.js
CHANGED
|
@@ -42,7 +42,7 @@ function readAbr(buffer, options) {
|
|
|
42
42
|
if (version === 1 || version === 2) {
|
|
43
43
|
throw new Error("Unsupported ABR version (" + version + ")"); // TODO: ...
|
|
44
44
|
}
|
|
45
|
-
else if (version === 6 || version === 7 || version === 10) {
|
|
45
|
+
else if (version === 6 || version === 7 || version === 9 || version === 10) {
|
|
46
46
|
var minorVersion = psdReader_1.readInt16(reader);
|
|
47
47
|
if (minorVersion !== 1 && minorVersion !== 2)
|
|
48
48
|
throw new Error('Unsupported ABR minor version');
|
|
@@ -254,7 +254,7 @@ function readAbr(buffer, options) {
|
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
else {
|
|
257
|
-
throw new Error(
|
|
257
|
+
throw new Error("Unsupported ABR version (" + version + ")");
|
|
258
258
|
}
|
|
259
259
|
return { samples: samples, patterns: patterns, brushes: brushes };
|
|
260
260
|
}
|
|
@@ -680,15 +680,6 @@ addHandler('lyid', hasKey('id'), function (reader, target) { return target.id =
|
|
|
680
680
|
psdWriter_1.writeUint32(writer, id);
|
|
681
681
|
options.layerIds.push(id);
|
|
682
682
|
});
|
|
683
|
-
// some kind of ID ? ignore
|
|
684
|
-
addHandler('lsdk', function (target) { return target._lsdk !== undefined; }, function (reader, target) {
|
|
685
|
-
var id = psdReader_1.readInt32(reader);
|
|
686
|
-
if (helpers_1.MOCK_HANDLERS)
|
|
687
|
-
target._lsdk = id;
|
|
688
|
-
}, function (writer, target) {
|
|
689
|
-
if (helpers_1.MOCK_HANDLERS)
|
|
690
|
-
psdWriter_1.writeInt32(writer, target._lsdk);
|
|
691
|
-
});
|
|
692
683
|
addHandler('lsct', hasKey('sectionDivider'), function (reader, target, left) {
|
|
693
684
|
target.sectionDivider = { type: psdReader_1.readUint32(reader) };
|
|
694
685
|
if (left()) {
|
|
@@ -710,6 +701,9 @@ addHandler('lsct', hasKey('sectionDivider'), function (reader, target, left) {
|
|
|
710
701
|
}
|
|
711
702
|
}
|
|
712
703
|
});
|
|
704
|
+
// it seems lsdk is used when there's a layer is nested more than 6 levels, but I don't know why?
|
|
705
|
+
// maybe some limitation of old version of PS?
|
|
706
|
+
addHandlerAlias('lsdk', 'lsct');
|
|
713
707
|
addHandler('clbl', hasKey('blendClippendElements'), function (reader, target) {
|
|
714
708
|
target.blendClippendElements = !!psdReader_1.readUint8(reader);
|
|
715
709
|
psdReader_1.skipBytes(reader, 3);
|
|
@@ -1047,6 +1041,9 @@ addHandler('SoLd', hasKey('placedLayer'), function (reader, target, left) {
|
|
|
1047
1041
|
resolution: descriptor_1.parseUnits(desc.Rslt),
|
|
1048
1042
|
warp: parseWarp((desc.quiltWarp || desc.warp)),
|
|
1049
1043
|
};
|
|
1044
|
+
if (desc.nonAffineTransform && desc.nonAffineTransform.some(function (x, i) { return x !== desc.Trnf[i]; })) {
|
|
1045
|
+
target.placedLayer.nonAffineTransform = desc.nonAffineTransform;
|
|
1046
|
+
}
|
|
1050
1047
|
if (desc.Crop)
|
|
1051
1048
|
target.placedLayer.crop = desc.Crop;
|
|
1052
1049
|
if (desc.comp)
|
|
@@ -1055,7 +1052,7 @@ addHandler('SoLd', hasKey('placedLayer'), function (reader, target, left) {
|
|
|
1055
1052
|
target.placedLayer.compInfo = desc.compInfo;
|
|
1056
1053
|
psdReader_1.skipBytes(reader, left()); // HACK
|
|
1057
1054
|
}, function (writer, target) {
|
|
1058
|
-
var _a;
|
|
1055
|
+
var _a, _b;
|
|
1059
1056
|
psdWriter_1.writeSignature(writer, 'soLD');
|
|
1060
1057
|
psdWriter_1.writeInt32(writer, 4); // version
|
|
1061
1058
|
var placed = target.placedLayer;
|
|
@@ -1065,7 +1062,7 @@ addHandler('SoLd', hasKey('placedLayer'), function (reader, target, left) {
|
|
|
1065
1062
|
}, duration: {
|
|
1066
1063
|
numerator: 0,
|
|
1067
1064
|
denominator: 600
|
|
1068
|
-
}, frameCount: 1, Annt: 16, Type: placedLayerTypes.indexOf(placed.type), Trnf: placed.transform, nonAffineTransform: placed.transform, quiltWarp: {}, warp: encodeWarp(placed.warp || {}), 'Sz ': {
|
|
1065
|
+
}, frameCount: 1, Annt: 16, Type: placedLayerTypes.indexOf(placed.type), Trnf: placed.transform, nonAffineTransform: (_b = placed.nonAffineTransform) !== null && _b !== void 0 ? _b : placed.transform, quiltWarp: {}, warp: encodeWarp(placed.warp || {}), 'Sz ': {
|
|
1069
1066
|
Wdth: placed.width || 0,
|
|
1070
1067
|
Hght: placed.height || 0, // TODO: find size ?
|
|
1071
1068
|
}, Rslt: placed.resolution ? descriptor_1.unitsValue(placed.resolution, 'resolution') : { units: 'Density', value: 72 } });
|
|
@@ -2299,6 +2296,20 @@ addHandler('extn', function (target) { return target._extn !== undefined; }, fun
|
|
|
2299
2296
|
if (helpers_1.MOCK_HANDLERS)
|
|
2300
2297
|
descriptor_1.writeVersionAndDescriptor(writer, '', 'null', target._extn);
|
|
2301
2298
|
});
|
|
2299
|
+
addHandler('iOpa', hasKey('fillOpacity'), function (reader, target) {
|
|
2300
|
+
target.fillOpacity = psdReader_1.readUint8(reader) / 0xff;
|
|
2301
|
+
psdReader_1.skipBytes(reader, 3);
|
|
2302
|
+
}, function (writer, target) {
|
|
2303
|
+
psdWriter_1.writeUint8(writer, target.fillOpacity * 0xff);
|
|
2304
|
+
psdWriter_1.writeZeros(writer, 3);
|
|
2305
|
+
});
|
|
2306
|
+
addHandler('tsly', hasKey('transparencyShapesLayer'), function (reader, target) {
|
|
2307
|
+
target.transparencyShapesLayer = !!psdReader_1.readUint8(reader);
|
|
2308
|
+
psdReader_1.skipBytes(reader, 3);
|
|
2309
|
+
}, function (writer, target) {
|
|
2310
|
+
psdWriter_1.writeUint8(writer, target.transparencyShapesLayer ? 1 : 0);
|
|
2311
|
+
psdWriter_1.writeZeros(writer, 3);
|
|
2312
|
+
});
|
|
2302
2313
|
// descriptor helpers
|
|
2303
2314
|
function parseGradient(grad) {
|
|
2304
2315
|
if (grad.GrdF === 'GrdF.CstS') {
|
|
@@ -3573,6 +3584,10 @@ exports.BlnM = helpers_1.createEnum('BlnM', 'normal', {
|
|
|
3573
3584
|
'saturation': 'Strt',
|
|
3574
3585
|
'color': 'Clr ',
|
|
3575
3586
|
'luminosity': 'Lmns',
|
|
3587
|
+
// used in ABR
|
|
3588
|
+
'linear height': 'linearHeight',
|
|
3589
|
+
'height': 'Hght',
|
|
3590
|
+
'subtraction': 'Sbtr', // 2nd version of subtract ?
|
|
3576
3591
|
});
|
|
3577
3592
|
exports.BESl = helpers_1.createEnum('BESl', 'inner bevel', {
|
|
3578
3593
|
'inner bevel': 'InrB',
|
|
@@ -4100,7 +4115,7 @@ var floatKeys = [
|
|
|
4100
4115
|
'Axis', 'XY', 'Zone', 'WordSpacing', 'FirstLineIndent', 'GlyphSpacing', 'StartIndent', 'EndIndent', 'SpaceBefore',
|
|
4101
4116
|
'SpaceAfter', 'LetterSpacing', 'Values', 'GridSize', 'GridLeading', 'PointBase', 'BoxBounds', 'TransformPoint0', 'TransformPoint1',
|
|
4102
4117
|
'TransformPoint2', 'FontSize', 'Leading', 'HorizontalScale', 'VerticalScale', 'BaselineShift', 'Tsume',
|
|
4103
|
-
'OutlineWidth',
|
|
4118
|
+
'OutlineWidth', 'AutoLeading',
|
|
4104
4119
|
];
|
|
4105
4120
|
var intArrays = ['RunLengthArray'];
|
|
4106
4121
|
// TODO: handle /nil
|
|
@@ -4362,9 +4377,10 @@ var MaskParams;
|
|
|
4362
4377
|
})(MaskParams = exports.MaskParams || (exports.MaskParams = {}));
|
|
4363
4378
|
var ChannelID;
|
|
4364
4379
|
(function (ChannelID) {
|
|
4365
|
-
ChannelID[ChannelID["
|
|
4366
|
-
ChannelID[ChannelID["
|
|
4367
|
-
ChannelID[ChannelID["
|
|
4380
|
+
ChannelID[ChannelID["Color0"] = 0] = "Color0";
|
|
4381
|
+
ChannelID[ChannelID["Color1"] = 1] = "Color1";
|
|
4382
|
+
ChannelID[ChannelID["Color2"] = 2] = "Color2";
|
|
4383
|
+
ChannelID[ChannelID["Color3"] = 3] = "Color3";
|
|
4368
4384
|
ChannelID[ChannelID["Transparency"] = -1] = "Transparency";
|
|
4369
4385
|
ChannelID[ChannelID["UserMask"] = -2] = "UserMask";
|
|
4370
4386
|
ChannelID[ChannelID["RealUserMask"] = -3] = "RealUserMask";
|
|
@@ -4376,12 +4392,13 @@ var Compression;
|
|
|
4376
4392
|
Compression[Compression["ZipWithoutPrediction"] = 2] = "ZipWithoutPrediction";
|
|
4377
4393
|
Compression[Compression["ZipWithPrediction"] = 3] = "ZipWithPrediction";
|
|
4378
4394
|
})(Compression = exports.Compression || (exports.Compression = {}));
|
|
4379
|
-
function offsetForChannel(channelId) {
|
|
4395
|
+
function offsetForChannel(channelId, cmyk) {
|
|
4380
4396
|
switch (channelId) {
|
|
4381
|
-
case 0 /*
|
|
4382
|
-
case 1 /*
|
|
4383
|
-
case 2 /*
|
|
4384
|
-
case
|
|
4397
|
+
case 0 /* Color0 */: return 0;
|
|
4398
|
+
case 1 /* Color1 */: return 1;
|
|
4399
|
+
case 2 /* Color2 */: return 2;
|
|
4400
|
+
case 3 /* Color3 */: return cmyk ? 3 : channelId + 1;
|
|
4401
|
+
case -1 /* Transparency */: return cmyk ? 4 : 3;
|
|
4385
4402
|
default: return channelId + 1;
|
|
4386
4403
|
}
|
|
4387
4404
|
}
|
|
@@ -4401,9 +4418,9 @@ function hasAlpha(data) {
|
|
|
4401
4418
|
}
|
|
4402
4419
|
exports.hasAlpha = hasAlpha;
|
|
4403
4420
|
function resetImageData(_a) {
|
|
4404
|
-
var
|
|
4405
|
-
var size = (width * height) | 0;
|
|
4421
|
+
var data = _a.data;
|
|
4406
4422
|
var buffer = new Uint32Array(data.buffer);
|
|
4423
|
+
var size = buffer.length | 0;
|
|
4407
4424
|
for (var p = 0; p < size; p = (p + 1) | 0) {
|
|
4408
4425
|
buffer[p] = 0xff000000;
|
|
4409
4426
|
}
|
|
@@ -4981,6 +4998,8 @@ addHandler(1036, function (target) { return target.thumbnail !== undefined || ta
|
|
|
4981
4998
|
data = target.thumbnailRaw.data;
|
|
4982
4999
|
}
|
|
4983
5000
|
else {
|
|
5001
|
+
if (!target.thumbnail)
|
|
5002
|
+
throw new Error('Missing thumbnail');
|
|
4984
5003
|
width = target.thumbnail.width;
|
|
4985
5004
|
height = target.thumbnail.height;
|
|
4986
5005
|
data = base64_js_1.toByteArray(target.thumbnail.toDataURL('image/jpeg', 1).substr('data:image/jpeg;base64,'.length));
|
|
@@ -5472,6 +5491,9 @@ function readPsd(reader, options) {
|
|
|
5472
5491
|
if (!skipComposite) {
|
|
5473
5492
|
readImageData(reader, psd, globalAlpha, opt);
|
|
5474
5493
|
}
|
|
5494
|
+
// TODO: show converted color mode instead of original PSD file color mode
|
|
5495
|
+
// but add option to preserve file color mode (need to return image data instead of canvas in that case)
|
|
5496
|
+
// psd.colorMode = ColorMode.RGB; // we convert all color modes to RGB
|
|
5475
5497
|
return psd;
|
|
5476
5498
|
}
|
|
5477
5499
|
exports.readPsd = readPsd;
|
|
@@ -5510,10 +5532,10 @@ function readLayerInfo(reader, psd, options) {
|
|
|
5510
5532
|
}
|
|
5511
5533
|
else if (type === 3 /* BoundingSectionDivider */) {
|
|
5512
5534
|
stack.pop();
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
// sometimes layer group terminator doesn't have sectionDivider, so we just guess here (PS bug ?)
|
|
5516
|
-
stack.pop();
|
|
5535
|
+
// this was workaround because I didn't know what `lsdk` section was, now it's probably not needed anymore
|
|
5536
|
+
// } else if (l.name === '</Layer group>' && !l.sectionDivider && !l.top && !l.left && !l.bottom && !l.right) {
|
|
5537
|
+
// // sometimes layer group terminator doesn't have sectionDivider, so we just guess here (PS bug ?)
|
|
5538
|
+
// stack.pop();
|
|
5517
5539
|
}
|
|
5518
5540
|
else {
|
|
5519
5541
|
stack[stack.length - 1].children.unshift(l);
|
|
@@ -5621,14 +5643,21 @@ function readLayerBlendingRanges(reader) {
|
|
|
5621
5643
|
function readLayerChannelImageData(reader, psd, layer, channels, options) {
|
|
5622
5644
|
var layerWidth = (layer.right || 0) - (layer.left || 0);
|
|
5623
5645
|
var layerHeight = (layer.bottom || 0) - (layer.top || 0);
|
|
5646
|
+
var cmyk = psd.colorMode === 4 /* CMYK */;
|
|
5624
5647
|
var imageData;
|
|
5625
5648
|
if (layerWidth && layerHeight) {
|
|
5626
|
-
|
|
5627
|
-
|
|
5649
|
+
if (cmyk) {
|
|
5650
|
+
imageData = { width: layerWidth, height: layerHeight, data: new Uint8ClampedArray(layerWidth * layerHeight * 5) };
|
|
5651
|
+
for (var p = 4; p < imageData.data.byteLength; p += 5)
|
|
5652
|
+
imageData.data[p] = 255;
|
|
5653
|
+
}
|
|
5654
|
+
else {
|
|
5655
|
+
imageData = helpers_1.createImageData(layerWidth, layerHeight);
|
|
5656
|
+
helpers_1.resetImageData(imageData);
|
|
5657
|
+
}
|
|
5628
5658
|
}
|
|
5629
|
-
if (helpers_1.RAW_IMAGE_DATA)
|
|
5659
|
+
if (helpers_1.RAW_IMAGE_DATA)
|
|
5630
5660
|
layer.imageDataRaw = [];
|
|
5631
|
-
}
|
|
5632
5661
|
for (var _i = 0, channels_1 = channels; _i < channels_1.length; _i++) {
|
|
5633
5662
|
var channel = channels_1[_i];
|
|
5634
5663
|
var compression = readUint16(reader);
|
|
@@ -5642,7 +5671,7 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
|
|
|
5642
5671
|
var maskData = helpers_1.createImageData(maskWidth, maskHeight);
|
|
5643
5672
|
helpers_1.resetImageData(maskData);
|
|
5644
5673
|
var start = reader.offset;
|
|
5645
|
-
readData(reader, maskData, compression, maskWidth, maskHeight, 0, options.large);
|
|
5674
|
+
readData(reader, maskData, compression, maskWidth, maskHeight, 0, options.large, 4);
|
|
5646
5675
|
if (helpers_1.RAW_IMAGE_DATA) {
|
|
5647
5676
|
layer.maskDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
5648
5677
|
}
|
|
@@ -5657,7 +5686,7 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
|
|
|
5657
5686
|
}
|
|
5658
5687
|
}
|
|
5659
5688
|
else {
|
|
5660
|
-
var offset = helpers_1.offsetForChannel(channel.id);
|
|
5689
|
+
var offset = helpers_1.offsetForChannel(channel.id, cmyk);
|
|
5661
5690
|
var targetData = imageData;
|
|
5662
5691
|
if (offset < 0) {
|
|
5663
5692
|
targetData = undefined;
|
|
@@ -5666,7 +5695,7 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
|
|
|
5666
5695
|
}
|
|
5667
5696
|
}
|
|
5668
5697
|
var start = reader.offset;
|
|
5669
|
-
readData(reader, targetData, compression, layerWidth, layerHeight, offset, options.large);
|
|
5698
|
+
readData(reader, targetData, compression, layerWidth, layerHeight, offset, options.large, cmyk ? 5 : 4);
|
|
5670
5699
|
if (helpers_1.RAW_IMAGE_DATA) {
|
|
5671
5700
|
layer.imageDataRaw[channel.id] = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
5672
5701
|
}
|
|
@@ -5676,6 +5705,11 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
|
|
|
5676
5705
|
}
|
|
5677
5706
|
}
|
|
5678
5707
|
if (imageData) {
|
|
5708
|
+
if (cmyk) {
|
|
5709
|
+
var cmykData = imageData;
|
|
5710
|
+
imageData = helpers_1.createImageData(cmykData.width, cmykData.height);
|
|
5711
|
+
cmykToRgb(cmykData, imageData, false);
|
|
5712
|
+
}
|
|
5679
5713
|
if (options.useImageData) {
|
|
5680
5714
|
layer.imageData = imageData;
|
|
5681
5715
|
}
|
|
@@ -5685,12 +5719,12 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
|
|
|
5685
5719
|
}
|
|
5686
5720
|
}
|
|
5687
5721
|
}
|
|
5688
|
-
function readData(reader, data, compression, width, height, offset, large) {
|
|
5722
|
+
function readData(reader, data, compression, width, height, offset, large, step) {
|
|
5689
5723
|
if (compression === 0 /* RawData */) {
|
|
5690
|
-
readDataRaw(reader, data, offset, width, height);
|
|
5724
|
+
readDataRaw(reader, data, offset, width, height, step);
|
|
5691
5725
|
}
|
|
5692
5726
|
else if (compression === 1 /* RleCompressed */) {
|
|
5693
|
-
readDataRLE(reader, data, width, height,
|
|
5727
|
+
readDataRLE(reader, data, width, height, step, [offset], large);
|
|
5694
5728
|
}
|
|
5695
5729
|
else {
|
|
5696
5730
|
throw new Error("Compression type not supported: " + compression);
|
|
@@ -5734,7 +5768,7 @@ function readAdditionalLayerInfo(reader, target, psd, options) {
|
|
|
5734
5768
|
skipBytes(reader, left());
|
|
5735
5769
|
}
|
|
5736
5770
|
if (left()) {
|
|
5737
|
-
options.logMissingFeatures && console.log("Unread " + left() + " bytes left for
|
|
5771
|
+
options.logMissingFeatures && console.log("Unread " + left() + " bytes left for additional info: " + key);
|
|
5738
5772
|
skipBytes(reader, left());
|
|
5739
5773
|
}
|
|
5740
5774
|
}, false, u64);
|
|
@@ -5747,46 +5781,78 @@ function readImageData(reader, psd, globalAlpha, options) {
|
|
|
5747
5781
|
throw new Error("Compression type not supported: " + compression);
|
|
5748
5782
|
var imageData = helpers_1.createImageData(psd.width, psd.height);
|
|
5749
5783
|
helpers_1.resetImageData(imageData);
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
else if (compression === 1 /* RleCompressed */) {
|
|
5756
|
-
bytes = new Uint8Array(psd.width * psd.height);
|
|
5757
|
-
readDataRLE(reader, { data: bytes, width: psd.width, height: psd.height }, psd.width, psd.height, 1, [0], options.large);
|
|
5758
|
-
}
|
|
5759
|
-
else {
|
|
5760
|
-
throw new Error("Bitmap compression not supported: " + compression);
|
|
5761
|
-
}
|
|
5762
|
-
helpers_1.decodeBitmap(bytes, imageData.data, psd.width, psd.height);
|
|
5763
|
-
}
|
|
5764
|
-
else {
|
|
5765
|
-
var channels = psd.colorMode === 1 /* Grayscale */ ? [0] : [0, 1, 2];
|
|
5766
|
-
if (psd.channels && psd.channels > 3) {
|
|
5767
|
-
for (var i = 3; i < psd.channels; i++) {
|
|
5768
|
-
// TODO: store these channels in additional image data
|
|
5769
|
-
channels.push(i);
|
|
5784
|
+
switch (psd.colorMode) {
|
|
5785
|
+
case 0 /* Bitmap */: {
|
|
5786
|
+
var bytes = void 0;
|
|
5787
|
+
if (compression === 0 /* RawData */) {
|
|
5788
|
+
bytes = readBytes(reader, Math.ceil(psd.width / 8) * psd.height);
|
|
5770
5789
|
}
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
readDataRaw(reader, imageData, channels[i], psd.width, psd.height);
|
|
5790
|
+
else if (compression === 1 /* RleCompressed */) {
|
|
5791
|
+
bytes = new Uint8Array(psd.width * psd.height);
|
|
5792
|
+
readDataRLE(reader, { data: bytes, width: psd.width, height: psd.height }, psd.width, psd.height, 1, [0], options.large);
|
|
5793
|
+
}
|
|
5794
|
+
else {
|
|
5795
|
+
throw new Error("Bitmap compression not supported: " + compression);
|
|
5778
5796
|
}
|
|
5797
|
+
helpers_1.decodeBitmap(bytes, imageData.data, psd.width, psd.height);
|
|
5798
|
+
break;
|
|
5779
5799
|
}
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
if (
|
|
5784
|
-
|
|
5800
|
+
case 3 /* RGB */:
|
|
5801
|
+
case 1 /* Grayscale */: {
|
|
5802
|
+
var channels = psd.colorMode === 1 /* Grayscale */ ? [0] : [0, 1, 2];
|
|
5803
|
+
if (psd.channels && psd.channels > 3) {
|
|
5804
|
+
for (var i = 3; i < psd.channels; i++) {
|
|
5805
|
+
// TODO: store these channels in additional image data
|
|
5806
|
+
channels.push(i);
|
|
5807
|
+
}
|
|
5808
|
+
}
|
|
5809
|
+
else if (globalAlpha) {
|
|
5810
|
+
channels.push(3);
|
|
5811
|
+
}
|
|
5812
|
+
if (compression === 0 /* RawData */) {
|
|
5813
|
+
for (var i = 0; i < channels.length; i++) {
|
|
5814
|
+
readDataRaw(reader, imageData, channels[i], psd.width, psd.height, 4);
|
|
5815
|
+
}
|
|
5785
5816
|
}
|
|
5817
|
+
else if (compression === 1 /* RleCompressed */) {
|
|
5818
|
+
var start = reader.offset;
|
|
5819
|
+
readDataRLE(reader, imageData, psd.width, psd.height, 4, channels, options.large);
|
|
5820
|
+
if (helpers_1.RAW_IMAGE_DATA)
|
|
5821
|
+
psd.imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
5822
|
+
}
|
|
5823
|
+
if (psd.colorMode === 1 /* Grayscale */) {
|
|
5824
|
+
setupGrayscale(imageData);
|
|
5825
|
+
}
|
|
5826
|
+
break;
|
|
5786
5827
|
}
|
|
5787
|
-
|
|
5788
|
-
|
|
5828
|
+
case 4 /* CMYK */: {
|
|
5829
|
+
if (psd.channels !== 4)
|
|
5830
|
+
throw new Error("Invalid channel count");
|
|
5831
|
+
var channels = [0, 1, 2, 3];
|
|
5832
|
+
if (globalAlpha)
|
|
5833
|
+
channels.push(4);
|
|
5834
|
+
if (compression === 0 /* RawData */) {
|
|
5835
|
+
throw new Error("Not implemented");
|
|
5836
|
+
// TODO: ...
|
|
5837
|
+
// for (let i = 0; i < channels.length; i++) {
|
|
5838
|
+
// readDataRaw(reader, imageData, channels[i], psd.width, psd.height);
|
|
5839
|
+
// }
|
|
5840
|
+
}
|
|
5841
|
+
else if (compression === 1 /* RleCompressed */) {
|
|
5842
|
+
var cmykImageData = {
|
|
5843
|
+
width: imageData.width,
|
|
5844
|
+
height: imageData.height,
|
|
5845
|
+
data: new Uint8Array(imageData.width * imageData.height * 5),
|
|
5846
|
+
};
|
|
5847
|
+
var start = reader.offset;
|
|
5848
|
+
readDataRLE(reader, cmykImageData, psd.width, psd.height, 5, channels, options.large);
|
|
5849
|
+
cmykToRgb(cmykImageData, imageData, true);
|
|
5850
|
+
if (helpers_1.RAW_IMAGE_DATA)
|
|
5851
|
+
psd.imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
5852
|
+
}
|
|
5853
|
+
break;
|
|
5789
5854
|
}
|
|
5855
|
+
default: throw new Error("Color mode not supported: " + psd.colorMode);
|
|
5790
5856
|
}
|
|
5791
5857
|
if (options.useImageData) {
|
|
5792
5858
|
psd.imageData = imageData;
|
|
@@ -5796,12 +5862,37 @@ function readImageData(reader, psd, globalAlpha, options) {
|
|
|
5796
5862
|
psd.canvas.getContext('2d').putImageData(imageData, 0, 0);
|
|
5797
5863
|
}
|
|
5798
5864
|
}
|
|
5799
|
-
function
|
|
5865
|
+
function cmykToRgb(cmyk, rgb, reverseAlpha) {
|
|
5866
|
+
var size = rgb.width * rgb.height * 4;
|
|
5867
|
+
var srcData = cmyk.data;
|
|
5868
|
+
var dstData = rgb.data;
|
|
5869
|
+
for (var src = 0, dst = 0; dst < size; src += 5, dst += 4) {
|
|
5870
|
+
var c = srcData[src];
|
|
5871
|
+
var m = srcData[src + 1];
|
|
5872
|
+
var y = srcData[src + 2];
|
|
5873
|
+
var k = srcData[src + 3];
|
|
5874
|
+
dstData[dst] = ((((c * k) | 0) / 255) | 0);
|
|
5875
|
+
dstData[dst + 1] = ((((m * k) | 0) / 255) | 0);
|
|
5876
|
+
dstData[dst + 2] = ((((y * k) | 0) / 255) | 0);
|
|
5877
|
+
dstData[dst + 3] = reverseAlpha ? 255 - srcData[src + 4] : srcData[src + 4];
|
|
5878
|
+
}
|
|
5879
|
+
// for (let src = 0, dst = 0; dst < size; src += 5, dst += 4) {
|
|
5880
|
+
// const c = 1 - (srcData[src + 0] / 255);
|
|
5881
|
+
// const m = 1 - (srcData[src + 1] / 255);
|
|
5882
|
+
// const y = 1 - (srcData[src + 2] / 255);
|
|
5883
|
+
// // const k = srcData[src + 3] / 255;
|
|
5884
|
+
// dstData[dst + 0] = ((1 - c * 0.8) * 255) | 0;
|
|
5885
|
+
// dstData[dst + 1] = ((1 - m * 0.8) * 255) | 0;
|
|
5886
|
+
// dstData[dst + 2] = ((1 - y * 0.8) * 255) | 0;
|
|
5887
|
+
// dstData[dst + 3] = reverseAlpha ? 255 - srcData[src + 4] : srcData[src + 4];
|
|
5888
|
+
// }
|
|
5889
|
+
}
|
|
5890
|
+
function readDataRaw(reader, pixelData, offset, width, height, step) {
|
|
5800
5891
|
var size = width * height;
|
|
5801
5892
|
var buffer = readBytes(reader, size);
|
|
5802
|
-
if (pixelData && offset <
|
|
5893
|
+
if (pixelData && offset < step) {
|
|
5803
5894
|
var data = pixelData.data;
|
|
5804
|
-
for (var i = 0, p = offset | 0; i < size; i++, p = (p +
|
|
5895
|
+
for (var i = 0, p = offset | 0; i < size; i++, p = (p + step) | 0) {
|
|
5805
5896
|
data[p] = buffer[i];
|
|
5806
5897
|
}
|
|
5807
5898
|
}
|
|
@@ -5825,9 +5916,10 @@ function readDataRLE(reader, pixelData, _width, height, step, offsets, large) {
|
|
|
5825
5916
|
}
|
|
5826
5917
|
}
|
|
5827
5918
|
}
|
|
5919
|
+
var extraLimit = (step - 1) | 0; // 3 for rgb, 4 for cmyk
|
|
5828
5920
|
for (var c = 0, li = 0; c < offsets.length; c++) {
|
|
5829
5921
|
var offset = offsets[c] | 0;
|
|
5830
|
-
var extra = c >
|
|
5922
|
+
var extra = c > extraLimit || offset > extraLimit;
|
|
5831
5923
|
if (!data || extra) {
|
|
5832
5924
|
for (var y = 0; y < height; y++, li++) {
|
|
5833
5925
|
skipBytes(reader, lengths[li]);
|
|
@@ -5940,11 +6032,22 @@ function readPattern(reader) {
|
|
|
5940
6032
|
var x = readInt16(reader);
|
|
5941
6033
|
var y = readInt16(reader);
|
|
5942
6034
|
// we only support RGB and grayscale for now
|
|
5943
|
-
if (colorMode !== 3 /* RGB */ && colorMode !== 1 /* Grayscale */)
|
|
5944
|
-
throw new Error(
|
|
6035
|
+
if (colorMode !== 3 /* RGB */ && colorMode !== 1 /* Grayscale */ && colorMode !== 2 /* Indexed */) {
|
|
6036
|
+
throw new Error("Unsupported pattern color mode: " + colorMode);
|
|
6037
|
+
}
|
|
5945
6038
|
var name = readUnicodeString(reader);
|
|
5946
6039
|
var id = readPascalString(reader, 1);
|
|
5947
|
-
|
|
6040
|
+
var palette = [];
|
|
6041
|
+
if (colorMode === 2 /* Indexed */) {
|
|
6042
|
+
for (var i = 0; i < 256; i++) {
|
|
6043
|
+
palette.push({
|
|
6044
|
+
r: readUint8(reader),
|
|
6045
|
+
g: readUint8(reader),
|
|
6046
|
+
b: readUint8(reader),
|
|
6047
|
+
});
|
|
6048
|
+
}
|
|
6049
|
+
skipBytes(reader, 4); // no idea what this is
|
|
6050
|
+
}
|
|
5948
6051
|
// virtual memory array list
|
|
5949
6052
|
var version2 = readUint32(reader);
|
|
5950
6053
|
if (version2 !== 3)
|
|
@@ -5963,60 +6066,67 @@ function readPattern(reader) {
|
|
|
5963
6066
|
}
|
|
5964
6067
|
for (var i = 0, ch = 0; i < (channelsCount + 2); i++) {
|
|
5965
6068
|
var has = readUint32(reader);
|
|
5966
|
-
if (has)
|
|
5967
|
-
|
|
5968
|
-
|
|
5969
|
-
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
|
|
5973
|
-
|
|
5974
|
-
|
|
5975
|
-
|
|
5976
|
-
|
|
5977
|
-
|
|
5978
|
-
|
|
5979
|
-
|
|
5980
|
-
|
|
5981
|
-
|
|
5982
|
-
|
|
5983
|
-
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
5989
|
-
|
|
5990
|
-
|
|
6069
|
+
if (!has)
|
|
6070
|
+
continue;
|
|
6071
|
+
var length_2 = readUint32(reader);
|
|
6072
|
+
var pixelDepth = readUint32(reader);
|
|
6073
|
+
var ctop = readUint32(reader);
|
|
6074
|
+
var cleft = readUint32(reader);
|
|
6075
|
+
var cbottom = readUint32(reader);
|
|
6076
|
+
var cright = readUint32(reader);
|
|
6077
|
+
var pixelDepth2 = readUint16(reader);
|
|
6078
|
+
var compressionMode = readUint8(reader); // 0 - raw, 1 - zip
|
|
6079
|
+
var dataLength = length_2 - (4 + 16 + 2 + 1);
|
|
6080
|
+
var cdata = readBytes(reader, dataLength);
|
|
6081
|
+
if (pixelDepth !== 8 || pixelDepth2 !== 8) {
|
|
6082
|
+
throw new Error('16bit pixel depth not supported for patterns');
|
|
6083
|
+
}
|
|
6084
|
+
var w = cright - cleft;
|
|
6085
|
+
var h = cbottom - ctop;
|
|
6086
|
+
var ox = cleft - left;
|
|
6087
|
+
var oy = ctop - top;
|
|
6088
|
+
if (compressionMode === 0) {
|
|
6089
|
+
if (colorMode === 3 /* RGB */ && ch < 3) {
|
|
6090
|
+
for (var y_1 = 0; y_1 < h; y_1++) {
|
|
6091
|
+
for (var x_1 = 0; x_1 < w; x_1++) {
|
|
6092
|
+
var src = x_1 + y_1 * w;
|
|
6093
|
+
var dst = (ox + x_1 + (y_1 + oy) * width) * 4;
|
|
6094
|
+
data[dst + ch] = cdata[src];
|
|
5991
6095
|
}
|
|
5992
6096
|
}
|
|
5993
|
-
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6097
|
+
}
|
|
6098
|
+
if (colorMode === 1 /* Grayscale */ && ch < 1) {
|
|
6099
|
+
for (var y_2 = 0; y_2 < h; y_2++) {
|
|
6100
|
+
for (var x_2 = 0; x_2 < w; x_2++) {
|
|
6101
|
+
var src = x_2 + y_2 * w;
|
|
6102
|
+
var dst = (ox + x_2 + (y_2 + oy) * width) * 4;
|
|
6103
|
+
var value = cdata[src];
|
|
6104
|
+
data[dst + 0] = value;
|
|
6105
|
+
data[dst + 1] = value;
|
|
6106
|
+
data[dst + 2] = value;
|
|
6003
6107
|
}
|
|
6004
6108
|
}
|
|
6005
6109
|
}
|
|
6006
|
-
|
|
6007
|
-
//
|
|
6008
|
-
|
|
6009
|
-
// const data = require('zlib').inflateRawSync(cdata);
|
|
6010
|
-
// const data = require('zlib').unzipSync(cdata);
|
|
6011
|
-
// console.log(data);
|
|
6012
|
-
// throw new Error('Zip compression not supported for palettes');
|
|
6013
|
-
throw new Error('Unsupported palette compression mode');
|
|
6014
|
-
}
|
|
6015
|
-
else {
|
|
6016
|
-
throw new Error('Invalid palette compression mode');
|
|
6110
|
+
if (colorMode === 2 /* Indexed */) {
|
|
6111
|
+
// TODO:
|
|
6112
|
+
throw new Error('Indexed pattern color mode not implemented');
|
|
6017
6113
|
}
|
|
6018
|
-
ch++;
|
|
6019
6114
|
}
|
|
6115
|
+
else if (compressionMode === 1) {
|
|
6116
|
+
// console.log({ colorMode });
|
|
6117
|
+
// require('fs').writeFileSync('zip.bin', Buffer.from(cdata));
|
|
6118
|
+
// const data = require('zlib').inflateRawSync(cdata);
|
|
6119
|
+
// const data = require('zlib').unzipSync(cdata);
|
|
6120
|
+
// console.log(data);
|
|
6121
|
+
// throw new Error('Zip compression not supported for pattern');
|
|
6122
|
+
// throw new Error('Unsupported pattern compression');
|
|
6123
|
+
console.error('Unsupported pattern compression');
|
|
6124
|
+
name += ' (failed to decode)';
|
|
6125
|
+
}
|
|
6126
|
+
else {
|
|
6127
|
+
throw new Error('Invalid pattern compression mode');
|
|
6128
|
+
}
|
|
6129
|
+
ch++;
|
|
6020
6130
|
}
|
|
6021
6131
|
// TODO: use canvas instead of data ?
|
|
6022
6132
|
return { id: id, name: name, x: x, y: y, bounds: { x: left, y: top, w: width, h: height }, data: data };
|
|
@@ -6216,7 +6326,7 @@ function writePsd(writer, psd, options) {
|
|
|
6216
6326
|
writeUint32(writer, psd.height);
|
|
6217
6327
|
writeUint32(writer, psd.width);
|
|
6218
6328
|
writeUint16(writer, 8); // bits per channel
|
|
6219
|
-
writeUint16(writer, 3 /* RGB */);
|
|
6329
|
+
writeUint16(writer, 3 /* RGB */); // we only support saving RGB right now
|
|
6220
6330
|
// color mode data
|
|
6221
6331
|
writeSection(writer, 1, function () {
|
|
6222
6332
|
// TODO: implement
|
|
@@ -6564,9 +6674,9 @@ function getLayerChannels(tempBuffer, layer, background, options) {
|
|
|
6564
6674
|
var _b = layer.top, top = _b === void 0 ? 0 : _b, _c = layer.left, left = _c === void 0 ? 0 : _c, _d = layer.right, right = _d === void 0 ? 0 : _d, _e = layer.bottom, bottom = _e === void 0 ? 0 : _e;
|
|
6565
6675
|
var channels = [
|
|
6566
6676
|
{ channelId: -1 /* Transparency */, compression: 0 /* RawData */, buffer: undefined, length: 2 },
|
|
6567
|
-
{ channelId: 0 /*
|
|
6568
|
-
{ channelId: 1 /*
|
|
6569
|
-
{ channelId: 2 /*
|
|
6677
|
+
{ channelId: 0 /* Color0 */, compression: 0 /* RawData */, buffer: undefined, length: 2 },
|
|
6678
|
+
{ channelId: 1 /* Color1 */, compression: 0 /* RawData */, buffer: undefined, length: 2 },
|
|
6679
|
+
{ channelId: 2 /* Color2 */, compression: 0 /* RawData */, buffer: undefined, length: 2 },
|
|
6570
6680
|
];
|
|
6571
6681
|
var _f = getLayerDimentions(layer), width = _f.width, height = _f.height;
|
|
6572
6682
|
if (!(layer.canvas || layer.imageData) || !width || !height) {
|
|
@@ -6598,15 +6708,15 @@ function getLayerChannels(tempBuffer, layer, background, options) {
|
|
|
6598
6708
|
}
|
|
6599
6709
|
}
|
|
6600
6710
|
var channelIds = [
|
|
6601
|
-
0 /*
|
|
6602
|
-
1 /*
|
|
6603
|
-
2 /*
|
|
6711
|
+
0 /* Color0 */,
|
|
6712
|
+
1 /* Color1 */,
|
|
6713
|
+
2 /* Color2 */,
|
|
6604
6714
|
];
|
|
6605
6715
|
if (!background || options.noBackground || layer.mask || helpers_1.hasAlpha(data) || (helpers_1.RAW_IMAGE_DATA && ((_a = layer.imageDataRaw) === null || _a === void 0 ? void 0 : _a['-1']))) {
|
|
6606
6716
|
channelIds.unshift(-1 /* Transparency */);
|
|
6607
6717
|
}
|
|
6608
6718
|
channels = channelIds.map(function (channel) {
|
|
6609
|
-
var offset = helpers_1.offsetForChannel(channel);
|
|
6719
|
+
var offset = helpers_1.offsetForChannel(channel, false); // TODO: psd.colorMode === ColorMode.CMYK);
|
|
6610
6720
|
var buffer = helpers_1.writeDataRLE(tempBuffer, data, width, height, [offset], !!options.psb);
|
|
6611
6721
|
if (helpers_1.RAW_IMAGE_DATA && layer.imageDataRaw) {
|
|
6612
6722
|
// console.log('written raw layer image data');
|