ag-psd 19.0.0 → 20.0.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 (53) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README_PSD.md +6 -0
  3. package/TODO +5 -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 +99 -10
  8. package/dist/additionalInfo.js.map +1 -1
  9. package/dist/bundle.js +408 -151
  10. package/dist/descriptor.js +21 -16
  11. package/dist/descriptor.js.map +1 -1
  12. package/dist/helpers.d.ts +2 -7
  13. package/dist/helpers.js +33 -10
  14. package/dist/helpers.js.map +1 -1
  15. package/dist/imageResources.js +37 -0
  16. package/dist/imageResources.js.map +1 -1
  17. package/dist/psd.d.ts +46 -3
  18. package/dist/psd.js +8 -1
  19. package/dist/psd.js.map +1 -1
  20. package/dist/psdReader.d.ts +11 -5
  21. package/dist/psdReader.js +179 -97
  22. package/dist/psdReader.js.map +1 -1
  23. package/dist/psdWriter.js +27 -13
  24. package/dist/psdWriter.js.map +1 -1
  25. package/dist-es/abr.js +4 -4
  26. package/dist-es/abr.js.map +1 -1
  27. package/dist-es/additionalInfo.d.ts +3 -3
  28. package/dist-es/additionalInfo.js +102 -13
  29. package/dist-es/additionalInfo.js.map +1 -1
  30. package/dist-es/descriptor.js +21 -16
  31. package/dist-es/descriptor.js.map +1 -1
  32. package/dist-es/helpers.d.ts +2 -7
  33. package/dist-es/helpers.js +31 -9
  34. package/dist-es/helpers.js.map +1 -1
  35. package/dist-es/imageResources.js +37 -0
  36. package/dist-es/imageResources.js.map +1 -1
  37. package/dist-es/psd.d.ts +46 -3
  38. package/dist-es/psd.js +7 -0
  39. package/dist-es/psd.js.map +1 -1
  40. package/dist-es/psdReader.d.ts +11 -5
  41. package/dist-es/psdReader.js +178 -99
  42. package/dist-es/psdReader.js.map +1 -1
  43. package/dist-es/psdWriter.js +28 -14
  44. package/dist-es/psdWriter.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/abr.ts +4 -4
  47. package/src/additionalInfo.ts +142 -49
  48. package/src/descriptor.ts +14 -9
  49. package/src/helpers.ts +35 -18
  50. package/src/imageResources.ts +53 -0
  51. package/src/psd.ts +41 -5
  52. package/src/psdReader.ts +170 -126
  53. package/src/psdWriter.ts +36 -23
@@ -10,7 +10,7 @@ var __assign = (this && this.__assign) || function () {
10
10
  return __assign.apply(this, arguments);
11
11
  };
12
12
  import { inflate } from 'pako';
13
- import { resetImageData, offsetForChannel, decodeBitmap, createCanvas, createImageData, toBlendMode, RAW_IMAGE_DATA, largeAdditionalInfoKeys } from './helpers';
13
+ import { resetImageData, offsetForChannel, decodeBitmap, createImageData, toBlendMode, RAW_IMAGE_DATA, largeAdditionalInfoKeys, imageDataToCanvas } from './helpers';
14
14
  import { infoHandlersMap } from './additionalInfo';
15
15
  import { resourceHandlersMap } from './imageResources';
16
16
  export var supportedColorModes = [0 /* ColorMode.Bitmap */, 1 /* ColorMode.Grayscale */, 3 /* ColorMode.RGB */];
@@ -160,9 +160,9 @@ function readShortString(reader, length) {
160
160
  function isValidSignature(sig) {
161
161
  return sig === '8BIM' || sig === 'MeSa' || sig === 'AgHg' || sig === 'PHUT' || sig === 'DCSR';
162
162
  }
163
- export function readPsd(reader, options) {
163
+ export function readPsd(reader, readOptions) {
164
164
  var _a;
165
- if (options === void 0) { options = {}; }
165
+ if (readOptions === void 0) { readOptions = {}; }
166
166
  // header
167
167
  checkSignature(reader, '8BPS');
168
168
  var version = readUint16(reader);
@@ -176,19 +176,19 @@ export function readPsd(reader, options) {
176
176
  var colorMode = readUint16(reader);
177
177
  var maxSize = version === 1 ? 30000 : 300000;
178
178
  if (width > maxSize || height > maxSize)
179
- throw new Error("Invalid size");
179
+ throw new Error("Invalid size: ".concat(width, "x").concat(height));
180
180
  if (channels > 16)
181
- throw new Error("Invalid channel count");
182
- if (bitsPerChannel > 32)
183
- throw new Error("Invalid bitsPerChannel count");
181
+ throw new Error("Invalid channel count: ".concat(channels));
182
+ if (![1, 8, 16, 32].includes(bitsPerChannel))
183
+ throw new Error("Invalid bitsPerChannel: ".concat(bitsPerChannel));
184
184
  if (supportedColorModes.indexOf(colorMode) === -1)
185
185
  throw new Error("Color mode not supported: ".concat((_a = colorModes[colorMode]) !== null && _a !== void 0 ? _a : colorMode));
186
186
  var psd = { width: width, height: height, channels: channels, bitsPerChannel: bitsPerChannel, colorMode: colorMode };
187
- var opt = __assign(__assign({}, options), { large: version === 2 });
187
+ var options = __assign(__assign({}, readOptions), { large: version === 2, globalAlpha: false });
188
188
  var fixOffsets = [0, 1, -1, 2, -2, 3, -3, 4, -4];
189
189
  // color mode data
190
190
  readSection(reader, 1, function (left) {
191
- if (opt.throwForMissingFeatures)
191
+ if (options.throwForMissingFeatures)
192
192
  throw new Error('Color mode data not supported');
193
193
  skipBytes(reader, left());
194
194
  });
@@ -215,22 +215,22 @@ export function readPsd(reader, options) {
215
215
  readPascalString(reader, 2); // name
216
216
  readSection(reader, 2, function (left) {
217
217
  var handler = resourceHandlersMap[id];
218
- var skip = id === 1036 && !!opt.skipThumbnail;
218
+ var skip = id === 1036 && !!options.skipThumbnail;
219
219
  if (!psd.imageResources) {
220
220
  psd.imageResources = {};
221
221
  }
222
222
  if (handler && !skip) {
223
223
  try {
224
- handler.read(reader, psd.imageResources, left, opt);
224
+ handler.read(reader, psd.imageResources, left, options);
225
225
  }
226
226
  catch (e) {
227
- if (opt.throwForMissingFeatures)
227
+ if (options.throwForMissingFeatures)
228
228
  throw e;
229
229
  skipBytes(reader, left());
230
230
  }
231
231
  }
232
232
  else {
233
- // options.logMissingFeatures && console.log(`Unhandled image resource: ${id}`);
233
+ // options.logMissingFeatures && console.log(`Unhandled image resource: ${id} (${left()})`);
234
234
  skipBytes(reader, left());
235
235
  }
236
236
  });
@@ -240,9 +240,11 @@ export function readPsd(reader, options) {
240
240
  }
241
241
  });
242
242
  // layer and mask info
243
- var globalAlpha = false;
244
243
  readSection(reader, 1, function (left) {
245
- globalAlpha = readLayerInfo(reader, psd, opt);
244
+ readSection(reader, 2, function (left) {
245
+ readLayerInfo(reader, psd, options);
246
+ skipBytes(reader, left());
247
+ }, undefined, options.large);
246
248
  // SAI does not include this section
247
249
  if (left() > 0) {
248
250
  var globalLayerMaskInfo = readGlobalLayerMaskInfo(reader);
@@ -261,70 +263,65 @@ export function readPsd(reader, options) {
261
263
  skipBytes(reader, 1);
262
264
  }
263
265
  if (left() >= 12) {
264
- readAdditionalLayerInfo(reader, psd, psd, opt);
266
+ readAdditionalLayerInfo(reader, psd, psd, options);
265
267
  }
266
268
  else {
267
269
  // opt.logMissingFeatures && console.log('skipping leftover bytes', left());
268
270
  skipBytes(reader, left());
269
271
  }
270
272
  }
271
- }, undefined, opt.large);
273
+ }, undefined, options.large);
272
274
  var hasChildren = psd.children && psd.children.length;
273
- var skipComposite = opt.skipCompositeImageData && (opt.skipLayerImageData || hasChildren);
275
+ var skipComposite = options.skipCompositeImageData && (options.skipLayerImageData || hasChildren);
274
276
  if (!skipComposite) {
275
- readImageData(reader, psd, globalAlpha, opt);
277
+ readImageData(reader, psd, options);
276
278
  }
277
279
  // TODO: show converted color mode instead of original PSD file color mode
278
280
  // but add option to preserve file color mode (need to return image data instead of canvas in that case)
279
281
  // psd.colorMode = ColorMode.RGB; // we convert all color modes to RGB
280
282
  return psd;
281
283
  }
282
- function readLayerInfo(reader, psd, options) {
283
- var globalAlpha = false;
284
- readSection(reader, 2, function (left) {
285
- var layerCount = readInt16(reader);
286
- if (layerCount < 0) {
287
- globalAlpha = true;
288
- layerCount = -layerCount;
289
- }
290
- var layers = [];
291
- var layerChannels = [];
284
+ export function readLayerInfo(reader, psd, options) {
285
+ var layerCount = readInt16(reader);
286
+ if (layerCount < 0) {
287
+ options.globalAlpha = true;
288
+ layerCount = -layerCount;
289
+ }
290
+ var layers = [];
291
+ var layerChannels = [];
292
+ for (var i = 0; i < layerCount; i++) {
293
+ var _a = readLayerRecord(reader, psd, options), layer = _a.layer, channels = _a.channels;
294
+ layers.push(layer);
295
+ layerChannels.push(channels);
296
+ }
297
+ if (!options.skipLayerImageData) {
292
298
  for (var i = 0; i < layerCount; i++) {
293
- var _a = readLayerRecord(reader, psd, options), layer = _a.layer, channels = _a.channels;
294
- layers.push(layer);
295
- layerChannels.push(channels);
299
+ readLayerChannelImageData(reader, psd, layers[i], layerChannels[i], options);
296
300
  }
297
- if (!options.skipLayerImageData) {
298
- for (var i = 0; i < layerCount; i++) {
299
- readLayerChannelImageData(reader, psd, layers[i], layerChannels[i], options);
300
- }
301
+ }
302
+ if (!psd.children)
303
+ psd.children = [];
304
+ var stack = [psd];
305
+ for (var i = layers.length - 1; i >= 0; i--) {
306
+ var l = layers[i];
307
+ var type = l.sectionDivider ? l.sectionDivider.type : 0 /* SectionDividerType.Other */;
308
+ if (type === 1 /* SectionDividerType.OpenFolder */ || type === 2 /* SectionDividerType.ClosedFolder */) {
309
+ l.opened = type === 1 /* SectionDividerType.OpenFolder */;
310
+ l.children = [];
311
+ stack[stack.length - 1].children.unshift(l);
312
+ stack.push(l);
301
313
  }
302
- skipBytes(reader, left());
303
- if (!psd.children)
304
- psd.children = [];
305
- var stack = [psd];
306
- for (var i = layers.length - 1; i >= 0; i--) {
307
- var l = layers[i];
308
- var type = l.sectionDivider ? l.sectionDivider.type : 0 /* SectionDividerType.Other */;
309
- if (type === 1 /* SectionDividerType.OpenFolder */ || type === 2 /* SectionDividerType.ClosedFolder */) {
310
- l.opened = type === 1 /* SectionDividerType.OpenFolder */;
311
- l.children = [];
312
- stack[stack.length - 1].children.unshift(l);
313
- stack.push(l);
314
- }
315
- else if (type === 3 /* SectionDividerType.BoundingSectionDivider */) {
316
- stack.pop();
317
- // this was workaround because I didn't know what `lsdk` section was, now it's probably not needed anymore
318
- // } else if (l.name === '</Layer group>' && !l.sectionDivider && !l.top && !l.left && !l.bottom && !l.right) {
319
- // // sometimes layer group terminator doesn't have sectionDivider, so we just guess here (PS bug ?)
320
- // stack.pop();
321
- }
322
- else {
323
- stack[stack.length - 1].children.unshift(l);
324
- }
314
+ else if (type === 3 /* SectionDividerType.BoundingSectionDivider */) {
315
+ stack.pop();
316
+ // this was workaround because I didn't know what `lsdk` section was, now it's probably not needed anymore
317
+ // } else if (l.name === '</Layer group>' && !l.sectionDivider && !l.top && !l.left && !l.bottom && !l.right) {
318
+ // // sometimes layer group terminator doesn't have sectionDivider, so we just guess here (PS bug ?)
319
+ // stack.pop();
325
320
  }
326
- }, undefined, options.large);
327
- return globalAlpha;
321
+ else {
322
+ stack[stack.length - 1].children.unshift(l);
323
+ }
324
+ }
328
325
  }
329
326
  function readLayerRecord(reader, psd, options) {
330
327
  var layer = {};
@@ -426,18 +423,21 @@ function readLayerBlendingRanges(reader) {
426
423
  });
427
424
  }
428
425
  function readLayerChannelImageData(reader, psd, layer, channels, options) {
426
+ var _a, _b, _c, _d;
429
427
  var layerWidth = (layer.right || 0) - (layer.left || 0);
430
428
  var layerHeight = (layer.bottom || 0) - (layer.top || 0);
431
429
  var cmyk = psd.colorMode === 4 /* ColorMode.CMYK */;
432
430
  var imageData;
433
431
  if (layerWidth && layerHeight) {
434
432
  if (cmyk) {
433
+ if (psd.bitsPerChannel !== 8)
434
+ throw new Error('bitsPerChannel Not supproted');
435
435
  imageData = { width: layerWidth, height: layerHeight, data: new Uint8ClampedArray(layerWidth * layerHeight * 5) };
436
436
  for (var p = 4; p < imageData.data.byteLength; p += 5)
437
437
  imageData.data[p] = 255;
438
438
  }
439
439
  else {
440
- imageData = createImageData(layerWidth, layerHeight);
440
+ imageData = createImageDataBitDepth(layerWidth, layerHeight, (_a = psd.bitsPerChannel) !== null && _a !== void 0 ? _a : 8);
441
441
  resetImageData(imageData);
442
442
  }
443
443
  }
@@ -470,10 +470,10 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
470
470
  var maskWidth = (mask.right || 0) - (mask.left || 0);
471
471
  var maskHeight = (mask.bottom || 0) - (mask.top || 0);
472
472
  if (maskWidth && maskHeight) {
473
- var maskData = createImageData(maskWidth, maskHeight);
473
+ var maskData = createImageDataBitDepth(maskWidth, maskHeight, (_b = psd.bitsPerChannel) !== null && _b !== void 0 ? _b : 8);
474
474
  resetImageData(maskData);
475
475
  var start_1 = reader.offset;
476
- readData(reader, channel.length, maskData, compression, maskWidth, maskHeight, 0, options.large, 4);
476
+ readData(reader, channel.length, maskData, compression, maskWidth, maskHeight, (_c = psd.bitsPerChannel) !== null && _c !== void 0 ? _c : 8, 0, options.large, 4);
477
477
  if (RAW_IMAGE_DATA) {
478
478
  layer.maskDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start_1, reader.offset - start_1);
479
479
  }
@@ -482,8 +482,7 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
482
482
  mask.imageData = maskData;
483
483
  }
484
484
  else {
485
- mask.canvas = createCanvas(maskWidth, maskHeight);
486
- mask.canvas.getContext('2d').putImageData(maskData, 0, 0);
485
+ mask.canvas = imageDataToCanvas(maskData);
487
486
  }
488
487
  }
489
488
  }
@@ -496,7 +495,7 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
496
495
  throw new Error("Channel not supported: ".concat(channel.id));
497
496
  }
498
497
  }
499
- readData(reader, channel.length, targetData, compression, layerWidth, layerHeight, offset, options.large, cmyk ? 5 : 4);
498
+ readData(reader, channel.length, targetData, compression, layerWidth, layerHeight, (_d = psd.bitsPerChannel) !== null && _d !== void 0 ? _d : 8, offset, options.large, cmyk ? 5 : 4);
500
499
  if (RAW_IMAGE_DATA) {
501
500
  layer.imageDataRaw[channel.id] = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start + 2, channel.length - 2);
502
501
  }
@@ -516,29 +515,28 @@ function readLayerChannelImageData(reader, psd, layer, channels, options) {
516
515
  layer.imageData = imageData;
517
516
  }
518
517
  else {
519
- layer.canvas = createCanvas(layerWidth, layerHeight);
520
- layer.canvas.getContext('2d').putImageData(imageData, 0, 0);
518
+ layer.canvas = imageDataToCanvas(imageData);
521
519
  }
522
520
  }
523
521
  }
524
- function readData(reader, length, data, compression, width, height, offset, large, step) {
522
+ function readData(reader, length, data, compression, width, height, bitDepth, offset, large, step) {
525
523
  if (compression === 0 /* Compression.RawData */) {
526
- readDataRaw(reader, data, width, height, step, offset);
524
+ readDataRaw(reader, data, width, height, bitDepth, step, offset);
527
525
  }
528
526
  else if (compression === 1 /* Compression.RleCompressed */) {
529
- readDataRLE(reader, data, width, height, step, [offset], large);
527
+ readDataRLE(reader, data, width, height, bitDepth, step, [offset], large);
530
528
  }
531
529
  else if (compression === 2 /* Compression.ZipWithoutPrediction */) {
532
- readDataZipWithoutPrediction(reader, length, data, width, height, step, offset);
530
+ readDataZip(reader, length, data, width, height, bitDepth, step, offset, false);
533
531
  }
534
532
  else if (compression === 3 /* Compression.ZipWithPrediction */) {
535
- throw new Error("Compression type not supported: ".concat(compression));
533
+ readDataZip(reader, length, data, width, height, bitDepth, step, offset, true);
536
534
  }
537
535
  else {
538
536
  throw new Error("Invalid Compression type: ".concat(compression));
539
537
  }
540
538
  }
541
- function readGlobalLayerMaskInfo(reader) {
539
+ export function readGlobalLayerMaskInfo(reader) {
542
540
  return readSection(reader, 1, function (left) {
543
541
  if (!left())
544
542
  return undefined;
@@ -553,7 +551,7 @@ function readGlobalLayerMaskInfo(reader) {
553
551
  return { overlayColorSpace: overlayColorSpace, colorSpace1: colorSpace1, colorSpace2: colorSpace2, colorSpace3: colorSpace3, colorSpace4: colorSpace4, opacity: opacity, kind: kind };
554
552
  });
555
553
  }
556
- function readAdditionalLayerInfo(reader, target, psd, options) {
554
+ export function readAdditionalLayerInfo(reader, target, psd, options) {
557
555
  var sig = readSignature(reader);
558
556
  if (sig !== '8BIM' && sig !== '8B64')
559
557
  throw new Error("Invalid signature: '".concat(sig, "' at 0x").concat((reader.offset - 4).toString(16)));
@@ -581,13 +579,29 @@ function readAdditionalLayerInfo(reader, target, psd, options) {
581
579
  }
582
580
  }, false, u64);
583
581
  }
584
- function readImageData(reader, psd, globalAlpha, options) {
582
+ function createImageDataBitDepth(width, height, bitDepth) {
583
+ if (bitDepth === 1 || bitDepth === 8) {
584
+ return createImageData(width, height);
585
+ }
586
+ else if (bitDepth === 16) {
587
+ return { width: width, height: height, data: new Uint16Array(width * height * 4) };
588
+ }
589
+ else if (bitDepth === 32) {
590
+ return { width: width, height: height, data: new Uint32Array(width * height * 4) };
591
+ }
592
+ else {
593
+ throw new Error("Invalid bitDepth (".concat(bitDepth, ")"));
594
+ }
595
+ }
596
+ function readImageData(reader, psd, options) {
597
+ var _a, _b;
585
598
  var compression = readUint16(reader);
599
+ var bitsPerChannel = (_a = psd.bitsPerChannel) !== null && _a !== void 0 ? _a : 8;
586
600
  if (supportedColorModes.indexOf(psd.colorMode) === -1)
587
601
  throw new Error("Color mode not supported: ".concat(psd.colorMode));
588
602
  if (compression !== 0 /* Compression.RawData */ && compression !== 1 /* Compression.RleCompressed */)
589
603
  throw new Error("Compression type not supported: ".concat(compression));
590
- var imageData = createImageData(psd.width, psd.height);
604
+ var imageData = createImageDataBitDepth(psd.width, psd.height, bitsPerChannel);
591
605
  resetImageData(imageData);
592
606
  switch (psd.colorMode) {
593
607
  case 0 /* ColorMode.Bitmap */: {
@@ -597,7 +611,7 @@ function readImageData(reader, psd, globalAlpha, options) {
597
611
  }
598
612
  else if (compression === 1 /* Compression.RleCompressed */) {
599
613
  bytes = new Uint8Array(psd.width * psd.height);
600
- readDataRLE(reader, { data: bytes, width: psd.width, height: psd.height }, psd.width, psd.height, 1, [0], options.large);
614
+ readDataRLE(reader, { data: bytes, width: psd.width, height: psd.height }, psd.width, psd.height, bitsPerChannel, 1, [0], options.large);
601
615
  }
602
616
  else {
603
617
  throw new Error("Bitmap compression not supported: ".concat(compression));
@@ -614,17 +628,17 @@ function readImageData(reader, psd, globalAlpha, options) {
614
628
  channels.push(i);
615
629
  }
616
630
  }
617
- else if (globalAlpha) {
631
+ else if (options.globalAlpha) {
618
632
  channels.push(3);
619
633
  }
620
634
  if (compression === 0 /* Compression.RawData */) {
621
635
  for (var i = 0; i < channels.length; i++) {
622
- readDataRaw(reader, imageData, psd.width, psd.height, 4, channels[i]);
636
+ readDataRaw(reader, imageData, psd.width, psd.height, bitsPerChannel, 4, channels[i]);
623
637
  }
624
638
  }
625
639
  else if (compression === 1 /* Compression.RleCompressed */) {
626
640
  var start = reader.offset;
627
- readDataRLE(reader, imageData, psd.width, psd.height, 4, channels, options.large);
641
+ readDataRLE(reader, imageData, psd.width, psd.height, bitsPerChannel, 4, channels, options.large);
628
642
  if (RAW_IMAGE_DATA)
629
643
  psd.imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
630
644
  }
@@ -634,10 +648,12 @@ function readImageData(reader, psd, globalAlpha, options) {
634
648
  break;
635
649
  }
636
650
  case 4 /* ColorMode.CMYK */: {
651
+ if (psd.bitsPerChannel !== 8)
652
+ throw new Error('bitsPerChannel Not supproted');
637
653
  if (psd.channels !== 4)
638
654
  throw new Error("Invalid channel count");
639
655
  var channels = [0, 1, 2, 3];
640
- if (globalAlpha)
656
+ if (options.globalAlpha)
641
657
  channels.push(4);
642
658
  if (compression === 0 /* Compression.RawData */) {
643
659
  throw new Error("Not implemented");
@@ -653,7 +669,7 @@ function readImageData(reader, psd, globalAlpha, options) {
653
669
  data: new Uint8Array(imageData.width * imageData.height * 5),
654
670
  };
655
671
  var start = reader.offset;
656
- readDataRLE(reader, cmykImageData, psd.width, psd.height, 5, channels, options.large);
672
+ readDataRLE(reader, cmykImageData, psd.width, psd.height, (_b = psd.bitsPerChannel) !== null && _b !== void 0 ? _b : 8, 5, channels, options.large);
657
673
  cmykToRgb(cmykImageData, imageData, true);
658
674
  if (RAW_IMAGE_DATA)
659
675
  psd.imageDataRaw = new Uint8Array(reader.view.buffer, reader.view.byteOffset + start, reader.offset - start);
@@ -663,7 +679,9 @@ function readImageData(reader, psd, globalAlpha, options) {
663
679
  default: throw new Error("Color mode not supported: ".concat(psd.colorMode));
664
680
  }
665
681
  // remove weird white matte
666
- if (globalAlpha) {
682
+ if (options.globalAlpha) {
683
+ if (psd.bitsPerChannel !== 8)
684
+ throw new Error('bitsPerChannel Not supproted');
667
685
  var p = imageData.data;
668
686
  var size = imageData.width * imageData.height * 4;
669
687
  for (var i = 0; i < size; i += 4) {
@@ -682,8 +700,7 @@ function readImageData(reader, psd, globalAlpha, options) {
682
700
  psd.imageData = imageData;
683
701
  }
684
702
  else {
685
- psd.canvas = createCanvas(psd.width, psd.height);
686
- psd.canvas.getContext('2d').putImageData(imageData, 0, 0);
703
+ psd.canvas = imageDataToCanvas(imageData);
687
704
  }
688
705
  }
689
706
  function cmykToRgb(cmyk, rgb, reverseAlpha) {
@@ -711,28 +728,88 @@ function cmykToRgb(cmyk, rgb, reverseAlpha) {
711
728
  // dstData[dst + 3] = reverseAlpha ? 255 - srcData[src + 4] : srcData[src + 4];
712
729
  // }
713
730
  }
714
- function readDataRaw(reader, pixelData, width, height, step, offset) {
715
- var size = width * height;
716
- var buffer = readBytes(reader, size);
731
+ function verifyCompatible(a, b) {
732
+ if ((a.byteLength / a.length) !== (b.byteLength / b.length)) {
733
+ throw new Error('Invalid array types');
734
+ }
735
+ }
736
+ function bytesToArray(bytes, bitDepth) {
737
+ if (bitDepth === 8) {
738
+ return bytes;
739
+ }
740
+ else if (bitDepth === 16) {
741
+ if (bytes.byteOffset % 2) {
742
+ var result = new Uint16Array(bytes.byteLength / 2);
743
+ new Uint8Array(result.buffer, result.byteOffset, result.byteLength).set(bytes);
744
+ return result;
745
+ }
746
+ else {
747
+ return new Uint16Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 2);
748
+ }
749
+ }
750
+ else if (bitDepth === 32) {
751
+ if (bytes.byteOffset % 4) {
752
+ var result = new Uint32Array(bytes.byteLength / 4);
753
+ new Uint8Array(result.buffer, result.byteOffset, result.byteLength).set(bytes);
754
+ return result;
755
+ }
756
+ else {
757
+ return new Uint32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4);
758
+ }
759
+ }
760
+ else {
761
+ throw new Error("Invalid bitDepth (".concat(bitDepth, ")"));
762
+ }
763
+ }
764
+ function copyChannelToPixelData(pixelData, channel, offset, step) {
765
+ verifyCompatible(pixelData.data, channel);
766
+ var size = pixelData.width * pixelData.height;
767
+ var data = pixelData.data;
768
+ for (var i = 0, p = offset | 0; i < size; i++, p = (p + step) | 0) {
769
+ data[p] = channel[i];
770
+ }
771
+ }
772
+ function readDataRaw(reader, pixelData, width, height, bitDepth, step, offset) {
773
+ var buffer = readBytes(reader, width * height * Math.floor(bitDepth / 8));
774
+ var array = bytesToArray(buffer, bitDepth);
717
775
  if (pixelData && offset < step) {
718
- var data = pixelData.data;
719
- for (var i = 0, p = offset | 0; i < size; i++, p = (p + step) | 0) {
720
- data[p] = buffer[i];
776
+ copyChannelToPixelData(pixelData, array, offset, step);
777
+ }
778
+ }
779
+ function decodePredicted(data, width, height, mod) {
780
+ for (var y = 0; y < height; y++) {
781
+ var offset = y * width;
782
+ for (var x = 1, o = offset + 1; x < width; x++, o++) {
783
+ data[o] = (data[o - 1] + data[o]) % mod;
721
784
  }
722
785
  }
723
786
  }
724
- export function readDataZipWithoutPrediction(reader, length, pixelData, width, height, step, offset) {
787
+ export function readDataZip(reader, length, pixelData, width, height, bitDepth, step, offset, prediction) {
725
788
  var compressed = readBytes(reader, length);
726
789
  var decompressed = inflate(compressed);
727
- var size = width * height;
728
790
  if (pixelData && offset < step) {
729
- var data = pixelData.data;
730
- for (var i = 0, p = offset | 0; i < size; i++, p = (p + step) | 0) {
731
- data[p] = decompressed[i];
791
+ var array = bytesToArray(decompressed, bitDepth);
792
+ if (bitDepth === 8) {
793
+ if (prediction)
794
+ decodePredicted(decompressed, width, height, 0x100);
795
+ copyChannelToPixelData(pixelData, decompressed, offset, step);
796
+ }
797
+ else if (bitDepth === 16) {
798
+ if (prediction)
799
+ decodePredicted(array, width, height, 0x10000);
800
+ copyChannelToPixelData(pixelData, array, offset, step);
801
+ }
802
+ else if (bitDepth === 32) {
803
+ if (prediction)
804
+ decodePredicted(decompressed, width, height, 0x100);
805
+ copyChannelToPixelData(pixelData, array, offset, step);
806
+ }
807
+ else {
808
+ throw new Error('Invalid bitDepth');
732
809
  }
733
810
  }
734
811
  }
735
- export function readDataRLE(reader, pixelData, _width, height, step, offsets, large) {
812
+ export function readDataRLE(reader, pixelData, _width, height, bitDepth, step, offsets, large) {
736
813
  var data = pixelData && pixelData.data;
737
814
  var lengths;
738
815
  if (large) {
@@ -751,6 +828,8 @@ export function readDataRLE(reader, pixelData, _width, height, step, offsets, la
751
828
  }
752
829
  }
753
830
  }
831
+ if (bitDepth !== 1 && bitDepth !== 8)
832
+ throw new Error("Invalid bit depth (".concat(bitDepth, ")"));
754
833
  var extraLimit = (step - 1) | 0; // 3 for rgb, 4 for cmyk
755
834
  for (var c = 0, li = 0; c < offsets.length; c++) {
756
835
  var offset = offsets[c] | 0;