ag-psd 19.0.1 → 20.1.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/CHANGELOG.md +10 -0
- package/README_PSD.md +20 -2
- package/TODO +7 -0
- package/dist/abr.js +4 -4
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.d.ts +3 -3
- package/dist/additionalInfo.js +107 -12
- package/dist/additionalInfo.js.map +1 -1
- package/dist/bundle.js +15305 -7643
- package/dist/descriptor.js +21 -16
- package/dist/descriptor.js.map +1 -1
- package/dist/engineData2.d.ts +1 -0
- package/dist/engineData2.js +349 -0
- package/dist/engineData2.js.map +1 -0
- package/dist/helpers.d.ts +2 -7
- package/dist/helpers.js +45 -12
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.js +42 -1
- package/dist/imageResources.js.map +1 -1
- package/dist/psd.d.ts +46 -3
- package/dist/psd.js +8 -1
- package/dist/psd.js.map +1 -1
- package/dist/psdReader.d.ts +11 -5
- package/dist/psdReader.js +213 -100
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.js +24 -4
- package/dist/psdWriter.js.map +1 -1
- package/dist/utf8.js +10 -4
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.js +4 -4
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +3 -3
- package/dist-es/additionalInfo.js +110 -15
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/descriptor.js +21 -16
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/engineData2.d.ts +1 -0
- package/dist-es/engineData2.js +345 -0
- package/dist-es/engineData2.js.map +1 -0
- package/dist-es/helpers.d.ts +2 -7
- package/dist-es/helpers.js +43 -11
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.js +42 -1
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/psd.d.ts +46 -3
- package/dist-es/psd.js +7 -0
- package/dist-es/psd.js.map +1 -1
- package/dist-es/psdReader.d.ts +11 -5
- package/dist-es/psdReader.js +212 -102
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.js +25 -5
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/utf8.js +10 -4
- package/dist-es/utf8.js.map +1 -1
- package/package.json +6 -7
- package/src/abr.ts +4 -4
- package/src/additionalInfo.ts +156 -51
- package/src/descriptor.ts +14 -9
- package/src/engineData2.ts +367 -0
- package/src/helpers.ts +47 -20
- package/src/imageResources.ts +59 -2
- package/src/psd.ts +41 -5
- package/src/psdReader.ts +210 -128
- package/src/psdWriter.ts +33 -14
- package/src/utf8.ts +12 -4
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/// Engine data 2 experiments
|
|
2
|
+
// /test/engineData2.json:1109 is character codes
|
|
3
|
+
|
|
4
|
+
interface KeysDict {
|
|
5
|
+
[key: string]: {
|
|
6
|
+
name?: string;
|
|
7
|
+
uproot?: boolean;
|
|
8
|
+
children?: KeysDict;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const keysColor: KeysDict = {
|
|
13
|
+
'0': {
|
|
14
|
+
uproot: true,
|
|
15
|
+
children: {
|
|
16
|
+
'0': { name: 'Type' },
|
|
17
|
+
'1': { name: 'Values' },
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const keysStyleSheet: KeysDict = {
|
|
23
|
+
'0': { name: 'Font' },
|
|
24
|
+
'1': { name: 'FontSize' },
|
|
25
|
+
'2': { name: 'FauxBold' },
|
|
26
|
+
'3': { name: 'FauxItalic' },
|
|
27
|
+
'4': { name: 'AutoLeading' },
|
|
28
|
+
'5': { name: 'Leading' },
|
|
29
|
+
'6': { name: 'HorizontalScale' },
|
|
30
|
+
'7': { name: 'VerticalScale' },
|
|
31
|
+
'8': { name: 'Tracking' },
|
|
32
|
+
'9': { name: 'BaselineShift' },
|
|
33
|
+
// '10': ???
|
|
34
|
+
'11': { name: 'Kerning?' }, // different value than EngineData
|
|
35
|
+
'12': { name: 'FontCaps' },
|
|
36
|
+
'13': { name: 'FontBaseline' },
|
|
37
|
+
|
|
38
|
+
'15': { name: 'Strikethrough?' }, // number instead of bool
|
|
39
|
+
'16': { name: 'Underline?' }, // number instead of bool
|
|
40
|
+
|
|
41
|
+
'18': { name: 'Ligatures' },
|
|
42
|
+
'19': { name: 'DLigatures' },
|
|
43
|
+
// '20': ???
|
|
44
|
+
// '21': ???
|
|
45
|
+
// '22': ???
|
|
46
|
+
'23': { name: 'Fractions' }, // not present in EngineData
|
|
47
|
+
'24': { name: 'Ordinals' }, // not present in EngineData
|
|
48
|
+
// '25': ???
|
|
49
|
+
// '26': ???
|
|
50
|
+
// '27': ???
|
|
51
|
+
'28': { name: 'StylisticAlternates' }, // not present in EngineData
|
|
52
|
+
// '29': ???
|
|
53
|
+
'30': { name: 'OldStyle?' }, // OpenType > OldStyle, number instead of bool, not present in EngineData
|
|
54
|
+
|
|
55
|
+
'35': { name: 'BaselineDirection' },
|
|
56
|
+
|
|
57
|
+
'38': { name: 'Language' },
|
|
58
|
+
|
|
59
|
+
'52': { name: 'NoBreak' },
|
|
60
|
+
'53': { name: 'FillColor', children: keysColor },
|
|
61
|
+
'54': { name: 'StrokeColor?', children: keysColor },
|
|
62
|
+
'55': { children: { '99': { uproot: true } } },
|
|
63
|
+
|
|
64
|
+
// '68': ???
|
|
65
|
+
|
|
66
|
+
// '70': ???
|
|
67
|
+
// '71': ???
|
|
68
|
+
// '72': ???
|
|
69
|
+
// '73': ???
|
|
70
|
+
|
|
71
|
+
'79': { children: keysColor },
|
|
72
|
+
|
|
73
|
+
// '85': ???
|
|
74
|
+
|
|
75
|
+
// '87': ???
|
|
76
|
+
// '88': ???
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const keysParagraph: KeysDict = {
|
|
80
|
+
'0': { name: 'Justification' },
|
|
81
|
+
'1': { name: 'FirstLineIndent' },
|
|
82
|
+
'2': { name: 'StartIndent' },
|
|
83
|
+
'3': { name: 'EndIndent' },
|
|
84
|
+
'4': { name: 'SpaceBefore' },
|
|
85
|
+
'5': { name: 'SpaceAfter' },
|
|
86
|
+
|
|
87
|
+
'7': { name: 'AutoLeading' },
|
|
88
|
+
|
|
89
|
+
'9': { name: 'AutoHyphenate' },
|
|
90
|
+
'10': { name: 'HyphenatedWordSize' },
|
|
91
|
+
'11': { name: 'PreHyphen' },
|
|
92
|
+
'12': { name: 'PostHyphen' },
|
|
93
|
+
'13': { name: 'ConsecutiveHyphens?' }, // different value than EngineData
|
|
94
|
+
'14': { name: 'Zone' },
|
|
95
|
+
'15': { name: 'HypenateCapitalizedWords' }, // not present in EngineData
|
|
96
|
+
|
|
97
|
+
'17': { name: 'WordSpacing' },
|
|
98
|
+
'18': { name: 'LetterSpacing' },
|
|
99
|
+
'19': { name: 'GlyphSpacing' },
|
|
100
|
+
|
|
101
|
+
'32': { name: 'StyleSheet', children: keysStyleSheet },
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const keysStyleSheetData: KeysDict[''] = {
|
|
105
|
+
name: 'StyleSheetData',
|
|
106
|
+
children: keysStyleSheet,
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const keysRoot: KeysDict = {
|
|
110
|
+
'0': {
|
|
111
|
+
name: 'ResourceDict',
|
|
112
|
+
children: {
|
|
113
|
+
'1': {
|
|
114
|
+
name: 'FontSet',
|
|
115
|
+
children: {
|
|
116
|
+
'0': {
|
|
117
|
+
uproot: true,
|
|
118
|
+
children: {
|
|
119
|
+
'0': {
|
|
120
|
+
uproot: true,
|
|
121
|
+
children: {
|
|
122
|
+
'0': {
|
|
123
|
+
uproot: true,
|
|
124
|
+
children: {
|
|
125
|
+
'0': { name: 'Name' },
|
|
126
|
+
'2': { name: 'FontType' },
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
'2': {
|
|
136
|
+
name: '2',
|
|
137
|
+
children: {},
|
|
138
|
+
},
|
|
139
|
+
'3': {
|
|
140
|
+
name: 'MojiKumiSet',
|
|
141
|
+
children: {
|
|
142
|
+
'0': {
|
|
143
|
+
uproot: true,
|
|
144
|
+
children: {
|
|
145
|
+
'0': {
|
|
146
|
+
uproot: true,
|
|
147
|
+
children: {
|
|
148
|
+
'0': { name: 'InternalName' },
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
'4': {
|
|
156
|
+
name: 'KinsokuSet',
|
|
157
|
+
children: {
|
|
158
|
+
'0': {
|
|
159
|
+
uproot: true,
|
|
160
|
+
children: {
|
|
161
|
+
'0': {
|
|
162
|
+
uproot: true,
|
|
163
|
+
children: {
|
|
164
|
+
'0': { name: 'Name' },
|
|
165
|
+
'5': {
|
|
166
|
+
uproot: true,
|
|
167
|
+
children: {
|
|
168
|
+
'0': { name: 'NoStart' },
|
|
169
|
+
'1': { name: 'NoEnd' },
|
|
170
|
+
'2': { name: 'Keep' },
|
|
171
|
+
'3': { name: 'Hanging' },
|
|
172
|
+
'4': { name: 'Name' },
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
'5': {
|
|
182
|
+
name: 'StyleSheetSet',
|
|
183
|
+
children: {
|
|
184
|
+
'0': {
|
|
185
|
+
uproot: true,
|
|
186
|
+
children: {
|
|
187
|
+
'0': {
|
|
188
|
+
uproot: true,
|
|
189
|
+
children: {
|
|
190
|
+
'0': { name: 'Name' },
|
|
191
|
+
'6': keysStyleSheetData,
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
'6': {
|
|
199
|
+
name: 'ParagraphSheetSet',
|
|
200
|
+
children: {
|
|
201
|
+
'0': {
|
|
202
|
+
uproot: true,
|
|
203
|
+
children: {
|
|
204
|
+
'0': {
|
|
205
|
+
uproot: true,
|
|
206
|
+
children: {
|
|
207
|
+
'0': { name: 'Name' },
|
|
208
|
+
'5': {
|
|
209
|
+
name: 'Properties',
|
|
210
|
+
children: keysParagraph,
|
|
211
|
+
},
|
|
212
|
+
'6': { name: 'DefaultStyleSheet' },
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
'8': {
|
|
220
|
+
name: '8',
|
|
221
|
+
children: {},
|
|
222
|
+
},
|
|
223
|
+
'9': {
|
|
224
|
+
name: 'Predefined',
|
|
225
|
+
children: {
|
|
226
|
+
'0': {
|
|
227
|
+
children: { '0': { uproot: true } },
|
|
228
|
+
},
|
|
229
|
+
'1': {
|
|
230
|
+
children: { '0': { uproot: true } },
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
'1': {
|
|
237
|
+
name: 'EngineDict',
|
|
238
|
+
children: {
|
|
239
|
+
'0': {
|
|
240
|
+
name: '0',
|
|
241
|
+
children: {
|
|
242
|
+
// 0: ???
|
|
243
|
+
// 1: ???
|
|
244
|
+
// 2: ???
|
|
245
|
+
'3': { name: 'SuperscriptSize' },
|
|
246
|
+
'4': { name: 'SuperscriptPosition' },
|
|
247
|
+
'5': { name: 'SubscriptSize' },
|
|
248
|
+
'6': { name: 'SubscriptPosition' },
|
|
249
|
+
'7': { name: 'SmallCapSize' },
|
|
250
|
+
'8': { name: 'UseFractionalGlyphWidths' }, // ???
|
|
251
|
+
|
|
252
|
+
'15': { children: { '0': { uproot: true } } },
|
|
253
|
+
// 16: ???
|
|
254
|
+
// 17: ???
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
'1': {
|
|
258
|
+
name: 'Editors?',
|
|
259
|
+
children: {
|
|
260
|
+
'0': {
|
|
261
|
+
name: 'Editor',
|
|
262
|
+
children: {
|
|
263
|
+
'0': { name: 'Text' },
|
|
264
|
+
'5': {
|
|
265
|
+
name: 'ParagraphRun',
|
|
266
|
+
children: {
|
|
267
|
+
'0': {
|
|
268
|
+
name: 'RunArray',
|
|
269
|
+
children: {
|
|
270
|
+
'0': {
|
|
271
|
+
name: 'ParagraphSheet',
|
|
272
|
+
children: {
|
|
273
|
+
'0': {
|
|
274
|
+
uproot: true,
|
|
275
|
+
children: {
|
|
276
|
+
'0': { name: '0' },
|
|
277
|
+
'5': {
|
|
278
|
+
name: '5',
|
|
279
|
+
children: keysParagraph,
|
|
280
|
+
},
|
|
281
|
+
'6': { name: '6' },
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
'1': { name: 'RunLength' },
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
'6': {
|
|
292
|
+
name: 'StyleRun',
|
|
293
|
+
children: {
|
|
294
|
+
'0': {
|
|
295
|
+
name: 'RunArray',
|
|
296
|
+
children: {
|
|
297
|
+
'0': {
|
|
298
|
+
name: 'StyleSheet',
|
|
299
|
+
children: {
|
|
300
|
+
'0': {
|
|
301
|
+
uproot: true,
|
|
302
|
+
children: {
|
|
303
|
+
'6': keysStyleSheetData,
|
|
304
|
+
},
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
'1': { name: 'RunLength' },
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
},
|
|
315
|
+
'1': {
|
|
316
|
+
name: 'FontVectorData ???',
|
|
317
|
+
// children: {
|
|
318
|
+
// '0': {},
|
|
319
|
+
// '2': {
|
|
320
|
+
// // '5'
|
|
321
|
+
// // '6'
|
|
322
|
+
// },
|
|
323
|
+
// }
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
'2': {
|
|
328
|
+
name: 'StyleSheet',
|
|
329
|
+
children: keysStyleSheet,
|
|
330
|
+
},
|
|
331
|
+
'3': {
|
|
332
|
+
name: 'ParagraphSheet',
|
|
333
|
+
children: keysParagraph,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
function decodeObj(obj: any, keys: KeysDict): any {
|
|
340
|
+
if (obj === null) return obj;
|
|
341
|
+
if (Array.isArray(obj)) return obj.map(x => decodeObj(x, keys));
|
|
342
|
+
if (typeof obj !== 'object') return obj;
|
|
343
|
+
|
|
344
|
+
let result: any = {};
|
|
345
|
+
|
|
346
|
+
for (const key of Object.keys(obj)) {
|
|
347
|
+
if (keys[key]) {
|
|
348
|
+
if (keys[key].uproot) {
|
|
349
|
+
if (key !== '99') result = decodeObj(obj[key], keys[key].children ?? {});
|
|
350
|
+
if (obj['99']) result._type = obj['99'];
|
|
351
|
+
break;
|
|
352
|
+
} else {
|
|
353
|
+
result[keys[key].name || key] = decodeObj(obj[key], keys[key].children ?? {});
|
|
354
|
+
}
|
|
355
|
+
} else if (key === '99') {
|
|
356
|
+
result._type = obj[key];
|
|
357
|
+
} else {
|
|
358
|
+
result[key] = decodeObj(obj[key], {});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return result;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
export function decodeEngineData2(data: any) {
|
|
366
|
+
return decodeObj(data, keysRoot);
|
|
367
|
+
}
|
package/src/helpers.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { fromByteArray } from 'base64-js';
|
|
2
|
-
import {
|
|
3
|
-
import { Layer, BlendMode, LayerColor } from './psd';
|
|
2
|
+
import { deflateSync } from 'zlib';
|
|
3
|
+
import { Layer, BlendMode, LayerColor, PixelData, PixelArray } from './psd';
|
|
4
4
|
|
|
5
5
|
export const MOCK_HANDLERS = false;
|
|
6
6
|
export const RAW_IMAGE_DATA = false;
|
|
@@ -138,14 +138,6 @@ export interface LayerChannelData {
|
|
|
138
138
|
mask?: Bounds;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
export type PixelArray = Uint8ClampedArray | Uint8Array;
|
|
142
|
-
|
|
143
|
-
export interface PixelData {
|
|
144
|
-
data: PixelArray;
|
|
145
|
-
width: number;
|
|
146
|
-
height: number;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
141
|
export function offsetForChannel(channelId: ChannelID, cmyk: boolean) {
|
|
150
142
|
switch (channelId) {
|
|
151
143
|
case ChannelID.Color0: return 0;
|
|
@@ -174,26 +166,61 @@ export function hasAlpha(data: PixelData) {
|
|
|
174
166
|
}
|
|
175
167
|
|
|
176
168
|
export function resetImageData({ data }: PixelData) {
|
|
177
|
-
const
|
|
178
|
-
|
|
169
|
+
const alpha = (data instanceof Float32Array) ? 1.0 : ((data instanceof Uint16Array) ? 0xffff : 0xff);
|
|
170
|
+
|
|
171
|
+
for (let p = 0, size = data.length | 0; p < size; p = (p + 4) | 0) {
|
|
172
|
+
data[p + 0] = 0;
|
|
173
|
+
data[p + 1] = 0;
|
|
174
|
+
data[p + 2] = 0;
|
|
175
|
+
data[p + 3] = alpha;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function imageDataToCanvas(pixelData: PixelData) {
|
|
180
|
+
const canvas = createCanvas(pixelData.width, pixelData.height);
|
|
181
|
+
let imageData: ImageData;
|
|
179
182
|
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
if (pixelData.data instanceof Uint8ClampedArray) {
|
|
184
|
+
imageData = pixelData as ImageData;
|
|
185
|
+
} else {
|
|
186
|
+
imageData = createImageData(pixelData.width, pixelData.height);
|
|
187
|
+
const src = pixelData.data;
|
|
188
|
+
const dst = imageData.data;
|
|
189
|
+
|
|
190
|
+
if (src instanceof Float32Array) {
|
|
191
|
+
for (let i = 0, size = src.length; i < size; i += 4) {
|
|
192
|
+
dst[i + 0] = Math.round(Math.pow(src[i + 0], 1.0 / 2.2) * 255);
|
|
193
|
+
dst[i + 1] = Math.round(Math.pow(src[i + 1], 1.0 / 2.2) * 255);
|
|
194
|
+
dst[i + 2] = Math.round(Math.pow(src[i + 2], 1.0 / 2.2) * 255);
|
|
195
|
+
dst[i + 3] = Math.round(src[i + 3] * 255);
|
|
196
|
+
}
|
|
197
|
+
} else {
|
|
198
|
+
const shift = (src instanceof Uint16Array) ? 8 : 0;
|
|
199
|
+
|
|
200
|
+
for (let i = 0, size = src.length; i < size; i++) {
|
|
201
|
+
dst[i] = src[i] >>> shift;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
182
204
|
}
|
|
205
|
+
|
|
206
|
+
canvas.getContext('2d')!.putImageData(imageData, 0, 0);
|
|
207
|
+
return canvas;
|
|
183
208
|
}
|
|
184
209
|
|
|
185
210
|
export function decodeBitmap(input: PixelArray, output: PixelArray, width: number, height: number) {
|
|
211
|
+
if (!(input instanceof Uint8Array || input instanceof Uint8ClampedArray)) throw new Error('Invalid bit depth');
|
|
212
|
+
|
|
186
213
|
for (let y = 0, p = 0, o = 0; y < height; y++) {
|
|
187
214
|
for (let x = 0; x < width;) {
|
|
188
215
|
let b = input[o++];
|
|
189
216
|
|
|
190
|
-
for (let i = 0; i < 8 && x < width; i++, x
|
|
217
|
+
for (let i = 0; i < 8 && x < width; i++, x++, p += 4) {
|
|
191
218
|
const v = b & 0x80 ? 0 : 255;
|
|
192
219
|
b = b << 1;
|
|
193
|
-
output[p
|
|
194
|
-
output[p
|
|
195
|
-
output[p
|
|
196
|
-
output[p
|
|
220
|
+
output[p + 0] = v;
|
|
221
|
+
output[p + 1] = v;
|
|
222
|
+
output[p + 2] = v;
|
|
223
|
+
output[p + 3] = 255;
|
|
197
224
|
}
|
|
198
225
|
}
|
|
199
226
|
}
|
|
@@ -322,7 +349,7 @@ export function writeDataZipWithoutPrediction({ data, width, height }: PixelData
|
|
|
322
349
|
channel[i] = data[o];
|
|
323
350
|
}
|
|
324
351
|
|
|
325
|
-
const buffer =
|
|
352
|
+
const buffer = deflateSync(channel);
|
|
326
353
|
buffers.push(buffer);
|
|
327
354
|
totalLength += buffer.byteLength;
|
|
328
355
|
}
|
package/src/imageResources.ts
CHANGED
|
@@ -98,8 +98,12 @@ addHandler(
|
|
|
98
98
|
addHandler(
|
|
99
99
|
1060,
|
|
100
100
|
target => target.xmpMetadata !== undefined,
|
|
101
|
-
(reader, target, left) =>
|
|
102
|
-
|
|
101
|
+
(reader, target, left) => {
|
|
102
|
+
target.xmpMetadata = readUtf8String(reader, left());
|
|
103
|
+
},
|
|
104
|
+
(writer, target) => {
|
|
105
|
+
writeUtf8String(writer, target.xmpMetadata!);
|
|
106
|
+
},
|
|
103
107
|
);
|
|
104
108
|
|
|
105
109
|
const Inte = createEnum<RenderingIntent>('Inte', 'perceptual', {
|
|
@@ -566,6 +570,59 @@ addHandler(
|
|
|
566
570
|
},
|
|
567
571
|
);
|
|
568
572
|
|
|
573
|
+
interface LayerCompsDescriptor {
|
|
574
|
+
list: {
|
|
575
|
+
_classID: 'Comp';
|
|
576
|
+
'Nm ': string;
|
|
577
|
+
compID: number;
|
|
578
|
+
capturedInfo: number;
|
|
579
|
+
comment?: string;
|
|
580
|
+
}[];
|
|
581
|
+
lastAppliedComp?: number;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
addHandler(
|
|
585
|
+
1065, // Layer Comps
|
|
586
|
+
target => target.layerComps !== undefined,
|
|
587
|
+
(reader, target) => {
|
|
588
|
+
const desc = readVersionAndDescriptor(reader, true) as LayerCompsDescriptor;
|
|
589
|
+
// console.log('CompList', require('util').inspect(desc, false, 99, true));
|
|
590
|
+
|
|
591
|
+
target.layerComps = { list: [] };
|
|
592
|
+
|
|
593
|
+
for (const item of desc.list) {
|
|
594
|
+
target.layerComps.list.push({
|
|
595
|
+
id: item.compID,
|
|
596
|
+
name: item['Nm '],
|
|
597
|
+
capturedInfo: item.capturedInfo,
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
if ('comment' in item) target.layerComps.list[target.layerComps.list.length - 1].comment = item.comment;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if ('lastAppliedComp' in desc) target.layerComps.lastApplied = desc.lastAppliedComp;
|
|
604
|
+
},
|
|
605
|
+
(writer, target) => {
|
|
606
|
+
const layerComps = target.layerComps!;
|
|
607
|
+
const desc: LayerCompsDescriptor = { list: [] };
|
|
608
|
+
|
|
609
|
+
for (const item of layerComps.list) {
|
|
610
|
+
const t: LayerCompsDescriptor['list'][0] = {} as any;
|
|
611
|
+
t._classID = 'Comp';
|
|
612
|
+
t['Nm '] = item.name;
|
|
613
|
+
if ('comment' in item) t.comment = item.comment;
|
|
614
|
+
t.compID = item.id;
|
|
615
|
+
t.capturedInfo = item.capturedInfo;
|
|
616
|
+
desc.list.push(t);
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if ('lastApplied' in layerComps) desc.lastAppliedComp = layerComps.lastApplied;
|
|
620
|
+
|
|
621
|
+
// console.log('CompList', require('util').inspect(desc, false, 99, true));
|
|
622
|
+
writeVersionAndDescriptor(writer, '', 'CompList', desc);
|
|
623
|
+
},
|
|
624
|
+
);
|
|
625
|
+
|
|
569
626
|
MOCK_HANDLERS && addHandler(
|
|
570
627
|
1092, // ???
|
|
571
628
|
target => (target as any)._ir1092 !== undefined,
|
package/src/psd.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const enum SectionDividerType {
|
|
|
24
24
|
|
|
25
25
|
export type RGBA = { r: number; g: number; b: number; a: number; }; // values from 0 to 255
|
|
26
26
|
export type RGB = { r: number; g: number; b: number; }; // values from 0 to 255
|
|
27
|
-
export type FRGB = { fr: number; fg: number; fb: number; }; // values from 0 to 1 (can be above 1)
|
|
27
|
+
export type FRGB = { fr: number; fg: number; fb: number; }; // values from 0 to 1 (can be above 1, can be negative)
|
|
28
28
|
export type HSB = { h: number; s: number; b: number; }; // values from 0 to 1
|
|
29
29
|
export type CMYK = { c: number; m: number; y: number; k: number; }; // values from 0 to 255
|
|
30
30
|
export type LAB = { l: number; a: number; b: number; }; // values `l` from 0 to 1; `a` and `b` from -1 to 1
|
|
@@ -222,6 +222,14 @@ export interface LayerEffectsInfo {
|
|
|
222
222
|
patternOverlay?: LayerEffectPatternOverlay; // not supported yet because of `Patt` section not implemented
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
+
export type PixelArray = Uint8ClampedArray | Uint8Array | Uint16Array | Float32Array;
|
|
226
|
+
|
|
227
|
+
export interface PixelData {
|
|
228
|
+
data: PixelArray; // type depends on document bit depth
|
|
229
|
+
width: number;
|
|
230
|
+
height: number;
|
|
231
|
+
}
|
|
232
|
+
|
|
225
233
|
export interface LayerMaskData {
|
|
226
234
|
top?: number;
|
|
227
235
|
left?: number;
|
|
@@ -236,7 +244,7 @@ export interface LayerMaskData {
|
|
|
236
244
|
vectorMaskDensity?: number;
|
|
237
245
|
vectorMaskFeather?: number;
|
|
238
246
|
canvas?: HTMLCanvasElement;
|
|
239
|
-
imageData?:
|
|
247
|
+
imageData?: PixelData;
|
|
240
248
|
}
|
|
241
249
|
|
|
242
250
|
export type TextGridding = 'none' | 'round'; // TODO: other values (no idea where to set it up in Photoshop)
|
|
@@ -416,7 +424,6 @@ export interface LayerTextData {
|
|
|
416
424
|
shapeType?: 'point' | 'box';
|
|
417
425
|
pointBase?: number[];
|
|
418
426
|
boxBounds?: number[];
|
|
419
|
-
|
|
420
427
|
bounds?: UnitsBounds;
|
|
421
428
|
boundingBox?: UnitsBounds;
|
|
422
429
|
}
|
|
@@ -1385,12 +1392,32 @@ export interface LayerAdditionalInfo {
|
|
|
1385
1392
|
data: Uint8Array;
|
|
1386
1393
|
};
|
|
1387
1394
|
}[];
|
|
1395
|
+
comps?: {
|
|
1396
|
+
originalEffectsReferencePoint?: { x: number; y: number; };
|
|
1397
|
+
settings: {
|
|
1398
|
+
enabled?: boolean;
|
|
1399
|
+
compList: number[];
|
|
1400
|
+
offset?: { x: number; y: number; };
|
|
1401
|
+
effectsReferencePoint?: { x: number; y: number; };
|
|
1402
|
+
}[];
|
|
1403
|
+
};
|
|
1404
|
+
userMask?: {
|
|
1405
|
+
colorSpace: Color;
|
|
1406
|
+
opacity: number;
|
|
1407
|
+
};
|
|
1388
1408
|
|
|
1389
1409
|
// Base64 encoded raw EngineData, currently just kept in original state to support
|
|
1390
1410
|
// loading and modifying PSD file without breaking text layers.
|
|
1391
1411
|
engineData?: string;
|
|
1392
1412
|
}
|
|
1393
1413
|
|
|
1414
|
+
export enum LayerCompCapturedInfo {
|
|
1415
|
+
None = 0,
|
|
1416
|
+
Visibility = 1,
|
|
1417
|
+
Position = 2,
|
|
1418
|
+
Appearance = 4,
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1394
1421
|
export interface ImageResources {
|
|
1395
1422
|
layerState?: number;
|
|
1396
1423
|
layersGroup?: number[];
|
|
@@ -1564,6 +1591,15 @@ export interface ImageResources {
|
|
|
1564
1591
|
rightOutset?: number;
|
|
1565
1592
|
}[];
|
|
1566
1593
|
}[];
|
|
1594
|
+
layerComps?: {
|
|
1595
|
+
list: {
|
|
1596
|
+
id: number;
|
|
1597
|
+
name: string;
|
|
1598
|
+
comment?: string;
|
|
1599
|
+
capturedInfo: LayerCompCapturedInfo;
|
|
1600
|
+
}[];
|
|
1601
|
+
lastApplied?: number;
|
|
1602
|
+
};
|
|
1567
1603
|
}
|
|
1568
1604
|
|
|
1569
1605
|
export interface GlobalLayerMaskInfo {
|
|
@@ -1600,7 +1636,7 @@ export interface Layer extends LayerAdditionalInfo {
|
|
|
1600
1636
|
hidden?: boolean;
|
|
1601
1637
|
clipping?: boolean;
|
|
1602
1638
|
canvas?: HTMLCanvasElement;
|
|
1603
|
-
imageData?:
|
|
1639
|
+
imageData?: PixelData;
|
|
1604
1640
|
children?: Layer[];
|
|
1605
1641
|
/** Applies only for layer groups. */
|
|
1606
1642
|
opened?: boolean;
|
|
@@ -1614,7 +1650,7 @@ export interface Psd extends LayerAdditionalInfo {
|
|
|
1614
1650
|
colorMode?: ColorMode;
|
|
1615
1651
|
children?: Layer[];
|
|
1616
1652
|
canvas?: HTMLCanvasElement;
|
|
1617
|
-
imageData?:
|
|
1653
|
+
imageData?: PixelData;
|
|
1618
1654
|
imageResources?: ImageResources;
|
|
1619
1655
|
linkedFiles?: LinkedFile[]; // used in smart objects
|
|
1620
1656
|
artboards?: {
|