ag-psd 16.0.0 → 17.0.1
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/CHANGELOG.md +9 -0
- package/README.md +1 -0
- package/dist/additionalInfo.js +933 -247
- package/dist/additionalInfo.js.map +1 -1
- package/dist/bundle.js +1299 -325
- package/dist/descriptor.d.ts +140 -1
- package/dist/descriptor.js +297 -37
- package/dist/descriptor.js.map +1 -1
- package/dist/imageResources.js +13 -21
- package/dist/imageResources.js.map +1 -1
- package/dist/psd.d.ts +445 -62
- package/dist/psdReader.d.ts +2 -0
- package/dist/psdReader.js +30 -13
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +4 -0
- package/dist/psdWriter.js +26 -7
- package/dist/psdWriter.js.map +1 -1
- package/dist-es/additionalInfo.js +934 -248
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/descriptor.d.ts +140 -1
- package/dist-es/descriptor.js +293 -38
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/imageResources.js +14 -22
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/psd.d.ts +445 -62
- package/dist-es/psdReader.d.ts +2 -0
- package/dist-es/psdReader.js +27 -12
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +4 -0
- package/dist-es/psdWriter.js +22 -7
- package/dist-es/psdWriter.js.map +1 -1
- package/package.json +1 -1
- package/src/additionalInfo.ts +2014 -289
- package/src/descriptor.ts +329 -39
- package/src/imageResources.ts +18 -23
- package/src/psd.ts +477 -46
- package/src/psdReader.ts +26 -7
- package/src/psdWriter.ts +25 -8
package/src/descriptor.ts
CHANGED
|
@@ -7,15 +7,16 @@ import {
|
|
|
7
7
|
LayerEffectSatin, LayerEffectShadow, LayerEffectsInfo, LayerEffectSolidFill,
|
|
8
8
|
LayerEffectsOuterGlow, LayerEffectStroke, LineAlignment, LineCapType, LineJoinType,
|
|
9
9
|
Orientation, TextGridding, TimelineKey, TimelineKeyInterpolation, TimelineTrack, TimelineTrackType,
|
|
10
|
-
Units, UnitsValue, VectorContent, WarpStyle
|
|
10
|
+
Units, UnitsBounds, UnitsValue, VectorContent, WarpStyle
|
|
11
11
|
} from './psd';
|
|
12
12
|
import {
|
|
13
13
|
PsdReader, readSignature, readUnicodeString, readUint32, readUint8, readFloat64,
|
|
14
|
-
readBytes, readAsciiString, readInt32, readFloat32, readInt32LE,
|
|
14
|
+
readBytes, readAsciiString, readInt32, readFloat32, readInt32LE, readUnicodeStringWithLengthLE
|
|
15
15
|
} from './psdReader';
|
|
16
16
|
import {
|
|
17
17
|
PsdWriter, writeSignature, writeBytes, writeUint32, writeFloat64, writeUint8,
|
|
18
|
-
writeUnicodeStringWithPadding, writeInt32, writeFloat32, writeUnicodeString
|
|
18
|
+
writeUnicodeStringWithPadding, writeInt32, writeFloat32, writeUnicodeString, writeInt32LE,
|
|
19
|
+
writeUnicodeStringWithoutLengthLE
|
|
19
20
|
} from './psdWriter';
|
|
20
21
|
|
|
21
22
|
interface Dict { [key: string]: string; }
|
|
@@ -118,6 +119,7 @@ const fieldToExtType: ExtTypeDict = {
|
|
|
118
119
|
sheetStyle: nullType,
|
|
119
120
|
translation: nullType,
|
|
120
121
|
Skew: nullType,
|
|
122
|
+
boundingBox: makeType('', 'boundingBox'),
|
|
121
123
|
'Lnk ': makeType('', 'ExternalFileLink'),
|
|
122
124
|
frameReader: makeType('', 'FrameReader'),
|
|
123
125
|
effectParams: makeType('', 'motionTrackEffectParams'),
|
|
@@ -125,11 +127,15 @@ const fieldToExtType: ExtTypeDict = {
|
|
|
125
127
|
Anch: makeType('', 'Pnt '),
|
|
126
128
|
'Fwd ': makeType('', 'Pnt '),
|
|
127
129
|
'Bwd ': makeType('', 'Pnt '),
|
|
130
|
+
FlrC: makeType('', 'Pnt '),
|
|
128
131
|
meshBoundaryPath: makeType('', 'pathClass'),
|
|
129
132
|
filterFX: makeType('', 'filterFXStyle'),
|
|
130
133
|
Fltr: makeType('', 'rigidTransform'),
|
|
131
134
|
FrgC: makeType('', 'RGBC'),
|
|
132
135
|
BckC: makeType('', 'RGBC'),
|
|
136
|
+
sdwM: makeType('Parameters', 'adaptCorrectTones'),
|
|
137
|
+
hglM: makeType('Parameters', 'adaptCorrectTones'),
|
|
138
|
+
customShape: makeType('', 'customShape'),
|
|
133
139
|
};
|
|
134
140
|
|
|
135
141
|
const fieldToArrayExtType: ExtTypeDict = {
|
|
@@ -159,6 +165,8 @@ const fieldToArrayExtType: ExtTypeDict = {
|
|
|
159
165
|
pathComponents: makeType('', 'PaCm'),
|
|
160
166
|
filterFXList: makeType('', 'filterFX'),
|
|
161
167
|
puppetShapeList: makeType('', 'puppetShape'),
|
|
168
|
+
channelDenoise: makeType('', 'channelDenoiseParams'),
|
|
169
|
+
ShrP: makeType('', 'Pnt '),
|
|
162
170
|
};
|
|
163
171
|
|
|
164
172
|
const typeToField: { [key: string]: string[]; } = {
|
|
@@ -166,9 +174,12 @@ const typeToField: { [key: string]: string[]; } = {
|
|
|
166
174
|
'Txt ', 'printerName', 'Nm ', 'Idnt', 'blackAndWhitePresetFileName', 'LUT3DFileName',
|
|
167
175
|
'presetFileName', 'curvesPresetFileName', 'mixerPresetFileName', 'placed', 'description', 'reason',
|
|
168
176
|
'artboardPresetName', 'json', 'clipID', 'relPath', 'fullPath', 'mediaDescriptor', 'Msge',
|
|
169
|
-
'altTag', 'url', 'cellText',
|
|
177
|
+
'altTag', 'url', 'cellText', 'preset', 'KnNm', 'FPth',
|
|
178
|
+
],
|
|
179
|
+
'tdta': [
|
|
180
|
+
'EngineData', 'LUT3DFileData', 'indexArray', 'originalVertexArray', 'deformedVertexArray',
|
|
181
|
+
'LqMe',
|
|
170
182
|
],
|
|
171
|
-
'tdta': ['EngineData', 'LUT3DFileData', 'indexArray', 'originalVertexArray', 'deformedVertexArray'],
|
|
172
183
|
'long': [
|
|
173
184
|
'TextIndex', 'RndS', 'Mdpn', 'Smth', 'Lctn', 'strokeStyleVersion', 'LaID', 'Vrsn', 'Cnt ',
|
|
174
185
|
'Brgh', 'Cntr', 'means', 'vibrance', 'Strt', 'bwPresetKind', 'presetKind', 'comp', 'compID', 'originalCompID',
|
|
@@ -179,16 +190,19 @@ const typeToField: { [key: string]: string[]; } = {
|
|
|
179
190
|
'numBefore', 'numAfter', 'Spcn', 'minOpacity', 'maxOpacity', 'BlnM', 'sheetID', 'gblA', 'globalAltitude',
|
|
180
191
|
'descVersion', 'frameReaderType', 'LyrI', 'zoomOrigin', 'fontSize', 'Rds ', 'sliceID',
|
|
181
192
|
'topOutset', 'leftOutset', 'bottomOutset', 'rightOutset', 'filterID', 'meshQuality',
|
|
182
|
-
'meshExpansion', 'meshRigidity', 'VrsM', 'VrsN',
|
|
193
|
+
'meshExpansion', 'meshRigidity', 'VrsM', 'VrsN', 'NmbG', 'WLMn', 'WLMx', 'AmMn', 'AmMx', 'SclH', 'SclV',
|
|
194
|
+
'Lvl ', 'TlNm', 'TlOf', 'FlRs', 'Thsh', 'ShrS', 'ShrE', 'FlRs', 'Vrnc', 'Strg', 'ExtS', 'ExtD',
|
|
195
|
+
'HrzS', 'VrtS', 'NmbR', 'EdgF', 'Ang1', 'Ang2', 'Ang3', 'Ang4',
|
|
183
196
|
],
|
|
184
197
|
'enum': [
|
|
185
|
-
'textGridding', 'Ornt', 'warpStyle', 'warpRotate', 'Inte', 'Bltn', 'ClrS',
|
|
186
|
-
'
|
|
198
|
+
'textGridding', 'Ornt', 'warpStyle', 'warpRotate', 'Inte', 'Bltn', 'ClrS', 'BlrQ',
|
|
199
|
+
'bvlT', 'bvlS', 'bvlD', 'Md ', 'glwS', 'GrdF', 'GlwT', 'RplS', 'BlrM', 'SmBM',
|
|
187
200
|
'strokeStyleLineCapType', 'strokeStyleLineJoinType', 'strokeStyleLineAlignment',
|
|
188
201
|
'strokeStyleBlendMode', 'PntT', 'Styl', 'lookupType', 'LUTFormat', 'dataOrder',
|
|
189
202
|
'tableOrder', 'enableCompCore', 'enableCompCoreGPU', 'compCoreSupport', 'compCoreGPUSupport', 'Engn',
|
|
190
203
|
'enableCompCoreThreads', 'gs99', 'FrDs', 'trackID', 'animInterpStyle', 'horzAlign',
|
|
191
|
-
'vertAlign', 'bgColorType', 'shapeOperation',
|
|
204
|
+
'vertAlign', 'bgColorType', 'shapeOperation', 'UndA', 'Wvtp', 'Drct', 'WndM', 'Edg ', 'FlCl', 'IntE',
|
|
205
|
+
'IntC', 'Cnvr', 'Fl ', 'Dstr', 'MztT', 'Lns ', 'ExtT', 'DspM', 'ExtR', 'ZZTy', 'SphM', 'SmBQ',
|
|
192
206
|
],
|
|
193
207
|
'bool': [
|
|
194
208
|
'PstS', 'printSixteenBit', 'masterFXSwitch', 'enab', 'uglg', 'antialiasGloss',
|
|
@@ -200,7 +214,8 @@ const typeToField: { [key: string]: string[]; } = {
|
|
|
200
214
|
'present', 'showInDialog', 'overprint', 'sheetDisclosed', 'lightsDisclosed', 'meshesDisclosed',
|
|
201
215
|
'materialsDisclosed', 'hasMotion', 'muted', 'Effc', 'selected', 'autoScope', 'fillCanvas',
|
|
202
216
|
'cellTextIsHTML', 'Smoo', 'Clsp', 'validAtPosition', 'rigidType', 'hasoptions', 'filterMaskEnable',
|
|
203
|
-
'filterMaskLinked', 'filterMaskExtendWithWhite',
|
|
217
|
+
'filterMaskLinked', 'filterMaskExtendWithWhite', 'removeJPEGArtifact', 'Mnch', 'ExtF', 'ExtM',
|
|
218
|
+
'moreAccurate', 'GpuY', 'LIWy',
|
|
204
219
|
],
|
|
205
220
|
'doub': [
|
|
206
221
|
'warpValue', 'warpPerspective', 'warpPerspectiveOther', 'Intr', 'Wdth', 'Hght',
|
|
@@ -210,10 +225,10 @@ const typeToField: { [key: string]: string[]; } = {
|
|
|
210
225
|
'PuX0', 'PuX1', 'PuX2', 'PuX3', 'PuY0', 'PuY1', 'PuY2', 'PuY3'
|
|
211
226
|
],
|
|
212
227
|
'UntF': [
|
|
213
|
-
'
|
|
228
|
+
'sdwO', 'hglO', 'lagl', 'Lald', 'srgR', 'blur', 'Sftn', 'Opct', 'Dstn', 'Angl',
|
|
214
229
|
'Ckmt', 'Nose', 'Inpr', 'ShdN', 'strokeStyleLineWidth', 'strokeStyleLineDashOffset',
|
|
215
230
|
'strokeStyleOpacity', 'H ', 'Top ', 'Left', 'Btom', 'Rght', 'Rslt',
|
|
216
|
-
'topRight', 'topLeft', 'bottomLeft', 'bottomRight',
|
|
231
|
+
'topRight', 'topLeft', 'bottomLeft', 'bottomRight', 'ClNs', 'Shrp',
|
|
217
232
|
],
|
|
218
233
|
'VlLs': [
|
|
219
234
|
'Crv ', 'Clrs', 'Mnm ', 'Mxm ', 'Trns', 'pathList', 'strokeStyleLineDashSet', 'FrLs', 'slices',
|
|
@@ -221,10 +236,12 @@ const typeToField: { [key: string]: string[]; } = {
|
|
|
221
236
|
'solidFillMulti', 'frameFXMulti', 'innerShadowMulti', 'dropShadowMulti', 'FrIn', 'FSts', 'FsFr',
|
|
222
237
|
'sheetTimelineOptions', 'audioClipList', 'trackList', 'globalTrackList', 'keyList', 'audioClipList',
|
|
223
238
|
'warpValues', 'selectedPin', 'Pts ', 'SbpL', 'pathComponents', 'pinOffsets', 'posFinalPins',
|
|
224
|
-
'pinVertexIndices', 'PinP', 'PnRt', 'PnOv', 'PnDp', 'filterFXList', 'puppetShapeList',
|
|
239
|
+
'pinVertexIndices', 'PinP', 'PnRt', 'PnOv', 'PnDp', 'filterFXList', 'puppetShapeList', 'ShrP',
|
|
240
|
+
'channelDenoise', 'Mtrx',
|
|
225
241
|
],
|
|
226
242
|
'ObAr': ['meshPoints', 'quiltSliceX', 'quiltSliceY'],
|
|
227
|
-
'obj ': ['null'],
|
|
243
|
+
'obj ': ['null', 'Chnl'],
|
|
244
|
+
'Pth ': ['DspF'],
|
|
228
245
|
};
|
|
229
246
|
|
|
230
247
|
const channels = [
|
|
@@ -265,6 +282,9 @@ const fieldToArrayType: Dict = {
|
|
|
265
282
|
PnDp: 'doub',
|
|
266
283
|
filterFXList: 'Objc',
|
|
267
284
|
puppetShapeList: 'Objc',
|
|
285
|
+
ShrP: 'Objc',
|
|
286
|
+
channelDenoise: 'Objc',
|
|
287
|
+
Mtrx: 'long',
|
|
268
288
|
};
|
|
269
289
|
|
|
270
290
|
const fieldToType: Dict = {};
|
|
@@ -331,11 +351,13 @@ function writeAsciiStringOrClassId(writer: PsdWriter, value: string) {
|
|
|
331
351
|
}
|
|
332
352
|
|
|
333
353
|
export function readDescriptorStructure(reader: PsdReader) {
|
|
334
|
-
const
|
|
335
|
-
// object.__struct =
|
|
354
|
+
// const struct =
|
|
336
355
|
readClassStructure(reader);
|
|
356
|
+
// const object: any = { _name: struct.name, _classID: struct.classID };
|
|
357
|
+
const object: any = {};
|
|
358
|
+
// console.log('>> ', struct);
|
|
337
359
|
const itemsCount = readUint32(reader);
|
|
338
|
-
|
|
360
|
+
|
|
339
361
|
for (let i = 0; i < itemsCount; i++) {
|
|
340
362
|
const key = readAsciiStringOrClassId(reader);
|
|
341
363
|
const type = readSignature(reader);
|
|
@@ -356,25 +378,59 @@ export function writeDescriptorStructure(writer: PsdWriter, name: string, classI
|
|
|
356
378
|
writeAsciiStringOrClassId(writer, classId);
|
|
357
379
|
|
|
358
380
|
const keys = Object.keys(value);
|
|
359
|
-
|
|
381
|
+
let keyCount = keys.length;
|
|
382
|
+
if ('_name' in value) keyCount--;
|
|
383
|
+
if ('_classID' in value) keyCount--;
|
|
384
|
+
|
|
385
|
+
writeUint32(writer, keyCount);
|
|
360
386
|
|
|
361
387
|
for (const key of keys) {
|
|
388
|
+
if (key === '_name' || key === '_classID') continue;
|
|
389
|
+
|
|
362
390
|
let type = getTypeByKey(key, value[key], root, value);
|
|
363
391
|
let extType = fieldToExtType[key];
|
|
364
392
|
|
|
365
|
-
if (key === '
|
|
393
|
+
if (key === 'bounds' && root === 'text') {
|
|
394
|
+
extType = makeType('', 'bounds');
|
|
395
|
+
} else if (key === 'origin') {
|
|
366
396
|
type = root === 'slices' ? 'enum' : 'Objc';
|
|
397
|
+
} else if ((key === 'Cyn ' || key === 'Mgnt' || key === 'Ylw ' || key === 'Blck') && value._classID === 'CMYC') {
|
|
398
|
+
type = 'doub';
|
|
399
|
+
} else if (/^PN[a-z][a-z]$/.test(key)) {
|
|
400
|
+
type = 'TEXT';
|
|
401
|
+
} else if (/^PT[a-z][a-z]$/.test(key)) {
|
|
402
|
+
type = 'long';
|
|
403
|
+
} else if (/^PF[a-z][a-z]$/.test(key)) {
|
|
404
|
+
type = 'doub';
|
|
405
|
+
} else if (key === 'ClSz' || key === 'Rds ' || key === 'Amnt') {
|
|
406
|
+
type = typeof value[key] === 'number' ? 'long' : 'UntF';
|
|
407
|
+
} else if ((key === 'sdwM' || key === 'hglM') && typeof value[key] === 'string') {
|
|
408
|
+
type = 'enum';
|
|
409
|
+
} else if (key === 'blur' && typeof value[key] === 'string') {
|
|
410
|
+
type = 'enum';
|
|
411
|
+
} else if (key === 'Angl' && typeof value[key] === 'number') {
|
|
412
|
+
type = 'doub'; // ???
|
|
367
413
|
} else if (key === 'bounds' && root === 'slices') {
|
|
368
414
|
type = 'Objc';
|
|
369
415
|
extType = makeType('', 'Rct1');
|
|
370
|
-
} else if (key === 'Scl '
|
|
371
|
-
|
|
372
|
-
|
|
416
|
+
} else if (key === 'Scl ') {
|
|
417
|
+
if (typeof value[key] === 'object' && 'Hrzn' in value[key]) {
|
|
418
|
+
type = 'Objc';
|
|
419
|
+
extType = nullType;
|
|
420
|
+
} else if (typeof value[key] === 'number') {
|
|
421
|
+
type = 'long';
|
|
422
|
+
} else {
|
|
423
|
+
type = 'UntF';
|
|
424
|
+
}
|
|
373
425
|
} else if (key === 'audioClipGroupList' && keys.length === 1) {
|
|
374
426
|
type = 'VlLs';
|
|
375
427
|
} else if ((key === 'Strt' || key === 'Brgh') && 'H ' in value) {
|
|
376
428
|
type = 'doub';
|
|
377
|
-
} else if (key === '
|
|
429
|
+
} else if (key === 'Wdth' && typeof value[key] === 'object') {
|
|
430
|
+
type = 'UntF';
|
|
431
|
+
} else if (key === 'Ofst' && typeof value[key] === 'number') {
|
|
432
|
+
type = 'long';
|
|
433
|
+
} else if (key === 'Strt' && typeof value[key] === 'object') {
|
|
378
434
|
type = 'Objc';
|
|
379
435
|
extType = nullType;
|
|
380
436
|
} else if (channels.indexOf(key) !== -1) {
|
|
@@ -491,11 +547,11 @@ function readOSType(reader: PsdReader, type: string) {
|
|
|
491
547
|
return items;
|
|
492
548
|
}
|
|
493
549
|
case 'Pth ': { // File path
|
|
494
|
-
/*const length =*/ readInt32(reader);
|
|
550
|
+
/*const length =*/ readInt32(reader); // total size of all fields below
|
|
495
551
|
const sig = readSignature(reader);
|
|
496
|
-
/*const pathSize =*/ readInt32LE(reader);
|
|
552
|
+
/*const pathSize =*/ readInt32LE(reader); // the same as length
|
|
497
553
|
const charsCount = readInt32LE(reader);
|
|
498
|
-
const path =
|
|
554
|
+
const path = readUnicodeStringWithLengthLE(reader, charsCount);
|
|
499
555
|
return { sig, path };
|
|
500
556
|
}
|
|
501
557
|
default:
|
|
@@ -515,11 +571,16 @@ function writeOSType(writer: PsdWriter, type: string, value: any, key: string, e
|
|
|
515
571
|
writeReferenceStructure(writer, key, value);
|
|
516
572
|
break;
|
|
517
573
|
case 'Objc': // Descriptor
|
|
518
|
-
case 'GlbO': // GlobalObject same as Descriptor
|
|
574
|
+
case 'GlbO': { // GlobalObject same as Descriptor
|
|
575
|
+
if (typeof value !== 'object') throw new Error(`Invalid struct value: ${JSON.stringify(value)}, key: ${key}`);
|
|
519
576
|
if (!extType) throw new Error(`Missing ext type for: '${key}' (${JSON.stringify(value)})`);
|
|
520
|
-
|
|
577
|
+
const name = value._name || extType.name;
|
|
578
|
+
const classID = value._classID || extType.classID;
|
|
579
|
+
writeDescriptorStructure(writer, name, classID, value, root);
|
|
521
580
|
break;
|
|
581
|
+
}
|
|
522
582
|
case 'VlLs': // List
|
|
583
|
+
if (!Array.isArray(value)) throw new Error(`Invalid list value: ${JSON.stringify(value)}, key: ${key}`);
|
|
523
584
|
writeInt32(writer, value.length);
|
|
524
585
|
|
|
525
586
|
for (let i = 0; i < value.length; i++) {
|
|
@@ -530,6 +591,7 @@ function writeOSType(writer: PsdWriter, type: string, value: any, key: string, e
|
|
|
530
591
|
}
|
|
531
592
|
break;
|
|
532
593
|
case 'doub': // Double
|
|
594
|
+
if (typeof value !== 'number') throw new Error(`Invalid number value: ${JSON.stringify(value)}, key: ${key}`);
|
|
533
595
|
writeFloat64(writer, value);
|
|
534
596
|
break;
|
|
535
597
|
case 'UntF': // Unit double
|
|
@@ -546,17 +608,20 @@ function writeOSType(writer: PsdWriter, type: string, value: any, key: string, e
|
|
|
546
608
|
writeUnicodeStringWithPadding(writer, value);
|
|
547
609
|
break;
|
|
548
610
|
case 'enum': { // Enumerated
|
|
611
|
+
if (typeof value !== 'string') throw new Error(`Invalid enum value: ${JSON.stringify(value)}, key: ${key}`);
|
|
549
612
|
const [_type, val] = value.split('.');
|
|
550
613
|
writeAsciiStringOrClassId(writer, _type);
|
|
551
614
|
writeAsciiStringOrClassId(writer, val);
|
|
552
615
|
break;
|
|
553
616
|
}
|
|
554
617
|
case 'long': // Integer
|
|
618
|
+
if (typeof value !== 'number') throw new Error(`Invalid integer value: ${JSON.stringify(value)}, key: ${key}`);
|
|
555
619
|
writeInt32(writer, value);
|
|
556
620
|
break;
|
|
557
621
|
// case 'comp': // Large Integer
|
|
558
622
|
// writeLargeInteger(reader);
|
|
559
623
|
case 'bool': // Boolean
|
|
624
|
+
if (typeof value !== 'boolean') throw new Error(`Invalid boolean value: ${JSON.stringify(value)}, key: ${key}`);
|
|
560
625
|
writeUint8(writer, value ? 1 : 0);
|
|
561
626
|
break;
|
|
562
627
|
// case 'type': // Class
|
|
@@ -588,8 +653,15 @@ function writeOSType(writer: PsdWriter, type: string, value: any, key: string, e
|
|
|
588
653
|
}
|
|
589
654
|
break;
|
|
590
655
|
}
|
|
591
|
-
|
|
592
|
-
|
|
656
|
+
case 'Pth ': { // File path
|
|
657
|
+
const length = 4 + 4 + 4 + value.path.length * 2;
|
|
658
|
+
writeInt32(writer, length);
|
|
659
|
+
writeSignature(writer, value.sig);
|
|
660
|
+
writeInt32LE(writer, length);
|
|
661
|
+
writeInt32LE(writer, value.path.length);
|
|
662
|
+
writeUnicodeStringWithoutLengthLE(writer, value.path);
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
593
665
|
default:
|
|
594
666
|
throw new Error(`Not implemented descriptor OSType: ${type}`);
|
|
595
667
|
}
|
|
@@ -690,7 +762,6 @@ function writeReferenceStructure(writer: PsdWriter, _key: string, items: any[])
|
|
|
690
762
|
function readClassStructure(reader: PsdReader) {
|
|
691
763
|
const name = readUnicodeString(reader);
|
|
692
764
|
const classID = readAsciiStringOrClassId(reader);
|
|
693
|
-
// console.log({ name, classID });
|
|
694
765
|
return { name, classID };
|
|
695
766
|
}
|
|
696
767
|
|
|
@@ -721,25 +792,37 @@ export interface DescriptorUnitsValue {
|
|
|
721
792
|
}
|
|
722
793
|
|
|
723
794
|
export type DescriptorColor = {
|
|
795
|
+
_name: '';
|
|
796
|
+
_classID: 'RGBC';
|
|
724
797
|
'Rd ': number;
|
|
725
798
|
'Grn ': number;
|
|
726
799
|
'Bl ': number;
|
|
727
800
|
} | {
|
|
801
|
+
_name: '';
|
|
802
|
+
_classID: 'HSBC'; // ???
|
|
728
803
|
'H ': DescriptorUnitsValue;
|
|
729
804
|
Strt: number;
|
|
730
805
|
Brgh: number;
|
|
731
806
|
} | {
|
|
807
|
+
_name: '';
|
|
808
|
+
_classID: 'CMYC';
|
|
732
809
|
'Cyn ': number;
|
|
733
810
|
Mgnt: number;
|
|
734
811
|
'Ylw ': number;
|
|
735
812
|
Blck: number;
|
|
736
813
|
} | {
|
|
814
|
+
_name: '';
|
|
815
|
+
_classID: 'GRYC'; // ???
|
|
737
816
|
'Gry ': number;
|
|
738
817
|
} | {
|
|
818
|
+
_name: '';
|
|
819
|
+
_classID: 'LABC'; // ???
|
|
739
820
|
Lmnc: number;
|
|
740
821
|
'A ': number;
|
|
741
822
|
'B ': number;
|
|
742
823
|
} | {
|
|
824
|
+
_name: '';
|
|
825
|
+
_classID: 'XXXX'; // ???
|
|
743
826
|
redFloat: number;
|
|
744
827
|
greenFloat: number;
|
|
745
828
|
blueFloat: number;
|
|
@@ -819,11 +902,20 @@ export interface StrokeDescriptor {
|
|
|
819
902
|
strokeStyleResolution: number;
|
|
820
903
|
}
|
|
821
904
|
|
|
905
|
+
export interface BoundsDescriptor {
|
|
906
|
+
Left: DescriptorUnitsValue;
|
|
907
|
+
'Top ': DescriptorUnitsValue;
|
|
908
|
+
Rght: DescriptorUnitsValue;
|
|
909
|
+
Btom: DescriptorUnitsValue;
|
|
910
|
+
}
|
|
911
|
+
|
|
822
912
|
export interface TextDescriptor {
|
|
823
913
|
'Txt ': string;
|
|
824
914
|
textGridding: string;
|
|
825
915
|
Ornt: string;
|
|
826
916
|
AntA: string;
|
|
917
|
+
bounds?: BoundsDescriptor;
|
|
918
|
+
boundingBox?: BoundsDescriptor;
|
|
827
919
|
TextIndex: number;
|
|
828
920
|
EngineData?: Uint8Array;
|
|
829
921
|
}
|
|
@@ -844,6 +936,8 @@ export interface WarpDescriptor {
|
|
|
844
936
|
uOrder: number;
|
|
845
937
|
vOrder: number;
|
|
846
938
|
customEnvelopeWarp?: {
|
|
939
|
+
_name: '';
|
|
940
|
+
_classID: 'customEnvelopeWarp';
|
|
847
941
|
meshPoints: {
|
|
848
942
|
type: 'Hrzn' | 'Vrtc';
|
|
849
943
|
values: number[];
|
|
@@ -855,6 +949,8 @@ export interface QuiltWarpDescriptor extends WarpDescriptor {
|
|
|
855
949
|
deformNumRows: number;
|
|
856
950
|
deformNumCols: number;
|
|
857
951
|
customEnvelopeWarp: {
|
|
952
|
+
_name: '';
|
|
953
|
+
_classID: 'customEnvelopeWarp';
|
|
858
954
|
quiltSliceX: {
|
|
859
955
|
type: 'quiltSliceX';
|
|
860
956
|
values: number[];
|
|
@@ -904,6 +1000,24 @@ export function xyToHorzVrtc(xy: { x: number; y: number; }): HrznVrtcDescriptor
|
|
|
904
1000
|
return { Hrzn: xy.x, Vrtc: xy.y };
|
|
905
1001
|
}
|
|
906
1002
|
|
|
1003
|
+
export function descBoundsToBounds(desc: BoundsDescriptor): UnitsBounds {
|
|
1004
|
+
return {
|
|
1005
|
+
top: parseUnits(desc['Top ']),
|
|
1006
|
+
left: parseUnits(desc.Left),
|
|
1007
|
+
right: parseUnits(desc.Rght),
|
|
1008
|
+
bottom: parseUnits(desc.Btom),
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
export function boundsToDescBounds(bounds: UnitsBounds): BoundsDescriptor {
|
|
1013
|
+
return {
|
|
1014
|
+
Left: unitsValue(bounds.left, 'bounds.left'),
|
|
1015
|
+
['Top ']: unitsValue(bounds.top, 'bounds.top'),
|
|
1016
|
+
Rght: unitsValue(bounds.right, 'bounds.right'),
|
|
1017
|
+
Btom: unitsValue(bounds.bottom, 'bounds.bottom'),
|
|
1018
|
+
};
|
|
1019
|
+
}
|
|
1020
|
+
|
|
907
1021
|
export type TimelineAnimKeyDescriptor = {
|
|
908
1022
|
Type: 'keyType.Opct';
|
|
909
1023
|
Opct: DescriptorUnitsValue;
|
|
@@ -1122,7 +1236,8 @@ function parseKeyList(keyList: TimelineKeyDescriptor[], logMissingFeatures: bool
|
|
|
1122
1236
|
|
|
1123
1237
|
for (let j = 0; j < keyList.length; j++) {
|
|
1124
1238
|
const key = keyList[j];
|
|
1125
|
-
const { time, selected, animKey } = key;
|
|
1239
|
+
const { time: { denominator, numerator }, selected, animKey } = key;
|
|
1240
|
+
const time = { numerator, denominator };
|
|
1126
1241
|
const interpolation = animInterpStyleEnum.decode(key.animInterpStyle);
|
|
1127
1242
|
|
|
1128
1243
|
switch (animKey.Type) {
|
|
@@ -1307,6 +1422,9 @@ function parseEffectObject(obj: any, reportErrors: boolean) {
|
|
|
1307
1422
|
case 'present':
|
|
1308
1423
|
case 'showInDialog':
|
|
1309
1424
|
case 'antialiasGloss': result[key] = val; break;
|
|
1425
|
+
case '_name':
|
|
1426
|
+
case '_classID':
|
|
1427
|
+
break;
|
|
1310
1428
|
default:
|
|
1311
1429
|
reportErrors && console.log(`Invalid effect key: '${key}', value:`, val);
|
|
1312
1430
|
}
|
|
@@ -1564,19 +1682,19 @@ export function parseColor(color: DescriptorColor): Color {
|
|
|
1564
1682
|
|
|
1565
1683
|
export function serializeColor(color: Color | undefined): DescriptorColor {
|
|
1566
1684
|
if (!color) {
|
|
1567
|
-
return { 'Rd ': 0, 'Grn ': 0, 'Bl ': 0 };
|
|
1685
|
+
return { _name: '', _classID: 'RGBC', 'Rd ': 0, 'Grn ': 0, 'Bl ': 0 };
|
|
1568
1686
|
} else if ('r' in color) {
|
|
1569
|
-
return { 'Rd ': color.r || 0, 'Grn ': color.g || 0, 'Bl ': color.b || 0 };
|
|
1687
|
+
return { _name: '', _classID: 'RGBC', 'Rd ': color.r || 0, 'Grn ': color.g || 0, 'Bl ': color.b || 0 };
|
|
1570
1688
|
} else if ('fr' in color) {
|
|
1571
|
-
return { redFloat: color.fr, greenFloat: color.fg, blueFloat: color.fb };
|
|
1689
|
+
return { _name: '', _classID: 'XXXX', redFloat: color.fr, greenFloat: color.fg, blueFloat: color.fb };
|
|
1572
1690
|
} else if ('h' in color) {
|
|
1573
|
-
return { 'H ': unitsAngle(color.h * 360), Strt: color.s || 0, Brgh: color.b || 0 };
|
|
1691
|
+
return { _name: '', _classID: 'HSBC', 'H ': unitsAngle(color.h * 360), Strt: color.s || 0, Brgh: color.b || 0 };
|
|
1574
1692
|
} else if ('c' in color) {
|
|
1575
|
-
return { 'Cyn ': color.c || 0, Mgnt: color.m || 0, 'Ylw ': color.y || 0, Blck: color.k || 0 };
|
|
1693
|
+
return { _name: '', _classID: 'CMYC', 'Cyn ': color.c || 0, Mgnt: color.m || 0, 'Ylw ': color.y || 0, Blck: color.k || 0 };
|
|
1576
1694
|
} else if ('l' in color) {
|
|
1577
|
-
return { Lmnc: color.l || 0, 'A ': color.a || 0, 'B ': color.b || 0 };
|
|
1695
|
+
return { _name: '', _classID: 'LABC', Lmnc: color.l || 0, 'A ': color.a || 0, 'B ': color.b || 0 };
|
|
1578
1696
|
} else if ('k' in color) {
|
|
1579
|
-
return { 'Gry ': color.k };
|
|
1697
|
+
return { _name: '', _classID: 'GRYC', 'Gry ': color.k };
|
|
1580
1698
|
} else {
|
|
1581
1699
|
throw new Error('Invalid color value');
|
|
1582
1700
|
}
|
|
@@ -1629,6 +1747,10 @@ export function unitsPercent(value: number | undefined): DescriptorUnitsValue {
|
|
|
1629
1747
|
return { units: 'Percent', value: Math.round((value || 0) * 100) };
|
|
1630
1748
|
}
|
|
1631
1749
|
|
|
1750
|
+
export function unitsPercentF(value: number | undefined): DescriptorUnitsValue {
|
|
1751
|
+
return { units: 'Percent', value: (value || 0) * 100 };
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1632
1754
|
export function unitsValue(x: UnitsValue | undefined, key: string): DescriptorUnitsValue {
|
|
1633
1755
|
if (x == null) return { units: 'Pixels', value: 0 };
|
|
1634
1756
|
|
|
@@ -1650,6 +1772,10 @@ export function unitsValue(x: UnitsValue | undefined, key: string): DescriptorUn
|
|
|
1650
1772
|
return { units, value };
|
|
1651
1773
|
}
|
|
1652
1774
|
|
|
1775
|
+
export function frac({ numerator, denominator }: FractionDescriptor) {
|
|
1776
|
+
return { numerator, denominator };
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1653
1779
|
export const textGridding = createEnum<TextGridding>('textGridding', 'none', {
|
|
1654
1780
|
none: 'None',
|
|
1655
1781
|
round: 'Rnd ',
|
|
@@ -1785,6 +1911,7 @@ export const ClrS = createEnum<'rgb' | 'hsb' | 'lab'>('ClrS', 'rgb', {
|
|
|
1785
1911
|
rgb: 'RGBC',
|
|
1786
1912
|
hsb: 'HSBl',
|
|
1787
1913
|
lab: 'LbCl',
|
|
1914
|
+
hsl: 'HSLC',
|
|
1788
1915
|
});
|
|
1789
1916
|
|
|
1790
1917
|
export const FStl = createEnum<'inside' | 'center' | 'outside'>('FStl', 'outside', {
|
|
@@ -1841,3 +1968,166 @@ export const strokeStyleLineAlignment = createEnum<LineAlignment>('strokeStyleLi
|
|
|
1841
1968
|
center: 'strokeStyleAlignCenter',
|
|
1842
1969
|
outside: 'strokeStyleAlignOutside',
|
|
1843
1970
|
});
|
|
1971
|
+
|
|
1972
|
+
export const BlrM = createEnum<'spin' | 'zoom'>('BlrM', 'ispinmage', {
|
|
1973
|
+
spin: 'Spn ',
|
|
1974
|
+
zoom: 'Zm ',
|
|
1975
|
+
});
|
|
1976
|
+
|
|
1977
|
+
export const BlrQ = createEnum<'draft' | 'good' | 'best'>('BlrQ', 'good', {
|
|
1978
|
+
draft: 'Drft',
|
|
1979
|
+
good: 'Gd ',
|
|
1980
|
+
best: 'Bst ',
|
|
1981
|
+
});
|
|
1982
|
+
|
|
1983
|
+
export const SmBM = createEnum<'normal' | 'edge only' | 'overlay edge'>('SmBM', 'normal', {
|
|
1984
|
+
normal: 'SBMN',
|
|
1985
|
+
'edge only': 'SBME',
|
|
1986
|
+
'overlay edge': 'SBMO',
|
|
1987
|
+
});
|
|
1988
|
+
|
|
1989
|
+
export const SmBQ = createEnum<'low' | 'medium' | 'high'>('SmBQ', 'medium', {
|
|
1990
|
+
low: 'SBQL',
|
|
1991
|
+
medium: 'SBQM',
|
|
1992
|
+
high: 'SBQH',
|
|
1993
|
+
});
|
|
1994
|
+
|
|
1995
|
+
export const DspM = createEnum<'stretch to fit' | 'tile'>('DspM', 'stretch to fit', {
|
|
1996
|
+
'stretch to fit': 'StrF',
|
|
1997
|
+
'tile': 'Tile',
|
|
1998
|
+
});
|
|
1999
|
+
|
|
2000
|
+
export const UndA = createEnum<'wrap around' | 'repeat edge pixels'>('UndA', 'repeat edge pixels', {
|
|
2001
|
+
'wrap around': 'WrpA',
|
|
2002
|
+
'repeat edge pixels': 'RptE',
|
|
2003
|
+
});
|
|
2004
|
+
|
|
2005
|
+
export const Cnvr = createEnum<'rectangular to polar' | 'polar to rectangular'>('Cnvr', 'rectangular to polar', {
|
|
2006
|
+
'rectangular to polar': 'RctP',
|
|
2007
|
+
'polar to rectangular': 'PlrR',
|
|
2008
|
+
});
|
|
2009
|
+
|
|
2010
|
+
export const RplS = createEnum<'small' | 'medium' | 'large'>('RplS', 'medium', {
|
|
2011
|
+
small: 'Sml ',
|
|
2012
|
+
medium: 'Mdm ',
|
|
2013
|
+
large: 'Lrg ',
|
|
2014
|
+
});
|
|
2015
|
+
|
|
2016
|
+
export const SphM = createEnum<'normal' | 'horizontal only' | 'vertical only'>('SphM', 'normal', {
|
|
2017
|
+
'normal': 'Nrml',
|
|
2018
|
+
'horizontal only': 'HrzO',
|
|
2019
|
+
'vertical only': 'VrtO',
|
|
2020
|
+
});
|
|
2021
|
+
|
|
2022
|
+
export const Wvtp = createEnum<'sine' | 'triangle' | 'square'>('Wvtp', 'sine', {
|
|
2023
|
+
sine: 'WvSn',
|
|
2024
|
+
triangle: 'WvTr',
|
|
2025
|
+
square: 'WvSq',
|
|
2026
|
+
});
|
|
2027
|
+
|
|
2028
|
+
export const ZZTy = createEnum<'around center' | 'out from center' | 'pond ripples'>('ZZTy', 'pond ripples', {
|
|
2029
|
+
'around center': 'ArnC',
|
|
2030
|
+
'out from center': 'OtFr',
|
|
2031
|
+
'pond ripples': 'PndR',
|
|
2032
|
+
});
|
|
2033
|
+
|
|
2034
|
+
export const Dstr = createEnum<'uniform' | 'gaussian'>('Dstr', 'uniform', {
|
|
2035
|
+
uniform: 'Unfr',
|
|
2036
|
+
gaussian: 'Gsn ',
|
|
2037
|
+
});
|
|
2038
|
+
|
|
2039
|
+
export const Chnl = createEnum<'red' | 'green' | 'blue' | 'composite'>('Chnl', 'composite', {
|
|
2040
|
+
red: 'Rd ',
|
|
2041
|
+
green: 'Grn ',
|
|
2042
|
+
blue: 'Bl ',
|
|
2043
|
+
composite: 'Cmps',
|
|
2044
|
+
});
|
|
2045
|
+
|
|
2046
|
+
export const MztT = createEnum<'fine dots' | 'medium dots' | 'grainy dots' | 'coarse dots' | 'short lines' | 'medium lines' | 'long lines' | 'short strokes' | 'medium strokes' | 'long strokes'>('MztT', 'fine dots', {
|
|
2047
|
+
'fine dots': 'FnDt',
|
|
2048
|
+
'medium dots': 'MdmD',
|
|
2049
|
+
'grainy dots': 'GrnD',
|
|
2050
|
+
'coarse dots': 'CrsD',
|
|
2051
|
+
'short lines': 'ShrL',
|
|
2052
|
+
'medium lines': 'MdmL',
|
|
2053
|
+
'long lines': 'LngL',
|
|
2054
|
+
'short strokes': 'ShSt',
|
|
2055
|
+
'medium strokes': 'MdmS',
|
|
2056
|
+
'long strokes': 'LngS',
|
|
2057
|
+
});
|
|
2058
|
+
|
|
2059
|
+
export const Lns = createEnum<'50-300mm zoom' | '32mm prime' | '105mm prime' | 'movie prime'>('Lns ', '50-300mm zoom', {
|
|
2060
|
+
'50-300mm zoom': 'Zm ',
|
|
2061
|
+
'32mm prime': 'Nkn ',
|
|
2062
|
+
'105mm prime': 'Nkn1',
|
|
2063
|
+
'movie prime': 'PnVs',
|
|
2064
|
+
});
|
|
2065
|
+
|
|
2066
|
+
export const blurType = createEnum<'gaussian blur' | 'lens blur' | 'motion blur'>('blurType', 'gaussian blur', {
|
|
2067
|
+
'gaussian blur': 'GsnB',
|
|
2068
|
+
'lens blur': 'lensBlur',
|
|
2069
|
+
'motion blur': 'MtnB',
|
|
2070
|
+
});
|
|
2071
|
+
|
|
2072
|
+
export const DfsM = createEnum<'normal' | 'darken only' | 'lighten only' | 'anisotropic'>('DfsM', 'normal', {
|
|
2073
|
+
'normal': 'Nrml',
|
|
2074
|
+
'darken only': 'DrkO',
|
|
2075
|
+
'lighten only': 'LghO',
|
|
2076
|
+
'anisotropic': 'anisotropic',
|
|
2077
|
+
});
|
|
2078
|
+
|
|
2079
|
+
export const ExtT = createEnum<'blocks' | 'pyramids'>('ExtT', 'blocks', {
|
|
2080
|
+
blocks: 'Blks',
|
|
2081
|
+
pyramids: 'Pyrm',
|
|
2082
|
+
});
|
|
2083
|
+
|
|
2084
|
+
export const ExtR = createEnum<'random' | 'level-based'>('ExtR', 'random', {
|
|
2085
|
+
random: 'Rndm',
|
|
2086
|
+
'level-based': 'LvlB',
|
|
2087
|
+
});
|
|
2088
|
+
|
|
2089
|
+
export const FlCl = createEnum<'background color' | 'foreground color' | 'inverse image' | 'unaltered image'>('FlCl', 'background color', {
|
|
2090
|
+
'background color': 'FlBc',
|
|
2091
|
+
'foreground color': 'FlFr',
|
|
2092
|
+
'inverse image': 'FlIn',
|
|
2093
|
+
'unaltered image': 'FlSm',
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
export const CntE = createEnum<'lower' | 'upper'>('CntE', 'upper', {
|
|
2097
|
+
lower: 'Lwr ',
|
|
2098
|
+
upper: 'Upr ',
|
|
2099
|
+
});
|
|
2100
|
+
|
|
2101
|
+
export const WndM = createEnum<'wind' | 'blast' | 'stagger'>('WndM', 'wind', {
|
|
2102
|
+
wind: 'Wnd ',
|
|
2103
|
+
blast: 'Blst',
|
|
2104
|
+
stagger: 'Stgr',
|
|
2105
|
+
});
|
|
2106
|
+
|
|
2107
|
+
export const Drct = createEnum<'left' | 'right'>('Drct', 'from the right', {
|
|
2108
|
+
left: 'Left',
|
|
2109
|
+
right: 'Rght',
|
|
2110
|
+
});
|
|
2111
|
+
|
|
2112
|
+
export const IntE = createEnum<'odd lines' | 'even lines'>('IntE', 'odd lines', {
|
|
2113
|
+
'odd lines': 'ElmO',
|
|
2114
|
+
'even lines': 'ElmE',
|
|
2115
|
+
});
|
|
2116
|
+
|
|
2117
|
+
export const IntC = createEnum<'duplication' | 'interpolation'>('IntC', 'interpolation', {
|
|
2118
|
+
duplication: 'CrtD',
|
|
2119
|
+
interpolation: 'CrtI',
|
|
2120
|
+
});
|
|
2121
|
+
|
|
2122
|
+
export const FlMd = createEnum<'set to transparent' | 'repeat edge pixels' | 'wrap around'>('FlMd', 'wrap around', {
|
|
2123
|
+
'set to transparent': 'Bckg',
|
|
2124
|
+
'repeat edge pixels': 'Rpt ',
|
|
2125
|
+
'wrap around': 'Wrp ',
|
|
2126
|
+
});
|
|
2127
|
+
|
|
2128
|
+
export const prjM = createEnum<'fisheye' | 'perspective' | 'auto' | 'full spherical'>('prjM', 'fisheye', {
|
|
2129
|
+
'fisheye': 'fisP',
|
|
2130
|
+
'perspective': 'perP',
|
|
2131
|
+
'auto': 'auto',
|
|
2132
|
+
'full spherical': 'fusP',
|
|
2133
|
+
});
|