ag-psd 33.0.0 → 34.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 (86) hide show
  1. package/.v8-cache/v24.7.0-x64-ef5a0af0/05135617 +0 -0
  2. package/.v8-cache/v24.7.0-x64-ef5a0af0/226e2801 +0 -0
  3. package/.v8-cache/v24.7.0-x64-ef5a0af0/4511bacf +0 -0
  4. package/.v8-cache/v24.7.0-x64-ef5a0af0/68416cb2 +0 -0
  5. package/.v8-cache/v24.7.0-x64-ef5a0af0/71df9cb3 +0 -0
  6. package/.v8-cache/v24.7.0-x64-ef5a0af0/7ea06cea +0 -0
  7. package/.v8-cache/v24.7.0-x64-ef5a0af0/87cf2209 +0 -0
  8. package/.v8-cache/v24.7.0-x64-ef5a0af0/932f0770 +0 -0
  9. package/.v8-cache/v24.7.0-x64-ef5a0af0/acc36e66 +0 -0
  10. package/.v8-cache/v24.7.0-x64-ef5a0af0/b3c2fab7 +0 -0
  11. package/.v8-cache/v24.7.0-x64-ef5a0af0/c0b789d2 +0 -0
  12. package/.v8-cache/v24.7.0-x64-ef5a0af0/c314aece +0 -0
  13. package/.v8-cache/v24.7.0-x64-ef5a0af0/cfc49f4f +0 -0
  14. package/.v8-cache/v24.7.0-x64-ef5a0af0/d13d7610 +0 -0
  15. package/.v8-cache/v24.7.0-x64-ef5a0af0/dc86f000 +0 -0
  16. package/.v8-cache/v24.7.0-x64-ef5a0af0/e03e2acd +0 -0
  17. package/.v8-cache/v24.7.0-x64-ef5a0af0/e6b99945 +0 -0
  18. package/CHANGELOG.md +22 -0
  19. package/README.md +1 -1
  20. package/README_PSD.md +25 -9
  21. package/TODO.md +13 -84
  22. package/dist/abr.js +12 -7
  23. package/dist/abr.js.map +1 -1
  24. package/dist/additionalInfo.d.ts +2 -0
  25. package/dist/additionalInfo.js +361 -75
  26. package/dist/additionalInfo.js.map +1 -1
  27. package/dist/bundle.js +1524 -389
  28. package/dist/descriptor.d.ts +14 -5
  29. package/dist/descriptor.js +102 -64
  30. package/dist/descriptor.js.map +1 -1
  31. package/dist/helpers.d.ts +6 -0
  32. package/dist/helpers.js +242 -2
  33. package/dist/helpers.js.map +1 -1
  34. package/dist/imageResources.js +84 -3
  35. package/dist/imageResources.js.map +1 -1
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.js +1 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/psd.d.ts +144 -2
  40. package/dist/psd.js.map +1 -1
  41. package/dist/psdReader.js +206 -110
  42. package/dist/psdReader.js.map +1 -1
  43. package/dist/psdWriter.d.ts +1 -0
  44. package/dist/psdWriter.js +336 -91
  45. package/dist/psdWriter.js.map +1 -1
  46. package/dist/text.d.ts +32 -1
  47. package/dist/text.js +58 -0
  48. package/dist/text.js.map +1 -1
  49. package/dist-es/abr.js +12 -7
  50. package/dist-es/abr.js.map +1 -1
  51. package/dist-es/additionalInfo.d.ts +2 -0
  52. package/dist-es/additionalInfo.js +361 -75
  53. package/dist-es/additionalInfo.js.map +1 -1
  54. package/dist-es/descriptor.d.ts +14 -5
  55. package/dist-es/descriptor.js +102 -64
  56. package/dist-es/descriptor.js.map +1 -1
  57. package/dist-es/helpers.d.ts +6 -0
  58. package/dist-es/helpers.js +242 -2
  59. package/dist-es/helpers.js.map +1 -1
  60. package/dist-es/imageResources.js +84 -3
  61. package/dist-es/imageResources.js.map +1 -1
  62. package/dist-es/index.d.ts +1 -0
  63. package/dist-es/index.js +1 -0
  64. package/dist-es/index.js.map +1 -1
  65. package/dist-es/psd.d.ts +144 -2
  66. package/dist-es/psd.js.map +1 -1
  67. package/dist-es/psdReader.js +206 -110
  68. package/dist-es/psdReader.js.map +1 -1
  69. package/dist-es/psdWriter.d.ts +1 -0
  70. package/dist-es/psdWriter.js +336 -91
  71. package/dist-es/psdWriter.js.map +1 -1
  72. package/dist-es/text.d.ts +32 -1
  73. package/dist-es/text.js +58 -0
  74. package/dist-es/text.js.map +1 -1
  75. package/package.json +1 -1
  76. package/perf.js +312 -9
  77. package/src/abr.ts +14 -7
  78. package/src/additionalInfo.ts +433 -87
  79. package/src/descriptor.ts +103 -58
  80. package/src/helpers.ts +262 -2
  81. package/src/imageResources.ts +107 -4
  82. package/src/index.ts +1 -0
  83. package/src/psd.ts +115 -2
  84. package/src/psdReader.ts +226 -108
  85. package/src/psdWriter.ts +345 -90
  86. package/src/text.ts +76 -1
@@ -1,5 +1,5 @@
1
1
  import { toByteArray } from 'base64-js';
2
- import { BlendMode, HalftoneScreen, ImageResources, KeyDescriptorItem, PrintTransferFunction, RenderingIntent, SavedPath } from './psd';
2
+ import { BlendMode, Color, HalftoneScreen, ImageResources, KeyDescriptorItem, PrintTransferFunction, RenderingIntent, SavedPath } from './psd';
3
3
  import { KeyDescriptorListDescriptor, parseKeyDescriptorList, readVectorMask, serializeKeyDescriptorList, writeVectorMask } from './additionalInfo';
4
4
  import { PsdReader, readUnicodeString, readUint32, readUint16, readUint8, readFloat64, readBytes, skipBytes, readFloat32, readInt16, readFixedPoint32, readSignature, checkSignature, readSection, readColor, readInt32, readAsciiString, decodeUtf8, getUtf8StrictDecoder, getGbkStrictDecoder } from './psdReader';
5
5
  import { PsdWriter, writeUnicodeString, writeUint32, writeUint8, writeFloat64, writeUint16, writeBytes, writeInt16, writeFloat32, writeFixedPoint32, writeUnicodeStringWithPadding, writeColor, writeSignature, writeSection, writeInt32, writeAsciiString, writeZeros } from './psdWriter';
@@ -734,6 +734,50 @@ function writeTransferFunctions(writer: PsdWriter, functions: PrintTransferFunct
734
734
  }
735
735
  }
736
736
 
737
+ addHandler(
738
+ 1014, // Duotone halftoning information
739
+ target => target.duotoneHalftoneScreens !== undefined,
740
+ (reader, target, left) => target.duotoneHalftoneScreens = readHalftoneScreens(reader, left),
741
+ (writer, target) => writeHalftoneScreens(writer, target.duotoneHalftoneScreens!),
742
+ );
743
+
744
+ addHandler(
745
+ 1017, // Duotone transfer functions
746
+ target => target.duotoneTransferFunctions !== undefined,
747
+ (reader, target, left) => target.duotoneTransferFunctions = readTransferFunctions(reader, left),
748
+ (writer, target) => writeTransferFunctions(writer, target.duotoneTransferFunctions!),
749
+ );
750
+
751
+ addHandler(
752
+ 1018, // Duotone image information
753
+ target => target.duotoneImageInformation !== undefined,
754
+ (reader, target, left) => target.duotoneImageInformation = readBytes(reader, left()),
755
+ (writer, target) => writeBytes(writer, target.duotoneImageInformation),
756
+ );
757
+
758
+ addHandler(
759
+ 1066, // Alternate duotone colors
760
+ target => target.alternateDuotoneColors !== undefined,
761
+ (reader, target, left) => {
762
+ if (readUint16(reader) !== 1) throw new Error('Invalid alternate duotone colors version');
763
+ const colors: Color[] = [];
764
+ const count = readUint16(reader);
765
+ for (let i = 0; i < count && left() >= 10; i++) colors.push(readColor(reader));
766
+ const labCount = readUint16(reader);
767
+ if (labCount * 3 > left()) throw new Error('Invalid alternate duotone colors Lab table size');
768
+ const labColors = readBytes(reader, labCount * 3);
769
+ target.alternateDuotoneColors = { colors, labColors };
770
+ },
771
+ (writer, target) => {
772
+ const { colors, labColors } = target.alternateDuotoneColors!;
773
+ writeUint16(writer, 1); // version
774
+ writeUint16(writer, colors.length);
775
+ for (const color of colors) writeColor(writer, color);
776
+ writeUint16(writer, Math.floor(labColors.byteLength / 3));
777
+ writeBytes(writer, labColors.subarray(0, Math.floor(labColors.byteLength / 3) * 3));
778
+ },
779
+ );
780
+
737
781
  addHandler(
738
782
  1015, // Grayscale and multichannel transfer function
739
783
  target => target.grayscaleTransferFunctions !== undefined,
@@ -1161,7 +1205,7 @@ addHandler(
1161
1205
  workOutTime: frac(desc.workOutTime),
1162
1206
  repeats: desc.LCnt,
1163
1207
  hasMotion: desc.hasMotion,
1164
- globalTracks: parseTrackList(desc.globalTrackList, !!reader.logMissingFeatures),
1208
+ globalTracks: parseTrackList(desc.globalTrackList, reader),
1165
1209
  };
1166
1210
 
1167
1211
  if (desc.audioClipGroupList?.audioClipGroupList?.length) {
@@ -1201,7 +1245,7 @@ addHandler(
1201
1245
  workInTime: timeline.workInTime,
1202
1246
  workOutTime: timeline.workOutTime,
1203
1247
  LCnt: timeline.repeats,
1204
- globalTrackList: serializeTrackList(timeline.globalTracks),
1248
+ globalTrackList: serializeTrackList(timeline.globalTracks, writer),
1205
1249
  audioClipGroupList: {
1206
1250
  audioClipGroupList: (timeline.audioClipGroups ?? []).map(a => ({
1207
1251
  groupID: a.id,
@@ -1600,10 +1644,11 @@ addHandler(
1600
1644
 
1601
1645
  addHandler(
1602
1646
  1038, // Color samplers (Photoshop 5.0, replaced by 1073 in CS3)
1603
- target => target.colorSamplers !== undefined,
1647
+ target => target.colorSamplers !== undefined && !target.colorSamplers.some(s => s.depth !== undefined),
1604
1648
  (reader, target, left) => {
1605
1649
  const version = readUint32(reader);
1606
1650
  if (version !== 1) throw new Error(`Invalid color samplers version: ${version}`);
1651
+ if (target.colorSamplers?.some(s => s.depth !== undefined)) return skipBytes(reader, left()); // already read from 1073
1607
1652
  const count = readUint32(reader);
1608
1653
  target.colorSamplers = [];
1609
1654
 
@@ -1628,6 +1673,64 @@ addHandler(
1628
1673
  },
1629
1674
  );
1630
1675
 
1676
+ addHandler(
1677
+ 1073, // Color samplers (Photoshop CS3)
1678
+ target => target.colorSamplers !== undefined && target.colorSamplers.some(s => s.depth !== undefined),
1679
+ (reader, target, left) => {
1680
+ const version = readUint32(reader);
1681
+ if (version < 1 || version > 3) throw new Error(`Invalid color samplers version: ${version}`);
1682
+ const count = readUint32(reader);
1683
+ target.colorSamplers = [];
1684
+
1685
+ for (let i = 0; i < count && left() >= 10; i++) {
1686
+ // position is fixed point value for sampler version 1 (stored the same way as in 1038 resource) or float for version 2
1687
+ const samplerVersion = version === 3 ? readUint32(reader) : version;
1688
+ const y = samplerVersion === 1 ? readInt32(reader) / 16 : readFloat32(reader);
1689
+ const x = samplerVersion === 1 ? readInt32(reader) / 16 : readFloat32(reader);
1690
+ const colorSpace = readInt16(reader);
1691
+ const depth = version >= 2 ? readInt16(reader) : 1;
1692
+ target.colorSamplers.push({ x, y, colorSpace, depth });
1693
+ }
1694
+ },
1695
+ (writer, target) => {
1696
+ writeUint32(writer, 3); // version
1697
+ writeUint32(writer, target.colorSamplers!.length);
1698
+
1699
+ for (const sampler of target.colorSamplers!) {
1700
+ writeUint32(writer, 1); // sampler version
1701
+ writeInt32(writer, Math.round(sampler.y * 16));
1702
+ writeInt32(writer, Math.round(sampler.x * 16));
1703
+ writeInt16(writer, sampler.colorSpace);
1704
+ writeInt16(writer, sampler.depth ?? 1);
1705
+ }
1706
+ },
1707
+ );
1708
+
1709
+ addHandler(
1710
+ 1022, // Quick Mask information
1711
+ target => target.quickMaskInfo !== undefined,
1712
+ (reader, target) => {
1713
+ const channelId = readUint16(reader);
1714
+ const initiallyEmpty = !!readUint8(reader);
1715
+ target.quickMaskInfo = { channelId, initiallyEmpty };
1716
+ },
1717
+ (writer, target) => {
1718
+ writeUint16(writer, target.quickMaskInfo!.channelId);
1719
+ writeUint8(writer, target.quickMaskInfo!.initiallyEmpty ? 1 : 0);
1720
+ },
1721
+ );
1722
+
1723
+ addHandler(
1724
+ 1074, // Measurement scale
1725
+ target => target.measurementScale !== undefined,
1726
+ (reader, target, left) => {
1727
+ target.measurementScale = readBytes(reader, left());
1728
+ },
1729
+ (writer, target) => {
1730
+ writeBytes(writer, target.measurementScale);
1731
+ },
1732
+ );
1733
+
1631
1734
  addHandler(
1632
1735
  1042, // Effects visible (only present when effects are hidden)
1633
1736
  target => target.effectsVisible !== undefined,
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ import { fromByteArray } from 'base64-js';
5
5
 
6
6
  export * from './abr';
7
7
  export * from './csh';
8
+ export * from './ase';
8
9
  export { initializeCanvas } from './helpers';
9
10
  export * from './psd';
10
11
  export type { PsdReader, PsdWriter };
package/src/psd.ts CHANGED
@@ -31,7 +31,15 @@ export type HSB = { h: number; s: number; b: number; }; // values from 0 to 1
31
31
  export type CMYK = { c: number; m: number; y: number; k: number; }; // values from 0 to 255
32
32
  export type LAB = { l: number; a: number; b: number; }; // values `l` from 0 to 1; `a` and `b` from -1 to 1
33
33
  export type Grayscale = { k: number }; // values from 0 to 255
34
- export type Color = RGBA | RGB | FRGB | HSB | CMYK | LAB | Grayscale;
34
+ export interface ColorBookInfo {
35
+ book: string; // name of the color book (e.g. 'PANTONE+® Solid Coated')
36
+ name: string; // name of the color in the book (e.g. 'PANTONE 688 C')
37
+ bookID: number;
38
+ bookKey: string; // unique key of the color in the book
39
+ }
40
+ // `book` is only present for colors picked from color books (Pantone, etc.) in descriptors, color values are the
41
+ // book color converted to document color space
42
+ export type Color = (RGBA | RGB | FRGB | HSB | CMYK | LAB | Grayscale) & { book?: ColorBookInfo; };
35
43
 
36
44
  export interface EffectContour {
37
45
  name: string;
@@ -559,6 +567,9 @@ export interface CurvesAdjustment extends PresetInfo {
559
567
  // curve for each channel, index 0 is composite channel, followed by document color channels (red, green, blue for RGB,
560
568
  // cyan, magenta, yellow, black for CMYK, gray for Grayscale), missing or empty curve means no change to the channel
561
569
  channels?: CurvesAdjustmentChannel[];
570
+ // curves drawn with pencil tool, lookup table of 256 output values (0-255) for each channel (same indexing as
571
+ // `channels`), missing or empty table means no change to the channel, used instead of `channels` when present
572
+ values?: number[][];
562
573
  }
563
574
 
564
575
  export interface ExposureAdjustment extends PresetInfo {
@@ -1213,8 +1224,75 @@ type FilterVariant = {
1213
1224
  contrast: number;
1214
1225
  useLegacy: boolean;
1215
1226
  };
1227
+ } | {
1228
+ type: 'camera raw';
1229
+ filter: CameraRawFilterSettings;
1216
1230
  };
1217
1231
 
1232
+ export type CameraRawCurvePoint = { input: number; output: number; };
1233
+ export type CameraRawColors = { red?: number; orange?: number; yellow?: number; green?: number; aqua?: number; blue?: number; purple?: number; magenta?: number; };
1234
+ export type CameraRawColorGradingWheel = { hue?: number; saturation?: number; luminance?: number; };
1235
+
1236
+ // Camera Raw Filter settings (missing values use Camera Raw defaults), settings that are not supported are not preserved
1237
+ export interface CameraRawFilterSettings {
1238
+ version?: string; // Camera Raw version (e.g. '18.4')
1239
+ processVersion?: number;
1240
+ processVersionCode?: number;
1241
+ whiteBalance?: string; // raw white balance value (e.g. 'Cst ' for custom)
1242
+ temperature?: number;
1243
+ tint?: number;
1244
+ exposure?: number;
1245
+ contrast?: number;
1246
+ highlights?: number;
1247
+ shadows?: number;
1248
+ whites?: number;
1249
+ blacks?: number;
1250
+ texture?: number;
1251
+ clarity?: number;
1252
+ dehaze?: number;
1253
+ vibrance?: number;
1254
+ saturation?: number;
1255
+ parametricCurve?: {
1256
+ shadows?: number;
1257
+ darks?: number;
1258
+ lights?: number;
1259
+ highlights?: number;
1260
+ shadowSplit?: number;
1261
+ midtoneSplit?: number;
1262
+ highlightSplit?: number;
1263
+ };
1264
+ pointCurve?: {
1265
+ composite?: CameraRawCurvePoint[];
1266
+ red?: CameraRawCurvePoint[];
1267
+ green?: CameraRawCurvePoint[];
1268
+ blue?: CameraRawCurvePoint[];
1269
+ };
1270
+ hsl?: {
1271
+ hue?: CameraRawColors;
1272
+ saturation?: CameraRawColors;
1273
+ luminance?: CameraRawColors;
1274
+ };
1275
+ colorGrading?: {
1276
+ shadows?: CameraRawColorGradingWheel;
1277
+ midtones?: CameraRawColorGradingWheel;
1278
+ highlights?: CameraRawColorGradingWheel;
1279
+ global?: CameraRawColorGradingWheel;
1280
+ blending?: number;
1281
+ balance?: number;
1282
+ };
1283
+ sharpening?: { amount?: number; radius?: number; detail?: number; masking?: number; };
1284
+ noiseReduction?: {
1285
+ luminance?: number;
1286
+ luminanceDetail?: number;
1287
+ luminanceContrast?: number;
1288
+ color?: number;
1289
+ colorDetail?: number;
1290
+ colorSmoothness?: number;
1291
+ };
1292
+ grain?: { amount?: number; size?: number; roughness?: number; };
1293
+ postCropVignette?: { amount?: number; midpoint?: number; feather?: number; roundness?: number; };
1294
+ }
1295
+
1218
1296
  /*
1219
1297
  export interface Position3D {
1220
1298
  x: number;
@@ -1290,7 +1368,8 @@ export type AdjustmentLayer = BrightnessAdjustment | LevelsAdjustment | CurvesAd
1290
1368
  InvertAdjustment | PosterizeAdjustment | ThresholdAdjustment | GradientMapAdjustment |
1291
1369
  SelectiveColorAdjustment;
1292
1370
 
1293
- export type LayerColor = 'none' | 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'violet' | 'gray';
1371
+ export type LayerColor = 'none' | 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'violet' | 'gray' |
1372
+ 'seafoam' | 'indigo' | 'magenta' | 'fuchsia';
1294
1373
 
1295
1374
  export interface KeyDescriptorItem {
1296
1375
  keyShapeInvalidated?: boolean;
@@ -1414,6 +1493,7 @@ export interface LayerAdditionalInfo {
1414
1493
  blendInteriorElements?: boolean;
1415
1494
  knockout?: boolean;
1416
1495
  layerMaskAsGlobalMask?: boolean;
1496
+ vectorMaskAsGlobalMask?: boolean;
1417
1497
  protected?: {
1418
1498
  transparency?: boolean;
1419
1499
  composite?: boolean;
@@ -1542,6 +1622,26 @@ export interface LayerAdditionalInfo {
1542
1622
  ranges: { sourceRange: number[]; destRange: number[]; }[];
1543
1623
  };
1544
1624
  vowv?: number; // ???
1625
+ foreignEffectId?: number; // foreign effect ID (Photoshop 6.0)
1626
+ framedGroup?: { // frame tool group (frame layer)
1627
+ rect: { top: number; left: number; bottom: number; right: number; };
1628
+ type: number; // 1 - rectangle, 2 - ellipse
1629
+ lockPPI?: boolean;
1630
+ preferredResolution?: number;
1631
+ savedIteratedName?: string;
1632
+ };
1633
+ animationEffects?: Uint8Array; // animation effects (Photoshop CS6, raw descriptor data)
1634
+ patternData?: { // pattern data (Photoshop 6.0)
1635
+ signature: string;
1636
+ key: string;
1637
+ copyOnSheetDuplication: boolean;
1638
+ patterns: {
1639
+ colorHandling: 'convert' | 'avoid conversion' | 'luminance only';
1640
+ name: string;
1641
+ id: string;
1642
+ }[];
1643
+ }[];
1644
+ pixelSourceData?: Uint8Array[]; // pixel source data of video layers (raw data of each entry)
1545
1645
  pixelSource?: {
1546
1646
  type: 'vdPS';
1547
1647
  origin: { x: number; y: number; };
@@ -1676,6 +1776,7 @@ export interface ImageResources {
1676
1776
  x: number; // pixels
1677
1777
  y: number; // pixels
1678
1778
  colorSpace: number; // -1 - actual color, 0 - RGB, 1 - HSB, 2 - CMYK, 7 - Lab, 8 - grayscale, ...
1779
+ depth?: number; // sample size (Photoshop CS3 format), samplers are written in Photoshop 5 format if missing
1679
1780
  }[];
1680
1781
  effectsVisible?: boolean; // global flag to show or hide all layer effects
1681
1782
  iccProfile?: Uint8Array; // raw ICC profile data
@@ -1687,6 +1788,18 @@ export interface ImageResources {
1687
1788
  grayscaleHalftoneScreens?: HalftoneScreen[];
1688
1789
  colorTransferFunctions?: PrintTransferFunction[]; // one for each of 4 printing plates
1689
1790
  grayscaleTransferFunctions?: PrintTransferFunction[];
1791
+ duotoneHalftoneScreens?: HalftoneScreen[];
1792
+ duotoneTransferFunctions?: PrintTransferFunction[];
1793
+ duotoneImageInformation?: Uint8Array; // raw data
1794
+ alternateDuotoneColors?: {
1795
+ colors: Color[];
1796
+ labColors: Uint8Array; // Lab color table (usually 256 colors), 3 bytes for each color (L, a, b)
1797
+ };
1798
+ quickMaskInfo?: {
1799
+ channelId: number;
1800
+ initiallyEmpty: boolean;
1801
+ };
1802
+ measurementScale?: Uint8Array; // raw descriptor data
1690
1803
  printStyle?: {
1691
1804
  caption?: boolean;
1692
1805
  calibrationBars?: boolean;