ag-psd 32.0.0 → 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/03e19709 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/2a19133e +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/7ea06cea +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +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/c314aece +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/dc86f000 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +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/f6fd8125 +0 -0
- package/CHANGELOG.md +78 -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 +357 -230
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.d.ts +54 -2
- package/dist/additionalInfo.js +487 -306
- 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 +1937 -1115
- package/dist/descriptor.d.ts +14 -8
- package/dist/descriptor.js +202 -186
- package/dist/descriptor.js.map +1 -1
- package/dist/helpers.d.ts +1 -1
- package/dist/helpers.js +4 -2
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.d.ts +15 -3
- package/dist/imageResources.js +503 -142
- package/dist/imageResources.js.map +1 -1
- package/dist/jpeg.js +8 -8
- package/dist/jpeg.js.map +1 -1
- package/dist/psd.d.ts +148 -17
- package/dist/psd.js.map +1 -1
- package/dist/psdReader.d.ts +10 -0
- package/dist/psdReader.js +278 -166
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +1 -0
- package/dist/psdWriter.js +77 -62
- package/dist/psdWriter.js.map +1 -1
- package/dist/text.js +17 -6
- package/dist/text.js.map +1 -1
- package/dist/utf8.js +0 -3
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.d.ts +11 -4
- package/dist-es/abr.js +357 -230
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +54 -2
- package/dist-es/additionalInfo.js +487 -306
- 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 +14 -8
- package/dist-es/descriptor.js +202 -186
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/helpers.d.ts +1 -1
- package/dist-es/helpers.js +4 -2
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.d.ts +15 -3
- package/dist-es/imageResources.js +503 -142
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/jpeg.js +8 -8
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psd.d.ts +148 -17
- package/dist-es/psd.js.map +1 -1
- package/dist-es/psdReader.d.ts +10 -0
- package/dist-es/psdReader.js +278 -166
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +1 -0
- package/dist-es/psdWriter.js +77 -62
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/text.js +17 -6
- package/dist-es/text.js.map +1 -1
- package/dist-es/utf8.js +0 -3
- package/dist-es/utf8.js.map +1 -1
- package/package.json +2 -2
- package/src/abr.ts +375 -235
- package/src/additionalInfo.ts +663 -420
- package/src/ase.ts +66 -61
- package/src/descriptor.ts +199 -195
- package/src/helpers.ts +4 -1
- package/src/imageResources.ts +632 -168
- package/src/jpeg.ts +8 -8
- package/src/psd.ts +156 -30
- package/src/psdReader.ts +273 -172
- package/src/psdWriter.ts +95 -58
- package/src/text.ts +17 -6
- package/src/utf8.ts +0 -4
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");
|
|
@@ -33,6 +36,7 @@ function readLength64(reader) {
|
|
|
33
36
|
return (0, psdReader_1.readUint32)(reader);
|
|
34
37
|
}
|
|
35
38
|
addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
|
|
39
|
+
var _a;
|
|
36
40
|
if ((0, psdReader_1.readInt16)(reader) !== 1)
|
|
37
41
|
throw new Error(`Invalid TySh version`);
|
|
38
42
|
const transform = [];
|
|
@@ -79,7 +83,8 @@ addHandler('TySh', hasKey('text'), (reader, target, leftBytes) => {
|
|
|
79
83
|
// require('fs').writeFileSync('before.txt', require('util').inspect(before, false, 99, false), 'utf8');
|
|
80
84
|
// require('fs').writeFileSync('after.txt', require('util').inspect(after, false, 99, false), 'utf8');
|
|
81
85
|
// console.log(require('util').inspect(parseEngineData(text.EngineData), false, 99, true));
|
|
82
|
-
|
|
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 });
|
|
83
88
|
// console.log(require('util').inspect(target.text, false, 99, true));
|
|
84
89
|
}
|
|
85
90
|
(0, psdReader_1.skipBytes)(reader, leftBytes());
|
|
@@ -209,25 +214,8 @@ function readVectorMask(reader, vectorMask, width, height, size) {
|
|
|
209
214
|
}
|
|
210
215
|
return paths;
|
|
211
216
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
throw new Error('Invalid vmsk version');
|
|
215
|
-
target.vectorMask = { paths: [] };
|
|
216
|
-
const vectorMask = target.vectorMask;
|
|
217
|
-
const flags = (0, psdReader_1.readUint32)(reader);
|
|
218
|
-
vectorMask.invert = (flags & 1) !== 0;
|
|
219
|
-
vectorMask.notLink = (flags & 2) !== 0;
|
|
220
|
-
vectorMask.disable = (flags & 4) !== 0;
|
|
221
|
-
readVectorMask(reader, vectorMask, width, height, left());
|
|
222
|
-
// drawBezierPaths(vectorMask.paths, width, height, 'out.png');
|
|
223
|
-
(0, psdReader_1.skipBytes)(reader, left());
|
|
224
|
-
}, (writer, target, { width, height }) => {
|
|
225
|
-
const vectorMask = target.vectorMask;
|
|
226
|
-
const flags = (vectorMask.invert ? 1 : 0) |
|
|
227
|
-
(vectorMask.notLink ? 2 : 0) |
|
|
228
|
-
(vectorMask.disable ? 4 : 0);
|
|
229
|
-
(0, psdWriter_1.writeUint32)(writer, 3); // version
|
|
230
|
-
(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) {
|
|
231
219
|
// initial entry
|
|
232
220
|
(0, psdWriter_1.writeUint16)(writer, 6);
|
|
233
221
|
(0, psdWriter_1.writeZeros)(writer, 24);
|
|
@@ -244,12 +232,18 @@ addHandler('vmsk', hasKey('vectorMask'), (reader, target, left, { width, height
|
|
|
244
232
|
(0, psdWriter_1.writeUint16)(writer, 8);
|
|
245
233
|
(0, psdWriter_1.writeUint16)(writer, vectorMask.fillStartsWithAllPixels ? 1 : 0);
|
|
246
234
|
(0, psdWriter_1.writeZeros)(writer, 22);
|
|
235
|
+
let componentIndex = -1;
|
|
247
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++;
|
|
248
240
|
(0, psdWriter_1.writeUint16)(writer, path.open ? 3 : 0);
|
|
249
241
|
(0, psdWriter_1.writeUint16)(writer, path.knots.length);
|
|
250
242
|
(0, psdWriter_1.writeUint16)(writer, path.operation ? exports.booleanOperations.indexOf(path.operation) : -1); // -1 for undefined
|
|
251
243
|
(0, psdWriter_1.writeUint16)(writer, path.fillRule === 'non-zero' ? 2 : 1);
|
|
252
|
-
(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);
|
|
253
247
|
const linkedKnot = path.open ? 4 : 1;
|
|
254
248
|
const unlinkedKnot = path.open ? 5 : 2;
|
|
255
249
|
for (const { linked, points } of path.knots) {
|
|
@@ -257,8 +251,29 @@ addHandler('vmsk', hasKey('vectorMask'), (reader, target, left, { width, height
|
|
|
257
251
|
writeBezierKnot(writer, points, width, height);
|
|
258
252
|
}
|
|
259
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);
|
|
260
275
|
});
|
|
261
|
-
//
|
|
276
|
+
// written instead of 'vmsk' for layers with vector stroke ('vscg' section)
|
|
262
277
|
addHandlerAlias('vsms', 'vmsk');
|
|
263
278
|
// addHandlerAlias('vmsk', 'vsms');
|
|
264
279
|
addHandler('vowv', // something with vectors?
|
|
@@ -267,12 +282,8 @@ hasKey('vowv'), (reader, target) => {
|
|
|
267
282
|
}, (writer, target) => {
|
|
268
283
|
(0, psdWriter_1.writeUint32)(writer, target.vowv);
|
|
269
284
|
});
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
throw new Error(`Invalid vogk version`);
|
|
273
|
-
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
274
|
-
// console.log(require('util').inspect(desc, false, 99, true));
|
|
275
|
-
target.vectorOrigination = { keyDescriptorList: [] };
|
|
285
|
+
function parseKeyDescriptorList(desc) {
|
|
286
|
+
const keyDescriptorList = [];
|
|
276
287
|
for (const i of desc.keyDescriptorList) {
|
|
277
288
|
const item = {};
|
|
278
289
|
if (i.keyShapeInvalidated != null)
|
|
@@ -311,15 +322,14 @@ addHandler('vogk', hasKey('vectorOrigination'), (reader, target, left) => {
|
|
|
311
322
|
if (trnf) {
|
|
312
323
|
item.transform = [trnf.xx, trnf.xy, trnf.yx, trnf.yy, trnf.tx, trnf.ty];
|
|
313
324
|
}
|
|
314
|
-
|
|
325
|
+
keyDescriptorList.push(item);
|
|
315
326
|
}
|
|
316
|
-
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const orig = target.vectorOrigination;
|
|
327
|
+
return keyDescriptorList;
|
|
328
|
+
}
|
|
329
|
+
function serializeKeyDescriptorList(keyDescriptorList) {
|
|
320
330
|
const desc = { keyDescriptorList: [] };
|
|
321
|
-
for (let i = 0; i <
|
|
322
|
-
const item =
|
|
331
|
+
for (let i = 0; i < keyDescriptorList.length; i++) {
|
|
332
|
+
const item = keyDescriptorList[i];
|
|
323
333
|
desc.keyDescriptorList.push({}); // we're adding keyOriginIndex at the end
|
|
324
334
|
const out = desc.keyDescriptorList[desc.keyDescriptorList.length - 1];
|
|
325
335
|
if (item.keyOriginType != null)
|
|
@@ -370,10 +380,21 @@ addHandler('vogk', hasKey('vectorOrigination'), (reader, target, left) => {
|
|
|
370
380
|
out.keyShapeInvalidated = item.keyShapeInvalidated;
|
|
371
381
|
out.keyOriginIndex = i;
|
|
372
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);
|
|
373
394
|
(0, psdWriter_1.writeInt32)(writer, 1); // version
|
|
374
395
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
375
396
|
});
|
|
376
|
-
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) => {
|
|
377
398
|
const version = (0, psdReader_1.readUint32)(reader);
|
|
378
399
|
if (version !== 0)
|
|
379
400
|
throw new Error('Invalid lmfx version');
|
|
@@ -449,8 +470,12 @@ addHandler('lyid', target => target.id !== undefined || layerNeedsId(target), (r
|
|
|
449
470
|
let id;
|
|
450
471
|
if (target.id !== undefined) {
|
|
451
472
|
id = target.id;
|
|
452
|
-
|
|
453
|
-
|
|
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
|
+
}
|
|
454
479
|
}
|
|
455
480
|
else {
|
|
456
481
|
// generate id for layers that don't have it, if it's referenced by other sections
|
|
@@ -523,12 +548,15 @@ addHandler('lspf', hasKey('protected'), (reader, target) => {
|
|
|
523
548
|
};
|
|
524
549
|
if (flags & 0x08)
|
|
525
550
|
target.protected.artboards = true;
|
|
551
|
+
if (flags & 0x80000000)
|
|
552
|
+
target.protected.all = true;
|
|
526
553
|
}, (writer, target) => {
|
|
527
554
|
const flags = (target.protected.transparency ? 0x01 : 0) |
|
|
528
555
|
(target.protected.composite ? 0x02 : 0) |
|
|
529
556
|
(target.protected.position ? 0x04 : 0) |
|
|
530
|
-
(target.protected.artboards ? 0x08 : 0)
|
|
531
|
-
|
|
557
|
+
(target.protected.artboards ? 0x08 : 0) |
|
|
558
|
+
(target.protected.all ? 0x80000000 : 0);
|
|
559
|
+
(0, psdWriter_1.writeUint32)(writer, flags >>> 0);
|
|
532
560
|
});
|
|
533
561
|
addHandler('lclr', hasKey('layerColor'), (reader, target) => {
|
|
534
562
|
const color = (0, psdReader_1.readUint16)(reader);
|
|
@@ -539,106 +567,160 @@ addHandler('lclr', hasKey('layerColor'), (reader, target) => {
|
|
|
539
567
|
(0, psdWriter_1.writeUint16)(writer, index === -1 ? 0 : index);
|
|
540
568
|
(0, psdWriter_1.writeZeros)(writer, 6);
|
|
541
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
|
+
}
|
|
542
611
|
addHandler('shmd', // Metadata setting
|
|
543
612
|
// Metadata setting
|
|
544
|
-
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) => {
|
|
545
615
|
const count = (0, psdReader_1.readUint32)(reader);
|
|
546
616
|
for (let i = 0; i < count; i++) {
|
|
547
|
-
(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
|
|
548
620
|
const key = (0, psdReader_1.readSignature)(reader);
|
|
549
621
|
(0, psdReader_1.readUint8)(reader); // copy
|
|
550
622
|
(0, psdReader_1.skipBytes)(reader, 3);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
target.
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
560
|
-
// console.log('mlst', target.name, require('util').inspect(desc, false, 99, true));
|
|
561
|
-
target.animationFrames = [];
|
|
562
|
-
for (let i = 0; i < desc.LaSt.length; i++) {
|
|
563
|
-
const f = desc.LaSt[i];
|
|
564
|
-
const frame = { frames: f.FrLs };
|
|
565
|
-
if (f.enab !== undefined)
|
|
566
|
-
frame.enable = f.enab;
|
|
567
|
-
if (f.Ofst)
|
|
568
|
-
frame.offset = (0, descriptor_1.horzVrtcToXY)(f.Ofst);
|
|
569
|
-
if (f.FXRf)
|
|
570
|
-
frame.referencePoint = (0, descriptor_1.horzVrtcToXY)(f.FXRf);
|
|
571
|
-
if (f.Lefx)
|
|
572
|
-
frame.effects = (0, descriptor_1.parseEffects)(f.Lefx, !!reader.logMissingFeatures);
|
|
573
|
-
if (f.blendOptions && f.blendOptions.Opct)
|
|
574
|
-
frame.opacity = (0, descriptor_1.parsePercent)(f.blendOptions.Opct);
|
|
575
|
-
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;
|
|
576
631
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
duration: (0, descriptor_1.frac)(timeScope.duration),
|
|
597
|
-
inTime: (0, descriptor_1.frac)(timeScope.inTime),
|
|
598
|
-
outTime: (0, descriptor_1.frac)(timeScope.outTime),
|
|
599
|
-
autoScope: desc.autoScope,
|
|
600
|
-
audioLevel: desc.audioLevel,
|
|
601
|
-
};
|
|
602
|
-
if (desc.trackList) {
|
|
603
|
-
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
|
+
}
|
|
604
651
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
for (const item of desc.layerSettings) {
|
|
617
|
-
target.comps.settings.push({ compList: item.compList });
|
|
618
|
-
const t = target.comps.settings[target.comps.settings.length - 1];
|
|
619
|
-
if ('enab' in item)
|
|
620
|
-
t.enabled = item.enab;
|
|
621
|
-
if (item.Ofst)
|
|
622
|
-
t.offset = { x: item.Ofst.Hrzn, y: item.Ofst.Vrtc };
|
|
623
|
-
if (item.FXRefPoint)
|
|
624
|
-
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
|
+
};
|
|
625
663
|
}
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
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
|
+
}
|
|
638
719
|
}
|
|
639
720
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
640
721
|
}, (writer, target, _, options) => {
|
|
641
722
|
const { animationFrames, animationFrameFlags, timestamp, timeline, comps } = target;
|
|
723
|
+
const generatorSettings = isDocument(target) ? undefined : target.generatorSettings;
|
|
642
724
|
let count = 0;
|
|
643
725
|
if (animationFrames)
|
|
644
726
|
count++;
|
|
@@ -650,6 +732,8 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
650
732
|
count++;
|
|
651
733
|
if (comps)
|
|
652
734
|
count++;
|
|
735
|
+
if (generatorSettings)
|
|
736
|
+
count++;
|
|
653
737
|
(0, psdWriter_1.writeUint32)(writer, count);
|
|
654
738
|
if (animationFrames) {
|
|
655
739
|
(0, psdWriter_1.writeSignature)(writer, '8BIM');
|
|
@@ -672,9 +756,9 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
672
756
|
if (f.referencePoint)
|
|
673
757
|
frame.FXRf = (0, descriptor_1.xyToHorzVrtc)(f.referencePoint);
|
|
674
758
|
if (f.effects)
|
|
675
|
-
frame.Lefx = (0, descriptor_1.serializeEffects)(f.effects, false,
|
|
759
|
+
frame.Lefx = (0, descriptor_1.serializeEffects)(f.effects, false, hasMultiEffects(f.effects));
|
|
676
760
|
if (f.opacity !== undefined)
|
|
677
|
-
frame.blendOptions = { Opct: (0, descriptor_1.
|
|
761
|
+
frame.blendOptions = { Opct: (0, descriptor_1.unitsPercentF)(f.opacity) };
|
|
678
762
|
desc.LaSt.push(frame);
|
|
679
763
|
}
|
|
680
764
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
@@ -758,6 +842,15 @@ target => target.timestamp !== undefined || target.animationFrames !== undefined
|
|
|
758
842
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
759
843
|
}, true);
|
|
760
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
|
+
}
|
|
761
854
|
});
|
|
762
855
|
addHandler('PxSc', hasKey('pixelSource'), (reader, target) => {
|
|
763
856
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
|
|
@@ -837,7 +930,7 @@ addHandler('vstk', hasKey('vectorStroke'), (reader, target, left) => {
|
|
|
837
930
|
lineAlignment: descriptor_1.strokeStyleLineAlignment.decode(desc.strokeStyleLineAlignment),
|
|
838
931
|
scaleLock: desc.strokeStyleScaleLock,
|
|
839
932
|
strokeAdjust: desc.strokeStyleStrokeAdjust,
|
|
840
|
-
lineDashSet: desc.strokeStyleLineDashSet.map(descriptor_1.parseUnits),
|
|
933
|
+
lineDashSet: (desc.strokeStyleLineDashSet || []).map(descriptor_1.parseUnits),
|
|
841
934
|
blendMode: descriptor_1.BlnM.decode(desc.strokeStyleBlendMode),
|
|
842
935
|
opacity: (0, descriptor_1.parsePercent)(desc.strokeStyleOpacity),
|
|
843
936
|
content: (0, descriptor_1.parseVectorContent)(desc.strokeStyleContent),
|
|
@@ -875,9 +968,11 @@ hasKey('artboard'), (reader, target, left) => {
|
|
|
875
968
|
rect: { top: rect['Top '], left: rect.Left, bottom: rect.Btom, right: rect.Rght },
|
|
876
969
|
guideIndices: desc.guideIndeces,
|
|
877
970
|
presetName: desc.artboardPresetName,
|
|
878
|
-
color: (0, descriptor_1.parseColor)(desc['Clr ']),
|
|
879
|
-
backgroundType: desc.artboardBackgroundType,
|
|
880
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;
|
|
881
976
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
882
977
|
}, (writer, target) => {
|
|
883
978
|
var _a;
|
|
@@ -983,14 +1078,15 @@ function encodeWarp(warp) {
|
|
|
983
1078
|
}
|
|
984
1079
|
return desc;
|
|
985
1080
|
}
|
|
986
|
-
addHandler('PlLd',
|
|
1081
|
+
addHandler('PlLd', target => !!target.placedLayer && !target.placedLayer.external, // linked smart objects are stored in SoLE
|
|
1082
|
+
(reader, target, left) => {
|
|
987
1083
|
if ((0, psdReader_1.readSignature)(reader) !== 'plcL')
|
|
988
1084
|
throw new Error(`Invalid PlLd signature`);
|
|
989
1085
|
if ((0, psdReader_1.readInt32)(reader) !== 3)
|
|
990
1086
|
throw new Error(`Invalid PlLd version`);
|
|
991
1087
|
const id = (0, psdReader_1.readPascalString)(reader, 1);
|
|
992
1088
|
const pageNumber = (0, psdReader_1.readInt32)(reader);
|
|
993
|
-
const totalPages = (0, psdReader_1.readInt32)(reader); //
|
|
1089
|
+
const totalPages = (0, psdReader_1.readInt32)(reader); // for multi-page documents (PDF)
|
|
994
1090
|
(0, psdReader_1.readInt32)(reader); // anitAliasPolicy 16
|
|
995
1091
|
const placedLayerType = (0, psdReader_1.readInt32)(reader); // 0 = unknown, 1 = vector, 2 = raster, 3 = image stack
|
|
996
1092
|
if (!placedLayerTypes[placedLayerType])
|
|
@@ -1035,6 +1131,8 @@ addHandler('PlLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
1035
1131
|
const type = isQuilt ? 'quiltWarp' : 'warp';
|
|
1036
1132
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', type, encodeWarp(warp), type);
|
|
1037
1133
|
});
|
|
1134
|
+
const levelsFilterKeys = ['_name', '_classID', 'presetKind', 'Adjs'];
|
|
1135
|
+
const levelsFilterAdjustmentKeys = ['_name', '_classID', 'Chnl', 'Inpt', 'Otpt', 'Gmm '];
|
|
1038
1136
|
function uint8ToFloat32(array) {
|
|
1039
1137
|
const length = Math.floor(array.byteLength / 4);
|
|
1040
1138
|
return new Float32Array(array.buffer.slice(array.byteOffset, array.byteOffset + length * 4), 0, length);
|
|
@@ -1077,7 +1175,7 @@ function pointToHrznVrtc(point) {
|
|
|
1077
1175
|
Vrtc: (0, descriptor_1.unitsValue)(point.y, 'y'),
|
|
1078
1176
|
};
|
|
1079
1177
|
}
|
|
1080
|
-
function parseFilterFXItem(f,
|
|
1178
|
+
function parseFilterFXItem(f, reader) {
|
|
1081
1179
|
const base = {
|
|
1082
1180
|
name: f['Nm '],
|
|
1083
1181
|
opacity: (0, descriptor_1.parsePercent)(f.blendOptions.Opct),
|
|
@@ -1125,7 +1223,7 @@ function parseFilterFXItem(f, options) {
|
|
|
1125
1223
|
undefinedAreas: descriptor_1.UndA.decode(f.Fltr.UndA),
|
|
1126
1224
|
displacementFile: {
|
|
1127
1225
|
signature: f.Fltr.DspF.sig,
|
|
1128
|
-
path: f.Fltr.DspF.path,
|
|
1226
|
+
path: f.Fltr.DspF.path,
|
|
1129
1227
|
},
|
|
1130
1228
|
} });
|
|
1131
1229
|
case 'Pnch': return Object.assign(Object.assign({}, base), { type: 'pinch', filter: {
|
|
@@ -1312,8 +1410,7 @@ function parseFilterFXItem(f, options) {
|
|
|
1312
1410
|
],
|
|
1313
1411
|
puppetShapeList: (f.Fltr.puppetShapeList || []).map(p => ({
|
|
1314
1412
|
rigidType: p.rigidType,
|
|
1315
|
-
//
|
|
1316
|
-
// TODO: VrsN
|
|
1413
|
+
// VrsM / VrsN - version (always 1.0)
|
|
1317
1414
|
originalVertexArray: uint8ToPoints(p.originalVertexArray),
|
|
1318
1415
|
deformedVertexArray: uint8ToPoints(p.deformedVertexArray),
|
|
1319
1416
|
indexArray: Array.from(uint8ToUint32(p.indexArray)),
|
|
@@ -1410,7 +1507,7 @@ function parseFilterFXItem(f, options) {
|
|
|
1410
1507
|
;
|
|
1411
1508
|
case 'Crvs':
|
|
1412
1509
|
{
|
|
1413
|
-
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 ? {
|
|
1414
1511
|
adjustments: f.Fltr.Adjs.map(a => {
|
|
1415
1512
|
const channels = a.Chnl.map(descriptor_1.Chnl.decode);
|
|
1416
1513
|
if (a['Crv ']) {
|
|
@@ -1434,6 +1531,35 @@ function parseFilterFXItem(f, options) {
|
|
|
1434
1531
|
} : {})) });
|
|
1435
1532
|
}
|
|
1436
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
|
+
;
|
|
1437
1563
|
case 'BrgC':
|
|
1438
1564
|
{
|
|
1439
1565
|
return Object.assign(Object.assign({}, base), { type: 'brightness/contrast', filter: {
|
|
@@ -1444,10 +1570,11 @@ function parseFilterFXItem(f, options) {
|
|
|
1444
1570
|
}
|
|
1445
1571
|
;
|
|
1446
1572
|
default:
|
|
1447
|
-
if (
|
|
1573
|
+
if (reader.throwForMissingFeatures) {
|
|
1448
1574
|
// console.log('FILTER', require('util').inspect(f, false, 99, true));
|
|
1449
1575
|
throw new Error(`Unknown filter classId: ${f.Fltr._classID}`);
|
|
1450
1576
|
}
|
|
1577
|
+
reader.logMissingFeatures && reader.log(`Unhandled smart filter: ${f.Fltr._classID} (${f['Nm ']})`);
|
|
1451
1578
|
return undefined;
|
|
1452
1579
|
}
|
|
1453
1580
|
}
|
|
@@ -1467,21 +1594,23 @@ function parseFilterFXItem(f, options) {
|
|
|
1467
1594
|
case 1314149187: return Object.assign(Object.assign({}, base), { type: 'ntsc colors' });
|
|
1468
1595
|
case 1231976050: return Object.assign(Object.assign({}, base), { type: 'invert' });
|
|
1469
1596
|
default:
|
|
1470
|
-
if (
|
|
1597
|
+
if (reader.throwForMissingFeatures) {
|
|
1471
1598
|
// console.log('FILTER', require('util').inspect(f, false, 99, true));
|
|
1472
1599
|
throw new Error(`Unknown filterID: ${f.filterID}`);
|
|
1473
1600
|
}
|
|
1601
|
+
reader.logMissingFeatures && reader.log(`Unhandled smart filter: ${f.filterID} (${f['Nm ']})`);
|
|
1602
|
+
return undefined;
|
|
1474
1603
|
}
|
|
1475
1604
|
}
|
|
1476
1605
|
}
|
|
1477
|
-
function parseFilterFX(desc,
|
|
1606
|
+
function parseFilterFX(desc, reader) {
|
|
1478
1607
|
return {
|
|
1479
1608
|
enabled: desc.enab,
|
|
1480
1609
|
validAtPosition: desc.validAtPosition,
|
|
1481
1610
|
maskEnabled: desc.filterMaskEnable,
|
|
1482
1611
|
maskLinked: desc.filterMaskLinked,
|
|
1483
1612
|
maskExtendWithWhite: desc.filterMaskExtendWithWhite,
|
|
1484
|
-
list: desc.filterFXList.map(x => parseFilterFXItem(x,
|
|
1613
|
+
list: desc.filterFXList.map(x => parseFilterFXItem(x, reader)).filter((x) => !!x),
|
|
1485
1614
|
};
|
|
1486
1615
|
}
|
|
1487
1616
|
function uvRadius(t) {
|
|
@@ -1837,14 +1966,14 @@ function serializeFilterFXItem(f) {
|
|
|
1837
1966
|
case 'puppet': return Object.assign(Object.assign({}, base), { Fltr: {
|
|
1838
1967
|
_name: 'Rigid Transform',
|
|
1839
1968
|
_classID: 'rigidTransform',
|
|
1840
|
-
'null': ['Ordn.Trgt'], //
|
|
1969
|
+
'null': ['Ordn.Trgt'], // target layer reference
|
|
1841
1970
|
rigidType: f.filter.rigidType,
|
|
1842
1971
|
puppetShapeList: (f.filter.puppetShapeList || []).map(p => ({
|
|
1843
1972
|
_name: '',
|
|
1844
1973
|
_classID: 'puppetShape',
|
|
1845
1974
|
rigidType: p.rigidType,
|
|
1846
|
-
VrsM: 1, //
|
|
1847
|
-
VrsN: 0, //
|
|
1975
|
+
VrsM: 1, // version major
|
|
1976
|
+
VrsN: 0, // version minor
|
|
1848
1977
|
originalVertexArray: toUint8(new Float32Array(pointsToArray(p.originalVertexArray))),
|
|
1849
1978
|
deformedVertexArray: toUint8(new Float32Array(pointsToArray(p.deformedVertexArray))),
|
|
1850
1979
|
indexArray: toUint8(new Uint32Array(p.indexArray)),
|
|
@@ -1926,7 +2055,7 @@ function serializeFilterFXItem(f) {
|
|
|
1926
2055
|
warpedVertices: f.filter.warpedVertices.map(pointToHrznVrtc),
|
|
1927
2056
|
quads: f.filter.quads.map(indices => ({ _name: '', _classID: 'quadIndices', indices })),
|
|
1928
2057
|
}, filterID: 442 });
|
|
1929
|
-
case 'curves': return Object.assign(Object.assign({}, base), { Fltr: Object.assign({ _name: 'Curves', _classID: 'Crvs', presetKind: descriptor_1.presetKindType.encode(f.filter.presetKind) }, (f.filter.adjustments ? {
|
|
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 ? {
|
|
1930
2059
|
Adjs: f.filter.adjustments.map(a => 'curve' in a ? {
|
|
1931
2060
|
_name: '',
|
|
1932
2061
|
_classID: 'CrvA',
|
|
@@ -1939,6 +2068,21 @@ function serializeFilterFXItem(f) {
|
|
|
1939
2068
|
Mpng: a.values,
|
|
1940
2069
|
})
|
|
1941
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 });
|
|
1942
2086
|
case 'brightness/contrast': return Object.assign(Object.assign({}, base), { Fltr: {
|
|
1943
2087
|
_name: 'Brightness/Contrast',
|
|
1944
2088
|
_classID: 'BrgC',
|
|
@@ -1989,7 +2133,8 @@ function getWarpFromPlacedLayer(placed) {
|
|
|
1989
2133
|
},
|
|
1990
2134
|
};
|
|
1991
2135
|
}
|
|
1992
|
-
addHandler('SoLd',
|
|
2136
|
+
addHandler('SoLd', target => !!target.placedLayer && !target.placedLayer.external, // linked smart objects are stored in SoLE
|
|
2137
|
+
(reader, target, left) => {
|
|
1993
2138
|
if ((0, psdReader_1.readSignature)(reader) !== 'soLD')
|
|
1994
2139
|
throw new Error(`Invalid SoLd type`);
|
|
1995
2140
|
const version = (0, psdReader_1.readInt32)(reader);
|
|
@@ -2046,13 +2191,18 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
2046
2191
|
const placedType = placedLayerTypes.indexOf(placed.type);
|
|
2047
2192
|
if (placedType === -1)
|
|
2048
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);
|
|
2049
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,
|
|
2050
2200
|
// quiltWarp: {} as any,
|
|
2051
|
-
warp: encodeWarp(
|
|
2201
|
+
warp: encodeWarp(warp), 'Sz ': {
|
|
2052
2202
|
_name: '',
|
|
2053
2203
|
_classID: 'Pnt ',
|
|
2054
|
-
Wdth:
|
|
2055
|
-
Hght:
|
|
2204
|
+
Wdth: width,
|
|
2205
|
+
Hght: height,
|
|
2056
2206
|
}, Rslt: placed.resolution ? (0, descriptor_1.unitsValue)(placed.resolution, 'resolution') : { units: 'Density', value: 72 } });
|
|
2057
2207
|
if (placed.filter) {
|
|
2058
2208
|
desc.filterFX = {
|
|
@@ -2066,14 +2216,6 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
2066
2216
|
filterFXList: placed.filter.list.map(f => serializeFilterFXItem(f)),
|
|
2067
2217
|
};
|
|
2068
2218
|
}
|
|
2069
|
-
// TODO:
|
|
2070
|
-
// desc.comp = -1;
|
|
2071
|
-
// desc.compInfo = { _name: '', _classID: 'null', compID: -1, originalCompID: -1 } as any;
|
|
2072
|
-
// desc.ClMg = {
|
|
2073
|
-
// _name: '',
|
|
2074
|
-
// _classID: 'ClMg',
|
|
2075
|
-
// placedLayerOCIOConversion: 'placedLayerOCIOConversion.placedLayerOCIOConvertEmbedded'
|
|
2076
|
-
// } as any;
|
|
2077
2219
|
// if (JSON.stringify(t) !== JSON.stringify(desc)) {
|
|
2078
2220
|
// console.log('read', require('util').inspect(t, false, 99, true));
|
|
2079
2221
|
// console.log('write', require('util').inspect(desc, false, 99, true));
|
|
@@ -2103,7 +2245,13 @@ addHandler('SoLd', hasKey('placedLayer'), (reader, target, left) => {
|
|
|
2103
2245
|
desc.compInfo = placed.compInfo;
|
|
2104
2246
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc, desc.quiltWarp ? 'quiltWarp' : 'warp');
|
|
2105
2247
|
});
|
|
2106
|
-
|
|
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);
|
|
2107
2255
|
addHandler('fxrp', hasKey('referencePoint'), (reader, target) => {
|
|
2108
2256
|
target.referencePoint = {
|
|
2109
2257
|
x: (0, psdReader_1.readFloat64)(reader),
|
|
@@ -2113,14 +2261,37 @@ addHandler('fxrp', hasKey('referencePoint'), (reader, target) => {
|
|
|
2113
2261
|
(0, psdWriter_1.writeFloat64)(writer, target.referencePoint.x);
|
|
2114
2262
|
(0, psdWriter_1.writeFloat64)(writer, target.referencePoint.y);
|
|
2115
2263
|
});
|
|
2116
|
-
|
|
2117
|
-
(
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
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
|
+
}
|
|
2124
2295
|
addHandler('LMsk', hasKey('userMask'), (reader, target) => {
|
|
2125
2296
|
target.userMask = {
|
|
2126
2297
|
colorSpace: (0, psdReader_1.readColor)(reader),
|
|
@@ -2144,11 +2315,13 @@ if (helpers_1.MOCK_HANDLERS) {
|
|
|
2144
2315
|
}, (writer, target) => false && (0, psdWriter_1.writeBytes)(writer, target._Patt));
|
|
2145
2316
|
}
|
|
2146
2317
|
else {
|
|
2147
|
-
addHandler('Patt', //
|
|
2148
|
-
//
|
|
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
|
|
2149
2320
|
target => !!(target.patterns && target.patterns.length > 0), (reader, target, left) => {
|
|
2150
2321
|
while (left() > 0) {
|
|
2151
|
-
const pattern = (0, psdReader_1.
|
|
2322
|
+
const pattern = (0, psdReader_1.readPatternSafe)(reader);
|
|
2323
|
+
if (!pattern)
|
|
2324
|
+
continue;
|
|
2152
2325
|
if (target.patterns === undefined)
|
|
2153
2326
|
target.patterns = [];
|
|
2154
2327
|
target.patterns.push(pattern);
|
|
@@ -2336,6 +2509,10 @@ addHandler('Anno', target => target.annotations !== undefined, (reader, target,
|
|
|
2336
2509
|
writer.view.setUint32(dataOffset - 4, writer.offset - dataOffset, false);
|
|
2337
2510
|
}
|
|
2338
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
|
+
}
|
|
2339
2516
|
function createLnkHandler(tag) {
|
|
2340
2517
|
addHandler(tag, (target) => {
|
|
2341
2518
|
const psd = target;
|
|
@@ -2357,8 +2534,8 @@ function createLnkHandler(tag) {
|
|
|
2357
2534
|
const version = (0, psdReader_1.readInt32)(reader);
|
|
2358
2535
|
const id = (0, psdReader_1.readPascalString)(reader, 1);
|
|
2359
2536
|
const name = (0, psdReader_1.readUnicodeString)(reader);
|
|
2360
|
-
const fileType = (
|
|
2361
|
-
const fileCreator = (
|
|
2537
|
+
const fileType = readFileTypeSignature(reader); // ' ' if empty
|
|
2538
|
+
const fileCreator = readFileTypeSignature(reader); // ' ' or '\0\0\0\0' if empty
|
|
2362
2539
|
const dataSize = readLength64(reader);
|
|
2363
2540
|
const hasFileOpenDescriptor = (0, psdReader_1.readUint8)(reader);
|
|
2364
2541
|
const fileOpenDescriptor = hasFileOpenDescriptor ? (0, descriptor_1.readVersionAndDescriptor)(reader) : undefined;
|
|
@@ -2509,28 +2686,40 @@ createLnkHandler('lnk2');
|
|
|
2509
2686
|
createLnkHandler('lnkE');
|
|
2510
2687
|
addHandlerAlias('lnkD', 'lnk2');
|
|
2511
2688
|
addHandlerAlias('lnk3', 'lnk2');
|
|
2512
|
-
|
|
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;
|
|
2513
2692
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
desc;
|
|
2517
|
-
|
|
2518
|
-
|
|
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) => {
|
|
2519
2708
|
const desc = {
|
|
2520
|
-
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
|
+
} : {})))),
|
|
2521
2716
|
};
|
|
2522
2717
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'pathsDataClass', desc);
|
|
2523
2718
|
});
|
|
2524
2719
|
addHandler('lyvr', hasKey('version'), (reader, target) => target.version = (0, psdReader_1.readUint32)(reader), (writer, target) => (0, psdWriter_1.writeUint32)(writer, target.version));
|
|
2525
|
-
addHandler('lfxs',
|
|
2526
|
-
//
|
|
2527
|
-
|
|
2528
|
-
// !!target.effects.dropShadow?.some(e => e.choke) ||
|
|
2529
|
-
// !!target.effects.innerShadow?.some(e => e.choke) ||
|
|
2530
|
-
// !!target.effects.outerGlow?.choke ||
|
|
2531
|
-
// !!target.effects.innerGlow?.choke
|
|
2532
|
-
// ),
|
|
2533
|
-
(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) => {
|
|
2534
2723
|
const version = (0, psdReader_1.readUint32)(reader);
|
|
2535
2724
|
if (version !== 0)
|
|
2536
2725
|
throw new Error(`Invalid lfxs version`);
|
|
@@ -2574,6 +2763,10 @@ function readLevelsChannel(reader) {
|
|
|
2574
2763
|
const midtoneInput = (0, psdReader_1.readInt16)(reader) / 100;
|
|
2575
2764
|
return { shadowInput, highlightInput, shadowOutput, highlightOutput, midtoneInput };
|
|
2576
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
|
+
}
|
|
2577
2770
|
function writeLevelsChannel(writer, channel) {
|
|
2578
2771
|
(0, psdWriter_1.writeInt16)(writer, channel.shadowInput);
|
|
2579
2772
|
(0, psdWriter_1.writeInt16)(writer, channel.highlightInput);
|
|
@@ -2584,48 +2777,36 @@ function writeLevelsChannel(writer, channel) {
|
|
|
2584
2777
|
addHandler('levl', adjustmentType('levels'), (reader, target, left) => {
|
|
2585
2778
|
if ((0, psdReader_1.readUint16)(reader) !== 2)
|
|
2586
2779
|
throw new Error('Invalid levl version');
|
|
2587
|
-
const
|
|
2588
|
-
for (let i = 0; i < 29 && left(); i++) {
|
|
2589
|
-
|
|
2590
|
-
}
|
|
2591
|
-
|
|
2592
|
-
target.adjustment = Object.assign(Object.assign({}, target.adjustment), { type: 'levels', rgb,
|
|
2593
|
-
red,
|
|
2594
|
-
green,
|
|
2595
|
-
blue });
|
|
2596
|
-
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) {
|
|
2597
2785
|
if ((0, psdReader_1.readSignature)(reader) !== 'Lvls')
|
|
2598
2786
|
throw new Error(`Invalid levl signature`);
|
|
2599
2787
|
if ((0, psdReader_1.readUint16)(reader) !== 3)
|
|
2600
2788
|
throw new Error(`Invalid levl version`);
|
|
2601
2789
|
const totalChannelRecords = (0, psdReader_1.readUint16)(reader);
|
|
2602
|
-
|
|
2603
|
-
|
|
2790
|
+
while (channels.length < totalChannelRecords && left() >= 10) {
|
|
2791
|
+
channels.push(readLevelsChannel(reader));
|
|
2604
2792
|
}
|
|
2605
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 });
|
|
2606
2798
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
2607
2799
|
}, (writer, target) => {
|
|
2608
|
-
const
|
|
2609
|
-
const defaultChannel = {
|
|
2610
|
-
shadowInput: 0,
|
|
2611
|
-
highlightInput: 255,
|
|
2612
|
-
shadowOutput: 0,
|
|
2613
|
-
highlightOutput: 255,
|
|
2614
|
-
midtoneInput: 1,
|
|
2615
|
-
};
|
|
2800
|
+
const channels = target.adjustment.channels || [];
|
|
2616
2801
|
(0, psdWriter_1.writeUint16)(writer, 2); // version
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
writeLevelsChannel(writer, info.green || defaultChannel);
|
|
2620
|
-
writeLevelsChannel(writer, info.blue || defaultChannel);
|
|
2621
|
-
for (let i = 0; i < (29 - 4); i++) {
|
|
2622
|
-
writeLevelsChannel(writer, defaultChannel);
|
|
2802
|
+
for (let i = 0; i < 29; i++) {
|
|
2803
|
+
writeLevelsChannel(writer, channels[i] || defaultLevelsChannel);
|
|
2623
2804
|
}
|
|
2624
2805
|
(0, psdWriter_1.writeSignature)(writer, 'Lvls');
|
|
2625
2806
|
(0, psdWriter_1.writeUint16)(writer, 3); // version
|
|
2626
2807
|
(0, psdWriter_1.writeUint16)(writer, 62); // total count
|
|
2627
|
-
for (let i =
|
|
2628
|
-
writeLevelsChannel(writer,
|
|
2808
|
+
for (let i = 29; i < 62; i++) {
|
|
2809
|
+
writeLevelsChannel(writer, channels[i] || defaultLevelsChannel);
|
|
2629
2810
|
}
|
|
2630
2811
|
});
|
|
2631
2812
|
function readCurveChannel(reader) {
|
|
@@ -2650,17 +2831,16 @@ addHandler('curv', adjustmentType('curves'), (reader, target, left) => {
|
|
|
2650
2831
|
if ((0, psdReader_1.readUint16)(reader) !== 1)
|
|
2651
2832
|
throw new Error('Invalid curv version');
|
|
2652
2833
|
(0, psdReader_1.readUint16)(reader);
|
|
2653
|
-
const
|
|
2654
|
-
const
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
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 });
|
|
2664
2844
|
// ignoring, duplicate information
|
|
2665
2845
|
// checkSignature(reader, 'Crv ');
|
|
2666
2846
|
// const cVersion = readUint16(reader);
|
|
@@ -2676,57 +2856,29 @@ addHandler('curv', adjustmentType('curves'), (reader, target, left) => {
|
|
|
2676
2856
|
// }
|
|
2677
2857
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
2678
2858
|
}, (writer, target) => {
|
|
2679
|
-
|
|
2680
|
-
const
|
|
2681
|
-
|
|
2682
|
-
let
|
|
2683
|
-
|
|
2684
|
-
channels
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
channels |= 2;
|
|
2689
|
-
channelCount++;
|
|
2690
|
-
}
|
|
2691
|
-
if (green && green.length) {
|
|
2692
|
-
channels |= 4;
|
|
2693
|
-
channelCount++;
|
|
2694
|
-
}
|
|
2695
|
-
if (blue && blue.length) {
|
|
2696
|
-
channels |= 8;
|
|
2697
|
-
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
|
+
}
|
|
2698
2868
|
}
|
|
2699
2869
|
(0, psdWriter_1.writeUint8)(writer, 0);
|
|
2700
2870
|
(0, psdWriter_1.writeUint16)(writer, 1); // version
|
|
2701
2871
|
(0, psdWriter_1.writeUint16)(writer, 0);
|
|
2702
|
-
(0, psdWriter_1.writeUint16)(writer,
|
|
2703
|
-
|
|
2704
|
-
writeCurveChannel(writer,
|
|
2705
|
-
if (red && red.length)
|
|
2706
|
-
writeCurveChannel(writer, red);
|
|
2707
|
-
if (green && green.length)
|
|
2708
|
-
writeCurveChannel(writer, green);
|
|
2709
|
-
if (blue && blue.length)
|
|
2710
|
-
writeCurveChannel(writer, blue);
|
|
2872
|
+
(0, psdWriter_1.writeUint16)(writer, channelsMask);
|
|
2873
|
+
for (const i of used)
|
|
2874
|
+
writeCurveChannel(writer, channels[i]);
|
|
2711
2875
|
(0, psdWriter_1.writeSignature)(writer, 'Crv ');
|
|
2712
2876
|
(0, psdWriter_1.writeUint16)(writer, 4); // version
|
|
2713
2877
|
(0, psdWriter_1.writeUint16)(writer, 0);
|
|
2714
|
-
(0, psdWriter_1.writeUint16)(writer,
|
|
2715
|
-
|
|
2716
|
-
(0, psdWriter_1.writeUint16)(writer,
|
|
2717
|
-
writeCurveChannel(writer,
|
|
2718
|
-
}
|
|
2719
|
-
if (red && red.length) {
|
|
2720
|
-
(0, psdWriter_1.writeUint16)(writer, 1);
|
|
2721
|
-
writeCurveChannel(writer, red);
|
|
2722
|
-
}
|
|
2723
|
-
if (green && green.length) {
|
|
2724
|
-
(0, psdWriter_1.writeUint16)(writer, 2);
|
|
2725
|
-
writeCurveChannel(writer, green);
|
|
2726
|
-
}
|
|
2727
|
-
if (blue && blue.length) {
|
|
2728
|
-
(0, psdWriter_1.writeUint16)(writer, 3);
|
|
2729
|
-
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]);
|
|
2730
2882
|
}
|
|
2731
2883
|
});
|
|
2732
2884
|
addHandler('expA', adjustmentType('exposure'), (reader, target, left) => {
|
|
@@ -2783,12 +2935,34 @@ function writeHueChannel(writer, channel) {
|
|
|
2783
2935
|
addHandler('hue2', adjustmentType('hue/saturation'), (reader, target, left) => {
|
|
2784
2936
|
if ((0, psdReader_1.readUint16)(reader) !== 2)
|
|
2785
2937
|
throw new Error('Invalid hue2 version');
|
|
2786
|
-
|
|
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) });
|
|
2787
2952
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
2788
2953
|
}, (writer, target) => {
|
|
2954
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
2789
2955
|
const info = target.adjustment;
|
|
2790
2956
|
(0, psdWriter_1.writeUint16)(writer, 2); // version
|
|
2791
|
-
|
|
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));
|
|
2792
2966
|
writeHueChannel(writer, info.reds);
|
|
2793
2967
|
writeHueChannel(writer, info.yellows);
|
|
2794
2968
|
writeHueChannel(writer, info.greens);
|
|
@@ -2867,16 +3041,18 @@ addHandler('phfl', adjustmentType('photo filter'), (reader, target, left) => {
|
|
|
2867
3041
|
color = (0, psdReader_1.readColor)(reader);
|
|
2868
3042
|
}
|
|
2869
3043
|
else { // version 3
|
|
2870
|
-
//
|
|
2871
|
-
//
|
|
2872
|
-
|
|
2873
|
-
const
|
|
2874
|
-
const
|
|
2875
|
-
|
|
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;
|
|
2876
3052
|
color = {
|
|
2877
|
-
l:
|
|
2878
|
-
a: (0, helpers_1.normalizeLabAB)(
|
|
2879
|
-
b: (0, helpers_1.normalizeLabAB)(
|
|
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))),
|
|
2880
3056
|
};
|
|
2881
3057
|
}
|
|
2882
3058
|
target.adjustment = {
|
|
@@ -3044,7 +3220,7 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
|
|
|
3044
3220
|
reader.offset--;
|
|
3045
3221
|
if (hasMethod) {
|
|
3046
3222
|
const method = (0, psdReader_1.readSignature)(reader);
|
|
3047
|
-
info.method = descriptor_1.gradientInterpolationMethodType.decode(method);
|
|
3223
|
+
info.method = descriptor_1.gradientInterpolationMethodType.decode(`gradientInterpolationMethodType.${method}`);
|
|
3048
3224
|
}
|
|
3049
3225
|
info.name = (0, psdReader_1.readUnicodeString)(reader);
|
|
3050
3226
|
info.colorStops = [];
|
|
@@ -3106,7 +3282,7 @@ addHandler('grdm', adjustmentType('gradient map'), (reader, target, left) => {
|
|
|
3106
3282
|
(0, psdWriter_1.writeUint8)(writer, info.reverse ? 1 : 0);
|
|
3107
3283
|
(0, psdWriter_1.writeUint8)(writer, info.dither ? 1 : 0);
|
|
3108
3284
|
if (info.method !== undefined) {
|
|
3109
|
-
(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]);
|
|
3110
3286
|
}
|
|
3111
3287
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, info.name || '');
|
|
3112
3288
|
(0, psdWriter_1.writeUint16)(writer, info.colorStops && info.colorStops.length || 0);
|
|
@@ -3428,17 +3604,22 @@ addHandler('artd', // document-wide artboard info
|
|
|
3428
3604
|
// document-wide artboard info
|
|
3429
3605
|
target => target.artboards !== undefined, (reader, target, left) => {
|
|
3430
3606
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
3431
|
-
target.artboards = {
|
|
3432
|
-
|
|
3433
|
-
autoExpandOffset
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
|
|
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;
|
|
3442
3623
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
3443
3624
|
}, (writer, target) => {
|
|
3444
3625
|
var _a, _b, _c, _d, _e;
|
|
@@ -3456,17 +3637,19 @@ target => target.artboards !== undefined, (reader, target, left) => {
|
|
|
3456
3637
|
};
|
|
3457
3638
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc, 'artd');
|
|
3458
3639
|
});
|
|
3640
|
+
function isGroupLayer(target) {
|
|
3641
|
+
return !!target.children;
|
|
3642
|
+
}
|
|
3459
3643
|
function hasMultiEffects(effects) {
|
|
3460
3644
|
return Object.keys(effects).map(key => effects[key]).some(v => Array.isArray(v) && v.length > 1);
|
|
3461
3645
|
}
|
|
3462
|
-
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) => {
|
|
3463
3647
|
const version = (0, psdReader_1.readUint32)(reader);
|
|
3464
3648
|
if (version !== 0)
|
|
3465
3649
|
throw new Error(`Invalid lfx2 version`);
|
|
3466
3650
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
3467
3651
|
// console.log('READ', require('util').inspect(desc, false, 99, true));
|
|
3468
|
-
//
|
|
3469
|
-
// discard if read in 'lrFX' section
|
|
3652
|
+
// discard if read in 'lrFX' section ('lmfx' and 'lfx2' are never stored together)
|
|
3470
3653
|
target.effects = (0, descriptor_1.parseEffects)(desc, !!reader.logMissingFeatures);
|
|
3471
3654
|
(0, psdReader_1.skipBytes)(reader, left());
|
|
3472
3655
|
}, (writer, target, _, options) => {
|
|
@@ -3523,16 +3706,14 @@ addHandler('cinf', hasKey('compositorUsed'), (reader, target, left) => {
|
|
|
3523
3706
|
desc.compCoreGPUSupport = `reason.${cinf.compCoreGPUSupport}`;
|
|
3524
3707
|
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', desc);
|
|
3525
3708
|
});
|
|
3526
|
-
//
|
|
3527
|
-
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) => {
|
|
3528
3711
|
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3712
|
+
if (desc.generatorSettings)
|
|
3713
|
+
target.generatorSettings = parseGeneratorSettings(desc.generatorSettings);
|
|
3714
|
+
(0, psdReader_1.skipBytes)(reader, left());
|
|
3532
3715
|
}, (writer, target) => {
|
|
3533
|
-
|
|
3534
|
-
if (helpers_1.MOCK_HANDLERS)
|
|
3535
|
-
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', target._extn);
|
|
3716
|
+
(0, descriptor_1.writeVersionAndDescriptor)(writer, '', 'null', serializeGeneratorSettings(target.generatorSettings));
|
|
3536
3717
|
});
|
|
3537
3718
|
addHandler('iOpa', hasKey('fillOpacity'), (reader, target) => {
|
|
3538
3719
|
target.fillOpacity = (0, psdReader_1.readUint8)(reader) / 0xff;
|