ag-psd 19.0.1 → 20.1.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README_PSD.md +20 -2
  3. package/TODO +7 -0
  4. package/dist/abr.js +4 -4
  5. package/dist/abr.js.map +1 -1
  6. package/dist/additionalInfo.d.ts +3 -3
  7. package/dist/additionalInfo.js +107 -12
  8. package/dist/additionalInfo.js.map +1 -1
  9. package/dist/bundle.js +15305 -7643
  10. package/dist/descriptor.js +21 -16
  11. package/dist/descriptor.js.map +1 -1
  12. package/dist/engineData2.d.ts +1 -0
  13. package/dist/engineData2.js +349 -0
  14. package/dist/engineData2.js.map +1 -0
  15. package/dist/helpers.d.ts +2 -7
  16. package/dist/helpers.js +45 -12
  17. package/dist/helpers.js.map +1 -1
  18. package/dist/imageResources.js +42 -1
  19. package/dist/imageResources.js.map +1 -1
  20. package/dist/psd.d.ts +46 -3
  21. package/dist/psd.js +8 -1
  22. package/dist/psd.js.map +1 -1
  23. package/dist/psdReader.d.ts +11 -5
  24. package/dist/psdReader.js +213 -100
  25. package/dist/psdReader.js.map +1 -1
  26. package/dist/psdWriter.js +24 -4
  27. package/dist/psdWriter.js.map +1 -1
  28. package/dist/utf8.js +10 -4
  29. package/dist/utf8.js.map +1 -1
  30. package/dist-es/abr.js +4 -4
  31. package/dist-es/abr.js.map +1 -1
  32. package/dist-es/additionalInfo.d.ts +3 -3
  33. package/dist-es/additionalInfo.js +110 -15
  34. package/dist-es/additionalInfo.js.map +1 -1
  35. package/dist-es/descriptor.js +21 -16
  36. package/dist-es/descriptor.js.map +1 -1
  37. package/dist-es/engineData2.d.ts +1 -0
  38. package/dist-es/engineData2.js +345 -0
  39. package/dist-es/engineData2.js.map +1 -0
  40. package/dist-es/helpers.d.ts +2 -7
  41. package/dist-es/helpers.js +43 -11
  42. package/dist-es/helpers.js.map +1 -1
  43. package/dist-es/imageResources.js +42 -1
  44. package/dist-es/imageResources.js.map +1 -1
  45. package/dist-es/psd.d.ts +46 -3
  46. package/dist-es/psd.js +7 -0
  47. package/dist-es/psd.js.map +1 -1
  48. package/dist-es/psdReader.d.ts +11 -5
  49. package/dist-es/psdReader.js +212 -102
  50. package/dist-es/psdReader.js.map +1 -1
  51. package/dist-es/psdWriter.js +25 -5
  52. package/dist-es/psdWriter.js.map +1 -1
  53. package/dist-es/utf8.js +10 -4
  54. package/dist-es/utf8.js.map +1 -1
  55. package/package.json +6 -7
  56. package/src/abr.ts +4 -4
  57. package/src/additionalInfo.ts +156 -51
  58. package/src/descriptor.ts +14 -9
  59. package/src/engineData2.ts +367 -0
  60. package/src/helpers.ts +47 -20
  61. package/src/imageResources.ts +59 -2
  62. package/src/psd.ts +41 -5
  63. package/src/psdReader.ts +210 -128
  64. package/src/psdWriter.ts +33 -14
  65. package/src/utf8.ts +12 -4
package/src/psdWriter.ts CHANGED
@@ -1,9 +1,5 @@
1
- import { Psd, Layer, LayerAdditionalInfo, ColorMode, SectionDividerType, WriteOptions, Color, GlobalLayerMaskInfo } from './psd';
2
- import {
3
- hasAlpha, createCanvas, writeDataRLE, PixelData, LayerChannelData, ChannelData,
4
- offsetForChannel, createImageData, fromBlendMode, ChannelID, Compression, clamp,
5
- LayerMaskFlags, MaskParams, ColorSpace, Bounds, largeAdditionalInfoKeys, RAW_IMAGE_DATA, writeDataZipWithoutPrediction
6
- } from './helpers';
1
+ import { Psd, Layer, LayerAdditionalInfo, ColorMode, SectionDividerType, WriteOptions, Color, GlobalLayerMaskInfo, PixelData } from './psd';
2
+ import { hasAlpha, createCanvas, writeDataRLE, LayerChannelData, ChannelData, offsetForChannel, createImageData, fromBlendMode, ChannelID, Compression, clamp, LayerMaskFlags, MaskParams, ColorSpace, Bounds, largeAdditionalInfoKeys, RAW_IMAGE_DATA, writeDataZipWithoutPrediction, imageDataToCanvas } from './helpers';
7
3
  import { ExtendedWriteOptions, infoHandlers } from './additionalInfo';
8
4
  import { resourceHandlers } from './imageResources';
9
5
 
@@ -189,6 +185,22 @@ export function writeSection(writer: PsdWriter, round: number, func: () => void,
189
185
  writer.view.setUint32(offset, length, false);
190
186
  }
191
187
 
188
+ function verifyBitCount(target: Psd | Layer) {
189
+ target.children?.forEach(verifyBitCount);
190
+
191
+ const data = target.imageData;
192
+ if (data && (data.data instanceof Uint32Array || data.data instanceof Uint16Array)) {
193
+ throw new Error('imageData has incorrect bitDepth');
194
+ }
195
+
196
+ if ('mask' in target && target.mask) {
197
+ const data = target.mask.imageData;
198
+ if (data && (data.data instanceof Uint32Array || data.data instanceof Uint16Array)) {
199
+ throw new Error('mask imageData has incorrect bitDepth');
200
+ }
201
+ }
202
+ }
203
+
192
204
  export function writePsd(writer: PsdWriter, psd: Psd, options: WriteOptions = {}) {
193
205
  if (!(+psd.width > 0 && +psd.height > 0))
194
206
  throw new Error('Invalid document size');
@@ -196,6 +208,13 @@ export function writePsd(writer: PsdWriter, psd: Psd, options: WriteOptions = {}
196
208
  if ((psd.width > 30000 || psd.height > 30000) && !options.psb)
197
209
  throw new Error('Document size is too large (max is 30000x30000, use PSB format instead)');
198
210
 
211
+ const bitsPerChannel = psd.bitsPerChannel ?? 8;
212
+
213
+ if (bitsPerChannel !== 8)
214
+ throw new Error('bitsPerChannel other than 8 are not supported for writing');
215
+
216
+ verifyBitCount(psd);
217
+
199
218
  let imageResources = psd.imageResources || {};
200
219
 
201
220
  const opt: ExtendedWriteOptions = { ...options, layerIds: new Set(), layerToId: new Map() };
@@ -224,7 +243,7 @@ export function writePsd(writer: PsdWriter, psd: Psd, options: WriteOptions = {}
224
243
  writeUint16(writer, globalAlpha ? 4 : 3); // channels
225
244
  writeUint32(writer, psd.height);
226
245
  writeUint32(writer, psd.width);
227
- writeUint16(writer, 8); // bits per channel
246
+ writeUint16(writer, bitsPerChannel); // bits per channel
228
247
  writeUint16(writer, ColorMode.RGB); // we only support saving RGB right now
229
248
 
230
249
  // color mode data
@@ -525,9 +544,7 @@ function createThumbnail(psd: Psd) {
525
544
  context.scale(scale, scale);
526
545
 
527
546
  if (psd.imageData) {
528
- const temp = createCanvas(psd.imageData.width, psd.imageData.height);
529
- temp.getContext('2d')!.putImageData(psd.imageData, 0, 0);
530
- context.drawImage(temp, 0, 0);
547
+ context.drawImage(imageDataToCanvas(psd.imageData), 0, 0);
531
548
  } else if (psd.canvas) {
532
549
  context.drawImage(psd.canvas, 0, 0);
533
550
  }
@@ -590,7 +607,11 @@ function getLayerDimentions({ canvas, imageData }: Layer): { width: number; heig
590
607
  return imageData || canvas || { width: 0, height: 0 };
591
608
  }
592
609
 
593
- function cropImageData(data: ImageData, left: number, top: number, width: number, height: number) {
610
+ function cropImageData(data: PixelData, left: number, top: number, width: number, height: number) {
611
+ if (data.data instanceof Uint32Array || data.data instanceof Uint16Array) {
612
+ throw new Error('imageData has incorrect bit depth');
613
+ }
614
+
594
615
  const croppedData = createImageData(width, height);
595
616
  const srcData = data.data;
596
617
  const dstData = croppedData.data;
@@ -609,9 +630,7 @@ function cropImageData(data: ImageData, left: number, top: number, width: number
609
630
  return croppedData;
610
631
  }
611
632
 
612
- function getLayerChannels(
613
- tempBuffer: Uint8Array, layer: Layer, background: boolean, options: WriteOptions
614
- ): LayerChannelData {
633
+ function getLayerChannels(tempBuffer: Uint8Array, layer: Layer, background: boolean, options: WriteOptions): LayerChannelData {
615
634
  let top = (layer.top as any) | 0;
616
635
  let left = (layer.left as any) | 0;
617
636
  let right = (layer.right as any) | 0;
package/src/utf8.ts CHANGED
@@ -87,6 +87,10 @@ export function encodeStringTo(buffer: Uint8Array | Buffer, offset: number, valu
87
87
  }
88
88
 
89
89
  export function encodeString(value: string): Uint8Array {
90
+ if (value.length > 1000 && typeof TextEncoder !== 'undefined') {
91
+ return (new TextEncoder()).encode(value);
92
+ }
93
+
90
94
  const buffer = new Uint8Array(stringLengthInBytes(value));
91
95
  encodeStringTo(buffer, 0, value);
92
96
  return buffer;
@@ -107,7 +111,11 @@ function continuationByte(buffer: Uint8Array, index: number): number {
107
111
  }
108
112
 
109
113
  export function decodeString(value: Uint8Array): string {
110
- let result = '';
114
+ if (value.byteLength > 1000 && typeof TextDecoder !== 'undefined') {
115
+ return (new TextDecoder()).decode(value);
116
+ }
117
+
118
+ let result: string[] = [];
111
119
 
112
120
  for (let i = 0; i < value.length;) {
113
121
  const byte1 = value[i++];
@@ -149,12 +157,12 @@ export function decodeString(value: Uint8Array): string {
149
157
 
150
158
  if (code > 0xffff) {
151
159
  code -= 0x10000;
152
- result += String.fromCharCode(code >>> 10 & 0x3ff | 0xd800);
160
+ result.push(String.fromCharCode(code >>> 10 & 0x3ff | 0xd800));
153
161
  code = 0xdc00 | code & 0x3ff;
154
162
  }
155
163
 
156
- result += String.fromCharCode(code);
164
+ result.push(String.fromCharCode(code));
157
165
  }
158
166
 
159
- return result;
167
+ return result.join('');
160
168
  }