ag-psd 31.0.3 → 32.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.v8-cache/v24.7.0-x64-ef5a0af0/00d0e0b4 +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/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/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 +29 -0
- package/dist/abr.js +12 -5
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.d.ts +2 -0
- package/dist/additionalInfo.js +123 -68
- package/dist/additionalInfo.js.map +1 -1
- package/dist/bundle.js +1365 -632
- package/dist/descriptor.d.ts +15 -2
- package/dist/descriptor.js +329 -100
- 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 +5 -2
- package/dist/helpers.js +18 -4
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.js +45 -21
- package/dist/imageResources.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/jpeg.js +27 -7
- package/dist/jpeg.js.map +1 -1
- package/dist/psd.d.ts +6 -1
- package/dist/psdReader.d.ts +2 -2
- package/dist/psdReader.js +457 -270
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +2 -0
- package/dist/psdWriter.js +98 -76
- package/dist/psdWriter.js.map +1 -1
- package/dist/text.js +126 -23
- package/dist/text.js.map +1 -1
- package/dist/utf8.js +36 -15
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.js +12 -5
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +2 -0
- package/dist-es/additionalInfo.js +123 -68
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/descriptor.d.ts +15 -2
- package/dist-es/descriptor.js +329 -100
- 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 +5 -2
- package/dist-es/helpers.js +18 -4
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.js +45 -21
- 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 +27 -7
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psd.d.ts +6 -1
- package/dist-es/psdReader.d.ts +2 -2
- package/dist-es/psdReader.js +457 -270
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +2 -0
- package/dist-es/psdWriter.js +98 -76
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/text.js +126 -23
- package/dist-es/text.js.map +1 -1
- package/dist-es/utf8.js +36 -15
- package/dist-es/utf8.js.map +1 -1
- package/package.json +1 -1
- package/src/abr.ts +14 -6
- package/src/additionalInfo.ts +127 -66
- package/src/descriptor.ts +347 -107
- package/src/effectsHelpers.ts +9 -9
- package/src/engineData.ts +36 -13
- package/src/engineData2.ts +468 -432
- package/src/helpers.ts +19 -4
- package/src/imageResources.ts +49 -22
- package/src/index.ts +1 -0
- package/src/jpeg.ts +24 -9
- package/src/psd.ts +3 -1
- package/src/psdReader.ts +477 -260
- package/src/psdWriter.ts +100 -83
- package/src/text.ts +122 -12
- package/src/utf8.ts +35 -17
package/dist-es/descriptor.js
CHANGED
|
@@ -15,8 +15,12 @@ exports.IntC = exports.IntE = exports.Drct = exports.WndM = exports.CntE = expor
|
|
|
15
15
|
exports.presetKindType = exports.prjM = exports.FlMd = void 0;
|
|
16
16
|
exports.setLogErrors = setLogErrors;
|
|
17
17
|
exports.readAsciiStringOrClassId = readAsciiStringOrClassId;
|
|
18
|
+
exports.writeAsciiStringOrClassId = writeAsciiStringOrClassId;
|
|
18
19
|
exports.readDescriptorStructure = readDescriptorStructure;
|
|
19
20
|
exports.writeDescriptorStructure = writeDescriptorStructure;
|
|
21
|
+
exports.createDescriptorReference = createDescriptorReference;
|
|
22
|
+
exports.pathSelectionStateToReference = pathSelectionStateToReference;
|
|
23
|
+
exports.writeClassStructure = writeClassStructure;
|
|
20
24
|
exports.readVersionAndDescriptor = readVersionAndDescriptor;
|
|
21
25
|
exports.writeVersionAndDescriptor = writeVersionAndDescriptor;
|
|
22
26
|
exports.horzVrtcToXY = horzVrtcToXY;
|
|
@@ -155,6 +159,8 @@ const fieldToExtType = {
|
|
|
155
159
|
origFXRefPoint: nullType,
|
|
156
160
|
FXRefPoint: nullType,
|
|
157
161
|
ClMg: makeType('', 'ClMg'),
|
|
162
|
+
interpretation: makeType('', 'footageInterpretation'),
|
|
163
|
+
bgColor: makeType('', 'NativeQuad'),
|
|
158
164
|
};
|
|
159
165
|
const fieldToArrayExtType = {
|
|
160
166
|
'Crv ': makeType('', 'CrPt'),
|
|
@@ -188,6 +194,9 @@ const fieldToArrayExtType = {
|
|
|
188
194
|
layerSettings: nullType,
|
|
189
195
|
list: nullType,
|
|
190
196
|
Adjs: makeType('', 'CrvA'),
|
|
197
|
+
vertices: makeType('', 'Pnt '),
|
|
198
|
+
warpedVertices: makeType('', 'Pnt '),
|
|
199
|
+
quads: makeType('', 'quadIndices'),
|
|
191
200
|
};
|
|
192
201
|
const typeToField = {
|
|
193
202
|
'TEXT': [
|
|
@@ -213,6 +222,7 @@ const typeToField = {
|
|
|
213
222
|
'meshExpansion', 'meshRigidity', 'VrsM', 'VrsN', 'NmbG', 'WLMn', 'WLMx', 'AmMn', 'AmMx', 'SclH', 'SclV',
|
|
214
223
|
'Lvl ', 'TlNm', 'TlOf', 'FlRs', 'Thsh', 'ShrS', 'ShrE', 'FlRs', 'Vrnc', 'Strg', 'ExtS', 'ExtD',
|
|
215
224
|
'HrzS', 'VrtS', 'NmbR', 'EdgF', 'Ang1', 'Ang2', 'Ang3', 'Ang4', 'lastAppliedComp', 'capturedInfo',
|
|
225
|
+
'pixelSourceType',
|
|
216
226
|
],
|
|
217
227
|
'enum': [
|
|
218
228
|
'textGridding', 'Ornt', 'warpStyle', 'warpRotate', 'Inte', 'Bltn', 'ClrS', 'BlrQ',
|
|
@@ -223,6 +233,7 @@ const typeToField = {
|
|
|
223
233
|
'enableCompCoreThreads', 'gs99', 'FrDs', 'trackID', 'animInterpStyle', 'horzAlign',
|
|
224
234
|
'vertAlign', 'bgColorType', 'shapeOperation', 'UndA', 'Wvtp', 'Drct', 'WndM', 'Edg ', 'FlCl', 'IntE',
|
|
225
235
|
'IntC', 'Cnvr', 'Fl ', 'Dstr', 'MztT', 'Lns ', 'ExtT', 'DspM', 'ExtR', 'ZZTy', 'SphM', 'SmBQ', 'placedLayerOCIOConversion', 'gradientsInterpolationMethod',
|
|
236
|
+
'interpretAlpha',
|
|
226
237
|
],
|
|
227
238
|
'bool': [
|
|
228
239
|
'PstS', 'printSixteenBit', 'masterFXSwitch', 'enab', 'uglg', 'antialiasGloss',
|
|
@@ -235,14 +246,15 @@ const typeToField = {
|
|
|
235
246
|
'materialsDisclosed', 'hasMotion', 'muted', 'Effc', 'selected', 'autoScope', 'fillCanvas',
|
|
236
247
|
'cellTextIsHTML', 'Smoo', 'Clsp', 'validAtPosition', 'rigidType', 'hasoptions', 'filterMaskEnable',
|
|
237
248
|
'filterMaskLinked', 'filterMaskExtendWithWhite', 'removeJPEGArtifact', 'Mnch', 'ExtF', 'ExtM',
|
|
238
|
-
'moreAccurate', 'GpuY', 'LIWy', 'Cnty',
|
|
249
|
+
'moreAccurate', 'GpuY', 'LIWy', 'Cnty', 'Lnkd', 'showAlteredVideo', 'lightingOn',
|
|
239
250
|
],
|
|
240
251
|
'doub': [
|
|
241
252
|
'warpValue', 'warpPerspective', 'warpPerspectiveOther', 'Intr', 'Wdth', 'Hght',
|
|
242
253
|
'strokeStyleMiterLimit', 'strokeStyleResolution', 'layerTime', 'keyOriginResolution',
|
|
243
254
|
'xx', 'xy', 'yx', 'yy', 'tx', 'ty', 'FrGA', 'frameRate', 'audioLevel', 'rotation',
|
|
244
255
|
'X ', 'Y ', 'redFloat', 'greenFloat', 'blueFloat', 'imageResolution',
|
|
245
|
-
'PuX0', 'PuX1', 'PuX2', 'PuX3', 'PuY0', 'PuY1', 'PuY2', 'PuY3'
|
|
256
|
+
'PuX0', 'PuX1', 'PuX2', 'PuX3', 'PuY0', 'PuY1', 'PuY2', 'PuY3',
|
|
257
|
+
'stylization', 'cleanliness', 'brushScale', 'microBrush', 'specularity',
|
|
246
258
|
],
|
|
247
259
|
'UntF': [
|
|
248
260
|
'sdwO', 'hglO', 'lagl', 'Lald', 'srgR', 'blur', 'Sftn', 'Opct', 'Dstn', 'Angl',
|
|
@@ -258,14 +270,57 @@ const typeToField = {
|
|
|
258
270
|
'warpValues', 'selectedPin', 'Pts ', 'SbpL', 'pathComponents', 'pinOffsets', 'posFinalPins',
|
|
259
271
|
'pinVertexIndices', 'PinP', 'PnRt', 'PnOv', 'PnDp', 'filterFXList', 'puppetShapeList', 'ShrP',
|
|
260
272
|
'channelDenoise', 'Mtrx', 'layerSettings', 'list', 'compList', 'Adjs',
|
|
273
|
+
'vertices', 'warpedVertices', 'quads', 'indices', 'Mpng',
|
|
261
274
|
],
|
|
262
275
|
'ObAr': ['meshPoints', 'quiltSliceX', 'quiltSliceY'],
|
|
263
276
|
'obj ': ['null', 'Chnl'],
|
|
264
277
|
'Pth ': ['DspF'],
|
|
278
|
+
'alis': ['alis'],
|
|
265
279
|
};
|
|
266
280
|
const channels = [
|
|
267
281
|
'Rd ', 'Grn ', 'Bl ', 'Yllw', 'Ylw ', 'Cyn ', 'Mgnt', 'Blck', 'Gry ', 'Lmnc', 'A ', 'B ',
|
|
268
282
|
];
|
|
283
|
+
// color classes whose channel values are written as doubles ('GRYC' and 'LABC' are kept for backwards compatibility)
|
|
284
|
+
const doubleColorClasses = ['Grsc', 'LbCl', 'GRYC', 'LABC'];
|
|
285
|
+
// Hidden (non-enumerable) markers used to remember how values were stored in the file, so they can be
|
|
286
|
+
// written back the same way. They don't change the shape of the objects returned by the reader.
|
|
287
|
+
const osTypeKey = typeof Symbol !== 'undefined' ? Symbol('agPsdOSType') : '__agPsdOSType';
|
|
288
|
+
const obArInfoKey = typeof Symbol !== 'undefined' ? Symbol('agPsdObAr') : '__agPsdObAr';
|
|
289
|
+
const referenceInfoKey = typeof Symbol !== 'undefined' ? Symbol('agPsdReference') : '__agPsdReference';
|
|
290
|
+
function setHidden(target, key, value) {
|
|
291
|
+
Object.defineProperty(target, key, { value, enumerable: false, configurable: true, writable: true });
|
|
292
|
+
return target;
|
|
293
|
+
}
|
|
294
|
+
function getHidden(target, key) {
|
|
295
|
+
return (target && typeof target === 'object') ? target[key] : undefined;
|
|
296
|
+
}
|
|
297
|
+
const osTypeFamilies = {
|
|
298
|
+
UntF: 'UntF', UnFl: 'UntF',
|
|
299
|
+
Objc: 'Objc', GlbO: 'Objc',
|
|
300
|
+
type: 'type', GlbC: 'type',
|
|
301
|
+
comp: 'comp',
|
|
302
|
+
};
|
|
303
|
+
// returns the OS type the value was originally read with, if it's compatible with the type we'd write it as
|
|
304
|
+
// fallback for unknown keys, based on the type of the value
|
|
305
|
+
function guessOSType(value) {
|
|
306
|
+
if (typeof value === 'boolean')
|
|
307
|
+
return 'bool';
|
|
308
|
+
if (typeof value === 'number' && !Number.isInteger(value))
|
|
309
|
+
return 'doub';
|
|
310
|
+
if (Array.isArray(value))
|
|
311
|
+
return 'VlLs';
|
|
312
|
+
if (value && typeof value === 'object' && typeof value._classID === 'string')
|
|
313
|
+
return 'Objc';
|
|
314
|
+
return undefined;
|
|
315
|
+
}
|
|
316
|
+
function getRecordedOSType(value, type) {
|
|
317
|
+
const recorded = getHidden(value, osTypeKey);
|
|
318
|
+
if (!recorded)
|
|
319
|
+
return type;
|
|
320
|
+
if (!type || recorded === 'comp' || recorded === 'type' || recorded === 'GlbC')
|
|
321
|
+
return recorded;
|
|
322
|
+
return osTypeFamilies[recorded] === osTypeFamilies[type] ? recorded : type;
|
|
323
|
+
}
|
|
269
324
|
const fieldToArrayType = {
|
|
270
325
|
'Mnm ': 'long',
|
|
271
326
|
'Mxm ': 'long',
|
|
@@ -305,6 +360,8 @@ const fieldToArrayType = {
|
|
|
305
360
|
Mtrx: 'long',
|
|
306
361
|
compList: 'long',
|
|
307
362
|
Chnl: 'enum',
|
|
363
|
+
indices: 'long',
|
|
364
|
+
Mpng: 'long',
|
|
308
365
|
};
|
|
309
366
|
const fieldToType = {};
|
|
310
367
|
for (const type of Object.keys(typeToField)) {
|
|
@@ -319,6 +376,7 @@ for (const field of Object.keys(fieldToExtType)) {
|
|
|
319
376
|
for (const field of Object.keys(fieldToArrayExtType)) {
|
|
320
377
|
fieldToArrayType[field] = 'Objc';
|
|
321
378
|
}
|
|
379
|
+
const pixelSourceOriginRoot = 'PixelSource.origin';
|
|
322
380
|
function getTypeByKey(key, value, root, parent) {
|
|
323
381
|
if (key === 'presetKind') {
|
|
324
382
|
return typeof value === 'string' ? 'enum' : 'long';
|
|
@@ -338,7 +396,7 @@ function getTypeByKey(key, value, root, parent) {
|
|
|
338
396
|
else if (key === 'AntA') {
|
|
339
397
|
return typeof value === 'string' ? 'enum' : 'bool';
|
|
340
398
|
}
|
|
341
|
-
else if ((key === 'Hrzn' || key === 'Vrtc') && (parent.Type === 'keyType.Pstn' || parent._classID === 'Ofst')) {
|
|
399
|
+
else if ((key === 'Hrzn' || key === 'Vrtc') && (parent.Type === 'keyType.Pstn' || parent._classID === 'Ofst' || root === pixelSourceOriginRoot)) {
|
|
342
400
|
return 'long';
|
|
343
401
|
}
|
|
344
402
|
else if (key === 'Hrzn' || key === 'Vrtc' || key === 'Top ' || key === 'Left' || key === 'Btom' || key === 'Rght') {
|
|
@@ -355,6 +413,15 @@ function getTypeByKey(key, value, root, parent) {
|
|
|
355
413
|
else if (key === 'Trnf') {
|
|
356
414
|
return Array.isArray(value) ? 'VlLs' : 'Objc';
|
|
357
415
|
}
|
|
416
|
+
else if (key === 'alpha' && root === 'slices') {
|
|
417
|
+
return 'long';
|
|
418
|
+
}
|
|
419
|
+
else if ((key === 'Inpt' || key === 'Otpt') && parent._classID === 'HsbP') {
|
|
420
|
+
return 'enum';
|
|
421
|
+
}
|
|
422
|
+
else if (key === 'LghD' && parent._classID === 'oilPaint') {
|
|
423
|
+
return 'long';
|
|
424
|
+
}
|
|
358
425
|
else {
|
|
359
426
|
return fieldToType[key];
|
|
360
427
|
}
|
|
@@ -398,23 +465,22 @@ function writeDescriptorStructure(writer, name, classId, value, root) {
|
|
|
398
465
|
// write class structure
|
|
399
466
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, name);
|
|
400
467
|
writeAsciiStringOrClassId(writer, classId);
|
|
401
|
-
const
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
keyCount--;
|
|
405
|
-
if ('_classID' in value)
|
|
406
|
-
keyCount--;
|
|
407
|
-
(0, psdWriter_1.writeUint32)(writer, keyCount);
|
|
468
|
+
const allKeys = Object.keys(value);
|
|
469
|
+
const keys = allKeys.filter(key => key !== '_name' && key !== '_classID' && value[key] !== undefined);
|
|
470
|
+
(0, psdWriter_1.writeUint32)(writer, keys.length);
|
|
408
471
|
for (const key of keys) {
|
|
409
|
-
if (key === '_name' || key === '_classID')
|
|
410
|
-
continue;
|
|
411
472
|
let type = getTypeByKey(key, value[key], root, value);
|
|
473
|
+
let childRoot = root;
|
|
412
474
|
let extType = fieldToExtType[key];
|
|
413
475
|
if (key === 'bounds' && root === 'text') {
|
|
414
476
|
extType = makeType('', 'bounds');
|
|
415
477
|
}
|
|
416
478
|
else if (key === 'origin') {
|
|
417
479
|
type = root === 'slices' ? 'enum' : 'Objc';
|
|
480
|
+
if (classId === 'PixelSource') {
|
|
481
|
+
extType = nullType; // stored as 'null' class with integer Hrzn/Vrtc
|
|
482
|
+
childRoot = pixelSourceOriginRoot;
|
|
483
|
+
}
|
|
418
484
|
}
|
|
419
485
|
else if ((key === 'Cyn ' || key === 'Mgnt' || key === 'Ylw ' || key === 'Blck') && value._classID === 'CMYC') {
|
|
420
486
|
type = 'doub';
|
|
@@ -482,10 +548,14 @@ function writeDescriptorStructure(writer, name, classId, value, root) {
|
|
|
482
548
|
extType = nullType;
|
|
483
549
|
}
|
|
484
550
|
else if (channels.indexOf(key) !== -1) {
|
|
485
|
-
type = (classId === 'RGBC' && root !== 'artd') ? 'doub' : 'long';
|
|
551
|
+
type = ((classId === 'RGBC' && root !== 'artd') || doubleColorClasses.indexOf(classId) !== -1) ? 'doub' : 'long';
|
|
486
552
|
}
|
|
487
553
|
else if (key === 'profile') {
|
|
488
|
-
type = classId === 'printOutput' ? 'TEXT' : 'tdta';
|
|
554
|
+
type = (classId === 'printOutput' || classId === 'proofSetup') ? 'TEXT' : 'tdta';
|
|
555
|
+
}
|
|
556
|
+
else if (key === 'alis' && typeof value[key] === 'string') {
|
|
557
|
+
// 'alis' is read as a binary string (one char per byte), strings with wider chars can only be stored as TEXT
|
|
558
|
+
type = /[^\x00-\xff]/.test(value[key]) ? 'TEXT' : 'alis';
|
|
489
559
|
}
|
|
490
560
|
else if (key === 'strokeStyleContent') {
|
|
491
561
|
if (value[key]['Clr ']) {
|
|
@@ -509,9 +579,12 @@ function writeDescriptorStructure(writer, name, classId, value, root) {
|
|
|
509
579
|
extType = { classID: 'HSBC', name: '' };
|
|
510
580
|
// TODO: other color spaces
|
|
511
581
|
}
|
|
582
|
+
type = getRecordedOSType(value[key], type);
|
|
583
|
+
if (!type)
|
|
584
|
+
type = guessOSType(value[key]);
|
|
512
585
|
writeAsciiStringOrClassId(writer, key);
|
|
513
586
|
(0, psdWriter_1.writeSignature)(writer, type || 'long');
|
|
514
|
-
writeOSType(writer, type || 'long', value[key], key, extType,
|
|
587
|
+
writeOSType(writer, type || 'long', value[key], key, extType, childRoot);
|
|
515
588
|
if (logErrors && !type)
|
|
516
589
|
console.log(`Missing descriptor field type for: '${key}' in`, value);
|
|
517
590
|
}
|
|
@@ -521,8 +594,9 @@ function readOSType(reader, type, includeClass) {
|
|
|
521
594
|
case 'obj ': // Reference
|
|
522
595
|
return readReferenceStructure(reader);
|
|
523
596
|
case 'Objc': // Descriptor
|
|
524
|
-
case 'GlbO': // GlobalObject same as Descriptor
|
|
525
597
|
return readDescriptorStructure(reader, includeClass);
|
|
598
|
+
case 'GlbO': // GlobalObject same as Descriptor
|
|
599
|
+
return setHidden(readDescriptorStructure(reader, includeClass), osTypeKey, type);
|
|
526
600
|
case 'VlLs': { // List
|
|
527
601
|
const length = (0, psdReader_1.readInt32)(reader);
|
|
528
602
|
const items = [];
|
|
@@ -547,7 +621,7 @@ function readOSType(reader, type, includeClass) {
|
|
|
547
621
|
const value = (0, psdReader_1.readFloat32)(reader);
|
|
548
622
|
if (!unitsMap[units])
|
|
549
623
|
throw new Error(`Invalid units: ${units}`);
|
|
550
|
-
return { units: unitsMap[units], value };
|
|
624
|
+
return setHidden({ units: unitsMap[units], value }, osTypeKey, type);
|
|
551
625
|
}
|
|
552
626
|
case 'TEXT': // String
|
|
553
627
|
return (0, psdReader_1.readUnicodeString)(reader);
|
|
@@ -561,13 +635,13 @@ function readOSType(reader, type, includeClass) {
|
|
|
561
635
|
case 'comp': { // Large Integer
|
|
562
636
|
const low = (0, psdReader_1.readUint32)(reader);
|
|
563
637
|
const high = (0, psdReader_1.readUint32)(reader);
|
|
564
|
-
return { low, high };
|
|
638
|
+
return setHidden({ low, high }, osTypeKey, type);
|
|
565
639
|
}
|
|
566
640
|
case 'bool': // Boolean
|
|
567
641
|
return !!(0, psdReader_1.readUint8)(reader);
|
|
568
642
|
case 'type': // Class
|
|
569
643
|
case 'GlbC': // Class
|
|
570
|
-
return readClassStructure(reader);
|
|
644
|
+
return setHidden(readClassStructure(reader), osTypeKey, type);
|
|
571
645
|
case 'alis': { // Alias
|
|
572
646
|
const length = (0, psdReader_1.readInt32)(reader);
|
|
573
647
|
return (0, psdReader_1.readAsciiString)(reader, length);
|
|
@@ -579,21 +653,21 @@ function readOSType(reader, type, includeClass) {
|
|
|
579
653
|
case 'ObAr': { // Object array
|
|
580
654
|
(0, psdReader_1.readInt32)(reader); // version: 16
|
|
581
655
|
(0, psdReader_1.readUnicodeString)(reader); // name: ''
|
|
582
|
-
readAsciiStringOrClassId(reader); // 'rationalPoint'
|
|
656
|
+
const classID = readAsciiStringOrClassId(reader); // 'rationalPoint'
|
|
583
657
|
const length = (0, psdReader_1.readInt32)(reader);
|
|
584
658
|
const items = [];
|
|
585
659
|
for (let i = 0; i < length; i++) {
|
|
586
660
|
const type1 = readAsciiStringOrClassId(reader); // type Hrzn | Vrtc
|
|
587
|
-
(0, psdReader_1.readSignature)(reader); // UnFl
|
|
588
|
-
(0, psdReader_1.readSignature)(reader); // units ? '#Pxl'
|
|
661
|
+
const valueType = (0, psdReader_1.readSignature)(reader); // UnFl
|
|
662
|
+
const units = (0, psdReader_1.readSignature)(reader); // units ? '#Pxl'
|
|
589
663
|
const valuesCount = (0, psdReader_1.readInt32)(reader);
|
|
590
664
|
const values = [];
|
|
591
665
|
for (let j = 0; j < valuesCount; j++) {
|
|
592
666
|
values.push((0, psdReader_1.readFloat64)(reader));
|
|
593
667
|
}
|
|
594
|
-
items.push({ type: type1, values });
|
|
668
|
+
items.push(setHidden({ type: type1, values }, obArInfoKey, { valueType, units }));
|
|
595
669
|
}
|
|
596
|
-
return items;
|
|
670
|
+
return setHidden(items, obArInfoKey, { classID });
|
|
597
671
|
}
|
|
598
672
|
case 'Pth ': { // File path
|
|
599
673
|
/*const length =*/ (0, psdReader_1.readInt32)(reader); // total size of all fields below
|
|
@@ -613,6 +687,7 @@ const ObArTypes = {
|
|
|
613
687
|
quiltSliceY: 'UntF',
|
|
614
688
|
};
|
|
615
689
|
function writeOSType(writer, type, value, key, extType, root) {
|
|
690
|
+
var _a, _b, _c, _d, _e;
|
|
616
691
|
switch (type) {
|
|
617
692
|
case 'obj ': // Reference
|
|
618
693
|
writeReferenceStructure(writer, key, value);
|
|
@@ -621,9 +696,9 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
621
696
|
case 'GlbO': { // GlobalObject same as Descriptor
|
|
622
697
|
if (typeof value !== 'object')
|
|
623
698
|
throw new Error(`Invalid struct value: ${JSON.stringify(value)}, key: ${key}`);
|
|
624
|
-
if (!extType)
|
|
699
|
+
if (!extType && !value._classID)
|
|
625
700
|
throw new Error(`Missing ext type for: '${key}' (${JSON.stringify(value)})`);
|
|
626
|
-
const name = value._name || extType.name;
|
|
701
|
+
const name = value._name || (extType === null || extType === void 0 ? void 0 : extType.name) || '';
|
|
627
702
|
const classID = value._classID || extType.classID;
|
|
628
703
|
writeDescriptorStructure(writer, name, classID, value, root);
|
|
629
704
|
break;
|
|
@@ -633,7 +708,7 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
633
708
|
throw new Error(`Invalid list value: ${JSON.stringify(value)}, key: ${key}`);
|
|
634
709
|
(0, psdWriter_1.writeInt32)(writer, value.length);
|
|
635
710
|
for (let i = 0; i < value.length; i++) {
|
|
636
|
-
const type = fieldToArrayType[key];
|
|
711
|
+
const type = (_a = getRecordedOSType(value[i], fieldToArrayType[key])) !== null && _a !== void 0 ? _a : guessOSType(value[i]);
|
|
637
712
|
(0, psdWriter_1.writeSignature)(writer, type || 'long');
|
|
638
713
|
writeOSType(writer, type || 'long', value[i], `${key}[]`, fieldToArrayExtType[key], root);
|
|
639
714
|
if (logErrors && !type)
|
|
@@ -671,20 +746,35 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
671
746
|
case 'long': // Integer
|
|
672
747
|
if (typeof value !== 'number')
|
|
673
748
|
throw new Error(`Invalid integer value: ${JSON.stringify(value)}, key: ${key}`);
|
|
674
|
-
(0, psdWriter_1.writeInt32)(writer, value);
|
|
749
|
+
(0, psdWriter_1.writeInt32)(writer, Math.round(value)); // round instead of truncating fractional values
|
|
750
|
+
break;
|
|
751
|
+
case 'comp': // Large Integer
|
|
752
|
+
if (!value || typeof value !== 'object')
|
|
753
|
+
throw new Error(`Invalid large integer value: ${JSON.stringify(value)}, key: ${key}`);
|
|
754
|
+
(0, psdWriter_1.writeUint32)(writer, value.low >>> 0);
|
|
755
|
+
(0, psdWriter_1.writeUint32)(writer, value.high >>> 0);
|
|
675
756
|
break;
|
|
676
|
-
// case 'comp': // Large Integer
|
|
677
|
-
// writeLargeInteger(reader);
|
|
678
757
|
case 'bool': // Boolean
|
|
679
758
|
if (typeof value !== 'boolean')
|
|
680
759
|
throw new Error(`Invalid boolean value: ${JSON.stringify(value)}, key: ${key}`);
|
|
681
760
|
(0, psdWriter_1.writeUint8)(writer, value ? 1 : 0);
|
|
682
761
|
break;
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
762
|
+
case 'type': // Class
|
|
763
|
+
case 'GlbC': // Class
|
|
764
|
+
if (!value || typeof value !== 'object')
|
|
765
|
+
throw new Error(`Invalid class value: ${JSON.stringify(value)}, key: ${key}`);
|
|
766
|
+
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, value.name || '');
|
|
767
|
+
writeAsciiStringOrClassId(writer, value.classID);
|
|
768
|
+
break;
|
|
769
|
+
case 'alis': { // Alias (read as a binary string, one char per byte)
|
|
770
|
+
if (typeof value !== 'string')
|
|
771
|
+
throw new Error(`Invalid alias value: ${JSON.stringify(value)}, key: ${key}`);
|
|
772
|
+
(0, psdWriter_1.writeInt32)(writer, value.length);
|
|
773
|
+
for (let i = 0; i < value.length; i++) {
|
|
774
|
+
(0, psdWriter_1.writeUint8)(writer, value.charCodeAt(i) & 0xff);
|
|
775
|
+
}
|
|
776
|
+
break;
|
|
777
|
+
}
|
|
688
778
|
case 'tdta': // Raw Data
|
|
689
779
|
(0, psdWriter_1.writeInt32)(writer, value.byteLength);
|
|
690
780
|
(0, psdWriter_1.writeBytes)(writer, value);
|
|
@@ -692,15 +782,16 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
692
782
|
case 'ObAr': { // Object array
|
|
693
783
|
(0, psdWriter_1.writeInt32)(writer, 16); // version
|
|
694
784
|
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, ''); // name
|
|
695
|
-
const type = ObArTypes[key];
|
|
785
|
+
const type = (_c = (_b = getHidden(value, obArInfoKey)) === null || _b === void 0 ? void 0 : _b.classID) !== null && _c !== void 0 ? _c : ObArTypes[key];
|
|
696
786
|
if (!type)
|
|
697
787
|
throw new Error(`Not implemented ObArType for: ${key}`);
|
|
698
788
|
writeAsciiStringOrClassId(writer, type);
|
|
699
789
|
(0, psdWriter_1.writeInt32)(writer, value.length);
|
|
700
790
|
for (let i = 0; i < value.length; i++) {
|
|
791
|
+
const info = getHidden(value[i], obArInfoKey);
|
|
701
792
|
writeAsciiStringOrClassId(writer, value[i].type); // Hrzn | Vrtc
|
|
702
|
-
(0, psdWriter_1.writeSignature)(writer, 'UnFl');
|
|
703
|
-
(0, psdWriter_1.writeSignature)(writer, '#Pxl');
|
|
793
|
+
(0, psdWriter_1.writeSignature)(writer, (_d = info === null || info === void 0 ? void 0 : info.valueType) !== null && _d !== void 0 ? _d : 'UnFl');
|
|
794
|
+
(0, psdWriter_1.writeSignature)(writer, (_e = info === null || info === void 0 ? void 0 : info.units) !== null && _e !== void 0 ? _e : '#Pxl');
|
|
704
795
|
(0, psdWriter_1.writeInt32)(writer, value[i].values.length);
|
|
705
796
|
for (let j = 0; j < value[i].values.length; j++) {
|
|
706
797
|
(0, psdWriter_1.writeFloat64)(writer, value[i].values[j]);
|
|
@@ -721,85 +812,144 @@ function writeOSType(writer, type, value, key, extType, root) {
|
|
|
721
812
|
throw new Error(`Not implemented descriptor OSType: ${type}`);
|
|
722
813
|
}
|
|
723
814
|
}
|
|
815
|
+
function referenceItemToValue(item) {
|
|
816
|
+
switch (item.type) {
|
|
817
|
+
case 'prop': return item.keyID;
|
|
818
|
+
case 'Clss': return { name: item.name || '', classID: item.classID };
|
|
819
|
+
case 'Enmr': return `${item.typeID}.${item.enumValue}`;
|
|
820
|
+
default: return item.value;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
function referenceItemMatches(item, value) {
|
|
824
|
+
if (!item)
|
|
825
|
+
return false;
|
|
826
|
+
const expected = referenceItemToValue(item);
|
|
827
|
+
if (expected && typeof expected === 'object') {
|
|
828
|
+
return !!value && typeof value === 'object' && value.name === expected.name && value.classID === expected.classID;
|
|
829
|
+
}
|
|
830
|
+
return expected === value;
|
|
831
|
+
}
|
|
832
|
+
// Attaches information about how each item of reference should be written (class IDs, reference types),
|
|
833
|
+
// the public value of the array stays the same (array of strings/numbers/class objects)
|
|
834
|
+
function createDescriptorReference(items) {
|
|
835
|
+
return setHidden(items.map(referenceItemToValue), referenceInfoKey, items);
|
|
836
|
+
}
|
|
724
837
|
function readReferenceStructure(reader) {
|
|
725
838
|
const itemsCount = (0, psdReader_1.readInt32)(reader);
|
|
726
|
-
const
|
|
839
|
+
const infos = [];
|
|
727
840
|
for (let i = 0; i < itemsCount; i++) {
|
|
728
841
|
const type = (0, psdReader_1.readSignature)(reader);
|
|
729
842
|
switch (type) {
|
|
730
843
|
case 'prop': { // Property
|
|
731
|
-
readClassStructure(reader);
|
|
844
|
+
const { name, classID } = readClassStructure(reader);
|
|
732
845
|
const keyID = readAsciiStringOrClassId(reader);
|
|
733
|
-
|
|
846
|
+
infos.push({ type, name, classID, keyID });
|
|
734
847
|
break;
|
|
735
848
|
}
|
|
736
|
-
case 'Clss': // Class
|
|
737
|
-
|
|
849
|
+
case 'Clss': { // Class
|
|
850
|
+
const { name, classID } = readClassStructure(reader);
|
|
851
|
+
infos.push({ type, name, classID });
|
|
738
852
|
break;
|
|
853
|
+
}
|
|
739
854
|
case 'Enmr': { // Enumerated Reference
|
|
740
|
-
readClassStructure(reader);
|
|
855
|
+
const { name, classID } = readClassStructure(reader);
|
|
741
856
|
const typeID = readAsciiStringOrClassId(reader);
|
|
742
|
-
const
|
|
743
|
-
|
|
857
|
+
const enumValue = readAsciiStringOrClassId(reader);
|
|
858
|
+
infos.push({ type, name, classID, typeID, enumValue });
|
|
744
859
|
break;
|
|
745
860
|
}
|
|
746
861
|
case 'rele': { // Offset
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
items.push((0, psdReader_1.readUint32)(reader));
|
|
862
|
+
const { name, classID } = readClassStructure(reader);
|
|
863
|
+
infos.push({ type, name, classID, value: (0, psdReader_1.readUint32)(reader) });
|
|
750
864
|
break;
|
|
751
865
|
}
|
|
752
866
|
case 'Idnt': // Identifier
|
|
753
|
-
items.push((0, psdReader_1.readInt32)(reader));
|
|
754
|
-
break;
|
|
755
867
|
case 'indx': // Index
|
|
756
|
-
|
|
868
|
+
infos.push({ type, value: (0, psdReader_1.readInt32)(reader) });
|
|
757
869
|
break;
|
|
758
870
|
case 'name': { // Name
|
|
759
|
-
readClassStructure(reader);
|
|
760
|
-
|
|
871
|
+
const { name, classID } = readClassStructure(reader);
|
|
872
|
+
infos.push({ type, name, classID, value: (0, psdReader_1.readUnicodeString)(reader) });
|
|
761
873
|
break;
|
|
762
874
|
}
|
|
763
875
|
default:
|
|
764
876
|
throw new Error(`Invalid descriptor reference type: ${type}`);
|
|
765
877
|
}
|
|
766
878
|
}
|
|
767
|
-
return
|
|
879
|
+
return createDescriptorReference(infos);
|
|
880
|
+
}
|
|
881
|
+
function guessReferenceItem(value) {
|
|
882
|
+
if (typeof value === 'string') {
|
|
883
|
+
// enumerated references are read as `${typeID}.${enumValue}` where typeID is a 4 character ID or a string ID
|
|
884
|
+
// (values like 'My.Path' or 'Logo.v2' can't be typeID/enum value, so they are written as name references)
|
|
885
|
+
const match = /^([a-z ]{4}|[a-z]{5,})\.([a-z ]+)$/i.exec(value);
|
|
886
|
+
if (match) {
|
|
887
|
+
return { type: 'Enmr', name: '', classID: match[1], typeID: match[1], enumValue: match[2] };
|
|
888
|
+
}
|
|
889
|
+
else {
|
|
890
|
+
return { type: 'name', name: '', classID: 'Lyr ', value };
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
else if (typeof value === 'number') {
|
|
894
|
+
return { type: 'Idnt', value };
|
|
895
|
+
}
|
|
896
|
+
else if (value && typeof value === 'object' && typeof value.classID === 'string') {
|
|
897
|
+
return { type: 'Clss', name: value.name || '', classID: value.classID };
|
|
898
|
+
}
|
|
899
|
+
else {
|
|
900
|
+
throw new Error(`Invalid descriptor reference value: ${JSON.stringify(value)}`);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
// path selection state (image resource 1088) is a reference to paths, enumerated references there use 'Path' class
|
|
904
|
+
// (name references use 'Lyr ' class, they reference layer of the vector mask)
|
|
905
|
+
function pathSelectionStateToReference(items) {
|
|
906
|
+
const infos = getHidden(items, referenceInfoKey);
|
|
907
|
+
return createDescriptorReference(items.map((value, i) => {
|
|
908
|
+
if (referenceItemMatches(infos === null || infos === void 0 ? void 0 : infos[i], value))
|
|
909
|
+
return infos[i]; // keep information read from the file
|
|
910
|
+
const item = guessReferenceItem(value);
|
|
911
|
+
if (item.type === 'Enmr')
|
|
912
|
+
item.classID = 'Path';
|
|
913
|
+
return item;
|
|
914
|
+
}));
|
|
768
915
|
}
|
|
769
916
|
function writeReferenceStructure(writer, _key, items) {
|
|
917
|
+
if (!Array.isArray(items))
|
|
918
|
+
throw new Error(`Invalid reference value: ${JSON.stringify(items)}, key: ${_key}`);
|
|
919
|
+
const infos = getHidden(items, referenceInfoKey);
|
|
770
920
|
(0, psdWriter_1.writeInt32)(writer, items.length);
|
|
771
921
|
for (let i = 0; i < items.length; i++) {
|
|
772
922
|
const value = items[i];
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
(0, psdWriter_1.writeSignature)(writer, type);
|
|
783
|
-
switch (type) {
|
|
784
|
-
// case 'prop': // Property
|
|
785
|
-
// case 'Clss': // Class
|
|
786
|
-
case 'Enmr': { // Enumerated Reference
|
|
787
|
-
const [typeID, enumValue] = value.split('.');
|
|
788
|
-
writeClassStructure(writer, '\0', typeID);
|
|
789
|
-
writeAsciiStringOrClassId(writer, typeID);
|
|
790
|
-
writeAsciiStringOrClassId(writer, enumValue);
|
|
923
|
+
const recorded = infos === null || infos === void 0 ? void 0 : infos[i];
|
|
924
|
+
const item = referenceItemMatches(recorded, value) ? recorded : guessReferenceItem(value);
|
|
925
|
+
(0, psdWriter_1.writeSignature)(writer, item.type);
|
|
926
|
+
switch (item.type) {
|
|
927
|
+
case 'prop': // Property
|
|
928
|
+
writeClassStructure(writer, item.name || '', item.classID);
|
|
929
|
+
writeAsciiStringOrClassId(writer, item.keyID);
|
|
791
930
|
break;
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
(
|
|
931
|
+
case 'Clss': // Class
|
|
932
|
+
writeClassStructure(writer, item.name || '', item.classID);
|
|
933
|
+
break;
|
|
934
|
+
case 'Enmr': // Enumerated Reference
|
|
935
|
+
writeClassStructure(writer, item.name || '', item.classID);
|
|
936
|
+
writeAsciiStringOrClassId(writer, item.typeID);
|
|
937
|
+
writeAsciiStringOrClassId(writer, item.enumValue);
|
|
938
|
+
break;
|
|
939
|
+
case 'rele': // Offset
|
|
940
|
+
writeClassStructure(writer, item.name || '', item.classID);
|
|
941
|
+
(0, psdWriter_1.writeUint32)(writer, item.value);
|
|
942
|
+
break;
|
|
943
|
+
case 'Idnt': // Identifier
|
|
944
|
+
case 'indx': // Index
|
|
945
|
+
(0, psdWriter_1.writeInt32)(writer, item.value);
|
|
946
|
+
break;
|
|
947
|
+
case 'name': // Name
|
|
948
|
+
writeClassStructure(writer, item.name || '', item.classID);
|
|
949
|
+
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, `${item.value}`);
|
|
799
950
|
break;
|
|
800
|
-
}
|
|
801
951
|
default:
|
|
802
|
-
throw new Error(`Invalid descriptor reference type: ${type}`);
|
|
952
|
+
throw new Error(`Invalid descriptor reference type: ${item.type}`);
|
|
803
953
|
}
|
|
804
954
|
}
|
|
805
955
|
return items;
|
|
@@ -810,7 +960,7 @@ function readClassStructure(reader) {
|
|
|
810
960
|
return { name, classID };
|
|
811
961
|
}
|
|
812
962
|
function writeClassStructure(writer, name, classID) {
|
|
813
|
-
(0, psdWriter_1.
|
|
963
|
+
(0, psdWriter_1.writeUnicodeStringWithPadding)(writer, name);
|
|
814
964
|
writeAsciiStringOrClassId(writer, classID);
|
|
815
965
|
}
|
|
816
966
|
function readVersionAndDescriptor(reader, includeClass = false) {
|
|
@@ -942,9 +1092,11 @@ function serializeEffects(e, log, multi) {
|
|
|
942
1092
|
info.numModifyingFX = 0;
|
|
943
1093
|
for (const key of Object.keys(e)) {
|
|
944
1094
|
const value = e[key];
|
|
1095
|
+
if (value == null || typeof value !== 'object')
|
|
1096
|
+
continue;
|
|
945
1097
|
if (Array.isArray(value)) {
|
|
946
1098
|
for (const effect of value) {
|
|
947
|
-
if (effect.enabled)
|
|
1099
|
+
if (effect === null || effect === void 0 ? void 0 : effect.enabled)
|
|
948
1100
|
info.numModifyingFX++;
|
|
949
1101
|
}
|
|
950
1102
|
}
|
|
@@ -1093,7 +1245,7 @@ function serializeTrackList(tracks) {
|
|
|
1093
1245
|
const t = tracks[i];
|
|
1094
1246
|
trackList.push(Object.assign(Object.assign({ trackID: exports.stdTrackID.encode(t.type), Vrsn: 1, enab: !!t.enabled, Effc: !!t.effectParams }, (t.effectParams ? {
|
|
1095
1247
|
effectParams: {
|
|
1096
|
-
keyList: serializeKeyList(t.keys),
|
|
1248
|
+
keyList: serializeKeyList(t.effectParams.keys),
|
|
1097
1249
|
fillCanvas: t.effectParams.fillCanvas,
|
|
1098
1250
|
zoomOrigin: t.effectParams.zoomOrigin,
|
|
1099
1251
|
}
|
|
@@ -1336,7 +1488,7 @@ function serializeEffectObject(obj, objName, reportErrors) {
|
|
|
1336
1488
|
result.sdwO = unitsPercent(val);
|
|
1337
1489
|
break;
|
|
1338
1490
|
case 'angle':
|
|
1339
|
-
if (objName === 'gradientOverlay' || objName === '
|
|
1491
|
+
if (objName === 'gradientOverlay' || objName === 'patternOverlay') {
|
|
1340
1492
|
result.Angl = unitsAngle(val);
|
|
1341
1493
|
}
|
|
1342
1494
|
else {
|
|
@@ -1408,7 +1560,8 @@ function serializeEffectObject(obj, objName, reportErrors) {
|
|
|
1408
1560
|
}
|
|
1409
1561
|
function parseGradient(grad) {
|
|
1410
1562
|
if (grad.GrdF === 'GrdF.CstS') {
|
|
1411
|
-
|
|
1563
|
+
// stop locations are always in 0..4096 range, independent of smoothness (Intr)
|
|
1564
|
+
const samples = 4096;
|
|
1412
1565
|
return {
|
|
1413
1566
|
type: 'solid',
|
|
1414
1567
|
name: grad['Nm '],
|
|
@@ -1442,11 +1595,12 @@ function parseGradient(grad) {
|
|
|
1442
1595
|
function serializeGradient(grad) {
|
|
1443
1596
|
var _a, _b;
|
|
1444
1597
|
if (grad.type === 'solid') {
|
|
1445
|
-
|
|
1598
|
+
// stop locations are always in 0..4096 range, independent of smoothness (Intr)
|
|
1599
|
+
const samples = 4096;
|
|
1446
1600
|
return {
|
|
1447
1601
|
'Nm ': grad.name || '',
|
|
1448
1602
|
GrdF: 'GrdF.CstS',
|
|
1449
|
-
Intr:
|
|
1603
|
+
Intr: Math.round(((_a = grad.smoothness) !== null && _a !== void 0 ? _a : 1) * 4096),
|
|
1450
1604
|
Clrs: grad.colorStops.map(s => {
|
|
1451
1605
|
var _a;
|
|
1452
1606
|
return ({
|
|
@@ -1475,8 +1629,8 @@ function serializeGradient(grad) {
|
|
|
1475
1629
|
ClrS: exports.ClrS.encode(grad.colorModel),
|
|
1476
1630
|
RndS: grad.randomSeed || 0,
|
|
1477
1631
|
Smth: Math.round(((_b = grad.roughness) !== null && _b !== void 0 ? _b : 1) * 4096),
|
|
1478
|
-
'Mnm ': (grad.min || [0, 0, 0, 0]).map(x => x * 100),
|
|
1479
|
-
'Mxm ': (grad.max || [1, 1, 1, 1]).map(x => x * 100),
|
|
1632
|
+
'Mnm ': (grad.min || [0, 0, 0, 0]).map(x => Math.round(x * 100)),
|
|
1633
|
+
'Mxm ': (grad.max || [1, 1, 1, 1]).map(x => Math.round(x * 100)),
|
|
1480
1634
|
};
|
|
1481
1635
|
}
|
|
1482
1636
|
}
|
|
@@ -1576,21 +1730,65 @@ function serializeVectorContent(content) {
|
|
|
1576
1730
|
return { key: 'GdFl', descriptor: serializeGradientContent(content) };
|
|
1577
1731
|
}
|
|
1578
1732
|
}
|
|
1733
|
+
// Descriptor color values: HSB saturation/brightness 0..100, CMYK 0..100, Gray 0..100, Lab L 0..100, a/b -128..127
|
|
1734
|
+
// Color values (see psd.ts): HSB 0..1, CMYK 0..255, Gray 0..255, Lab L 0..1, a/b -1..1 (same as readColor/writeColor)
|
|
1735
|
+
const colorSourceKey = typeof Symbol !== 'undefined' ? Symbol('agPsdColorSource') : '__agPsdColorSource';
|
|
1736
|
+
const colorConversions = {
|
|
1737
|
+
// key: [descriptor -> color, color -> descriptor]
|
|
1738
|
+
Strt: [x => x / 100, x => x * 100],
|
|
1739
|
+
Brgh: [x => x / 100, x => x * 100],
|
|
1740
|
+
'Cyn ': [x => x * 255 / 100, x => x * 100 / 255],
|
|
1741
|
+
Mgnt: [x => x * 255 / 100, x => x * 100 / 255],
|
|
1742
|
+
'Ylw ': [x => x * 255 / 100, x => x * 100 / 255],
|
|
1743
|
+
Blck: [x => x * 255 / 100, x => x * 100 / 255],
|
|
1744
|
+
'Gry ': [x => x * 255 / 100, x => x * 100 / 255],
|
|
1745
|
+
Lmnc: [x => x / 100, x => x * 100],
|
|
1746
|
+
'A ': [helpers_1.normalizeLabAB, helpers_1.denormalizeLabAB],
|
|
1747
|
+
'B ': [helpers_1.normalizeLabAB, helpers_1.denormalizeLabAB],
|
|
1748
|
+
};
|
|
1749
|
+
function colorToDescriptorValue(key, value) {
|
|
1750
|
+
const conversion = colorConversions[key];
|
|
1751
|
+
if (!conversion)
|
|
1752
|
+
return value;
|
|
1753
|
+
const [from, to] = conversion;
|
|
1754
|
+
const result = to(value);
|
|
1755
|
+
if (!isFinite(result))
|
|
1756
|
+
return result;
|
|
1757
|
+
// prefer shortest number that converts back to the same value (avoids values like 30.200000000000003)
|
|
1758
|
+
for (let precision = 1; precision < 17; precision++) {
|
|
1759
|
+
const candidate = +result.toPrecision(precision);
|
|
1760
|
+
if (from(candidate) === value)
|
|
1761
|
+
return candidate;
|
|
1762
|
+
}
|
|
1763
|
+
return result;
|
|
1764
|
+
}
|
|
1765
|
+
function shallowEqual(a, b) {
|
|
1766
|
+
const keys = Object.keys(a);
|
|
1767
|
+
if (keys.length !== Object.keys(b).length)
|
|
1768
|
+
return false;
|
|
1769
|
+
return keys.every(key => a[key] === b[key]);
|
|
1770
|
+
}
|
|
1579
1771
|
function parseColor(color) {
|
|
1772
|
+
let result;
|
|
1580
1773
|
if ('H ' in color) {
|
|
1581
|
-
|
|
1774
|
+
result = { h: parsePercentOrAngle(color['H ']), s: color.Strt / 100, b: color.Brgh / 100 };
|
|
1582
1775
|
}
|
|
1583
1776
|
else if ('Rd ' in color) {
|
|
1584
1777
|
return { r: color['Rd '], g: color['Grn '], b: color['Bl '] };
|
|
1585
1778
|
}
|
|
1586
1779
|
else if ('Cyn ' in color) {
|
|
1587
|
-
|
|
1780
|
+
result = {
|
|
1781
|
+
c: color['Cyn '] * 255 / 100,
|
|
1782
|
+
m: color.Mgnt * 255 / 100,
|
|
1783
|
+
y: color['Ylw '] * 255 / 100,
|
|
1784
|
+
k: color.Blck * 255 / 100,
|
|
1785
|
+
};
|
|
1588
1786
|
}
|
|
1589
1787
|
else if ('Gry ' in color) {
|
|
1590
|
-
|
|
1788
|
+
result = { k: color['Gry '] * 255 / 100 };
|
|
1591
1789
|
}
|
|
1592
1790
|
else if ('Lmnc' in color) {
|
|
1593
|
-
|
|
1791
|
+
result = { l: color.Lmnc / 100, a: (0, helpers_1.normalizeLabAB)(color['A ']), b: (0, helpers_1.normalizeLabAB)(color['B ']) };
|
|
1594
1792
|
}
|
|
1595
1793
|
else if ('redFloat' in color) {
|
|
1596
1794
|
return { fr: color.redFloat, fg: color.greenFloat, fb: color.blueFloat };
|
|
@@ -1598,8 +1796,10 @@ function parseColor(color) {
|
|
|
1598
1796
|
else {
|
|
1599
1797
|
throw new Error('Unsupported color descriptor');
|
|
1600
1798
|
}
|
|
1799
|
+
// remember original descriptor values, so unmodified colors can be written back without conversion errors
|
|
1800
|
+
return setHidden(result, colorSourceKey, { color: Object.assign({}, result), descriptor: color });
|
|
1601
1801
|
}
|
|
1602
|
-
function
|
|
1802
|
+
function serializeColorValues(color) {
|
|
1603
1803
|
if (!color) {
|
|
1604
1804
|
return { _name: '', _classID: 'RGBC', 'Rd ': 0, 'Grn ': 0, 'Bl ': 0 };
|
|
1605
1805
|
}
|
|
@@ -1610,21 +1810,50 @@ function serializeColor(color) {
|
|
|
1610
1810
|
return { _name: '', _classID: 'RGBC', redFloat: color.fr, greenFloat: color.fg, blueFloat: color.fb };
|
|
1611
1811
|
}
|
|
1612
1812
|
else if ('h' in color) {
|
|
1613
|
-
return {
|
|
1813
|
+
return {
|
|
1814
|
+
_name: '', _classID: 'HSBC',
|
|
1815
|
+
'H ': unitsAngle((color.h || 0) * 360),
|
|
1816
|
+
Strt: colorToDescriptorValue('Strt', color.s || 0),
|
|
1817
|
+
Brgh: colorToDescriptorValue('Brgh', color.b || 0),
|
|
1818
|
+
};
|
|
1614
1819
|
}
|
|
1615
1820
|
else if ('c' in color) {
|
|
1616
|
-
return {
|
|
1821
|
+
return {
|
|
1822
|
+
_name: '', _classID: 'CMYC',
|
|
1823
|
+
'Cyn ': colorToDescriptorValue('Cyn ', color.c || 0),
|
|
1824
|
+
Mgnt: colorToDescriptorValue('Mgnt', color.m || 0),
|
|
1825
|
+
'Ylw ': colorToDescriptorValue('Ylw ', color.y || 0),
|
|
1826
|
+
Blck: colorToDescriptorValue('Blck', color.k || 0),
|
|
1827
|
+
};
|
|
1617
1828
|
}
|
|
1618
1829
|
else if ('l' in color) {
|
|
1619
|
-
return {
|
|
1830
|
+
return {
|
|
1831
|
+
_name: '', _classID: 'LbCl',
|
|
1832
|
+
Lmnc: colorToDescriptorValue('Lmnc', color.l || 0),
|
|
1833
|
+
'A ': colorToDescriptorValue('A ', color.a || 0),
|
|
1834
|
+
'B ': colorToDescriptorValue('B ', color.b || 0),
|
|
1835
|
+
};
|
|
1620
1836
|
}
|
|
1621
1837
|
else if ('k' in color) {
|
|
1622
|
-
return { _name: '', _classID: '
|
|
1838
|
+
return { _name: '', _classID: 'Grsc', 'Gry ': colorToDescriptorValue('Gry ', color.k || 0) };
|
|
1623
1839
|
}
|
|
1624
1840
|
else {
|
|
1625
1841
|
throw new Error('Invalid color value');
|
|
1626
1842
|
}
|
|
1627
1843
|
}
|
|
1844
|
+
function serializeColor(color) {
|
|
1845
|
+
const result = serializeColorValues(color);
|
|
1846
|
+
const source = getHidden(color, colorSourceKey);
|
|
1847
|
+
if (source && shallowEqual(source.color, color)) {
|
|
1848
|
+
// color was not modified since it was read, use exact original values
|
|
1849
|
+
for (const key of Object.keys(result)) {
|
|
1850
|
+
if (colorConversions[key] && typeof source.descriptor[key] === 'number') {
|
|
1851
|
+
result[key] = source.descriptor[key];
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
return result;
|
|
1856
|
+
}
|
|
1628
1857
|
function parseAngle(x) {
|
|
1629
1858
|
if (x === undefined)
|
|
1630
1859
|
return 0;
|