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/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('Unsupported ABR version');
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["Red"] = 0] = "Red";
4366
- ChannelID[ChannelID["Green"] = 1] = "Green";
4367
- ChannelID[ChannelID["Blue"] = 2] = "Blue";
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 /* Red */: return 0;
4382
- case 1 /* Green */: return 1;
4383
- case 2 /* Blue */: return 2;
4384
- case -1 /* Transparency */: return 3;
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 width = _a.width, height = _a.height, data = _a.data;
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
- else if (l.name === '</Layer group>' && !l.sectionDivider && !l.top && !l.left && !l.bottom && !l.right) {
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
- imageData = helpers_1.createImageData(layerWidth, layerHeight);
5627
- helpers_1.resetImageData(imageData);
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, 4, [offset], large);
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 tag: " + key);
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
- if (psd.colorMode === 0 /* Bitmap */) {
5751
- var bytes = void 0;
5752
- if (compression === 0 /* RawData */) {
5753
- bytes = readBytes(reader, Math.ceil(psd.width / 8) * psd.height);
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
- else if (globalAlpha) {
5773
- channels.push(3);
5774
- }
5775
- if (compression === 0 /* RawData */) {
5776
- for (var i = 0; i < channels.length; i++) {
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
- else if (compression === 1 /* RleCompressed */) {
5781
- var start = reader.offset;
5782
- readDataRLE(reader, imageData, psd.width, psd.height, 4, channels, options.large);
5783
- if (helpers_1.RAW_IMAGE_DATA) {
5784
- psd.imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
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
- if (psd.colorMode === 1 /* Grayscale */) {
5788
- setupGrayscale(imageData);
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 readDataRaw(reader, pixelData, offset, width, height) {
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 < 4) {
5893
+ if (pixelData && offset < step) {
5803
5894
  var data = pixelData.data;
5804
- for (var i = 0, p = offset | 0; i < size; i++, p = (p + 4) | 0) {
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 > 3 || offset > 3;
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('Unsupported pattern color mode');
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
- // TODO: index color table here (only for indexed color mode, not supported right now)
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
- var length_2 = readUint32(reader);
5968
- var pixelDepth = readUint32(reader);
5969
- var ctop = readUint32(reader);
5970
- var cleft = readUint32(reader);
5971
- var cbottom = readUint32(reader);
5972
- var cright = readUint32(reader);
5973
- var pixelDepth2 = readUint16(reader);
5974
- var compressionMode = readUint8(reader); // 0 - raw, 1 - zip
5975
- var dataLength = length_2 - (4 + 16 + 2 + 1);
5976
- var cdata = readBytes(reader, dataLength);
5977
- if (pixelDepth !== 8 || pixelDepth2 !== 8)
5978
- throw new Error('16bit pixel depth not supported for palettes');
5979
- var w = cright - cleft;
5980
- var h = cbottom - ctop;
5981
- var ox = cleft - left;
5982
- var oy = ctop - top;
5983
- if (compressionMode === 0) {
5984
- if (colorMode === 3 /* RGB */ && ch < 3) {
5985
- for (var y_1 = 0; y_1 < h; y_1++) {
5986
- for (var x_1 = 0; x_1 < w; x_1++) {
5987
- var src = x_1 + y_1 * w;
5988
- var dst = (ox + x_1 + (y_1 + oy) * width) * 4;
5989
- data[dst + ch] = cdata[src];
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
- if (colorMode === 1 /* Grayscale */ && ch < 1) {
5994
- for (var y_2 = 0; y_2 < h; y_2++) {
5995
- for (var x_2 = 0; x_2 < w; x_2++) {
5996
- var src = x_2 + y_2 * w;
5997
- var dst = (ox + x_2 + (y_2 + oy) * width) * 4;
5998
- var value = cdata[src];
5999
- data[dst + 0] = value;
6000
- data[dst + 1] = value;
6001
- data[dst + 2] = value;
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
- else if (compressionMode === 1) {
6007
- // console.log({ colorMode });
6008
- // require('fs').writeFileSync('zip.bin', Buffer.from(cdata));
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 /* Red */, compression: 0 /* RawData */, buffer: undefined, length: 2 },
6568
- { channelId: 1 /* Green */, compression: 0 /* RawData */, buffer: undefined, length: 2 },
6569
- { channelId: 2 /* Blue */, compression: 0 /* RawData */, buffer: undefined, length: 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 /* Red */,
6602
- 1 /* Green */,
6603
- 2 /* Blue */,
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');