ag-psd 32.0.0 → 33.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.v8-cache/v24.7.0-x64-ef5a0af0/03e19709 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/1130885f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/2a19133e +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/cff9434a +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6745c2b +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/e6b99945 +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/eeeebdfe +0 -0
- package/.v8-cache/v24.7.0-x64-ef5a0af0/f6fd8125 +0 -0
- package/CHANGELOG.md +78 -0
- package/LICENSE +5 -0
- package/README.md +3 -6
- package/README_PSD.md +242 -81
- package/dist/abr.d.ts +11 -4
- package/dist/abr.js +357 -230
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.d.ts +54 -2
- package/dist/additionalInfo.js +487 -306
- package/dist/additionalInfo.js.map +1 -1
- package/dist/ase.d.ts +6 -1
- package/dist/ase.js +61 -61
- package/dist/ase.js.map +1 -1
- package/dist/bundle.js +1937 -1115
- package/dist/descriptor.d.ts +14 -8
- package/dist/descriptor.js +202 -186
- package/dist/descriptor.js.map +1 -1
- package/dist/helpers.d.ts +1 -1
- package/dist/helpers.js +4 -2
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.d.ts +15 -3
- package/dist/imageResources.js +503 -142
- package/dist/imageResources.js.map +1 -1
- package/dist/jpeg.js +8 -8
- package/dist/jpeg.js.map +1 -1
- package/dist/psd.d.ts +148 -17
- package/dist/psd.js.map +1 -1
- package/dist/psdReader.d.ts +10 -0
- package/dist/psdReader.js +278 -166
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +1 -0
- package/dist/psdWriter.js +77 -62
- package/dist/psdWriter.js.map +1 -1
- package/dist/text.js +17 -6
- package/dist/text.js.map +1 -1
- package/dist/utf8.js +0 -3
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.d.ts +11 -4
- package/dist-es/abr.js +357 -230
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +54 -2
- package/dist-es/additionalInfo.js +487 -306
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/ase.d.ts +6 -1
- package/dist-es/ase.js +61 -61
- package/dist-es/ase.js.map +1 -1
- package/dist-es/descriptor.d.ts +14 -8
- package/dist-es/descriptor.js +202 -186
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/helpers.d.ts +1 -1
- package/dist-es/helpers.js +4 -2
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.d.ts +15 -3
- package/dist-es/imageResources.js +503 -142
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/jpeg.js +8 -8
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psd.d.ts +148 -17
- package/dist-es/psd.js.map +1 -1
- package/dist-es/psdReader.d.ts +10 -0
- package/dist-es/psdReader.js +278 -166
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +1 -0
- package/dist-es/psdWriter.js +77 -62
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/text.js +17 -6
- package/dist-es/text.js.map +1 -1
- package/dist-es/utf8.js +0 -3
- package/dist-es/utf8.js.map +1 -1
- package/package.json +2 -2
- package/src/abr.ts +375 -235
- package/src/additionalInfo.ts +663 -420
- package/src/ase.ts +66 -61
- package/src/descriptor.ts +199 -195
- package/src/helpers.ts +4 -1
- package/src/imageResources.ts +632 -168
- package/src/jpeg.ts +8 -8
- package/src/psd.ts +156 -30
- package/src/psdReader.ts +273 -172
- package/src/psdWriter.ts +95 -58
- package/src/text.ts +17 -6
- package/src/utf8.ts +0 -4
package/dist/abr.d.ts
CHANGED
|
@@ -85,6 +85,7 @@ interface DynamicBrushShape {
|
|
|
85
85
|
}
|
|
86
86
|
export interface Brush {
|
|
87
87
|
name: string;
|
|
88
|
+
group?: string[];
|
|
88
89
|
shape: BrushShape;
|
|
89
90
|
shapeDynamics?: {
|
|
90
91
|
sizeDynamics: BrushDynamics;
|
|
@@ -138,8 +139,8 @@ export interface Brush {
|
|
|
138
139
|
transfer?: {
|
|
139
140
|
flowDynamics: BrushDynamics;
|
|
140
141
|
opacityDynamics: BrushDynamics;
|
|
141
|
-
wetnessDynamics
|
|
142
|
-
mixDynamics
|
|
142
|
+
wetnessDynamics?: BrushDynamics;
|
|
143
|
+
mixDynamics?: BrushDynamics;
|
|
143
144
|
};
|
|
144
145
|
brushPose?: {
|
|
145
146
|
overrideAngle: boolean;
|
|
@@ -153,6 +154,7 @@ export interface Brush {
|
|
|
153
154
|
};
|
|
154
155
|
noise: boolean;
|
|
155
156
|
wetEdges: boolean;
|
|
157
|
+
buildUp: boolean;
|
|
156
158
|
protectTexture?: boolean;
|
|
157
159
|
spacing: number;
|
|
158
160
|
brushGroup?: undefined;
|
|
@@ -190,7 +192,12 @@ export interface Brush {
|
|
|
190
192
|
strength?: number;
|
|
191
193
|
};
|
|
192
194
|
}
|
|
193
|
-
export
|
|
195
|
+
export interface ReadAbrOptions {
|
|
194
196
|
logMissingFeatures?: boolean;
|
|
195
|
-
|
|
197
|
+
/** Throw on unsupported or invalid parts of the file instead of skipping them */
|
|
198
|
+
throwForMissingFeatures?: boolean;
|
|
199
|
+
/** Memory limit for decoded data in bytes (2GB by default), set to `undefined` explicitly to disable */
|
|
200
|
+
totalMemoryLimit?: number;
|
|
201
|
+
}
|
|
202
|
+
export declare function readAbr(buffer: ArrayBufferView, options?: ReadAbrOptions): Abr;
|
|
196
203
|
export {};
|
package/dist/abr.js
CHANGED
|
@@ -98,261 +98,92 @@ function parseHeightmap(array) {
|
|
|
98
98
|
// return result;
|
|
99
99
|
}
|
|
100
100
|
function readAbr(buffer, options = {}) {
|
|
101
|
-
var _a, _b, _c, _d;
|
|
102
101
|
const reader = (0, psdReader_1.createReader)(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
102
|
+
reader.logMissingFeatures = options.logMissingFeatures;
|
|
103
|
+
reader.throwForMissingFeatures = options.throwForMissingFeatures;
|
|
104
|
+
reader.totalMemoryLimit = 'totalMemoryLimit' in options ? options.totalMemoryLimit : 2 * 1024 * 1024 * 1024;
|
|
105
|
+
// skips invalid or unsupported part of the file
|
|
106
|
+
const skip = (e, what) => {
|
|
107
|
+
if (options.throwForMissingFeatures)
|
|
108
|
+
throw e;
|
|
109
|
+
options.logMissingFeatures && reader.log(`Skipped ${what}: ${e.message}`);
|
|
110
|
+
};
|
|
111
|
+
if (reader.view.byteLength < 4)
|
|
112
|
+
throw new Error('Invalid ABR file');
|
|
103
113
|
const version = (0, psdReader_1.readInt16)(reader);
|
|
104
114
|
const samples = [];
|
|
105
115
|
const brushes = [];
|
|
106
116
|
const patterns = [];
|
|
117
|
+
const brushByPreset = []; // brush for each preset in 'desc' section (brushes that fail to parse are skipped)
|
|
118
|
+
let hierarchy;
|
|
107
119
|
if (version === 1 || version === 2) {
|
|
108
|
-
|
|
120
|
+
readLegacyBrushes(reader, version, samples, brushes, skip);
|
|
109
121
|
}
|
|
110
122
|
else if (version === 6 || version === 7 || version === 9 || version === 10) {
|
|
111
123
|
const minorVersion = (0, psdReader_1.readInt16)(reader);
|
|
112
124
|
if (minorVersion !== 1 && minorVersion !== 2)
|
|
113
125
|
throw new Error('Unsupported ABR minor version');
|
|
114
|
-
|
|
126
|
+
// section header is 12 bytes, ignore any shorter trailing data
|
|
127
|
+
while (reader.offset + 12 <= reader.view.byteLength) {
|
|
115
128
|
(0, psdReader_1.checkSignature)(reader, '8BIM');
|
|
116
129
|
const type = (0, psdReader_1.readSignature)(reader);
|
|
117
130
|
const size = (0, psdReader_1.readUint32)(reader);
|
|
118
|
-
const end = reader.offset + size;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
brushLength
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
const y = (0, psdReader_1.readInt32)(reader);
|
|
131
|
-
const x = (0, psdReader_1.readInt32)(reader);
|
|
132
|
-
const h = (0, psdReader_1.readInt32)(reader) - y;
|
|
133
|
-
const w = (0, psdReader_1.readInt32)(reader) - x;
|
|
134
|
-
if (w <= 0 || h <= 0)
|
|
135
|
-
throw new Error('Invalid bounds');
|
|
136
|
-
if (w > MAX_BRUSH_SIZE || h > MAX_BRUSH_SIZE) {
|
|
137
|
-
throw new Error(`Brush sample too large (${w}x${h})`);
|
|
138
|
-
}
|
|
139
|
-
const bithDepth = (0, psdReader_1.readInt16)(reader);
|
|
140
|
-
const compression = (0, psdReader_1.readUint8)(reader); // 0 - raw, 1 - RLE
|
|
141
|
-
if (compression === 0 && w * h * (bithDepth === 16 ? 2 : 1) > brushEnd - reader.offset) {
|
|
142
|
-
throw new Error('Brush sample data out of bounds');
|
|
143
|
-
}
|
|
144
|
-
const alpha = new Uint8Array(w * h);
|
|
145
|
-
if (bithDepth === 8) {
|
|
146
|
-
if (compression === 0) {
|
|
147
|
-
alpha.set((0, psdReader_1.readBytes)(reader, alpha.byteLength));
|
|
148
|
-
}
|
|
149
|
-
else if (compression === 1) {
|
|
150
|
-
(0, psdReader_1.readDataRLE)(reader, { width: w, height: h, data: alpha }, w, h, bithDepth, 1, [0], false);
|
|
131
|
+
const end = Math.min(reader.offset + size, reader.view.byteLength);
|
|
132
|
+
try {
|
|
133
|
+
switch (type) {
|
|
134
|
+
case 'samp': {
|
|
135
|
+
while (reader.offset + 4 <= end) {
|
|
136
|
+
let brushLength = (0, psdReader_1.readUint32)(reader);
|
|
137
|
+
while (brushLength & 0b11)
|
|
138
|
+
brushLength++; // pad to 4 byte alignment
|
|
139
|
+
const brushEnd = Math.min(reader.offset + brushLength, end);
|
|
140
|
+
try {
|
|
141
|
+
const sample = readSample(reader, brushEnd, minorVersion);
|
|
142
|
+
samples.push(sample);
|
|
151
143
|
}
|
|
152
|
-
|
|
153
|
-
|
|
144
|
+
catch (e) {
|
|
145
|
+
skip(e, 'brush sample');
|
|
154
146
|
}
|
|
147
|
+
reader.offset = brushEnd;
|
|
155
148
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case 'desc': {
|
|
152
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
|
|
153
|
+
for (const [index, brush] of (desc.Brsh || []).entries()) {
|
|
154
|
+
try {
|
|
155
|
+
const parsed = parseBrush(brush);
|
|
156
|
+
brushes.push(parsed);
|
|
157
|
+
brushByPreset[index] = parsed;
|
|
164
158
|
}
|
|
165
|
-
|
|
166
|
-
|
|
159
|
+
catch (e) {
|
|
160
|
+
skip(e, `brush "${brush['Nm ']}"`);
|
|
167
161
|
}
|
|
168
162
|
}
|
|
169
|
-
|
|
170
|
-
throw new Error('Invalid depth');
|
|
171
|
-
}
|
|
172
|
-
samples.push({ id, bounds: { x, y, w, h }, alpha });
|
|
173
|
-
reader.offset = brushEnd;
|
|
163
|
+
break;
|
|
174
164
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// require('fs').writeFileSync('test.log', require('util').inspect(desc, false, 99, false), 'utf8');
|
|
181
|
-
for (const brush of desc.Brsh) {
|
|
182
|
-
const b = {
|
|
183
|
-
name: brush['Nm '],
|
|
184
|
-
shape: parseBrushShape(brush.Brsh),
|
|
185
|
-
spacing: (0, descriptor_1.parsePercent)(brush.Spcn),
|
|
186
|
-
// TODO: brushGroup ???
|
|
187
|
-
wetEdges: brush.Wtdg,
|
|
188
|
-
noise: brush.Nose,
|
|
189
|
-
// TODO: TxtC ??? smoothing / build-up ?
|
|
190
|
-
// TODO: 'Rpt ' ???
|
|
191
|
-
useBrushSize: brush.useBrushSize, // ???
|
|
192
|
-
};
|
|
193
|
-
if (brush.interpretation != null)
|
|
194
|
-
b.interpretation = brush.interpretation;
|
|
195
|
-
if (brush.protectTexture != null)
|
|
196
|
-
b.protectTexture = brush.protectTexture;
|
|
197
|
-
if (brush.useTipDynamics) {
|
|
198
|
-
b.shapeDynamics = {
|
|
199
|
-
tiltScale: (0, descriptor_1.parsePercent)(brush.tiltScale),
|
|
200
|
-
sizeDynamics: parseDynamics(brush.szVr),
|
|
201
|
-
angleDynamics: parseDynamics(brush.angleDynamics),
|
|
202
|
-
roundnessDynamics: parseDynamics(brush.roundnessDynamics),
|
|
203
|
-
flipX: brush.flipX,
|
|
204
|
-
flipY: brush.flipY,
|
|
205
|
-
brushProjection: brush.brushProjection,
|
|
206
|
-
minimumDiameter: (0, descriptor_1.parsePercent)(brush.minimumDiameter),
|
|
207
|
-
minimumRoundness: (0, descriptor_1.parsePercent)(brush.minimumRoundness),
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
if (brush.useScatter) {
|
|
211
|
-
b.scatter = {
|
|
212
|
-
count: brush['Cnt '],
|
|
213
|
-
bothAxes: brush.bothAxes,
|
|
214
|
-
countDynamics: parseDynamics(brush.countDynamics),
|
|
215
|
-
scatterDynamics: parseDynamics(brush.scatterDynamics),
|
|
216
|
-
};
|
|
217
|
-
}
|
|
218
|
-
if (brush.useTexture && brush.Txtr) {
|
|
219
|
-
b.texture = {
|
|
220
|
-
id: brush.Txtr.Idnt,
|
|
221
|
-
name: brush.Txtr['Nm '],
|
|
222
|
-
blendMode: descriptor_1.BlnM.decode(brush.textureBlendMode),
|
|
223
|
-
depth: (0, descriptor_1.parsePercent)(brush.textureDepth),
|
|
224
|
-
depthMinimum: (0, descriptor_1.parsePercent)(brush.minimumDepth),
|
|
225
|
-
depthDynamics: parseDynamics(brush.textureDepthDynamics),
|
|
226
|
-
scale: (0, descriptor_1.parsePercent)(brush.textureScale),
|
|
227
|
-
invert: brush.InvT,
|
|
228
|
-
brightness: brush.textureBrightness,
|
|
229
|
-
contrast: brush.textureContrast,
|
|
230
|
-
textureEachTip: !!brush.TxtC,
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
const db = brush.dualBrush;
|
|
234
|
-
if (db && db.useDualBrush) {
|
|
235
|
-
b.dualBrush = {
|
|
236
|
-
flip: db.Flip,
|
|
237
|
-
shape: parseBrushShape(db.Brsh),
|
|
238
|
-
blendMode: descriptor_1.BlnM.decode(db.BlnM),
|
|
239
|
-
useScatter: db.useScatter,
|
|
240
|
-
spacing: (0, descriptor_1.parsePercent)(db.Spcn),
|
|
241
|
-
count: db['Cnt '],
|
|
242
|
-
bothAxes: db.bothAxes,
|
|
243
|
-
countDynamics: parseDynamics(db.countDynamics),
|
|
244
|
-
scatterDynamics: parseDynamics(db.scatterDynamics),
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
if (brush.useColorDynamics) {
|
|
248
|
-
b.colorDynamics = {
|
|
249
|
-
foregroundBackground: parseDynamics(brush.clVr),
|
|
250
|
-
hue: (0, descriptor_1.parsePercent)(brush['H ']),
|
|
251
|
-
saturation: (0, descriptor_1.parsePercent)(brush.Strt),
|
|
252
|
-
brightness: (0, descriptor_1.parsePercent)(brush.Brgh),
|
|
253
|
-
purity: (0, descriptor_1.parsePercent)(brush.purity),
|
|
254
|
-
perTip: brush.colorDynamicsPerTip,
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
if (brush.usePaintDynamics) {
|
|
258
|
-
b.transfer = {
|
|
259
|
-
flowDynamics: parseDynamics(brush.prVr),
|
|
260
|
-
opacityDynamics: parseDynamics(brush.opVr),
|
|
261
|
-
wetnessDynamics: parseDynamics(brush.wtVr),
|
|
262
|
-
mixDynamics: parseDynamics(brush.mxVr),
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
if (brush.useBrushPose) {
|
|
266
|
-
b.brushPose = {
|
|
267
|
-
overrideAngle: brush.overridePoseAngle,
|
|
268
|
-
overrideTiltX: brush.overridePoseTiltX,
|
|
269
|
-
overrideTiltY: brush.overridePoseTiltY,
|
|
270
|
-
overridePressure: brush.overridePosePressure,
|
|
271
|
-
pressure: (0, descriptor_1.parsePercent)(brush.brushPosePressure),
|
|
272
|
-
tiltX: brush.brushPoseTiltX,
|
|
273
|
-
tiltY: brush.brushPoseTiltY,
|
|
274
|
-
angle: brush.brushPoseAngle,
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
const to = brush.toolOptions;
|
|
278
|
-
if (to) {
|
|
279
|
-
b.toolOptions = {
|
|
280
|
-
type: toBrushType[to._classID] || 'brush',
|
|
281
|
-
brushPreset: to.brushPreset,
|
|
282
|
-
flow: (_a = to.flow) !== null && _a !== void 0 ? _a : 100,
|
|
283
|
-
smooth: (_b = to.Smoo) !== null && _b !== void 0 ? _b : 0,
|
|
284
|
-
mode: descriptor_1.BlnM.decode(to['Md '] || 'BlnM.Nrml'), // sometimes mode is missing
|
|
285
|
-
opacity: (_c = to.Opct) !== null && _c !== void 0 ? _c : 100,
|
|
286
|
-
smoothing: !!to.smoothing,
|
|
287
|
-
smoothingValue: to.smoothingValue || 0,
|
|
288
|
-
smoothingRadiusMode: !!to.smoothingRadiusMode,
|
|
289
|
-
smoothingCatchup: !!to.smoothingCatchup,
|
|
290
|
-
smoothingCatchupAtEnd: !!to.smoothingCatchupAtEnd,
|
|
291
|
-
smoothingZoomCompensation: !!to.smoothingZoomCompensation,
|
|
292
|
-
pressureSmoothing: !!to.pressureSmoothing,
|
|
293
|
-
usePressureOverridesSize: !!to.usePressureOverridesSize,
|
|
294
|
-
usePressureOverridesOpacity: !!to.usePressureOverridesOpacity,
|
|
295
|
-
useLegacy: !!to.useLegacy,
|
|
296
|
-
};
|
|
297
|
-
if (to.prVr)
|
|
298
|
-
b.toolOptions.flowDynamics = parseDynamics(to.prVr);
|
|
299
|
-
if (to.opVr)
|
|
300
|
-
b.toolOptions.opacityDynamics = parseDynamics(to.opVr);
|
|
301
|
-
if (to.szVr)
|
|
302
|
-
b.toolOptions.sizeDynamics = parseDynamics(to.szVr);
|
|
303
|
-
if ('wetness' in to)
|
|
304
|
-
b.toolOptions.wetness = to.wetness;
|
|
305
|
-
if ('dryness' in to)
|
|
306
|
-
b.toolOptions.dryness = to.dryness;
|
|
307
|
-
if ('mix' in to)
|
|
308
|
-
b.toolOptions.mix = to.mix;
|
|
309
|
-
if ('autoFill' in to)
|
|
310
|
-
b.toolOptions.autoFill = to.autoFill;
|
|
311
|
-
if ('autoClean' in to)
|
|
312
|
-
b.toolOptions.autoClean = to.autoClean;
|
|
313
|
-
if ('loadSolidColorOnly' in to)
|
|
314
|
-
b.toolOptions.loadSolidColorOnly = to.loadSolidColorOnly;
|
|
315
|
-
if ('sampleAllLayers' in to)
|
|
316
|
-
b.toolOptions.sampleAllLayers = to.sampleAllLayers;
|
|
317
|
-
if ('SmdF' in to)
|
|
318
|
-
b.toolOptions.smudgeFingerPainting = to.SmdF;
|
|
319
|
-
if ('SmdS' in to)
|
|
320
|
-
b.toolOptions.smudgeSampleAllLayers = to.SmdS;
|
|
321
|
-
if ('Prs ' in to)
|
|
322
|
-
b.toolOptions.strength = to['Prs '];
|
|
165
|
+
case 'patt': {
|
|
166
|
+
while (reader.offset + 4 <= end) {
|
|
167
|
+
const pattern = (0, psdReader_1.readPatternSafe)(reader);
|
|
168
|
+
if (pattern)
|
|
169
|
+
patterns.push(pattern);
|
|
323
170
|
}
|
|
324
|
-
|
|
171
|
+
break;
|
|
325
172
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
}
|
|
332
|
-
reader.offset = end;
|
|
333
|
-
break;
|
|
334
|
-
}
|
|
335
|
-
case 'phry': {
|
|
336
|
-
// TODO: what is this ?
|
|
337
|
-
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader);
|
|
338
|
-
// example:
|
|
339
|
-
// hierarchy: [
|
|
340
|
-
// {
|
|
341
|
-
// 'Nm ': 'PRE_EXPORT ',
|
|
342
|
-
// zuid: '965209f2-6f35-9a40-aa43-485684382172'
|
|
343
|
-
// },
|
|
344
|
-
// {},
|
|
345
|
-
// ...
|
|
346
|
-
// ]
|
|
347
|
-
if (options.logMissingFeatures) {
|
|
348
|
-
if ((_d = desc.hierarchy) === null || _d === void 0 ? void 0 : _d.length) {
|
|
349
|
-
// console.log('unhandled phry section', desc);
|
|
350
|
-
}
|
|
173
|
+
case 'phry': { // brush groups (folders in brushes panel)
|
|
174
|
+
// flat list of group starts, presets (in the same order as in 'desc' section) and group ends
|
|
175
|
+
const desc = (0, descriptor_1.readVersionAndDescriptor)(reader, true);
|
|
176
|
+
hierarchy = desc.hierarchy;
|
|
177
|
+
break;
|
|
351
178
|
}
|
|
352
|
-
|
|
179
|
+
default:
|
|
180
|
+
// 'lPdc' (tool presets) and other unknown sections
|
|
181
|
+
options.logMissingFeatures && reader.log(`Unhandled brush section: ${type}`);
|
|
182
|
+
break;
|
|
353
183
|
}
|
|
354
|
-
|
|
355
|
-
|
|
184
|
+
}
|
|
185
|
+
catch (e) {
|
|
186
|
+
skip(e, `brush section ${type}`);
|
|
356
187
|
}
|
|
357
188
|
// skip any unread data in the section and align to 4 bytes
|
|
358
189
|
reader.offset = end;
|
|
@@ -363,6 +194,302 @@ function readAbr(buffer, options = {}) {
|
|
|
363
194
|
else {
|
|
364
195
|
throw new Error(`Unsupported ABR version (${version})`);
|
|
365
196
|
}
|
|
197
|
+
if (hierarchy) {
|
|
198
|
+
const groups = [];
|
|
199
|
+
let presetIndex = 0;
|
|
200
|
+
for (const item of hierarchy) {
|
|
201
|
+
if (item._classID === 'Grup') {
|
|
202
|
+
groups.push(item['Nm ']);
|
|
203
|
+
}
|
|
204
|
+
else if (item._classID === 'groupEnd') {
|
|
205
|
+
groups.pop();
|
|
206
|
+
}
|
|
207
|
+
else if (item._classID === 'preset') {
|
|
208
|
+
const brush = brushByPreset[presetIndex];
|
|
209
|
+
if (brush && groups.length)
|
|
210
|
+
brush.group = groups.slice();
|
|
211
|
+
presetIndex++;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
366
215
|
return { samples, patterns, brushes };
|
|
367
216
|
}
|
|
217
|
+
function readSample(reader, brushEnd, minorVersion) {
|
|
218
|
+
const id = (0, psdReader_1.readPascalString)(reader, 1);
|
|
219
|
+
// v1 - Skip the Int16 bounds rectangle and the unknown Int16.
|
|
220
|
+
// v2 - Skip the unknown bytes.
|
|
221
|
+
(0, psdReader_1.skipBytes)(reader, minorVersion === 1 ? 10 : 264);
|
|
222
|
+
return readSampleBitmap(reader, brushEnd, id);
|
|
223
|
+
}
|
|
224
|
+
// bounds, bit depth, compression and image data of brush sample
|
|
225
|
+
function readSampleBitmap(reader, brushEnd, id) {
|
|
226
|
+
const y = (0, psdReader_1.readInt32)(reader);
|
|
227
|
+
const x = (0, psdReader_1.readInt32)(reader);
|
|
228
|
+
const h = (0, psdReader_1.readInt32)(reader) - y;
|
|
229
|
+
const w = (0, psdReader_1.readInt32)(reader) - x;
|
|
230
|
+
if (w <= 0 || h <= 0)
|
|
231
|
+
throw new Error('Invalid bounds');
|
|
232
|
+
if (w > MAX_BRUSH_SIZE || h > MAX_BRUSH_SIZE) {
|
|
233
|
+
throw new Error(`Brush sample too large (${w}x${h})`);
|
|
234
|
+
}
|
|
235
|
+
const bithDepth = (0, psdReader_1.readInt16)(reader);
|
|
236
|
+
const compression = (0, psdReader_1.readUint8)(reader); // 0 - raw, 1 - RLE
|
|
237
|
+
if (bithDepth !== 8 && bithDepth !== 16)
|
|
238
|
+
throw new Error('Invalid depth');
|
|
239
|
+
if (compression !== 0 && compression !== 1)
|
|
240
|
+
throw new Error('Invalid compression');
|
|
241
|
+
const rowSize = w * (bithDepth === 16 ? 2 : 1);
|
|
242
|
+
// RLE needs at least 2 bytes for row length and 2 bytes per each 128 byte run
|
|
243
|
+
const minDataSize = compression === 0 ? h * rowSize : h * (2 + Math.ceil(rowSize / 128) * 2);
|
|
244
|
+
if (minDataSize > brushEnd - reader.offset) {
|
|
245
|
+
throw new Error('Brush sample data out of bounds');
|
|
246
|
+
}
|
|
247
|
+
(0, psdReader_1.consumeMemory)(reader, w * h * (compression === 1 && bithDepth === 16 ? 3 : 1));
|
|
248
|
+
const alpha = new Uint8Array(w * h);
|
|
249
|
+
if (bithDepth === 8) {
|
|
250
|
+
if (compression === 0) {
|
|
251
|
+
alpha.set((0, psdReader_1.readBytes)(reader, alpha.byteLength));
|
|
252
|
+
}
|
|
253
|
+
else if (compression === 1) {
|
|
254
|
+
(0, psdReader_1.readDataRLE)(reader, { width: w, height: h, data: alpha }, w, h, bithDepth, 1, [0], false);
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
throw new Error('Invalid compression');
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (bithDepth === 16) {
|
|
261
|
+
if (compression === 0) {
|
|
262
|
+
for (let i = 0; i < alpha.byteLength; i++) {
|
|
263
|
+
alpha[i] = (0, psdReader_1.readUint16)(reader) >> 8; // convert to 8bit values
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
else if (compression === 1) {
|
|
267
|
+
const data = new Uint16Array(w * h);
|
|
268
|
+
(0, psdReader_1.readDataRLE)(reader, { width: w, height: h, data }, w, h, bithDepth, 1, [0], false);
|
|
269
|
+
for (let i = 0; i < alpha.byteLength; i++) {
|
|
270
|
+
alpha[i] = data[i] >> 8; // convert to 8bit values
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
throw new Error('Invalid compression');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
throw new Error('Invalid depth');
|
|
279
|
+
}
|
|
280
|
+
return { id, bounds: { x, y, w, h }, alpha };
|
|
281
|
+
}
|
|
282
|
+
// ABR versions 1 and 2 (Photoshop 6 and earlier) contain a list of brushes with brush tips in them
|
|
283
|
+
function readLegacyBrushes(reader, version, samples, brushes, skip) {
|
|
284
|
+
const count = (0, psdReader_1.readUint16)(reader);
|
|
285
|
+
for (let i = 0; i < count; i++) {
|
|
286
|
+
const type = (0, psdReader_1.readUint16)(reader);
|
|
287
|
+
const size = (0, psdReader_1.readUint32)(reader);
|
|
288
|
+
const end = reader.offset + size;
|
|
289
|
+
if (end > reader.view.byteLength) { // truncated file
|
|
290
|
+
skip(new Error('Brush data out of bounds'), `brush ${i + 1}`);
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
if (type === 1) { // computed brush
|
|
295
|
+
(0, psdReader_1.skipBytes)(reader, 4); // misc
|
|
296
|
+
const spacing = (0, psdReader_1.readUint16)(reader);
|
|
297
|
+
const diameter = (0, psdReader_1.readUint16)(reader);
|
|
298
|
+
const roundness = (0, psdReader_1.readUint16)(reader);
|
|
299
|
+
const angle = (0, psdReader_1.readInt16)(reader);
|
|
300
|
+
const hardness = (0, psdReader_1.readUint16)(reader);
|
|
301
|
+
if (reader.offset > end)
|
|
302
|
+
throw new Error('Brush data out of bounds');
|
|
303
|
+
brushes.push(createLegacyBrush('', {
|
|
304
|
+
type: 'computed',
|
|
305
|
+
size: diameter,
|
|
306
|
+
angle,
|
|
307
|
+
roundness: roundness / 100,
|
|
308
|
+
spacingOn: spacing !== 0,
|
|
309
|
+
spacing: spacing / 100,
|
|
310
|
+
flipX: false,
|
|
311
|
+
flipY: false,
|
|
312
|
+
hardness: hardness / 100,
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
else if (type === 2) { // sampled brush
|
|
316
|
+
(0, psdReader_1.skipBytes)(reader, 4); // misc
|
|
317
|
+
const spacing = (0, psdReader_1.readUint16)(reader);
|
|
318
|
+
const name = version === 2 ? (0, psdReader_1.readUnicodeString)(reader) : '';
|
|
319
|
+
(0, psdReader_1.skipBytes)(reader, 1 + 8); // antialiasing, Int16 bounds rectangle (same as Int32 one)
|
|
320
|
+
// legacy brushes don't have sample ids
|
|
321
|
+
const sample = readSampleBitmap(reader, end, `brush-${i + 1}`);
|
|
322
|
+
samples.push(sample);
|
|
323
|
+
brushes.push(createLegacyBrush(name, {
|
|
324
|
+
type: 'sampled',
|
|
325
|
+
size: Math.max(sample.bounds.w, sample.bounds.h),
|
|
326
|
+
angle: 0,
|
|
327
|
+
roundness: 1,
|
|
328
|
+
spacingOn: spacing !== 0,
|
|
329
|
+
spacing: spacing / 100,
|
|
330
|
+
flipX: false,
|
|
331
|
+
flipY: false,
|
|
332
|
+
name,
|
|
333
|
+
sampledData: sample.id,
|
|
334
|
+
}));
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
throw new Error(`Unknown brush type: ${type}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
catch (e) {
|
|
341
|
+
skip(e, `brush ${i + 1}`);
|
|
342
|
+
}
|
|
343
|
+
reader.offset = end;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function createLegacyBrush(name, shape) {
|
|
347
|
+
return { name, shape, spacing: 1, wetEdges: false, noise: false, buildUp: false, useBrushSize: true };
|
|
348
|
+
}
|
|
349
|
+
function parseBrush(brush) {
|
|
350
|
+
var _a, _b, _c;
|
|
351
|
+
const b = {
|
|
352
|
+
name: brush['Nm '],
|
|
353
|
+
shape: parseBrushShape(brush.Brsh),
|
|
354
|
+
spacing: (0, descriptor_1.parsePercent)(brush.Spcn),
|
|
355
|
+
wetEdges: brush.Wtdg,
|
|
356
|
+
noise: brush.Nose,
|
|
357
|
+
buildUp: !!brush['Rpt '],
|
|
358
|
+
useBrushSize: brush.useBrushSize, // ???
|
|
359
|
+
};
|
|
360
|
+
if (brush.interpretation != null)
|
|
361
|
+
b.interpretation = brush.interpretation;
|
|
362
|
+
if (brush.protectTexture != null)
|
|
363
|
+
b.protectTexture = brush.protectTexture;
|
|
364
|
+
if (brush.useTipDynamics) {
|
|
365
|
+
b.shapeDynamics = {
|
|
366
|
+
tiltScale: (0, descriptor_1.parsePercent)(brush.tiltScale),
|
|
367
|
+
sizeDynamics: parseDynamics(brush.szVr),
|
|
368
|
+
angleDynamics: parseDynamics(brush.angleDynamics),
|
|
369
|
+
roundnessDynamics: parseDynamics(brush.roundnessDynamics),
|
|
370
|
+
flipX: brush.flipX,
|
|
371
|
+
flipY: brush.flipY,
|
|
372
|
+
brushProjection: brush.brushProjection,
|
|
373
|
+
minimumDiameter: (0, descriptor_1.parsePercent)(brush.minimumDiameter),
|
|
374
|
+
minimumRoundness: (0, descriptor_1.parsePercent)(brush.minimumRoundness),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
if (brush.useScatter) {
|
|
378
|
+
b.scatter = {
|
|
379
|
+
count: brush['Cnt '],
|
|
380
|
+
bothAxes: brush.bothAxes,
|
|
381
|
+
countDynamics: parseDynamics(brush.countDynamics),
|
|
382
|
+
scatterDynamics: parseDynamics(brush.scatterDynamics),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
if (brush.useTexture && brush.Txtr) {
|
|
386
|
+
b.texture = {
|
|
387
|
+
id: brush.Txtr.Idnt,
|
|
388
|
+
name: brush.Txtr['Nm '],
|
|
389
|
+
blendMode: descriptor_1.BlnM.decode(brush.textureBlendMode),
|
|
390
|
+
depth: (0, descriptor_1.parsePercent)(brush.textureDepth),
|
|
391
|
+
depthMinimum: (0, descriptor_1.parsePercent)(brush.minimumDepth),
|
|
392
|
+
depthDynamics: parseDynamics(brush.textureDepthDynamics),
|
|
393
|
+
scale: (0, descriptor_1.parsePercent)(brush.textureScale),
|
|
394
|
+
invert: brush.InvT,
|
|
395
|
+
brightness: brush.textureBrightness,
|
|
396
|
+
contrast: brush.textureContrast,
|
|
397
|
+
textureEachTip: !!brush.TxtC,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
const db = brush.dualBrush;
|
|
401
|
+
if (db && db.useDualBrush) {
|
|
402
|
+
b.dualBrush = {
|
|
403
|
+
flip: db.Flip,
|
|
404
|
+
shape: parseBrushShape(db.Brsh),
|
|
405
|
+
blendMode: descriptor_1.BlnM.decode(db.BlnM),
|
|
406
|
+
useScatter: db.useScatter,
|
|
407
|
+
spacing: (0, descriptor_1.parsePercent)(db.Spcn),
|
|
408
|
+
count: db['Cnt '],
|
|
409
|
+
bothAxes: db.bothAxes,
|
|
410
|
+
countDynamics: parseDynamics(db.countDynamics),
|
|
411
|
+
scatterDynamics: parseDynamics(db.scatterDynamics),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
if (brush.useColorDynamics) {
|
|
415
|
+
b.colorDynamics = {
|
|
416
|
+
foregroundBackground: parseDynamics(brush.clVr),
|
|
417
|
+
hue: (0, descriptor_1.parsePercent)(brush['H ']),
|
|
418
|
+
saturation: (0, descriptor_1.parsePercent)(brush.Strt),
|
|
419
|
+
brightness: (0, descriptor_1.parsePercent)(brush.Brgh),
|
|
420
|
+
purity: (0, descriptor_1.parsePercent)(brush.purity),
|
|
421
|
+
perTip: brush.colorDynamicsPerTip,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
if (brush.usePaintDynamics) {
|
|
425
|
+
b.transfer = {
|
|
426
|
+
flowDynamics: parseDynamics(brush.prVr),
|
|
427
|
+
opacityDynamics: parseDynamics(brush.opVr),
|
|
428
|
+
};
|
|
429
|
+
if (brush.wtVr)
|
|
430
|
+
b.transfer.wetnessDynamics = parseDynamics(brush.wtVr);
|
|
431
|
+
if (brush.mxVr)
|
|
432
|
+
b.transfer.mixDynamics = parseDynamics(brush.mxVr);
|
|
433
|
+
}
|
|
434
|
+
if (brush.useBrushPose) {
|
|
435
|
+
b.brushPose = {
|
|
436
|
+
overrideAngle: brush.overridePoseAngle,
|
|
437
|
+
overrideTiltX: brush.overridePoseTiltX,
|
|
438
|
+
overrideTiltY: brush.overridePoseTiltY,
|
|
439
|
+
overridePressure: brush.overridePosePressure,
|
|
440
|
+
pressure: (0, descriptor_1.parsePercent)(brush.brushPosePressure),
|
|
441
|
+
tiltX: brush.brushPoseTiltX,
|
|
442
|
+
tiltY: brush.brushPoseTiltY,
|
|
443
|
+
angle: brush.brushPoseAngle,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
const to = brush.toolOptions;
|
|
447
|
+
if (to) {
|
|
448
|
+
b.toolOptions = {
|
|
449
|
+
type: toBrushType[to._classID] || 'brush',
|
|
450
|
+
brushPreset: to.brushPreset,
|
|
451
|
+
flow: (_a = to.flow) !== null && _a !== void 0 ? _a : 100,
|
|
452
|
+
smooth: (_b = to.Smoo) !== null && _b !== void 0 ? _b : 0,
|
|
453
|
+
mode: descriptor_1.BlnM.decode(to['Md '] || 'BlnM.Nrml'), // sometimes mode is missing
|
|
454
|
+
opacity: (_c = to.Opct) !== null && _c !== void 0 ? _c : 100,
|
|
455
|
+
smoothing: !!to.smoothing,
|
|
456
|
+
smoothingValue: to.smoothingValue || 0,
|
|
457
|
+
smoothingRadiusMode: !!to.smoothingRadiusMode,
|
|
458
|
+
smoothingCatchup: !!to.smoothingCatchup,
|
|
459
|
+
smoothingCatchupAtEnd: !!to.smoothingCatchupAtEnd,
|
|
460
|
+
smoothingZoomCompensation: !!to.smoothingZoomCompensation,
|
|
461
|
+
pressureSmoothing: !!to.pressureSmoothing,
|
|
462
|
+
usePressureOverridesSize: !!to.usePressureOverridesSize,
|
|
463
|
+
usePressureOverridesOpacity: !!to.usePressureOverridesOpacity,
|
|
464
|
+
useLegacy: !!to.useLegacy,
|
|
465
|
+
};
|
|
466
|
+
if (to.prVr)
|
|
467
|
+
b.toolOptions.flowDynamics = parseDynamics(to.prVr);
|
|
468
|
+
if (to.opVr)
|
|
469
|
+
b.toolOptions.opacityDynamics = parseDynamics(to.opVr);
|
|
470
|
+
if (to.szVr)
|
|
471
|
+
b.toolOptions.sizeDynamics = parseDynamics(to.szVr);
|
|
472
|
+
if ('wetness' in to)
|
|
473
|
+
b.toolOptions.wetness = to.wetness;
|
|
474
|
+
if ('dryness' in to)
|
|
475
|
+
b.toolOptions.dryness = to.dryness;
|
|
476
|
+
if ('mix' in to)
|
|
477
|
+
b.toolOptions.mix = to.mix;
|
|
478
|
+
if ('autoFill' in to)
|
|
479
|
+
b.toolOptions.autoFill = to.autoFill;
|
|
480
|
+
if ('autoClean' in to)
|
|
481
|
+
b.toolOptions.autoClean = to.autoClean;
|
|
482
|
+
if ('loadSolidColorOnly' in to)
|
|
483
|
+
b.toolOptions.loadSolidColorOnly = to.loadSolidColorOnly;
|
|
484
|
+
if ('sampleAllLayers' in to)
|
|
485
|
+
b.toolOptions.sampleAllLayers = to.sampleAllLayers;
|
|
486
|
+
if ('SmdF' in to)
|
|
487
|
+
b.toolOptions.smudgeFingerPainting = to.SmdF;
|
|
488
|
+
if ('SmdS' in to)
|
|
489
|
+
b.toolOptions.smudgeSampleAllLayers = to.SmdS;
|
|
490
|
+
if ('Prs ' in to)
|
|
491
|
+
b.toolOptions.strength = to['Prs '];
|
|
492
|
+
}
|
|
493
|
+
return b;
|
|
494
|
+
}
|
|
368
495
|
//# sourceMappingURL=abr.js.map
|