ag-psd 21.0.2 → 22.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 +4 -0
- package/dist/additionalInfo.d.ts +2 -2
- package/dist/additionalInfo.js +30 -17
- package/dist/additionalInfo.js.map +1 -1
- package/dist/bundle.js +125 -108
- package/dist/descriptor.js +1 -0
- package/dist/descriptor.js.map +1 -1
- package/dist/imageResources.d.ts +2 -2
- package/dist/imageResources.js +25 -27
- package/dist/imageResources.js.map +1 -1
- package/dist/psd.d.ts +7 -1
- package/dist/psdReader.d.ts +7 -9
- package/dist/psdReader.js +67 -62
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.js +2 -2
- package/dist/psdWriter.js.map +1 -1
- package/dist-es/additionalInfo.d.ts +2 -2
- package/dist-es/additionalInfo.js +30 -17
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/descriptor.js +1 -0
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/imageResources.d.ts +2 -2
- package/dist-es/imageResources.js +25 -27
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/psd.d.ts +7 -1
- package/dist-es/psdReader.d.ts +7 -9
- package/dist-es/psdReader.js +65 -61
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.js +2 -2
- package/dist-es/psdWriter.js.map +1 -1
- package/package.json +1 -1
- package/src/additionalInfo.ts +30 -19
- package/src/descriptor.ts +1 -0
- package/src/engineData2.ts +2 -2
- package/src/imageResources.ts +28 -28
- package/src/psd.ts +9 -2
- package/src/psdReader.ts +72 -58
- package/src/psdWriter.ts +2 -1
package/src/psdReader.ts
CHANGED
|
@@ -9,11 +9,6 @@ interface ChannelInfo {
|
|
|
9
9
|
length: number;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export interface ReadOptionsExt extends ReadOptions {
|
|
13
|
-
large: boolean;
|
|
14
|
-
globalAlpha: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
12
|
export const supportedColorModes = [ColorMode.Bitmap, ColorMode.Grayscale, ColorMode.RGB];
|
|
18
13
|
const colorModes = ['bitmap', 'grayscale', 'indexed', 'RGB', 'CMYK', 'multichannel', 'duotone', 'lab'];
|
|
19
14
|
|
|
@@ -26,21 +21,22 @@ function setupGrayscale(data: PixelData) {
|
|
|
26
21
|
}
|
|
27
22
|
}
|
|
28
23
|
|
|
29
|
-
export interface PsdReader {
|
|
24
|
+
export interface PsdReader extends ReadOptions {
|
|
30
25
|
offset: number;
|
|
31
26
|
view: DataView;
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
large: boolean;
|
|
28
|
+
globalAlpha: boolean;
|
|
29
|
+
log(...args: any[]): void;
|
|
34
30
|
}
|
|
35
31
|
|
|
36
32
|
export function createReader(buffer: ArrayBuffer, offset?: number, length?: number): PsdReader {
|
|
37
33
|
const view = new DataView(buffer, offset, length);
|
|
38
|
-
return { view, offset: 0, strict: false, debug: false };
|
|
34
|
+
return { view, offset: 0, strict: false, debug: false, large: false, globalAlpha: false, log: console.log };
|
|
39
35
|
}
|
|
40
36
|
|
|
41
37
|
export function warnOrThrow(reader: PsdReader, message: string) {
|
|
42
38
|
if (reader.strict) throw new Error(message);
|
|
43
|
-
if (reader.debug)
|
|
39
|
+
if (reader.debug) reader.log(message);
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
export function readUint8(reader: PsdReader) {
|
|
@@ -123,6 +119,14 @@ export function readSignature(reader: PsdReader) {
|
|
|
123
119
|
return readShortString(reader, 4);
|
|
124
120
|
}
|
|
125
121
|
|
|
122
|
+
export function validSignatureAt(reader: PsdReader, offset: number) {
|
|
123
|
+
const sig = String.fromCharCode(reader.view.getUint8(offset))
|
|
124
|
+
+ String.fromCharCode(reader.view.getUint8(offset + 1))
|
|
125
|
+
+ String.fromCharCode(reader.view.getUint8(offset + 2))
|
|
126
|
+
+ String.fromCharCode(reader.view.getUint8(offset + 3));
|
|
127
|
+
return sig == '8BIM' || sig == '8B64';
|
|
128
|
+
}
|
|
129
|
+
|
|
126
130
|
export function readPascalString(reader: PsdReader, padTo: number) {
|
|
127
131
|
let length = readUint8(reader);
|
|
128
132
|
const text = length ? readShortString(reader, length) : '';
|
|
@@ -225,7 +229,11 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
225
229
|
if (supportedColorModes.indexOf(colorMode) === -1) throw new Error(`Color mode not supported: ${colorModes[colorMode] ?? colorMode}`);
|
|
226
230
|
|
|
227
231
|
const psd: Psd = { width, height, channels, bitsPerChannel, colorMode };
|
|
228
|
-
|
|
232
|
+
|
|
233
|
+
Object.assign(reader, readOptions);
|
|
234
|
+
reader.large = version === 2;
|
|
235
|
+
reader.globalAlpha = false;
|
|
236
|
+
|
|
229
237
|
const fixOffsets = [0, 1, -1, 2, -2, 3, -3, 4, -4];
|
|
230
238
|
|
|
231
239
|
// color mode data
|
|
@@ -267,7 +275,7 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
267
275
|
|
|
268
276
|
readSection(reader, 2, left => {
|
|
269
277
|
const handler = resourceHandlersMap[id];
|
|
270
|
-
const skip = id === 1036 && !!
|
|
278
|
+
const skip = id === 1036 && !!reader.skipThumbnail;
|
|
271
279
|
|
|
272
280
|
if (!psd.imageResources) {
|
|
273
281
|
psd.imageResources = {};
|
|
@@ -275,9 +283,9 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
275
283
|
|
|
276
284
|
if (handler && !skip) {
|
|
277
285
|
try {
|
|
278
|
-
handler.read(reader, psd.imageResources, left
|
|
286
|
+
handler.read(reader, psd.imageResources, left);
|
|
279
287
|
} catch (e) {
|
|
280
|
-
if (
|
|
288
|
+
if (reader.throwForMissingFeatures) throw e;
|
|
281
289
|
skipBytes(reader, left());
|
|
282
290
|
}
|
|
283
291
|
} else {
|
|
@@ -291,9 +299,9 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
291
299
|
// layer and mask info
|
|
292
300
|
readSection(reader, 1, left => {
|
|
293
301
|
readSection(reader, 2, left => {
|
|
294
|
-
readLayerInfo(reader, psd
|
|
302
|
+
readLayerInfo(reader, psd);
|
|
295
303
|
skipBytes(reader, left());
|
|
296
|
-
}, undefined,
|
|
304
|
+
}, undefined, reader.large);
|
|
297
305
|
|
|
298
306
|
// SAI does not include this section
|
|
299
307
|
if (left() > 0) {
|
|
@@ -313,19 +321,19 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
313
321
|
}
|
|
314
322
|
|
|
315
323
|
if (left() >= 12) {
|
|
316
|
-
readAdditionalLayerInfo(reader, psd, psd,
|
|
324
|
+
readAdditionalLayerInfo(reader, psd, psd,);
|
|
317
325
|
} else {
|
|
318
326
|
// opt.logMissingFeatures && console.log('skipping leftover bytes', left());
|
|
319
327
|
skipBytes(reader, left());
|
|
320
328
|
}
|
|
321
329
|
}
|
|
322
|
-
}, undefined,
|
|
330
|
+
}, undefined, reader.large);
|
|
323
331
|
|
|
324
332
|
const hasChildren = psd.children && psd.children.length;
|
|
325
|
-
const skipComposite =
|
|
333
|
+
const skipComposite = reader.skipCompositeImageData && (reader.skipLayerImageData || hasChildren);
|
|
326
334
|
|
|
327
335
|
if (!skipComposite) {
|
|
328
|
-
readImageData(reader, psd
|
|
336
|
+
readImageData(reader, psd);
|
|
329
337
|
}
|
|
330
338
|
|
|
331
339
|
// TODO: show converted color mode instead of original PSD file color mode
|
|
@@ -335,11 +343,11 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
335
343
|
return psd;
|
|
336
344
|
}
|
|
337
345
|
|
|
338
|
-
export function readLayerInfo(reader: PsdReader, psd: Psd
|
|
346
|
+
export function readLayerInfo(reader: PsdReader, psd: Psd) {
|
|
339
347
|
let layerCount = readInt16(reader);
|
|
340
348
|
|
|
341
349
|
if (layerCount < 0) {
|
|
342
|
-
|
|
350
|
+
reader.globalAlpha = true;
|
|
343
351
|
layerCount = -layerCount;
|
|
344
352
|
}
|
|
345
353
|
|
|
@@ -347,14 +355,14 @@ export function readLayerInfo(reader: PsdReader, psd: Psd, options: ReadOptionsE
|
|
|
347
355
|
const layerChannels: ChannelInfo[][] = [];
|
|
348
356
|
|
|
349
357
|
for (let i = 0; i < layerCount; i++) {
|
|
350
|
-
const { layer, channels } = readLayerRecord(reader, psd
|
|
358
|
+
const { layer, channels } = readLayerRecord(reader, psd);
|
|
351
359
|
layers.push(layer);
|
|
352
360
|
layerChannels.push(channels);
|
|
353
361
|
}
|
|
354
362
|
|
|
355
|
-
if (!
|
|
363
|
+
if (!reader.skipLayerImageData) {
|
|
356
364
|
for (let i = 0; i < layerCount; i++) {
|
|
357
|
-
readLayerChannelImageData(reader, psd, layers[i], layerChannels[i]
|
|
365
|
+
readLayerChannelImageData(reader, psd, layers[i], layerChannels[i]);
|
|
358
366
|
}
|
|
359
367
|
}
|
|
360
368
|
|
|
@@ -369,6 +377,11 @@ export function readLayerInfo(reader: PsdReader, psd: Psd, options: ReadOptionsE
|
|
|
369
377
|
if (type === SectionDividerType.OpenFolder || type === SectionDividerType.ClosedFolder) {
|
|
370
378
|
l.opened = type === SectionDividerType.OpenFolder;
|
|
371
379
|
l.children = [];
|
|
380
|
+
|
|
381
|
+
if (l.sectionDivider?.key) {
|
|
382
|
+
l.blendMode = toBlendMode[l.sectionDivider.key] ?? l.blendMode;
|
|
383
|
+
}
|
|
384
|
+
|
|
372
385
|
stack[stack.length - 1].children!.unshift(l);
|
|
373
386
|
stack.push(l);
|
|
374
387
|
} else if (type === SectionDividerType.BoundingSectionDivider) {
|
|
@@ -383,7 +396,7 @@ export function readLayerInfo(reader: PsdReader, psd: Psd, options: ReadOptionsE
|
|
|
383
396
|
}
|
|
384
397
|
}
|
|
385
398
|
|
|
386
|
-
function readLayerRecord(reader: PsdReader, psd: Psd
|
|
399
|
+
function readLayerRecord(reader: PsdReader, psd: Psd) {
|
|
387
400
|
const layer: Layer = {};
|
|
388
401
|
layer.top = readInt32(reader);
|
|
389
402
|
layer.left = readInt32(reader);
|
|
@@ -397,7 +410,7 @@ function readLayerRecord(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
397
410
|
let id = readInt16(reader) as ChannelID;
|
|
398
411
|
let length = readUint32(reader);
|
|
399
412
|
|
|
400
|
-
if (
|
|
413
|
+
if (reader.large) {
|
|
401
414
|
if (length !== 0) throw new Error('Sizes larger than 4GB are not supported');
|
|
402
415
|
length = readUint32(reader);
|
|
403
416
|
}
|
|
@@ -425,21 +438,22 @@ function readLayerRecord(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
425
438
|
skipBytes(reader, 1);
|
|
426
439
|
|
|
427
440
|
readSection(reader, 1, left => {
|
|
428
|
-
const mask = readLayerMaskData(reader
|
|
441
|
+
const mask = readLayerMaskData(reader);
|
|
429
442
|
if (mask) layer.mask = mask;
|
|
430
443
|
|
|
431
444
|
/*const blendingRanges =*/ readLayerBlendingRanges(reader);
|
|
432
|
-
layer.name = readPascalString(reader,
|
|
445
|
+
layer.name = readPascalString(reader, 1); // should be padded to 4, but is not sometimes
|
|
433
446
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
447
|
+
// HACK: fix for sometimes layer.name string not being padded correctly, just skip until we get valid signature
|
|
448
|
+
while (left() > 4 && !validSignatureAt(reader, reader.offset)) reader.offset++;
|
|
449
|
+
|
|
450
|
+
while (left() > 4) readAdditionalLayerInfo(reader, layer, psd);
|
|
437
451
|
});
|
|
438
452
|
|
|
439
453
|
return { layer, channels };
|
|
440
454
|
}
|
|
441
455
|
|
|
442
|
-
function readLayerMaskData(reader: PsdReader
|
|
456
|
+
function readLayerMaskData(reader: PsdReader) {
|
|
443
457
|
return readSection<LayerMaskData | undefined>(reader, 1, left => {
|
|
444
458
|
if (!left()) return undefined;
|
|
445
459
|
|
|
@@ -475,8 +489,8 @@ function readLayerMaskData(reader: PsdReader, options: ReadOptions) {
|
|
|
475
489
|
// TEMP
|
|
476
490
|
(mask as any)._real = { realFlags, realUserMaskBackground, top2, left2, bottom2, right2 };*/
|
|
477
491
|
|
|
478
|
-
if (
|
|
479
|
-
|
|
492
|
+
if (reader.logMissingFeatures) {
|
|
493
|
+
reader.log('Unhandled extra real user mask params');
|
|
480
494
|
}
|
|
481
495
|
}
|
|
482
496
|
|
|
@@ -501,7 +515,7 @@ function readLayerBlendingRanges(reader: PsdReader) {
|
|
|
501
515
|
});
|
|
502
516
|
}
|
|
503
517
|
|
|
504
|
-
function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, channels: ChannelInfo[]
|
|
518
|
+
function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, channels: ChannelInfo[]) {
|
|
505
519
|
const layerWidth = (layer.right || 0) - (layer.left || 0);
|
|
506
520
|
const layerHeight = (layer.bottom || 0) - (layer.top || 0);
|
|
507
521
|
const cmyk = psd.colorMode === ColorMode.CMYK;
|
|
@@ -556,7 +570,7 @@ function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, ch
|
|
|
556
570
|
resetImageData(maskData);
|
|
557
571
|
|
|
558
572
|
const start = reader.offset;
|
|
559
|
-
readData(reader, channel.length, maskData, compression, maskWidth, maskHeight, psd.bitsPerChannel ?? 8, 0,
|
|
573
|
+
readData(reader, channel.length, maskData, compression, maskWidth, maskHeight, psd.bitsPerChannel ?? 8, 0, reader.large, 4);
|
|
560
574
|
|
|
561
575
|
if (RAW_IMAGE_DATA) {
|
|
562
576
|
(layer as any).maskDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
@@ -564,15 +578,15 @@ function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, ch
|
|
|
564
578
|
|
|
565
579
|
setupGrayscale(maskData);
|
|
566
580
|
|
|
567
|
-
if (
|
|
581
|
+
if (reader.useImageData) {
|
|
568
582
|
mask.imageData = maskData;
|
|
569
583
|
} else {
|
|
570
584
|
mask.canvas = imageDataToCanvas(maskData);
|
|
571
585
|
}
|
|
572
586
|
}
|
|
573
587
|
} else if (channel.id === ChannelID.RealUserMask) {
|
|
574
|
-
if (
|
|
575
|
-
|
|
588
|
+
if (reader.logMissingFeatures) {
|
|
589
|
+
reader.log(`RealUserMask not supported`);
|
|
576
590
|
}
|
|
577
591
|
|
|
578
592
|
reader.offset = start + channel.length;
|
|
@@ -583,12 +597,12 @@ function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, ch
|
|
|
583
597
|
if (offset < 0) {
|
|
584
598
|
targetData = undefined;
|
|
585
599
|
|
|
586
|
-
if (
|
|
600
|
+
if (reader.throwForMissingFeatures) {
|
|
587
601
|
throw new Error(`Channel not supported: ${channel.id}`);
|
|
588
602
|
}
|
|
589
603
|
}
|
|
590
604
|
|
|
591
|
-
readData(reader, channel.length, targetData, compression, layerWidth, layerHeight, psd.bitsPerChannel ?? 8, offset,
|
|
605
|
+
readData(reader, channel.length, targetData, compression, layerWidth, layerHeight, psd.bitsPerChannel ?? 8, offset, reader.large, cmyk ? 5 : 4);
|
|
592
606
|
|
|
593
607
|
if (RAW_IMAGE_DATA) {
|
|
594
608
|
(layer as any).imageDataRaw[channel.id] = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start + 2, channel.length - 2);
|
|
@@ -609,7 +623,7 @@ function readLayerChannelImageData(reader: PsdReader, psd: Psd, layer: Layer, ch
|
|
|
609
623
|
cmykToRgb(cmykData, imageData, false);
|
|
610
624
|
}
|
|
611
625
|
|
|
612
|
-
if (
|
|
626
|
+
if (reader.useImageData) {
|
|
613
627
|
layer.imageData = imageData;
|
|
614
628
|
} else {
|
|
615
629
|
layer.canvas = imageDataToCanvas(imageData);
|
|
@@ -647,30 +661,30 @@ export function readGlobalLayerMaskInfo(reader: PsdReader) {
|
|
|
647
661
|
});
|
|
648
662
|
}
|
|
649
663
|
|
|
650
|
-
export function readAdditionalLayerInfo(reader: PsdReader, target: LayerAdditionalInfo, psd: Psd
|
|
664
|
+
export function readAdditionalLayerInfo(reader: PsdReader, target: LayerAdditionalInfo, psd: Psd) {
|
|
651
665
|
const sig = readSignature(reader);
|
|
652
666
|
if (sig !== '8BIM' && sig !== '8B64') throw new Error(`Invalid signature: '${sig}' at 0x${(reader.offset - 4).toString(16)}`);
|
|
653
667
|
const key = readSignature(reader);
|
|
654
668
|
|
|
655
669
|
// `largeAdditionalInfoKeys` fallback, because some keys don't have 8B64 signature even when they are 64bit
|
|
656
|
-
const u64 = sig === '8B64' || (
|
|
670
|
+
const u64 = sig === '8B64' || (reader.large && largeAdditionalInfoKeys.indexOf(key) !== -1);
|
|
657
671
|
|
|
658
672
|
readSection(reader, 2, left => {
|
|
659
673
|
const handler = infoHandlersMap[key];
|
|
660
674
|
|
|
661
675
|
if (handler) {
|
|
662
676
|
try {
|
|
663
|
-
handler.read(reader, target, left, psd
|
|
677
|
+
handler.read(reader, target, left, psd);
|
|
664
678
|
} catch (e) {
|
|
665
|
-
if (
|
|
679
|
+
if (reader.throwForMissingFeatures) throw e;
|
|
666
680
|
}
|
|
667
681
|
} else {
|
|
668
|
-
|
|
682
|
+
reader.logMissingFeatures && reader.log(`Unhandled additional info: ${key}`);
|
|
669
683
|
skipBytes(reader, left());
|
|
670
684
|
}
|
|
671
685
|
|
|
672
686
|
if (left()) {
|
|
673
|
-
|
|
687
|
+
reader.logMissingFeatures && reader.log(`Unread ${left()} bytes left for additional info: ${key}`);
|
|
674
688
|
skipBytes(reader, left());
|
|
675
689
|
}
|
|
676
690
|
}, false, u64);
|
|
@@ -688,7 +702,7 @@ function createImageDataBitDepth(width: number, height: number, bitDepth: number
|
|
|
688
702
|
}
|
|
689
703
|
}
|
|
690
704
|
|
|
691
|
-
function readImageData(reader: PsdReader, psd: Psd
|
|
705
|
+
function readImageData(reader: PsdReader, psd: Psd) {
|
|
692
706
|
const compression = readUint16(reader) as Compression;
|
|
693
707
|
const bitsPerChannel = psd.bitsPerChannel ?? 8;
|
|
694
708
|
|
|
@@ -711,7 +725,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
711
725
|
bytes = readBytes(reader, Math.ceil(psd.width / 8) * psd.height);
|
|
712
726
|
} else if (compression === Compression.RleCompressed) {
|
|
713
727
|
bytes = new Uint8Array(psd.width * psd.height);
|
|
714
|
-
readDataRLE(reader, { data: bytes, width: psd.width, height: psd.height }, psd.width, psd.height, 8, 1, [0],
|
|
728
|
+
readDataRLE(reader, { data: bytes, width: psd.width, height: psd.height }, psd.width, psd.height, 8, 1, [0], reader.large);
|
|
715
729
|
} else {
|
|
716
730
|
throw new Error(`Bitmap compression not supported: ${compression}`);
|
|
717
731
|
}
|
|
@@ -728,7 +742,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
728
742
|
// TODO: store these channels in additional image data
|
|
729
743
|
channels.push(i);
|
|
730
744
|
}
|
|
731
|
-
} else if (
|
|
745
|
+
} else if (reader.globalAlpha) {
|
|
732
746
|
channels.push(3);
|
|
733
747
|
}
|
|
734
748
|
|
|
@@ -738,7 +752,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
738
752
|
}
|
|
739
753
|
} else if (compression === Compression.RleCompressed) {
|
|
740
754
|
const start = reader.offset;
|
|
741
|
-
readDataRLE(reader, imageData, psd.width, psd.height, bitsPerChannel, 4, channels,
|
|
755
|
+
readDataRLE(reader, imageData, psd.width, psd.height, bitsPerChannel, 4, channels, reader.large);
|
|
742
756
|
if (RAW_IMAGE_DATA) (psd as any).imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
743
757
|
}
|
|
744
758
|
|
|
@@ -752,7 +766,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
752
766
|
if (psd.channels !== 4) throw new Error(`Invalid channel count`);
|
|
753
767
|
|
|
754
768
|
const channels = [0, 1, 2, 3];
|
|
755
|
-
if (
|
|
769
|
+
if (reader.globalAlpha) channels.push(4);
|
|
756
770
|
|
|
757
771
|
if (compression === Compression.RawData) {
|
|
758
772
|
throw new Error(`Not implemented`);
|
|
@@ -768,7 +782,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
768
782
|
};
|
|
769
783
|
|
|
770
784
|
const start = reader.offset;
|
|
771
|
-
readDataRLE(reader, cmykImageData, psd.width, psd.height, psd.bitsPerChannel ?? 8, 5, channels,
|
|
785
|
+
readDataRLE(reader, cmykImageData, psd.width, psd.height, psd.bitsPerChannel ?? 8, 5, channels, reader.large);
|
|
772
786
|
cmykToRgb(cmykImageData, imageData, true);
|
|
773
787
|
|
|
774
788
|
if (RAW_IMAGE_DATA) (psd as any).imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
|
|
@@ -780,7 +794,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
780
794
|
}
|
|
781
795
|
|
|
782
796
|
// remove weird white matte
|
|
783
|
-
if (
|
|
797
|
+
if (reader.globalAlpha) {
|
|
784
798
|
if (psd.bitsPerChannel !== 8) throw new Error('bitsPerChannel Not supproted');
|
|
785
799
|
const p = imageData.data;
|
|
786
800
|
const size = imageData.width * imageData.height * 4;
|
|
@@ -797,7 +811,7 @@ function readImageData(reader: PsdReader, psd: Psd, options: ReadOptionsExt) {
|
|
|
797
811
|
}
|
|
798
812
|
}
|
|
799
813
|
|
|
800
|
-
if (
|
|
814
|
+
if (reader.useImageData) {
|
|
801
815
|
psd.imageData = imageData;
|
|
802
816
|
} else {
|
|
803
817
|
psd.canvas = imageDataToCanvas(imageData);
|
|
@@ -1189,7 +1203,7 @@ export function readPattern(reader: PsdReader): PatternInfo {
|
|
|
1189
1203
|
// console.log(data);
|
|
1190
1204
|
// throw new Error('Zip compression not supported for pattern');
|
|
1191
1205
|
// throw new Error('Unsupported pattern compression');
|
|
1192
|
-
|
|
1206
|
+
reader.log('Unsupported pattern compression');
|
|
1193
1207
|
name += ' (failed to decode)';
|
|
1194
1208
|
} else {
|
|
1195
1209
|
throw new Error('Invalid pattern compression mode');
|
package/src/psdWriter.ts
CHANGED
|
@@ -486,12 +486,13 @@ function addChildren(layers: Layer[], children: Layer[] | undefined) {
|
|
|
486
486
|
});
|
|
487
487
|
addChildren(layers, c.children);
|
|
488
488
|
layers.push({
|
|
489
|
+
...c,
|
|
490
|
+
blendMode: c.blendMode === 'pass through' ? 'normal' : c.blendMode,
|
|
489
491
|
sectionDivider: {
|
|
490
492
|
type: c.opened === false ? SectionDividerType.ClosedFolder : SectionDividerType.OpenFolder,
|
|
491
493
|
key: fromBlendMode[c.blendMode!] || 'pass',
|
|
492
494
|
subType: 0,
|
|
493
495
|
},
|
|
494
|
-
...c,
|
|
495
496
|
});
|
|
496
497
|
} else {
|
|
497
498
|
layers.push({ ...c });
|