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.
- package/.v8-cache/v24.7.0-x64-ef5a0af0/00d0e0b4 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/03e19709 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/0cc76730 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/20729831 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/214a593b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/25f8b84a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/27518289 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/2a19133e +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/330ef2d9 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/37ff16b8 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/3f72a97c +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/75efccd4 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/762f9305 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/7bcfc50a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/825e9a05 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/87372817 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/87cf2209 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/891a7c73 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/8b68a3a2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/a1d12a93 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/a7e80865 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/ac317c9c +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b8569d6b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b8b073c4 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/bb489c89 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c0b789d2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c46725e1 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c794cb34 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cd4ae980 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cff9434a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/d02dd6f7 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6735171 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6745c2b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6b99945 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/eeeebdfe +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f5417276 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f6fd8125 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f74d3518 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f886deac +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/fd0a2987 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/fe349423 +0 -0
- package/CHANGELOG.md +107 -0
- package/LICENSE +5 -0
- package/README.md +3 -6
- package/README_PSD.md +242 -81
- package/dist/abr.d.ts +11 -4
- package/dist/abr.js +363 -229
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.d.ts +56 -2
- package/dist/additionalInfo.js +600 -364
- package/dist/additionalInfo.js.map +1 -1
- package/dist/ase.d.ts +6 -1
- package/dist/ase.js +61 -61
- package/dist/ase.js.map +1 -1
- package/dist/bundle.js +3096 -1541
- package/dist/descriptor.d.ts +25 -6
- package/dist/descriptor.js +380 -135
- package/dist/descriptor.js.map +1 -1
- package/dist/effectsHelpers.js +12 -12
- package/dist/effectsHelpers.js.map +1 -1
- package/dist/engineData.d.ts +3 -1
- package/dist/engineData.js +34 -13
- package/dist/engineData.js.map +1 -1
- package/dist/engineData2.js +50 -21
- package/dist/engineData2.js.map +1 -1
- package/dist/helpers.d.ts +6 -3
- package/dist/helpers.js +22 -6
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.d.ts +15 -3
- package/dist/imageResources.js +529 -144
- package/dist/imageResources.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jpeg.js +30 -10
- package/dist/jpeg.js.map +1 -1
- package/dist/psd.d.ts +154 -18
- package/dist/psd.js.map +1 -1
- package/dist/psdReader.d.ts +12 -2
- package/dist/psdReader.js +720 -421
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +3 -0
- package/dist/psdWriter.js +167 -130
- package/dist/psdWriter.js.map +1 -1
- package/dist/text.js +143 -29
- package/dist/text.js.map +1 -1
- package/dist/utf8.js +36 -18
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.d.ts +11 -4
- package/dist-es/abr.js +363 -229
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +56 -2
- package/dist-es/additionalInfo.js +600 -364
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/ase.d.ts +6 -1
- package/dist-es/ase.js +61 -61
- package/dist-es/ase.js.map +1 -1
- package/dist-es/descriptor.d.ts +25 -6
- package/dist-es/descriptor.js +380 -135
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/effectsHelpers.js +12 -12
- package/dist-es/effectsHelpers.js.map +1 -1
- package/dist-es/engineData.d.ts +3 -1
- package/dist-es/engineData.js +34 -13
- package/dist-es/engineData.js.map +1 -1
- package/dist-es/engineData2.js +50 -21
- package/dist-es/engineData2.js.map +1 -1
- package/dist-es/helpers.d.ts +6 -3
- package/dist-es/helpers.js +22 -6
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.d.ts +15 -3
- package/dist-es/imageResources.js +529 -144
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/index.js +1 -0
- package/dist-es/index.js.map +1 -1
- package/dist-es/jpeg.js +30 -10
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psd.d.ts +154 -18
- package/dist-es/psd.js.map +1 -1
- package/dist-es/psdReader.d.ts +12 -2
- package/dist-es/psdReader.js +720 -421
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +3 -0
- package/dist-es/psdWriter.js +167 -130
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/text.js +143 -29
- package/dist-es/text.js.map +1 -1
- package/dist-es/utf8.js +36 -18
- package/dist-es/utf8.js.map +1 -1
- package/package.json +2 -2
- package/src/abr.ts +380 -232
- package/src/additionalInfo.ts +781 -477
- package/src/ase.ts +66 -61
- package/src/descriptor.ts +386 -142
- package/src/effectsHelpers.ts +9 -9
- package/src/engineData.ts +36 -13
- package/src/engineData2.ts +468 -432
- package/src/helpers.ts +23 -5
- package/src/imageResources.ts +658 -167
- package/src/index.ts +1 -0
- package/src/jpeg.ts +27 -12
- package/src/psd.ts +158 -30
- package/src/psdReader.ts +732 -414
- package/src/psdWriter.ts +186 -132
- package/src/text.ts +139 -18
- package/src/utf8.ts +35 -21
package/dist/additionalInfo.js
CHANGED
|
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.booleanOperations = exports.infoHandlersMap = exports.infoHandlers = void 0;
|
|
4
4
|
exports.readBezierKnot = readBezierKnot;
|
|
5
5
|
exports.readVectorMask = readVectorMask;
|
|
6
|
+
exports.writeVectorMask = writeVectorMask;
|
|
7
|
+
exports.parseKeyDescriptorList = parseKeyDescriptorList;
|
|
8
|
+
exports.serializeKeyDescriptorList = serializeKeyDescriptorList;
|
|
6
9
|
exports.hasMultiEffects = hasMultiEffects;
|
|
7
10
|
const base64_js_1 = require("base64-js");
|
|
8
11
|
const effectsHelpers_1 = require("./effectsHelpers");
|
|
@@ -32,11 +35,8 @@ function readLength64(reader) {
|
|
|
32
35
|
throw new Error(`Resource size above 4 GB limit at ${reader.offset.toString(16)}`);
|
|
33
36
|
return (0, psdReader_1.readUint32)(reader);
|
|
34
37
|
}
|
|
35
|
-
function writeLength64(writer, length) {
|
|
36
|
-
(0, psdWriter_1.writeUint32)(writer, 0);
|
|
37
|
-
(0, psdWriter_1.writeUint32)(writer, length);
|
|
38
|
-
}
|
|
39
38
|
addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
|
|
39
|
+
var _a;
|
|
40
40
|
if ((0, psdReader_1.readInt16)(reader) !== 1)
|
|
41
41
|
throw new Error(`Invalid TySh version`);
|
|
42
42
|
const transform = [];
|
|
@@ -74,7 +74,7 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
|
|
|
74
74
|
if (text.boundingBox)
|
|
75
75
|
target.text.boundingBox = (0, descriptor_1.descBoundsToBounds)(text.boundingBox);
|
|
76
76
|
if (text.EngineData) {
|
|
77
|
-
const engineData = (0, engineData_1.parseEngineData)(text.EngineData);
|
|
77
|
+
const engineData = (0, engineData_1.parseEngineData)(text.EngineData, reader);
|
|
78
78
|
const textData = (0, text_1.decodeEngineData)(engineData);
|
|
79
79
|
// console.log(require('util').inspect(engineData, false, 99, false), 'utf8');
|
|
80
80
|
// require('fs').writeFileSync(`layer-${target.name}.txt`, require('util').inspect(engineData, false, 99, false), 'utf8');
|
|
@@ -83,11 +83,13 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
|
|
|
83
83
|
// require('fs').writeFileSync('before.txt', require('util').inspect(before, false, 99, false), 'utf8');
|
|
84
84
|
// require('fs').writeFileSync('after.txt', require('util').inspect(after, false, 99, false), 'utf8');
|
|
85
85
|
// console.log(require('util').inspect(parseEngineData(text.EngineData), false, 99, true));
|
|
86
|
-
|
|
86
|
+
// descriptor anti-alias value is more reliable than the one from engine data
|
|
87
|
+
target.text = Object.assign(Object.assign(Object.assign({}, target.text), textData), { antiAlias: (_a = target.text.antiAlias) !== null && _a !== void 0 ? _a : textData.antiAlias });
|
|
87
88
|
// console.log(require('util').inspect(target.text, false, 99, true));
|
|
88
89
|
}
|
|
89
90
|
(0, psdReader_1.skipBytes)(reader, leftBytes());
|
|
90
91
|
}, (writer, target) => {
|
|
92
|
+
var _a, _b, _c, _d;
|
|
91
93
|
const text = target.text;
|
|
92
94
|
const warp = text.warp || {};
|
|
93
95
|
const transform = text.transform || [1, 0, 0, 1, 0, 0];
|
|
@@ -100,10 +102,10 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
|
|
|
100
102
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'TxLr', textDescriptor, 'text');
|
|
101
103
|
(0, psdWriter_1.writeInt16)(writer, 1); // warp version
|
|
102
104
|
(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);
|
|
105
|
+
(0, psdWriter_1.writeFloat32)(writer, (_a = text.left) !== null && _a !== void 0 ? _a : 0);
|
|
106
|
+
(0, psdWriter_1.writeFloat32)(writer, (_b = text.top) !== null && _b !== void 0 ? _b : 0);
|
|
107
|
+
(0, psdWriter_1.writeFloat32)(writer, (_c = text.right) !== null && _c !== void 0 ? _c : 0);
|
|
108
|
+
(0, psdWriter_1.writeFloat32)(writer, (_d = text.bottom) !== null && _d !== void 0 ? _d : 0);
|
|
107
109
|
// writeZeros(writer, 2);
|
|
108
110
|
});
|
|
109
111
|
// vector fills
|
|
@@ -212,25 +214,8 @@ function readVectorMask(reader, vectorMask, width, height, size) {
|
|
|
212
214
|
}
|
|
213
215
|
return paths;
|
|
214
216
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
throw new Error('Invalid vmsk version');
|
|
218
|
-
target.vectorMask = { paths: [] };
|
|
219
|
-
const vectorMask = target.vectorMask;
|
|
220
|
-
const flags = (0, psdReader_1.readUint32)(reader);
|
|
221
|
-
vectorMask.invert = (flags & 1) !== 0;
|
|
222
|
-
vectorMask.notLink = (flags & 2) !== 0;
|
|
223
|
-
vectorMask.disable = (flags & 4) !== 0;
|
|
224
|
-
readVectorMask(reader, vectorMask, width, height, left());
|
|
225
|
-
// drawBezierPaths(vectorMask.paths, width, height, 'out.png');
|
|
226
|
-
(0, psdReader_1.skipBytes)(reader, left());
|
|
227
|
-
}, (writer, target, { width, height }) => {
|
|
228
|
-
const vectorMask = target.vectorMask;
|
|
229
|
-
const flags = (vectorMask.invert ? 1 : 0) |
|
|
230
|
-
(vectorMask.notLink ? 2 : 0) |
|
|
231
|
-
(vectorMask.disable ? 4 : 0);
|
|
232
|
-
(0, psdWriter_1.writeUint32)(writer, 3); // version
|
|
233
|
-
(0, psdWriter_1.writeUint32)(writer, flags);
|
|
217
|
+
// componentIndices - write index of path component for each subpath (Photoshop writes them for layer vector masks)
|
|
218
|
+
function writeVectorMask(writer, vectorMask, width, height, componentIndices = false) {
|
|
234
219
|
// initial entry
|
|
235
220
|
(0, psdWriter_1.writeUint16)(writer, 6);
|
|
236
221
|
(0, psdWriter_1.writeZeros)(writer, 24);
|
|
@@ -247,12 +232,18 @@ addHandler('vmsk', hasKey('vectorMask'), (reader, target, left, { width, height
|
|
|
247
232
|
(0, psdWriter_1.writeUint16)(writer, 8);
|
|
248
233
|
(0, psdWriter_1.writeUint16)(writer, vectorMask.fillStartsWithAllPixels ? 1 : 0);
|
|
249
234
|
(0, psdWriter_1.writeZeros)(writer, 22);
|
|
235
|
+
let componentIndex = -1;
|
|
250
236
|
for (const path of vectorMask.paths) {
|
|
237
|
+
// subpaths without operation are part of the same path component as previous subpath
|
|
238
|
+
if (path.operation || componentIndex < 0)
|
|
239
|
+
componentIndex++;
|
|
251
240
|
(0, psdWriter_1.writeUint16)(writer, path.open ? 3 : 0);
|
|
252
241
|
(0, psdWriter_1.writeUint16)(writer, path.knots.length);
|
|
253
242
|
(0, psdWriter_1.writeUint16)(writer, path.operation ? exports.booleanOperations.indexOf(path.operation) : -1); // -1 for undefined
|
|
254
243
|
(0, psdWriter_1.writeUint16)(writer, path.fillRule === 'non-zero' ? 2 : 1);
|
|
255
|
-
(0, psdWriter_1.writeZeros)(writer,
|
|
244
|
+
(0, psdWriter_1.writeZeros)(writer, 4);
|
|
245
|
+
(0, psdWriter_1.writeUint32)(writer, componentIndices ? componentIndex : 0);
|
|
246
|
+
(0, psdWriter_1.writeZeros)(writer, 10);
|
|
256
247
|
const linkedKnot = path.open ? 4 : 1;
|
|
257
248
|
const unlinkedKnot = path.open ? 5 : 2;
|
|
258
249
|
for (const { linked, points } of path.knots) {
|
|
@@ -260,8 +251,29 @@ addHandler('vmsk', hasKey('vectorMask'), (reader, target, left, { width, height
|
|
|
260
251
|
writeBezierKnot(writer, points, width, height);
|
|
261
252
|
}
|
|
262
253
|
}
|
|
254
|
+
}
|
|
255
|
+
addHandler('vmsk', hasKey('vectorMask'), (reader, target, left, { width, height }) => {
|
|
256
|
+
if ((0, psdReader_1.readUint32)(reader) !== 3)
|
|
257
|
+
throw new Error('Invalid vmsk version');
|
|
258
|
+
target.vectorMask = { paths: [] };
|
|
259
|
+
const vectorMask = target.vectorMask;
|
|
260
|
+
const flags = (0, psdReader_1.readUint32)(reader);
|
|
261
|
+
vectorMask.invert = (flags & 1) !== 0;
|
|
262
|
+
vectorMask.notLink = (flags & 2) !== 0;
|
|
263
|
+
vectorMask.disable = (flags & 4) !== 0;
|
|
264
|
+
readVectorMask(reader, vectorMask, width, height, left());
|
|
265
|
+
// drawBezierPaths(vectorMask.paths, width, height, 'out.png');
|
|
266
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
267
|
+
}, (writer, target, { width, height }) => {
|
|
268
|
+
const vectorMask = target.vectorMask;
|
|
269
|
+
const flags = (vectorMask.invert ? 1 : 0) |
|
|
270
|
+
(vectorMask.notLink ? 2 : 0) |
|
|
271
|
+
(vectorMask.disable ? 4 : 0);
|
|
272
|
+
(0, psdWriter_1.writeUint32)(writer, 3); // version
|
|
273
|
+
(0, psdWriter_1.writeUint32)(writer, flags);
|
|
274
|
+
writeVectorMask(writer, vectorMask, width, height, true);
|
|
263
275
|
});
|
|
264
|
-
//
|
|
276
|
+
// written instead of 'vmsk' for layers with vector stroke ('vscg' section)
|
|
265
277
|
addHandlerAlias('vsms', 'vmsk');
|
|
266
278
|
// addHandlerAlias('vmsk', 'vsms');
|
|
267
279
|
addHandler('vowv', // something with vectors?
|
|
@@ -270,12 +282,8 @@ hasKey('vowv'), (reader, target) => {
|
|
|
270
282
|
}, (writer, target) => {
|
|
271
283
|
(0, psdWriter_1.writeUint32)(writer, target.vowv);
|
|
272
284
|
});
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
throw new Error(`Invalid vogk version`);
|
|
276
|
-
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
277
|
-
// console.log(require('util').inspect(desc, false, 99, true));
|
|
278
|
-
target.vectorOrigination = { keyDescriptorList: [] };
|
|
285
|
+
function parseKeyDescriptorList(desc) {
|
|
286
|
+
const keyDescriptorList = [];
|
|
279
287
|
for (const i of desc.keyDescriptorList) {
|
|
280
288
|
const item = {};
|
|
281
289
|
if (i.keyShapeInvalidated != null)
|
|
@@ -314,15 +322,14 @@ addHandler('vogk', hasKey('vectorOrigination'), (reader, target, left) => {
|
|
|
314
322
|
if (trnf) {
|
|
315
323
|
item.transform = [trnf.xx, trnf.xy, trnf.yx, trnf.yy, trnf.tx, trnf.ty];
|
|
316
324
|
}
|
|
317
|
-
|
|
325
|
+
keyDescriptorList.push(item);
|
|
318
326
|
}
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
const orig = target.vectorOrigination;
|
|
327
|
+
return keyDescriptorList;
|
|
328
|
+
}
|
|
329
|
+
function serializeKeyDescriptorList(keyDescriptorList) {
|
|
323
330
|
const desc = { keyDescriptorList: [] };
|
|
324
|
-
for (let i = 0; i <
|
|
325
|
-
const item =
|
|
331
|
+
for (let i = 0; i < keyDescriptorList.length; i++) {
|
|
332
|
+
const item = keyDescriptorList[i];
|
|
326
333
|
desc.keyDescriptorList.push({}); // we're adding keyOriginIndex at the end
|
|
327
334
|
const out = desc.keyDescriptorList[desc.keyDescriptorList.length - 1];
|
|
328
335
|
if (item.keyOriginType != null)
|
|
@@ -373,10 +380,21 @@ addHandler('vogk', hasKey('vectorOrigination'), (reader, target, left) => {
|
|
|
373
380
|
out.keyShapeInvalidated = item.keyShapeInvalidated;
|
|
374
381
|
out.keyOriginIndex = i;
|
|
375
382
|
}
|
|
383
|
+
return desc;
|
|
384
|
+
}
|
|
385
|
+
addHandler('vogk', hasKey('vectorOrigination'), (reader, target, left) => {
|
|
386
|
+
if ((0, psdReader_1.readInt32)(reader) !== 1)
|
|
387
|
+
throw new Error(`Invalid vogk version`);
|
|
388
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
389
|
+
// console.log(require('util').inspect(desc, false, 99, true));
|
|
390
|
+
target.vectorOrigination = { keyDescriptorList: parseKeyDescriptorList(desc) };
|
|
391
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
392
|
+
}, (writer, target) => {
|
|
393
|
+
const desc = serializeKeyDescriptorList(target.vectorOrigination.keyDescriptorList);
|
|
376
394
|
(0, psdWriter_1.writeInt32)(writer, 1); // version
|
|
377
395
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
378
396
|
});
|
|
379
|
-
addHandler('lmfx', target => target.effects !== undefined && hasMultiEffects(target.effects), (reader, target, left) => {
|
|
397
|
+
addHandler('lmfx', target => target.effects !== undefined && !isGroupLayer(target) && hasMultiEffects(target.effects), (reader, target, left) => {
|
|
380
398
|
const version = (0, psdReader_1.readUint32)(reader);
|
|
381
399
|
if (version !== 0)
|
|
382
400
|
throw new Error('Invalid lmfx version');
|
|
@@ -419,12 +437,54 @@ addHandler('luni', hasKey('name'), (reader, target, left) => {
|
|
|
419
437
|
// writeUint16(writer, 0); // padding (but not extending string length)
|
|
420
438
|
});
|
|
421
439
|
addHandler('lnsr', hasKey('nameSource'), (reader, target) => target.nameSource = (0, psdReader_1.readSignature)(reader), (writer, target) => (0, psdWriter_1.writeSignature)(writer, target.nameSource));
|
|
422
|
-
|
|
440
|
+
// these sections reference layer id
|
|
441
|
+
function layerNeedsId(target) {
|
|
442
|
+
return !!(target.animationFrames || target.timeline || target.comps);
|
|
443
|
+
}
|
|
444
|
+
function getExplicitLayerIds(psd, options) {
|
|
445
|
+
if (!options.explicitLayerIds) {
|
|
446
|
+
const ids = new Set();
|
|
447
|
+
const addIds = (layers) => {
|
|
448
|
+
for (const layer of layers !== null && layers !== void 0 ? layers : []) {
|
|
449
|
+
if (layer.id !== undefined)
|
|
450
|
+
ids.add(layer.id);
|
|
451
|
+
addIds(layer.children);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
addIds(psd.children);
|
|
455
|
+
options.explicitLayerIds = ids;
|
|
456
|
+
}
|
|
457
|
+
return options.explicitLayerIds;
|
|
458
|
+
}
|
|
459
|
+
function getLayerId(target, options) {
|
|
460
|
+
var _a;
|
|
461
|
+
const id = (_a = options.layerToId.get(target)) !== null && _a !== void 0 ? _a : target.id;
|
|
462
|
+
if (id === undefined)
|
|
463
|
+
throw new Error('Missing layer id');
|
|
464
|
+
return id;
|
|
465
|
+
}
|
|
466
|
+
addHandler('lyid', target => target.id !== undefined || layerNeedsId(target), (reader, target) => {
|
|
423
467
|
target.id = (0, psdReader_1.readUint32)(reader);
|
|
424
|
-
}, (writer, target,
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
468
|
+
}, (writer, target, psd, options) => {
|
|
469
|
+
var _a;
|
|
470
|
+
let id;
|
|
471
|
+
if (target.id !== undefined) {
|
|
472
|
+
id = target.id;
|
|
473
|
+
if (options.layerIds.has(id)) {
|
|
474
|
+
// make sure we don't have duplicate layer ids (and don't take id explicitly set on another layer)
|
|
475
|
+
const explicitIds = getExplicitLayerIds(psd, options);
|
|
476
|
+
while (options.layerIds.has(id) || explicitIds.has(id))
|
|
477
|
+
id += 100;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
// generate id for layers that don't have it, if it's referenced by other sections
|
|
482
|
+
const explicitIds = getExplicitLayerIds(psd, options);
|
|
483
|
+
id = (_a = options.nextGeneratedLayerId) !== null && _a !== void 0 ? _a : 1;
|
|
484
|
+
while (options.layerIds.has(id) || explicitIds.has(id))
|
|
485
|
+
id++;
|
|
486
|
+
options.nextGeneratedLayerId = id + 1;
|
|
487
|
+
}
|
|
428
488
|
(0, psdWriter_1.writeUint32)(writer, id);
|
|
429
489
|
options.layerIds.add(id);
|
|
430
490
|
options.layerToId.set(target, id);
|
|
@@ -488,12 +548,15 @@ addHandler('lspf', hasKey('protected'), (reader, target) => {
|
|
|
488
548
|
};
|
|
489
549
|
if (flags & 0x08)
|
|
490
550
|
target.protected.artboards = true;
|
|
551
|
+
if (flags & 0x80000000)
|
|
552
|
+
target.protected.all = true;
|
|
491
553
|
}, (writer, target) => {
|
|
492
554
|
const flags = (target.protected.transparency ? 0x01 : 0) |
|
|
493
555
|
(target.protected.composite ? 0x02 : 0) |
|
|
494
556
|
(target.protected.position ? 0x04 : 0) |
|
|
495
|
-
(target.protected.artboards ? 0x08 : 0)
|
|
496
|
-
|
|
557
|
+
(target.protected.artboards ? 0x08 : 0) |
|
|
558
|
+
(target.protected.all ? 0x80000000 : 0);
|
|
559
|
+
(0, psdWriter_1.writeUint32)(writer, flags >>> 0);
|
|
497
560
|
});
|
|
498
561
|
addHandler('lclr', hasKey('layerColor'), (reader, target) => {
|
|
499
562
|
const color = (0, psdReader_1.readUint16)(reader);
|
|
@@ -504,106 +567,160 @@ addHandler('lclr', hasKey('layerColor'), (reader, target) => {
|
|
|
504
567
|
(0, psdWriter_1.writeUint16)(writer, index === -1 ? 0 : index);
|
|
505
568
|
(0, psdWriter_1.writeZeros)(writer, 6);
|
|
506
569
|
});
|
|
570
|
+
function parseGeneratorSettings(settings) {
|
|
571
|
+
const result = {};
|
|
572
|
+
if (settings.exportAs) {
|
|
573
|
+
result.exportAs = {};
|
|
574
|
+
if (settings.exportAs.exportOption !== undefined)
|
|
575
|
+
result.exportAs.exportOption = settings.exportAs.exportOption;
|
|
576
|
+
if (settings.exportAs.scaleSettings !== undefined)
|
|
577
|
+
result.exportAs.scaleSettings = settings.exportAs.scaleSettings;
|
|
578
|
+
}
|
|
579
|
+
if (settings.generator_45_assets)
|
|
580
|
+
result.assets = settings.generator_45_assets.json;
|
|
581
|
+
if (settings.layerTime !== undefined)
|
|
582
|
+
result.layerTime = settings.layerTime;
|
|
583
|
+
if (settings.crema)
|
|
584
|
+
result.crema = settings.crema.json;
|
|
585
|
+
return result;
|
|
586
|
+
}
|
|
587
|
+
function serializeGeneratorSettings(generatorSettings) {
|
|
588
|
+
const settings = {
|
|
589
|
+
_name: '',
|
|
590
|
+
_classID: generatorSettings.assets !== undefined ? 'generatorSettings' : 'null',
|
|
591
|
+
};
|
|
592
|
+
if (generatorSettings.exportAs) {
|
|
593
|
+
settings.exportAs = { _name: '', _classID: 'null' };
|
|
594
|
+
if (generatorSettings.exportAs.exportOption !== undefined)
|
|
595
|
+
settings.exportAs.exportOption = generatorSettings.exportAs.exportOption;
|
|
596
|
+
if (generatorSettings.exportAs.scaleSettings !== undefined)
|
|
597
|
+
settings.exportAs.scaleSettings = generatorSettings.exportAs.scaleSettings;
|
|
598
|
+
}
|
|
599
|
+
if (generatorSettings.assets !== undefined)
|
|
600
|
+
settings.generator_45_assets = { _name: '', _classID: 'generatorSettings', json: generatorSettings.assets };
|
|
601
|
+
if (generatorSettings.layerTime !== undefined)
|
|
602
|
+
settings.layerTime = generatorSettings.layerTime;
|
|
603
|
+
if (generatorSettings.crema !== undefined)
|
|
604
|
+
settings.crema = { _name: '', _classID: 'null', json: generatorSettings.crema };
|
|
605
|
+
return { generatorSettings: settings };
|
|
606
|
+
}
|
|
607
|
+
// document (Psd object) stores generator settings in 'extn' section instead of 'shmd' section
|
|
608
|
+
function isDocument(target) {
|
|
609
|
+
return target.width !== undefined;
|
|
610
|
+
}
|
|
507
611
|
addHandler('shmd', // Metadata setting
|
|
508
612
|
// Metadata setting
|
|
509
|
-
target => target.timestamp !== undefined || target.animationFrames !== undefined || target.animationFrameFlags !== undefined || target.timeline !== undefined || target.comps !== undefined
|
|
613
|
+
target => target.timestamp !== undefined || target.animationFrames !== undefined || target.animationFrameFlags !== undefined || target.timeline !== undefined || target.comps !== undefined ||
|
|
614
|
+
(target.generatorSettings !== undefined && !isDocument(target)), (reader, target, left) => {
|
|
510
615
|
const count = (0, psdReader_1.readUint32)(reader);
|
|
511
616
|
for (let i = 0; i < count; i++) {
|
|
512
|
-
(0, psdReader_1.
|
|
617
|
+
const signature = (0, psdReader_1.readSignature)(reader);
|
|
618
|
+
if (signature !== '8BIM' && signature !== '8ELE')
|
|
619
|
+
throw new Error(`Invalid shmd signature: '${signature}'`); // 8ELE in Photoshop Elements
|
|
513
620
|
const key = (0, psdReader_1.readSignature)(reader);
|
|
514
621
|
(0, psdReader_1.readUint8)(reader); // copy
|
|
515
622
|
(0, psdReader_1.skipBytes)(reader, 3);
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
target.
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
525
|
-
// console.log('mlst', target.name, require('util').inspect(desc, false, 99, true));
|
|
526
|
-
target.animationFrames = [];
|
|
527
|
-
for (let i = 0; i < desc.LaSt.length; i++) {
|
|
528
|
-
const f = desc.LaSt[i];
|
|
529
|
-
const frame = { frames: f.FrLs };
|
|
530
|
-
if (f.enab !== undefined)
|
|
531
|
-
frame.enable = f.enab;
|
|
532
|
-
if (f.Ofst)
|
|
533
|
-
frame.offset = (0, descriptor_1.horzVrtcToXY)(f.Ofst);
|
|
534
|
-
if (f.FXRf)
|
|
535
|
-
frame.referencePoint = (0, descriptor_1.horzVrtcToXY)(f.FXRf);
|
|
536
|
-
if (f.Lefx)
|
|
537
|
-
frame.effects = (0, descriptor_1.parseEffects)(f.Lefx, !!reader.logMissingFeatures);
|
|
538
|
-
if (f.blendOptions && f.blendOptions.Opct)
|
|
539
|
-
frame.opacity = (0, descriptor_1.parsePercent)(f.blendOptions.Opct);
|
|
540
|
-
target.animationFrames.push(frame);
|
|
623
|
+
const end = reader.offset + 4 + reader.view.getUint32(reader.offset);
|
|
624
|
+
try {
|
|
625
|
+
(0, psdReader_1.readSection)(reader, 1, left => {
|
|
626
|
+
if (key === 'cust') {
|
|
627
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
628
|
+
// console.log('cust', target.name, require('util').inspect(desc, false, 99, true));
|
|
629
|
+
if (desc.layerTime !== undefined)
|
|
630
|
+
target.timestamp = desc.layerTime;
|
|
541
631
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
duration: (0, descriptor_1.frac)(timeScope.duration),
|
|
562
|
-
inTime: (0, descriptor_1.frac)(timeScope.inTime),
|
|
563
|
-
outTime: (0, descriptor_1.frac)(timeScope.outTime),
|
|
564
|
-
autoScope: desc.autoScope,
|
|
565
|
-
audioLevel: desc.audioLevel,
|
|
566
|
-
};
|
|
567
|
-
if (desc.trackList) {
|
|
568
|
-
timeline.tracks = (0, descriptor_1.parseTrackList)(desc.trackList, !!reader.logMissingFeatures);
|
|
632
|
+
else if (key === 'mlst') {
|
|
633
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
634
|
+
// console.log('mlst', target.name, require('util').inspect(desc, false, 99, true));
|
|
635
|
+
target.animationFrames = [];
|
|
636
|
+
for (let i = 0; i < desc.LaSt.length; i++) {
|
|
637
|
+
const f = desc.LaSt[i];
|
|
638
|
+
const frame = { frames: f.FrLs };
|
|
639
|
+
if (f.enab !== undefined)
|
|
640
|
+
frame.enable = f.enab;
|
|
641
|
+
if (f.Ofst)
|
|
642
|
+
frame.offset = (0, descriptor_1.horzVrtcToXY)(f.Ofst);
|
|
643
|
+
if (f.FXRf)
|
|
644
|
+
frame.referencePoint = (0, descriptor_1.horzVrtcToXY)(f.FXRf);
|
|
645
|
+
if (f.Lefx)
|
|
646
|
+
frame.effects = (0, descriptor_1.parseEffects)(f.Lefx, !!reader.logMissingFeatures);
|
|
647
|
+
if (f.blendOptions && f.blendOptions.Opct)
|
|
648
|
+
frame.opacity = (0, descriptor_1.parsePercent)(f.blendOptions.Opct);
|
|
649
|
+
target.animationFrames.push(frame);
|
|
650
|
+
}
|
|
569
651
|
}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
for (const item of desc.layerSettings) {
|
|
582
|
-
target.comps.settings.push({ compList: item.compList });
|
|
583
|
-
const t = target.comps.settings[target.comps.settings.length - 1];
|
|
584
|
-
if ('enab' in item)
|
|
585
|
-
t.enabled = item.enab;
|
|
586
|
-
if (item.Ofst)
|
|
587
|
-
t.offset = { x: item.Ofst.Hrzn, y: item.Ofst.Vrtc };
|
|
588
|
-
if (item.FXRefPoint)
|
|
589
|
-
t.effectsReferencePoint = { x: item.FXRefPoint.Hrzn, y: item.FXRefPoint.Vrtc };
|
|
652
|
+
else if (key === 'mdyn') {
|
|
653
|
+
// frame flags
|
|
654
|
+
(0, psdReader_1.readUint16)(reader); // unknown
|
|
655
|
+
const propagate = (0, psdReader_1.readUint8)(reader);
|
|
656
|
+
const flags = (0, psdReader_1.readUint8)(reader);
|
|
657
|
+
target.animationFrameFlags = {
|
|
658
|
+
propagateFrameOne: !propagate,
|
|
659
|
+
unifyLayerPosition: (flags & 1) !== 0,
|
|
660
|
+
unifyLayerStyle: (flags & 2) !== 0,
|
|
661
|
+
unifyLayerVisibility: (flags & 4) !== 0,
|
|
662
|
+
};
|
|
590
663
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
664
|
+
else if (key === 'tmln') {
|
|
665
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
666
|
+
const timeScope = desc.timeScope;
|
|
667
|
+
// console.log('tmln', target.name, target.id, require('util').inspect(desc, false, 99, true));
|
|
668
|
+
const timeline = {
|
|
669
|
+
start: (0, descriptor_1.frac)(timeScope.Strt),
|
|
670
|
+
duration: (0, descriptor_1.frac)(timeScope.duration),
|
|
671
|
+
inTime: (0, descriptor_1.frac)(timeScope.inTime),
|
|
672
|
+
outTime: (0, descriptor_1.frac)(timeScope.outTime),
|
|
673
|
+
autoScope: desc.autoScope,
|
|
674
|
+
audioLevel: desc.audioLevel,
|
|
675
|
+
};
|
|
676
|
+
if (desc.trackList) {
|
|
677
|
+
timeline.tracks = (0, descriptor_1.parseTrackList)(desc.trackList, !!reader.logMissingFeatures);
|
|
678
|
+
}
|
|
679
|
+
target.timeline = timeline;
|
|
680
|
+
// console.log('tmln:result', target.name, target.id, require('util').inspect(timeline, false, 99, true));
|
|
681
|
+
}
|
|
682
|
+
else if (key === 'cmls') {
|
|
683
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
684
|
+
// console.log('cmls', require('util').inspect(desc, false, 99, true));
|
|
685
|
+
target.comps = {
|
|
686
|
+
settings: [],
|
|
687
|
+
};
|
|
688
|
+
if (desc.origFXRefPoint)
|
|
689
|
+
target.comps.originalEffectsReferencePoint = { x: desc.origFXRefPoint.Hrzn, y: desc.origFXRefPoint.Vrtc };
|
|
690
|
+
for (const item of desc.layerSettings) {
|
|
691
|
+
target.comps.settings.push({ compList: item.compList });
|
|
692
|
+
const t = target.comps.settings[target.comps.settings.length - 1];
|
|
693
|
+
if ('enab' in item)
|
|
694
|
+
t.enabled = item.enab;
|
|
695
|
+
if (item.Ofst)
|
|
696
|
+
t.offset = { x: item.Ofst.Hrzn, y: item.Ofst.Vrtc };
|
|
697
|
+
if (item.FXRefPoint)
|
|
698
|
+
t.effectsReferencePoint = { x: item.FXRefPoint.Hrzn, y: item.FXRefPoint.Vrtc };
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
else if (key === 'extn') {
|
|
702
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
703
|
+
if (desc.generatorSettings)
|
|
704
|
+
target.generatorSettings = parseGeneratorSettings(desc.generatorSettings);
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
reader.logMissingFeatures && reader.log('Unhandled "shmd" section key', key);
|
|
708
|
+
}
|
|
709
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
catch (e) {
|
|
713
|
+
// failure to read one item shouldn't drop all other items
|
|
714
|
+
if (reader.throwForMissingFeatures)
|
|
715
|
+
throw e;
|
|
716
|
+
reader.logMissingFeatures && reader.log(`Failed to read "shmd" section key ${key}: ${e.message}`);
|
|
717
|
+
reader.offset = end;
|
|
718
|
+
}
|
|
603
719
|
}
|
|
604
720
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
605
721
|
}, (writer, target, _, options) => {
|
|
606
722
|
const { animationFrames, animationFrameFlags, timestamp, timeline, comps } = target;
|
|
723
|
+
const generatorSettings = isDocument(target) ? undefined : target.generatorSettings;
|
|
607
724
|
let count = 0;
|
|
608
725
|
if (animationFrames)
|
|
609
726
|
count++;
|
|
@@ -615,6 +732,8 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
615
732
|
count++;
|
|
616
733
|
if (comps)
|
|
617
734
|
count++;
|
|
735
|
+
if (generatorSettings)
|
|
736
|
+
count++;
|
|
618
737
|
(0, psdWriter_1.writeUint32)(writer, count);
|
|
619
738
|
if (animationFrames) {
|
|
620
739
|
(0, psdWriter_1.writeSignature)(writer, '8BIM');
|
|
@@ -622,9 +741,8 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
622
741
|
(0, psdWriter_1.writeUint8)(writer, 0); // copy (always false)
|
|
623
742
|
(0, psdWriter_1.writeZeros)(writer, 3);
|
|
624
743
|
(0, psdWriter_1.writeSection)(writer, 2, () => {
|
|
625
|
-
var _a;
|
|
626
744
|
const desc = {
|
|
627
|
-
LaID: (
|
|
745
|
+
LaID: getLayerId(target, options),
|
|
628
746
|
LaSt: [],
|
|
629
747
|
};
|
|
630
748
|
for (let i = 0; i < animationFrames.length; i++) {
|
|
@@ -638,9 +756,9 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
638
756
|
if (f.referencePoint)
|
|
639
757
|
frame.FXRf = (0, descriptor_1.xyToHorzVrtc)(f.referencePoint);
|
|
640
758
|
if (f.effects)
|
|
641
|
-
frame.Lefx = (0, descriptor_1.serializeEffects)(f.effects, false,
|
|
759
|
+
frame.Lefx = (0, descriptor_1.serializeEffects)(f.effects, false, hasMultiEffects(f.effects));
|
|
642
760
|
if (f.opacity !== undefined)
|
|
643
|
-
frame.blendOptions = { Opct: (0, descriptor_1.
|
|
761
|
+
frame.blendOptions = { Opct: (0, descriptor_1.unitsPercentF)(f.opacity) };
|
|
644
762
|
desc.LaSt.push(frame);
|
|
645
763
|
}
|
|
646
764
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
@@ -680,10 +798,7 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
680
798
|
if (timeline.tracks) {
|
|
681
799
|
desc.trackList = (0, descriptor_1.serializeTrackList)(timeline.tracks);
|
|
682
800
|
}
|
|
683
|
-
|
|
684
|
-
if (!id)
|
|
685
|
-
throw new Error('You need to provide layer.id value whan writing document with animations');
|
|
686
|
-
desc.LyrI = id;
|
|
801
|
+
desc.LyrI = getLayerId(target, options);
|
|
687
802
|
// console.log('WRITE:tmln', target.name, target.id, require('util').inspect(desc, false, 99, true));
|
|
688
803
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc, 'anim');
|
|
689
804
|
}, true);
|
|
@@ -706,14 +821,11 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
706
821
|
(0, psdWriter_1.writeUint8)(writer, 0); // copy (always false)
|
|
707
822
|
(0, psdWriter_1.writeZeros)(writer, 3);
|
|
708
823
|
(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
824
|
const desc = {};
|
|
713
825
|
if (comps.originalEffectsReferencePoint) {
|
|
714
826
|
desc.origFXRefPoint = { Hrzn: comps.originalEffectsReferencePoint.x, Vrtc: comps.originalEffectsReferencePoint.y };
|
|
715
827
|
}
|
|
716
|
-
desc.LyrI =
|
|
828
|
+
desc.LyrI = getLayerId(target, options);
|
|
717
829
|
desc.layerSettings = [];
|
|
718
830
|
for (const item of comps.settings) {
|
|
719
831
|
const t = {};
|
|
@@ -730,8 +842,17 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
730
842
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
731
843
|
}, true);
|
|
732
844
|
}
|
|
845
|
+
if (generatorSettings) {
|
|
846
|
+
(0, psdWriter_1.writeSignature)(writer, '8BIM');
|
|
847
|
+
(0, psdWriter_1.writeSignature)(writer, 'extn');
|
|
848
|
+
(0, psdWriter_1.writeUint8)(writer, 0); // copy (always false)
|
|
849
|
+
(0, psdWriter_1.writeZeros)(writer, 3);
|
|
850
|
+
(0, psdWriter_1.writeSection)(writer, 2, () => {
|
|
851
|
+
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', serializeGeneratorSettings(generatorSettings));
|
|
852
|
+
}, true);
|
|
853
|
+
}
|
|
733
854
|
});
|
|
734
|
-
addHandler('PxSc', ()
|
|
855
|
+
addHandler('PxSc', hasKey('pixelSource'), (reader, target) => {
|
|
735
856
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
|
|
736
857
|
// console.log('PxSc', require('util').inspect(desc, false, 99, true));
|
|
737
858
|
if (desc.pixelSourceType === 1986285651) {
|
|
@@ -766,7 +887,7 @@ addHandler('PxSc', () => false, (reader, target) => {
|
|
|
766
887
|
_classID: 'PixelSource',
|
|
767
888
|
pixelSourceType: 1986285651, // vdP
|
|
768
889
|
descVersion: 1,
|
|
769
|
-
origin: { Hrzn: source.origin.x, Vrtc: source.origin.y },
|
|
890
|
+
origin: { Hrzn: source.origin.x, Vrtc: source.origin.y }, // written as 'null' class with 'long' values (see writeDescriptorStructure)
|
|
770
891
|
interpretation: {
|
|
771
892
|
_name: '',
|
|
772
893
|
_classID: 'footageInterpretation',
|
|
@@ -809,7 +930,7 @@ addHandler('vstk', hasKey('vectorStroke'), (reader, target, left) => {
|
|
|
809
930
|
lineAlignment: descriptor_1.strokeStyleLineAlignment.decode(desc.strokeStyleLineAlignment),
|
|
810
931
|
scaleLock: desc.strokeStyleScaleLock,
|
|
811
932
|
strokeAdjust: desc.strokeStyleStrokeAdjust,
|
|
812
|
-
lineDashSet: desc.strokeStyleLineDashSet.map(descriptor_1.parseUnits),
|
|
933
|
+
lineDashSet: (desc.strokeStyleLineDashSet || []).map(descriptor_1.parseUnits),
|
|
813
934
|
blendMode: descriptor_1.BlnM.decode(desc.strokeStyleBlendMode),
|
|
814
935
|
opacity: (0, descriptor_1.parsePercent)(desc.strokeStyleOpacity),
|
|
815
936
|
content: (0, descriptor_1.parseVectorContent)(desc.strokeStyleContent),
|
|
@@ -847,9 +968,11 @@ hasKey('artboard'), (reader, target, left) => {
|
|
|
847
968
|
rect: { top: rect['Top '], left: rect.Left, bottom: rect.Btom, right: rect.Rght },
|
|
848
969
|
guideIndices: desc.guideIndeces,
|
|
849
970
|
presetName: desc.artboardPresetName,
|
|
850
|
-
color: (0, descriptor_1.parseColor)(desc['Clr ']),
|
|
851
|
-
backgroundType: desc.artboardBackgroundType,
|
|
852
971
|
};
|
|
972
|
+
if (desc['Clr '])
|
|
973
|
+
target.artboard.color = (0, descriptor_1.parseColor)(desc['Clr ']);
|
|
974
|
+
if (desc.artboardBackgroundType !== undefined)
|
|
975
|
+
target.artboard.backgroundType = desc.artboardBackgroundType;
|
|
853
976
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
854
977
|
}, (writer, target) => {
|
|
855
978
|
var _a;
|
|
@@ -955,14 +1078,15 @@ function encodeWarp(warp) {
|
|
|
955
1078
|
}
|
|
956
1079
|
return desc;
|
|
957
1080
|
}
|
|
958
|
-
addHandler('PlLd',
|
|
1081
|
+
addHandler('PlLd', target => !!target.placedLayer && !target.placedLayer.external, // linked smart objects are stored in SoLE
|
|
1082
|
+
(reader, target, left) => {
|
|
959
1083
|
if ((0, psdReader_1.readSignature)(reader) !== 'plcL')
|
|
960
1084
|
throw new Error(`Invalid PlLd signature`);
|
|
961
1085
|
if ((0, psdReader_1.readInt32)(reader) !== 3)
|
|
962
1086
|
throw new Error(`Invalid PlLd version`);
|
|
963
1087
|
const id = (0, psdReader_1.readPascalString)(reader, 1);
|
|
964
1088
|
const pageNumber = (0, psdReader_1.readInt32)(reader);
|
|
965
|
-
const totalPages = (0, psdReader_1.readInt32)(reader); //
|
|
1089
|
+
const totalPages = (0, psdReader_1.readInt32)(reader); // for multi-page documents (PDF)
|
|
966
1090
|
(0, psdReader_1.readInt32)(reader); // anitAliasPolicy 16
|
|
967
1091
|
const placedLayerType = (0, psdReader_1.readInt32)(reader); // 0 = unknown, 1 = vector, 2 = raster, 3 = image stack
|
|
968
1092
|
if (!placedLayerTypes[placedLayerType])
|
|
@@ -1007,11 +1131,15 @@ addHandler('PlLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
1007
1131
|
const type = isQuilt ? 'quiltWarp' : 'warp';
|
|
1008
1132
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', type, encodeWarp(warp), type);
|
|
1009
1133
|
});
|
|
1134
|
+
const levelsFilterKeys = ['_name', '_classID', 'presetKind', 'Adjs'];
|
|
1135
|
+
const levelsFilterAdjustmentKeys = ['_name', '_classID', 'Chnl', 'Inpt', 'Otpt', 'Gmm '];
|
|
1010
1136
|
function uint8ToFloat32(array) {
|
|
1011
|
-
|
|
1137
|
+
const length = Math.floor(array.byteLength / 4);
|
|
1138
|
+
return new Float32Array(array.buffer.slice(array.byteOffset, array.byteOffset + length * 4), 0, length);
|
|
1012
1139
|
}
|
|
1013
1140
|
function uint8ToUint32(array) {
|
|
1014
|
-
|
|
1141
|
+
const length = Math.floor(array.byteLength / 4);
|
|
1142
|
+
return new Uint32Array(array.buffer.slice(array.byteOffset, array.byteOffset + length * 4), 0, length);
|
|
1015
1143
|
}
|
|
1016
1144
|
function toUint8(array) {
|
|
1017
1145
|
return new Uint8Array(array.buffer, array.byteOffset, array.byteLength);
|
|
@@ -1047,7 +1175,7 @@ function pointToHrznVrtc(point) {
|
|
|
1047
1175
|
Vrtc: (0, descriptor_1.unitsValue)(point.y, 'y'),
|
|
1048
1176
|
};
|
|
1049
1177
|
}
|
|
1050
|
-
function parseFilterFXItem(f,
|
|
1178
|
+
function parseFilterFXItem(f, reader) {
|
|
1051
1179
|
const base = {
|
|
1052
1180
|
name: f['Nm '],
|
|
1053
1181
|
opacity: (0, descriptor_1.parsePercent)(f.blendOptions.Opct),
|
|
@@ -1095,7 +1223,7 @@ function parseFilterFXItem(f, options) {
|
|
|
1095
1223
|
undefinedAreas: descriptor_1.UndA.decode(f.Fltr.UndA),
|
|
1096
1224
|
displacementFile: {
|
|
1097
1225
|
signature: f.Fltr.DspF.sig,
|
|
1098
|
-
path: f.Fltr.DspF.path,
|
|
1226
|
+
path: f.Fltr.DspF.path,
|
|
1099
1227
|
},
|
|
1100
1228
|
} });
|
|
1101
1229
|
case 'Pnch': return Object.assign(Object.assign({}, base), { type: 'pinch', filter: {
|
|
@@ -1280,10 +1408,9 @@ function parseFilterFXItem(f, options) {
|
|
|
1280
1408
|
{ x: f.Fltr.PuX2, y: f.Fltr.PuY2, },
|
|
1281
1409
|
{ x: f.Fltr.PuX3, y: f.Fltr.PuY3, },
|
|
1282
1410
|
],
|
|
1283
|
-
puppetShapeList: f.Fltr.puppetShapeList.map(p => ({
|
|
1411
|
+
puppetShapeList: (f.Fltr.puppetShapeList || []).map(p => ({
|
|
1284
1412
|
rigidType: p.rigidType,
|
|
1285
|
-
//
|
|
1286
|
-
// TODO: VrsN
|
|
1413
|
+
// VrsM / VrsN - version (always 1.0)
|
|
1287
1414
|
originalVertexArray: uint8ToPoints(p.originalVertexArray),
|
|
1288
1415
|
deformedVertexArray: uint8ToPoints(p.deformedVertexArray),
|
|
1289
1416
|
indexArray: Array.from(uint8ToUint32(p.indexArray)),
|
|
@@ -1380,7 +1507,7 @@ function parseFilterFXItem(f, options) {
|
|
|
1380
1507
|
;
|
|
1381
1508
|
case 'Crvs':
|
|
1382
1509
|
{
|
|
1383
|
-
return Object.assign(Object.assign({}, base), { type: 'curves', filter: Object.assign({ presetKind: descriptor_1.presetKindType.decode(f.Fltr.presetKind) }, (f.Fltr.Adjs ? {
|
|
1510
|
+
return Object.assign(Object.assign({}, base), { type: 'curves', filter: Object.assign(Object.assign({}, (f.Fltr.presetKind !== undefined ? { presetKind: descriptor_1.presetKindType.decode(f.Fltr.presetKind) } : {})), (f.Fltr.Adjs ? {
|
|
1384
1511
|
adjustments: f.Fltr.Adjs.map(a => {
|
|
1385
1512
|
const channels = a.Chnl.map(descriptor_1.Chnl.decode);
|
|
1386
1513
|
if (a['Crv ']) {
|
|
@@ -1404,6 +1531,35 @@ function parseFilterFXItem(f, options) {
|
|
|
1404
1531
|
} : {})) });
|
|
1405
1532
|
}
|
|
1406
1533
|
;
|
|
1534
|
+
case 'Lvls':
|
|
1535
|
+
{
|
|
1536
|
+
const adjustments = f.Fltr.Adjs;
|
|
1537
|
+
const isKnown = (obj, keys) => Object.keys(obj).every(k => keys.indexOf(k) !== -1);
|
|
1538
|
+
// skip filter with settings we don't know about
|
|
1539
|
+
if (!isKnown(f.Fltr, levelsFilterKeys) || (adjustments && !adjustments.every(a => isKnown(a, levelsFilterAdjustmentKeys)))) {
|
|
1540
|
+
if (reader.throwForMissingFeatures)
|
|
1541
|
+
throw new Error('Unknown levels filter settings');
|
|
1542
|
+
reader.logMissingFeatures && reader.log(`Skipped levels smart filter with unknown settings`);
|
|
1543
|
+
return undefined;
|
|
1544
|
+
}
|
|
1545
|
+
return Object.assign(Object.assign({}, base), { type: 'levels', filter: Object.assign(Object.assign({}, (f.Fltr.presetKind !== undefined ? { presetKind: descriptor_1.presetKindType.decode(f.Fltr.presetKind) } : {})), (adjustments ? {
|
|
1546
|
+
adjustments: adjustments.map(a => {
|
|
1547
|
+
const result = { channels: a.Chnl.map(descriptor_1.Chnl.decode) };
|
|
1548
|
+
if (a.Inpt) {
|
|
1549
|
+
result.shadowInput = a.Inpt[0];
|
|
1550
|
+
result.highlightInput = a.Inpt[1];
|
|
1551
|
+
}
|
|
1552
|
+
if (a.Otpt) {
|
|
1553
|
+
result.shadowOutput = a.Otpt[0];
|
|
1554
|
+
result.highlightOutput = a.Otpt[1];
|
|
1555
|
+
}
|
|
1556
|
+
if (a['Gmm '] !== undefined)
|
|
1557
|
+
result.midtoneInput = a['Gmm '];
|
|
1558
|
+
return result;
|
|
1559
|
+
}),
|
|
1560
|
+
} : {})) });
|
|
1561
|
+
}
|
|
1562
|
+
;
|
|
1407
1563
|
case 'BrgC':
|
|
1408
1564
|
{
|
|
1409
1565
|
return Object.assign(Object.assign({}, base), { type: 'brightness/contrast', filter: {
|
|
@@ -1414,10 +1570,11 @@ function parseFilterFXItem(f, options) {
|
|
|
1414
1570
|
}
|
|
1415
1571
|
;
|
|
1416
1572
|
default:
|
|
1417
|
-
if (
|
|
1573
|
+
if (reader.throwForMissingFeatures) {
|
|
1418
1574
|
// console.log('FILTER', require('util').inspect(f, false, 99, true));
|
|
1419
1575
|
throw new Error(`Unknown filter classId: ${f.Fltr._classID}`);
|
|
1420
1576
|
}
|
|
1577
|
+
reader.logMissingFeatures && reader.log(`Unhandled smart filter: ${f.Fltr._classID} (${f['Nm ']})`);
|
|
1421
1578
|
return undefined;
|
|
1422
1579
|
}
|
|
1423
1580
|
}
|
|
@@ -1437,21 +1594,23 @@ function parseFilterFXItem(f, options) {
|
|
|
1437
1594
|
case 1314149187: return Object.assign(Object.assign({}, base), { type: 'ntsc colors' });
|
|
1438
1595
|
case 1231976050: return Object.assign(Object.assign({}, base), { type: 'invert' });
|
|
1439
1596
|
default:
|
|
1440
|
-
if (
|
|
1597
|
+
if (reader.throwForMissingFeatures) {
|
|
1441
1598
|
// console.log('FILTER', require('util').inspect(f, false, 99, true));
|
|
1442
1599
|
throw new Error(`Unknown filterID: ${f.filterID}`);
|
|
1443
1600
|
}
|
|
1601
|
+
reader.logMissingFeatures && reader.log(`Unhandled smart filter: ${f.filterID} (${f['Nm ']})`);
|
|
1602
|
+
return undefined;
|
|
1444
1603
|
}
|
|
1445
1604
|
}
|
|
1446
1605
|
}
|
|
1447
|
-
function parseFilterFX(desc,
|
|
1606
|
+
function parseFilterFX(desc, reader) {
|
|
1448
1607
|
return {
|
|
1449
1608
|
enabled: desc.enab,
|
|
1450
1609
|
validAtPosition: desc.validAtPosition,
|
|
1451
1610
|
maskEnabled: desc.filterMaskEnable,
|
|
1452
1611
|
maskLinked: desc.filterMaskLinked,
|
|
1453
1612
|
maskExtendWithWhite: desc.filterMaskExtendWithWhite,
|
|
1454
|
-
list: desc.filterFXList.map(x => parseFilterFXItem(x,
|
|
1613
|
+
list: desc.filterFXList.map(x => parseFilterFXItem(x, reader)).filter((x) => !!x),
|
|
1455
1614
|
};
|
|
1456
1615
|
}
|
|
1457
1616
|
function uvRadius(t) {
|
|
@@ -1807,14 +1966,14 @@ function serializeFilterFXItem(f) {
|
|
|
1807
1966
|
case 'puppet': return Object.assign(Object.assign({}, base), { Fltr: {
|
|
1808
1967
|
_name: 'Rigid Transform',
|
|
1809
1968
|
_classID: 'rigidTransform',
|
|
1810
|
-
'null': ['Ordn.Trgt'], //
|
|
1969
|
+
'null': ['Ordn.Trgt'], // target layer reference
|
|
1811
1970
|
rigidType: f.filter.rigidType,
|
|
1812
|
-
puppetShapeList: f.filter.puppetShapeList.map(p => ({
|
|
1971
|
+
puppetShapeList: (f.filter.puppetShapeList || []).map(p => ({
|
|
1813
1972
|
_name: '',
|
|
1814
1973
|
_classID: 'puppetShape',
|
|
1815
1974
|
rigidType: p.rigidType,
|
|
1816
|
-
VrsM: 1, //
|
|
1817
|
-
VrsN: 0, //
|
|
1975
|
+
VrsM: 1, // version major
|
|
1976
|
+
VrsN: 0, // version minor
|
|
1818
1977
|
originalVertexArray: toUint8(new Float32Array(pointsToArray(p.originalVertexArray))),
|
|
1819
1978
|
deformedVertexArray: toUint8(new Float32Array(pointsToArray(p.deformedVertexArray))),
|
|
1820
1979
|
indexArray: toUint8(new Uint32Array(p.indexArray)),
|
|
@@ -1894,9 +2053,9 @@ function serializeFilterFXItem(f) {
|
|
|
1894
2053
|
_classID: 'perspectiveWarpTransform',
|
|
1895
2054
|
vertices: f.filter.vertices.map(pointToHrznVrtc),
|
|
1896
2055
|
warpedVertices: f.filter.warpedVertices.map(pointToHrznVrtc),
|
|
1897
|
-
quads: f.filter.quads.map(indices => ({ indices })),
|
|
2056
|
+
quads: f.filter.quads.map(indices => ({ _name: '', _classID: 'quadIndices', indices })),
|
|
1898
2057
|
}, filterID: 442 });
|
|
1899
|
-
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 ? {
|
|
2058
|
+
case 'curves': return Object.assign(Object.assign({}, base), { Fltr: Object.assign(Object.assign({ _name: 'Curves', _classID: 'Crvs' }, (f.filter.presetKind !== undefined ? { presetKind: descriptor_1.presetKindType.encode(f.filter.presetKind) } : {})), (f.filter.adjustments ? {
|
|
1900
2059
|
Adjs: f.filter.adjustments.map(a => 'curve' in a ? {
|
|
1901
2060
|
_name: '',
|
|
1902
2061
|
_classID: 'CrvA',
|
|
@@ -1909,6 +2068,21 @@ function serializeFilterFXItem(f) {
|
|
|
1909
2068
|
Mpng: a.values,
|
|
1910
2069
|
})
|
|
1911
2070
|
} : {})), filterID: 1131574899 });
|
|
2071
|
+
case 'levels': return Object.assign(Object.assign({}, base), { Fltr: Object.assign(Object.assign({ _name: 'Levels', _classID: 'Lvls' }, (f.filter.presetKind !== undefined ? { presetKind: descriptor_1.presetKindType.encode(f.filter.presetKind) } : {})), (f.filter.adjustments ? {
|
|
2072
|
+
Adjs: f.filter.adjustments.map(a => {
|
|
2073
|
+
var _a, _b, _c, _d;
|
|
2074
|
+
const adjustment = { _name: '', _classID: 'LvlA', Chnl: a.channels.map(descriptor_1.Chnl.encode) };
|
|
2075
|
+
if (a.shadowInput !== undefined || a.highlightInput !== undefined) {
|
|
2076
|
+
adjustment.Inpt = [Math.round((_a = a.shadowInput) !== null && _a !== void 0 ? _a : 0), Math.round((_b = a.highlightInput) !== null && _b !== void 0 ? _b : 255)];
|
|
2077
|
+
}
|
|
2078
|
+
if (a.shadowOutput !== undefined || a.highlightOutput !== undefined) {
|
|
2079
|
+
adjustment.Otpt = [Math.round((_c = a.shadowOutput) !== null && _c !== void 0 ? _c : 0), Math.round((_d = a.highlightOutput) !== null && _d !== void 0 ? _d : 255)];
|
|
2080
|
+
}
|
|
2081
|
+
if (a.midtoneInput !== undefined)
|
|
2082
|
+
adjustment['Gmm '] = a.midtoneInput;
|
|
2083
|
+
return adjustment;
|
|
2084
|
+
}),
|
|
2085
|
+
} : {})), filterID: 1282829427 });
|
|
1912
2086
|
case 'brightness/contrast': return Object.assign(Object.assign({}, base), { Fltr: {
|
|
1913
2087
|
_name: 'Brightness/Contrast',
|
|
1914
2088
|
_classID: 'BrgC',
|
|
@@ -1916,10 +2090,13 @@ function serializeFilterFXItem(f) {
|
|
|
1916
2090
|
Cntr: f.filter.contrast,
|
|
1917
2091
|
useLegacy: !!f.filter.useLegacy,
|
|
1918
2092
|
}, filterID: 1114793795 });
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
2093
|
+
case 'hsb/hsl': return Object.assign(Object.assign({}, base), { Fltr: {
|
|
2094
|
+
_name: 'HSB/HSL',
|
|
2095
|
+
_classID: 'HsbP',
|
|
2096
|
+
Inpt: descriptor_1.ClrS.encode(f.filter.inputMode),
|
|
2097
|
+
Otpt: descriptor_1.ClrS.encode(f.filter.rowOrder),
|
|
2098
|
+
}, filterID: 1215521360 });
|
|
2099
|
+
default: throw new Error(`Unknown filter type: ${f.type}`);
|
|
1923
2100
|
}
|
|
1924
2101
|
}
|
|
1925
2102
|
// let t: any;
|
|
@@ -1956,7 +2133,8 @@ function getWarpFromPlacedLayer(placed) {
|
|
|
1956
2133
|
},
|
|
1957
2134
|
};
|
|
1958
2135
|
}
|
|
1959
|
-
addHandler('SoLd',
|
|
2136
|
+
addHandler('SoLd', target => !!target.placedLayer && !target.placedLayer.external, // linked smart objects are stored in SoLE
|
|
2137
|
+
(reader, target, left) => {
|
|
1960
2138
|
if ((0, psdReader_1.readSignature)(reader) !== 'soLD')
|
|
1961
2139
|
throw new Error(`Invalid SoLd type`);
|
|
1962
2140
|
const version = (0, psdReader_1.readInt32)(reader);
|
|
@@ -2010,13 +2188,21 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
2010
2188
|
if (!placed.id || typeof placed.id !== 'string' || !/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/.test(placed.id)) {
|
|
2011
2189
|
throw new Error('Placed layer ID must be in a GUID format (example: 20953ddb-9391-11ec-b4f1-c15674f50bc4)');
|
|
2012
2190
|
}
|
|
2013
|
-
const
|
|
2191
|
+
const placedType = placedLayerTypes.indexOf(placed.type);
|
|
2192
|
+
if (placedType === -1)
|
|
2193
|
+
throw new Error('Invalid placedLayer type');
|
|
2194
|
+
const warp = getWarpFromPlacedLayer(placed);
|
|
2195
|
+
// size of linked image matches warp bounds if it's not provided
|
|
2196
|
+
const bounds = warp.bounds;
|
|
2197
|
+
const width = placed.width || (bounds ? bounds.right.value - bounds.left.value : 0);
|
|
2198
|
+
const height = placed.height || (bounds ? bounds.bottom.value - bounds.top.value : 0);
|
|
2199
|
+
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
2200
|
// quiltWarp: {} as any,
|
|
2015
|
-
warp: encodeWarp(
|
|
2201
|
+
warp: encodeWarp(warp), 'Sz ': {
|
|
2016
2202
|
_name: '',
|
|
2017
2203
|
_classID: 'Pnt ',
|
|
2018
|
-
Wdth:
|
|
2019
|
-
Hght:
|
|
2204
|
+
Wdth: width,
|
|
2205
|
+
Hght: height,
|
|
2020
2206
|
}, Rslt: placed.resolution ? (0, descriptor_1.unitsValue)(placed.resolution, 'resolution') : { units: 'Density', value: 72 } });
|
|
2021
2207
|
if (placed.filter) {
|
|
2022
2208
|
desc.filterFX = {
|
|
@@ -2030,14 +2216,6 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
2030
2216
|
filterFXList: placed.filter.list.map(f => serializeFilterFXItem(f)),
|
|
2031
2217
|
};
|
|
2032
2218
|
}
|
|
2033
|
-
// TODO:
|
|
2034
|
-
// desc.comp = -1;
|
|
2035
|
-
// desc.compInfo = { _name: '', _classID: 'null', compID: -1, originalCompID: -1 } as any;
|
|
2036
|
-
// desc.ClMg = {
|
|
2037
|
-
// _name: '',
|
|
2038
|
-
// _classID: 'ClMg',
|
|
2039
|
-
// placedLayerOCIOConversion: 'placedLayerOCIOConversion.placedLayerOCIOConvertEmbedded'
|
|
2040
|
-
// } as any;
|
|
2041
2219
|
// if (JSON.stringify(t) !== JSON.stringify(desc)) {
|
|
2042
2220
|
// console.log('read', require('util').inspect(t, false, 99, true));
|
|
2043
2221
|
// console.log('write', require('util').inspect(desc, false, 99, true));
|
|
@@ -2067,7 +2245,13 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
2067
2245
|
desc.compInfo = placed.compInfo;
|
|
2068
2246
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc, desc.quiltWarp ? 'quiltWarp' : 'warp');
|
|
2069
2247
|
});
|
|
2070
|
-
|
|
2248
|
+
const soLdHandler = exports.infoHandlersMap['SoLd'];
|
|
2249
|
+
addHandler('SoLE', // linked smart object (Photoshop doesn't write PlLd for these)
|
|
2250
|
+
// linked smart object (Photoshop doesn't write PlLd for these)
|
|
2251
|
+
target => { var _a; return !!((_a = target.placedLayer) === null || _a === void 0 ? void 0 : _a.external); }, (reader, target, left, psd, imageResources) => {
|
|
2252
|
+
soLdHandler.read(reader, target, left, psd, imageResources);
|
|
2253
|
+
target.placedLayer.external = true;
|
|
2254
|
+
}, soLdHandler.write);
|
|
2071
2255
|
addHandler('fxrp', hasKey('referencePoint'), (reader, target) => {
|
|
2072
2256
|
target.referencePoint = {
|
|
2073
2257
|
x: (0, psdReader_1.readFloat64)(reader),
|
|
@@ -2077,18 +2261,41 @@ addHandler('fxrp', hasKey('referencePoint'), (reader, target) => {
|
|
|
2077
2261
|
(0, psdWriter_1.writeFloat64)(writer, target.referencePoint.x);
|
|
2078
2262
|
(0, psdWriter_1.writeFloat64)(writer, target.referencePoint.y);
|
|
2079
2263
|
});
|
|
2080
|
-
|
|
2081
|
-
(
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2264
|
+
function createGlobalLayerInfoHandler(key, bitsPerChannel) {
|
|
2265
|
+
addHandler(key, () => false, (reader, _target, left, psd, imageResources) => {
|
|
2266
|
+
var _a;
|
|
2267
|
+
// Photoshop writes empty (or 8bit compatibility) layer info section alongside Lr16/Lr32 in 16/32bit documents,
|
|
2268
|
+
// layers from global info with matching bit depth replace layers from that section, other ones are only used
|
|
2269
|
+
// if the section is empty
|
|
2270
|
+
if (!reader.layersInGlobalInfo && (psd.bitsPerChannel === bitsPerChannel || !((_a = psd.children) === null || _a === void 0 ? void 0 : _a.length))) {
|
|
2271
|
+
const sectionLayers = psd.children;
|
|
2272
|
+
psd.children = [];
|
|
2273
|
+
try {
|
|
2274
|
+
(0, psdReader_1.readLayerInfo)(reader, psd, imageResources);
|
|
2275
|
+
}
|
|
2276
|
+
catch (e) {
|
|
2277
|
+
psd.children = sectionLayers; // keep layers from layer info section if global info is broken
|
|
2278
|
+
throw e;
|
|
2279
|
+
}
|
|
2280
|
+
reader.layersInGlobalInfo = true;
|
|
2281
|
+
}
|
|
2282
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
2283
|
+
}, () => { });
|
|
2284
|
+
}
|
|
2285
|
+
createGlobalLayerInfoHandler('Lr16', 16);
|
|
2286
|
+
createGlobalLayerInfoHandler('Lr32', 32);
|
|
2287
|
+
createGlobalLayerInfoHandler('Layr', undefined);
|
|
2288
|
+
// merged transparency markers, first extra channel of composite image is transparency
|
|
2289
|
+
for (const key of ['Mtrn', 'Mt16', 'Mt32']) {
|
|
2290
|
+
addHandler(key, () => false, (reader, _target, left) => {
|
|
2291
|
+
reader.globalAlpha = true;
|
|
2292
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
2293
|
+
}, () => { });
|
|
2294
|
+
}
|
|
2088
2295
|
addHandler('LMsk', hasKey('userMask'), (reader, target) => {
|
|
2089
2296
|
target.userMask = {
|
|
2090
2297
|
colorSpace: (0, psdReader_1.readColor)(reader),
|
|
2091
|
-
opacity: (0, psdReader_1.readUint16)(reader) /
|
|
2298
|
+
opacity: (0, psdReader_1.readUint16)(reader) / 100,
|
|
2092
2299
|
};
|
|
2093
2300
|
const flag = (0, psdReader_1.readUint8)(reader);
|
|
2094
2301
|
if (flag !== 128)
|
|
@@ -2097,7 +2304,7 @@ addHandler('LMsk', hasKey('userMask'), (reader, target) => {
|
|
|
2097
2304
|
}, (writer, target) => {
|
|
2098
2305
|
const userMask = target.userMask;
|
|
2099
2306
|
(0, psdWriter_1.writeColor)(writer, userMask.colorSpace);
|
|
2100
|
-
(0, psdWriter_1.writeUint16)(writer, (0, helpers_1.clamp)(userMask.opacity, 0, 1) *
|
|
2307
|
+
(0, psdWriter_1.writeUint16)(writer, Math.round((0, helpers_1.clamp)(userMask.opacity, 0, 1) * 100));
|
|
2101
2308
|
(0, psdWriter_1.writeUint8)(writer, 128);
|
|
2102
2309
|
(0, psdWriter_1.writeZeros)(writer, 1);
|
|
2103
2310
|
});
|
|
@@ -2108,11 +2315,13 @@ if (helpers_1.MOCK_HANDLERS) {
|
|
|
2108
2315
|
}, (writer, target) => false && (0, psdWriter_1.writeBytes)(writer, target._Patt));
|
|
2109
2316
|
}
|
|
2110
2317
|
else {
|
|
2111
|
-
addHandler('Patt', //
|
|
2112
|
-
//
|
|
2318
|
+
addHandler('Patt', // 'Pat2' and 'Pat3' (16 and 32 bit documents) are aliases, patterns are always written as 8 bit
|
|
2319
|
+
// 'Pat2' and 'Pat3' (16 and 32 bit documents) are aliases, patterns are always written as 8 bit
|
|
2113
2320
|
target => !!(target.patterns && target.patterns.length > 0), (reader, target, left) => {
|
|
2114
2321
|
while (left() > 0) {
|
|
2115
|
-
const pattern = (0, psdReader_1.
|
|
2322
|
+
const pattern = (0, psdReader_1.readPatternSafe)(reader);
|
|
2323
|
+
if (!pattern)
|
|
2324
|
+
continue;
|
|
2116
2325
|
if (target.patterns === undefined)
|
|
2117
2326
|
target.patterns = [];
|
|
2118
2327
|
target.patterns.push(pattern);
|
|
@@ -2217,7 +2426,8 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
|
|
|
2217
2426
|
const count = (0, psdReader_1.readUint32)(reader);
|
|
2218
2427
|
const annotations = [];
|
|
2219
2428
|
for (let i = 0; i < count; i++) {
|
|
2220
|
-
|
|
2429
|
+
const recordStart = reader.offset;
|
|
2430
|
+
const length = (0, psdReader_1.readUint32)(reader); // includes the length field itself
|
|
2221
2431
|
const type = (0, psdReader_1.readSignature)(reader);
|
|
2222
2432
|
const open = !!(0, psdReader_1.readUint8)(reader);
|
|
2223
2433
|
/*const flags =*/ (0, psdReader_1.readUint8)(reader); // always 28
|
|
@@ -2233,11 +2443,12 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
|
|
|
2233
2443
|
const dataLength = (0, psdReader_1.readUint32)(reader);
|
|
2234
2444
|
let data;
|
|
2235
2445
|
if (type === 'txtA') {
|
|
2446
|
+
const dataStart = reader.offset;
|
|
2236
2447
|
if (dataLength >= 2 && (0, psdReader_1.readUint16)(reader) === 0xfeff) {
|
|
2237
|
-
data = (0, psdReader_1.readUnicodeStringWithLength)(reader, (dataLength - 2) / 2);
|
|
2448
|
+
data = (0, psdReader_1.readUnicodeStringWithLength)(reader, Math.floor((dataLength - 2) / 2));
|
|
2238
2449
|
}
|
|
2239
2450
|
else {
|
|
2240
|
-
reader.offset
|
|
2451
|
+
reader.offset = dataStart;
|
|
2241
2452
|
data = (0, psdReader_1.readAsciiString)(reader, dataLength);
|
|
2242
2453
|
}
|
|
2243
2454
|
data = data.replace(/\r/g, '\n');
|
|
@@ -2251,6 +2462,8 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
|
|
|
2251
2462
|
annotations.push({
|
|
2252
2463
|
type: type === 'txtA' ? 'text' : 'sound', open, iconLocation, popupLocation, color, author, name, date, data,
|
|
2253
2464
|
});
|
|
2465
|
+
if (length >= (reader.offset - recordStart))
|
|
2466
|
+
reader.offset = recordStart + length;
|
|
2254
2467
|
}
|
|
2255
2468
|
target.annotations = annotations;
|
|
2256
2469
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
@@ -2296,6 +2509,10 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
|
|
|
2296
2509
|
writer.view.setUint32(dataOffset - 4, writer.offset - dataOffset, false);
|
|
2297
2510
|
}
|
|
2298
2511
|
});
|
|
2512
|
+
function readFileTypeSignature(reader) {
|
|
2513
|
+
const value = (0, psdReader_1.readSignature)(reader);
|
|
2514
|
+
return /^[\0 ]*$/.test(value) ? '' : value.trim(); // empty value is stored as spaces or zeros
|
|
2515
|
+
}
|
|
2299
2516
|
function createLnkHandler(tag) {
|
|
2300
2517
|
addHandler(tag, (target) => {
|
|
2301
2518
|
const psd = target;
|
|
@@ -2317,8 +2534,8 @@ function createLnkHandler(tag) {
|
|
|
2317
2534
|
const version = (0, psdReader_1.readInt32)(reader);
|
|
2318
2535
|
const id = (0, psdReader_1.readPascalString)(reader, 1);
|
|
2319
2536
|
const name = (0, psdReader_1.readUnicodeString)(reader);
|
|
2320
|
-
const fileType = (
|
|
2321
|
-
const fileCreator = (
|
|
2537
|
+
const fileType = readFileTypeSignature(reader); // ' ' if empty
|
|
2538
|
+
const fileCreator = readFileTypeSignature(reader); // ' ' or '\0\0\0\0' if empty
|
|
2322
2539
|
const dataSize = readLength64(reader);
|
|
2323
2540
|
const hasFileOpenDescriptor = (0, psdReader_1.readUint8)(reader);
|
|
2324
2541
|
const fileOpenDescriptor = hasFileOpenDescriptor ? (0, descriptor_1.readVersionAndDescriptor)(reader) : undefined;
|
|
@@ -2378,11 +2595,12 @@ function createLnkHandler(tag) {
|
|
|
2378
2595
|
}
|
|
2379
2596
|
(0, psdReader_1.skipBytes)(reader, left()); // ?
|
|
2380
2597
|
}, (writer, target) => {
|
|
2381
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
2598
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
2382
2599
|
const psd = target;
|
|
2383
2600
|
for (const file of psd.linkedFiles) {
|
|
2384
2601
|
if ((tag === 'lnkE') !== !!file.linkedFile)
|
|
2385
2602
|
continue;
|
|
2603
|
+
const external = tag === 'lnkE';
|
|
2386
2604
|
let version = 2;
|
|
2387
2605
|
if (file.assetLockedState != null)
|
|
2388
2606
|
version = 7;
|
|
@@ -2390,11 +2608,13 @@ function createLnkHandler(tag) {
|
|
|
2390
2608
|
version = 6;
|
|
2391
2609
|
else if (file.childDocumentID != null)
|
|
2392
2610
|
version = 5;
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2611
|
+
// liFE version 2 is the only one with embedded data, it has no date and its file size is the size of the data,
|
|
2612
|
+
// versions 5+ can't store the data, so it's not written in that case
|
|
2613
|
+
else if (external && !file.data)
|
|
2614
|
+
version = 4;
|
|
2615
|
+
(0, psdWriter_1.writeUint64)(writer, 0);
|
|
2396
2616
|
const sizeOffset = writer.offset;
|
|
2397
|
-
(0, psdWriter_1.writeSignature)(writer,
|
|
2617
|
+
(0, psdWriter_1.writeSignature)(writer, external ? 'liFE' : (file.data ? 'liFD' : 'liFA'));
|
|
2398
2618
|
(0, psdWriter_1.writeInt32)(writer, version);
|
|
2399
2619
|
if (!file.id || typeof file.id !== 'string' || !/^[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}$/.test(file.id)) {
|
|
2400
2620
|
throw new Error('Linked file ID must be in a GUID format (example: 20953ddb-9391-11ec-b4f1-c15674f50bc4)');
|
|
@@ -2403,7 +2623,7 @@ function createLnkHandler(tag) {
|
|
|
2403
2623
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, file.name || '');
|
|
2404
2624
|
(0, psdWriter_1.writeSignature)(writer, file.type ? `${file.type} `.substring(0, 4) : ' ');
|
|
2405
2625
|
(0, psdWriter_1.writeSignature)(writer, file.creator ? `${file.creator} `.substring(0, 4) : '\0\0\0\0');
|
|
2406
|
-
|
|
2626
|
+
(0, psdWriter_1.writeUint64)(writer, (!external && file.data) ? file.data.byteLength : 0);
|
|
2407
2627
|
if (file.descriptor && file.descriptor.compInfo) {
|
|
2408
2628
|
const desc = {
|
|
2409
2629
|
compInfo: {
|
|
@@ -2417,7 +2637,7 @@ function createLnkHandler(tag) {
|
|
|
2417
2637
|
else {
|
|
2418
2638
|
(0, psdWriter_1.writeUint8)(writer, 0);
|
|
2419
2639
|
}
|
|
2420
|
-
if (
|
|
2640
|
+
if (external) {
|
|
2421
2641
|
const desc = {
|
|
2422
2642
|
descVersion: 2,
|
|
2423
2643
|
'Nm ': (_b = (_a = file.linkedFile) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : '',
|
|
@@ -2426,6 +2646,8 @@ function createLnkHandler(tag) {
|
|
|
2426
2646
|
relPath: (_h = (_g = file.linkedFile) === null || _g === void 0 ? void 0 : _g.relativePath) !== null && _h !== void 0 ? _h : '',
|
|
2427
2647
|
};
|
|
2428
2648
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'ExternalFileLink', desc);
|
|
2649
|
+
}
|
|
2650
|
+
if (external && version > 3) {
|
|
2429
2651
|
const time = file.time ? new Date(file.time) : new Date();
|
|
2430
2652
|
(0, psdWriter_1.writeInt32)(writer, time.getUTCFullYear());
|
|
2431
2653
|
(0, psdWriter_1.writeUint8)(writer, time.getUTCMonth());
|
|
@@ -2434,11 +2656,14 @@ function createLnkHandler(tag) {
|
|
|
2434
2656
|
(0, psdWriter_1.writeUint8)(writer, time.getUTCMinutes());
|
|
2435
2657
|
(0, psdWriter_1.writeFloat64)(writer, time.getUTCSeconds() + time.getUTCMilliseconds() / 1000);
|
|
2436
2658
|
}
|
|
2437
|
-
if (
|
|
2438
|
-
(0, psdWriter_1.
|
|
2659
|
+
if (external) {
|
|
2660
|
+
(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
|
|
2661
|
+
}
|
|
2662
|
+
else if (file.data) {
|
|
2663
|
+
(0, psdWriter_1.writeBytes)(writer, file.data); // liFD
|
|
2439
2664
|
}
|
|
2440
2665
|
else {
|
|
2441
|
-
|
|
2666
|
+
(0, psdWriter_1.writeZeros)(writer, 8); // liFA
|
|
2442
2667
|
}
|
|
2443
2668
|
if (version >= 5)
|
|
2444
2669
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, file.childDocumentID || '');
|
|
@@ -2446,6 +2671,8 @@ function createLnkHandler(tag) {
|
|
|
2446
2671
|
(0, psdWriter_1.writeFloat64)(writer, file.assetModTime || 0);
|
|
2447
2672
|
if (version >= 7)
|
|
2448
2673
|
(0, psdWriter_1.writeUint8)(writer, file.assetLockedState || 0);
|
|
2674
|
+
if (external && version === 2 && file.data)
|
|
2675
|
+
(0, psdWriter_1.writeBytes)(writer, file.data);
|
|
2449
2676
|
let size = writer.offset - sizeOffset;
|
|
2450
2677
|
writer.view.setUint32(sizeOffset - 4, size, false); // write size
|
|
2451
2678
|
while (size % 4) {
|
|
@@ -2459,28 +2686,40 @@ createLnkHandler('lnk2');
|
|
|
2459
2686
|
createLnkHandler('lnkE');
|
|
2460
2687
|
addHandlerAlias('lnkD', 'lnk2');
|
|
2461
2688
|
addHandlerAlias('lnk3', 'lnk2');
|
|
2462
|
-
|
|
2689
|
+
// unicode names of saved paths (path data is stored in image resources 2000-2998)
|
|
2690
|
+
addHandler('pths', target => { var _a; return ((_a = target.imageResources) === null || _a === void 0 ? void 0 : _a.savedPaths) !== undefined; }, (reader, _target, left, psd) => {
|
|
2691
|
+
var _a, _b;
|
|
2463
2692
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
desc;
|
|
2467
|
-
|
|
2468
|
-
|
|
2693
|
+
const imageResources = (_a = psd.imageResources) !== null && _a !== void 0 ? _a : (psd.imageResources = {});
|
|
2694
|
+
const savedPaths = (_b = imageResources.savedPaths) !== null && _b !== void 0 ? _b : (imageResources.savedPaths = []);
|
|
2695
|
+
for (let i = 0; i < desc.pathList.length && i < savedPaths.length; i++) {
|
|
2696
|
+
const { pathUnicodeName, pathSymmetryClass } = desc.pathList[i];
|
|
2697
|
+
const path = savedPaths[i];
|
|
2698
|
+
// clipping path is referenced by (non-unicode) name
|
|
2699
|
+
if (imageResources.clippingPath && imageResources.clippingPath.name === path.name) {
|
|
2700
|
+
imageResources.clippingPath.name = pathUnicodeName;
|
|
2701
|
+
}
|
|
2702
|
+
path.name = pathUnicodeName;
|
|
2703
|
+
if (pathSymmetryClass)
|
|
2704
|
+
path.symmetryMode = pathSymmetryClass.pathSymmetryMode.split('.')[1];
|
|
2705
|
+
}
|
|
2706
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
2707
|
+
}, (writer, _target, psd) => {
|
|
2469
2708
|
const desc = {
|
|
2470
|
-
pathList:
|
|
2709
|
+
pathList: psd.imageResources.savedPaths.map(path => (Object.assign({ _name: '', _classID: 'pathInfoClass', pathUnicodeName: path.name }, (path.symmetryMode ? {
|
|
2710
|
+
pathSymmetryClass: {
|
|
2711
|
+
_name: '',
|
|
2712
|
+
_classID: 'pathSymmetryClass',
|
|
2713
|
+
pathSymmetryMode: `pathSymmetryModeEnum.${path.symmetryMode}`,
|
|
2714
|
+
},
|
|
2715
|
+
} : {})))),
|
|
2471
2716
|
};
|
|
2472
2717
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'pathsDataClass', desc);
|
|
2473
2718
|
});
|
|
2474
2719
|
addHandler('lyvr', hasKey('version'), (reader, target) => target.version = (0, psdReader_1.readUint32)(reader), (writer, target) => (0, psdWriter_1.writeUint32)(writer, target.version));
|
|
2475
|
-
addHandler('lfxs',
|
|
2476
|
-
//
|
|
2477
|
-
|
|
2478
|
-
// !!target.effects.dropShadow?.some(e => e.choke) ||
|
|
2479
|
-
// !!target.effects.innerShadow?.some(e => e.choke) ||
|
|
2480
|
-
// !!target.effects.outerGlow?.choke ||
|
|
2481
|
-
// !!target.effects.innerGlow?.choke
|
|
2482
|
-
// ),
|
|
2483
|
-
(reader, target, left) => {
|
|
2720
|
+
addHandler('lfxs', // effects of group layers (instead of 'lfx2' / 'lmfx')
|
|
2721
|
+
// effects of group layers (instead of 'lfx2' / 'lmfx')
|
|
2722
|
+
target => target.effects !== undefined && isGroupLayer(target), (reader, target, left) => {
|
|
2484
2723
|
const version = (0, psdReader_1.readUint32)(reader);
|
|
2485
2724
|
if (version !== 0)
|
|
2486
2725
|
throw new Error(`Invalid lfxs version`);
|
|
@@ -2524,6 +2763,10 @@ function readLevelsChannel(reader) {
|
|
|
2524
2763
|
const midtoneInput = (0, psdReader_1.readInt16)(reader) / 100;
|
|
2525
2764
|
return { shadowInput, highlightInput, shadowOutput, highlightOutput, midtoneInput };
|
|
2526
2765
|
}
|
|
2766
|
+
const defaultLevelsChannel = { shadowInput: 0, highlightInput: 255, shadowOutput: 0, highlightOutput: 255, midtoneInput: 1 };
|
|
2767
|
+
function isDefaultLevelsChannel(c) {
|
|
2768
|
+
return c.shadowInput === 0 && c.highlightInput === 255 && c.shadowOutput === 0 && c.highlightOutput === 255 && c.midtoneInput === 1;
|
|
2769
|
+
}
|
|
2527
2770
|
function writeLevelsChannel(writer, channel) {
|
|
2528
2771
|
(0, psdWriter_1.writeInt16)(writer, channel.shadowInput);
|
|
2529
2772
|
(0, psdWriter_1.writeInt16)(writer, channel.highlightInput);
|
|
@@ -2534,48 +2777,36 @@ function writeLevelsChannel(writer, channel) {
|
|
|
2534
2777
|
addHandler('levl', adjustmentType('levels'), (reader, target, left) => {
|
|
2535
2778
|
if ((0, psdReader_1.readUint16)(reader) !== 2)
|
|
2536
2779
|
throw new Error('Invalid levl version');
|
|
2537
|
-
const
|
|
2538
|
-
for (let i = 0; i < 29 && left(); i++) {
|
|
2539
|
-
|
|
2540
|
-
}
|
|
2541
|
-
|
|
2542
|
-
target.adjustment = Object.assign(Object.assign({}, target.adjustment), { type: 'levels', rgb,
|
|
2543
|
-
red,
|
|
2544
|
-
green,
|
|
2545
|
-
blue });
|
|
2546
|
-
if (left()) {
|
|
2780
|
+
const channels = [];
|
|
2781
|
+
for (let i = 0; i < 29 && left() >= 10; i++) {
|
|
2782
|
+
channels.push(readLevelsChannel(reader));
|
|
2783
|
+
}
|
|
2784
|
+
if (left() >= 8) {
|
|
2547
2785
|
if ((0, psdReader_1.readSignature)(reader) !== 'Lvls')
|
|
2548
2786
|
throw new Error(`Invalid levl signature`);
|
|
2549
2787
|
if ((0, psdReader_1.readUint16)(reader) !== 3)
|
|
2550
2788
|
throw new Error(`Invalid levl version`);
|
|
2551
2789
|
const totalChannelRecords = (0, psdReader_1.readUint16)(reader);
|
|
2552
|
-
|
|
2553
|
-
|
|
2790
|
+
while (channels.length < totalChannelRecords && left() >= 10) {
|
|
2791
|
+
channels.push(readLevelsChannel(reader));
|
|
2554
2792
|
}
|
|
2555
2793
|
}
|
|
2794
|
+
// records for all possible channels are stored, skip unused ones
|
|
2795
|
+
while (channels.length && isDefaultLevelsChannel(channels[channels.length - 1]))
|
|
2796
|
+
channels.pop();
|
|
2797
|
+
target.adjustment = Object.assign(Object.assign({}, target.adjustment), { type: 'levels', channels });
|
|
2556
2798
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
2557
2799
|
}, (writer, target) => {
|
|
2558
|
-
const
|
|
2559
|
-
const defaultChannel = {
|
|
2560
|
-
shadowInput: 0,
|
|
2561
|
-
highlightInput: 255,
|
|
2562
|
-
shadowOutput: 0,
|
|
2563
|
-
highlightOutput: 255,
|
|
2564
|
-
midtoneInput: 1,
|
|
2565
|
-
};
|
|
2800
|
+
const channels = target.adjustment.channels || [];
|
|
2566
2801
|
(0, psdWriter_1.writeUint16)(writer, 2); // version
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
writeLevelsChannel(writer, info.green || defaultChannel);
|
|
2570
|
-
writeLevelsChannel(writer, info.blue || defaultChannel);
|
|
2571
|
-
for (let i = 0; i < (29 - 4); i++) {
|
|
2572
|
-
writeLevelsChannel(writer, defaultChannel);
|
|
2802
|
+
for (let i = 0; i < 29; i++) {
|
|
2803
|
+
writeLevelsChannel(writer, channels[i] || defaultLevelsChannel);
|
|
2573
2804
|
}
|
|
2574
2805
|
(0, psdWriter_1.writeSignature)(writer, 'Lvls');
|
|
2575
2806
|
(0, psdWriter_1.writeUint16)(writer, 3); // version
|
|
2576
2807
|
(0, psdWriter_1.writeUint16)(writer, 62); // total count
|
|
2577
|
-
for (let i =
|
|
2578
|
-
writeLevelsChannel(writer,
|
|
2808
|
+
for (let i = 29; i < 62; i++) {
|
|
2809
|
+
writeLevelsChannel(writer, channels[i] || defaultLevelsChannel);
|
|
2579
2810
|
}
|
|
2580
2811
|
});
|
|
2581
2812
|
function readCurveChannel(reader) {
|
|
@@ -2600,17 +2831,16 @@ addHandler('curv', adjustmentType('curves'), (reader, target, left) => {
|
|
|
2600
2831
|
if ((0, psdReader_1.readUint16)(reader) !== 1)
|
|
2601
2832
|
throw new Error('Invalid curv version');
|
|
2602
2833
|
(0, psdReader_1.readUint16)(reader);
|
|
2603
|
-
const
|
|
2604
|
-
const
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
target.adjustment = Object.assign(Object.assign({}, target.adjustment), info);
|
|
2834
|
+
const channelsMask = (0, psdReader_1.readUint16)(reader);
|
|
2835
|
+
const channels = [];
|
|
2836
|
+
for (let i = 0; i < 16; i++) {
|
|
2837
|
+
if (channelsMask & (1 << i)) {
|
|
2838
|
+
while (channels.length < i)
|
|
2839
|
+
channels.push([]);
|
|
2840
|
+
channels.push(readCurveChannel(reader));
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
target.adjustment = Object.assign(Object.assign({}, target.adjustment), { type: 'curves', channels });
|
|
2614
2844
|
// ignoring, duplicate information
|
|
2615
2845
|
// checkSignature(reader, 'Crv ');
|
|
2616
2846
|
// const cVersion = readUint16(reader);
|
|
@@ -2626,57 +2856,29 @@ addHandler('curv', adjustmentType('curves'), (reader, target, left) => {
|
|
|
2626
2856
|
// }
|
|
2627
2857
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
2628
2858
|
}, (writer, target) => {
|
|
2629
|
-
|
|
2630
|
-
const
|
|
2631
|
-
|
|
2632
|
-
let
|
|
2633
|
-
|
|
2634
|
-
channels
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
channels |= 2;
|
|
2639
|
-
channelCount++;
|
|
2640
|
-
}
|
|
2641
|
-
if (green && green.length) {
|
|
2642
|
-
channels |= 4;
|
|
2643
|
-
channelCount++;
|
|
2644
|
-
}
|
|
2645
|
-
if (blue && blue.length) {
|
|
2646
|
-
channels |= 8;
|
|
2647
|
-
channelCount++;
|
|
2859
|
+
var _a;
|
|
2860
|
+
const channels = (target.adjustment.channels || []).slice(0, 16);
|
|
2861
|
+
const used = [];
|
|
2862
|
+
let channelsMask = 0;
|
|
2863
|
+
for (let i = 0; i < channels.length; i++) {
|
|
2864
|
+
if ((_a = channels[i]) === null || _a === void 0 ? void 0 : _a.length) {
|
|
2865
|
+
channelsMask |= 1 << i;
|
|
2866
|
+
used.push(i);
|
|
2867
|
+
}
|
|
2648
2868
|
}
|
|
2649
2869
|
(0, psdWriter_1.writeUint8)(writer, 0);
|
|
2650
2870
|
(0, psdWriter_1.writeUint16)(writer, 1); // version
|
|
2651
2871
|
(0, psdWriter_1.writeUint16)(writer, 0);
|
|
2652
|
-
(0, psdWriter_1.writeUint16)(writer,
|
|
2653
|
-
|
|
2654
|
-
writeCurveChannel(writer,
|
|
2655
|
-
if (red && red.length)
|
|
2656
|
-
writeCurveChannel(writer, red);
|
|
2657
|
-
if (green && green.length)
|
|
2658
|
-
writeCurveChannel(writer, green);
|
|
2659
|
-
if (blue && blue.length)
|
|
2660
|
-
writeCurveChannel(writer, blue);
|
|
2872
|
+
(0, psdWriter_1.writeUint16)(writer, channelsMask);
|
|
2873
|
+
for (const i of used)
|
|
2874
|
+
writeCurveChannel(writer, channels[i]);
|
|
2661
2875
|
(0, psdWriter_1.writeSignature)(writer, 'Crv ');
|
|
2662
2876
|
(0, psdWriter_1.writeUint16)(writer, 4); // version
|
|
2663
2877
|
(0, psdWriter_1.writeUint16)(writer, 0);
|
|
2664
|
-
(0, psdWriter_1.writeUint16)(writer,
|
|
2665
|
-
|
|
2666
|
-
(0, psdWriter_1.writeUint16)(writer,
|
|
2667
|
-
writeCurveChannel(writer,
|
|
2668
|
-
}
|
|
2669
|
-
if (red && red.length) {
|
|
2670
|
-
(0, psdWriter_1.writeUint16)(writer, 1);
|
|
2671
|
-
writeCurveChannel(writer, red);
|
|
2672
|
-
}
|
|
2673
|
-
if (green && green.length) {
|
|
2674
|
-
(0, psdWriter_1.writeUint16)(writer, 2);
|
|
2675
|
-
writeCurveChannel(writer, green);
|
|
2676
|
-
}
|
|
2677
|
-
if (blue && blue.length) {
|
|
2678
|
-
(0, psdWriter_1.writeUint16)(writer, 3);
|
|
2679
|
-
writeCurveChannel(writer, blue);
|
|
2878
|
+
(0, psdWriter_1.writeUint16)(writer, used.length);
|
|
2879
|
+
for (const i of used) {
|
|
2880
|
+
(0, psdWriter_1.writeUint16)(writer, i);
|
|
2881
|
+
writeCurveChannel(writer, channels[i]);
|
|
2680
2882
|
}
|
|
2681
2883
|
});
|
|
2682
2884
|
addHandler('expA', adjustmentType('exposure'), (reader, target, left) => {
|
|
@@ -2733,12 +2935,34 @@ function writeHueChannel(writer, channel) {
|
|
|
2733
2935
|
addHandler('hue2', adjustmentType('hue/saturation'), (reader, target, left) => {
|
|
2734
2936
|
if ((0, psdReader_1.readUint16)(reader) !== 2)
|
|
2735
2937
|
throw new Error('Invalid hue2 version');
|
|
2736
|
-
|
|
2938
|
+
const colorize = !!(0, psdReader_1.readUint8)(reader);
|
|
2939
|
+
(0, psdReader_1.skipBytes)(reader, 1);
|
|
2940
|
+
const colorizeHue = (0, psdReader_1.readInt16)(reader); // stored as -180..180
|
|
2941
|
+
const colorizeSaturation = (0, psdReader_1.readInt16)(reader);
|
|
2942
|
+
const colorizeLightness = (0, psdReader_1.readInt16)(reader);
|
|
2943
|
+
target.adjustment = Object.assign(Object.assign({}, target.adjustment), { type: 'hue/saturation', colorize, colorization: {
|
|
2944
|
+
hue: colorizeHue < 0 ? colorizeHue + 360 : colorizeHue,
|
|
2945
|
+
saturation: colorizeSaturation,
|
|
2946
|
+
lightness: colorizeLightness,
|
|
2947
|
+
}, master: {
|
|
2948
|
+
hue: (0, psdReader_1.readInt16)(reader),
|
|
2949
|
+
saturation: (0, psdReader_1.readInt16)(reader),
|
|
2950
|
+
lightness: (0, psdReader_1.readInt16)(reader),
|
|
2951
|
+
}, reds: readHueChannel(reader), yellows: readHueChannel(reader), greens: readHueChannel(reader), cyans: readHueChannel(reader), blues: readHueChannel(reader), magentas: readHueChannel(reader) });
|
|
2737
2952
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
2738
2953
|
}, (writer, target) => {
|
|
2954
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
2739
2955
|
const info = target.adjustment;
|
|
2740
2956
|
(0, psdWriter_1.writeUint16)(writer, 2); // version
|
|
2741
|
-
|
|
2957
|
+
(0, psdWriter_1.writeUint8)(writer, info.colorize ? 1 : 0);
|
|
2958
|
+
(0, psdWriter_1.writeUint8)(writer, 0);
|
|
2959
|
+
const colorizeHue = Math.round((_b = (_a = info.colorization) === null || _a === void 0 ? void 0 : _a.hue) !== null && _b !== void 0 ? _b : 0);
|
|
2960
|
+
(0, psdWriter_1.writeInt16)(writer, colorizeHue > 180 ? colorizeHue - 360 : colorizeHue);
|
|
2961
|
+
(0, psdWriter_1.writeInt16)(writer, Math.round((_d = (_c = info.colorization) === null || _c === void 0 ? void 0 : _c.saturation) !== null && _d !== void 0 ? _d : 0));
|
|
2962
|
+
(0, psdWriter_1.writeInt16)(writer, Math.round((_f = (_e = info.colorization) === null || _e === void 0 ? void 0 : _e.lightness) !== null && _f !== void 0 ? _f : 0));
|
|
2963
|
+
(0, psdWriter_1.writeInt16)(writer, Math.round((_h = (_g = info.master) === null || _g === void 0 ? void 0 : _g.hue) !== null && _h !== void 0 ? _h : 0));
|
|
2964
|
+
(0, psdWriter_1.writeInt16)(writer, Math.round((_k = (_j = info.master) === null || _j === void 0 ? void 0 : _j.saturation) !== null && _k !== void 0 ? _k : 0));
|
|
2965
|
+
(0, psdWriter_1.writeInt16)(writer, Math.round((_m = (_l = info.master) === null || _l === void 0 ? void 0 : _l.lightness) !== null && _m !== void 0 ? _m : 0));
|
|
2742
2966
|
writeHueChannel(writer, info.reds);
|
|
2743
2967
|
writeHueChannel(writer, info.yellows);
|
|
2744
2968
|
writeHueChannel(writer, info.greens);
|
|
@@ -2817,11 +3041,18 @@ addHandler('phfl', adjustmentType('photo filter'), (reader, target, left) => {
|
|
|
2817
3041
|
color = (0, psdReader_1.readColor)(reader);
|
|
2818
3042
|
}
|
|
2819
3043
|
else { // version 3
|
|
2820
|
-
//
|
|
3044
|
+
// XYZ color relative to D50 white point, 32768 = 1.0 (not documented, matches colors of Photoshop presets),
|
|
3045
|
+
// converted to Lab (same scale as readColor()) so it can be written back as version 2
|
|
3046
|
+
const x = (0, psdReader_1.readInt32)(reader) / 32768;
|
|
3047
|
+
const y = (0, psdReader_1.readInt32)(reader) / 32768;
|
|
3048
|
+
const z = (0, psdReader_1.readInt32)(reader) / 32768;
|
|
3049
|
+
if (!(x >= 0 && y >= 0 && z >= 0 && x <= 2 && y <= 2 && z <= 2))
|
|
3050
|
+
throw new Error('Invalid phfl XYZ color');
|
|
3051
|
+
const f = (t) => t > 216 / 24389 ? Math.cbrt(t) : (24389 / 27 * t + 16) / 116;
|
|
2821
3052
|
color = {
|
|
2822
|
-
l: (0,
|
|
2823
|
-
a: (0,
|
|
2824
|
-
b: (0,
|
|
3053
|
+
l: Math.max(0, 116 * f(y) - 16) / 100,
|
|
3054
|
+
a: (0, helpers_1.normalizeLabAB)(500 * (f(x) - f(y))),
|
|
3055
|
+
b: (0, helpers_1.normalizeLabAB)(200 * (f(y) - f(z))),
|
|
2825
3056
|
};
|
|
2826
3057
|
}
|
|
2827
3058
|
target.adjustment = {
|
|
@@ -2835,7 +3066,7 @@ addHandler('phfl', adjustmentType('photo filter'), (reader, target, left) => {
|
|
|
2835
3066
|
const info = target.adjustment;
|
|
2836
3067
|
(0, psdWriter_1.writeUint16)(writer, 2); // version
|
|
2837
3068
|
(0, psdWriter_1.writeColor)(writer, info.color || { l: 0, a: 0, b: 0 });
|
|
2838
|
-
(0, psdWriter_1.writeUint32)(writer, (info.density || 0) * 100);
|
|
3069
|
+
(0, psdWriter_1.writeUint32)(writer, Math.round(Math.max(0, info.density || 0) * 100));
|
|
2839
3070
|
(0, psdWriter_1.writeUint8)(writer, info.preserveLuminosity ? 1 : 0);
|
|
2840
3071
|
(0, psdWriter_1.writeZeros)(writer, 3);
|
|
2841
3072
|
});
|
|
@@ -2989,7 +3220,7 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
|
|
|
2989
3220
|
reader.offset--;
|
|
2990
3221
|
if (hasMethod) {
|
|
2991
3222
|
const method = (0, psdReader_1.readSignature)(reader);
|
|
2992
|
-
info.method = descriptor_1.gradientInterpolationMethodType.decode(method);
|
|
3223
|
+
info.method = descriptor_1.gradientInterpolationMethodType.decode(`gradientInterpolationMethodType.${method}`);
|
|
2993
3224
|
}
|
|
2994
3225
|
info.name = (0, psdReader_1.readUnicodeString)(reader);
|
|
2995
3226
|
info.colorStops = [];
|
|
@@ -3038,10 +3269,11 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
|
|
|
3038
3269
|
(0, psdReader_1.readUint16)(reader) / 0x8000,
|
|
3039
3270
|
];
|
|
3040
3271
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
3272
|
+
// stop locations are always in 0..4096 range, independent of smoothness
|
|
3041
3273
|
for (const s of info.colorStops)
|
|
3042
|
-
s.location /=
|
|
3274
|
+
s.location /= 4096;
|
|
3043
3275
|
for (const s of info.opacityStops)
|
|
3044
|
-
s.location /=
|
|
3276
|
+
s.location /= 4096;
|
|
3045
3277
|
target.adjustment = info;
|
|
3046
3278
|
}, (writer, target) => {
|
|
3047
3279
|
var _a, _b, _c;
|
|
@@ -3050,22 +3282,22 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
|
|
|
3050
3282
|
(0, psdWriter_1.writeUint8)(writer, info.reverse ? 1 : 0);
|
|
3051
3283
|
(0, psdWriter_1.writeUint8)(writer, info.dither ? 1 : 0);
|
|
3052
3284
|
if (info.method !== undefined) {
|
|
3053
|
-
(0, psdWriter_1.writeSignature)(writer, descriptor_1.gradientInterpolationMethodType.encode(info.method));
|
|
3285
|
+
(0, psdWriter_1.writeSignature)(writer, descriptor_1.gradientInterpolationMethodType.encode(info.method).split('.')[1]);
|
|
3054
3286
|
}
|
|
3055
3287
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, info.name || '');
|
|
3056
3288
|
(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);
|
|
3289
|
+
const interpolation = Math.round((0, helpers_1.clamp)((_a = info.smoothness) !== null && _a !== void 0 ? _a : 1, 0, 1) * 4096);
|
|
3058
3290
|
for (const s of info.colorStops || []) {
|
|
3059
|
-
(0, psdWriter_1.writeUint32)(writer, Math.round(s.location *
|
|
3291
|
+
(0, psdWriter_1.writeUint32)(writer, Math.round((0, helpers_1.clamp)(s.location, 0, 1) * 4096));
|
|
3060
3292
|
(0, psdWriter_1.writeUint32)(writer, Math.round(s.midpoint * 100));
|
|
3061
3293
|
(0, psdWriter_1.writeColor)(writer, s.color);
|
|
3062
3294
|
(0, psdWriter_1.writeZeros)(writer, 2);
|
|
3063
3295
|
}
|
|
3064
3296
|
(0, psdWriter_1.writeUint16)(writer, info.opacityStops && info.opacityStops.length || 0);
|
|
3065
3297
|
for (const s of info.opacityStops || []) {
|
|
3066
|
-
(0, psdWriter_1.writeUint32)(writer, Math.round(s.location *
|
|
3298
|
+
(0, psdWriter_1.writeUint32)(writer, Math.round((0, helpers_1.clamp)(s.location, 0, 1) * 4096));
|
|
3067
3299
|
(0, psdWriter_1.writeUint32)(writer, Math.round(s.midpoint * 100));
|
|
3068
|
-
(0, psdWriter_1.writeUint16)(writer, Math.round(s.opacity * 0xff));
|
|
3300
|
+
(0, psdWriter_1.writeUint16)(writer, Math.round((0, helpers_1.clamp)(s.opacity, 0, 1) * 0xff));
|
|
3069
3301
|
}
|
|
3070
3302
|
(0, psdWriter_1.writeUint16)(writer, 2); // expansion count
|
|
3071
3303
|
(0, psdWriter_1.writeUint16)(writer, interpolation);
|
|
@@ -3227,7 +3459,7 @@ addHandler('Txt2', hasKey('engineData'), (reader, target, left, psd) => {
|
|
|
3227
3459
|
const data = (0, psdReader_1.readBytes)(reader, left());
|
|
3228
3460
|
target.engineData = (0, base64_js_1.fromByteArray)(data);
|
|
3229
3461
|
const layersByIndex = getTextLayersSortedByIndex(psd);
|
|
3230
|
-
const engineData = (0, engineData_1.parseEngineData)(data);
|
|
3462
|
+
const engineData = (0, engineData_1.parseEngineData)(data, reader);
|
|
3231
3463
|
const engineData2 = (0, engineData2_1.decodeEngineData2)(engineData);
|
|
3232
3464
|
const TextFrameSet = engineData2.ResourceDict.TextFrameSet;
|
|
3233
3465
|
if (TextFrameSet) {
|
|
@@ -3309,7 +3541,6 @@ addHandler('FEid', hasKey('filterEffectsMasks'), (reader, target, leftBytes) =>
|
|
|
3309
3541
|
}
|
|
3310
3542
|
}
|
|
3311
3543
|
}, (writer, target) => {
|
|
3312
|
-
var _a;
|
|
3313
3544
|
(0, psdWriter_1.writeInt32)(writer, 3); // version
|
|
3314
3545
|
for (const mask of target.filterEffectsMasks) {
|
|
3315
3546
|
(0, psdWriter_1.writeUint32)(writer, 0);
|
|
@@ -3338,7 +3569,7 @@ addHandler('FEid', hasKey('filterEffectsMasks'), (reader, target, leftBytes) =>
|
|
|
3338
3569
|
}
|
|
3339
3570
|
}
|
|
3340
3571
|
writer.view.setUint32(length2Offset - 4, writer.offset - length2Offset, false);
|
|
3341
|
-
const extra =
|
|
3572
|
+
const extra = mask.extra;
|
|
3342
3573
|
if (extra) {
|
|
3343
3574
|
(0, psdWriter_1.writeUint8)(writer, 1);
|
|
3344
3575
|
(0, psdWriter_1.writeInt32)(writer, extra.top);
|
|
@@ -3362,28 +3593,33 @@ addHandlerAlias('FXid', 'FEid');
|
|
|
3362
3593
|
addHandler('FMsk', hasKey('filterMask'), (reader, target) => {
|
|
3363
3594
|
target.filterMask = {
|
|
3364
3595
|
colorSpace: (0, psdReader_1.readColor)(reader),
|
|
3365
|
-
opacity: (0, psdReader_1.readUint16)(reader) /
|
|
3596
|
+
opacity: (0, psdReader_1.readUint16)(reader) / 100,
|
|
3366
3597
|
};
|
|
3367
3598
|
}, (writer, target) => {
|
|
3368
3599
|
var _a;
|
|
3369
3600
|
(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) *
|
|
3601
|
+
(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
3602
|
});
|
|
3372
3603
|
addHandler('artd', // document-wide artboard info
|
|
3373
3604
|
// document-wide artboard info
|
|
3374
3605
|
target => target.artboards !== undefined, (reader, target, left) => {
|
|
3375
3606
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
3376
|
-
target.artboards = {
|
|
3377
|
-
|
|
3378
|
-
autoExpandOffset
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3607
|
+
const artboards = target.artboards = { count: desc['Cnt '] };
|
|
3608
|
+
if (desc.autoExpandOffset)
|
|
3609
|
+
artboards.autoExpandOffset = { horizontal: desc.autoExpandOffset.Hrzn, vertical: desc.autoExpandOffset.Vrtc };
|
|
3610
|
+
if (desc.origin)
|
|
3611
|
+
artboards.origin = { horizontal: desc.origin.Hrzn, vertical: desc.origin.Vrtc };
|
|
3612
|
+
if (desc.autoExpandEnabled !== undefined)
|
|
3613
|
+
artboards.autoExpandEnabled = desc.autoExpandEnabled;
|
|
3614
|
+
if (desc.autoNestEnabled !== undefined)
|
|
3615
|
+
artboards.autoNestEnabled = desc.autoNestEnabled;
|
|
3616
|
+
if (desc.autoPositionEnabled !== undefined)
|
|
3617
|
+
artboards.autoPositionEnabled = desc.autoPositionEnabled;
|
|
3618
|
+
artboards.shrinkwrapOnSaveEnabled = !!desc.shrinkwrapOnSaveEnabled;
|
|
3619
|
+
if (desc.docDefaultNewArtboardBackgroundColor)
|
|
3620
|
+
artboards.docDefaultNewArtboardBackgroundColor = (0, descriptor_1.parseColor)(desc.docDefaultNewArtboardBackgroundColor);
|
|
3621
|
+
if (desc.docDefaultNewArtboardBackgroundType !== undefined)
|
|
3622
|
+
artboards.docDefaultNewArtboardBackgroundType = desc.docDefaultNewArtboardBackgroundType;
|
|
3387
3623
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
3388
3624
|
}, (writer, target) => {
|
|
3389
3625
|
var _a, _b, _c, _d, _e;
|
|
@@ -3401,17 +3637,19 @@ target => target.artboards !== undefined, (reader, target, left) => {
|
|
|
3401
3637
|
};
|
|
3402
3638
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc, 'artd');
|
|
3403
3639
|
});
|
|
3640
|
+
function isGroupLayer(target) {
|
|
3641
|
+
return !!target.children;
|
|
3642
|
+
}
|
|
3404
3643
|
function hasMultiEffects(effects) {
|
|
3405
3644
|
return Object.keys(effects).map(key => effects[key]).some(v => Array.isArray(v) && v.length > 1);
|
|
3406
3645
|
}
|
|
3407
|
-
addHandler('lfx2', target => target.effects !== undefined && !hasMultiEffects(target.effects), (reader, target, left) => {
|
|
3646
|
+
addHandler('lfx2', target => target.effects !== undefined && !isGroupLayer(target) && !hasMultiEffects(target.effects), (reader, target, left) => {
|
|
3408
3647
|
const version = (0, psdReader_1.readUint32)(reader);
|
|
3409
3648
|
if (version !== 0)
|
|
3410
3649
|
throw new Error(`Invalid lfx2 version`);
|
|
3411
3650
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
3412
3651
|
// console.log('READ', require('util').inspect(desc, false, 99, true));
|
|
3413
|
-
//
|
|
3414
|
-
// discard if read in 'lrFX' section
|
|
3652
|
+
// discard if read in 'lrFX' section ('lmfx' and 'lfx2' are never stored together)
|
|
3415
3653
|
target.effects = (0, descriptor_1.parseEffects)(desc, !!reader.logMissingFeatures);
|
|
3416
3654
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
3417
3655
|
}, (writer, target, _, options) => {
|
|
@@ -3468,27 +3706,25 @@ addHandler('cinf', hasKey('compositorUsed'), (reader, target, left) => {
|
|
|
3468
3706
|
desc.compCoreGPUSupport = `reason.${cinf.compCoreGPUSupport}`;
|
|
3469
3707
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
3470
3708
|
});
|
|
3471
|
-
//
|
|
3472
|
-
addHandler('extn', target => target.
|
|
3709
|
+
// generator settings of the document (layers store them in 'shmd' section)
|
|
3710
|
+
addHandler('extn', target => target.generatorSettings !== undefined && isDocument(target), (reader, target, left) => {
|
|
3473
3711
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3712
|
+
if (desc.generatorSettings)
|
|
3713
|
+
target.generatorSettings = parseGeneratorSettings(desc.generatorSettings);
|
|
3714
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
3477
3715
|
}, (writer, target) => {
|
|
3478
|
-
|
|
3479
|
-
if (helpers_1.MOCK_HANDLERS)
|
|
3480
|
-
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', target._extn);
|
|
3716
|
+
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', serializeGeneratorSettings(target.generatorSettings));
|
|
3481
3717
|
});
|
|
3482
3718
|
addHandler('iOpa', hasKey('fillOpacity'), (reader, target) => {
|
|
3483
3719
|
target.fillOpacity = (0, psdReader_1.readUint8)(reader) / 0xff;
|
|
3484
3720
|
(0, psdReader_1.skipBytes)(reader, 3);
|
|
3485
3721
|
}, (writer, target) => {
|
|
3486
|
-
(0, psdWriter_1.writeUint8)(writer, target.fillOpacity * 0xff);
|
|
3722
|
+
(0, psdWriter_1.writeUint8)(writer, Math.round((0, helpers_1.clamp)(target.fillOpacity, 0, 1) * 0xff));
|
|
3487
3723
|
(0, psdWriter_1.writeZeros)(writer, 3);
|
|
3488
3724
|
});
|
|
3489
3725
|
addHandler('brst', hasKey('channelBlendingRestrictions'), (reader, target, left) => {
|
|
3490
3726
|
target.channelBlendingRestrictions = [];
|
|
3491
|
-
while (left()
|
|
3727
|
+
while (left() >= 4) {
|
|
3492
3728
|
target.channelBlendingRestrictions.push((0, psdReader_1.readInt32)(reader));
|
|
3493
3729
|
}
|
|
3494
3730
|
}, (writer, target) => {
|