ag-psd 31.0.3 → 33.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 (159) hide show
  1. package/.v8-cache/v24.7.0-x64-ef5a0af0/00d0e0b4 +0 -0
  2. package/.v8-cache/v24.7.0-x64-ef5a0af0/03e19709 +0 -0
  3. package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
  4. package/.v8-cache/v24.7.0-x64-ef5a0af0/0cc76730 +0 -0
  5. package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
  6. package/.v8-cache/v24.7.0-x64-ef5a0af0/20729831 +0 -0
  7. package/.v8-cache/v24.7.0-x64-ef5a0af0/214a593b +0 -0
  8. package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
  9. package/.v8-cache/v24.7.0-x64-ef5a0af0/25f8b84a +0 -0
  10. package/.v8-cache/v24.7.0-x64-ef5a0af0/27518289 +0 -0
  11. package/.v8-cache/v24.7.0-x64-ef5a0af0/2a19133e +0 -0
  12. package/.v8-cache/v24.7.0-x64-ef5a0af0/330ef2d9 +0 -0
  13. package/.v8-cache/v24.7.0-x64-ef5a0af0/37ff16b8 +0 -0
  14. package/.v8-cache/v24.7.0-x64-ef5a0af0/3f72a97c +0 -0
  15. package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
  16. package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
  17. package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
  18. package/.v8-cache/v24.7.0-x64-ef5a0af0/75efccd4 +0 -0
  19. package/.v8-cache/v24.7.0-x64-ef5a0af0/762f9305 +0 -0
  20. package/.v8-cache/v24.7.0-x64-ef5a0af0/7bcfc50a +0 -0
  21. package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
  22. package/.v8-cache/v24.7.0-x64-ef5a0af0/825e9a05 +0 -0
  23. package/.v8-cache/v24.7.0-x64-ef5a0af0/87372817 +0 -0
  24. package/.v8-cache/v24.7.0-x64-ef5a0af0/87cf2209 +0 -0
  25. package/.v8-cache/v24.7.0-x64-ef5a0af0/891a7c73 +0 -0
  26. package/.v8-cache/v24.7.0-x64-ef5a0af0/8b68a3a2 +0 -0
  27. package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
  28. package/.v8-cache/v24.7.0-x64-ef5a0af0/a1d12a93 +0 -0
  29. package/.v8-cache/v24.7.0-x64-ef5a0af0/a7e80865 +0 -0
  30. package/.v8-cache/v24.7.0-x64-ef5a0af0/ac317c9c +0 -0
  31. package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
  32. package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
  33. package/.v8-cache/v24.7.0-x64-ef5a0af0/b8569d6b +0 -0
  34. package/.v8-cache/v24.7.0-x64-ef5a0af0/b8b073c4 +0 -0
  35. package/.v8-cache/v24.7.0-x64-ef5a0af0/bb489c89 +0 -0
  36. package/.v8-cache/v24.7.0-x64-ef5a0af0/c0b789d2 +0 -0
  37. package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
  38. package/.v8-cache/v24.7.0-x64-ef5a0af0/c46725e1 +0 -0
  39. package/.v8-cache/v24.7.0-x64-ef5a0af0/c794cb34 +0 -0
  40. package/.v8-cache/v24.7.0-x64-ef5a0af0/cd4ae980 +0 -0
  41. package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
  42. package/.v8-cache/v24.7.0-x64-ef5a0af0/cff9434a +0 -0
  43. package/.v8-cache/v24.7.0-x64-ef5a0af0/d02dd6f7 +0 -0
  44. package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
  45. package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
  46. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6735171 +0 -0
  47. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6745c2b +0 -0
  48. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6b99945 +0 -0
  49. package/.v8-cache/v24.7.0-x64-ef5a0af0/eeeebdfe +0 -0
  50. package/.v8-cache/v24.7.0-x64-ef5a0af0/f5417276 +0 -0
  51. package/.v8-cache/v24.7.0-x64-ef5a0af0/f6fd8125 +0 -0
  52. package/.v8-cache/v24.7.0-x64-ef5a0af0/f74d3518 +0 -0
  53. package/.v8-cache/v24.7.0-x64-ef5a0af0/f886deac +0 -0
  54. package/.v8-cache/v24.7.0-x64-ef5a0af0/fd0a2987 +0 -0
  55. package/.v8-cache/v24.7.0-x64-ef5a0af0/fe349423 +0 -0
  56. package/CHANGELOG.md +107 -0
  57. package/LICENSE +5 -0
  58. package/README.md +3 -6
  59. package/README_PSD.md +242 -81
  60. package/dist/abr.d.ts +11 -4
  61. package/dist/abr.js +363 -229
  62. package/dist/abr.js.map +1 -1
  63. package/dist/additionalInfo.d.ts +56 -2
  64. package/dist/additionalInfo.js +600 -364
  65. package/dist/additionalInfo.js.map +1 -1
  66. package/dist/ase.d.ts +6 -1
  67. package/dist/ase.js +61 -61
  68. package/dist/ase.js.map +1 -1
  69. package/dist/bundle.js +3096 -1541
  70. package/dist/descriptor.d.ts +25 -6
  71. package/dist/descriptor.js +380 -135
  72. package/dist/descriptor.js.map +1 -1
  73. package/dist/effectsHelpers.js +12 -12
  74. package/dist/effectsHelpers.js.map +1 -1
  75. package/dist/engineData.d.ts +3 -1
  76. package/dist/engineData.js +34 -13
  77. package/dist/engineData.js.map +1 -1
  78. package/dist/engineData2.js +50 -21
  79. package/dist/engineData2.js.map +1 -1
  80. package/dist/helpers.d.ts +6 -3
  81. package/dist/helpers.js +22 -6
  82. package/dist/helpers.js.map +1 -1
  83. package/dist/imageResources.d.ts +15 -3
  84. package/dist/imageResources.js +529 -144
  85. package/dist/imageResources.js.map +1 -1
  86. package/dist/index.js +1 -0
  87. package/dist/index.js.map +1 -1
  88. package/dist/jpeg.js +30 -10
  89. package/dist/jpeg.js.map +1 -1
  90. package/dist/psd.d.ts +154 -18
  91. package/dist/psd.js.map +1 -1
  92. package/dist/psdReader.d.ts +12 -2
  93. package/dist/psdReader.js +720 -421
  94. package/dist/psdReader.js.map +1 -1
  95. package/dist/psdWriter.d.ts +3 -0
  96. package/dist/psdWriter.js +167 -130
  97. package/dist/psdWriter.js.map +1 -1
  98. package/dist/text.js +143 -29
  99. package/dist/text.js.map +1 -1
  100. package/dist/utf8.js +36 -18
  101. package/dist/utf8.js.map +1 -1
  102. package/dist-es/abr.d.ts +11 -4
  103. package/dist-es/abr.js +363 -229
  104. package/dist-es/abr.js.map +1 -1
  105. package/dist-es/additionalInfo.d.ts +56 -2
  106. package/dist-es/additionalInfo.js +600 -364
  107. package/dist-es/additionalInfo.js.map +1 -1
  108. package/dist-es/ase.d.ts +6 -1
  109. package/dist-es/ase.js +61 -61
  110. package/dist-es/ase.js.map +1 -1
  111. package/dist-es/descriptor.d.ts +25 -6
  112. package/dist-es/descriptor.js +380 -135
  113. package/dist-es/descriptor.js.map +1 -1
  114. package/dist-es/effectsHelpers.js +12 -12
  115. package/dist-es/effectsHelpers.js.map +1 -1
  116. package/dist-es/engineData.d.ts +3 -1
  117. package/dist-es/engineData.js +34 -13
  118. package/dist-es/engineData.js.map +1 -1
  119. package/dist-es/engineData2.js +50 -21
  120. package/dist-es/engineData2.js.map +1 -1
  121. package/dist-es/helpers.d.ts +6 -3
  122. package/dist-es/helpers.js +22 -6
  123. package/dist-es/helpers.js.map +1 -1
  124. package/dist-es/imageResources.d.ts +15 -3
  125. package/dist-es/imageResources.js +529 -144
  126. package/dist-es/imageResources.js.map +1 -1
  127. package/dist-es/index.js +1 -0
  128. package/dist-es/index.js.map +1 -1
  129. package/dist-es/jpeg.js +30 -10
  130. package/dist-es/jpeg.js.map +1 -1
  131. package/dist-es/psd.d.ts +154 -18
  132. package/dist-es/psd.js.map +1 -1
  133. package/dist-es/psdReader.d.ts +12 -2
  134. package/dist-es/psdReader.js +720 -421
  135. package/dist-es/psdReader.js.map +1 -1
  136. package/dist-es/psdWriter.d.ts +3 -0
  137. package/dist-es/psdWriter.js +167 -130
  138. package/dist-es/psdWriter.js.map +1 -1
  139. package/dist-es/text.js +143 -29
  140. package/dist-es/text.js.map +1 -1
  141. package/dist-es/utf8.js +36 -18
  142. package/dist-es/utf8.js.map +1 -1
  143. package/package.json +2 -2
  144. package/src/abr.ts +380 -232
  145. package/src/additionalInfo.ts +781 -477
  146. package/src/ase.ts +66 -61
  147. package/src/descriptor.ts +386 -142
  148. package/src/effectsHelpers.ts +9 -9
  149. package/src/engineData.ts +36 -13
  150. package/src/engineData2.ts +468 -432
  151. package/src/helpers.ts +23 -5
  152. package/src/imageResources.ts +658 -167
  153. package/src/index.ts +1 -0
  154. package/src/jpeg.ts +27 -12
  155. package/src/psd.ts +158 -30
  156. package/src/psdReader.ts +732 -414
  157. package/src/psdWriter.ts +186 -132
  158. package/src/text.ts +139 -18
  159. package/src/utf8.ts +35 -21
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resourceHandlersMap = exports.resourceHandlers = void 0;
4
4
  const base64_js_1 = require("base64-js");
5
+ const additionalInfo_1 = require("./additionalInfo");
5
6
  const psdReader_1 = require("./psdReader");
6
7
  const psdWriter_1 = require("./psdWriter");
7
8
  const helpers_1 = require("./helpers");
@@ -9,10 +10,12 @@ const utf8_1 = require("./utf8");
9
10
  const descriptor_1 = require("./descriptor");
10
11
  exports.resourceHandlers = [];
11
12
  exports.resourceHandlersMap = {};
12
- function addHandler(key, has, read, write) {
13
- const handler = { key, has, read, write };
13
+ function addHandler(key, has, read, write, options = {}) {
14
+ var _a;
15
+ const handler = { key, keyCount: (_a = options.keyCount) !== null && _a !== void 0 ? _a : 1, has, read, write, name: options.name };
14
16
  exports.resourceHandlers.push(handler);
15
- exports.resourceHandlersMap[handler.key] = handler;
17
+ for (let i = 0; i < handler.keyCount; i++)
18
+ exports.resourceHandlersMap[handler.key + i] = handler;
16
19
  }
17
20
  const LOG_MOCK_HANDLERS = false;
18
21
  const RESOLUTION_UNITS = [undefined, 'PPI', 'PPCM'];
@@ -30,7 +33,7 @@ function byteAt(value, index) {
30
33
  }
31
34
  function readUtf8String(reader, length) {
32
35
  const buffer = (0, psdReader_1.readBytes)(reader, length);
33
- return (0, utf8_1.decodeString)(buffer);
36
+ return (0, psdReader_1.decodeUtf8)(reader, buffer);
34
37
  }
35
38
  function writeUtf8String(writer, value) {
36
39
  const buffer = (0, utf8_1.encodeString)(value);
@@ -39,6 +42,9 @@ function writeUtf8String(writer, value) {
39
42
  function readEncodedString(reader) {
40
43
  const length = (0, psdReader_1.readUint8)(reader);
41
44
  const buffer = (0, psdReader_1.readBytes)(reader, length);
45
+ return decodeEncodedString(reader, buffer);
46
+ }
47
+ function decodeEncodedString(reader, buffer) {
42
48
  let notAscii = false;
43
49
  for (let i = 0; i < buffer.byteLength; i++) {
44
50
  if (buffer[i] & 0x80) {
@@ -47,30 +53,40 @@ function readEncodedString(reader) {
47
53
  }
48
54
  }
49
55
  if (notAscii) {
50
- try {
51
- const decoder = new TextDecoder('gbk');
52
- return decoder.decode(buffer);
56
+ // encoding is ambiguous, many GBK strings are also valid UTF-8 and vice versa, GBK is preferred,
57
+ // UTF-8 is only used if the string is not valid GBK
58
+ for (const decoder of [(0, psdReader_1.getGbkStrictDecoder)(reader), (0, psdReader_1.getUtf8StrictDecoder)(reader)]) {
59
+ if (decoder) {
60
+ try {
61
+ return decoder.decode(buffer);
62
+ }
63
+ catch (_a) { }
64
+ }
53
65
  }
54
- catch (_a) { }
55
66
  }
56
- return (0, utf8_1.decodeString)(buffer);
67
+ return (0, psdReader_1.decodeUtf8)(reader, buffer);
57
68
  }
58
- function writeEncodedString(writer, value) {
69
+ function toShortAsciiString(value) {
59
70
  let ascii = '';
60
- for (let i = 0, code = value.codePointAt(i++); code !== undefined; code = value.codePointAt(i++)) {
61
- ascii += code > 0x7f ? '?' : String.fromCodePoint(code);
71
+ for (let i = 0; i < value.length;) {
72
+ const code = value.codePointAt(i);
73
+ ascii += code > 0x7f ? '?' : String.fromCharCode(code);
74
+ i += code > 0xffff ? 2 : 1; // skip low surrogate of astral characters
62
75
  }
63
- const buffer = (0, utf8_1.encodeString)(ascii);
76
+ // length is stored in a single byte
77
+ return ascii.length > 255 ? ascii.substring(0, 255) : ascii;
78
+ }
79
+ function writeEncodedString(writer, value) {
80
+ const buffer = (0, utf8_1.encodeString)(toShortAsciiString(value));
64
81
  (0, psdWriter_1.writeUint8)(writer, buffer.byteLength);
65
82
  (0, psdWriter_1.writeBytes)(writer, buffer);
66
83
  }
67
- helpers_1.MOCK_HANDLERS && addHandler(1028, // IPTC-NAA record
84
+ addHandler(1028, // IPTC-NAA record
68
85
  // IPTC-NAA record
69
- target => target._ir1028 !== undefined, (reader, target, left) => {
70
- LOG_MOCK_HANDLERS && console.log('image resource 1028', left());
71
- target._ir1028 = (0, psdReader_1.readBytes)(reader, left());
86
+ target => target.iptcData !== undefined, (reader, target, left) => {
87
+ target.iptcData = (0, psdReader_1.readBytes)(reader, left());
72
88
  }, (writer, target) => {
73
- (0, psdWriter_1.writeBytes)(writer, target._ir1028);
89
+ (0, psdWriter_1.writeBytes)(writer, target.iptcData);
74
90
  });
75
91
  addHandler(1061, target => target.captionDigest !== undefined, (reader, target) => {
76
92
  let captionDigest = '';
@@ -96,12 +112,12 @@ const Inte = (0, helpers_1.createEnum)('Inte', 'perceptual', {
96
112
  'relative colorimetric': 'Clrm',
97
113
  'absolute colorimetric': 'AClr',
98
114
  });
99
- helpers_1.MOCK_HANDLERS && addHandler(1085, // Windows DEVMODE. Variable OS specific info for Windows.
115
+ addHandler(1085, // Windows DEVMODE. Variable OS specific info for Windows.
100
116
  // Windows DEVMODE. Variable OS specific info for Windows.
101
- target => target._ir1085 !== undefined, (reader, target, left) => {
102
- target._ir1085 = (0, psdReader_1.readBytes)(reader, left());
117
+ target => target.windowsDevMode !== undefined, (reader, target, left) => {
118
+ target.windowsDevMode = (0, psdReader_1.readBytes)(reader, left());
103
119
  }, (writer, target) => {
104
- (0, psdWriter_1.writeBytes)(writer, target._ir1085);
120
+ (0, psdWriter_1.writeBytes)(writer, target.windowsDevMode);
105
121
  });
106
122
  addHandler(1082, target => target.printInformation !== undefined, (reader, target) => {
107
123
  var _a, _b;
@@ -113,6 +129,8 @@ addHandler(1082, target => target.printInformation !== undefined, (reader, targe
113
129
  const info = target.printInformation;
114
130
  if (desc.PstS !== undefined)
115
131
  info.printerManagesColors = desc.PstS;
132
+ if (desc.ClrS === 'ClrS.Grys')
133
+ info.printerProfileColorSpace = 'grayscale';
116
134
  if (desc['Nm '] !== undefined)
117
135
  info.printerProfile = desc['Nm '];
118
136
  if (desc.MpBl !== undefined)
@@ -135,7 +153,6 @@ addHandler(1082, target => target.printInformation !== undefined, (reader, targe
135
153
  }
136
154
  }
137
155
  }, (writer, target) => {
138
- var _a, _b;
139
156
  const info = target.printInformation;
140
157
  const desc = {};
141
158
  if (info.printerManagesColors) {
@@ -144,11 +161,12 @@ addHandler(1082, target => target.printInformation !== undefined, (reader, targe
144
161
  else {
145
162
  if (info.hardProof !== undefined)
146
163
  desc.hardProof = !!info.hardProof;
147
- desc.ClrS = 'ClrS.RGBC'; // TODO: ???
148
- desc['Nm '] = (_a = info.printerProfile) !== null && _a !== void 0 ? _a : 'CIE RGB';
164
+ desc.ClrS = info.printerProfileColorSpace === 'grayscale' ? 'ClrS.Grys' : 'ClrS.RGBC';
165
+ if (info.printerProfile !== undefined)
166
+ desc['Nm '] = info.printerProfile;
149
167
  }
150
168
  desc.Inte = Inte.encode(info.renderingIntent);
151
- if (!info.printerManagesColors)
169
+ if (!info.printerManagesColors && info.blackPointCompensation !== undefined)
152
170
  desc.MpBl = !!info.blackPointCompensation;
153
171
  desc.printSixteenBit = !!info.printSixteenBit;
154
172
  desc.printerName = info.printerName || '';
@@ -160,23 +178,77 @@ addHandler(1082, target => target.printInformation !== undefined, (reader, targe
160
178
  paperWhite: !!info.proofSetup.paperWhite,
161
179
  };
162
180
  }
163
- else {
181
+ else if (info.proofSetup) {
164
182
  desc.printProofSetup = {
165
- Bltn: ((_b = info.proofSetup) === null || _b === void 0 ? void 0 : _b.builtin) ? `builtinProof.${info.proofSetup.builtin}` : 'builtinProof.proofCMYK',
183
+ Bltn: `builtinProof.${info.proofSetup.builtin || 'proofCMYK'}`,
166
184
  };
167
185
  }
168
186
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'printOutput', desc);
169
187
  });
170
- helpers_1.MOCK_HANDLERS && addHandler(1083, // Print style
188
+ addHandler(1083, // Print style
171
189
  // Print style
172
- target => target._ir1083 !== undefined, (reader, target, left) => {
173
- LOG_MOCK_HANDLERS && console.log('image resource 1083', left());
174
- target._ir1083 = (0, psdReader_1.readBytes)(reader, left());
175
- // TODO:
176
- // const desc = readVersionAndDescriptor(reader);
177
- // console.log('1083', require('util').inspect(desc, false, 99, true));
190
+ target => target.printStyle !== undefined, (reader, target) => {
191
+ const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
192
+ target.printStyle = {
193
+ caption: desc.Cptn,
194
+ calibrationBars: desc.Clbr,
195
+ registrationMarks: desc.RgsM,
196
+ cornerCropMarks: desc.CrnC,
197
+ centerCropMarks: desc.CntC,
198
+ labels: desc.Lbls,
199
+ negative: desc.Ngtv,
200
+ emulsionDown: desc.EmlD,
201
+ interpolate: desc.Intr,
202
+ backgroundColor: (0, descriptor_1.parseColor)(desc.Bckg),
203
+ border: (0, descriptor_1.parseUnits)(desc.BrdT),
204
+ bleed: (0, descriptor_1.parseUnits)(desc['Bld ']),
205
+ resolution: (0, descriptor_1.parseUnits)(desc.Rslt),
206
+ vectorData: desc.vectorData,
207
+ pagePosition: desc.PgPs === 'PgPs.PgPC' ? 'centered' : desc.PgPs,
208
+ left: (0, descriptor_1.parseUnits)(desc.Left),
209
+ top: (0, descriptor_1.parseUnits)(desc['Top ']),
210
+ scale: (0, descriptor_1.parsePercent)(desc['Scl ']),
211
+ };
212
+ if (desc.cropWhenPrinting !== undefined) {
213
+ target.printStyle.cropWhenPrinting = desc.cropWhenPrinting;
214
+ target.printStyle.cropRect = {
215
+ top: desc.cropRectTop || 0,
216
+ left: desc.cropRectLeft || 0,
217
+ bottom: desc.cropRectBottom || 0,
218
+ right: desc.cropRectRight || 0,
219
+ };
220
+ }
178
221
  }, (writer, target) => {
179
- (0, psdWriter_1.writeBytes)(writer, target._ir1083);
222
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
223
+ const style = target.printStyle;
224
+ const desc = {
225
+ Cptn: !!style.caption,
226
+ Clbr: !!style.calibrationBars,
227
+ RgsM: !!style.registrationMarks,
228
+ CrnC: !!style.cornerCropMarks,
229
+ CntC: !!style.centerCropMarks,
230
+ Lbls: !!style.labels,
231
+ Ngtv: !!style.negative,
232
+ EmlD: !!style.emulsionDown,
233
+ Intr: !!style.interpolate,
234
+ Bckg: (0, descriptor_1.serializeColor)(style.backgroundColor || { r: 255, g: 255, b: 255 }),
235
+ BrdT: (0, descriptor_1.unitsValue)(style.border || { units: 'Distance', value: 0 }, 'border'),
236
+ 'Bld ': (0, descriptor_1.unitsValue)(style.bleed || { units: 'Distance', value: 0 }, 'bleed'),
237
+ Rslt: (0, descriptor_1.unitsValue)(style.resolution || { units: 'Pixels', value: 72 }, 'resolution'),
238
+ vectorData: (_a = style.vectorData) !== null && _a !== void 0 ? _a : true,
239
+ PgPs: (!style.pagePosition || style.pagePosition === 'centered') ? 'PgPs.PgPC' : style.pagePosition,
240
+ Left: (0, descriptor_1.unitsValue)(style.left || { units: 'Distance', value: 0 }, 'left'),
241
+ 'Top ': (0, descriptor_1.unitsValue)(style.top || { units: 'Distance', value: 0 }, 'top'),
242
+ 'Scl ': (0, descriptor_1.unitsPercentF)((_b = style.scale) !== null && _b !== void 0 ? _b : 1),
243
+ };
244
+ if (style.cropWhenPrinting !== undefined || style.cropRect) {
245
+ desc.cropWhenPrinting = !!style.cropWhenPrinting;
246
+ desc.cropRectBottom = (_d = (_c = style.cropRect) === null || _c === void 0 ? void 0 : _c.bottom) !== null && _d !== void 0 ? _d : 0;
247
+ desc.cropRectLeft = (_f = (_e = style.cropRect) === null || _e === void 0 ? void 0 : _e.left) !== null && _f !== void 0 ? _f : 0;
248
+ desc.cropRectRight = (_h = (_g = style.cropRect) === null || _g === void 0 ? void 0 : _g.right) !== null && _h !== void 0 ? _h : 0;
249
+ desc.cropRectTop = (_k = (_j = style.cropRect) === null || _j === void 0 ? void 0 : _j.top) !== null && _k !== void 0 ? _k : 0;
250
+ }
251
+ (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'printOutputOptions', desc);
180
252
  });
181
253
  addHandler(1005, target => target.resolutionInfo !== undefined, (reader, target) => {
182
254
  const horizontalResolution = (0, psdReader_1.readFixedPoint32)(reader);
@@ -245,11 +317,61 @@ addHandler(1045, target => target.alphaChannelNames !== undefined, (reader, targ
245
317
  (0, psdWriter_1.writeUnicodeStringWithPadding)(writer, name);
246
318
  }
247
319
  });
248
- helpers_1.MOCK_HANDLERS && addHandler(1077, target => target._ir1077 !== undefined, (reader, target, left) => {
249
- LOG_MOCK_HANDLERS && console.log('image resource 1077', left());
250
- target._ir1077 = (0, psdReader_1.readBytes)(reader, left());
320
+ const displayInfoKinds = ['selected', 'protected', 'spot'];
321
+ const supportedColorSpaces = [0 /* ColorSpace.RGB */, 1 /* ColorSpace.HSB */, 2 /* ColorSpace.CMYK */, 7 /* ColorSpace.Lab */, 8 /* ColorSpace.Grayscale */];
322
+ function readDisplayInfo(reader) {
323
+ const info = { opacity: 0, kind: 'selected' };
324
+ const colorSpace = reader.view.getUint16(reader.offset);
325
+ if (supportedColorSpaces.indexOf(colorSpace) !== -1) {
326
+ info.color = (0, psdReader_1.readColor)(reader);
327
+ }
328
+ else {
329
+ // keep color in unknown color space as it is, so the channel info is not lost or misaligned
330
+ (0, psdReader_1.skipBytes)(reader, 2);
331
+ info.rawColor = { colorSpace, values: [(0, psdReader_1.readUint16)(reader), (0, psdReader_1.readUint16)(reader), (0, psdReader_1.readUint16)(reader), (0, psdReader_1.readUint16)(reader)] };
332
+ }
333
+ info.opacity = (0, psdReader_1.readUint16)(reader) / 100;
334
+ const kind = displayInfoKinds[(0, psdReader_1.readUint8)(reader)];
335
+ if (!kind)
336
+ throw new Error('Invalid display info kind');
337
+ info.kind = kind;
338
+ return info;
339
+ }
340
+ addHandler(1007, // Display info (obsolete, replaced by 1077), written back as 1077
341
+ () => false, (reader, target, left) => {
342
+ const info = [];
343
+ while (left() >= 14) {
344
+ info.push(readDisplayInfo(reader));
345
+ (0, psdReader_1.skipBytes)(reader, 1); // padding
346
+ }
347
+ // 1077 resource has more precise data and is used if present
348
+ if (!target.alphaChannelDisplayInfo)
349
+ target.alphaChannelDisplayInfo = info;
350
+ }, () => { });
351
+ addHandler(1077, // Display info (alpha and spot channels)
352
+ // Display info (alpha and spot channels)
353
+ target => target.alphaChannelDisplayInfo !== undefined, (reader, target, left) => {
354
+ const version = (0, psdReader_1.readUint32)(reader);
355
+ if (version !== 1)
356
+ throw new Error(`Invalid display info version: ${version}`);
357
+ target.alphaChannelDisplayInfo = [];
358
+ while (left() >= 13) {
359
+ target.alphaChannelDisplayInfo.push(readDisplayInfo(reader));
360
+ }
251
361
  }, (writer, target) => {
252
- (0, psdWriter_1.writeBytes)(writer, target._ir1077);
362
+ (0, psdWriter_1.writeUint32)(writer, 1); // version
363
+ for (const info of target.alphaChannelDisplayInfo) {
364
+ if (!info.color && info.rawColor) {
365
+ (0, psdWriter_1.writeUint16)(writer, info.rawColor.colorSpace);
366
+ for (let i = 0; i < 4; i++)
367
+ (0, psdWriter_1.writeUint16)(writer, info.rawColor.values[i] | 0);
368
+ }
369
+ else {
370
+ (0, psdWriter_1.writeColor)(writer, info.color || { r: 255, g: 0, b: 0 });
371
+ }
372
+ (0, psdWriter_1.writeUint16)(writer, Math.round((0, helpers_1.clamp)(info.opacity, 0, 1) * 100));
373
+ (0, psdWriter_1.writeUint8)(writer, Math.max(0, displayInfoKinds.indexOf(info.kind)));
374
+ }
253
375
  });
254
376
  addHandler(1053, target => target.alphaIdentifiers !== undefined, (reader, target, left) => {
255
377
  target.alphaIdentifiers = [];
@@ -302,30 +424,101 @@ target => target.url !== undefined, (reader, target, left) => {
302
424
  }, (writer, target) => {
303
425
  (0, psdWriter_1.writeAsciiString)(writer, target.url);
304
426
  });
305
- helpers_1.MOCK_HANDLERS && addHandler(10000, // Print flags
306
- // Print flags
307
- target => target._ir10000 !== undefined, (reader, target, left) => {
308
- LOG_MOCK_HANDLERS && console.log('image resource 10000', left());
309
- target._ir10000 = (0, psdReader_1.readBytes)(reader, left());
427
+ addHandler(10000, // Print flags information
428
+ // Print flags information
429
+ target => target.printFlagsInfo !== undefined, (reader, target) => {
430
+ const version = (0, psdReader_1.readUint16)(reader);
431
+ if (version !== 1)
432
+ throw new Error(`Invalid print flags information version: ${version}`);
433
+ const centerCropMarks = !!(0, psdReader_1.readUint8)(reader);
434
+ (0, psdReader_1.skipBytes)(reader, 1);
435
+ const bleedWidth = (0, psdReader_1.readUint32)(reader);
436
+ const bleedWidthScale = (0, psdReader_1.readUint16)(reader);
437
+ target.printFlagsInfo = { centerCropMarks, bleedWidth, bleedWidthScale };
310
438
  }, (writer, target) => {
311
- (0, psdWriter_1.writeBytes)(writer, target._ir10000);
439
+ const info = target.printFlagsInfo;
440
+ (0, psdWriter_1.writeUint16)(writer, 1); // version
441
+ (0, psdWriter_1.writeUint8)(writer, info.centerCropMarks ? 1 : 0);
442
+ (0, psdWriter_1.writeUint8)(writer, 0);
443
+ (0, psdWriter_1.writeUint32)(writer, info.bleedWidth | 0);
444
+ (0, psdWriter_1.writeUint16)(writer, info.bleedWidthScale | 0);
312
445
  });
313
- helpers_1.MOCK_HANDLERS && addHandler(1013, // Color halftoning
314
- // Color halftoning
315
- target => target._ir1013 !== undefined, (reader, target, left) => {
316
- LOG_MOCK_HANDLERS && console.log('image resource 1013', left());
317
- target._ir1013 = (0, psdReader_1.readBytes)(reader, left());
446
+ addHandler(1046, // Indexed color table count
447
+ // Indexed color table count
448
+ target => target.indexedColorCount !== undefined, (reader, target) => {
449
+ target.indexedColorCount = (0, psdReader_1.readUint16)(reader);
318
450
  }, (writer, target) => {
319
- (0, psdWriter_1.writeBytes)(writer, target._ir1013);
451
+ (0, psdWriter_1.writeUint16)(writer, target.indexedColorCount);
320
452
  });
321
- helpers_1.MOCK_HANDLERS && addHandler(1016, // Color transfer functions
322
- // Color transfer functions
323
- target => target._ir1016 !== undefined, (reader, target, left) => {
324
- LOG_MOCK_HANDLERS && console.log('image resource 1016', left());
325
- target._ir1016 = (0, psdReader_1.readBytes)(reader, left());
453
+ addHandler(1047, // Transparency index
454
+ // Transparency index
455
+ target => target.transparencyIndex !== undefined, (reader, target) => {
456
+ target.transparencyIndex = (0, psdReader_1.readUint16)(reader);
326
457
  }, (writer, target) => {
327
- (0, psdWriter_1.writeBytes)(writer, target._ir1016);
458
+ (0, psdWriter_1.writeUint16)(writer, target.transparencyIndex);
328
459
  });
460
+ const halftoneFrequencyUnits = ['lines/inch', 'lines/cm']; // 1, 2
461
+ const halftoneShapes = ['round', 'ellipse', 'line', 'square', 'cross', undefined, 'diamond']; // 0 - 6
462
+ function readHalftoneScreens(reader, left) {
463
+ const screens = [];
464
+ while (left() >= 18) {
465
+ const frequency = (0, psdReader_1.readFixedPoint32)(reader);
466
+ const frequencyUnits = halftoneFrequencyUnits[(0, psdReader_1.readUint16)(reader) - 1];
467
+ if (!frequencyUnits)
468
+ throw new Error('Invalid halftone screen frequency units');
469
+ const angle = (0, psdReader_1.readFixedPoint32)(reader);
470
+ const shape = halftoneShapes[(0, psdReader_1.readInt16)(reader)];
471
+ if (!shape)
472
+ throw new Error('Invalid halftone screen shape');
473
+ (0, psdReader_1.skipBytes)(reader, 4);
474
+ const accurateScreens = !!(0, psdReader_1.readUint8)(reader);
475
+ const printerDefaultScreens = !!(0, psdReader_1.readUint8)(reader);
476
+ screens.push({ frequency, frequencyUnits, angle, shape, accurateScreens, printerDefaultScreens });
477
+ }
478
+ return screens;
479
+ }
480
+ function writeHalftoneScreens(writer, screens) {
481
+ for (const screen of screens) {
482
+ (0, psdWriter_1.writeFixedPoint32)(writer, screen.frequency);
483
+ (0, psdWriter_1.writeUint16)(writer, Math.max(0, halftoneFrequencyUnits.indexOf(screen.frequencyUnits)) + 1);
484
+ (0, psdWriter_1.writeFixedPoint32)(writer, screen.angle);
485
+ (0, psdWriter_1.writeInt16)(writer, Math.max(0, halftoneShapes.indexOf(screen.shape)));
486
+ (0, psdWriter_1.writeZeros)(writer, 4);
487
+ (0, psdWriter_1.writeUint8)(writer, screen.accurateScreens ? 1 : 0);
488
+ (0, psdWriter_1.writeUint8)(writer, screen.printerDefaultScreens ? 1 : 0);
489
+ }
490
+ }
491
+ addHandler(1012, // Grayscale and multichannel halftoning information
492
+ // Grayscale and multichannel halftoning information
493
+ target => target.grayscaleHalftoneScreens !== undefined, (reader, target, left) => target.grayscaleHalftoneScreens = readHalftoneScreens(reader, left), (writer, target) => writeHalftoneScreens(writer, target.grayscaleHalftoneScreens));
494
+ addHandler(1013, // Color halftoning information
495
+ // Color halftoning information
496
+ target => target.colorHalftoneScreens !== undefined, (reader, target, left) => target.colorHalftoneScreens = readHalftoneScreens(reader, left), (writer, target) => writeHalftoneScreens(writer, target.colorHalftoneScreens));
497
+ function readTransferFunctions(reader, left) {
498
+ const functions = [];
499
+ while (left() >= 28) {
500
+ const curve = [];
501
+ for (let i = 0; i < 13; i++)
502
+ curve.push((0, psdReader_1.readInt16)(reader));
503
+ const override = !!(0, psdReader_1.readUint16)(reader);
504
+ functions.push({ curve, override });
505
+ }
506
+ return functions;
507
+ }
508
+ function writeTransferFunctions(writer, functions) {
509
+ var _a;
510
+ for (const f of functions) {
511
+ for (let i = 0; i < 13; i++)
512
+ (0, psdWriter_1.writeInt16)(writer, (_a = f.curve[i]) !== null && _a !== void 0 ? _a : -1);
513
+ (0, psdWriter_1.writeUint16)(writer, f.override ? 1 : 0);
514
+ }
515
+ }
516
+ addHandler(1015, // Grayscale and multichannel transfer function
517
+ // Grayscale and multichannel transfer function
518
+ target => target.grayscaleTransferFunctions !== undefined, (reader, target, left) => target.grayscaleTransferFunctions = readTransferFunctions(reader, left), (writer, target) => writeTransferFunctions(writer, target.grayscaleTransferFunctions));
519
+ addHandler(1016, // Color transfer functions
520
+ // Color transfer functions
521
+ target => target.colorTransferFunctions !== undefined, (reader, target, left) => target.colorTransferFunctions = readTransferFunctions(reader, left), (writer, target) => writeTransferFunctions(writer, target.colorTransferFunctions));
329
522
  addHandler(1080, // Count Information
330
523
  // Count Information
331
524
  target => target.countInformation !== undefined, (reader, target) => {
@@ -388,33 +581,108 @@ addHandler(1069, target => target.layerSelectionIds !== undefined, (reader, targ
388
581
  }
389
582
  });
390
583
  addHandler(1032, target => target.gridAndGuidesInformation !== undefined, (reader, target) => {
584
+ var _a;
391
585
  const version = (0, psdReader_1.readUint32)(reader);
392
586
  const horizontal = (0, psdReader_1.readUint32)(reader);
393
587
  const vertical = (0, psdReader_1.readUint32)(reader);
394
588
  const count = (0, psdReader_1.readUint32)(reader);
395
589
  if (version !== 1)
396
590
  throw new Error(`Invalid 1032 resource version: ${version}`);
397
- target.gridAndGuidesInformation = {
398
- grid: { horizontal, vertical },
399
- guides: [],
400
- };
591
+ const previous = (_a = target.gridAndGuidesInformation) === null || _a === void 0 ? void 0 : _a.guides; // in case guides were already read from 1092
592
+ const guides = [];
401
593
  for (let i = 0; i < count; i++) {
402
- target.gridAndGuidesInformation.guides.push({
403
- location: (0, psdReader_1.readUint32)(reader) / 32,
594
+ const guide = {
595
+ location: (0, psdReader_1.readInt32)(reader) / 32,
404
596
  direction: (0, psdReader_1.readUint8)(reader) ? 'horizontal' : 'vertical'
405
- });
597
+ };
598
+ if ((previous === null || previous === void 0 ? void 0 : previous.length) === count && previous[i].color)
599
+ guide.color = previous[i].color;
600
+ if ((previous === null || previous === void 0 ? void 0 : previous.length) === count && previous[i].id)
601
+ guide.id = previous[i].id;
602
+ guides.push(guide);
406
603
  }
604
+ target.gridAndGuidesInformation = { grid: { horizontal, vertical }, guides };
407
605
  }, (writer, target) => {
408
606
  const info = target.gridAndGuidesInformation;
409
607
  const grid = info.grid || { horizontal: 18 * 32, vertical: 18 * 32 };
410
608
  const guides = info.guides || [];
411
609
  (0, psdWriter_1.writeUint32)(writer, 1);
412
- (0, psdWriter_1.writeUint32)(writer, grid.horizontal);
413
- (0, psdWriter_1.writeUint32)(writer, grid.vertical);
610
+ (0, psdWriter_1.writeUint32)(writer, Math.round(grid.horizontal));
611
+ (0, psdWriter_1.writeUint32)(writer, Math.round(grid.vertical));
612
+ (0, psdWriter_1.writeUint32)(writer, guides.length);
613
+ for (const g of guides) {
614
+ (0, psdWriter_1.writeInt32)(writer, Math.round(g.location * 32));
615
+ (0, psdWriter_1.writeUint8)(writer, g.direction === 'horizontal' ? 1 : 0);
616
+ }
617
+ });
618
+ const defaultGuideColor = { r: 74, g: 255, b: 255 }; // Photoshop default (cyan)
619
+ addHandler(1092, // Grid and guides information with guide colors (same as 1032 with color of each guide)
620
+ // Grid and guides information with guide colors (same as 1032 with color of each guide)
621
+ target => target.gridAndGuidesInformation !== undefined, (reader, target) => {
622
+ var _a;
623
+ const version = (0, psdReader_1.readUint32)(reader);
624
+ if (version !== 2)
625
+ throw new Error(`Invalid 1092 resource version: ${version}`);
626
+ const horizontal = (0, psdReader_1.readUint32)(reader);
627
+ const vertical = (0, psdReader_1.readUint32)(reader);
628
+ const count = (0, psdReader_1.readUint32)(reader);
629
+ const guides = [];
630
+ for (let i = 0; i < count; i++) {
631
+ const location = (0, psdReader_1.readInt32)(reader) / 32;
632
+ const direction = (0, psdReader_1.readUint8)(reader) ? 'horizontal' : 'vertical';
633
+ (0, psdReader_1.skipBytes)(reader, 1);
634
+ const color = { r: (0, psdReader_1.readUint8)(reader), g: (0, psdReader_1.readUint8)(reader), b: (0, psdReader_1.readUint8)(reader) };
635
+ guides.push({ location, direction, color });
636
+ }
637
+ const existing = (_a = target.gridAndGuidesInformation) === null || _a === void 0 ? void 0 : _a.guides;
638
+ if (existing && existing.length === count) {
639
+ existing.forEach((guide, i) => guide.color = guides[i].color);
640
+ }
641
+ else {
642
+ target.gridAndGuidesInformation = { grid: { horizontal, vertical }, guides };
643
+ }
644
+ }, (writer, target) => {
645
+ const info = target.gridAndGuidesInformation;
646
+ const grid = info.grid || { horizontal: 18 * 32, vertical: 18 * 32 };
647
+ const guides = info.guides || [];
648
+ (0, psdWriter_1.writeUint32)(writer, 2); // version
649
+ (0, psdWriter_1.writeUint32)(writer, Math.round(grid.horizontal));
650
+ (0, psdWriter_1.writeUint32)(writer, Math.round(grid.vertical));
414
651
  (0, psdWriter_1.writeUint32)(writer, guides.length);
415
652
  for (const g of guides) {
416
- (0, psdWriter_1.writeUint32)(writer, g.location * 32);
653
+ const color = g.color || defaultGuideColor;
654
+ (0, psdWriter_1.writeInt32)(writer, Math.round(g.location * 32));
417
655
  (0, psdWriter_1.writeUint8)(writer, g.direction === 'horizontal' ? 1 : 0);
656
+ (0, psdWriter_1.writeUint8)(writer, 0);
657
+ (0, psdWriter_1.writeUint8)(writer, Math.round(color.r));
658
+ (0, psdWriter_1.writeUint8)(writer, Math.round(color.g));
659
+ (0, psdWriter_1.writeUint8)(writer, Math.round(color.b));
660
+ }
661
+ });
662
+ const emptyGuid = '00000000-0000-0000-0000-000000000000';
663
+ addHandler(1097, // Guide ids
664
+ // Guide ids
665
+ target => !!target.gridAndGuidesInformation && (target.gridAndGuidesInformation.guides || []).every(g => g.id), (reader, target) => {
666
+ var _a;
667
+ const count = (0, psdReader_1.readUint32)(reader);
668
+ const ids = [];
669
+ for (let i = 0; i < count; i++) {
670
+ ids.push((0, psdReader_1.readAsciiString)(reader, (0, psdReader_1.readUint32)(reader)));
671
+ (0, psdReader_1.readUint32)(reader); // unknown, always 0
672
+ (0, psdReader_1.readAsciiString)(reader, (0, psdReader_1.readUint32)(reader)); // unknown, always empty guid
673
+ }
674
+ const guides = (_a = target.gridAndGuidesInformation) === null || _a === void 0 ? void 0 : _a.guides;
675
+ if (guides && guides.length === count)
676
+ guides.forEach((guide, i) => guide.id = ids[i]);
677
+ }, (writer, target) => {
678
+ const guides = target.gridAndGuidesInformation.guides || [];
679
+ (0, psdWriter_1.writeUint32)(writer, guides.length);
680
+ for (const g of guides) {
681
+ (0, psdWriter_1.writeUint32)(writer, g.id.length);
682
+ (0, psdWriter_1.writeAsciiString)(writer, g.id);
683
+ (0, psdWriter_1.writeUint32)(writer, 0);
684
+ (0, psdWriter_1.writeUint32)(writer, emptyGuid.length);
685
+ (0, psdWriter_1.writeAsciiString)(writer, emptyGuid);
418
686
  }
419
687
  });
420
688
  addHandler(1065, // Layer Comps
@@ -429,10 +697,10 @@ target => target.layerComps !== undefined, (reader, target) => {
429
697
  name: item['Nm '],
430
698
  capturedInfo: item.capturedInfo,
431
699
  });
432
- if ('comment' in item)
700
+ if (item.comment !== undefined)
433
701
  target.layerComps.list[target.layerComps.list.length - 1].comment = item.comment;
434
702
  }
435
- if ('lastAppliedComp' in desc)
703
+ if (desc.lastAppliedComp !== undefined)
436
704
  target.layerComps.lastApplied = desc.lastAppliedComp;
437
705
  }, (writer, target) => {
438
706
  const layerComps = target.layerComps;
@@ -441,13 +709,13 @@ target => target.layerComps !== undefined, (reader, target) => {
441
709
  const t = {};
442
710
  t._classID = 'Comp';
443
711
  t['Nm '] = item.name;
444
- if ('comment' in item)
712
+ if (item.comment !== undefined)
445
713
  t.comment = item.comment;
446
714
  t.compID = item.id;
447
715
  t.capturedInfo = item.capturedInfo;
448
716
  desc.list.push(t);
449
717
  }
450
- if ('lastApplied' in layerComps)
718
+ if (layerComps.lastApplied !== undefined)
451
719
  desc.lastAppliedComp = layerComps.lastApplied;
452
720
  // console.log('CompList', require('util').inspect(desc, false, 99, true));
453
721
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'CompList', desc);
@@ -489,8 +757,8 @@ target => target.onionSkins !== undefined, (reader, target) => {
489
757
  numBefore: onionSkins.framesBefore,
490
758
  numAfter: onionSkins.framesAfter,
491
759
  Spcn: onionSkins.frameSpacing,
492
- minOpacity: (onionSkins.minOpacity * 100) | 0,
493
- maxOpacity: (onionSkins.maxOpacity * 100) | 0,
760
+ minOpacity: Math.round(onionSkins.minOpacity * 100),
761
+ maxOpacity: Math.round(onionSkins.maxOpacity * 100),
494
762
  BlnM: Math.max(0, onionSkinsBlendModes.indexOf(onionSkins.blendMode)),
495
763
  };
496
764
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
@@ -551,7 +819,7 @@ target => target.timelineInformation !== undefined, (reader, target) => {
551
819
  LCnt: timeline.repeats,
552
820
  globalTrackList: (0, descriptor_1.serializeTrackList)(timeline.globalTracks),
553
821
  audioClipGroupList: {
554
- audioClipGroupList: (_a = timeline.audioClipGroups) === null || _a === void 0 ? void 0 : _a.map(a => ({
822
+ audioClipGroupList: ((_a = timeline.audioClipGroups) !== null && _a !== void 0 ? _a : []).map(a => ({
555
823
  groupID: a.id,
556
824
  muted: a.muted,
557
825
  audioClipList: a.audioClips.map(c => ({
@@ -694,8 +962,13 @@ target => target.slices ? target.slices.length : 0, (reader, target, leftBytes)
694
962
  }
695
963
  if (leftBytes()) {
696
964
  const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
965
+ const slicesById = new Map();
966
+ for (const s of slices) {
967
+ if (!slicesById.has(s.id))
968
+ slicesById.set(s.id, s);
969
+ }
697
970
  desc.slices.forEach(d => {
698
- const slice = slices.find(s => d.sliceID == s.id);
971
+ const slice = slicesById.get(d.sliceID);
699
972
  if (slice) {
700
973
  slice.topOutset = d.topOutset;
701
974
  slice.leftOutset = d.leftOutset;
@@ -792,27 +1065,78 @@ addHandler(1041, target => target.iccUntaggedProfile !== undefined, (reader, tar
792
1065
  }, (writer, target) => {
793
1066
  (0, psdWriter_1.writeUint8)(writer, target.iccUntaggedProfile ? 1 : 0);
794
1067
  });
795
- helpers_1.MOCK_HANDLERS && addHandler(1039, // ICC Profile
1068
+ addHandler(1039, // ICC Profile
796
1069
  // ICC Profile
797
- target => target._ir1039 !== undefined, (reader, target, left) => {
798
- // TODO: this is raw bytes, just return as a byte array
799
- LOG_MOCK_HANDLERS && console.log('image resource 1039', left());
800
- target._ir1039 = (0, psdReader_1.readBytes)(reader, left());
1070
+ target => target.iccProfile !== undefined, (reader, target, left) => {
1071
+ target.iccProfile = (0, psdReader_1.readBytes)(reader, left());
801
1072
  }, (writer, target) => {
802
- (0, psdWriter_1.writeBytes)(writer, target._ir1039);
1073
+ (0, psdWriter_1.writeBytes)(writer, target.iccProfile);
803
1074
  });
804
1075
  addHandler(1044, target => target.idsSeedNumber !== undefined, (reader, target) => target.idsSeedNumber = (0, psdReader_1.readUint32)(reader), (writer, target) => (0, psdWriter_1.writeUint32)(writer, target.idsSeedNumber));
1076
+ addHandler(1038, // Color samplers (Photoshop 5.0, replaced by 1073 in CS3)
1077
+ // Color samplers (Photoshop 5.0, replaced by 1073 in CS3)
1078
+ target => target.colorSamplers !== undefined, (reader, target, left) => {
1079
+ const version = (0, psdReader_1.readUint32)(reader);
1080
+ if (version !== 1)
1081
+ throw new Error(`Invalid color samplers version: ${version}`);
1082
+ const count = (0, psdReader_1.readUint32)(reader);
1083
+ target.colorSamplers = [];
1084
+ for (let i = 0; i < count && left() >= 10; i++) {
1085
+ // vertical and horizontal position in 1/16 pixel (inferred from sample files, the specification describes
1086
+ // these values as horizontal and vertical fixed point numbers)
1087
+ const y = (0, psdReader_1.readInt32)(reader) / 16;
1088
+ const x = (0, psdReader_1.readInt32)(reader) / 16;
1089
+ const colorSpace = (0, psdReader_1.readInt16)(reader);
1090
+ target.colorSamplers.push({ x, y, colorSpace });
1091
+ }
1092
+ }, (writer, target) => {
1093
+ (0, psdWriter_1.writeUint32)(writer, 1); // version
1094
+ (0, psdWriter_1.writeUint32)(writer, target.colorSamplers.length);
1095
+ for (const sampler of target.colorSamplers) {
1096
+ (0, psdWriter_1.writeInt32)(writer, Math.round(sampler.y * 16));
1097
+ (0, psdWriter_1.writeInt32)(writer, Math.round(sampler.x * 16));
1098
+ (0, psdWriter_1.writeInt16)(writer, sampler.colorSpace);
1099
+ }
1100
+ });
1101
+ addHandler(1042, // Effects visible (only present when effects are hidden)
1102
+ // Effects visible (only present when effects are hidden)
1103
+ target => target.effectsVisible !== undefined, (reader, target) => {
1104
+ target.effectsVisible = !!(0, psdReader_1.readUint8)(reader);
1105
+ }, (writer, target) => {
1106
+ (0, psdWriter_1.writeUint8)(writer, target.effectsVisible ? 1 : 0);
1107
+ });
805
1108
  addHandler(1036, target => target.thumbnail !== undefined || target.thumbnailRaw !== undefined, (reader, target, left) => {
806
1109
  const format = (0, psdReader_1.readUint32)(reader); // 1 = kJpegRGB, 0 = kRawRGB
807
1110
  const width = (0, psdReader_1.readUint32)(reader);
808
1111
  const height = (0, psdReader_1.readUint32)(reader);
809
- (0, psdReader_1.readUint32)(reader); // widthBytes = (width * bits_per_pixel + 31) / 32 * 4.
1112
+ const widthBytes = (0, psdReader_1.readUint32)(reader); // widthBytes = (width * bits_per_pixel + 31) / 32 * 4.
810
1113
  (0, psdReader_1.readUint32)(reader); // totalSize = widthBytes * height * planes
811
1114
  (0, psdReader_1.readUint32)(reader); // sizeAfterCompression
812
1115
  const bitsPerPixel = (0, psdReader_1.readUint16)(reader); // 24
813
- const planes = (0, psdReader_1.readUint16)(reader); // 1
814
- if (format !== 1 || bitsPerPixel !== 24 || planes !== 1) {
815
- reader.logMissingFeatures && reader.log(`Invalid thumbnail data (format: ${format}, bitsPerPixel: ${bitsPerPixel}, planes: ${planes})`);
1116
+ (0, psdReader_1.readUint16)(reader); // planes, should be 1 (some applications write 3)
1117
+ if (format === 0 && bitsPerPixel === 24 && widthBytes >= width * 3 && widthBytes * height <= left()) {
1118
+ // raw RGB data, rows are padded to 4 bytes
1119
+ if (reader.useRawThumbnail) {
1120
+ reader.logMissingFeatures && reader.log('Raw thumbnail data is not supported with useRawThumbnail option');
1121
+ (0, psdReader_1.skipBytes)(reader, left());
1122
+ return;
1123
+ }
1124
+ const data = (0, psdReader_1.readBytes)(reader, widthBytes * height);
1125
+ const imageData = (0, helpers_1.createImageData)(width, height);
1126
+ for (let y = 0, dst = 0; y < height; y++) {
1127
+ for (let x = 0, src = y * widthBytes; x < width; x++, src += 3, dst += 4) {
1128
+ imageData.data[dst + 0] = data[src + 0];
1129
+ imageData.data[dst + 1] = data[src + 1];
1130
+ imageData.data[dst + 2] = data[src + 2];
1131
+ imageData.data[dst + 3] = 255;
1132
+ }
1133
+ }
1134
+ target.thumbnail = (0, helpers_1.imageDataToCanvas)(imageData);
1135
+ (0, psdReader_1.skipBytes)(reader, left());
1136
+ return;
1137
+ }
1138
+ if (format !== 1 || bitsPerPixel !== 24) {
1139
+ reader.logMissingFeatures && reader.log(`Invalid thumbnail data (format: ${format}, bitsPerPixel: ${bitsPerPixel})`);
816
1140
  (0, psdReader_1.skipBytes)(reader, left());
817
1141
  return;
818
1142
  }
@@ -822,7 +1146,7 @@ addHandler(1036, target => target.thumbnail !== undefined || target.thumbnailRaw
822
1146
  target.thumbnailRaw = { width, height, data };
823
1147
  }
824
1148
  else if (data.byteLength) {
825
- target.thumbnail = (0, helpers_1.createCanvasFromData)(data);
1149
+ target.thumbnail = (0, helpers_1.createCanvasFromData)(data, reader);
826
1150
  }
827
1151
  }, (writer, target) => {
828
1152
  var _a;
@@ -879,13 +1203,12 @@ addHandler(1057, target => target.versionInfo !== undefined, (reader, target, le
879
1203
  (0, psdWriter_1.writeUnicodeString)(writer, versionInfo.readerName);
880
1204
  (0, psdWriter_1.writeUint32)(writer, versionInfo.fileVersion);
881
1205
  });
882
- helpers_1.MOCK_HANDLERS && addHandler(1058, // EXIF data 1.
883
- // EXIF data 1.
884
- target => target._ir1058 !== undefined, (reader, target, left) => {
885
- LOG_MOCK_HANDLERS && console.log('image resource 1058', left());
886
- target._ir1058 = (0, psdReader_1.readBytes)(reader, left());
1206
+ addHandler(1058, // EXIF data 1
1207
+ // EXIF data 1
1208
+ target => target.exifData !== undefined, (reader, target, left) => {
1209
+ target.exifData = (0, psdReader_1.readBytes)(reader, left());
887
1210
  }, (writer, target) => {
888
- (0, psdWriter_1.writeBytes)(writer, target._ir1058);
1211
+ (0, psdWriter_1.writeBytes)(writer, target.exifData);
889
1212
  });
890
1213
  addHandler(7000, target => target.imageReadyVariables !== undefined, (reader, target, left) => {
891
1214
  target.imageReadyVariables = readUtf8String(reader, left());
@@ -901,25 +1224,104 @@ addHandler(1088, target => target.pathSelectionState !== undefined, (reader, tar
901
1224
  const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
902
1225
  target.pathSelectionState = desc['null'];
903
1226
  }, (writer, target) => {
904
- const desc = { 'null': target.pathSelectionState };
1227
+ const desc = { 'null': (0, descriptor_1.pathSelectionStateToReference)(target.pathSelectionState) };
905
1228
  (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
906
1229
  });
907
- helpers_1.MOCK_HANDLERS && addHandler(1025, target => target._ir1025 !== undefined, (reader, target, left) => {
908
- LOG_MOCK_HANDLERS && console.log('image resource 1025', left());
909
- target._ir1025 = (0, psdReader_1.readBytes)(reader, left());
1230
+ addHandler(1025, // Work path
1231
+ // Work path
1232
+ target => target.workPath !== undefined, (reader, target, left, { width, height }) => {
1233
+ target.workPath = { paths: [] };
1234
+ (0, additionalInfo_1.readVectorMask)(reader, target.workPath, width, height, left());
1235
+ (0, psdReader_1.skipBytes)(reader, left());
1236
+ }, (writer, target, _index, { width, height }) => {
1237
+ (0, additionalInfo_1.writeVectorMask)(writer, target.workPath, width, height);
1238
+ });
1239
+ const MAX_SAVED_PATHS = 999; // ids 2000-2998
1240
+ addHandler(2000, // Saved paths (one resource for each path, named after the path)
1241
+ // Saved paths (one resource for each path, named after the path)
1242
+ target => target.savedPaths ? Math.min(target.savedPaths.length, MAX_SAVED_PATHS) : 0, (reader, target, left, { signature, id, name, width, height }) => {
1243
+ var _a, _b;
1244
+ if (signature !== '8BIM') { // ImageReady ('MeSa') resources use the same ids for other data
1245
+ reader.logMissingFeatures && reader.log(`Unhandled image resource: ${signature} ${id}`);
1246
+ (0, psdReader_1.skipBytes)(reader, left());
1247
+ return;
1248
+ }
1249
+ const savedPaths = (_a = target.savedPaths) !== null && _a !== void 0 ? _a : (target.savedPaths = []);
1250
+ const path = { name: decodeEncodedString(reader, name), paths: [] };
1251
+ (0, additionalInfo_1.readVectorMask)(reader, path, width, height, left());
1252
+ (0, psdReader_1.skipBytes)(reader, left());
1253
+ const keyDescriptorList = (_b = target.savedPathsOrigination) === null || _b === void 0 ? void 0 : _b[savedPaths.length];
1254
+ if (keyDescriptorList)
1255
+ path.vectorOrigination = { keyDescriptorList };
1256
+ savedPaths.push(path);
1257
+ }, (writer, target, index, { width, height }) => {
1258
+ (0, additionalInfo_1.writeVectorMask)(writer, target.savedPaths[index], width, height);
1259
+ }, { keyCount: MAX_SAVED_PATHS, name: (target, index) => toShortAsciiString(target.savedPaths[index].name) });
1260
+ addHandler(3000, // Origin path info (origination data of saved paths)
1261
+ // Origin path info (origination data of saved paths)
1262
+ target => { var _a; return !!((_a = target.savedPaths) === null || _a === void 0 ? void 0 : _a.some(path => path.vectorOrigination)); }, (reader, target, left) => {
1263
+ const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
1264
+ desc.keyRootDescriptorList.forEach((item, i) => {
1265
+ var _a, _b;
1266
+ const keyDescriptorList = (0, additionalInfo_1.parseKeyDescriptorList)(item);
1267
+ if (!keyDescriptorList.length)
1268
+ return; // written for paths without origination data
1269
+ const path = (_a = target.savedPaths) === null || _a === void 0 ? void 0 : _a[i];
1270
+ if (path) {
1271
+ path.vectorOrigination = { keyDescriptorList };
1272
+ }
1273
+ else { // saved paths are stored after this resource
1274
+ ((_b = target.savedPathsOrigination) !== null && _b !== void 0 ? _b : (target.savedPathsOrigination = []))[i] = keyDescriptorList;
1275
+ }
1276
+ });
1277
+ (0, psdReader_1.skipBytes)(reader, left());
1278
+ }, (writer, target) => {
1279
+ const desc = {
1280
+ keyRootDescriptorList: target.savedPaths.slice(0, MAX_SAVED_PATHS)
1281
+ .map(path => { var _a, _b; return (0, additionalInfo_1.serializeKeyDescriptorList)((_b = (_a = path.vectorOrigination) === null || _a === void 0 ? void 0 : _a.keyDescriptorList) !== null && _b !== void 0 ? _b : []); }),
1282
+ };
1283
+ (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
1284
+ }, { name: () => 'OriginDataIRB' });
1285
+ addHandler(2999, // Clipping path
1286
+ // Clipping path
1287
+ target => target.clippingPath !== undefined, (reader, target, left) => {
1288
+ const name = readEncodedString(reader);
1289
+ const flatness = (0, psdReader_1.readFixedPoint32)(reader);
1290
+ (0, psdReader_1.skipBytes)(reader, left()); // fill rule (ignored by Photoshop)
1291
+ target.clippingPath = { name, flatness };
910
1292
  }, (writer, target) => {
911
- (0, psdWriter_1.writeBytes)(writer, target._ir1025);
1293
+ writeEncodedString(writer, target.clippingPath.name);
1294
+ (0, psdWriter_1.writeFixedPoint32)(writer, target.clippingPath.flatness);
1295
+ (0, psdWriter_1.writeUint16)(writer, 1); // fill rule (ignored by Photoshop)
912
1296
  });
913
1297
  const FrmD = (0, helpers_1.createEnum)('FrmD', 'auto', {
914
1298
  auto: 'Auto',
915
1299
  none: 'None',
916
1300
  dispose: 'Disp',
917
1301
  });
918
- addHandler(4000, // Plug-In resource(s)
919
- // Plug-In resource(s)
920
- target => target.animations !== undefined, (reader, target, left) => {
1302
+ // plug-in resources are written with consecutive ids starting at 4000, in the same order as Photoshop writes them
1303
+ function pluginResourceKeys(target) {
1304
+ const keys = [];
1305
+ if (target.outputSettings !== undefined)
1306
+ keys.push('mset');
1307
+ if (target.animations !== undefined)
1308
+ keys.push('mani', 'mfri');
1309
+ return keys;
1310
+ }
1311
+ addHandler(4000, // Plug-In resource(s), identified by key stored in the data (ids 4000-4999)
1312
+ // Plug-In resource(s), identified by key stored in the data (ids 4000-4999)
1313
+ target => pluginResourceKeys(target).length, (reader, target, left) => {
921
1314
  const key = (0, psdReader_1.readSignature)(reader);
922
- if (key === 'mani') {
1315
+ if (key === 'mset') {
1316
+ // Save for Web output settings
1317
+ target.outputSettings = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
1318
+ (0, psdReader_1.skipBytes)(reader, left());
1319
+ }
1320
+ else if (key === 'mfri') {
1321
+ // frame count, active frame and animation count, same data as in animations (mani)
1322
+ (0, psdReader_1.skipBytes)(reader, left());
1323
+ }
1324
+ else if (key === 'mani') {
923
1325
  (0, psdReader_1.checkSignature)(reader, 'IRFR');
924
1326
  (0, psdReader_1.readSection)(reader, 1, left => {
925
1327
  while (left() > 0) {
@@ -945,6 +1347,7 @@ target => target.animations !== undefined, (reader, target, left) => {
945
1347
  };
946
1348
  // console.log('#4000 AnDs', require('util').inspect(desc, false, 99, true));
947
1349
  // console.log('#4000 AnDs:result', require('util').inspect(target.animations, false, 99, true));
1350
+ (0, psdReader_1.skipBytes)(reader, left()); // padding
948
1351
  }
949
1352
  else if (key === 'Roll') {
950
1353
  const bytes = (0, psdReader_1.readBytes)(reader, left());
@@ -952,20 +1355,39 @@ target => target.animations !== undefined, (reader, target, left) => {
952
1355
  }
953
1356
  else {
954
1357
  reader.logMissingFeatures && reader.log('Unhandled subsection in #4000', key);
1358
+ (0, psdReader_1.skipBytes)(reader, left());
955
1359
  }
956
1360
  });
957
1361
  }
958
1362
  });
1363
+ (0, psdReader_1.skipBytes)(reader, left()); // unknown data after animations section
959
1364
  }
960
1365
  else if (key === 'mopt') {
961
1366
  const bytes = (0, psdReader_1.readBytes)(reader, left());
962
1367
  reader.logDevFeatures && reader.log('#4000 mopt', bytes);
963
1368
  }
964
1369
  else {
965
- reader.logMissingFeatures && reader.log('Unhandled key in #4000:', key);
1370
+ reader.logMissingFeatures && reader.log(`Unhandled plug-in resource key: ${key}`);
1371
+ (0, psdReader_1.skipBytes)(reader, left());
966
1372
  }
967
- }, (writer, target) => {
968
- if (target.animations) {
1373
+ }, (writer, target, index) => {
1374
+ var _a, _b;
1375
+ const key = pluginResourceKeys(target)[index];
1376
+ if (key === 'mset') {
1377
+ (0, psdWriter_1.writeSignature)(writer, 'mset');
1378
+ (0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', target.outputSettings, descriptor_1.outputSettingsRoot);
1379
+ }
1380
+ else if (key === 'mfri') {
1381
+ const animations = target.animations;
1382
+ (0, psdWriter_1.writeSignature)(writer, 'mfri');
1383
+ (0, psdWriter_1.writeUint32)(writer, 2); // version
1384
+ (0, psdWriter_1.writeUint32)(writer, 16); // length
1385
+ (0, psdWriter_1.writeUint32)(writer, animations.frames.length);
1386
+ (0, psdWriter_1.writeUint32)(writer, (_b = (_a = animations.animations[0]) === null || _a === void 0 ? void 0 : _a.activeFrame) !== null && _b !== void 0 ? _b : 0);
1387
+ (0, psdWriter_1.writeUint32)(writer, animations.animations.length);
1388
+ (0, psdWriter_1.writeUint32)(writer, 0);
1389
+ }
1390
+ else if (key === 'mani') {
969
1391
  (0, psdWriter_1.writeSignature)(writer, 'mani');
970
1392
  (0, psdWriter_1.writeSignature)(writer, 'IRFR');
971
1393
  (0, psdWriter_1.writeSection)(writer, 1, () => {
@@ -983,7 +1405,7 @@ target => target.animations !== undefined, (reader, target, left) => {
983
1405
  FrID: f.id,
984
1406
  };
985
1407
  if (f.delay)
986
- frame.FrDl = (f.delay * 100) | 0;
1408
+ frame.FrDl = Math.round(f.delay * 100);
987
1409
  frame.FrDs = FrmD.encode(f.dispose);
988
1410
  // if (i === 0) frame.FrGA = 30; // ???
989
1411
  desc.FrIn.push(frame);
@@ -1007,42 +1429,5 @@ target => target.animations !== undefined, (reader, target, left) => {
1007
1429
  // });
1008
1430
  });
1009
1431
  }
1010
- });
1011
- // TODO: Unfinished
1012
- helpers_1.MOCK_HANDLERS && addHandler(4001, // Plug-In resource(s)
1013
- // Plug-In resource(s)
1014
- target => target._ir4001 !== undefined, (reader, target, left) => {
1015
- if (helpers_1.MOCK_HANDLERS) {
1016
- LOG_MOCK_HANDLERS && console.log('image resource 4001', left());
1017
- target._ir4001 = (0, psdReader_1.readBytes)(reader, left());
1018
- return;
1019
- }
1020
- const key = (0, psdReader_1.readSignature)(reader);
1021
- if (key === 'mfri') {
1022
- const version = (0, psdReader_1.readUint32)(reader);
1023
- if (version !== 2)
1024
- throw new Error('Invalid mfri version');
1025
- const length = (0, psdReader_1.readUint32)(reader);
1026
- const bytes = (0, psdReader_1.readBytes)(reader, length);
1027
- reader.logDevFeatures && reader.log('mfri', bytes);
1028
- }
1029
- else if (key === 'mset') {
1030
- const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
1031
- reader.logDevFeatures && reader.log('mset', desc);
1032
- }
1033
- else {
1034
- reader.logMissingFeatures && reader.log('Unhandled key in #4001', key);
1035
- }
1036
- }, (writer, target) => {
1037
- (0, psdWriter_1.writeBytes)(writer, target._ir4001);
1038
- });
1039
- // TODO: Unfinished
1040
- helpers_1.MOCK_HANDLERS && addHandler(4002, // Plug-In resource(s)
1041
- // Plug-In resource(s)
1042
- target => target._ir4002 !== undefined, (reader, target, left) => {
1043
- LOG_MOCK_HANDLERS && console.log('image resource 4002', left());
1044
- target._ir4002 = (0, psdReader_1.readBytes)(reader, left());
1045
- }, (writer, target) => {
1046
- (0, psdWriter_1.writeBytes)(writer, target._ir4002);
1047
- });
1432
+ }, { keyCount: 1000 });
1048
1433
  //# sourceMappingURL=imageResources.js.map