ag-psd 31.0.0 → 31.0.2
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.13.1-x64-cf738c9d/03e19709 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/1130885f +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/4511bacf +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/7ea06cea +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/932f0770 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/9ed80ba5 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/a7e80865 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/acc36e66 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/b3c2fab7 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/c314aece +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/cfc49f4f +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/cff9434a +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/e03e2acd +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/eeeebdfe +0 -0
- package/CHANGELOG.md +3 -0
- package/dist/abr.js +2 -6
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.js +6 -6
- package/dist/additionalInfo.js.map +1 -1
- package/dist/ase.js +2 -0
- package/dist/ase.js.map +1 -1
- package/dist/bundle.js +222 -2282
- package/dist/descriptor.d.ts +2 -2
- package/dist/descriptor.js +4 -3
- package/dist/descriptor.js.map +1 -1
- package/dist/engineData.js +1 -1
- package/dist/helpers.d.ts +3 -1
- package/dist/helpers.js +1 -1
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.js +12 -7
- package/dist/imageResources.js.map +1 -1
- package/dist/jpeg.js +18 -6
- package/dist/jpeg.js.map +1 -1
- package/dist/psd.d.ts +2 -2
- package/dist/psd.js +2 -0
- package/dist/psd.js.map +1 -1
- package/dist/psdReader.js +49 -19
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.js +9 -3
- package/dist/psdWriter.js.map +1 -1
- package/dist/utf8.js +92 -81
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.js +2 -6
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.js +6 -6
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/ase.js +2 -0
- package/dist-es/ase.js.map +1 -1
- package/dist-es/descriptor.d.ts +2 -2
- package/dist-es/descriptor.js +4 -3
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/engineData.js +1 -1
- package/dist-es/helpers.d.ts +3 -1
- package/dist-es/helpers.js +1 -1
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.js +12 -7
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/jpeg.js +18 -6
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psd.d.ts +2 -2
- package/dist-es/psd.js +2 -0
- package/dist-es/psd.js.map +1 -1
- package/dist-es/psdReader.js +49 -19
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.js +9 -3
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/utf8.js +92 -81
- package/dist-es/utf8.js.map +1 -1
- package/package.json +1 -1
- package/src/abr.ts +2 -4
- package/src/additionalInfo.ts +6 -6
- package/src/ase.ts +2 -1
- package/src/descriptor.ts +5 -4
- package/src/engineData.ts +1 -1
- package/src/helpers.ts +6 -3
- package/src/imageResources.ts +10 -6
- package/src/jpeg.ts +19 -7
- package/src/psd.ts +4 -2
- package/src/psdReader.ts +51 -16
- package/src/psdWriter.ts +11 -3
- package/src/utf8.ts +178 -168
package/src/imageResources.ts
CHANGED
|
@@ -38,7 +38,9 @@ const MEASUREMENT_UNITS = [undefined, 'Inches', 'Centimeters', 'Points', 'Picas'
|
|
|
38
38
|
const hex = '0123456789abcdef';
|
|
39
39
|
|
|
40
40
|
function charToNibble(code: number) {
|
|
41
|
-
|
|
41
|
+
if (code <= 57) return code - 48; // '0'-'9'
|
|
42
|
+
if (code >= 97) return code - 87; // 'a'-'f'
|
|
43
|
+
return code - 55; // 'A'-'F'
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
function byteAt(value: string, index: number) {
|
|
@@ -68,11 +70,13 @@ function readEncodedString(reader: PsdReader) {
|
|
|
68
70
|
}
|
|
69
71
|
|
|
70
72
|
if (notAscii) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
try {
|
|
74
|
+
const decoder = new TextDecoder('gbk');
|
|
75
|
+
return decoder.decode(buffer)
|
|
76
|
+
} catch { }
|
|
75
77
|
}
|
|
78
|
+
|
|
79
|
+
return decodeString(buffer);
|
|
76
80
|
}
|
|
77
81
|
|
|
78
82
|
function writeEncodedString(writer: PsdWriter, value: string) {
|
|
@@ -1397,7 +1401,7 @@ MOCK_HANDLERS && addHandler(
|
|
|
1397
1401
|
},
|
|
1398
1402
|
);
|
|
1399
1403
|
|
|
1400
|
-
const FrmD = createEnum<'auto' | 'none' | 'dispose'>('FrmD', '', {
|
|
1404
|
+
const FrmD = createEnum<'auto' | 'none' | 'dispose'>('FrmD', 'auto', {
|
|
1401
1405
|
auto: 'Auto',
|
|
1402
1406
|
none: 'None',
|
|
1403
1407
|
dispose: 'Disp',
|
package/src/jpeg.ts
CHANGED
|
@@ -24,7 +24,6 @@ interface DecodedComponent {
|
|
|
24
24
|
interface Decoded {
|
|
25
25
|
width: number;
|
|
26
26
|
height: number;
|
|
27
|
-
comments: string[];
|
|
28
27
|
exifBuffer: Uint8Array | undefined;
|
|
29
28
|
jfif: any;
|
|
30
29
|
adobe: any;
|
|
@@ -623,7 +622,6 @@ function parse(data: Uint8Array) {
|
|
|
623
622
|
const self: Decoded = {
|
|
624
623
|
width: 0,
|
|
625
624
|
height: 0,
|
|
626
|
-
comments: [],
|
|
627
625
|
adobe: undefined,
|
|
628
626
|
components: [],
|
|
629
627
|
exifBuffer: undefined,
|
|
@@ -731,11 +729,12 @@ function parse(data: Uint8Array) {
|
|
|
731
729
|
const appData = readDataBlock();
|
|
732
730
|
|
|
733
731
|
if (fileMarker === 0xFFFE) {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
732
|
+
// ignore comments
|
|
733
|
+
// let comment = '';
|
|
734
|
+
// for (let ii = 0; ii < appData.byteLength; ii++) {
|
|
735
|
+
// comment += String.fromCharCode(appData[ii]);
|
|
736
|
+
// }
|
|
737
|
+
// self.comments.push(comment);
|
|
739
738
|
}
|
|
740
739
|
|
|
741
740
|
if (fileMarker === 0xFFE0) {
|
|
@@ -1125,6 +1124,19 @@ export function decodeJpeg(encoded: Uint8Array, createImageData: (width: number,
|
|
|
1125
1124
|
}
|
|
1126
1125
|
}
|
|
1127
1126
|
break;
|
|
1127
|
+
case 2:
|
|
1128
|
+
for (let y = 0; y < height; y++) {
|
|
1129
|
+
for (let x = 0; x < width; x++) {
|
|
1130
|
+
const Y = data[i++];
|
|
1131
|
+
const A = data[i++];
|
|
1132
|
+
|
|
1133
|
+
imageDataArray[j++] = Y;
|
|
1134
|
+
imageDataArray[j++] = Y;
|
|
1135
|
+
imageDataArray[j++] = Y;
|
|
1136
|
+
imageDataArray[j++] = A;
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
break;
|
|
1128
1140
|
case 3:
|
|
1129
1141
|
for (let y = 0; y < height; y++) {
|
|
1130
1142
|
for (let x = 0; x < width; x++) {
|
package/src/psd.ts
CHANGED
|
@@ -2,7 +2,7 @@ export type BlendMode = 'pass through' | 'normal' | 'dissolve' | 'darken' | 'mul
|
|
|
2
2
|
'color burn' | 'linear burn' | 'darker color' | 'lighten' | 'screen' | 'color dodge' |
|
|
3
3
|
'linear dodge' | 'lighter color' | 'overlay' | 'soft light' | 'hard light' |
|
|
4
4
|
'vivid light' | 'linear light' | 'pin light' | 'hard mix' | 'difference' | 'exclusion' |
|
|
5
|
-
'subtract' | 'divide' | 'hue' | 'saturation' | 'color' | 'luminosity';
|
|
5
|
+
'subtract' | 'divide' | 'hue' | 'saturation' | 'color' | 'luminosity' | 'linear height' | 'height' | 'subtraction';
|
|
6
6
|
|
|
7
7
|
export const enum ColorMode {
|
|
8
8
|
Bitmap = 0,
|
|
@@ -10,6 +10,8 @@ export const enum ColorMode {
|
|
|
10
10
|
Indexed = 2,
|
|
11
11
|
RGB = 3,
|
|
12
12
|
CMYK = 4,
|
|
13
|
+
// 5
|
|
14
|
+
// 6
|
|
13
15
|
Multichannel = 7,
|
|
14
16
|
Duotone = 8,
|
|
15
17
|
Lab = 9,
|
|
@@ -183,7 +185,7 @@ export interface EffectNoiseGradient {
|
|
|
183
185
|
name: string;
|
|
184
186
|
type: 'noise';
|
|
185
187
|
roughness?: number;
|
|
186
|
-
colorModel?: 'rgb' | 'hsb' | 'lab';
|
|
188
|
+
colorModel?: 'rgb' | 'hsb' | 'lab' | 'hsl';
|
|
187
189
|
randomSeed?: number;
|
|
188
190
|
restrictColors?: boolean;
|
|
189
191
|
addTransparency?: boolean;
|
package/src/psdReader.ts
CHANGED
|
@@ -10,7 +10,7 @@ interface ChannelInfo {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const supportedColorModes = [ColorMode.Bitmap, ColorMode.Grayscale, ColorMode.RGB, ColorMode.Indexed];
|
|
13
|
-
const colorModes = ['bitmap', 'grayscale', 'indexed', 'RGB', 'CMYK', 'multichannel', 'duotone', 'lab'];
|
|
13
|
+
const colorModes = ['bitmap', 'grayscale', 'indexed', 'RGB', 'CMYK', '', '', 'multichannel', 'duotone', 'lab'];
|
|
14
14
|
|
|
15
15
|
function setupGrayscale(data: PixelData) {
|
|
16
16
|
const size = data.width * data.height * 4;
|
|
@@ -234,7 +234,9 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
234
234
|
Object.assign(reader, readOptions);
|
|
235
235
|
reader.large = version === 2;
|
|
236
236
|
reader.globalAlpha = false;
|
|
237
|
-
if (!
|
|
237
|
+
if (!('totalMemoryLimit' in reader)) { // setting totalMemoryLimit to undefined explicitly disables memory limit
|
|
238
|
+
reader.totalMemoryLimit = 2 * 1024 * 1024 * 1024; // default 2GB memory limit
|
|
239
|
+
}
|
|
238
240
|
|
|
239
241
|
// color mode data
|
|
240
242
|
readSection(reader, 1, left => {
|
|
@@ -287,7 +289,7 @@ export function readPsd(reader: PsdReader, readOptions: ReadOptions = {}) {
|
|
|
287
289
|
|
|
288
290
|
const { layersGroup, layerGroupsEnabledId, ...rest } = imageResources;
|
|
289
291
|
|
|
290
|
-
if (Object.keys(rest)) {
|
|
292
|
+
if (Object.keys(rest).length) {
|
|
291
293
|
psd.imageResources = rest;
|
|
292
294
|
}
|
|
293
295
|
|
|
@@ -408,6 +410,7 @@ function readLayerRecord(reader: PsdReader, psd: Psd, imageResources: InternalIm
|
|
|
408
410
|
layer.left = readInt32(reader);
|
|
409
411
|
layer.bottom = readInt32(reader);
|
|
410
412
|
layer.right = readInt32(reader);
|
|
413
|
+
if (!isValidBoxSize(layer, reader)) throw new Error('Invalid layer size');
|
|
411
414
|
|
|
412
415
|
const channelCount = readUint16(reader);
|
|
413
416
|
const channels: ChannelInfo[] = [];
|
|
@@ -461,6 +464,13 @@ function readLayerRecord(reader: PsdReader, psd: Psd, imageResources: InternalIm
|
|
|
461
464
|
return { layer, channels };
|
|
462
465
|
}
|
|
463
466
|
|
|
467
|
+
function isValidBoxSize(box: { top?: number; left?: number; bottom?: number; right?: number; }, reader: PsdReader) {
|
|
468
|
+
const width = (box.right || 0) - (box.left || 0);
|
|
469
|
+
const height = (box.bottom || 0) - (box.top || 0);
|
|
470
|
+
const maxSize = reader.large ? 300000 : 30000;
|
|
471
|
+
return width >= 0 && height >= 0 && width <= maxSize && height <= maxSize;
|
|
472
|
+
}
|
|
473
|
+
|
|
464
474
|
function readLayerMaskData(reader: PsdReader, layer: Layer) {
|
|
465
475
|
return readSection<LayerMaskData | undefined>(reader, 1, left => {
|
|
466
476
|
if (!left()) return undefined;
|
|
@@ -472,6 +482,8 @@ function readLayerMaskData(reader: PsdReader, layer: Layer) {
|
|
|
472
482
|
mask.left = readInt32(reader);
|
|
473
483
|
mask.bottom = readInt32(reader);
|
|
474
484
|
mask.right = readInt32(reader);
|
|
485
|
+
if (!isValidBoxSize(mask, reader)) throw new Error('Invalid mask size');
|
|
486
|
+
|
|
475
487
|
mask.defaultColor = readUint8(reader);
|
|
476
488
|
|
|
477
489
|
const flags = readUint8(reader);
|
|
@@ -493,6 +505,7 @@ function readLayerMaskData(reader: PsdReader, layer: Layer) {
|
|
|
493
505
|
realMask.left = readInt32(reader);
|
|
494
506
|
realMask.bottom = readInt32(reader);
|
|
495
507
|
realMask.right = readInt32(reader);
|
|
508
|
+
if (!isValidBoxSize(realMask, reader)) throw new Error('Invalid realMask size');
|
|
496
509
|
}
|
|
497
510
|
|
|
498
511
|
if (flags & LayerMaskFlags.MaskHasParametersAppliedToIt) {
|
|
@@ -636,23 +649,23 @@ export function decodeLayerPixels(layer: Layer, useImageData?: boolean) {
|
|
|
636
649
|
decodeLayerImageData(layer, { useImageData });
|
|
637
650
|
}
|
|
638
651
|
|
|
639
|
-
function decodeLayerImageData(layer: Layer, options:
|
|
652
|
+
function decodeLayerImageData(layer: Layer, options: Pick<ReadOptions, 'useImageData' | 'throwForMissingFeatures' | 'totalMemoryLimit'>) {
|
|
640
653
|
let { throwForMissingFeatures, useImageData } = options;
|
|
641
654
|
|
|
642
|
-
const imageData = getDataFromLayer(layer, LayerDataType.Layer, throwForMissingFeatures, options.
|
|
655
|
+
const imageData = getDataFromLayer(layer, LayerDataType.Layer, throwForMissingFeatures, options.totalMemoryLimit);
|
|
643
656
|
setImageDataOrCanvas(layer, imageData, useImageData);
|
|
644
|
-
if (options.
|
|
657
|
+
if (options.totalMemoryLimit !== undefined) options.totalMemoryLimit -= imageData?.data.byteLength ?? 0;
|
|
645
658
|
|
|
646
659
|
if (layer.mask) {
|
|
647
|
-
const maskData = getDataFromLayer(layer, LayerDataType.Mask, throwForMissingFeatures, options.
|
|
660
|
+
const maskData = getDataFromLayer(layer, LayerDataType.Mask, throwForMissingFeatures, options.totalMemoryLimit);
|
|
648
661
|
setImageDataOrCanvas(layer.mask, maskData, useImageData);
|
|
649
|
-
if (options.
|
|
662
|
+
if (options.totalMemoryLimit !== undefined) options.totalMemoryLimit -= maskData?.data.byteLength ?? 0;
|
|
650
663
|
}
|
|
651
664
|
|
|
652
665
|
if (layer.realMask) {
|
|
653
|
-
const maskData = getDataFromLayer(layer, LayerDataType.RealMask, throwForMissingFeatures, options.
|
|
666
|
+
const maskData = getDataFromLayer(layer, LayerDataType.RealMask, throwForMissingFeatures, options.totalMemoryLimit);
|
|
654
667
|
setImageDataOrCanvas(layer.realMask, maskData, useImageData);
|
|
655
|
-
if (options.
|
|
668
|
+
if (options.totalMemoryLimit !== undefined) options.totalMemoryLimit -= maskData?.data.byteLength ?? 0;
|
|
656
669
|
}
|
|
657
670
|
|
|
658
671
|
delete layer.rawData;
|
|
@@ -668,8 +681,8 @@ function getDataFromLayer(layer: Layer, read: LayerDataType, throwForMissingFeat
|
|
|
668
681
|
if (!layer.rawData) return undefined;
|
|
669
682
|
|
|
670
683
|
const { colorMode, bitsPerChannel, channels, large } = layer.rawData;
|
|
671
|
-
const layerWidth = (layer.right || 0) - (layer.left || 0);
|
|
672
|
-
const layerHeight = (layer.bottom || 0) - (layer.top || 0);
|
|
684
|
+
const layerWidth = Math.max(0, (layer.right || 0) - (layer.left || 0));
|
|
685
|
+
const layerHeight = Math.max(0, (layer.bottom || 0) - (layer.top || 0));
|
|
673
686
|
const cmyk = colorMode === ColorMode.CMYK;
|
|
674
687
|
|
|
675
688
|
let imageData: PixelData | undefined;
|
|
@@ -702,9 +715,8 @@ function getDataFromLayer(layer: Layer, read: LayerDataType, throwForMissingFeat
|
|
|
702
715
|
const mask = id === ChannelID.UserMask ? layer.mask : layer.realMask;
|
|
703
716
|
if (!mask) throw new Error(`Missing layer ${id === ChannelID.UserMask ? 'mask' : 'real mask'} data`);
|
|
704
717
|
|
|
705
|
-
const maskWidth = (mask.right || 0) - (mask.left || 0);
|
|
706
|
-
const maskHeight = (mask.bottom || 0) - (mask.top || 0);
|
|
707
|
-
if (maskWidth < 0 || maskHeight < 0 || maskWidth > 30000 || maskHeight > 30000) throw new Error('Invalid mask size');
|
|
718
|
+
const maskWidth = Math.max(0, (mask.right || 0) - (mask.left || 0));
|
|
719
|
+
const maskHeight = Math.max(0, (mask.bottom || 0) - (mask.top || 0));
|
|
708
720
|
|
|
709
721
|
if (maskWidth && maskHeight) {
|
|
710
722
|
maskData = createImageDataBitDepth(maskWidth, maskHeight, bitsPerChannel, 4, memoryLimit);
|
|
@@ -1174,6 +1186,7 @@ export function readDataRLE(reader: PsdReader, pixelData: PixelData | undefined,
|
|
|
1174
1186
|
let lengths: Uint16Array | Uint32Array;
|
|
1175
1187
|
|
|
1176
1188
|
if (large) {
|
|
1189
|
+
consumeMemory(reader, offsets.length * height * 4);
|
|
1177
1190
|
lengths = new Uint32Array(offsets.length * height);
|
|
1178
1191
|
|
|
1179
1192
|
for (let o = 0, li = 0; o < offsets.length; o++) {
|
|
@@ -1182,6 +1195,7 @@ export function readDataRLE(reader: PsdReader, pixelData: PixelData | undefined,
|
|
|
1182
1195
|
}
|
|
1183
1196
|
}
|
|
1184
1197
|
} else {
|
|
1198
|
+
consumeMemory(reader, offsets.length * height * 2);
|
|
1185
1199
|
lengths = new Uint16Array(offsets.length * height);
|
|
1186
1200
|
|
|
1187
1201
|
for (let o = 0, li = 0; o < offsets.length; o++) {
|
|
@@ -1234,6 +1248,8 @@ export function readDataRLE(reader: PsdReader, pixelData: PixelData | undefined,
|
|
|
1234
1248
|
}
|
|
1235
1249
|
}
|
|
1236
1250
|
}
|
|
1251
|
+
|
|
1252
|
+
recoverMemory(reader, lengths.byteLength);
|
|
1237
1253
|
}
|
|
1238
1254
|
|
|
1239
1255
|
export function readSection<T>(
|
|
@@ -1357,7 +1373,9 @@ export function readPattern(reader: PsdReader): PatternInfo {
|
|
|
1357
1373
|
const channelsCount = readUint32(reader);
|
|
1358
1374
|
const width = right - left;
|
|
1359
1375
|
const height = bottom - top;
|
|
1360
|
-
const
|
|
1376
|
+
const size = width * height * 4;
|
|
1377
|
+
consumeMemory(reader, size);
|
|
1378
|
+
const data = new Uint8Array(size);
|
|
1361
1379
|
|
|
1362
1380
|
for (let i = 3; i < data.byteLength; i += 4) {
|
|
1363
1381
|
data[i] = 255;
|
|
@@ -1423,6 +1441,8 @@ export function readPattern(reader: PsdReader): PatternInfo {
|
|
|
1423
1441
|
if (reader.throwForMissingFeatures) throw new Error('Invalid color pattern');
|
|
1424
1442
|
}
|
|
1425
1443
|
} else if (compressionMode === 1) {
|
|
1444
|
+
consumeMemory(reader, w * h);
|
|
1445
|
+
|
|
1426
1446
|
const pixelData: PixelData = { data, width, height };
|
|
1427
1447
|
const tempData: PixelData = { data: new Uint8Array(w * h), width: w, height: h };
|
|
1428
1448
|
const cdataReader = createReader(cdata.buffer, cdata.byteOffset, cdata.byteLength);
|
|
@@ -1442,6 +1462,8 @@ export function readPattern(reader: PsdReader): PatternInfo {
|
|
|
1442
1462
|
// TODO:
|
|
1443
1463
|
throw new Error('Indexed pattern color mode not implemented');
|
|
1444
1464
|
}
|
|
1465
|
+
|
|
1466
|
+
recoverMemory(reader, w * h);
|
|
1445
1467
|
} else {
|
|
1446
1468
|
throw new Error('Invalid pattern compression mode');
|
|
1447
1469
|
}
|
|
@@ -1468,3 +1490,16 @@ function copyChannelToRGBA(srcData: PixelData, dstData: PixelData, ox: number, o
|
|
|
1468
1490
|
}
|
|
1469
1491
|
}
|
|
1470
1492
|
}
|
|
1493
|
+
|
|
1494
|
+
function consumeMemory(reader: PsdReader, size: number) {
|
|
1495
|
+
if (reader.totalMemoryLimit !== undefined) {
|
|
1496
|
+
if (reader.totalMemoryLimit < size) throw new Error('Exceeded memory limit');
|
|
1497
|
+
reader.totalMemoryLimit -= size;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
function recoverMemory(reader: PsdReader, size: number) {
|
|
1502
|
+
if (reader.totalMemoryLimit !== undefined) {
|
|
1503
|
+
reader.totalMemoryLimit += size;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
package/src/psdWriter.ts
CHANGED
|
@@ -157,8 +157,16 @@ function getLargestLayerSize(layers: Layer[] = []): number {
|
|
|
157
157
|
let max = 0;
|
|
158
158
|
|
|
159
159
|
for (const layer of layers) {
|
|
160
|
-
|
|
161
|
-
|
|
160
|
+
const { width, height } = getLayerDimentions(layer);
|
|
161
|
+
max = Math.max(max, 2 * height + 2 * width * height);
|
|
162
|
+
|
|
163
|
+
if (layer.mask) {
|
|
164
|
+
const { width, height } = getLayerDimentions(layer.mask);
|
|
165
|
+
max = Math.max(max, 2 * height + 2 * width * height);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (layer.realMask) {
|
|
169
|
+
const { width, height } = getLayerDimentions(layer.realMask);
|
|
162
170
|
max = Math.max(max, 2 * height + 2 * width * height);
|
|
163
171
|
}
|
|
164
172
|
|
|
@@ -472,7 +480,7 @@ function writeGlobalLayerMaskInfo(writer: PsdWriter, info: GlobalLayerMaskInfo |
|
|
|
472
480
|
writeUint16(writer, info.colorSpace2);
|
|
473
481
|
writeUint16(writer, info.colorSpace3);
|
|
474
482
|
writeUint16(writer, info.colorSpace4);
|
|
475
|
-
writeUint16(writer, info.opacity * 0xff);
|
|
483
|
+
writeUint16(writer, Math.round(info.opacity * 0xff));
|
|
476
484
|
writeUint8(writer, info.kind);
|
|
477
485
|
writeZeros(writer, 3);
|
|
478
486
|
}
|