@yft-design/psd-lib 1.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.
@@ -0,0 +1,300 @@
1
+ import { fromByteArray } from 'base64-js';
2
+ import { deflate as deflateSync } from 'pako';
3
+ export const MOCK_HANDLERS = false;
4
+ export const RAW_IMAGE_DATA = false;
5
+ export const fromBlendMode = {};
6
+ export const toBlendMode = {
7
+ 'pass': 'pass through',
8
+ 'norm': 'normal',
9
+ 'diss': 'dissolve',
10
+ 'dark': 'darken',
11
+ 'mul ': 'multiply',
12
+ 'idiv': 'color burn',
13
+ 'lbrn': 'linear burn',
14
+ 'dkCl': 'darker color',
15
+ 'lite': 'lighten',
16
+ 'scrn': 'screen',
17
+ 'div ': 'color dodge',
18
+ 'lddg': 'linear dodge',
19
+ 'lgCl': 'lighter color',
20
+ 'over': 'overlay',
21
+ 'sLit': 'soft light',
22
+ 'hLit': 'hard light',
23
+ 'vLit': 'vivid light',
24
+ 'lLit': 'linear light',
25
+ 'pLit': 'pin light',
26
+ 'hMix': 'hard mix',
27
+ 'diff': 'difference',
28
+ 'smud': 'exclusion',
29
+ 'fsub': 'subtract',
30
+ 'fdiv': 'divide',
31
+ 'hue ': 'hue',
32
+ 'sat ': 'saturation',
33
+ 'colr': 'color',
34
+ 'lum ': 'luminosity',
35
+ };
36
+ Object.keys(toBlendMode).forEach(key => fromBlendMode[toBlendMode[key]] = key);
37
+ export const layerColors = [
38
+ 'none', 'red', 'orange', 'yellow', 'green', 'blue', 'violet', 'gray'
39
+ ];
40
+ export const largeAdditionalInfoKeys = [
41
+ // from documentation
42
+ 'LMsk', 'Lr16', 'Lr32', 'Layr', 'Mt16', 'Mt32', 'Mtrn', 'Alph', 'FMsk', 'lnk2', 'FEid', 'FXid', 'PxSD',
43
+ // from guessing
44
+ 'cinf',
45
+ ];
46
+ export function revMap(map) {
47
+ const result = {};
48
+ Object.keys(map).forEach(key => result[map[key]] = key);
49
+ return result;
50
+ }
51
+ export function createEnum(prefix, def, map) {
52
+ const rev = revMap(map);
53
+ const decode = (val) => {
54
+ const value = val.split('.')[1];
55
+ if (value && !rev[value])
56
+ throw new Error(`Unrecognized value for enum: '${val}'`);
57
+ return rev[value] || def;
58
+ };
59
+ const encode = (val) => {
60
+ if (val && !map[val])
61
+ throw new Error(`Invalid value for enum: '${val}'`);
62
+ return `${prefix}.${map[val] || map[def]}`;
63
+ };
64
+ return { decode, encode };
65
+ }
66
+ export function offsetForChannel(channelId, cmyk) {
67
+ switch (channelId) {
68
+ case 0 /* ChannelID.Color0 */: return 0;
69
+ case 1 /* ChannelID.Color1 */: return 1;
70
+ case 2 /* ChannelID.Color2 */: return 2;
71
+ case 3 /* ChannelID.Color3 */: return cmyk ? 3 : channelId + 1;
72
+ case -1 /* ChannelID.Transparency */: return cmyk ? 4 : 3;
73
+ default: return channelId + 1;
74
+ }
75
+ }
76
+ export function clamp(value, min, max) {
77
+ return value < min ? min : (value > max ? max : value);
78
+ }
79
+ export function hasAlpha(data) {
80
+ const size = data.width * data.height * 4;
81
+ for (let i = 3; i < size; i += 4) {
82
+ if (data.data[i] !== 255) {
83
+ return true;
84
+ }
85
+ }
86
+ return false;
87
+ }
88
+ export function resetImageData({ data }) {
89
+ const alpha = (data instanceof Float32Array) ? 1.0 : ((data instanceof Uint16Array) ? 0xffff : 0xff);
90
+ for (let p = 0, size = data.length | 0; p < size; p = (p + 4) | 0) {
91
+ data[p + 0] = 0;
92
+ data[p + 1] = 0;
93
+ data[p + 2] = 0;
94
+ data[p + 3] = alpha;
95
+ }
96
+ }
97
+ export function imageDataToCanvas(pixelData) {
98
+ const canvas = createCanvas(pixelData.width, pixelData.height);
99
+ let imageData;
100
+ if (pixelData.data instanceof Uint8ClampedArray) {
101
+ imageData = pixelData;
102
+ }
103
+ else {
104
+ imageData = createImageData(pixelData.width, pixelData.height);
105
+ const src = pixelData.data;
106
+ const dst = imageData.data;
107
+ if (src instanceof Float32Array) {
108
+ for (let i = 0, size = src.length; i < size; i += 4) {
109
+ dst[i + 0] = Math.round(Math.pow(src[i + 0], 1.0 / 2.2) * 255);
110
+ dst[i + 1] = Math.round(Math.pow(src[i + 1], 1.0 / 2.2) * 255);
111
+ dst[i + 2] = Math.round(Math.pow(src[i + 2], 1.0 / 2.2) * 255);
112
+ dst[i + 3] = Math.round(src[i + 3] * 255);
113
+ }
114
+ }
115
+ else {
116
+ const shift = (src instanceof Uint16Array) ? 8 : 0;
117
+ for (let i = 0, size = src.length; i < size; i++) {
118
+ dst[i] = src[i] >>> shift;
119
+ }
120
+ }
121
+ }
122
+ canvas.getContext('2d').putImageData(imageData, 0, 0);
123
+ return canvas;
124
+ }
125
+ export function decodeBitmap(input, output, width, height) {
126
+ if (!(input instanceof Uint8Array || input instanceof Uint8ClampedArray))
127
+ throw new Error('Invalid bit depth');
128
+ for (let y = 0, p = 0, o = 0; y < height; y++) {
129
+ for (let x = 0; x < width;) {
130
+ let b = input[o++];
131
+ for (let i = 0; i < 8 && x < width; i++, x++, p += 4) {
132
+ const v = b & 0x80 ? 0 : 255;
133
+ b = b << 1;
134
+ output[p + 0] = v;
135
+ output[p + 1] = v;
136
+ output[p + 2] = v;
137
+ output[p + 3] = 255;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ export function writeDataRaw(data, offset, width, height) {
143
+ if (!width || !height)
144
+ return undefined;
145
+ const array = new Uint8Array(width * height);
146
+ for (let i = 0; i < array.length; i++) {
147
+ array[i] = data.data[i * 4 + offset];
148
+ }
149
+ return array;
150
+ }
151
+ export function writeDataRLE(buffer, { data, width, height }, offsets, large) {
152
+ if (!width || !height)
153
+ return undefined;
154
+ const stride = (4 * width) | 0;
155
+ let ol = 0;
156
+ let o = (offsets.length * (large ? 4 : 2) * height) | 0;
157
+ for (const offset of offsets) {
158
+ for (let y = 0, p = offset | 0; y < height; y++) {
159
+ const strideStart = (y * stride) | 0;
160
+ const strideEnd = (strideStart + stride) | 0;
161
+ const lastIndex = (strideEnd + offset - 4) | 0;
162
+ const lastIndex2 = (lastIndex - 4) | 0;
163
+ const startOffset = o;
164
+ for (p = (strideStart + offset) | 0; p < strideEnd; p = (p + 4) | 0) {
165
+ if (p < lastIndex2) {
166
+ let value1 = data[p];
167
+ p = (p + 4) | 0;
168
+ let value2 = data[p];
169
+ p = (p + 4) | 0;
170
+ let value3 = data[p];
171
+ if (value1 === value2 && value1 === value3) {
172
+ let count = 3;
173
+ while (count < 128 && p < lastIndex && data[(p + 4) | 0] === value1) {
174
+ count = (count + 1) | 0;
175
+ p = (p + 4) | 0;
176
+ }
177
+ buffer[o++] = 1 - count;
178
+ buffer[o++] = value1;
179
+ }
180
+ else {
181
+ const countIndex = o;
182
+ let writeLast = true;
183
+ let count = 1;
184
+ buffer[o++] = 0;
185
+ buffer[o++] = value1;
186
+ while (p < lastIndex && count < 128) {
187
+ p = (p + 4) | 0;
188
+ value1 = value2;
189
+ value2 = value3;
190
+ value3 = data[p];
191
+ if (value1 === value2 && value1 === value3) {
192
+ p = (p - 12) | 0;
193
+ writeLast = false;
194
+ break;
195
+ }
196
+ else {
197
+ count++;
198
+ buffer[o++] = value1;
199
+ }
200
+ }
201
+ if (writeLast) {
202
+ if (count < 127) {
203
+ buffer[o++] = value2;
204
+ buffer[o++] = value3;
205
+ count += 2;
206
+ }
207
+ else if (count < 128) {
208
+ buffer[o++] = value2;
209
+ count++;
210
+ p = (p - 4) | 0;
211
+ }
212
+ else {
213
+ p = (p - 8) | 0;
214
+ }
215
+ }
216
+ buffer[countIndex] = count - 1;
217
+ }
218
+ }
219
+ else if (p === lastIndex) {
220
+ buffer[o++] = 0;
221
+ buffer[o++] = data[p];
222
+ }
223
+ else { // p === lastIndex2
224
+ buffer[o++] = 1;
225
+ buffer[o++] = data[p];
226
+ p = (p + 4) | 0;
227
+ buffer[o++] = data[p];
228
+ }
229
+ }
230
+ const length = o - startOffset;
231
+ if (large) {
232
+ buffer[ol++] = (length >> 24) & 0xff;
233
+ buffer[ol++] = (length >> 16) & 0xff;
234
+ }
235
+ buffer[ol++] = (length >> 8) & 0xff;
236
+ buffer[ol++] = length & 0xff;
237
+ }
238
+ }
239
+ return buffer.slice(0, o);
240
+ }
241
+ export function writeDataZipWithoutPrediction({ data, width, height }, offsets) {
242
+ const size = width * height;
243
+ const channel = new Uint8Array(size);
244
+ const buffers = [];
245
+ let totalLength = 0;
246
+ for (const offset of offsets) {
247
+ for (let i = 0, o = offset; i < size; i++, o += 4) {
248
+ channel[i] = data[o];
249
+ }
250
+ const buffer = deflateSync(channel);
251
+ buffers.push(buffer);
252
+ totalLength += buffer.byteLength;
253
+ }
254
+ if (buffers.length > 0) {
255
+ const buffer = new Uint8Array(totalLength);
256
+ let offset = 0;
257
+ for (const b of buffers) {
258
+ buffer.set(b, offset);
259
+ offset += b.byteLength;
260
+ }
261
+ return buffer;
262
+ }
263
+ else {
264
+ return buffers[0];
265
+ }
266
+ }
267
+ export let createCanvas = () => {
268
+ throw new Error('Canvas not initialized, use initializeCanvas method to set up createCanvas method');
269
+ };
270
+ export let createCanvasFromData = () => {
271
+ throw new Error('Canvas not initialized, use initializeCanvas method to set up createCanvasFromData method');
272
+ };
273
+ let tempCanvas = undefined;
274
+ export let createImageData = (width, height) => {
275
+ if (!tempCanvas)
276
+ tempCanvas = createCanvas(1, 1);
277
+ return tempCanvas.getContext('2d').createImageData(width, height);
278
+ };
279
+ if (typeof document !== 'undefined') {
280
+ createCanvas = (width, height) => {
281
+ const canvas = document.createElement('canvas');
282
+ canvas.width = width;
283
+ canvas.height = height;
284
+ return canvas;
285
+ };
286
+ createCanvasFromData = (data) => {
287
+ const image = new Image();
288
+ image.src = 'data:image/jpeg;base64,' + fromByteArray(data);
289
+ const canvas = document.createElement('canvas');
290
+ canvas.width = image.width;
291
+ canvas.height = image.height;
292
+ canvas.getContext('2d').drawImage(image, 0, 0);
293
+ return canvas;
294
+ };
295
+ }
296
+ export function initializeCanvas(createCanvasMethod, createCanvasFromDataMethod, createImageDataMethod) {
297
+ createCanvas = createCanvasMethod;
298
+ createCanvasFromData = createCanvasFromDataMethod || createCanvasFromData;
299
+ createImageData = createImageDataMethod || createImageData;
300
+ }
@@ -0,0 +1,17 @@
1
+ import { ImageResources } from './psd';
2
+ import { PsdReader } from './psdReader';
3
+ import { PsdWriter } from './psdWriter';
4
+ export interface InternalImageResources extends ImageResources {
5
+ layersGroup?: number[];
6
+ layerGroupsEnabledId?: number[];
7
+ }
8
+ export interface ResourceHandler {
9
+ key: number;
10
+ has: (target: InternalImageResources) => boolean | number;
11
+ read: (reader: PsdReader, target: InternalImageResources, left: () => number) => void;
12
+ write: (writer: PsdWriter, target: InternalImageResources, index: number) => void;
13
+ }
14
+ export declare const resourceHandlers: ResourceHandler[];
15
+ export declare const resourceHandlersMap: {
16
+ [key: number]: ResourceHandler;
17
+ };