ag-psd 31.0.3 → 32.0.0

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.
Files changed (138) hide show
  1. package/.v8-cache/v24.7.0-x64-ef5a0af0/00d0e0b4 +0 -0
  2. package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
  3. package/.v8-cache/v24.7.0-x64-ef5a0af0/0cc76730 +0 -0
  4. package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
  5. package/.v8-cache/v24.7.0-x64-ef5a0af0/20729831 +0 -0
  6. package/.v8-cache/v24.7.0-x64-ef5a0af0/214a593b +0 -0
  7. package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
  8. package/.v8-cache/v24.7.0-x64-ef5a0af0/25f8b84a +0 -0
  9. package/.v8-cache/v24.7.0-x64-ef5a0af0/27518289 +0 -0
  10. package/.v8-cache/v24.7.0-x64-ef5a0af0/330ef2d9 +0 -0
  11. package/.v8-cache/v24.7.0-x64-ef5a0af0/37ff16b8 +0 -0
  12. package/.v8-cache/v24.7.0-x64-ef5a0af0/3f72a97c +0 -0
  13. package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
  14. package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
  15. package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
  16. package/.v8-cache/v24.7.0-x64-ef5a0af0/75efccd4 +0 -0
  17. package/.v8-cache/v24.7.0-x64-ef5a0af0/762f9305 +0 -0
  18. package/.v8-cache/v24.7.0-x64-ef5a0af0/7bcfc50a +0 -0
  19. package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
  20. package/.v8-cache/v24.7.0-x64-ef5a0af0/825e9a05 +0 -0
  21. package/.v8-cache/v24.7.0-x64-ef5a0af0/87372817 +0 -0
  22. package/.v8-cache/v24.7.0-x64-ef5a0af0/87cf2209 +0 -0
  23. package/.v8-cache/v24.7.0-x64-ef5a0af0/891a7c73 +0 -0
  24. package/.v8-cache/v24.7.0-x64-ef5a0af0/8b68a3a2 +0 -0
  25. package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
  26. package/.v8-cache/v24.7.0-x64-ef5a0af0/a1d12a93 +0 -0
  27. package/.v8-cache/v24.7.0-x64-ef5a0af0/a7e80865 +0 -0
  28. package/.v8-cache/v24.7.0-x64-ef5a0af0/ac317c9c +0 -0
  29. package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
  30. package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
  31. package/.v8-cache/v24.7.0-x64-ef5a0af0/b8569d6b +0 -0
  32. package/.v8-cache/v24.7.0-x64-ef5a0af0/b8b073c4 +0 -0
  33. package/.v8-cache/v24.7.0-x64-ef5a0af0/bb489c89 +0 -0
  34. package/.v8-cache/v24.7.0-x64-ef5a0af0/c0b789d2 +0 -0
  35. package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
  36. package/.v8-cache/v24.7.0-x64-ef5a0af0/c46725e1 +0 -0
  37. package/.v8-cache/v24.7.0-x64-ef5a0af0/c794cb34 +0 -0
  38. package/.v8-cache/v24.7.0-x64-ef5a0af0/cd4ae980 +0 -0
  39. package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
  40. package/.v8-cache/v24.7.0-x64-ef5a0af0/cff9434a +0 -0
  41. package/.v8-cache/v24.7.0-x64-ef5a0af0/d02dd6f7 +0 -0
  42. package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
  43. package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
  44. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6735171 +0 -0
  45. package/.v8-cache/v24.7.0-x64-ef5a0af0/f5417276 +0 -0
  46. package/.v8-cache/v24.7.0-x64-ef5a0af0/f6fd8125 +0 -0
  47. package/.v8-cache/v24.7.0-x64-ef5a0af0/f74d3518 +0 -0
  48. package/.v8-cache/v24.7.0-x64-ef5a0af0/f886deac +0 -0
  49. package/.v8-cache/v24.7.0-x64-ef5a0af0/fd0a2987 +0 -0
  50. package/.v8-cache/v24.7.0-x64-ef5a0af0/fe349423 +0 -0
  51. package/CHANGELOG.md +29 -0
  52. package/dist/abr.js +12 -5
  53. package/dist/abr.js.map +1 -1
  54. package/dist/additionalInfo.d.ts +2 -0
  55. package/dist/additionalInfo.js +123 -68
  56. package/dist/additionalInfo.js.map +1 -1
  57. package/dist/bundle.js +1365 -632
  58. package/dist/descriptor.d.ts +15 -2
  59. package/dist/descriptor.js +329 -100
  60. package/dist/descriptor.js.map +1 -1
  61. package/dist/effectsHelpers.js +12 -12
  62. package/dist/effectsHelpers.js.map +1 -1
  63. package/dist/engineData.d.ts +3 -1
  64. package/dist/engineData.js +34 -13
  65. package/dist/engineData.js.map +1 -1
  66. package/dist/engineData2.js +50 -21
  67. package/dist/engineData2.js.map +1 -1
  68. package/dist/helpers.d.ts +5 -2
  69. package/dist/helpers.js +18 -4
  70. package/dist/helpers.js.map +1 -1
  71. package/dist/imageResources.js +45 -21
  72. package/dist/imageResources.js.map +1 -1
  73. package/dist/index.js +1 -0
  74. package/dist/index.js.map +1 -1
  75. package/dist/jpeg.js +27 -7
  76. package/dist/jpeg.js.map +1 -1
  77. package/dist/psd.d.ts +6 -1
  78. package/dist/psdReader.d.ts +2 -2
  79. package/dist/psdReader.js +457 -270
  80. package/dist/psdReader.js.map +1 -1
  81. package/dist/psdWriter.d.ts +2 -0
  82. package/dist/psdWriter.js +98 -76
  83. package/dist/psdWriter.js.map +1 -1
  84. package/dist/text.js +126 -23
  85. package/dist/text.js.map +1 -1
  86. package/dist/utf8.js +36 -15
  87. package/dist/utf8.js.map +1 -1
  88. package/dist-es/abr.js +12 -5
  89. package/dist-es/abr.js.map +1 -1
  90. package/dist-es/additionalInfo.d.ts +2 -0
  91. package/dist-es/additionalInfo.js +123 -68
  92. package/dist-es/additionalInfo.js.map +1 -1
  93. package/dist-es/descriptor.d.ts +15 -2
  94. package/dist-es/descriptor.js +329 -100
  95. package/dist-es/descriptor.js.map +1 -1
  96. package/dist-es/effectsHelpers.js +12 -12
  97. package/dist-es/effectsHelpers.js.map +1 -1
  98. package/dist-es/engineData.d.ts +3 -1
  99. package/dist-es/engineData.js +34 -13
  100. package/dist-es/engineData.js.map +1 -1
  101. package/dist-es/engineData2.js +50 -21
  102. package/dist-es/engineData2.js.map +1 -1
  103. package/dist-es/helpers.d.ts +5 -2
  104. package/dist-es/helpers.js +18 -4
  105. package/dist-es/helpers.js.map +1 -1
  106. package/dist-es/imageResources.js +45 -21
  107. package/dist-es/imageResources.js.map +1 -1
  108. package/dist-es/index.js +1 -0
  109. package/dist-es/index.js.map +1 -1
  110. package/dist-es/jpeg.js +27 -7
  111. package/dist-es/jpeg.js.map +1 -1
  112. package/dist-es/psd.d.ts +6 -1
  113. package/dist-es/psdReader.d.ts +2 -2
  114. package/dist-es/psdReader.js +457 -270
  115. package/dist-es/psdReader.js.map +1 -1
  116. package/dist-es/psdWriter.d.ts +2 -0
  117. package/dist-es/psdWriter.js +98 -76
  118. package/dist-es/psdWriter.js.map +1 -1
  119. package/dist-es/text.js +126 -23
  120. package/dist-es/text.js.map +1 -1
  121. package/dist-es/utf8.js +36 -15
  122. package/dist-es/utf8.js.map +1 -1
  123. package/package.json +1 -1
  124. package/src/abr.ts +14 -6
  125. package/src/additionalInfo.ts +127 -66
  126. package/src/descriptor.ts +347 -107
  127. package/src/effectsHelpers.ts +9 -9
  128. package/src/engineData.ts +36 -13
  129. package/src/engineData2.ts +468 -432
  130. package/src/helpers.ts +19 -4
  131. package/src/imageResources.ts +49 -22
  132. package/src/index.ts +1 -0
  133. package/src/jpeg.ts +24 -9
  134. package/src/psd.ts +3 -1
  135. package/src/psdReader.ts +477 -260
  136. package/src/psdWriter.ts +100 -83
  137. package/src/text.ts +122 -12
  138. package/src/utf8.ts +35 -17
@@ -32,10 +32,6 @@ function readLength64(reader) {
32
32
  throw new Error(`Resource size above 4 GB limit at ${reader.offset.toString(16)}`);
33
33
  return (0, psdReader_1.readUint32)(reader);
34
34
  }
35
- function writeLength64(writer, length) {
36
- (0, psdWriter_1.writeUint32)(writer, 0);
37
- (0, psdWriter_1.writeUint32)(writer, length);
38
- }
39
35
  addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
40
36
  if ((0, psdReader_1.readInt16)(reader) !== 1)
41
37
  throw new Error(`Invalid TySh version`);
@@ -74,7 +70,7 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
74
70
  if (text.boundingBox)
75
71
  target.text.boundingBox = (0, descriptor_1.descBoundsToBounds)(text.boundingBox);
76
72
  if (text.EngineData) {
77
- const engineData = (0, engineData_1.parseEngineData)(text.EngineData);
73
+ const engineData = (0, engineData_1.parseEngineData)(text.EngineData, reader);
78
74
  const textData = (0, text_1.decodeEngineData)(engineData);
79
75
  // console.log(require('util').inspect(engineData, false, 99, false), 'utf8');
80
76
  // require('fs').writeFileSync(`layer-${target.name}.txt`, require('util').inspect(engineData, false, 99, false), 'utf8');
@@ -88,6 +84,7 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
88
84
  }
89
85
  (0, psdReader_1.skipBytes)(reader, leftBytes());
90
86
  }, (writer, target) => {
87
+ var _a, _b, _c, _d;
91
88
  const text = target.text;
92
89
  const warp = text.warp || {};
93
90
  const transform = text.transform || [1, 0, 0, 1, 0, 0];
@@ -100,10 +97,10 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
100
97
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'TxLr', textDescriptor, 'text');
101
98
  (0, psdWriter_1.writeInt16)(writer, 1); // warp version
102
99
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'warp', encodeWarp(warp));
103
- (0, psdWriter_1.writeFloat32)(writer, text.left);
104
- (0, psdWriter_1.writeFloat32)(writer, text.top);
105
- (0, psdWriter_1.writeFloat32)(writer, text.right);
106
- (0, psdWriter_1.writeFloat32)(writer, text.bottom);
100
+ (0, psdWriter_1.writeFloat32)(writer, (_a = text.left) !== null && _a !== void 0 ? _a : 0);
101
+ (0, psdWriter_1.writeFloat32)(writer, (_b = text.top) !== null && _b !== void 0 ? _b : 0);
102
+ (0, psdWriter_1.writeFloat32)(writer, (_c = text.right) !== null && _c !== void 0 ? _c : 0);
103
+ (0, psdWriter_1.writeFloat32)(writer, (_d = text.bottom) !== null && _d !== void 0 ? _d : 0);
107
104
  // writeZeros(writer, 2);
108
105
  });
109
106
  // vector fills
@@ -419,12 +416,50 @@ addHandler('luni', hasKey('name'), (reader, target, left) => {
419
416
  // writeUint16(writer, 0); // padding (but not extending string length)
420
417
  });
421
418
  addHandler('lnsr', hasKey('nameSource'), (reader, target) => target.nameSource = (0, psdReader_1.readSignature)(reader), (writer, target) => (0, psdWriter_1.writeSignature)(writer, target.nameSource));
422
- addHandler('lyid', hasKey('id'), (reader, target) => {
419
+ // these sections reference layer id
420
+ function layerNeedsId(target) {
421
+ return !!(target.animationFrames || target.timeline || target.comps);
422
+ }
423
+ function getExplicitLayerIds(psd, options) {
424
+ if (!options.explicitLayerIds) {
425
+ const ids = new Set();
426
+ const addIds = (layers) => {
427
+ for (const layer of layers !== null && layers !== void 0 ? layers : []) {
428
+ if (layer.id !== undefined)
429
+ ids.add(layer.id);
430
+ addIds(layer.children);
431
+ }
432
+ };
433
+ addIds(psd.children);
434
+ options.explicitLayerIds = ids;
435
+ }
436
+ return options.explicitLayerIds;
437
+ }
438
+ function getLayerId(target, options) {
439
+ var _a;
440
+ const id = (_a = options.layerToId.get(target)) !== null && _a !== void 0 ? _a : target.id;
441
+ if (id === undefined)
442
+ throw new Error('Missing layer id');
443
+ return id;
444
+ }
445
+ addHandler('lyid', target => target.id !== undefined || layerNeedsId(target), (reader, target) => {
423
446
  target.id = (0, psdReader_1.readUint32)(reader);
424
- }, (writer, target, _psd, options) => {
425
- let id = target.id;
426
- while (options.layerIds.has(id))
427
- id += 100; // make sure we don't have duplicate layer ids
447
+ }, (writer, target, psd, options) => {
448
+ var _a;
449
+ let id;
450
+ if (target.id !== undefined) {
451
+ id = target.id;
452
+ while (options.layerIds.has(id))
453
+ id += 100; // make sure we don't have duplicate layer ids
454
+ }
455
+ else {
456
+ // generate id for layers that don't have it, if it's referenced by other sections
457
+ const explicitIds = getExplicitLayerIds(psd, options);
458
+ id = (_a = options.nextGeneratedLayerId) !== null && _a !== void 0 ? _a : 1;
459
+ while (options.layerIds.has(id) || explicitIds.has(id))
460
+ id++;
461
+ options.nextGeneratedLayerId = id + 1;
462
+ }
428
463
  (0, psdWriter_1.writeUint32)(writer, id);
429
464
  options.layerIds.add(id);
430
465
  options.layerToId.set(target, id);
@@ -622,9 +657,8 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
622
657
  (0, psdWriter_1.writeUint8)(writer, 0); // copy (always false)
623
658
  (0, psdWriter_1.writeZeros)(writer, 3);
624
659
  (0, psdWriter_1.writeSection)(writer, 2, () => {
625
- var _a;
626
660
  const desc = {
627
- LaID: (_a = target.id) !== null && _a !== void 0 ? _a : 0,
661
+ LaID: getLayerId(target, options),
628
662
  LaSt: [],
629
663
  };
630
664
  for (let i = 0; i < animationFrames.length; i++) {
@@ -680,10 +714,7 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
680
714
  if (timeline.tracks) {
681
715
  desc.trackList = (0, descriptor_1.serializeTrackList)(timeline.tracks);
682
716
  }
683
- const id = options.layerToId.get(target) || target.id;
684
- if (!id)
685
- throw new Error('You need to provide layer.id value whan writing document with animations');
686
- desc.LyrI = id;
717
+ desc.LyrI = getLayerId(target, options);
687
718
  // console.log('WRITE:tmln', target.name, target.id, require('util').inspect(desc, false, 99, true));
688
719
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc, 'anim');
689
720
  }, true);
@@ -706,14 +737,11 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
706
737
  (0, psdWriter_1.writeUint8)(writer, 0); // copy (always false)
707
738
  (0, psdWriter_1.writeZeros)(writer, 3);
708
739
  (0, psdWriter_1.writeSection)(writer, 2, () => {
709
- const id = options.layerToId.get(target) || target.id;
710
- if (!id)
711
- throw new Error('You need to provide layer.id value whan writing document with layer comps');
712
740
  const desc = {};
713
741
  if (comps.originalEffectsReferencePoint) {
714
742
  desc.origFXRefPoint = { Hrzn: comps.originalEffectsReferencePoint.x, Vrtc: comps.originalEffectsReferencePoint.y };
715
743
  }
716
- desc.LyrI = id;
744
+ desc.LyrI = getLayerId(target, options);
717
745
  desc.layerSettings = [];
718
746
  for (const item of comps.settings) {
719
747
  const t = {};
@@ -731,7 +759,7 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
731
759
  }, true);
732
760
  }
733
761
  });
734
- addHandler('PxSc', () => false, (reader, target) => {
762
+ addHandler('PxSc', hasKey('pixelSource'), (reader, target) => {
735
763
  const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
736
764
  // console.log('PxSc', require('util').inspect(desc, false, 99, true));
737
765
  if (desc.pixelSourceType === 1986285651) {
@@ -766,7 +794,7 @@ addHandler('PxSc', () => false, (reader, target) => {
766
794
  _classID: 'PixelSource',
767
795
  pixelSourceType: 1986285651, // vdP
768
796
  descVersion: 1,
769
- origin: { Hrzn: source.origin.x, Vrtc: source.origin.y },
797
+ origin: { Hrzn: source.origin.x, Vrtc: source.origin.y }, // written as 'null' class with 'long' values (see writeDescriptorStructure)
770
798
  interpretation: {
771
799
  _name: '',
772
800
  _classID: 'footageInterpretation',
@@ -1008,10 +1036,12 @@ addHandler('PlLd', hasKey('placedLayer'), (reader, target, left) => {
1008
1036
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', type, encodeWarp(warp), type);
1009
1037
  });
1010
1038
  function uint8ToFloat32(array) {
1011
- return new Float32Array(array.buffer.slice(array.byteOffset), 0, array.byteLength / 4);
1039
+ const length = Math.floor(array.byteLength / 4);
1040
+ return new Float32Array(array.buffer.slice(array.byteOffset, array.byteOffset + length * 4), 0, length);
1012
1041
  }
1013
1042
  function uint8ToUint32(array) {
1014
- return new Uint32Array(array.buffer.slice(array.byteOffset), 0, array.byteLength / 4);
1043
+ const length = Math.floor(array.byteLength / 4);
1044
+ return new Uint32Array(array.buffer.slice(array.byteOffset, array.byteOffset + length * 4), 0, length);
1015
1045
  }
1016
1046
  function toUint8(array) {
1017
1047
  return new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
@@ -1280,7 +1310,7 @@ function parseFilterFXItem(f, options) {
1280
1310
  { x: f.Fltr.PuX2, y: f.Fltr.PuY2, },
1281
1311
  { x: f.Fltr.PuX3, y: f.Fltr.PuY3, },
1282
1312
  ],
1283
- puppetShapeList: f.Fltr.puppetShapeList.map(p => ({
1313
+ puppetShapeList: (f.Fltr.puppetShapeList || []).map(p => ({
1284
1314
  rigidType: p.rigidType,
1285
1315
  // TODO: VrsM
1286
1316
  // TODO: VrsN
@@ -1809,7 +1839,7 @@ function serializeFilterFXItem(f) {
1809
1839
  _classID: 'rigidTransform',
1810
1840
  'null': ['Ordn.Trgt'], // TODO: ???
1811
1841
  rigidType: f.filter.rigidType,
1812
- puppetShapeList: f.filter.puppetShapeList.map(p => ({
1842
+ puppetShapeList: (f.filter.puppetShapeList || []).map(p => ({
1813
1843
  _name: '',
1814
1844
  _classID: 'puppetShape',
1815
1845
  rigidType: p.rigidType,
@@ -1894,7 +1924,7 @@ function serializeFilterFXItem(f) {
1894
1924
  _classID: 'perspectiveWarpTransform',
1895
1925
  vertices: f.filter.vertices.map(pointToHrznVrtc),
1896
1926
  warpedVertices: f.filter.warpedVertices.map(pointToHrznVrtc),
1897
- quads: f.filter.quads.map(indices => ({ indices })),
1927
+ quads: f.filter.quads.map(indices => ({ _name: '', _classID: 'quadIndices', indices })),
1898
1928
  }, filterID: 442 });
1899
1929
  case 'curves': return Object.assign(Object.assign({}, base), { Fltr: Object.assign({ _name: 'Curves', _classID: 'Crvs', presetKind: descriptor_1.presetKindType.encode(f.filter.presetKind) }, (f.filter.adjustments ? {
1900
1930
  Adjs: f.filter.adjustments.map(a => 'curve' in a ? {
@@ -1916,10 +1946,13 @@ function serializeFilterFXItem(f) {
1916
1946
  Cntr: f.filter.contrast,
1917
1947
  useLegacy: !!f.filter.useLegacy,
1918
1948
  }, filterID: 1114793795 });
1919
- // case 'hsb/hsl': return {
1920
- // TODO: ...
1921
- // };
1922
- default: throw new Error(`Unknow filter type: ${f.type}`);
1949
+ case 'hsb/hsl': return Object.assign(Object.assign({}, base), { Fltr: {
1950
+ _name: 'HSB/HSL',
1951
+ _classID: 'HsbP',
1952
+ Inpt: descriptor_1.ClrS.encode(f.filter.inputMode),
1953
+ Otpt: descriptor_1.ClrS.encode(f.filter.rowOrder),
1954
+ }, filterID: 1215521360 });
1955
+ default: throw new Error(`Unknown filter type: ${f.type}`);
1923
1956
  }
1924
1957
  }
1925
1958
  // let t: any;
@@ -2010,7 +2043,10 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
2010
2043
  if (!placed.id || typeof placed.id !== 'string' || !/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/.test(placed.id)) {
2011
2044
  throw new Error('Placed layer ID must be in a GUID format (example: 20953ddb-9391-11ec-b4f1-c15674f50bc4)');
2012
2045
  }
2013
- const desc = Object.assign(Object.assign({ Idnt: placed.id, placed: (_a = placed.placed) !== null && _a !== void 0 ? _a : placed.id, PgNm: placed.pageNumber || 1, totalPages: placed.totalPages || 1 }, (placed.crop ? { Crop: placed.crop } : {})), { frameStep: placed.frameStep || { numerator: 0, denominator: 600 }, duration: placed.duration || { numerator: 0, denominator: 600 }, frameCount: placed.frameCount || 0, Annt: 16, Type: placedLayerTypes.indexOf(placed.type), Trnf: placed.transform, nonAffineTransform: (_b = placed.nonAffineTransform) !== null && _b !== void 0 ? _b : placed.transform,
2046
+ const placedType = placedLayerTypes.indexOf(placed.type);
2047
+ if (placedType === -1)
2048
+ throw new Error('Invalid placedLayer type');
2049
+ const desc = Object.assign(Object.assign({ Idnt: placed.id, placed: (_a = placed.placed) !== null && _a !== void 0 ? _a : placed.id, PgNm: placed.pageNumber || 1, totalPages: placed.totalPages || 1 }, (placed.crop ? { Crop: placed.crop } : {})), { frameStep: placed.frameStep || { numerator: 0, denominator: 600 }, duration: placed.duration || { numerator: 0, denominator: 600 }, frameCount: placed.frameCount || 0, Annt: 16, Type: placedType, Trnf: placed.transform, nonAffineTransform: (_b = placed.nonAffineTransform) !== null && _b !== void 0 ? _b : placed.transform,
2014
2050
  // quiltWarp: {} as any,
2015
2051
  warp: encodeWarp(getWarpFromPlacedLayer(placed)), 'Sz ': {
2016
2052
  _name: '',
@@ -2088,7 +2124,7 @@ addHandler('Lr32', () => false, (reader, _target, _left, psd, imageResources) =>
2088
2124
  addHandler('LMsk', hasKey('userMask'), (reader, target) => {
2089
2125
  target.userMask = {
2090
2126
  colorSpace: (0, psdReader_1.readColor)(reader),
2091
- opacity: (0, psdReader_1.readUint16)(reader) / 0xff,
2127
+ opacity: (0, psdReader_1.readUint16)(reader) / 100,
2092
2128
  };
2093
2129
  const flag = (0, psdReader_1.readUint8)(reader);
2094
2130
  if (flag !== 128)
@@ -2097,7 +2133,7 @@ addHandler('LMsk', hasKey('userMask'), (reader, target) => {
2097
2133
  }, (writer, target) => {
2098
2134
  const userMask = target.userMask;
2099
2135
  (0, psdWriter_1.writeColor)(writer, userMask.colorSpace);
2100
- (0, psdWriter_1.writeUint16)(writer, (0, helpers_1.clamp)(userMask.opacity, 0, 1) * 0xff);
2136
+ (0, psdWriter_1.writeUint16)(writer, Math.round((0, helpers_1.clamp)(userMask.opacity, 0, 1) * 100));
2101
2137
  (0, psdWriter_1.writeUint8)(writer, 128);
2102
2138
  (0, psdWriter_1.writeZeros)(writer, 1);
2103
2139
  });
@@ -2217,7 +2253,8 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
2217
2253
  const count = (0, psdReader_1.readUint32)(reader);
2218
2254
  const annotations = [];
2219
2255
  for (let i = 0; i < count; i++) {
2220
- /*const length =*/ (0, psdReader_1.readUint32)(reader);
2256
+ const recordStart = reader.offset;
2257
+ const length = (0, psdReader_1.readUint32)(reader); // includes the length field itself
2221
2258
  const type = (0, psdReader_1.readSignature)(reader);
2222
2259
  const open = !!(0, psdReader_1.readUint8)(reader);
2223
2260
  /*const flags =*/ (0, psdReader_1.readUint8)(reader); // always 28
@@ -2233,11 +2270,12 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
2233
2270
  const dataLength = (0, psdReader_1.readUint32)(reader);
2234
2271
  let data;
2235
2272
  if (type === 'txtA') {
2273
+ const dataStart = reader.offset;
2236
2274
  if (dataLength >= 2 && (0, psdReader_1.readUint16)(reader) === 0xfeff) {
2237
- data = (0, psdReader_1.readUnicodeStringWithLength)(reader, (dataLength - 2) / 2);
2275
+ data = (0, psdReader_1.readUnicodeStringWithLength)(reader, Math.floor((dataLength - 2) / 2));
2238
2276
  }
2239
2277
  else {
2240
- reader.offset -= 2;
2278
+ reader.offset = dataStart;
2241
2279
  data = (0, psdReader_1.readAsciiString)(reader, dataLength);
2242
2280
  }
2243
2281
  data = data.replace(/\r/g, '\n');
@@ -2251,6 +2289,8 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
2251
2289
  annotations.push({
2252
2290
  type: type === 'txtA' ? 'text' : 'sound', open, iconLocation, popupLocation, color, author, name, date, data,
2253
2291
  });
2292
+ if (length >= (reader.offset - recordStart))
2293
+ reader.offset = recordStart + length;
2254
2294
  }
2255
2295
  target.annotations = annotations;
2256
2296
  (0, psdReader_1.skipBytes)(reader, left());
@@ -2378,11 +2418,12 @@ function createLnkHandler(tag) {
2378
2418
  }
2379
2419
  (0, psdReader_1.skipBytes)(reader, left()); // ?
2380
2420
  }, (writer, target) => {
2381
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
2421
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
2382
2422
  const psd = target;
2383
2423
  for (const file of psd.linkedFiles) {
2384
2424
  if ((tag === 'lnkE') !== !!file.linkedFile)
2385
2425
  continue;
2426
+ const external = tag === 'lnkE';
2386
2427
  let version = 2;
2387
2428
  if (file.assetLockedState != null)
2388
2429
  version = 7;
@@ -2390,11 +2431,13 @@ function createLnkHandler(tag) {
2390
2431
  version = 6;
2391
2432
  else if (file.childDocumentID != null)
2392
2433
  version = 5;
2393
- else if (tag === 'lnkE')
2394
- version = 3;
2395
- writeLength64(writer, 0);
2434
+ // liFE version 2 is the only one with embedded data, it has no date and its file size is the size of the data,
2435
+ // versions 5+ can't store the data, so it's not written in that case
2436
+ else if (external && !file.data)
2437
+ version = 4;
2438
+ (0, psdWriter_1.writeUint64)(writer, 0);
2396
2439
  const sizeOffset = writer.offset;
2397
- (0, psdWriter_1.writeSignature)(writer, (tag === 'lnkE') ? 'liFE' : (file.data ? 'liFD' : 'liFA'));
2440
+ (0, psdWriter_1.writeSignature)(writer, external ? 'liFE' : (file.data ? 'liFD' : 'liFA'));
2398
2441
  (0, psdWriter_1.writeInt32)(writer, version);
2399
2442
  if (!file.id || typeof file.id !== 'string' || !/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/.test(file.id)) {
2400
2443
  throw new Error('Linked file ID must be in a GUID format (example: 20953ddb-9391-11ec-b4f1-c15674f50bc4)');
@@ -2403,7 +2446,7 @@ function createLnkHandler(tag) {
2403
2446
  (0, psdWriter_1.writeUnicodeStringWithPadding)(writer, file.name || '');
2404
2447
  (0, psdWriter_1.writeSignature)(writer, file.type ? `${file.type} `.substring(0, 4) : ' ');
2405
2448
  (0, psdWriter_1.writeSignature)(writer, file.creator ? `${file.creator} `.substring(0, 4) : '\0\0\0\0');
2406
- writeLength64(writer, file.data ? file.data.byteLength : 0);
2449
+ (0, psdWriter_1.writeUint64)(writer, (!external && file.data) ? file.data.byteLength : 0);
2407
2450
  if (file.descriptor && file.descriptor.compInfo) {
2408
2451
  const desc = {
2409
2452
  compInfo: {
@@ -2417,7 +2460,7 @@ function createLnkHandler(tag) {
2417
2460
  else {
2418
2461
  (0, psdWriter_1.writeUint8)(writer, 0);
2419
2462
  }
2420
- if (tag === 'lnkE') {
2463
+ if (external) {
2421
2464
  const desc = {
2422
2465
  descVersion: 2,
2423
2466
  'Nm ': (_b = (_a = file.linkedFile) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '',
@@ -2426,6 +2469,8 @@ function createLnkHandler(tag) {
2426
2469
  relPath: (_h = (_g = file.linkedFile) === null || _g === void 0 ? void 0 : _g.relativePath) !== null && _h !== void 0 ? _h : '',
2427
2470
  };
2428
2471
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'ExternalFileLink', desc);
2472
+ }
2473
+ if (external && version > 3) {
2429
2474
  const time = file.time ? new Date(file.time) : new Date();
2430
2475
  (0, psdWriter_1.writeInt32)(writer, time.getUTCFullYear());
2431
2476
  (0, psdWriter_1.writeUint8)(writer, time.getUTCMonth());
@@ -2434,11 +2479,14 @@ function createLnkHandler(tag) {
2434
2479
  (0, psdWriter_1.writeUint8)(writer, time.getUTCMinutes());
2435
2480
  (0, psdWriter_1.writeFloat64)(writer, time.getUTCSeconds() + time.getUTCMilliseconds() / 1000);
2436
2481
  }
2437
- if (file.data) {
2438
- (0, psdWriter_1.writeBytes)(writer, file.data);
2482
+ if (external) {
2483
+ (0, psdWriter_1.writeUint64)(writer, (version === 2 ? (_j = file.data) === null || _j === void 0 ? void 0 : _j.byteLength : (_k = file.linkedFile) === null || _k === void 0 ? void 0 : _k.fileSize) || 0); // file size
2484
+ }
2485
+ else if (file.data) {
2486
+ (0, psdWriter_1.writeBytes)(writer, file.data); // liFD
2439
2487
  }
2440
2488
  else {
2441
- writeLength64(writer, ((_j = file.linkedFile) === null || _j === void 0 ? void 0 : _j.fileSize) || 0);
2489
+ (0, psdWriter_1.writeZeros)(writer, 8); // liFA
2442
2490
  }
2443
2491
  if (version >= 5)
2444
2492
  (0, psdWriter_1.writeUnicodeStringWithPadding)(writer, file.childDocumentID || '');
@@ -2446,6 +2494,8 @@ function createLnkHandler(tag) {
2446
2494
  (0, psdWriter_1.writeFloat64)(writer, file.assetModTime || 0);
2447
2495
  if (version >= 7)
2448
2496
  (0, psdWriter_1.writeUint8)(writer, file.assetLockedState || 0);
2497
+ if (external && version === 2 && file.data)
2498
+ (0, psdWriter_1.writeBytes)(writer, file.data);
2449
2499
  let size = writer.offset - sizeOffset;
2450
2500
  writer.view.setUint32(sizeOffset - 4, size, false); // write size
2451
2501
  while (size % 4) {
@@ -2818,10 +2868,15 @@ addHandler('phfl', adjustmentType('photo filter'), (reader, target, left) => {
2818
2868
  }
2819
2869
  else { // version 3
2820
2870
  // TODO: test this, this is probably wrong
2871
+ // values are stored as L (0..100), a, b (-128..127) multiplied by 100,
2872
+ // normalize them to the same scale as readColor() so they can be written back as version 2
2873
+ const l = (0, psdReader_1.readInt32)(reader) / 100;
2874
+ const a = (0, psdReader_1.readInt32)(reader) / 100;
2875
+ const b = (0, psdReader_1.readInt32)(reader) / 100;
2821
2876
  color = {
2822
- l: (0, psdReader_1.readInt32)(reader) / 100,
2823
- a: (0, psdReader_1.readInt32)(reader) / 100,
2824
- b: (0, psdReader_1.readInt32)(reader) / 100,
2877
+ l: l / 100,
2878
+ a: (0, helpers_1.normalizeLabAB)(a),
2879
+ b: (0, helpers_1.normalizeLabAB)(b),
2825
2880
  };
2826
2881
  }
2827
2882
  target.adjustment = {
@@ -2835,7 +2890,7 @@ addHandler('phfl', adjustmentType('photo filter'), (reader, target, left) => {
2835
2890
  const info = target.adjustment;
2836
2891
  (0, psdWriter_1.writeUint16)(writer, 2); // version
2837
2892
  (0, psdWriter_1.writeColor)(writer, info.color || { l: 0, a: 0, b: 0 });
2838
- (0, psdWriter_1.writeUint32)(writer, (info.density || 0) * 100);
2893
+ (0, psdWriter_1.writeUint32)(writer, Math.round(Math.max(0, info.density || 0) * 100));
2839
2894
  (0, psdWriter_1.writeUint8)(writer, info.preserveLuminosity ? 1 : 0);
2840
2895
  (0, psdWriter_1.writeZeros)(writer, 3);
2841
2896
  });
@@ -3038,10 +3093,11 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
3038
3093
  (0, psdReader_1.readUint16)(reader) / 0x8000,
3039
3094
  ];
3040
3095
  (0, psdReader_1.skipBytes)(reader, left());
3096
+ // stop locations are always in 0..4096 range, independent of smoothness
3041
3097
  for (const s of info.colorStops)
3042
- s.location /= interpolation;
3098
+ s.location /= 4096;
3043
3099
  for (const s of info.opacityStops)
3044
- s.location /= interpolation;
3100
+ s.location /= 4096;
3045
3101
  target.adjustment = info;
3046
3102
  }, (writer, target) => {
3047
3103
  var _a, _b, _c;
@@ -3054,18 +3110,18 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
3054
3110
  }
3055
3111
  (0, psdWriter_1.writeUnicodeStringWithPadding)(writer, info.name || '');
3056
3112
  (0, psdWriter_1.writeUint16)(writer, info.colorStops && info.colorStops.length || 0);
3057
- const interpolation = Math.round(((_a = info.smoothness) !== null && _a !== void 0 ? _a : 1) * 4096);
3113
+ const interpolation = Math.round((0, helpers_1.clamp)((_a = info.smoothness) !== null && _a !== void 0 ? _a : 1, 0, 1) * 4096);
3058
3114
  for (const s of info.colorStops || []) {
3059
- (0, psdWriter_1.writeUint32)(writer, Math.round(s.location * interpolation));
3115
+ (0, psdWriter_1.writeUint32)(writer, Math.round((0, helpers_1.clamp)(s.location, 0, 1) * 4096));
3060
3116
  (0, psdWriter_1.writeUint32)(writer, Math.round(s.midpoint * 100));
3061
3117
  (0, psdWriter_1.writeColor)(writer, s.color);
3062
3118
  (0, psdWriter_1.writeZeros)(writer, 2);
3063
3119
  }
3064
3120
  (0, psdWriter_1.writeUint16)(writer, info.opacityStops && info.opacityStops.length || 0);
3065
3121
  for (const s of info.opacityStops || []) {
3066
- (0, psdWriter_1.writeUint32)(writer, Math.round(s.location * interpolation));
3122
+ (0, psdWriter_1.writeUint32)(writer, Math.round((0, helpers_1.clamp)(s.location, 0, 1) * 4096));
3067
3123
  (0, psdWriter_1.writeUint32)(writer, Math.round(s.midpoint * 100));
3068
- (0, psdWriter_1.writeUint16)(writer, Math.round(s.opacity * 0xff));
3124
+ (0, psdWriter_1.writeUint16)(writer, Math.round((0, helpers_1.clamp)(s.opacity, 0, 1) * 0xff));
3069
3125
  }
3070
3126
  (0, psdWriter_1.writeUint16)(writer, 2); // expansion count
3071
3127
  (0, psdWriter_1.writeUint16)(writer, interpolation);
@@ -3227,7 +3283,7 @@ addHandler('Txt2', hasKey('engineData'), (reader, target, left, psd) => {
3227
3283
  const data = (0, psdReader_1.readBytes)(reader, left());
3228
3284
  target.engineData = (0, base64_js_1.fromByteArray)(data);
3229
3285
  const layersByIndex = getTextLayersSortedByIndex(psd);
3230
- const engineData = (0, engineData_1.parseEngineData)(data);
3286
+ const engineData = (0, engineData_1.parseEngineData)(data, reader);
3231
3287
  const engineData2 = (0, engineData2_1.decodeEngineData2)(engineData);
3232
3288
  const TextFrameSet = engineData2.ResourceDict.TextFrameSet;
3233
3289
  if (TextFrameSet) {
@@ -3309,7 +3365,6 @@ addHandler('FEid', hasKey('filterEffectsMasks'), (reader, target, leftBytes) =>
3309
3365
  }
3310
3366
  }
3311
3367
  }, (writer, target) => {
3312
- var _a;
3313
3368
  (0, psdWriter_1.writeInt32)(writer, 3); // version
3314
3369
  for (const mask of target.filterEffectsMasks) {
3315
3370
  (0, psdWriter_1.writeUint32)(writer, 0);
@@ -3338,7 +3393,7 @@ addHandler('FEid', hasKey('filterEffectsMasks'), (reader, target, leftBytes) =>
3338
3393
  }
3339
3394
  }
3340
3395
  writer.view.setUint32(length2Offset - 4, writer.offset - length2Offset, false);
3341
- const extra = (_a = target.filterEffectsMasks[target.filterEffectsMasks.length - 1]) === null || _a === void 0 ? void 0 : _a.extra;
3396
+ const extra = mask.extra;
3342
3397
  if (extra) {
3343
3398
  (0, psdWriter_1.writeUint8)(writer, 1);
3344
3399
  (0, psdWriter_1.writeInt32)(writer, extra.top);
@@ -3362,12 +3417,12 @@ addHandlerAlias('FXid', 'FEid');
3362
3417
  addHandler('FMsk', hasKey('filterMask'), (reader, target) => {
3363
3418
  target.filterMask = {
3364
3419
  colorSpace: (0, psdReader_1.readColor)(reader),
3365
- opacity: (0, psdReader_1.readUint16)(reader) / 0xff,
3420
+ opacity: (0, psdReader_1.readUint16)(reader) / 100,
3366
3421
  };
3367
3422
  }, (writer, target) => {
3368
3423
  var _a;
3369
3424
  (0, psdWriter_1.writeColor)(writer, target.filterMask.colorSpace);
3370
- (0, psdWriter_1.writeUint16)(writer, (0, helpers_1.clamp)((_a = target.filterMask.opacity) !== null && _a !== void 0 ? _a : 1, 0, 1) * 0xff);
3425
+ (0, psdWriter_1.writeUint16)(writer, Math.round((0, helpers_1.clamp)((_a = target.filterMask.opacity) !== null && _a !== void 0 ? _a : 1, 0, 1) * 100));
3371
3426
  });
3372
3427
  addHandler('artd', // document-wide artboard info
3373
3428
  // document-wide artboard info
@@ -3483,12 +3538,12 @@ addHandler('iOpa', hasKey('fillOpacity'), (reader, target) => {
3483
3538
  target.fillOpacity = (0, psdReader_1.readUint8)(reader) / 0xff;
3484
3539
  (0, psdReader_1.skipBytes)(reader, 3);
3485
3540
  }, (writer, target) => {
3486
- (0, psdWriter_1.writeUint8)(writer, target.fillOpacity * 0xff);
3541
+ (0, psdWriter_1.writeUint8)(writer, Math.round((0, helpers_1.clamp)(target.fillOpacity, 0, 1) * 0xff));
3487
3542
  (0, psdWriter_1.writeZeros)(writer, 3);
3488
3543
  });
3489
3544
  addHandler('brst', hasKey('channelBlendingRestrictions'), (reader, target, left) => {
3490
3545
  target.channelBlendingRestrictions = [];
3491
- while (left() > 4) {
3546
+ while (left() >= 4) {
3492
3547
  target.channelBlendingRestrictions.push((0, psdReader_1.readInt32)(reader));
3493
3548
  }
3494
3549
  }, (writer, target) => {