ag-psd 30.1.1 → 30.2.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.13.1-x64-cf738c9d/017325ac +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/043c7b90 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/05135617 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/059f8558 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/0706ecb8 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/0db754a7 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/1130885f +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/15f0e479 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/20477c23 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/20dfa422 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/2a19133e +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/2b069ee0 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/2de09439 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/2e44f5f0 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/2fb229a9 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/3144b401 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/37481985 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/4511bacf +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/49d22b79 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/4f5702bd +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/514cc428 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/57d3380b +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/6024ce3f +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/61735b23 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/63dbdb75 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/6cbfc0ec +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/6f08372c +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/7100ee08 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/71df9cb3 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/75e41e43 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/7ea06cea +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/8568576b +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/87372817 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/87cf2209 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/932f0770 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/a79a40bb +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/b69ed3a3 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/bdff1628 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/c0b789d2 +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/d02dd6f7 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/dc86f000 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/de74e659 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/e03e2acd +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/e158d332 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/e6735171 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/e6745c2b +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/e6b99945 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/eeeebdfe +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/fbca6276 +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/fc97d72d +0 -0
- package/.v8-cache/v24.13.1-x64-cf738c9d/fd0a2987 +0 -0
- package/CHANGELOG.md +3 -0
- package/README.md +1 -1
- package/README_PSD.md +1 -1
- package/dist/abr.js +43 -56
- package/dist/abr.js.map +1 -1
- package/dist/additionalInfo.js +770 -808
- package/dist/additionalInfo.js.map +1 -1
- package/dist/ase.js +21 -21
- package/dist/ase.js.map +1 -1
- package/dist/bundle.js +2592 -2778
- package/dist/csh.js +18 -29
- package/dist/csh.js.map +1 -1
- package/dist/descriptor.js +234 -269
- package/dist/descriptor.js.map +1 -1
- package/dist/effectsHelpers.js +91 -112
- package/dist/effectsHelpers.js.map +1 -1
- package/dist/engineData.js +45 -51
- package/dist/engineData.js.map +1 -1
- package/dist/engineData2.js +8 -9
- package/dist/engineData2.js.map +1 -1
- package/dist/helpers.js +75 -81
- package/dist/helpers.js.map +1 -1
- package/dist/imageResources.js +342 -381
- package/dist/imageResources.js.map +1 -1
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/initializeCanvas.js +2 -2
- package/dist/initializeCanvas.js.map +1 -1
- package/dist/jpeg.js +279 -279
- package/dist/jpeg.js.map +1 -1
- package/dist/psdReader.js +336 -347
- package/dist/psdReader.js.map +1 -1
- package/dist/psdWriter.d.ts +2 -1
- package/dist/psdWriter.js +225 -206
- package/dist/psdWriter.js.map +1 -1
- package/dist/text.js +98 -122
- package/dist/text.js.map +1 -1
- package/dist/utf8.js +22 -22
- package/dist/utf8.js.map +1 -1
- package/dist-es/abr.js +41 -54
- package/dist-es/abr.js.map +1 -1
- package/dist-es/additionalInfo.js +765 -803
- package/dist-es/additionalInfo.js.map +1 -1
- package/dist-es/ase.js +20 -20
- package/dist-es/ase.js.map +1 -1
- package/dist-es/csh.js +16 -27
- package/dist-es/csh.js.map +1 -1
- package/dist-es/descriptor.js +284 -319
- package/dist-es/descriptor.js.map +1 -1
- package/dist-es/effectsHelpers.js +88 -109
- package/dist-es/effectsHelpers.js.map +1 -1
- package/dist-es/engineData.js +45 -51
- package/dist-es/engineData.js.map +1 -1
- package/dist-es/engineData2.js +8 -9
- package/dist-es/engineData2.js.map +1 -1
- package/dist-es/helpers.js +79 -85
- package/dist-es/helpers.js.map +1 -1
- package/dist-es/imageResources.js +338 -377
- package/dist-es/imageResources.js.map +1 -1
- package/dist-es/index.js +4 -4
- package/dist-es/index.js.map +1 -1
- package/dist-es/jpeg.js +279 -279
- package/dist-es/jpeg.js.map +1 -1
- package/dist-es/psdReader.js +333 -344
- package/dist-es/psdReader.js.map +1 -1
- package/dist-es/psdWriter.d.ts +2 -1
- package/dist-es/psdWriter.js +220 -202
- package/dist-es/psdWriter.js.map +1 -1
- package/dist-es/text.js +98 -122
- package/dist-es/text.js.map +1 -1
- package/dist-es/utf8.js +22 -22
- package/dist-es/utf8.js.map +1 -1
- package/package.json +1 -1
- package/publish.js +24 -0
- package/src/additionalInfo.ts +15 -11
- package/src/psdWriter.ts +76 -1
- package/tsconfig.json +4 -3
package/dist/psdWriter.js
CHANGED
|
@@ -1,26 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.writeColor = exports.writePsd = exports.writeSection = exports.writeUnicodeStringWithPadding = exports.writeUnicodeString = exports.writeUnicodeStringWithoutLengthLE = exports.writeUnicodeStringWithoutLength = exports.writePascalString = exports.writeAsciiString = exports.writeSignature = exports.writeZeros = exports.writeBytes = exports.writeFixedPointPath32 = exports.writeFixedPoint32 = exports.writeFloat64 = exports.writeFloat32 = exports.writeUint32 = exports.writeInt32LE = exports.writeInt32 = exports.writeUint16LE = exports.writeUint16 = exports.writeInt16 = exports.writeUint8 = exports.getWriterBufferNoCopy = exports.getWriterBuffer = exports.createWriter = void 0;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
function createWriter(size) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return { buffer: buffer, view: view, offset: offset, tempBuffer: undefined };
|
|
3
|
+
exports.writePattern = exports.writeColor = exports.writePsd = exports.writeSection = exports.writeUnicodeStringWithPadding = exports.writeUnicodeString = exports.writeUnicodeStringWithoutLengthLE = exports.writeUnicodeStringWithoutLength = exports.writePascalString = exports.writeAsciiString = exports.writeSignature = exports.writeZeros = exports.writeBytes = exports.writeFixedPointPath32 = exports.writeFixedPoint32 = exports.writeFloat64 = exports.writeFloat32 = exports.writeUint32 = exports.writeInt32LE = exports.writeInt32 = exports.writeUint16LE = exports.writeUint16 = exports.writeInt16 = exports.writeUint8 = exports.getWriterBufferNoCopy = exports.getWriterBuffer = exports.createWriter = void 0;
|
|
4
|
+
const helpers_1 = require("./helpers");
|
|
5
|
+
const additionalInfo_1 = require("./additionalInfo");
|
|
6
|
+
const imageResources_1 = require("./imageResources");
|
|
7
|
+
function createWriter(size = 4096) {
|
|
8
|
+
const buffer = new ArrayBuffer(size);
|
|
9
|
+
const view = new DataView(buffer);
|
|
10
|
+
const offset = 0;
|
|
11
|
+
return { buffer, view, offset, tempBuffer: undefined };
|
|
24
12
|
}
|
|
25
13
|
exports.createWriter = createWriter;
|
|
26
14
|
function getWriterBuffer(writer) {
|
|
@@ -32,47 +20,47 @@ function getWriterBufferNoCopy(writer) {
|
|
|
32
20
|
}
|
|
33
21
|
exports.getWriterBufferNoCopy = getWriterBufferNoCopy;
|
|
34
22
|
function writeUint8(writer, value) {
|
|
35
|
-
|
|
23
|
+
const offset = addSize(writer, 1);
|
|
36
24
|
writer.view.setUint8(offset, value);
|
|
37
25
|
}
|
|
38
26
|
exports.writeUint8 = writeUint8;
|
|
39
27
|
function writeInt16(writer, value) {
|
|
40
|
-
|
|
28
|
+
const offset = addSize(writer, 2);
|
|
41
29
|
writer.view.setInt16(offset, value, false);
|
|
42
30
|
}
|
|
43
31
|
exports.writeInt16 = writeInt16;
|
|
44
32
|
function writeUint16(writer, value) {
|
|
45
|
-
|
|
33
|
+
const offset = addSize(writer, 2);
|
|
46
34
|
writer.view.setUint16(offset, value, false);
|
|
47
35
|
}
|
|
48
36
|
exports.writeUint16 = writeUint16;
|
|
49
37
|
function writeUint16LE(writer, value) {
|
|
50
|
-
|
|
38
|
+
const offset = addSize(writer, 2);
|
|
51
39
|
writer.view.setUint16(offset, value, true);
|
|
52
40
|
}
|
|
53
41
|
exports.writeUint16LE = writeUint16LE;
|
|
54
42
|
function writeInt32(writer, value) {
|
|
55
|
-
|
|
43
|
+
const offset = addSize(writer, 4);
|
|
56
44
|
writer.view.setInt32(offset, value, false);
|
|
57
45
|
}
|
|
58
46
|
exports.writeInt32 = writeInt32;
|
|
59
47
|
function writeInt32LE(writer, value) {
|
|
60
|
-
|
|
48
|
+
const offset = addSize(writer, 4);
|
|
61
49
|
writer.view.setInt32(offset, value, true);
|
|
62
50
|
}
|
|
63
51
|
exports.writeInt32LE = writeInt32LE;
|
|
64
52
|
function writeUint32(writer, value) {
|
|
65
|
-
|
|
53
|
+
const offset = addSize(writer, 4);
|
|
66
54
|
writer.view.setUint32(offset, value, false);
|
|
67
55
|
}
|
|
68
56
|
exports.writeUint32 = writeUint32;
|
|
69
57
|
function writeFloat32(writer, value) {
|
|
70
|
-
|
|
58
|
+
const offset = addSize(writer, 4);
|
|
71
59
|
writer.view.setFloat32(offset, value, false);
|
|
72
60
|
}
|
|
73
61
|
exports.writeFloat32 = writeFloat32;
|
|
74
62
|
function writeFloat64(writer, value) {
|
|
75
|
-
|
|
63
|
+
const offset = addSize(writer, 8);
|
|
76
64
|
writer.view.setFloat64(offset, value, false);
|
|
77
65
|
}
|
|
78
66
|
exports.writeFloat64 = writeFloat64;
|
|
@@ -89,39 +77,39 @@ exports.writeFixedPointPath32 = writeFixedPointPath32;
|
|
|
89
77
|
function writeBytes(writer, buffer) {
|
|
90
78
|
if (buffer) {
|
|
91
79
|
ensureSize(writer, writer.offset + buffer.length);
|
|
92
|
-
|
|
80
|
+
const bytes = new Uint8Array(writer.buffer);
|
|
93
81
|
bytes.set(buffer, writer.offset);
|
|
94
82
|
writer.offset += buffer.length;
|
|
95
83
|
}
|
|
96
84
|
}
|
|
97
85
|
exports.writeBytes = writeBytes;
|
|
98
86
|
function writeZeros(writer, count) {
|
|
99
|
-
for (
|
|
87
|
+
for (let i = 0; i < count; i++) {
|
|
100
88
|
writeUint8(writer, 0);
|
|
101
89
|
}
|
|
102
90
|
}
|
|
103
91
|
exports.writeZeros = writeZeros;
|
|
104
92
|
function writeSignature(writer, signature) {
|
|
105
93
|
if (signature.length !== 4)
|
|
106
|
-
throw new Error(
|
|
107
|
-
for (
|
|
94
|
+
throw new Error(`Invalid signature: '${signature}'`);
|
|
95
|
+
for (let i = 0; i < 4; i++) {
|
|
108
96
|
writeUint8(writer, signature.charCodeAt(i));
|
|
109
97
|
}
|
|
110
98
|
}
|
|
111
99
|
exports.writeSignature = writeSignature;
|
|
112
100
|
function writeAsciiString(writer, text) {
|
|
113
|
-
for (
|
|
101
|
+
for (let i = 0; i < text.length; i++) {
|
|
114
102
|
writeUint8(writer, text.charCodeAt(i));
|
|
115
103
|
}
|
|
116
104
|
}
|
|
117
105
|
exports.writeAsciiString = writeAsciiString;
|
|
118
106
|
function writePascalString(writer, text, padTo) {
|
|
119
|
-
|
|
107
|
+
let length = text.length;
|
|
120
108
|
if (length > 255)
|
|
121
|
-
throw new Error(
|
|
109
|
+
throw new Error(`String too long`);
|
|
122
110
|
writeUint8(writer, length);
|
|
123
|
-
for (
|
|
124
|
-
|
|
111
|
+
for (let i = 0; i < length; i++) {
|
|
112
|
+
const code = text.charCodeAt(i);
|
|
125
113
|
// writeUint8(writer, code); // for testing
|
|
126
114
|
writeUint8(writer, code < 128 ? code : '?'.charCodeAt(0));
|
|
127
115
|
}
|
|
@@ -131,13 +119,13 @@ function writePascalString(writer, text, padTo) {
|
|
|
131
119
|
}
|
|
132
120
|
exports.writePascalString = writePascalString;
|
|
133
121
|
function writeUnicodeStringWithoutLength(writer, text) {
|
|
134
|
-
for (
|
|
122
|
+
for (let i = 0; i < text.length; i++) {
|
|
135
123
|
writeUint16(writer, text.charCodeAt(i));
|
|
136
124
|
}
|
|
137
125
|
}
|
|
138
126
|
exports.writeUnicodeStringWithoutLength = writeUnicodeStringWithoutLength;
|
|
139
127
|
function writeUnicodeStringWithoutLengthLE(writer, text) {
|
|
140
|
-
for (
|
|
128
|
+
for (let i = 0; i < text.length; i++) {
|
|
141
129
|
writeUint16LE(writer, text.charCodeAt(i));
|
|
142
130
|
}
|
|
143
131
|
}
|
|
@@ -149,19 +137,17 @@ function writeUnicodeString(writer, text) {
|
|
|
149
137
|
exports.writeUnicodeString = writeUnicodeString;
|
|
150
138
|
function writeUnicodeStringWithPadding(writer, text) {
|
|
151
139
|
writeUint32(writer, text.length + 1);
|
|
152
|
-
for (
|
|
140
|
+
for (let i = 0; i < text.length; i++) {
|
|
153
141
|
writeUint16(writer, text.charCodeAt(i));
|
|
154
142
|
}
|
|
155
143
|
writeUint16(writer, 0);
|
|
156
144
|
}
|
|
157
145
|
exports.writeUnicodeStringWithPadding = writeUnicodeStringWithPadding;
|
|
158
|
-
function getLargestLayerSize(layers) {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
for (var _i = 0, layers_1 = layers; _i < layers_1.length; _i++) {
|
|
162
|
-
var layer = layers_1[_i];
|
|
146
|
+
function getLargestLayerSize(layers = []) {
|
|
147
|
+
let max = 0;
|
|
148
|
+
for (const layer of layers) {
|
|
163
149
|
if (layer.canvas || layer.imageData) {
|
|
164
|
-
|
|
150
|
+
const { width, height } = getLayerDimentions(layer);
|
|
165
151
|
max = Math.max(max, 2 * height + 2 * width * height);
|
|
166
152
|
}
|
|
167
153
|
if (layer.children) {
|
|
@@ -170,16 +156,14 @@ function getLargestLayerSize(layers) {
|
|
|
170
156
|
}
|
|
171
157
|
return max;
|
|
172
158
|
}
|
|
173
|
-
function writeSection(writer, round, func, writeTotalLength, large) {
|
|
174
|
-
if (writeTotalLength === void 0) { writeTotalLength = false; }
|
|
175
|
-
if (large === void 0) { large = false; }
|
|
159
|
+
function writeSection(writer, round, func, writeTotalLength = false, large = false) {
|
|
176
160
|
if (large)
|
|
177
161
|
writeUint32(writer, 0);
|
|
178
|
-
|
|
162
|
+
const offset = writer.offset;
|
|
179
163
|
writeUint32(writer, 0);
|
|
180
164
|
func();
|
|
181
|
-
|
|
182
|
-
|
|
165
|
+
let length = writer.offset - offset - 4;
|
|
166
|
+
let len = length;
|
|
183
167
|
while (len % round) {
|
|
184
168
|
writeUint8(writer, 0);
|
|
185
169
|
len++;
|
|
@@ -197,41 +181,40 @@ exports.writeSection = writeSection;
|
|
|
197
181
|
function verifyBitCount(target) {
|
|
198
182
|
var _a;
|
|
199
183
|
(_a = target.children) === null || _a === void 0 ? void 0 : _a.forEach(verifyBitCount);
|
|
200
|
-
|
|
184
|
+
const data = target.imageData;
|
|
201
185
|
if (data && (data.data instanceof Uint32Array || data.data instanceof Uint16Array)) {
|
|
202
186
|
throw new Error('imageData has incorrect bitDepth');
|
|
203
187
|
}
|
|
204
188
|
if ('mask' in target && target.mask) {
|
|
205
|
-
|
|
206
|
-
if (
|
|
189
|
+
const data = target.mask.imageData;
|
|
190
|
+
if (data && (data.data instanceof Uint32Array || data.data instanceof Uint16Array)) {
|
|
207
191
|
throw new Error('mask imageData has incorrect bitDepth');
|
|
208
192
|
}
|
|
209
193
|
}
|
|
210
194
|
}
|
|
211
|
-
function writePsd(writer, psd, options) {
|
|
195
|
+
function writePsd(writer, psd, options = {}) {
|
|
212
196
|
var _a;
|
|
213
|
-
if (options === void 0) { options = {}; }
|
|
214
197
|
if (!(+psd.width > 0 && +psd.height > 0))
|
|
215
198
|
throw new Error('Invalid document size');
|
|
216
199
|
if ((psd.width > 30000 || psd.height > 30000) && !options.psb)
|
|
217
200
|
throw new Error('Document size is too large (max is 30000x30000, use PSB format instead)');
|
|
218
|
-
|
|
201
|
+
const bitsPerChannel = (_a = psd.bitsPerChannel) !== null && _a !== void 0 ? _a : 8;
|
|
219
202
|
if (bitsPerChannel !== 8)
|
|
220
203
|
throw new Error('bitsPerChannel other than 8 are not supported for writing');
|
|
221
204
|
verifyBitCount(psd);
|
|
222
|
-
|
|
223
|
-
|
|
205
|
+
const imageResources = Object.assign({}, psd.imageResources);
|
|
206
|
+
const opt = Object.assign(Object.assign({}, options), { layerIds: new Set(), layerToId: new Map() });
|
|
224
207
|
if (opt.generateThumbnail) {
|
|
225
208
|
imageResources.thumbnail = createThumbnail(psd);
|
|
226
209
|
}
|
|
227
|
-
|
|
210
|
+
let imageData = psd.imageData;
|
|
228
211
|
if (!imageData && psd.canvas) {
|
|
229
212
|
imageData = psd.canvas.getContext('2d').getImageData(0, 0, psd.canvas.width, psd.canvas.height);
|
|
230
213
|
}
|
|
231
214
|
if (imageData && (psd.width !== imageData.width || psd.height !== imageData.height))
|
|
232
215
|
throw new Error('Document canvas must have the same size as document');
|
|
233
|
-
|
|
234
|
-
|
|
216
|
+
const globalAlpha = !!imageData && (0, helpers_1.hasAlpha)(imageData);
|
|
217
|
+
const maxBufferSize = Math.max(getLargestLayerSize(psd.children), 4 * 2 * psd.width * psd.height + 2 * psd.height);
|
|
235
218
|
writer.tempBuffer = new Uint8Array(maxBufferSize);
|
|
236
219
|
// header
|
|
237
220
|
writeSignature(writer, '8BPS');
|
|
@@ -243,55 +226,48 @@ function writePsd(writer, psd, options) {
|
|
|
243
226
|
writeUint16(writer, bitsPerChannel); // bits per channel
|
|
244
227
|
writeUint16(writer, 3 /* ColorMode.RGB */); // we only support saving RGB right now
|
|
245
228
|
// color mode data
|
|
246
|
-
writeSection(writer, 1,
|
|
229
|
+
writeSection(writer, 1, () => {
|
|
247
230
|
var _a, _b, _c;
|
|
248
231
|
if (psd.palette) {
|
|
249
|
-
for (
|
|
232
|
+
for (let i = 0; i < 256; i++)
|
|
250
233
|
writeUint8(writer, ((_a = psd.palette[i]) === null || _a === void 0 ? void 0 : _a.r) || 0);
|
|
251
|
-
for (
|
|
234
|
+
for (let i = 0; i < 256; i++)
|
|
252
235
|
writeUint8(writer, ((_b = psd.palette[i]) === null || _b === void 0 ? void 0 : _b.g) || 0);
|
|
253
|
-
for (
|
|
236
|
+
for (let i = 0; i < 256; i++)
|
|
254
237
|
writeUint8(writer, ((_c = psd.palette[i]) === null || _c === void 0 ? void 0 : _c.b) || 0);
|
|
255
238
|
}
|
|
256
239
|
// TODO: other data?
|
|
257
240
|
});
|
|
258
|
-
|
|
241
|
+
const layers = [];
|
|
259
242
|
addChildren(layers, psd.children);
|
|
260
243
|
if (!layers.length)
|
|
261
244
|
layers.push({});
|
|
262
245
|
// image resources
|
|
263
|
-
imageResources.layersGroup = layers.map(
|
|
264
|
-
imageResources.layerGroupsEnabledId = layers.map(
|
|
265
|
-
writeSection(writer, 1,
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
246
|
+
imageResources.layersGroup = layers.map(l => l.linkGroup || 0);
|
|
247
|
+
imageResources.layerGroupsEnabledId = layers.map(l => l.linkGroupEnabled == false ? 0 : 1);
|
|
248
|
+
writeSection(writer, 1, () => {
|
|
249
|
+
for (const handler of imageResources_1.resourceHandlers) {
|
|
250
|
+
const has = handler.has(imageResources);
|
|
251
|
+
const count = has === false ? 0 : (has === true ? 1 : has);
|
|
252
|
+
for (let i = 0; i < count; i++) {
|
|
270
253
|
writeSignature(writer, '8BIM');
|
|
271
254
|
writeUint16(writer, handler.key);
|
|
272
255
|
writePascalString(writer, '', 2);
|
|
273
|
-
writeSection(writer, 2,
|
|
274
|
-
};
|
|
275
|
-
for (var i = 0; i < count; i++) {
|
|
276
|
-
_loop_2(i);
|
|
256
|
+
writeSection(writer, 2, () => handler.write(writer, imageResources, i));
|
|
277
257
|
}
|
|
278
|
-
};
|
|
279
|
-
for (var _i = 0, resourceHandlers_1 = imageResources_1.resourceHandlers; _i < resourceHandlers_1.length; _i++) {
|
|
280
|
-
var handler = resourceHandlers_1[_i];
|
|
281
|
-
_loop_1(handler);
|
|
282
258
|
}
|
|
283
259
|
});
|
|
284
260
|
// layer and mask info
|
|
285
|
-
writeSection(writer, 2,
|
|
261
|
+
writeSection(writer, 2, () => {
|
|
286
262
|
writeLayerInfo(writer, layers, psd, globalAlpha, opt);
|
|
287
263
|
writeGlobalLayerMaskInfo(writer, psd.globalLayerMaskInfo);
|
|
288
264
|
writeAdditionalLayerInfo(writer, psd, psd, opt);
|
|
289
265
|
}, undefined, !!opt.psb);
|
|
290
266
|
// image data
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
267
|
+
const channels = globalAlpha ? [0, 1, 2, 3] : [0, 1, 2];
|
|
268
|
+
const width = imageData ? imageData.width : psd.width;
|
|
269
|
+
const height = imageData ? imageData.height : psd.height;
|
|
270
|
+
const data = { data: new Uint8Array(width * height * 4), width, height };
|
|
295
271
|
writeUint16(writer, 1 /* Compression.RleCompressed */); // Photoshop doesn't support zip compression of composite image data
|
|
296
272
|
if (helpers_1.RAW_IMAGE_DATA && psd.imageDataRaw) {
|
|
297
273
|
console.log('writing raw image data');
|
|
@@ -302,13 +278,13 @@ function writePsd(writer, psd, options) {
|
|
|
302
278
|
data.data.set(new Uint8Array(imageData.data.buffer, imageData.data.byteOffset, imageData.data.byteLength));
|
|
303
279
|
// add weird white matte
|
|
304
280
|
if (globalAlpha) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
for (
|
|
308
|
-
|
|
281
|
+
const size = data.width * data.height * 4;
|
|
282
|
+
const p = data.data;
|
|
283
|
+
for (let i = 0; i < size; i += 4) {
|
|
284
|
+
const pa = p[i + 3];
|
|
309
285
|
if (pa != 0 && pa != 255) {
|
|
310
|
-
|
|
311
|
-
|
|
286
|
+
const a = pa / 255;
|
|
287
|
+
const ra = 255 * (1 - a);
|
|
312
288
|
p[i + 0] = p[i + 0] * a + ra;
|
|
313
289
|
p[i + 1] = p[i + 1] * a + ra;
|
|
314
290
|
p[i + 2] = p[i + 2] * a + ra;
|
|
@@ -320,19 +296,19 @@ function writePsd(writer, psd, options) {
|
|
|
320
296
|
}
|
|
321
297
|
exports.writePsd = writePsd;
|
|
322
298
|
function writeLayerInfo(writer, layers, psd, globalAlpha, options) {
|
|
323
|
-
writeSection(writer, 4,
|
|
299
|
+
writeSection(writer, 4, () => {
|
|
324
300
|
var _a;
|
|
325
301
|
writeInt16(writer, globalAlpha ? -layers.length : layers.length);
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
302
|
+
const layersData = layers.map((l, i) => getChannels(writer.tempBuffer, l, i === 0, options));
|
|
303
|
+
// layer records
|
|
304
|
+
for (const layerData of layersData) {
|
|
305
|
+
const { layer, top, left, bottom, right, channels } = layerData;
|
|
306
|
+
writeInt32(writer, top);
|
|
330
307
|
writeInt32(writer, left);
|
|
331
308
|
writeInt32(writer, bottom);
|
|
332
309
|
writeInt32(writer, right);
|
|
333
310
|
writeUint16(writer, channels.length);
|
|
334
|
-
for (
|
|
335
|
-
var c = channels_1[_e];
|
|
311
|
+
for (const c of channels) {
|
|
336
312
|
writeInt16(writer, c.channelId);
|
|
337
313
|
if (options.psb)
|
|
338
314
|
writeUint32(writer, 0);
|
|
@@ -342,7 +318,7 @@ function writeLayerInfo(writer, layers, psd, globalAlpha, options) {
|
|
|
342
318
|
writeSignature(writer, helpers_1.fromBlendMode[layer.blendMode] || 'norm');
|
|
343
319
|
writeUint8(writer, Math.round((0, helpers_1.clamp)((_a = layer.opacity) !== null && _a !== void 0 ? _a : 1, 0, 1) * 255));
|
|
344
320
|
writeUint8(writer, layer.clipping ? 1 : 0);
|
|
345
|
-
|
|
321
|
+
let flags = 0x08; // 1 for Photoshop 5.0 and later, tells if bit 4 has useful information
|
|
346
322
|
if (layer.transparencyProtected)
|
|
347
323
|
flags |= 0x01;
|
|
348
324
|
if (layer.hidden)
|
|
@@ -354,23 +330,16 @@ function writeLayerInfo(writer, layers, psd, globalAlpha, options) {
|
|
|
354
330
|
flags |= 0x20;
|
|
355
331
|
writeUint8(writer, flags);
|
|
356
332
|
writeUint8(writer, 0); // filler
|
|
357
|
-
writeSection(writer, 1,
|
|
333
|
+
writeSection(writer, 1, () => {
|
|
358
334
|
writeLayerMaskData(writer, layer, layerData);
|
|
359
335
|
writeLayerBlendingRanges(writer, layer);
|
|
360
336
|
writePascalString(writer, (layer.name || '').substring(0, 255), 4);
|
|
361
337
|
writeAdditionalLayerInfo(writer, layer, psd, options);
|
|
362
338
|
});
|
|
363
|
-
};
|
|
364
|
-
// layer records
|
|
365
|
-
for (var _i = 0, layersData_1 = layersData; _i < layersData_1.length; _i++) {
|
|
366
|
-
var layerData = layersData_1[_i];
|
|
367
|
-
_loop_3(layerData);
|
|
368
339
|
}
|
|
369
340
|
// layer channel image data
|
|
370
|
-
for (
|
|
371
|
-
|
|
372
|
-
for (var _c = 0, _d = layerData.channels; _c < _d.length; _c++) {
|
|
373
|
-
var channel = _d[_c];
|
|
341
|
+
for (const layerData of layersData) {
|
|
342
|
+
for (const channel of layerData.channels) {
|
|
374
343
|
writeUint16(writer, channel.compression);
|
|
375
344
|
if (channel.buffer) {
|
|
376
345
|
writeBytes(writer, channel.buffer);
|
|
@@ -379,12 +348,11 @@ function writeLayerInfo(writer, layers, psd, globalAlpha, options) {
|
|
|
379
348
|
}
|
|
380
349
|
}, true, options.psb);
|
|
381
350
|
}
|
|
382
|
-
function writeLayerMaskData(writer,
|
|
383
|
-
|
|
384
|
-
writeSection(writer, 1, function () {
|
|
351
|
+
function writeLayerMaskData(writer, { mask, realMask }, layerData) {
|
|
352
|
+
writeSection(writer, 1, () => {
|
|
385
353
|
if (!mask && !realMask)
|
|
386
354
|
return;
|
|
387
|
-
|
|
355
|
+
let params = 0, flags = 0, realFlags = 0;
|
|
388
356
|
if (mask) {
|
|
389
357
|
if (mask.userMaskDensity !== undefined)
|
|
390
358
|
params |= 1 /* MaskParams.UserMaskDensity */;
|
|
@@ -403,7 +371,7 @@ function writeLayerMaskData(writer, _a, layerData) {
|
|
|
403
371
|
if (params)
|
|
404
372
|
flags |= 16 /* LayerMaskFlags.MaskHasParametersAppliedToIt */;
|
|
405
373
|
}
|
|
406
|
-
|
|
374
|
+
const m = layerData.mask || {};
|
|
407
375
|
writeInt32(writer, m.top || 0);
|
|
408
376
|
writeInt32(writer, m.left || 0);
|
|
409
377
|
writeInt32(writer, m.bottom || 0);
|
|
@@ -417,7 +385,7 @@ function writeLayerMaskData(writer, _a, layerData) {
|
|
|
417
385
|
realFlags |= 1 /* LayerMaskFlags.PositionRelativeToLayer */;
|
|
418
386
|
if (realMask.fromVectorData)
|
|
419
387
|
realFlags |= 8 /* LayerMaskFlags.LayerMaskFromRenderingOtherData */;
|
|
420
|
-
|
|
388
|
+
const r = layerData.realMask || {};
|
|
421
389
|
writeUint8(writer, realFlags);
|
|
422
390
|
writeUint8(writer, realMask.defaultColor || 0);
|
|
423
391
|
writeInt32(writer, r.top || 0);
|
|
@@ -446,13 +414,12 @@ function writerBlendingRange(writer, range) {
|
|
|
446
414
|
writeUint8(writer, range[3]);
|
|
447
415
|
}
|
|
448
416
|
function writeLayerBlendingRanges(writer, layer) {
|
|
449
|
-
writeSection(writer, 1,
|
|
450
|
-
|
|
417
|
+
writeSection(writer, 1, () => {
|
|
418
|
+
const ranges = layer.blendingRanges;
|
|
451
419
|
if (ranges) {
|
|
452
420
|
writerBlendingRange(writer, ranges.compositeGrayBlendSource);
|
|
453
421
|
writerBlendingRange(writer, ranges.compositeGraphBlendDestinationRange);
|
|
454
|
-
for (
|
|
455
|
-
var r = _a[_i];
|
|
422
|
+
for (const r of ranges.ranges) {
|
|
456
423
|
writerBlendingRange(writer, r.sourceRange);
|
|
457
424
|
writerBlendingRange(writer, r.destRange);
|
|
458
425
|
}
|
|
@@ -460,7 +427,7 @@ function writeLayerBlendingRanges(writer, layer) {
|
|
|
460
427
|
});
|
|
461
428
|
}
|
|
462
429
|
function writeGlobalLayerMaskInfo(writer, info) {
|
|
463
|
-
writeSection(writer, 1,
|
|
430
|
+
writeSection(writer, 1, () => {
|
|
464
431
|
if (info) {
|
|
465
432
|
writeUint16(writer, info.overlayColorSpace);
|
|
466
433
|
writeUint16(writer, info.colorSpace1);
|
|
@@ -474,28 +441,24 @@ function writeGlobalLayerMaskInfo(writer, info) {
|
|
|
474
441
|
});
|
|
475
442
|
}
|
|
476
443
|
function writeAdditionalLayerInfo(writer, target, psd, options) {
|
|
477
|
-
|
|
478
|
-
|
|
444
|
+
for (const handler of additionalInfo_1.infoHandlers) {
|
|
445
|
+
let key = handler.key;
|
|
479
446
|
if (key === 'Txt2' && options.invalidateTextLayers)
|
|
480
|
-
|
|
447
|
+
continue;
|
|
481
448
|
if (key === 'vmsk' && options.psb)
|
|
482
449
|
key = 'vsms';
|
|
483
450
|
if (handler.has(target)) {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
451
|
+
const large = options.psb && helpers_1.largeAdditionalInfoKeys.indexOf(key) !== -1;
|
|
452
|
+
const writeTotalLength = key !== 'Txt2' && key !== 'cinf' && key !== 'extn' && key !== 'CAI ' && key !== 'OCIO';
|
|
453
|
+
const fourBytes = key === 'Txt2' || key === 'luni' || key === 'vmsk' || key === 'artb' || key === 'artd' ||
|
|
487
454
|
key === 'vogk' || key === 'SoLd' || key === 'lnk2' || key === 'vscg' || key === 'vsms' || key === 'GdFl' ||
|
|
488
455
|
key === 'lmfx' || key === 'lrFX' || key === 'cinf' || key === 'PlLd' || key === 'Anno' || key === 'CAI ' || key === 'OCIO' || key === 'GenI' || key === 'FEid' || key === 'curv' || key === 'CgEd' || key === 'vibA' || key === 'blwh' || key === 'grdm';
|
|
489
456
|
writeSignature(writer, large ? '8B64' : '8BIM');
|
|
490
457
|
writeSignature(writer, key);
|
|
491
|
-
writeSection(writer, fourBytes ? 4 : 2,
|
|
458
|
+
writeSection(writer, fourBytes ? 4 : 2, () => {
|
|
492
459
|
handler.write(writer, target, psd, options);
|
|
493
460
|
}, writeTotalLength, large);
|
|
494
461
|
}
|
|
495
|
-
};
|
|
496
|
-
for (var _i = 0, infoHandlers_1 = additionalInfo_1.infoHandlers; _i < infoHandlers_1.length; _i++) {
|
|
497
|
-
var handler = infoHandlers_1[_i];
|
|
498
|
-
_loop_4(handler);
|
|
499
462
|
}
|
|
500
463
|
}
|
|
501
464
|
function addChildren(layers, children) {
|
|
@@ -503,12 +466,11 @@ function addChildren(layers, children) {
|
|
|
503
466
|
return;
|
|
504
467
|
// const layerIds: number[] = [2];
|
|
505
468
|
// const timestamps: number[] = [1740120767.0230637];
|
|
506
|
-
for (
|
|
507
|
-
var c = children_1[_i];
|
|
469
|
+
for (const c of children) {
|
|
508
470
|
if (c.children && c.canvas)
|
|
509
|
-
throw new Error(
|
|
471
|
+
throw new Error(`Invalid layer, cannot have both 'canvas' and 'children' properties`);
|
|
510
472
|
if (c.children && c.imageData)
|
|
511
|
-
throw new Error(
|
|
473
|
+
throw new Error(`Invalid layer, cannot have both 'imageData' and 'children' properties`);
|
|
512
474
|
if (c.children) {
|
|
513
475
|
layers.push({
|
|
514
476
|
name: '</Layer group>',
|
|
@@ -528,25 +490,25 @@ function addChildren(layers, children) {
|
|
|
528
490
|
// referencePoint: { x: 0, y: 0 },
|
|
529
491
|
});
|
|
530
492
|
addChildren(layers, c.children);
|
|
531
|
-
layers.push(
|
|
493
|
+
layers.push(Object.assign(Object.assign({}, c), { blendMode: c.blendMode === 'pass through' ? 'normal' : c.blendMode, sectionDivider: {
|
|
532
494
|
type: c.opened === false ? 2 /* SectionDividerType.ClosedFolder */ : 1 /* SectionDividerType.OpenFolder */,
|
|
533
495
|
key: helpers_1.fromBlendMode[c.blendMode] || 'pass',
|
|
534
496
|
subType: 0,
|
|
535
497
|
} }));
|
|
536
498
|
}
|
|
537
499
|
else {
|
|
538
|
-
layers.push(
|
|
500
|
+
layers.push(Object.assign({}, c));
|
|
539
501
|
}
|
|
540
502
|
}
|
|
541
503
|
}
|
|
542
504
|
function resizeBuffer(writer, size) {
|
|
543
|
-
|
|
505
|
+
let newLength = writer.buffer.byteLength;
|
|
544
506
|
do {
|
|
545
507
|
newLength *= 2;
|
|
546
508
|
} while (size > newLength);
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
509
|
+
const newBuffer = new ArrayBuffer(newLength);
|
|
510
|
+
const newBytes = new Uint8Array(newBuffer);
|
|
511
|
+
const oldBytes = new Uint8Array(writer.buffer);
|
|
550
512
|
newBytes.set(oldBytes);
|
|
551
513
|
writer.buffer = newBuffer;
|
|
552
514
|
writer.view = new DataView(writer.buffer);
|
|
@@ -557,13 +519,13 @@ function ensureSize(writer, size) {
|
|
|
557
519
|
}
|
|
558
520
|
}
|
|
559
521
|
function addSize(writer, size) {
|
|
560
|
-
|
|
522
|
+
const offset = writer.offset;
|
|
561
523
|
ensureSize(writer, writer.offset += size);
|
|
562
524
|
return offset;
|
|
563
525
|
}
|
|
564
526
|
function createThumbnail(psd) {
|
|
565
|
-
|
|
566
|
-
|
|
527
|
+
const canvas = (0, helpers_1.createCanvas)(10, 10);
|
|
528
|
+
let scale = 1;
|
|
567
529
|
if (psd.width > psd.height) {
|
|
568
530
|
canvas.width = 160;
|
|
569
531
|
canvas.height = Math.floor(psd.height * (canvas.width / psd.width));
|
|
@@ -574,7 +536,7 @@ function createThumbnail(psd) {
|
|
|
574
536
|
canvas.width = Math.floor(psd.width * (canvas.height / psd.height));
|
|
575
537
|
scale = canvas.height / psd.height;
|
|
576
538
|
}
|
|
577
|
-
|
|
539
|
+
const context = canvas.getContext('2d');
|
|
578
540
|
context.scale(scale, scale);
|
|
579
541
|
if (psd.imageData) {
|
|
580
542
|
context.drawImage((0, helpers_1.imageDataToCanvas)(psd.imageData), 0, 0);
|
|
@@ -585,12 +547,12 @@ function createThumbnail(psd) {
|
|
|
585
547
|
return canvas;
|
|
586
548
|
}
|
|
587
549
|
function getMaskChannels(tempBuffer, layerData, layer, mask, options, realMask) {
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
550
|
+
let top = mask.top | 0;
|
|
551
|
+
let left = mask.left | 0;
|
|
552
|
+
let right = mask.right | 0;
|
|
553
|
+
let bottom = mask.bottom | 0;
|
|
554
|
+
let { width, height } = getLayerDimentions(mask);
|
|
555
|
+
let imageData = mask.imageData;
|
|
594
556
|
if (!imageData && mask.canvas && width && height) {
|
|
595
557
|
imageData = mask.canvas.getContext('2d').getImageData(0, 0, width, height);
|
|
596
558
|
}
|
|
@@ -599,8 +561,8 @@ function getMaskChannels(tempBuffer, layerData, layer, mask, options, realMask)
|
|
|
599
561
|
}
|
|
600
562
|
right = left + width;
|
|
601
563
|
bottom = top + height;
|
|
602
|
-
|
|
603
|
-
|
|
564
|
+
let buffer;
|
|
565
|
+
let compression;
|
|
604
566
|
if (helpers_1.RAW_IMAGE_DATA && layer[realMask ? 'realMaskDataRaw' : 'maskDataRaw']) {
|
|
605
567
|
buffer = layer[realMask ? 'realMaskDataRaw' : 'maskDataRaw'];
|
|
606
568
|
compression = layer[realMask ? 'realMaskDataRawCompression' : 'maskDataRawCompression'];
|
|
@@ -617,36 +579,35 @@ function getMaskChannels(tempBuffer, layerData, layer, mask, options, realMask)
|
|
|
617
579
|
buffer = (0, helpers_1.writeDataRLE)(tempBuffer, imageData, [0], !!options.psb);
|
|
618
580
|
compression = 1 /* Compression.RleCompressed */;
|
|
619
581
|
}
|
|
620
|
-
layerData.channels.push({ channelId: realMask ? -3 /* ChannelID.RealUserMask */ : -2 /* ChannelID.UserMask */, compression
|
|
621
|
-
layerData[realMask ? 'realMask' : 'mask'] = { top
|
|
582
|
+
layerData.channels.push({ channelId: realMask ? -3 /* ChannelID.RealUserMask */ : -2 /* ChannelID.UserMask */, compression, buffer, length: 2 + buffer.length });
|
|
583
|
+
layerData[realMask ? 'realMask' : 'mask'] = { top, left, right, bottom };
|
|
622
584
|
}
|
|
623
585
|
function getChannels(tempBuffer, layer, background, options) {
|
|
624
|
-
|
|
586
|
+
const layerData = getLayerChannels(tempBuffer, layer, background, options);
|
|
625
587
|
if (layer.mask)
|
|
626
588
|
getMaskChannels(tempBuffer, layerData, layer, layer.mask, options, false);
|
|
627
589
|
if (layer.realMask)
|
|
628
590
|
getMaskChannels(tempBuffer, layerData, layer, layer.realMask, options, true);
|
|
629
591
|
return layerData;
|
|
630
592
|
}
|
|
631
|
-
function getLayerDimentions(
|
|
632
|
-
var _b, _c, _d
|
|
633
|
-
var canvas = _a.canvas, imageData = _a.imageData;
|
|
593
|
+
function getLayerDimentions({ canvas, imageData }) {
|
|
594
|
+
var _a, _b, _c, _d;
|
|
634
595
|
// this way in case canvas/imageData are incorrect objects without width/height properties
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
return { width
|
|
596
|
+
const width = (_b = (_a = imageData === null || imageData === void 0 ? void 0 : imageData.width) !== null && _a !== void 0 ? _a : canvas === null || canvas === void 0 ? void 0 : canvas.width) !== null && _b !== void 0 ? _b : 0;
|
|
597
|
+
const height = (_d = (_c = imageData === null || imageData === void 0 ? void 0 : imageData.height) !== null && _c !== void 0 ? _c : canvas === null || canvas === void 0 ? void 0 : canvas.height) !== null && _d !== void 0 ? _d : 0;
|
|
598
|
+
return { width, height };
|
|
638
599
|
}
|
|
639
600
|
function cropImageData(data, left, top, width, height) {
|
|
640
601
|
if (data.data instanceof Uint32Array || data.data instanceof Uint16Array) {
|
|
641
602
|
throw new Error('imageData has incorrect bit depth');
|
|
642
603
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
for (
|
|
647
|
-
for (
|
|
648
|
-
|
|
649
|
-
|
|
604
|
+
const croppedData = (0, helpers_1.createImageData)(width, height);
|
|
605
|
+
const srcData = data.data;
|
|
606
|
+
const dstData = croppedData.data;
|
|
607
|
+
for (let y = 0; y < height; y++) {
|
|
608
|
+
for (let x = 0; x < width; x++) {
|
|
609
|
+
let src = ((x + left) + (y + top) * data.width) * 4;
|
|
610
|
+
let dst = (x + y * width) * 4;
|
|
650
611
|
dstData[dst] = srcData[src];
|
|
651
612
|
dstData[dst + 1] = srcData[src + 1];
|
|
652
613
|
dstData[dst + 2] = srcData[src + 2];
|
|
@@ -657,27 +618,27 @@ function cropImageData(data, left, top, width, height) {
|
|
|
657
618
|
}
|
|
658
619
|
function getLayerChannels(tempBuffer, layer, background, options) {
|
|
659
620
|
var _a;
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
621
|
+
let top = layer.top | 0;
|
|
622
|
+
let left = layer.left | 0;
|
|
623
|
+
let right = layer.right | 0;
|
|
624
|
+
let bottom = layer.bottom | 0;
|
|
625
|
+
let channels = [
|
|
665
626
|
{ channelId: -1 /* ChannelID.Transparency */, compression: 0 /* Compression.RawData */, buffer: undefined, length: 2 },
|
|
666
627
|
{ channelId: 0 /* ChannelID.Color0 */, compression: 0 /* Compression.RawData */, buffer: undefined, length: 2 },
|
|
667
628
|
{ channelId: 1 /* ChannelID.Color1 */, compression: 0 /* Compression.RawData */, buffer: undefined, length: 2 },
|
|
668
629
|
{ channelId: 2 /* ChannelID.Color2 */, compression: 0 /* Compression.RawData */, buffer: undefined, length: 2 },
|
|
669
630
|
];
|
|
670
|
-
|
|
631
|
+
let { width, height } = getLayerDimentions(layer);
|
|
671
632
|
if (!(layer.canvas || layer.imageData) || !width || !height) {
|
|
672
633
|
right = left;
|
|
673
634
|
bottom = top;
|
|
674
|
-
return { layer
|
|
635
|
+
return { layer, top, left, right, bottom, channels };
|
|
675
636
|
}
|
|
676
637
|
right = left + width;
|
|
677
638
|
bottom = top + height;
|
|
678
|
-
|
|
639
|
+
let data = layer.imageData || layer.canvas.getContext('2d').getImageData(0, 0, width, height);
|
|
679
640
|
if (options.trimImageData) {
|
|
680
|
-
|
|
641
|
+
const trimmed = trimData(data);
|
|
681
642
|
if (trimmed.left !== 0 || trimmed.top !== 0 || trimmed.right !== data.width || trimmed.bottom !== data.height) {
|
|
682
643
|
left += trimmed.left;
|
|
683
644
|
top += trimmed.top;
|
|
@@ -686,11 +647,11 @@ function getLayerChannels(tempBuffer, layer, background, options) {
|
|
|
686
647
|
width = right - left;
|
|
687
648
|
height = bottom - top;
|
|
688
649
|
if (!width || !height)
|
|
689
|
-
return { layer
|
|
650
|
+
return { layer, top, left, right, bottom, channels };
|
|
690
651
|
data = cropImageData(data, trimmed.left, trimmed.top, width, height);
|
|
691
652
|
}
|
|
692
653
|
}
|
|
693
|
-
|
|
654
|
+
const channelIds = [
|
|
694
655
|
0 /* ChannelID.Color0 */,
|
|
695
656
|
1 /* ChannelID.Color1 */,
|
|
696
657
|
2 /* ChannelID.Color2 */,
|
|
@@ -698,10 +659,10 @@ function getLayerChannels(tempBuffer, layer, background, options) {
|
|
|
698
659
|
if (!background || options.noBackground || layer.mask || (0, helpers_1.hasAlpha)(data) || (helpers_1.RAW_IMAGE_DATA && ((_a = layer.imageDataRaw) === null || _a === void 0 ? void 0 : _a['-1']))) {
|
|
699
660
|
channelIds.unshift(-1 /* ChannelID.Transparency */);
|
|
700
661
|
}
|
|
701
|
-
channels = channelIds.map(
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
662
|
+
channels = channelIds.map(channelId => {
|
|
663
|
+
const offset = (0, helpers_1.offsetForChannel)(channelId, false); // TODO: psd.colorMode === ColorMode.CMYK);
|
|
664
|
+
let buffer;
|
|
665
|
+
let compression;
|
|
705
666
|
if (helpers_1.RAW_IMAGE_DATA && layer.imageDataRaw) {
|
|
706
667
|
// console.log('written raw layer image data');
|
|
707
668
|
buffer = layer.imageDataRaw[channelId];
|
|
@@ -715,26 +676,24 @@ function getLayerChannels(tempBuffer, layer, background, options) {
|
|
|
715
676
|
buffer = (0, helpers_1.writeDataRLE)(tempBuffer, data, [offset], !!options.psb);
|
|
716
677
|
compression = 1 /* Compression.RleCompressed */;
|
|
717
678
|
}
|
|
718
|
-
return { channelId
|
|
679
|
+
return { channelId, compression, buffer, length: 2 + buffer.length };
|
|
719
680
|
});
|
|
720
|
-
return { layer
|
|
681
|
+
return { layer, top, left, right, bottom, channels };
|
|
721
682
|
}
|
|
722
|
-
function isRowEmpty(
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
for (var i = start; i < end; i = (i + 4) | 0) {
|
|
683
|
+
function isRowEmpty({ data, width }, y, left, right) {
|
|
684
|
+
const start = ((y * width + left) * 4 + 3) | 0;
|
|
685
|
+
const end = (start + (right - left) * 4) | 0;
|
|
686
|
+
for (let i = start; i < end; i = (i + 4) | 0) {
|
|
727
687
|
if (data[i] !== 0) {
|
|
728
688
|
return false;
|
|
729
689
|
}
|
|
730
690
|
}
|
|
731
691
|
return true;
|
|
732
692
|
}
|
|
733
|
-
function isColEmpty(
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
for (var y = top, i = start; y < bottom; y++, i = (i + stride) | 0) {
|
|
693
|
+
function isColEmpty({ data, width }, x, top, bottom) {
|
|
694
|
+
const stride = (width * 4) | 0;
|
|
695
|
+
const start = (top * stride + x * 4 + 3) | 0;
|
|
696
|
+
for (let y = top, i = start; y < bottom; y++, i = (i + stride) | 0) {
|
|
738
697
|
if (data[i] !== 0) {
|
|
739
698
|
return false;
|
|
740
699
|
}
|
|
@@ -742,10 +701,10 @@ function isColEmpty(_a, x, top, bottom) {
|
|
|
742
701
|
return true;
|
|
743
702
|
}
|
|
744
703
|
function trimData(data) {
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
704
|
+
let top = 0;
|
|
705
|
+
let left = 0;
|
|
706
|
+
let right = data.width;
|
|
707
|
+
let bottom = data.height;
|
|
749
708
|
while (top < bottom && isRowEmpty(data, top, left, right))
|
|
750
709
|
top++;
|
|
751
710
|
while (bottom > top && isRowEmpty(data, bottom - 1, left, right))
|
|
@@ -754,7 +713,7 @@ function trimData(data) {
|
|
|
754
713
|
left++;
|
|
755
714
|
while (right > left && isColEmpty(data, right - 1, top, bottom))
|
|
756
715
|
right--;
|
|
757
|
-
return { top
|
|
716
|
+
return { top, left, right, bottom };
|
|
758
717
|
}
|
|
759
718
|
function writeColor(writer, color) {
|
|
760
719
|
if (!color) {
|
|
@@ -803,4 +762,64 @@ function writeColor(writer, color) {
|
|
|
803
762
|
}
|
|
804
763
|
}
|
|
805
764
|
exports.writeColor = writeColor;
|
|
765
|
+
// ponytail: only round-trips RGB 8-bit patterns; source colorMode (16-bit/Indexed) is not preserved,
|
|
766
|
+
// since readPattern already converted everything to RGBA. Upgrade if pattern colorMode must survive write.
|
|
767
|
+
function writePattern(writer, pattern) {
|
|
768
|
+
const width = pattern.bounds.w;
|
|
769
|
+
const height = pattern.bounds.h;
|
|
770
|
+
const pixelData = { width, height, data: pattern.data };
|
|
771
|
+
writeUint32(writer, 0); // length, fixed up below
|
|
772
|
+
const pattsOffset = writer.offset;
|
|
773
|
+
writeUint32(writer, 1); // version
|
|
774
|
+
writeUint32(writer, 3 /* ColorMode.RGB */); // color mode - rgb only
|
|
775
|
+
writeInt16(writer, pattern.x);
|
|
776
|
+
writeInt16(writer, pattern.y);
|
|
777
|
+
writeUnicodeString(writer, pattern.name + '\0'); // name
|
|
778
|
+
writePascalString(writer, pattern.id, 1); // id
|
|
779
|
+
// virtual memory array list
|
|
780
|
+
writeUint32(writer, 3); // version
|
|
781
|
+
writeUint32(writer, 0); // length, fixed up below
|
|
782
|
+
const vlOffset = writer.offset;
|
|
783
|
+
const top = pattern.bounds.y;
|
|
784
|
+
const left = pattern.bounds.x;
|
|
785
|
+
const bottom = top + height;
|
|
786
|
+
const right = left + width;
|
|
787
|
+
writeUint32(writer, top);
|
|
788
|
+
writeUint32(writer, left);
|
|
789
|
+
writeUint32(writer, bottom);
|
|
790
|
+
writeUint32(writer, right);
|
|
791
|
+
writeUint32(writer, 24); // channels count
|
|
792
|
+
// channels: RGB at indices 0,1,2 and alpha at index 25
|
|
793
|
+
for (let i = 0; i < 24 + 2; i++) {
|
|
794
|
+
const offset = i < 3 ? i : (i === 25 ? 3 : -1);
|
|
795
|
+
if (offset < 0) {
|
|
796
|
+
writeUint32(writer, 0); // has
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
// worst-case RLE size for a single channel: width + 1 per scanline, plus scanline length headers
|
|
800
|
+
const buffer = new Uint8Array(width * height + 2 * height + 2 * width + 16);
|
|
801
|
+
// ponytail: pattern channels always use small (2-byte) RLE scanline headers, matching
|
|
802
|
+
// readPattern which reads them as non-large; `large` here only affects the header width.
|
|
803
|
+
const data = (0, helpers_1.writeDataRLE)(buffer, pixelData, [offset], false);
|
|
804
|
+
writeUint32(writer, 1); // has
|
|
805
|
+
writeUint32(writer, data.length + 4 + 16 + 2 + 1); // length
|
|
806
|
+
writeUint32(writer, 8); // pixelDepth
|
|
807
|
+
writeUint32(writer, top);
|
|
808
|
+
writeUint32(writer, left);
|
|
809
|
+
writeUint32(writer, bottom);
|
|
810
|
+
writeUint32(writer, right);
|
|
811
|
+
writeUint16(writer, 8); // pixelDepth2
|
|
812
|
+
writeUint8(writer, 1); // compressionMode - rle
|
|
813
|
+
writeBytes(writer, data);
|
|
814
|
+
}
|
|
815
|
+
const vlLength = writer.offset - vlOffset;
|
|
816
|
+
let pattsLength = writer.offset - pattsOffset;
|
|
817
|
+
while (pattsLength % 4) {
|
|
818
|
+
writeZeros(writer, 1);
|
|
819
|
+
pattsLength++;
|
|
820
|
+
}
|
|
821
|
+
writer.view.setUint32(vlOffset - 4, vlLength, false);
|
|
822
|
+
writer.view.setUint32(pattsOffset - 4, pattsLength, false);
|
|
823
|
+
}
|
|
824
|
+
exports.writePattern = writePattern;
|
|
806
825
|
//# sourceMappingURL=psdWriter.js.map
|