ag-psd 16.0.0 → 17.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.
@@ -9,7 +9,7 @@ import {
9
9
  CurvesAdjustment, CurvesAdjustmentChannel, HueSaturationAdjustment, HueSaturationAdjustmentChannel,
10
10
  PresetInfo, Color, ColorBalanceValues, WriteOptions, LinkedFile, PlacedLayerType, Warp, KeyDescriptorItem,
11
11
  BooleanOperation, LayerEffectsInfo, Annotation, LayerVectorMask, AnimationFrame, Timeline, PlacedLayerFilter,
12
- UnitsValue, PlacedLayerPuppetFilter,
12
+ UnitsValue, Filter,
13
13
  } from './psd';
14
14
  import {
15
15
  PsdReader, readSignature, readUnicodeString, skipBytes, readUint32, readUint8, readFloat64, readUint16,
@@ -28,7 +28,9 @@ import {
28
28
  readVersionAndDescriptor, StrokeDescriptor, Ornt, horzVrtcToXY, LmfxDescriptor, Lfx2Descriptor,
29
29
  FrameListDescriptor, TimelineDescriptor, FrameDescriptor, xyToHorzVrtc, serializeEffects,
30
30
  parseEffects, parseColor, serializeColor, serializeVectorContent, parseVectorContent, parseTrackList,
31
- serializeTrackList, FractionDescriptor,
31
+ serializeTrackList, FractionDescriptor, BlrM, BlrQ, SmBQ, SmBM, DspM, UndA, Cnvr, RplS, SphM, Wvtp, ZZTy,
32
+ Dstr, Chnl, MztT, Lns, blurType, DfsM, ExtT, ExtR, FlCl, CntE, WndM, Drct, IntE, IntC, FlMd,
33
+ unitsPercentF, frac, ClrS, descBoundsToBounds, boundsToDescBounds,
32
34
  } from './descriptor';
33
35
  import { serializeEngineData, parseEngineData } from './engineData';
34
36
  import { encodeEngineData, decodeEngineData } from './text';
@@ -49,6 +51,7 @@ export interface InfoHandler {
49
51
  write: WriteMethod;
50
52
  }
51
53
 
54
+ const fromAtoZ = 'abcdefghijklmnopqrstuvwxyz';
52
55
  export const infoHandlers: InfoHandler[] = [];
53
56
  export const infoHandlersMap: { [key: string]: InfoHandler; } = {};
54
57
 
@@ -111,6 +114,9 @@ addHandler(
111
114
  },
112
115
  };
113
116
 
117
+ if (text.bounds) target.text.bounds = descBoundsToBounds(text.bounds);
118
+ if (text.boundingBox) target.text.boundingBox = descBoundsToBounds(text.boundingBox);
119
+
114
120
  if (text.EngineData) {
115
121
  const engineData = parseEngineData(text.EngineData);
116
122
  const textData = decodeEngineData(engineData);
@@ -138,6 +144,8 @@ addHandler(
138
144
  textGridding: textGridding.encode(text.gridding),
139
145
  Ornt: Ornt.encode(text.orientation),
140
146
  AntA: Annt.encode(text.antiAlias),
147
+ ...(text.bounds ? { bounds: boundsToDescBounds(text.bounds) } : {}),
148
+ ...(text.boundingBox ? { boundingBox: boundsToDescBounds(text.boundingBox) } : {}),
141
149
  TextIndex: text.index || 0,
142
150
  EngineData: serializeEngineData(encodeEngineData(text)),
143
151
  };
@@ -149,7 +157,7 @@ addHandler(
149
157
  }
150
158
 
151
159
  writeInt16(writer, 50); // text version
152
- writeVersionAndDescriptor(writer, '', 'TxLr', textDescriptor);
160
+ writeVersionAndDescriptor(writer, '', 'TxLr', textDescriptor, 'text');
153
161
 
154
162
  writeInt16(writer, 1); // warp version
155
163
  writeVersionAndDescriptor(writer, '', 'warp', encodeWarp(warp));
@@ -771,10 +779,10 @@ addHandler(
771
779
  // console.log('tmln', target.name, target.id, require('util').inspect(desc, false, 99, true));
772
780
 
773
781
  const timeline: Timeline = {
774
- start: timeScope.Strt,
775
- duration: timeScope.duration,
776
- inTime: timeScope.inTime,
777
- outTime: timeScope.outTime,
782
+ start: frac(timeScope.Strt),
783
+ duration: frac(timeScope.duration),
784
+ inTime: frac(timeScope.inTime),
785
+ outTime: frac(timeScope.outTime),
778
786
  autoScope: desc.autoScope,
779
787
  audioLevel: desc.audioLevel,
780
788
  };
@@ -923,7 +931,7 @@ addHandler(
923
931
  },
924
932
  (writer, target) => {
925
933
  const stroke = target.vectorStroke!;
926
- const descriptor: StrokeDescriptor = {
934
+ const desc: StrokeDescriptor = {
927
935
  strokeStyleVersion: 2,
928
936
  strokeEnabled: !!stroke.strokeEnabled,
929
937
  fillEnabled: !!stroke.fillEnabled,
@@ -943,7 +951,7 @@ addHandler(
943
951
  strokeStyleResolution: stroke.resolution ?? 72,
944
952
  };
945
953
 
946
- writeVersionAndDescriptor(writer, '', 'strokeStyle', descriptor);
954
+ writeVersionAndDescriptor(writer, '', 'strokeStyle', desc);
947
955
  },
948
956
  );
949
957
 
@@ -1048,7 +1056,7 @@ function encodeWarp(warp: Warp): WarpDescriptor {
1048
1056
  const bounds = warp.bounds;
1049
1057
  const desc: WarpDescriptor = {
1050
1058
  warpStyle: warpStyle.encode(warp.style),
1051
- ...(warp.values ? { warpValues: warp.values } : { warpValue: warp.value }),
1059
+ ...(warp.values ? { warpValues: warp.values } : { warpValue: warp.value || 0 }),
1052
1060
  warpPerspective: warp.perspective || 0,
1053
1061
  warpPerspectiveOther: warp.perspectiveOther || 0,
1054
1062
  warpRotate: Ornt.encode(warp.rotate),
@@ -1077,6 +1085,8 @@ function encodeWarp(warp: Warp): WarpDescriptor {
1077
1085
  if (isQuilt) {
1078
1086
  const desc2 = desc as QuiltWarpDescriptor;
1079
1087
  desc2.customEnvelopeWarp = {
1088
+ _name: '',
1089
+ _classID: 'customEnvelopeWarp',
1080
1090
  quiltSliceX: [{
1081
1091
  type: 'quiltSliceX',
1082
1092
  values: customEnvelopeWarp.quiltSliceX || [],
@@ -1092,6 +1102,8 @@ function encodeWarp(warp: Warp): WarpDescriptor {
1092
1102
  };
1093
1103
  } else {
1094
1104
  desc.customEnvelopeWarp = {
1105
+ _name: '',
1106
+ _classID: 'customEnvelopeWarp',
1095
1107
  meshPoints: [
1096
1108
  { type: 'Hrzn', values: meshPoints.map(p => p.x) },
1097
1109
  { type: 'Vrtc', values: meshPoints.map(p => p.y) },
@@ -1154,78 +1166,687 @@ addHandler(
1154
1166
  );
1155
1167
 
1156
1168
  interface HrznVrtcDescriptor {
1169
+ _name: '';
1170
+ _classID: 'Pnt ';
1157
1171
  Hrzn: DescriptorUnitsValue;
1158
1172
  Vrtc: DescriptorUnitsValue;
1159
1173
  }
1160
-
1161
- type FltrDescriptor = {
1162
- 'null': string[]; // [Ordn.Trgt]
1163
- rigidType: boolean;
1164
- puppetShapeList?: {
1174
+ /*
1175
+ interface K3DLight {
1176
+ 'Nm ': string;
1177
+ 'Rd ': number;
1178
+ 'Grn ': number;
1179
+ 'Bl ': number;
1180
+ hots: number;
1181
+ FlOf: number;
1182
+ shdw: number;
1183
+ attn: boolean;
1184
+ attt: number;
1185
+ atta: number;
1186
+ attb: number;
1187
+ attc: number;
1188
+ orad: number;
1189
+ irad: number;
1190
+ mult: number;
1191
+ Type: number;
1192
+ ison: boolean;
1193
+ ssml: number;
1194
+ afon: boolean;
1195
+ afpw: number;
1196
+ key3DMatrix: {
1197
+ key3DMatrixData: Uint8Array;
1198
+ },
1199
+ 'X ': number;
1200
+ 'Y ': number;
1201
+ 'Z ': number;
1202
+ tarx: number;
1203
+ tary: number;
1204
+ tarz: number;
1205
+ key3DPosition: {
1206
+ key3DXPos: number;
1207
+ key3DYPos: number;
1208
+ key3DZPos: number;
1209
+ key3DXAngle: number;
1210
+ key3DYAngle: number;
1211
+ key3DZAngle: number;
1212
+ };
1213
+ }
1214
+ */
1215
+
1216
+ type SoLdDescriptorFilterItem = {
1217
+ _name: '',
1218
+ _classID: 'filterFX',
1219
+ 'Nm ': string;
1220
+ blendOptions: {
1221
+ _name: '';
1222
+ _classID: 'blendOptions';
1223
+ Opct: DescriptorUnitsValue;
1224
+ 'Md ': string; // blend mode
1225
+ };
1226
+ enab: boolean;
1227
+ hasoptions: boolean;
1228
+ FrgC: DescriptorColor;
1229
+ BckC: DescriptorColor;
1230
+ } & ({
1231
+ filterID: 1098281575; // average
1232
+ } | {
1233
+ filterID: 1114403360; // blur
1234
+ } | {
1235
+ filterID: 1114403405; // blur more
1236
+ } | {
1237
+ filterID: 697;
1238
+ Fltr: {
1239
+ _name: 'Box Blur';
1240
+ _classID: 'boxblur';
1241
+ 'Rds ': DescriptorUnitsValue;
1242
+ };
1243
+ } | {
1244
+ filterID: 1198747202;
1245
+ Fltr: {
1246
+ _name: 'Gaussian Blur';
1247
+ _classID: 'GsnB';
1248
+ 'Rds ': DescriptorUnitsValue;
1249
+ };
1250
+ } | {
1251
+ filterID: 1299476034;
1252
+ Fltr: {
1253
+ _name: 'Motion Blur';
1254
+ _classID: 'MtnB';
1255
+ Angl: number;
1256
+ Dstn: DescriptorUnitsValue;
1257
+ };
1258
+ } | {
1259
+ filterID: 1382313026;
1260
+ Fltr: {
1261
+ _name: 'Radial Blur';
1262
+ _classID: 'RdlB';
1263
+ Amnt: number;
1264
+ BlrM: string;
1265
+ BlrQ: string;
1266
+ };
1267
+ } | {
1268
+ filterID: 702;
1269
+ Fltr: {
1270
+ _name: 'Shape Blur';
1271
+ _classID: 'shapeBlur';
1272
+ 'Rds ': DescriptorUnitsValue;
1273
+ customShape: {
1274
+ _name: '';
1275
+ _classID: 'customShape';
1276
+ 'Nm ': string;
1277
+ Idnt: string;
1278
+ };
1279
+ };
1280
+ } | {
1281
+ filterID: 1399681602;
1282
+ Fltr: {
1283
+ _name: 'Smart Blur';
1284
+ _classID: 'SmrB';
1285
+ 'Rds ': number;
1286
+ Thsh: number;
1287
+ SmBQ: string;
1288
+ SmBM: string;
1289
+ };
1290
+ } | {
1291
+ filterID: 701;
1292
+ Fltr: {
1293
+ _name: 'Surface Blur';
1294
+ _classID: 'surfaceBlur';
1295
+ 'Rds ': DescriptorUnitsValue;
1296
+ Thsh: number;
1297
+ };
1298
+ } | {
1299
+ filterID: 1148416108;
1300
+ Fltr: {
1301
+ _name: 'Displace';
1302
+ _classID: 'Dspl';
1303
+ HrzS: number;
1304
+ VrtS: number;
1305
+ DspM: string;
1306
+ UndA: string;
1307
+ DspF: {
1308
+ sig: string;
1309
+ path: string;
1310
+ };
1311
+ };
1312
+ } | {
1313
+ filterID: 1349411688;
1314
+ Fltr: {
1315
+ _name: 'Pinch';
1316
+ _classID: 'Pnch';
1317
+ Amnt: number;
1318
+ };
1319
+ } | {
1320
+ filterID: 1349284384;
1321
+ Fltr: {
1322
+ _name: 'Polar Coordinates';
1323
+ _classID: 'Plr ';
1324
+ Cnvr: string;
1325
+ };
1326
+ } | {
1327
+ filterID: 1383099493;
1328
+ Fltr: {
1329
+ _name: 'Ripple';
1330
+ _classID: 'Rple';
1331
+ Amnt: number;
1332
+ RplS: string;
1333
+ };
1334
+ } | {
1335
+ filterID: 1399353888;
1336
+ Fltr: {
1337
+ _name: 'Shear';
1338
+ _classID: 'Shr ';
1339
+ ShrP: { _name: '', _classID: 'Pnt ', Hrzn: number; Vrtc: number; }[];
1340
+ UndA: string;
1341
+ ShrS: number;
1342
+ ShrE: number;
1343
+ };
1344
+ } | {
1345
+ filterID: 1399875698;
1346
+ Fltr: {
1347
+ _name: 'Spherize';
1348
+ _classID: 'Sphr';
1349
+ Amnt: number;
1350
+ SphM: string;
1351
+ };
1352
+ } | {
1353
+ filterID: 1417114220;
1354
+ Fltr: {
1355
+ _name: 'Twirl';
1356
+ _classID: 'Twrl';
1357
+ Angl: number;
1358
+ };
1359
+ } | {
1360
+ filterID: 1466005093;
1361
+ Fltr: {
1362
+ _name: 'Wave';
1363
+ _classID: 'Wave';
1364
+ Wvtp: string;
1365
+ NmbG: number;
1366
+ WLMn: number;
1367
+ WLMx: number;
1368
+ AmMn: number;
1369
+ AmMx: number;
1370
+ SclH: number;
1371
+ SclV: number;
1372
+ UndA: string;
1373
+ RndS: number;
1374
+ };
1375
+ } | {
1376
+ filterID: 1516722791;
1377
+ Fltr: {
1378
+ _name: 'ZigZag';
1379
+ _classID: 'ZgZg';
1380
+ Amnt: number;
1381
+ NmbR: number;
1382
+ ZZTy: string;
1383
+ };
1384
+ } | {
1385
+ filterID: 1097092723;
1386
+ Fltr: {
1387
+ _name: 'Add Noise';
1388
+ _classID: 'AdNs';
1389
+ Dstr: string;
1390
+ Nose: DescriptorUnitsValue;
1391
+ Mnch: boolean;
1392
+ FlRs: number;
1393
+ };
1394
+ } | {
1395
+ filterID: 1148416099;
1396
+ } | {
1397
+ filterID: 1148417107;
1398
+ Fltr: {
1399
+ _name: 'Dust & Scratches';
1400
+ _classID: 'DstS';
1401
+ 'Rds ': number;
1402
+ Thsh: number;
1403
+ };
1404
+ } | {
1405
+ filterID: 1298427424;
1406
+ Fltr: {
1407
+ _name: 'Median';
1408
+ _classID: 'Mdn ';
1409
+ 'Rds ': DescriptorUnitsValue;
1410
+ };
1411
+ } | {
1412
+ filterID: 633;
1413
+ Fltr: {
1414
+ _name: 'Reduce Noise';
1415
+ _classID: 'denoise';
1416
+ ClNs: DescriptorUnitsValue; // percent
1417
+ Shrp: DescriptorUnitsValue; // percent
1418
+ removeJPEGArtifact: boolean;
1419
+ channelDenoise: {
1420
+ _name: '';
1421
+ _classID: 'channelDenoiseParams';
1422
+ Chnl: string[];
1423
+ Amnt: number;
1424
+ EdgF?: number;
1425
+ }[];
1426
+ preset: string;
1427
+ };
1428
+ } | {
1429
+ filterID: 1131180616;
1430
+ Fltr: {
1431
+ _name: 'Color Halftone';
1432
+ _classID: 'ClrH';
1433
+ 'Rds ': number;
1434
+ Ang1: number;
1435
+ Ang2: number;
1436
+ Ang3: number;
1437
+ Ang4: number;
1438
+ };
1439
+ } | {
1440
+ filterID: 1131574132;
1441
+ Fltr: {
1442
+ _name: 'Crystallize';
1443
+ _classID: 'Crst';
1444
+ ClSz: number;
1445
+ FlRs: number;
1446
+ };
1447
+ } | {
1448
+ filterID: 1180922912;
1449
+ } | {
1450
+ filterID: 1181902701;
1451
+ } | {
1452
+ filterID: 1299870830;
1453
+ Fltr: {
1454
+ _name: 'Mezzotint';
1455
+ _classID: 'Mztn';
1456
+ MztT: string;
1457
+ FlRs: number;
1458
+ };
1459
+ } | {
1460
+ filterID: 1299407648;
1461
+ Fltr: {
1462
+ _name: 'Mosaic';
1463
+ _classID: 'Msc ';
1464
+ ClSz: DescriptorUnitsValue;
1465
+ };
1466
+ } | {
1467
+ filterID: 1349416044;
1468
+ Fltr: {
1469
+ _name: 'Pointillize';
1470
+ _classID: 'Pntl';
1471
+ ClSz: number;
1472
+ FlRs: number;
1473
+ };
1474
+ } | {
1475
+ filterID: 1131177075;
1476
+ Fltr: {
1477
+ _name: 'Clouds';
1478
+ _classID: 'Clds';
1479
+ FlRs: number;
1480
+ };
1481
+ } | {
1482
+ filterID: 1147564611;
1483
+ Fltr: {
1484
+ _name: 'Difference Clouds',
1485
+ _classID: 'DfrC',
1486
+ FlRs: number;
1487
+ };
1488
+ } | {
1489
+ filterID: 1180856947;
1490
+ Fltr: {
1491
+ _name: 'Fibers';
1492
+ _classID: 'Fbrs';
1493
+ Vrnc: number;
1494
+ Strg: number;
1495
+ RndS: number;
1496
+ };
1497
+ } | {
1498
+ filterID: 1282306886;
1499
+ Fltr: {
1500
+ _name: 'Lens Flare';
1501
+ _classID: 'LnsF';
1502
+ Brgh: number;
1503
+ FlrC: { _name: ''; _classID: 'Pnt '; Hrzn: number; Vrtc: number; };
1504
+ 'Lns ': string;
1505
+ };
1506
+ } /*| {
1507
+ filterID: 587;
1508
+ Fltr: {
1509
+ k3DLights: K3DLight[];
1510
+ key3DCurrentCameraPosition: {
1511
+ key3DXPos: number;
1512
+ key3DYPos: number;
1513
+ key3DZPos: number;
1514
+ key3DXAngle: number;
1515
+ key3DYAngle: number;
1516
+ key3DZAngle: number;
1517
+ },
1518
+ Glos: number;
1519
+ Mtrl: number;
1520
+ Exps: number;
1521
+ AmbB: number;
1522
+ AmbC: DescriptorColor;
1523
+ BmpA: number;
1524
+ BmpC: string[];
1525
+ Wdth: number;
1526
+ Hght: number;
1527
+ };
1528
+ }*/ | {
1529
+ filterID: 1399353968 | 1399353925 | 1399353933;
1530
+ } | {
1531
+ filterID: 698;
1532
+ Fltr: {
1533
+ _name: 'Smart Sharpen';
1534
+ _classID: 'smartSharpen';
1535
+ Amnt: DescriptorUnitsValue; // %
1536
+ 'Rds ': DescriptorUnitsValue;
1537
+ Thsh: number;
1538
+ Angl: number;
1539
+ moreAccurate: boolean;
1540
+ blur: string;
1541
+ preset: string;
1542
+ sdwM: {
1543
+ _name: 'Parameters',
1544
+ _classID: 'adaptCorrectTones',
1545
+ Amnt: DescriptorUnitsValue; // %
1546
+ Wdth: DescriptorUnitsValue; // %
1547
+ 'Rds ': number;
1548
+ };
1549
+ hglM: {
1550
+ _name: 'Parameters',
1551
+ _classID: 'adaptCorrectTones',
1552
+ Amnt: DescriptorUnitsValue; // %
1553
+ Wdth: DescriptorUnitsValue; // %
1554
+ 'Rds ': number;
1555
+ };
1556
+ };
1557
+ } | {
1558
+ filterID: 1433301837;
1559
+ Fltr: {
1560
+ _name: 'Unsharp Mask';
1561
+ _classID: 'UnsM';
1562
+ Amnt: DescriptorUnitsValue; // %
1563
+ 'Rds ': DescriptorUnitsValue;
1564
+ Thsh: number;
1565
+ };
1566
+ } | {
1567
+ filterID: 1147564832;
1568
+ Fltr: {
1569
+ _name: 'Diffuse';
1570
+ _classID: 'Dfs ';
1571
+ 'Md ': string;
1572
+ FlRs: number;
1573
+ };
1574
+ } | {
1575
+ filterID: 1164796531;
1576
+ Fltr: {
1577
+ _name: 'Emboss';
1578
+ _classID: 'Embs';
1579
+ Angl: number;
1580
+ Hght: number;
1581
+ Amnt: number;
1582
+ };
1583
+ } | {
1584
+ filterID: 1165522034;
1585
+ Fltr: {
1586
+ _name: 'Extrude';
1587
+ _classID: 'Extr';
1588
+ ExtS: number;
1589
+ ExtD: number;
1590
+ ExtF: boolean;
1591
+ ExtM: boolean;
1592
+ ExtT: string;
1593
+ ExtR: string;
1594
+ FlRs: number;
1595
+ };
1596
+ } | {
1597
+ filterID: 1181639749 | 1399616122;
1598
+ } | {
1599
+ filterID: 1416393504;
1600
+ Fltr: {
1601
+ _name: 'Tiles';
1602
+ _classID: 'Tls ';
1603
+ TlNm: number;
1604
+ TlOf: number;
1605
+ FlCl: string;
1606
+ FlRs: number;
1607
+ };
1608
+ } | {
1609
+ filterID: 1416782659;
1610
+ Fltr: {
1611
+ _name: 'Trace Contour';
1612
+ _classID: 'TrcC';
1613
+ 'Lvl ': number;
1614
+ 'Edg ': string;
1615
+ };
1616
+ } | {
1617
+ filterID: 1466852384;
1618
+ Fltr: {
1619
+ _name: 'Wind';
1620
+ _classID: 'Wnd ';
1621
+ WndM: string;
1622
+ Drct: string;
1623
+ };
1624
+ } | {
1625
+ filterID: 1148089458;
1626
+ Fltr: {
1627
+ _name: 'De-Interlace';
1628
+ _classID: 'Dntr';
1629
+ IntE: string;
1630
+ IntC: string;
1631
+ };
1632
+ } | {
1633
+ filterID: 1314149187;
1634
+ } | {
1635
+ filterID: 1131639917;
1636
+ Fltr: {
1637
+ _name: 'Custom';
1638
+ _classID: 'Cstm';
1639
+ 'Scl ': number;
1640
+ Ofst: number;
1641
+ Mtrx: number[];
1642
+ };
1643
+ } | {
1644
+ filterID: 1214736464;
1645
+ Fltr: {
1646
+ _name: 'High Pass';
1647
+ _classID: 'HghP';
1648
+ 'Rds ': DescriptorUnitsValue;
1649
+ };
1650
+ } | {
1651
+ filterID: 1299737888;
1652
+ Fltr: {
1653
+ _name: 'Maximum';
1654
+ _classID: 'Mxm ';
1655
+ 'Rds ': DescriptorUnitsValue;
1656
+ };
1657
+ } | {
1658
+ filterID: 1299082528;
1659
+ Fltr: {
1660
+ _name: 'Minimum';
1661
+ _classID: 'Mnm ';
1662
+ 'Rds ': DescriptorUnitsValue;
1663
+ };
1664
+ } | {
1665
+ filterID: 1332114292;
1666
+ Fltr: {
1667
+ _name: 'Offset';
1668
+ _classID: 'Ofst';
1669
+ Hrzn: number;
1670
+ Vrtc: number;
1671
+ 'Fl ': string;
1672
+ };
1673
+ } | {
1674
+ filterID: 991;
1675
+ Fltr: {
1676
+ _name: 'Rigid Transform';
1677
+ _classID: 'rigidTransform';
1678
+ 'null': string[]; // [Ordn.Trgt]
1165
1679
  rigidType: boolean;
1166
- VrsM: number;
1167
- VrsN: number;
1168
- originalVertexArray: Uint8Array;
1169
- deformedVertexArray: Uint8Array;
1170
- indexArray: Uint8Array;
1171
- pinOffsets: number[];
1172
- posFinalPins: number[];
1173
- pinVertexIndices: number[];
1174
- PinP: number[];
1175
- PnRt: number[];
1176
- PnOv: boolean[];
1177
- PnDp: number[];
1178
- meshQuality: number;
1179
- meshExpansion: number;
1180
- meshRigidity: number;
1181
- imageResolution: number;
1182
- meshBoundaryPath: {
1183
- pathComponents: {
1184
- shapeOperation: string; // shapeOperation.xor
1185
- SbpL: {
1186
- Clsp: boolean;
1187
- 'Pts ': {
1188
- Anch: HrznVrtcDescriptor;
1189
- 'Fwd ': HrznVrtcDescriptor;
1190
- 'Bwd ': HrznVrtcDescriptor;
1191
- Smoo: boolean;
1680
+ puppetShapeList?: {
1681
+ _name: '';
1682
+ _classID: 'puppetShape';
1683
+ rigidType: boolean;
1684
+ VrsM: number;
1685
+ VrsN: number;
1686
+ originalVertexArray: Uint8Array;
1687
+ deformedVertexArray: Uint8Array;
1688
+ indexArray: Uint8Array;
1689
+ pinOffsets: number[];
1690
+ posFinalPins: number[];
1691
+ pinVertexIndices: number[];
1692
+ PinP: number[];
1693
+ PnRt: number[];
1694
+ PnOv: boolean[];
1695
+ PnDp: number[];
1696
+ meshQuality: number;
1697
+ meshExpansion: number;
1698
+ meshRigidity: number;
1699
+ imageResolution: number;
1700
+ meshBoundaryPath: {
1701
+ _name: '';
1702
+ _classID: 'pathClass';
1703
+ pathComponents: {
1704
+ _name: '';
1705
+ _classID: 'PaCm';
1706
+ shapeOperation: string; // shapeOperation.xor
1707
+ SbpL: {
1708
+ _name: '';
1709
+ _classID: 'Sbpl';
1710
+ Clsp: boolean;
1711
+ 'Pts ': {
1712
+ _name: '';
1713
+ _classID: 'Pthp';
1714
+ Anch: HrznVrtcDescriptor;
1715
+ 'Fwd ': HrznVrtcDescriptor;
1716
+ 'Bwd ': HrznVrtcDescriptor;
1717
+ Smoo: boolean;
1718
+ }[];
1192
1719
  }[];
1193
1720
  }[];
1194
- }[];
1195
- };
1196
- selectedPin: number[];
1197
- }[];
1198
- PuX0: number;
1199
- PuX1: number;
1200
- PuX2: number;
1201
- PuX3: number;
1202
- PuY0: number;
1203
- PuY1: number;
1204
- PuY2: number;
1205
- PuY3: number;
1721
+ };
1722
+ selectedPin: number[];
1723
+ }[];
1724
+ PuX0: number;
1725
+ PuX1: number;
1726
+ PuX2: number;
1727
+ PuX3: number;
1728
+ PuY0: number;
1729
+ PuY1: number;
1730
+ PuY2: number;
1731
+ PuY3: number;
1732
+ }
1206
1733
  } | {
1207
- LqMe: Uint8Array;
1208
- };
1734
+ filterID: 1348620396;
1735
+ Fltr: {
1736
+ _name: 'Oil Paint Plugin';
1737
+ _classID: 'PbPl';
1738
+ KnNm: string;
1739
+ GpuY: boolean;
1740
+ LIWy: boolean;
1741
+ FPth: string;
1742
+ // PNaa: string;
1743
+ // PTaa: number;
1744
+ // PFaa: number;
1745
+ // PNab: string;
1746
+ // PTab: number;
1747
+ // PFab: number;
1748
+ // ...
1749
+ };
1750
+ } /*| {
1751
+ filterID: 1282294642;
1752
+ Fltr: {
1753
+ _name: 'Lens Correction',
1754
+ _classID: 'LnCr',
1755
+ LnAg: boolean;
1756
+ LnAc: boolean;
1757
+ LnAv: boolean;
1758
+ LnAs: boolean;
1759
+ LnIp: boolean;
1760
+ LnFo: number;
1761
+ LnPr: string;
1762
+ LnIa: number;
1763
+ LnI0: number;
1764
+ LnI1: number;
1765
+ LnI2: number;
1766
+ LnI3: number;
1767
+ LnRa: number;
1768
+ LnVp: number;
1769
+ LnHp: number;
1770
+ LnSi: number;
1771
+ LnFt: number;
1772
+ LnSb: number;
1773
+ LnSt: number;
1774
+ LnRc: number;
1775
+ LnGm: number;
1776
+ LnBy: number;
1777
+ LnNa: number;
1778
+ LnIh: number;
1779
+ LnIv: number;
1780
+ LnIs: DescriptorColor;
1781
+ LnNm: boolean;
1782
+ };
1783
+ }*//* | {
1784
+ filterID: 2089;
1785
+ Fltr: {
1786
+ _name: 'Adaptive Wide Angle';
1787
+ _classID: '22C3EEBF-A978-4ca9-91DF-E4F0CCEE5ACE';
1788
+ actV: number;
1789
+ cnsD?: Uint8Array;
1790
+ prjM: string;
1791
+ regM: string;
1792
+ focL: number;
1793
+ PhyF: number;
1794
+ CrpF: number;
1795
+ imgS: number;
1796
+ imgX: number;
1797
+ imgY: number;
1798
+ };
1799
+ }*//* | {
1800
+ filterID: 1195730531;
1801
+ Fltr: {
1802
+ _name: 'Filter Gallery';
1803
+ _classID: 'GEfc';
1804
+ } & ({
1805
+ GEfk: string;
1806
+ Pncl: number;
1807
+ StrP: number;
1808
+ PprB: number;
1809
+ } | ...);
1810
+ };
1811
+ }*/ | {
1812
+ filterID: 1215521360;
1813
+ Fltr: {
1814
+ _name: 'HSB/HSL',
1815
+ _classID: 'HsbP',
1816
+ Inpt: string;
1817
+ Otpt: string;
1818
+ };
1819
+ } | {
1820
+ filterID: 1122;
1821
+ Fltr: {
1822
+ _name: 'Oil Paint',
1823
+ _classID: 'oilPaint',
1824
+ lightingOn: boolean;
1825
+ stylization: number;
1826
+ cleanliness: number;
1827
+ brushScale: number;
1828
+ microBrush: number;
1829
+ LghD: number;
1830
+ specularity: number;
1831
+ };
1832
+ } | {
1833
+ filterID: 1282492025;
1834
+ Fltr: {
1835
+ _name: 'Liquify',
1836
+ _classID: 'LqFy',
1837
+ LqMe: Uint8Array;
1838
+ };
1839
+ });
1209
1840
 
1210
1841
  interface SoLdDescriptorFilter {
1842
+ _name: '',
1843
+ _classID: 'filterFXStyle',
1211
1844
  enab: boolean,
1212
1845
  validAtPosition: boolean,
1213
1846
  filterMaskEnable: boolean,
1214
1847
  filterMaskLinked: boolean,
1215
1848
  filterMaskExtendWithWhite: boolean,
1216
- filterFXList: {
1217
- 'Nm ': string;
1218
- blendOptions: {
1219
- Opct: DescriptorUnitsValue;
1220
- 'Md ': string; // blend mode
1221
- };
1222
- enab: boolean;
1223
- hasoptions: boolean;
1224
- FrgC: DescriptorColor;
1225
- BckC: DescriptorColor;
1226
- Fltr: FltrDescriptor;
1227
- filterID: number;
1228
- }[];
1849
+ filterFXList: SoLdDescriptorFilterItem[];
1229
1850
  }
1230
1851
 
1231
1852
  function uint8ToFloat32(array: Uint8Array) {
@@ -1271,59 +1892,545 @@ function hrznVrtcToPoint(desc: HrznVrtcDescriptor) {
1271
1892
 
1272
1893
  function pointToHrznVrtc(point: { x: UnitsValue; y: UnitsValue; }): HrznVrtcDescriptor {
1273
1894
  return {
1895
+ _name: '',
1896
+ _classID: 'Pnt ',
1274
1897
  Hrzn: unitsValue(point.x, 'x'),
1275
1898
  Vrtc: unitsValue(point.y, 'y'),
1276
1899
  };
1277
1900
  }
1278
1901
 
1279
- function parseFilterFXFilter(Fltr: FltrDescriptor): PlacedLayerPuppetFilter | {} {
1280
- if ('puppetShapeList' in Fltr) {
1281
- return {
1282
- rigidType: Fltr.rigidType,
1283
- bounds: [
1284
- { x: Fltr.PuX0, y: Fltr.PuY0, },
1285
- { x: Fltr.PuX1, y: Fltr.PuY1, },
1286
- { x: Fltr.PuX2, y: Fltr.PuY2, },
1287
- { x: Fltr.PuX3, y: Fltr.PuY3, },
1288
- ],
1289
- puppetShapeList: Fltr.puppetShapeList!.map(p => ({
1290
- rigidType: p.rigidType,
1291
- // TODO: VrsM
1292
- // TODO: VrsN
1293
- originalVertexArray: uint8ToPoints(p.originalVertexArray),
1294
- deformedVertexArray: uint8ToPoints(p.deformedVertexArray),
1295
- indexArray: Array.from(uint8ToUint32(p.indexArray)),
1296
- pinOffsets: arrayToPoints(p.pinOffsets),
1297
- posFinalPins: arrayToPoints(p.posFinalPins),
1298
- pinVertexIndices: p.pinVertexIndices,
1299
- selectedPin: p.selectedPin,
1300
- pinPosition: arrayToPoints(p.PinP),
1301
- pinRotation: p.PnRt,
1302
- pinOverlay: p.PnOv,
1303
- pinDepth: p.PnDp,
1304
- meshQuality: p.meshQuality,
1305
- meshExpansion: p.meshExpansion,
1306
- meshRigidity: p.meshRigidity,
1307
- imageResolution: p.imageResolution,
1308
- meshBoundaryPath: {
1309
- pathComponents: p.meshBoundaryPath.pathComponents.map(c => ({
1310
- shapeOperation: c.shapeOperation.split('.')[1],
1311
- paths: c.SbpL.map(t => ({
1312
- closed: t.Clsp,
1313
- points: t['Pts '].map(pt => ({
1314
- anchor: hrznVrtcToPoint(pt.Anch),
1315
- forward: hrznVrtcToPoint(pt['Fwd ']),
1316
- backward: hrznVrtcToPoint(pt['Bwd ']),
1317
- smooth: pt.Smoo,
1902
+ function parseFilterFXItem(f: SoLdDescriptorFilterItem): Filter {
1903
+ const base: Omit<Filter, 'type' | 'filter'> = {
1904
+ name: f['Nm '],
1905
+ opacity: parsePercent(f.blendOptions.Opct),
1906
+ blendMode: BlnM.decode(f.blendOptions['Md ']),
1907
+ enabled: f.enab,
1908
+ hasOptions: f.hasoptions,
1909
+ foregroundColor: parseColor(f.FrgC),
1910
+ backgroundColor: parseColor(f.BckC),
1911
+ };
1912
+
1913
+ switch (f.filterID) {
1914
+ case 1098281575: return { ...base, type: 'average' };
1915
+ case 1114403360: return { ...base, type: 'blur' };
1916
+ case 1114403405: return { ...base, type: 'blur more' };
1917
+ case 697: return {
1918
+ ...base,
1919
+ type: 'box blur',
1920
+ filter: {
1921
+ radius: parseUnits(f.Fltr['Rds ']),
1922
+ },
1923
+ };
1924
+ case 1198747202: return {
1925
+ ...base,
1926
+ type: 'gaussian blur',
1927
+ filter: {
1928
+ radius: parseUnits(f.Fltr['Rds ']),
1929
+ },
1930
+ };
1931
+ case 1299476034: return {
1932
+ ...base,
1933
+ type: 'motion blur',
1934
+ filter: {
1935
+ angle: f.Fltr.Angl,
1936
+ distance: parseUnits(f.Fltr.Dstn),
1937
+ },
1938
+ };
1939
+ case 1382313026: return {
1940
+ ...base,
1941
+ type: 'radial blur',
1942
+ filter: {
1943
+ amount: f.Fltr.Amnt,
1944
+ method: BlrM.decode(f.Fltr.BlrM),
1945
+ quality: BlrQ.decode(f.Fltr.BlrQ),
1946
+ },
1947
+ };
1948
+ case 702: return {
1949
+ ...base,
1950
+ type: 'shape blur',
1951
+ filter: {
1952
+ radius: parseUnits(f.Fltr['Rds ']),
1953
+ customShape: { name: f.Fltr.customShape['Nm '], id: f.Fltr.customShape.Idnt },
1954
+ },
1955
+ };
1956
+ case 1399681602: return {
1957
+ ...base,
1958
+ type: 'smart blur',
1959
+ filter: {
1960
+ radius: f.Fltr['Rds '],
1961
+ threshold: f.Fltr.Thsh,
1962
+ quality: SmBQ.decode(f.Fltr.SmBQ),
1963
+ mode: SmBM.decode(f.Fltr.SmBM),
1964
+ },
1965
+ };
1966
+ case 701: return {
1967
+ ...base,
1968
+ type: 'surface blur',
1969
+ filter: {
1970
+ radius: parseUnits(f.Fltr['Rds ']),
1971
+ threshold: f.Fltr.Thsh,
1972
+ },
1973
+ };
1974
+ case 1148416108: return {
1975
+ ...base,
1976
+ type: 'displace',
1977
+ filter: {
1978
+ horizontalScale: f.Fltr.HrzS,
1979
+ verticalScale: f.Fltr.VrtS,
1980
+ displacementMap: DspM.decode(f.Fltr.DspM),
1981
+ undefinedAreas: UndA.decode(f.Fltr.UndA),
1982
+ displacementFile: {
1983
+ signature: f.Fltr.DspF.sig,
1984
+ path: f.Fltr.DspF.path, // TODO: this is decoded incorrectly ???
1985
+ },
1986
+ },
1987
+ };
1988
+ case 1349411688: return {
1989
+ ...base,
1990
+ type: 'pinch',
1991
+ filter: {
1992
+ amount: f.Fltr.Amnt,
1993
+ },
1994
+ };
1995
+ case 1349284384: return {
1996
+ ...base,
1997
+ type: 'polar coordinates',
1998
+ filter: {
1999
+ conversion: Cnvr.decode(f.Fltr.Cnvr),
2000
+ },
2001
+ };
2002
+ case 1383099493: return {
2003
+ ...base,
2004
+ type: 'ripple',
2005
+ filter: {
2006
+ amount: f.Fltr.Amnt,
2007
+ size: RplS.decode(f.Fltr.RplS),
2008
+ },
2009
+ };
2010
+ case 1399353888: return {
2011
+ ...base,
2012
+ type: 'shear',
2013
+ filter: {
2014
+ shearPoints: f.Fltr.ShrP.map(p => ({ x: p.Hrzn, y: p.Vrtc })),
2015
+ shearStart: f.Fltr.ShrS,
2016
+ shearEnd: f.Fltr.ShrE,
2017
+ undefinedAreas: UndA.decode(f.Fltr.UndA),
2018
+ },
2019
+ };
2020
+ case 1399875698: return {
2021
+ ...base,
2022
+ type: 'spherize',
2023
+ filter: {
2024
+ amount: f.Fltr.Amnt,
2025
+ mode: SphM.decode(f.Fltr.SphM),
2026
+ },
2027
+ };
2028
+ case 1417114220: return {
2029
+ ...base,
2030
+ type: 'twirl',
2031
+ filter: {
2032
+ angle: f.Fltr.Angl,
2033
+ },
2034
+ };
2035
+ case 1466005093: return {
2036
+ ...base,
2037
+ type: 'wave',
2038
+ filter: {
2039
+ numberOfGenerators: f.Fltr.NmbG,
2040
+ type: Wvtp.decode(f.Fltr.Wvtp),
2041
+ wavelength: { min: f.Fltr.WLMn, max: f.Fltr.WLMx },
2042
+ amplitude: { min: f.Fltr.AmMn, max: f.Fltr.AmMx },
2043
+ scale: { x: f.Fltr.SclH, y: f.Fltr.SclV },
2044
+ randomSeed: f.Fltr.RndS,
2045
+ undefinedAreas: UndA.decode(f.Fltr.UndA),
2046
+ },
2047
+ };
2048
+ case 1516722791: return {
2049
+ ...base,
2050
+ type: 'zigzag',
2051
+ filter: {
2052
+ amount: f.Fltr.Amnt,
2053
+ ridges: f.Fltr.NmbR,
2054
+ style: ZZTy.decode(f.Fltr.ZZTy),
2055
+ },
2056
+ };
2057
+ case 1097092723: return {
2058
+ ...base,
2059
+ type: 'add noise',
2060
+ filter: {
2061
+ amount: parsePercent(f.Fltr.Nose),
2062
+ distribution: Dstr.decode(f.Fltr.Dstr),
2063
+ monochromatic: f.Fltr.Mnch,
2064
+ randomSeed: f.Fltr.FlRs,
2065
+ },
2066
+ };
2067
+ case 1148416099: return { ...base, type: 'despeckle' };
2068
+ case 1148417107: return {
2069
+ ...base,
2070
+ type: 'dust and scratches',
2071
+ filter: {
2072
+ radius: f.Fltr['Rds '],
2073
+ threshold: f.Fltr.Thsh,
2074
+ },
2075
+ };
2076
+ case 1298427424: return {
2077
+ ...base,
2078
+ type: 'median',
2079
+ filter: {
2080
+ radius: parseUnits(f.Fltr['Rds ']),
2081
+ },
2082
+ };
2083
+ case 633: return {
2084
+ ...base,
2085
+ type: 'reduce noise',
2086
+ filter: {
2087
+ preset: f.Fltr.preset,
2088
+ removeJpegArtifact: f.Fltr.removeJPEGArtifact,
2089
+ reduceColorNoise: parsePercent(f.Fltr.ClNs),
2090
+ sharpenDetails: parsePercent(f.Fltr.Shrp),
2091
+ channelDenoise: f.Fltr.channelDenoise.map(c => ({
2092
+ channels: c.Chnl.map(i => Chnl.decode(i)),
2093
+ amount: c.Amnt,
2094
+ ...(c.EdgF ? { preserveDetails: c.EdgF } : {}),
2095
+ })),
2096
+ },
2097
+ };
2098
+ case 1131180616: return {
2099
+ ...base,
2100
+ type: 'color halftone',
2101
+ filter: {
2102
+ radius: f.Fltr['Rds '],
2103
+ angle1: f.Fltr.Ang1,
2104
+ angle2: f.Fltr.Ang2,
2105
+ angle3: f.Fltr.Ang3,
2106
+ angle4: f.Fltr.Ang4,
2107
+ },
2108
+ };
2109
+ case 1131574132: return {
2110
+ ...base,
2111
+ type: 'crystallize',
2112
+ filter: {
2113
+ cellSize: f.Fltr.ClSz,
2114
+ randomSeed: f.Fltr.FlRs,
2115
+ },
2116
+ };
2117
+ case 1180922912: return { ...base, type: 'facet' };
2118
+ case 1181902701: return { ...base, type: 'fragment' };
2119
+ case 1299870830: return {
2120
+ ...base,
2121
+ type: 'mezzotint',
2122
+ filter: {
2123
+ type: MztT.decode(f.Fltr.MztT),
2124
+ randomSeed: f.Fltr.FlRs,
2125
+ },
2126
+ };
2127
+ case 1299407648: return {
2128
+ ...base,
2129
+ type: 'mosaic',
2130
+ filter: {
2131
+ cellSize: parseUnits(f.Fltr.ClSz),
2132
+ },
2133
+ };
2134
+ case 1349416044: return {
2135
+ ...base,
2136
+ type: 'pointillize',
2137
+ filter: {
2138
+ cellSize: f.Fltr.ClSz,
2139
+ randomSeed: f.Fltr.FlRs,
2140
+ },
2141
+ };
2142
+ case 1131177075: return {
2143
+ ...base,
2144
+ type: 'clouds',
2145
+ filter: {
2146
+ randomSeed: f.Fltr.FlRs,
2147
+ },
2148
+ };
2149
+ case 1147564611: return {
2150
+ ...base,
2151
+ type: 'difference clouds',
2152
+ filter: {
2153
+ randomSeed: f.Fltr.FlRs,
2154
+ },
2155
+ };
2156
+ case 1180856947: return {
2157
+ ...base,
2158
+ type: 'fibers',
2159
+ filter: {
2160
+ variance: f.Fltr.Vrnc,
2161
+ strength: f.Fltr.Strg,
2162
+ randomSeed: f.Fltr.RndS,
2163
+ },
2164
+ };
2165
+ case 1282306886: return {
2166
+ ...base,
2167
+ type: 'lens flare',
2168
+ filter: {
2169
+ brightness: f.Fltr.Brgh,
2170
+ position: { x: f.Fltr.FlrC.Hrzn, y: f.Fltr.FlrC.Vrtc },
2171
+ lensType: Lns.decode(f.Fltr['Lns ']),
2172
+ },
2173
+ };
2174
+ case 1399353968: return { ...base, type: 'sharpen' };
2175
+ case 1399353925: return { ...base, type: 'sharpen edges' };
2176
+ case 1399353933: return { ...base, type: 'sharpen more' };
2177
+ case 698: return {
2178
+ ...base,
2179
+ type: 'smart sharpen',
2180
+ filter: {
2181
+ amount: parsePercent(f.Fltr.Amnt),
2182
+ radius: parseUnits(f.Fltr['Rds ']),
2183
+ threshold: f.Fltr.Thsh,
2184
+ angle: f.Fltr.Angl,
2185
+ moreAccurate: f.Fltr.moreAccurate,
2186
+ blur: blurType.decode(f.Fltr.blur),
2187
+ preset: f.Fltr.preset,
2188
+ shadow: {
2189
+ fadeAmount: parsePercent(f.Fltr.sdwM.Amnt),
2190
+ tonalWidth: parsePercent(f.Fltr.sdwM.Wdth),
2191
+ radius: f.Fltr.sdwM['Rds '],
2192
+ },
2193
+ highlight: {
2194
+ fadeAmount: parsePercent(f.Fltr.hglM.Amnt),
2195
+ tonalWidth: parsePercent(f.Fltr.hglM.Wdth),
2196
+ radius: f.Fltr.hglM['Rds '],
2197
+ },
2198
+ },
2199
+ };
2200
+ case 1433301837: return {
2201
+ ...base,
2202
+ type: 'unsharp mask',
2203
+ filter: {
2204
+ amount: parsePercent(f.Fltr.Amnt),
2205
+ radius: parseUnits(f.Fltr['Rds ']),
2206
+ threshold: f.Fltr.Thsh,
2207
+ },
2208
+ };
2209
+ case 1147564832: return {
2210
+ ...base,
2211
+ type: 'diffuse',
2212
+ filter: {
2213
+ mode: DfsM.decode(f.Fltr['Md ']),
2214
+ randomSeed: f.Fltr.FlRs,
2215
+ },
2216
+ };
2217
+ case 1164796531: return {
2218
+ ...base,
2219
+ type: 'emboss',
2220
+ filter: {
2221
+ angle: f.Fltr.Angl,
2222
+ height: f.Fltr.Hght,
2223
+ amount: f.Fltr.Amnt,
2224
+ },
2225
+ };
2226
+ case 1165522034: return {
2227
+ ...base,
2228
+ type: 'extrude',
2229
+ filter: {
2230
+ type: ExtT.decode(f.Fltr.ExtT),
2231
+ size: f.Fltr.ExtS,
2232
+ depth: f.Fltr.ExtD,
2233
+ depthMode: ExtR.decode(f.Fltr.ExtR),
2234
+ randomSeed: f.Fltr.FlRs,
2235
+ solidFrontFaces: f.Fltr.ExtF,
2236
+ maskIncompleteBlocks: f.Fltr.ExtM,
2237
+ },
2238
+ };
2239
+ case 1181639749: return { ...base, type: 'find edges' };
2240
+ case 1399616122: return { ...base, type: 'solarize' };
2241
+ case 1416393504: return {
2242
+ ...base,
2243
+ type: 'tiles',
2244
+ filter: {
2245
+ numberOfTiles: f.Fltr.TlNm,
2246
+ maximumOffset: f.Fltr.TlOf,
2247
+ fillEmptyAreaWith: FlCl.decode(f.Fltr.FlCl),
2248
+ randomSeed: f.Fltr.FlRs,
2249
+ },
2250
+ };
2251
+ case 1416782659: return {
2252
+ ...base,
2253
+ type: 'trace contour',
2254
+ filter: {
2255
+ level: f.Fltr['Lvl '],
2256
+ edge: CntE.decode(f.Fltr['Edg ']),
2257
+ },
2258
+ };
2259
+ case 1466852384: return {
2260
+ ...base,
2261
+ type: 'wind',
2262
+ filter: {
2263
+ method: WndM.decode(f.Fltr.WndM),
2264
+ direction: Drct.decode(f.Fltr.Drct),
2265
+ },
2266
+ };
2267
+ case 1148089458: return {
2268
+ ...base,
2269
+ type: 'de-interlace',
2270
+ filter: {
2271
+ eliminate: IntE.decode(f.Fltr.IntE),
2272
+ newFieldsBy: IntC.decode(f.Fltr.IntC),
2273
+ },
2274
+ };
2275
+ case 1314149187: return { ...base, type: 'ntsc colors' };
2276
+ case 1131639917: return {
2277
+ ...base,
2278
+ type: 'custom',
2279
+ filter: {
2280
+ scale: f.Fltr['Scl '],
2281
+ offset: f.Fltr.Ofst,
2282
+ matrix: f.Fltr.Mtrx,
2283
+ },
2284
+ };
2285
+ case 1214736464: return {
2286
+ ...base,
2287
+ type: 'high pass',
2288
+ filter: {
2289
+ radius: parseUnits(f.Fltr['Rds ']),
2290
+ },
2291
+ };
2292
+ case 1299737888: return {
2293
+ ...base,
2294
+ type: 'maximum',
2295
+ filter: {
2296
+ radius: parseUnits(f.Fltr['Rds ']),
2297
+ },
2298
+ };
2299
+ case 1299082528: return {
2300
+ ...base,
2301
+ type: 'minimum',
2302
+ filter: {
2303
+ radius: parseUnits(f.Fltr['Rds ']),
2304
+ },
2305
+ };
2306
+ case 1332114292: return {
2307
+ ...base,
2308
+ type: 'offset',
2309
+ filter: {
2310
+ horizontal: f.Fltr.Hrzn,
2311
+ vertical: f.Fltr.Vrtc,
2312
+ undefinedAreas: FlMd.decode(f.Fltr['Fl ']),
2313
+ },
2314
+ };
2315
+ case 991: return {
2316
+ ...base,
2317
+ type: 'puppet',
2318
+ filter: {
2319
+ rigidType: f.Fltr.rigidType,
2320
+ bounds: [
2321
+ { x: f.Fltr.PuX0, y: f.Fltr.PuY0, },
2322
+ { x: f.Fltr.PuX1, y: f.Fltr.PuY1, },
2323
+ { x: f.Fltr.PuX2, y: f.Fltr.PuY2, },
2324
+ { x: f.Fltr.PuX3, y: f.Fltr.PuY3, },
2325
+ ],
2326
+ puppetShapeList: f.Fltr.puppetShapeList!.map(p => ({
2327
+ rigidType: p.rigidType,
2328
+ // TODO: VrsM
2329
+ // TODO: VrsN
2330
+ originalVertexArray: uint8ToPoints(p.originalVertexArray),
2331
+ deformedVertexArray: uint8ToPoints(p.deformedVertexArray),
2332
+ indexArray: Array.from(uint8ToUint32(p.indexArray)),
2333
+ pinOffsets: arrayToPoints(p.pinOffsets),
2334
+ posFinalPins: arrayToPoints(p.posFinalPins),
2335
+ pinVertexIndices: p.pinVertexIndices,
2336
+ selectedPin: p.selectedPin,
2337
+ pinPosition: arrayToPoints(p.PinP),
2338
+ pinRotation: p.PnRt,
2339
+ pinOverlay: p.PnOv,
2340
+ pinDepth: p.PnDp,
2341
+ meshQuality: p.meshQuality,
2342
+ meshExpansion: p.meshExpansion,
2343
+ meshRigidity: p.meshRigidity,
2344
+ imageResolution: p.imageResolution,
2345
+ meshBoundaryPath: {
2346
+ pathComponents: p.meshBoundaryPath.pathComponents.map(c => ({
2347
+ shapeOperation: c.shapeOperation.split('.')[1],
2348
+ paths: c.SbpL.map(t => ({
2349
+ closed: t.Clsp,
2350
+ points: t['Pts '].map(pt => ({
2351
+ anchor: hrznVrtcToPoint(pt.Anch),
2352
+ forward: hrznVrtcToPoint(pt['Fwd ']),
2353
+ backward: hrznVrtcToPoint(pt['Bwd ']),
2354
+ smooth: pt.Smoo,
2355
+ })),
1318
2356
  })),
1319
2357
  })),
1320
- })),
2358
+ },
2359
+ })),
2360
+ },
2361
+ };
2362
+ case 1348620396: {
2363
+ const parameters: { name: string; value: number; }[] = [];
2364
+ const Flrt = f.Fltr as any;
2365
+
2366
+ for (let i = 0; i < fromAtoZ.length; i++) {
2367
+ if (!Flrt[`PN${fromAtoZ[i]}a`]) break;
2368
+
2369
+ for (let j = 0; j < fromAtoZ.length; j++) {
2370
+ if (!Flrt[`PN${fromAtoZ[i]}${fromAtoZ[j]}`]) break;
2371
+
2372
+ parameters.push({
2373
+ name: Flrt[`PN${fromAtoZ[i]}${fromAtoZ[j]}`],
2374
+ value: Flrt[`PF${fromAtoZ[i]}${fromAtoZ[j]}`]
2375
+ });
2376
+ }
2377
+ }
2378
+
2379
+ return {
2380
+ ...base,
2381
+ type: 'oil paint plugin',
2382
+ filter: {
2383
+ name: f.Fltr.KnNm,
2384
+ gpu: f.Fltr.GpuY,
2385
+ lighting: f.Fltr.LIWy,
2386
+ parameters,
1321
2387
  },
1322
- })),
2388
+ }
2389
+ }
2390
+ // case 2089: return {
2391
+ // ...base,
2392
+ // type: 'adaptive wide angle',
2393
+ // params: {
2394
+ // correction: prjM.decode(f.Fltr.prjM),
2395
+ // focalLength: f.Fltr.focL,
2396
+ // cropFactor: f.Fltr.CrpF,
2397
+ // imageScale: f.Fltr.imgS,
2398
+ // imageX: f.Fltr.imgX,
2399
+ // imageY: f.Fltr.imgY,
2400
+ // },
2401
+ // };
2402
+ case 1215521360: return {
2403
+ ...base,
2404
+ type: 'hsb/hsl',
2405
+ filter: {
2406
+ inputMode: ClrS.decode(f.Fltr.Inpt) as any,
2407
+ rowOrder: ClrS.decode(f.Fltr.Otpt) as any,
2408
+ },
1323
2409
  };
1324
- } else {
1325
- return {
2410
+ case 1122: return {
2411
+ ...base,
2412
+ type: 'oil paint',
2413
+ filter: {
2414
+ lightingOn: f.Fltr.lightingOn,
2415
+ stylization: f.Fltr.stylization,
2416
+ cleanliness: f.Fltr.cleanliness,
2417
+ brushScale: f.Fltr.brushScale,
2418
+ microBrush: f.Fltr.microBrush,
2419
+ lightDirection: f.Fltr.LghD,
2420
+ specularity: f.Fltr.specularity,
2421
+ },
1326
2422
  };
2423
+ case 1282492025: {
2424
+ return {
2425
+ ...base,
2426
+ type: 'liquify',
2427
+ filter: {
2428
+ liquifyMesh: f.Fltr.LqMe,
2429
+ },
2430
+ };
2431
+ }
2432
+ default:
2433
+ throw new Error(`Unknown filterID: ${(f as any).filterID}`);
1327
2434
  }
1328
2435
  }
1329
2436
 
@@ -1334,98 +2441,653 @@ function parseFilterFX(desc: SoLdDescriptorFilter): PlacedLayerFilter {
1334
2441
  maskEnabled: desc.filterMaskEnable,
1335
2442
  maskLinked: desc.filterMaskLinked,
1336
2443
  maskExtendWithWhite: desc.filterMaskExtendWithWhite,
1337
- list: desc.filterFXList.map(f => ({
1338
- id: f.filterID,
1339
- name: f['Nm '],
1340
- opacity: parsePercent(f.blendOptions.Opct),
1341
- blendMode: BlnM.decode(f.blendOptions['Md ']),
1342
- enabled: f.enab,
1343
- hasOptions: f.hasoptions,
1344
- foregroundColor: parseColor(f.FrgC),
1345
- backgroundColor: parseColor(f.BckC),
1346
- filter: parseFilterFXFilter(f.Fltr),
1347
- })),
2444
+ list: desc.filterFXList.map(parseFilterFXItem),
1348
2445
  };
1349
2446
  }
1350
2447
 
1351
- function serializeFltr(filter: PlacedLayerPuppetFilter | {}): FltrDescriptor {
1352
- if ('puppetShapeList' in filter) {
1353
- return {
1354
- 'null': ['Ordn.Trgt'], // ???
1355
- rigidType: filter.rigidType,
1356
- puppetShapeList: filter.puppetShapeList.map(p => ({
1357
- rigidType: p.rigidType,
1358
- VrsM: 1, // TODO: ...
1359
- VrsN: 0, // TODO: ...
1360
- originalVertexArray: toUint8(new Float32Array(pointsToArray(p.originalVertexArray))),
1361
- deformedVertexArray: toUint8(new Float32Array(pointsToArray(p.deformedVertexArray))),
1362
- indexArray: toUint8(new Uint32Array(p.indexArray)),
1363
- pinOffsets: pointsToArray(p.pinOffsets),
1364
- posFinalPins: pointsToArray(p.posFinalPins),
1365
- selectedPin: p.selectedPin,
1366
- pinVertexIndices: p.pinVertexIndices,
1367
- PinP: pointsToArray(p.pinPosition),
1368
- PnRt: p.pinRotation,
1369
- PnOv: p.pinOverlay,
1370
- PnDp: p.pinDepth,
1371
- meshQuality: p.meshQuality,
1372
- meshExpansion: p.meshExpansion,
1373
- meshRigidity: p.meshRigidity,
1374
- imageResolution: p.imageResolution,
1375
- meshBoundaryPath: {
1376
- pathComponents: (p.meshBoundaryPath.pathComponents || []).map(c => ({
1377
- shapeOperation: `shapeOperation.${c.shapeOperation}`,
1378
- SbpL: (c.paths || []).map(path => ({
1379
- Clsp: path.closed,
1380
- 'Pts ': (path.points || []).map(pt => ({
1381
- Anch: pointToHrznVrtc(pt.anchor),
1382
- 'Fwd ': pointToHrznVrtc(pt.forward),
1383
- 'Bwd ': pointToHrznVrtc(pt.backward),
1384
- Smoo: pt.smooth,
2448
+ function uvRadius(t: { radius: UnitsValue; }) {
2449
+ return unitsValue(t.radius, 'radius');
2450
+ }
2451
+
2452
+ function serializeFilterFXItem(f: Filter): SoLdDescriptorFilterItem {
2453
+ const base: Omit<SoLdDescriptorFilterItem, 'filterID' | 'filter'> = {
2454
+ _name: '',
2455
+ _classID: 'filterFX',
2456
+ 'Nm ': f.name,
2457
+ blendOptions: {
2458
+ _name: '',
2459
+ _classID: 'blendOptions',
2460
+ Opct: unitsPercentF(f.opacity),
2461
+ 'Md ': BlnM.encode(f.blendMode),
2462
+ },
2463
+ enab: f.enabled,
2464
+ hasoptions: f.hasOptions,
2465
+ FrgC: serializeColor(f.foregroundColor),
2466
+ BckC: serializeColor(f.backgroundColor),
2467
+ };
2468
+
2469
+ switch (f.type) {
2470
+ case 'average': return { ...base, filterID: 1098281575 };
2471
+ case 'blur': return { ...base, filterID: 1114403360 };
2472
+ case 'blur more': return { ...base, filterID: 1114403405 };
2473
+ case 'box blur': return {
2474
+ ...base,
2475
+ Fltr: {
2476
+ _name: 'Box Blur',
2477
+ _classID: 'boxblur',
2478
+ 'Rds ': uvRadius(f.filter),
2479
+ },
2480
+ filterID: 697,
2481
+ };
2482
+ case 'gaussian blur': return {
2483
+ ...base,
2484
+ Fltr: {
2485
+ _name: 'Gaussian Blur',
2486
+ _classID: 'GsnB',
2487
+ 'Rds ': uvRadius(f.filter),
2488
+ },
2489
+ filterID: 1198747202,
2490
+ };
2491
+ case 'motion blur': return {
2492
+ ...base,
2493
+ Fltr: {
2494
+ _name: 'Motion Blur',
2495
+ _classID: 'MtnB',
2496
+ Angl: f.filter.angle,
2497
+ Dstn: unitsValue(f.filter.distance, 'distance'),
2498
+ },
2499
+ filterID: 1299476034,
2500
+ };
2501
+ case 'radial blur': return {
2502
+ ...base,
2503
+ Fltr: {
2504
+ _name: 'Radial Blur',
2505
+ _classID: 'RdlB',
2506
+ Amnt: f.filter.amount,
2507
+ BlrM: BlrM.encode(f.filter.method),
2508
+ BlrQ: BlrQ.encode(f.filter.quality),
2509
+ },
2510
+ filterID: 1382313026,
2511
+ };
2512
+ case 'shape blur': return {
2513
+ ...base,
2514
+ Fltr: {
2515
+ _name: 'Shape Blur',
2516
+ _classID: 'shapeBlur',
2517
+ 'Rds ': uvRadius(f.filter),
2518
+ customShape: {
2519
+ _name: '',
2520
+ _classID: 'customShape',
2521
+ 'Nm ': f.filter.customShape.name,
2522
+ Idnt: f.filter.customShape.id,
2523
+ }
2524
+ },
2525
+ filterID: 702,
2526
+ };
2527
+ case 'smart blur': return {
2528
+ ...base,
2529
+ Fltr: {
2530
+ _name: 'Smart Blur',
2531
+ _classID: 'SmrB',
2532
+ 'Rds ': f.filter.radius,
2533
+ Thsh: f.filter.threshold,
2534
+ SmBQ: SmBQ.encode(f.filter.quality),
2535
+ SmBM: SmBM.encode(f.filter.mode),
2536
+ },
2537
+ filterID: 1399681602,
2538
+ };
2539
+ case 'surface blur': return {
2540
+ ...base,
2541
+ Fltr: {
2542
+ _name: 'Surface Blur',
2543
+ _classID: 'surfaceBlur',
2544
+ 'Rds ': uvRadius(f.filter),
2545
+ Thsh: f.filter.threshold,
2546
+ },
2547
+ filterID: 701,
2548
+ };
2549
+ case 'displace': return {
2550
+ ...base,
2551
+ Fltr: {
2552
+ _name: 'Displace',
2553
+ _classID: 'Dspl',
2554
+ HrzS: f.filter.horizontalScale,
2555
+ VrtS: f.filter.verticalScale,
2556
+ DspM: DspM.encode(f.filter.displacementMap),
2557
+ UndA: UndA.encode(f.filter.undefinedAreas),
2558
+ DspF: {
2559
+ sig: f.filter.displacementFile.signature,
2560
+ path: f.filter.displacementFile.path,
2561
+ },
2562
+ },
2563
+ filterID: 1148416108,
2564
+ };
2565
+ case 'pinch': return {
2566
+ ...base,
2567
+ Fltr: {
2568
+ _name: 'Pinch',
2569
+ _classID: 'Pnch',
2570
+ Amnt: f.filter.amount,
2571
+ },
2572
+ filterID: 1349411688,
2573
+ };
2574
+ case 'polar coordinates': return {
2575
+ ...base,
2576
+ Fltr: {
2577
+ _name: 'Polar Coordinates',
2578
+ _classID: 'Plr ',
2579
+ Cnvr: Cnvr.encode(f.filter.conversion),
2580
+ },
2581
+ filterID: 1349284384,
2582
+ };
2583
+ case 'ripple': return {
2584
+ ...base,
2585
+ Fltr: {
2586
+ _name: 'Ripple',
2587
+ _classID: 'Rple',
2588
+ Amnt: f.filter.amount,
2589
+ RplS: RplS.encode(f.filter.size),
2590
+ },
2591
+ filterID: 1383099493,
2592
+ };
2593
+ case 'shear': return {
2594
+ ...base,
2595
+ Fltr: {
2596
+ _name: 'Shear',
2597
+ _classID: 'Shr ',
2598
+ ShrP: f.filter.shearPoints.map(p => ({ _name: '', _classID: 'Pnt ', Hrzn: p.x, Vrtc: p.y })),
2599
+ UndA: UndA.encode(f.filter.undefinedAreas),
2600
+ ShrS: f.filter.shearStart,
2601
+ ShrE: f.filter.shearEnd,
2602
+ },
2603
+ filterID: 1399353888,
2604
+ };
2605
+ case 'spherize': return {
2606
+ ...base,
2607
+ Fltr: {
2608
+ _name: 'Spherize',
2609
+ _classID: 'Sphr',
2610
+ Amnt: f.filter.amount,
2611
+ SphM: SphM.encode(f.filter.mode),
2612
+ },
2613
+ filterID: 1399875698,
2614
+ };
2615
+ case 'twirl': return {
2616
+ ...base,
2617
+ Fltr: {
2618
+ _name: 'Twirl',
2619
+ _classID: 'Twrl',
2620
+ Angl: f.filter.angle,
2621
+ },
2622
+ filterID: 1417114220,
2623
+ };
2624
+ case 'wave': return {
2625
+ ...base,
2626
+ Fltr: {
2627
+ _name: 'Wave',
2628
+ _classID: 'Wave',
2629
+ Wvtp: Wvtp.encode(f.filter.type),
2630
+ NmbG: f.filter.numberOfGenerators,
2631
+ WLMn: f.filter.wavelength.min,
2632
+ WLMx: f.filter.wavelength.max,
2633
+ AmMn: f.filter.amplitude.min,
2634
+ AmMx: f.filter.amplitude.max,
2635
+ SclH: f.filter.scale.x,
2636
+ SclV: f.filter.scale.y,
2637
+ UndA: UndA.encode(f.filter.undefinedAreas),
2638
+ RndS: f.filter.randomSeed,
2639
+ },
2640
+ filterID: 1466005093,
2641
+ };
2642
+ case 'zigzag': return {
2643
+ ...base,
2644
+ Fltr: {
2645
+ _name: 'ZigZag',
2646
+ _classID: 'ZgZg',
2647
+ Amnt: f.filter.amount,
2648
+ NmbR: f.filter.ridges,
2649
+ ZZTy: ZZTy.encode(f.filter.style),
2650
+ },
2651
+ filterID: 1516722791,
2652
+ };
2653
+ case 'add noise': return {
2654
+ ...base,
2655
+ Fltr: {
2656
+ _name: 'Add Noise',
2657
+ _classID: 'AdNs',
2658
+ Dstr: Dstr.encode(f.filter.distribution),
2659
+ Nose: unitsPercentF(f.filter.amount),
2660
+ Mnch: f.filter.monochromatic,
2661
+ FlRs: f.filter.randomSeed,
2662
+ },
2663
+ filterID: 1097092723,
2664
+ };
2665
+ case 'despeckle': return { ...base, filterID: 1148416099 };
2666
+ case 'dust and scratches': return {
2667
+ ...base,
2668
+ Fltr: {
2669
+ _name: 'Dust & Scratches',
2670
+ _classID: 'DstS',
2671
+ 'Rds ': f.filter.radius,
2672
+ Thsh: f.filter.threshold,
2673
+ },
2674
+ filterID: 1148417107,
2675
+ };
2676
+ case 'median': return {
2677
+ ...base,
2678
+ Fltr: {
2679
+ _name: 'Median',
2680
+ _classID: 'Mdn ',
2681
+ 'Rds ': uvRadius(f.filter),
2682
+ },
2683
+ filterID: 1298427424,
2684
+ };
2685
+ case 'reduce noise': return {
2686
+ ...base,
2687
+ Fltr: {
2688
+ _name: 'Reduce Noise',
2689
+ _classID: 'denoise',
2690
+ ClNs: unitsPercentF(f.filter.reduceColorNoise),
2691
+ Shrp: unitsPercentF(f.filter.sharpenDetails),
2692
+ removeJPEGArtifact: f.filter.removeJpegArtifact,
2693
+ channelDenoise: f.filter.channelDenoise.map(c => ({
2694
+ _name: '',
2695
+ _classID: 'channelDenoiseParams',
2696
+ Chnl: c.channels.map(i => Chnl.encode(i)),
2697
+ Amnt: c.amount,
2698
+ ...(c.preserveDetails ? { EdgF: c.preserveDetails } : {}),
2699
+ })),
2700
+ preset: f.filter.preset,
2701
+ },
2702
+ filterID: 633,
2703
+ };
2704
+ case 'color halftone': return {
2705
+ ...base,
2706
+ Fltr: {
2707
+ _name: 'Color Halftone',
2708
+ _classID: 'ClrH',
2709
+ 'Rds ': f.filter.radius,
2710
+ Ang1: f.filter.angle1,
2711
+ Ang2: f.filter.angle2,
2712
+ Ang3: f.filter.angle3,
2713
+ Ang4: f.filter.angle4,
2714
+ },
2715
+ filterID: 1131180616,
2716
+ };
2717
+ case 'crystallize': return {
2718
+ ...base,
2719
+ Fltr: {
2720
+ _name: 'Crystallize',
2721
+ _classID: 'Crst',
2722
+ ClSz: f.filter.cellSize,
2723
+ FlRs: f.filter.randomSeed,
2724
+ },
2725
+ filterID: 1131574132,
2726
+ };
2727
+ case 'facet': return { ...base, filterID: 1180922912 };
2728
+ case 'fragment': return { ...base, filterID: 1181902701 };
2729
+ case 'mezzotint': return {
2730
+ ...base,
2731
+ Fltr: {
2732
+ _name: 'Mezzotint',
2733
+ _classID: 'Mztn',
2734
+ MztT: MztT.encode(f.filter.type),
2735
+ FlRs: f.filter.randomSeed,
2736
+ },
2737
+ filterID: 1299870830,
2738
+ };
2739
+ case 'mosaic': return {
2740
+ ...base,
2741
+ Fltr: {
2742
+ _name: 'Mosaic',
2743
+ _classID: 'Msc ',
2744
+ ClSz: unitsValue(f.filter.cellSize, 'cellSize'),
2745
+ },
2746
+ filterID: 1299407648,
2747
+ };
2748
+ case 'pointillize': return {
2749
+ ...base,
2750
+ Fltr: {
2751
+ _name: 'Pointillize',
2752
+ _classID: 'Pntl',
2753
+ ClSz: f.filter.cellSize,
2754
+ FlRs: f.filter.randomSeed,
2755
+ },
2756
+ filterID: 1349416044,
2757
+ };
2758
+ case 'clouds': return {
2759
+ ...base,
2760
+ Fltr: {
2761
+ _name: 'Clouds',
2762
+ _classID: 'Clds',
2763
+ FlRs: f.filter.randomSeed,
2764
+ },
2765
+ filterID: 1131177075,
2766
+ };
2767
+ case 'difference clouds': return {
2768
+ ...base,
2769
+ Fltr: {
2770
+ _name: 'Difference Clouds',
2771
+ _classID: 'DfrC',
2772
+ FlRs: f.filter.randomSeed,
2773
+ },
2774
+ filterID: 1147564611,
2775
+ };
2776
+ case 'fibers': return {
2777
+ ...base,
2778
+ Fltr: {
2779
+ _name: 'Fibers',
2780
+ _classID: 'Fbrs',
2781
+ Vrnc: f.filter.variance,
2782
+ Strg: f.filter.strength,
2783
+ RndS: f.filter.randomSeed,
2784
+ },
2785
+ filterID: 1180856947,
2786
+ };
2787
+ case 'lens flare': return {
2788
+ ...base,
2789
+ Fltr: {
2790
+ _name: 'Lens Flare',
2791
+ _classID: 'LnsF',
2792
+ Brgh: f.filter.brightness,
2793
+ FlrC: {
2794
+ _name: '',
2795
+ _classID: 'Pnt ',
2796
+ Hrzn: f.filter.position.x,
2797
+ Vrtc: f.filter.position.y,
2798
+ },
2799
+ 'Lns ': Lns.encode(f.filter.lensType),
2800
+ },
2801
+ filterID: 1282306886,
2802
+ };
2803
+ case 'sharpen': return { ...base, filterID: 1399353968 };
2804
+ case 'sharpen edges': return { ...base, filterID: 1399353925 };
2805
+ case 'sharpen more': return { ...base, filterID: 1399353933 };
2806
+ case 'smart sharpen': return {
2807
+ ...base,
2808
+ Fltr: {
2809
+ _name: 'Smart Sharpen',
2810
+ _classID: 'smartSharpen',
2811
+ Amnt: unitsPercentF(f.filter.amount),
2812
+ 'Rds ': uvRadius(f.filter),
2813
+ Thsh: f.filter.threshold,
2814
+ Angl: f.filter.angle,
2815
+ moreAccurate: f.filter.moreAccurate,
2816
+ blur: blurType.encode(f.filter.blur),
2817
+ preset: f.filter.preset,
2818
+ sdwM: {
2819
+ _name: 'Parameters',
2820
+ _classID: 'adaptCorrectTones',
2821
+ Amnt: unitsPercentF(f.filter.shadow.fadeAmount),
2822
+ Wdth: unitsPercentF(f.filter.shadow.tonalWidth),
2823
+ 'Rds ': f.filter.shadow.radius,
2824
+ },
2825
+ hglM: {
2826
+ _name: 'Parameters',
2827
+ _classID: 'adaptCorrectTones',
2828
+ Amnt: unitsPercentF(f.filter.highlight.fadeAmount),
2829
+ Wdth: unitsPercentF(f.filter.highlight.tonalWidth),
2830
+ 'Rds ': f.filter.highlight.radius,
2831
+ },
2832
+ },
2833
+ filterID: 698,
2834
+ };
2835
+ case 'unsharp mask': return {
2836
+ ...base,
2837
+ Fltr: {
2838
+ _name: 'Unsharp Mask',
2839
+ _classID: 'UnsM',
2840
+ Amnt: unitsPercentF(f.filter.amount),
2841
+ 'Rds ': uvRadius(f.filter),
2842
+ Thsh: f.filter.threshold,
2843
+ },
2844
+ filterID: 1433301837,
2845
+ };
2846
+ case 'diffuse': return {
2847
+ ...base,
2848
+ Fltr: {
2849
+ _name: 'Diffuse',
2850
+ _classID: 'Dfs ',
2851
+ 'Md ': DfsM.encode(f.filter.mode),
2852
+ FlRs: f.filter.randomSeed,
2853
+ },
2854
+ filterID: 1147564832,
2855
+ };
2856
+ case 'emboss': return {
2857
+ ...base,
2858
+ Fltr: {
2859
+ _name: 'Emboss',
2860
+ _classID: 'Embs',
2861
+ Angl: f.filter.angle,
2862
+ Hght: f.filter.height,
2863
+ Amnt: f.filter.amount,
2864
+ },
2865
+ filterID: 1164796531,
2866
+ };
2867
+ case 'extrude': return {
2868
+ ...base,
2869
+ Fltr: {
2870
+ _name: 'Extrude',
2871
+ _classID: 'Extr',
2872
+ ExtS: f.filter.size,
2873
+ ExtD: f.filter.depth,
2874
+ ExtF: f.filter.solidFrontFaces,
2875
+ ExtM: f.filter.maskIncompleteBlocks,
2876
+ ExtT: ExtT.encode(f.filter.type),
2877
+ ExtR: ExtR.encode(f.filter.depthMode),
2878
+ FlRs: f.filter.randomSeed,
2879
+ },
2880
+ filterID: 1165522034,
2881
+ };
2882
+ case 'find edges': return { ...base, filterID: 1181639749 };
2883
+ case 'solarize': return { ...base, filterID: 1399616122 };
2884
+ case 'tiles': return {
2885
+ ...base,
2886
+ Fltr: {
2887
+ _name: 'Tiles',
2888
+ _classID: 'Tls ',
2889
+ TlNm: f.filter.numberOfTiles,
2890
+ TlOf: f.filter.maximumOffset,
2891
+ FlCl: FlCl.encode(f.filter.fillEmptyAreaWith),
2892
+ FlRs: f.filter.randomSeed,
2893
+ },
2894
+ filterID: 1416393504,
2895
+ };
2896
+ case 'trace contour': return {
2897
+ ...base,
2898
+ Fltr: {
2899
+ _name: 'Trace Contour',
2900
+ _classID: 'TrcC',
2901
+ 'Lvl ': f.filter.level,
2902
+ 'Edg ': CntE.encode(f.filter.edge),
2903
+ },
2904
+ filterID: 1416782659,
2905
+ };
2906
+ case 'wind': return {
2907
+ ...base,
2908
+ Fltr: {
2909
+ _name: 'Wind',
2910
+ _classID: 'Wnd ',
2911
+ WndM: WndM.encode(f.filter.method),
2912
+ Drct: Drct.encode(f.filter.direction),
2913
+ },
2914
+ filterID: 1466852384,
2915
+ };
2916
+ case 'de-interlace': return {
2917
+ ...base,
2918
+ Fltr: {
2919
+ _name: 'De-Interlace',
2920
+ _classID: 'Dntr',
2921
+ IntE: IntE.encode(f.filter.eliminate),
2922
+ IntC: IntC.encode(f.filter.newFieldsBy),
2923
+ },
2924
+ filterID: 1148089458,
2925
+ };
2926
+ case 'ntsc colors': return { ...base, filterID: 1314149187 };
2927
+ case 'custom': return {
2928
+ ...base,
2929
+ Fltr: {
2930
+ _name: 'Custom',
2931
+ _classID: 'Cstm',
2932
+ 'Scl ': f.filter.scale,
2933
+ Ofst: f.filter.offset,
2934
+ Mtrx: f.filter.matrix,
2935
+ },
2936
+ filterID: 1131639917,
2937
+ };
2938
+ case 'high pass': return {
2939
+ ...base,
2940
+ Fltr: {
2941
+ _name: 'High Pass',
2942
+ _classID: 'HghP',
2943
+ 'Rds ': uvRadius(f.filter),
2944
+ },
2945
+ filterID: 1214736464,
2946
+ };
2947
+ case 'maximum': return {
2948
+ ...base,
2949
+ Fltr: {
2950
+ _name: 'Maximum',
2951
+ _classID: 'Mxm ',
2952
+ 'Rds ': uvRadius(f.filter),
2953
+ },
2954
+ filterID: 1299737888,
2955
+ };
2956
+ case 'minimum': return {
2957
+ ...base,
2958
+ Fltr: {
2959
+ _name: 'Minimum',
2960
+ _classID: 'Mnm ',
2961
+ 'Rds ': uvRadius(f.filter),
2962
+ },
2963
+ filterID: 1299082528,
2964
+ };
2965
+ case 'offset': return {
2966
+ ...base,
2967
+ Fltr: {
2968
+ _name: 'Offset',
2969
+ _classID: 'Ofst',
2970
+ Hrzn: f.filter.horizontal,
2971
+ Vrtc: f.filter.vertical,
2972
+ 'Fl ': FlMd.encode(f.filter.undefinedAreas),
2973
+ },
2974
+ filterID: 1332114292,
2975
+ };
2976
+ case 'puppet': return {
2977
+ ...base,
2978
+ Fltr: {
2979
+ _name: 'Rigid Transform',
2980
+ _classID: 'rigidTransform',
2981
+ 'null': ['Ordn.Trgt'], // TODO: ???
2982
+ rigidType: f.filter.rigidType,
2983
+ puppetShapeList: f.filter.puppetShapeList.map(p => ({
2984
+ _name: '',
2985
+ _classID: 'puppetShape',
2986
+ rigidType: p.rigidType,
2987
+ VrsM: 1, // TODO: ???
2988
+ VrsN: 0, // TODO: ???
2989
+ originalVertexArray: toUint8(new Float32Array(pointsToArray(p.originalVertexArray))),
2990
+ deformedVertexArray: toUint8(new Float32Array(pointsToArray(p.deformedVertexArray))),
2991
+ indexArray: toUint8(new Uint32Array(p.indexArray)),
2992
+ pinOffsets: pointsToArray(p.pinOffsets),
2993
+ posFinalPins: pointsToArray(p.posFinalPins),
2994
+ pinVertexIndices: p.pinVertexIndices,
2995
+ PinP: pointsToArray(p.pinPosition),
2996
+ PnRt: p.pinRotation,
2997
+ PnOv: p.pinOverlay,
2998
+ PnDp: p.pinDepth,
2999
+ meshQuality: p.meshQuality,
3000
+ meshExpansion: p.meshExpansion,
3001
+ meshRigidity: p.meshRigidity,
3002
+ imageResolution: p.imageResolution,
3003
+ meshBoundaryPath: {
3004
+ _name: '',
3005
+ _classID: 'pathClass',
3006
+ pathComponents: p.meshBoundaryPath.pathComponents.map(c => ({
3007
+ _name: '',
3008
+ _classID: 'PaCm',
3009
+ shapeOperation: `shapeOperation.${c.shapeOperation}`,
3010
+ SbpL: c.paths.map(path => ({
3011
+ _name: '',
3012
+ _classID: 'Sbpl',
3013
+ Clsp: path.closed,
3014
+ 'Pts ': path.points.map(pt => ({
3015
+ _name: '',
3016
+ _classID: 'Pthp',
3017
+ Anch: pointToHrznVrtc(pt.anchor),
3018
+ 'Fwd ': pointToHrznVrtc(pt.forward),
3019
+ 'Bwd ': pointToHrznVrtc(pt.backward),
3020
+ Smoo: pt.smooth,
3021
+ })),
1385
3022
  })),
1386
3023
  })),
1387
- })),
3024
+ },
3025
+ selectedPin: p.selectedPin,
3026
+ })),
3027
+ PuX0: f.filter.bounds[0].x,
3028
+ PuX1: f.filter.bounds[1].x,
3029
+ PuX2: f.filter.bounds[2].x,
3030
+ PuX3: f.filter.bounds[3].x,
3031
+ PuY0: f.filter.bounds[0].y,
3032
+ PuY1: f.filter.bounds[1].y,
3033
+ PuY2: f.filter.bounds[2].y,
3034
+ PuY3: f.filter.bounds[3].y,
3035
+ },
3036
+ filterID: 991,
3037
+ };
3038
+ case 'oil paint plugin': {
3039
+ const params: any = {};
3040
+
3041
+ for (let i = 0; i < f.filter.parameters.length; i++) {
3042
+ const { name, value } = f.filter.parameters[i];
3043
+ const suffix = `${fromAtoZ[Math.floor(i / fromAtoZ.length)]}${fromAtoZ[i % fromAtoZ.length]}`;
3044
+ params[`PN${suffix}`] = name;
3045
+ params[`PT${suffix}`] = 0;
3046
+ params[`PF${suffix}`] = value;
3047
+ }
3048
+
3049
+ return {
3050
+ ...base,
3051
+ Fltr: {
3052
+ _name: 'Oil Paint Plugin',
3053
+ _classID: 'PbPl',
3054
+ KnNm: f.filter.name,
3055
+ GpuY: f.filter.gpu,
3056
+ LIWy: f.filter.lighting,
3057
+ FPth: '1',
3058
+ ...params,
1388
3059
  },
1389
- })),
1390
- PuX0: filter.bounds[0].x,
1391
- PuX1: filter.bounds[1].x,
1392
- PuX2: filter.bounds[2].x,
1393
- PuX3: filter.bounds[3].x,
1394
- PuY0: filter.bounds[0].y,
1395
- PuY1: filter.bounds[1].y,
1396
- PuY2: filter.bounds[2].y,
1397
- PuY3: filter.bounds[3].y,
1398
- };
1399
- } else {
1400
- return {
1401
- LqMe: new Uint8Array(),
3060
+ filterID: 1348620396,
3061
+ };
3062
+ }
3063
+ case 'oil paint': return {
3064
+ ...base,
3065
+ Fltr: {
3066
+ _name: 'Oil Paint',
3067
+ _classID: 'oilPaint',
3068
+ lightingOn: f.filter.lightingOn,
3069
+ stylization: f.filter.stylization,
3070
+ cleanliness: f.filter.cleanliness,
3071
+ brushScale: f.filter.brushScale,
3072
+ microBrush: f.filter.microBrush,
3073
+ LghD: f.filter.lightDirection,
3074
+ specularity: f.filter.specularity,
3075
+ },
3076
+ filterID: 1122,
1402
3077
  };
3078
+ case 'liquify': return {
3079
+ ...base,
3080
+ Fltr: {
3081
+ _name: 'Liquify',
3082
+ _classID: 'LqFy',
3083
+ LqMe: f.filter.liquifyMesh,
3084
+ },
3085
+ filterID: 1282492025,
3086
+ };
3087
+ default: throw new Error(`Unknow filter type: ${(f as any).type}`);
1403
3088
  }
1404
3089
  }
1405
3090
 
1406
- function serializeFilterFX(filter: PlacedLayerFilter): SoLdDescriptorFilter {
1407
- return {
1408
- enab: filter.enabled,
1409
- validAtPosition: filter.validAtPosition,
1410
- filterMaskEnable: filter.maskEnabled,
1411
- filterMaskLinked: filter.maskLinked,
1412
- filterMaskExtendWithWhite: filter.maskExtendWithWhite,
1413
- filterFXList: (filter.list || []).map(f => ({
1414
- 'Nm ': f.name,
1415
- blendOptions: {
1416
- Opct: unitsPercent(f.opacity),
1417
- 'Md ': BlnM.encode(f.blendMode),
1418
- },
1419
- enab: f.enabled,
1420
- hasoptions: f.hasOptions,
1421
- FrgC: serializeColor(f.foregroundColor),
1422
- BckC: serializeColor(f.backgroundColor),
1423
- Fltr: serializeFltr(f.filter),
1424
- filterID: f.id,
1425
- })),
1426
- };
1427
- }
1428
-
1429
3091
  interface SoLdDescriptor {
1430
3092
  Idnt: string;
1431
3093
  placed: string;
@@ -1441,7 +3103,7 @@ interface SoLdDescriptor {
1441
3103
  nonAffineTransform: number[];
1442
3104
  quiltWarp?: QuiltWarpDescriptor;
1443
3105
  warp: WarpDescriptor;
1444
- 'Sz ': { Wdth: number; Hght: number; };
3106
+ 'Sz ': { _name: '', _classID: 'Pnt ', Wdth: number; Hght: number; };
1445
3107
  Rslt: DescriptorUnitsValue;
1446
3108
  filterFX?: SoLdDescriptorFilter;
1447
3109
  comp?: number;
@@ -1449,6 +3111,8 @@ interface SoLdDescriptor {
1449
3111
  Impr?: {}; // ???
1450
3112
  }
1451
3113
 
3114
+ // let t: any;
3115
+
1452
3116
  addHandler(
1453
3117
  'SoLd',
1454
3118
  hasKey('placedLayer'),
@@ -1461,7 +3125,9 @@ addHandler(
1461
3125
  // console.log('SoLd.warp', require('util').inspect(desc.warp, false, 99, true));
1462
3126
  // console.log('SoLd.quiltWarp', require('util').inspect(desc.quiltWarp, false, 99, true));
1463
3127
  // desc.filterFX!.filterFXList[0].Fltr.puppetShapeList[0].meshBoundaryPath.pathComponents[0].SbpL[0]['Pts '] = [];
1464
- // console.log('filterFX', require('util').inspect(desc.filterFX, false, 99, true));
3128
+ // console.log('read', require('util').inspect(desc.filterFX, false, 99, true));
3129
+ // console.log('filterFXList[0]', require('util').inspect((desc as any).filterFX.filterFXList[0], false, 99, true));
3130
+ // t = desc;
1465
3131
 
1466
3132
  target.placedLayer = {
1467
3133
  id: desc.Idnt,
@@ -1469,8 +3135,8 @@ addHandler(
1469
3135
  type: placedLayerTypes[desc.Type],
1470
3136
  pageNumber: desc.PgNm,
1471
3137
  totalPages: desc.totalPages,
1472
- frameStep: desc.frameStep,
1473
- duration: desc.duration,
3138
+ frameStep: frac(desc.frameStep),
3139
+ duration: frac(desc.duration),
1474
3140
  frameCount: desc.frameCount,
1475
3141
  transform: desc.Trnf,
1476
3142
  width: desc['Sz '].Wdth,
@@ -1485,9 +3151,16 @@ addHandler(
1485
3151
 
1486
3152
  if (desc.Crop) target.placedLayer.crop = desc.Crop;
1487
3153
  if (desc.comp) target.placedLayer.comp = desc.comp;
1488
- if (desc.compInfo) target.placedLayer.compInfo = desc.compInfo;
3154
+ if (desc.compInfo) {
3155
+ target.placedLayer.compInfo = {
3156
+ compID: desc.compInfo.compID,
3157
+ originalCompID: desc.compInfo.originalCompID,
3158
+ };
3159
+ }
1489
3160
  if (desc.filterFX) target.placedLayer.filter = parseFilterFX(desc.filterFX);
1490
3161
 
3162
+ // console.log('filter', require('util').inspect(target.placedLayer.filter, false, 99, true));
3163
+
1491
3164
  skipBytes(reader, left()); // HACK
1492
3165
  },
1493
3166
  (writer, target) => {
@@ -1508,16 +3181,38 @@ addHandler(
1508
3181
  Type: placedLayerTypes.indexOf(placed.type),
1509
3182
  Trnf: placed.transform,
1510
3183
  nonAffineTransform: placed.nonAffineTransform ?? placed.transform,
1511
- quiltWarp: {} as any,
3184
+ // quiltWarp: {} as any,
1512
3185
  warp: encodeWarp(placed.warp || {}),
1513
3186
  'Sz ': {
3187
+ _name: '',
3188
+ _classID: 'Pnt ',
1514
3189
  Wdth: placed.width || 0, // TODO: find size ?
1515
3190
  Hght: placed.height || 0, // TODO: find size ?
1516
3191
  },
1517
3192
  Rslt: placed.resolution ? unitsValue(placed.resolution, 'resolution') : { units: 'Density', value: 72 },
1518
3193
  };
1519
3194
 
1520
- if (placed.filter) desc.filterFX = serializeFilterFX(placed.filter);
3195
+ if (placed.filter) {
3196
+ desc.filterFX = {
3197
+ _name: '',
3198
+ _classID: 'filterFXStyle',
3199
+ enab: placed.filter.enabled,
3200
+ validAtPosition: placed.filter.validAtPosition,
3201
+ filterMaskEnable: placed.filter.maskEnabled,
3202
+ filterMaskLinked: placed.filter.maskLinked,
3203
+ filterMaskExtendWithWhite: placed.filter.maskExtendWithWhite,
3204
+ filterFXList: placed.filter.list.map(f => serializeFilterFXItem(f)),
3205
+ };
3206
+ }
3207
+
3208
+ // console.log('write', require('util').inspect(desc.filterFX, false, 99, true)); ///
3209
+
3210
+ // if (JSON.stringify(t) !== JSON.stringify(desc)) {
3211
+ // console.log('read', require('util').inspect(t, false, 99, true));
3212
+ // console.log('write', require('util').inspect(desc, false, 99, true));
3213
+ // console.error('DIFFERENT');
3214
+ // // throw new Error('DIFFERENT');
3215
+ // }
1521
3216
 
1522
3217
  if (placed.warp && isQuiltWarp(placed.warp)) {
1523
3218
  const quiltWarp = encodeWarp(placed.warp) as QuiltWarpDescriptor;
@@ -1728,7 +3423,15 @@ addHandler(
1728
3423
 
1729
3424
  if (fileType) file.type = fileType;
1730
3425
  if (fileCreator) file.creator = fileCreator;
1731
- if (fileOpenDescriptor) file.descriptor = fileOpenDescriptor;
3426
+
3427
+ if (fileOpenDescriptor) {
3428
+ file.descriptor = {
3429
+ compInfo: {
3430
+ compID: fileOpenDescriptor.compInfo.compID,
3431
+ originalCompID: fileOpenDescriptor.compInfo.originalCompID,
3432
+ }
3433
+ };
3434
+ }
1732
3435
 
1733
3436
  if (type === 'liFE' && version > 3) {
1734
3437
  const year = readInt32(reader);
@@ -1785,7 +3488,10 @@ addHandler(
1785
3488
 
1786
3489
  if (file.descriptor && file.descriptor.compInfo) {
1787
3490
  const desc: FileOpenDescriptor = {
1788
- compInfo: file.descriptor.compInfo,
3491
+ compInfo: {
3492
+ compID: file.descriptor.compInfo.compID,
3493
+ originalCompID: file.descriptor.compInfo.originalCompID,
3494
+ }
1789
3495
  };
1790
3496
 
1791
3497
  writeUint8(writer, 1);
@@ -2759,6 +4465,103 @@ addHandler(
2759
4465
  },
2760
4466
  );
2761
4467
 
4468
+ addHandler(
4469
+ 'FEid',
4470
+ hasKey('filterEffectsMasks'),
4471
+ (reader, target, leftBytes) => {
4472
+ const version = readInt32(reader);
4473
+ if (version < 1 || version > 3) throw new Error(`Invalid filterEffects version ${version}`);
4474
+
4475
+ if (readUint32(reader)) throw new Error('filterEffects: 64 bit length is not supported');
4476
+ const length = readUint32(reader);
4477
+ const end = reader.offset + length;
4478
+ target.filterEffectsMasks = [];
4479
+
4480
+ while (reader.offset < end) {
4481
+ const id = readPascalString(reader, 1);
4482
+ const effectVersion = readInt32(reader);
4483
+ if (effectVersion !== 1) throw new Error(`Invalid filterEffect version ${effectVersion}`);
4484
+ if (readUint32(reader)) throw new Error('filterEffect: 64 bit length is not supported');
4485
+ /*const effectLength =*/ readUint32(reader);
4486
+ // const endOfEffect = reader.offset + effectLength;
4487
+ const top = readInt32(reader);
4488
+ const left = readInt32(reader);
4489
+ const bottom = readInt32(reader);
4490
+ const right = readInt32(reader);
4491
+ const depth = readInt32(reader);
4492
+ const maxChannels = readInt32(reader);
4493
+ const channels: ({ compressionMode: number; data: Uint8Array; } | undefined)[] = [];
4494
+
4495
+ // 0 -> R, 1 -> G, 2 -> B, 25 -> A
4496
+ for (let i = 0; i < (maxChannels + 2); i++) {
4497
+ const exists = readInt32(reader);
4498
+ if (exists) {
4499
+ if (readUint32(reader)) throw new Error('filterEffect: 64 bit length is not supported');
4500
+ const channelLength = readUint32(reader);
4501
+ const compressionMode = readUint16(reader);
4502
+ const data = readBytes(reader, channelLength - 2);
4503
+ channels.push({ compressionMode, data });
4504
+ } else {
4505
+ channels.push(undefined);
4506
+ }
4507
+ }
4508
+
4509
+ target.filterEffectsMasks.push({ id, top, left, bottom, right, depth, channels });
4510
+
4511
+ if (leftBytes() && readUint8(reader)) {
4512
+ const compressionMode = readUint16(reader);
4513
+ const data = readBytes(reader, leftBytes());
4514
+ target.filterEffectsMasks[target.filterEffectsMasks.length - 1].extra = { compressionMode, data };
4515
+ }
4516
+ }
4517
+ },
4518
+ (writer, target) => {
4519
+ writeInt32(writer, 3);
4520
+ writeUint32(writer, 0);
4521
+ writeUint32(writer, 0);
4522
+ const lengthOffset = writer.offset;
4523
+
4524
+ for (const mask of target.filterEffectsMasks!) {
4525
+ writePascalString(writer, mask.id, 1);
4526
+ writeInt32(writer, 1);
4527
+ writeUint32(writer, 0);
4528
+ writeUint32(writer, 0);
4529
+ const length2Offset = writer.offset;
4530
+ writeInt32(writer, mask.top);
4531
+ writeInt32(writer, mask.left);
4532
+ writeInt32(writer, mask.bottom);
4533
+ writeInt32(writer, mask.right);
4534
+ writeInt32(writer, mask.depth);
4535
+ const maxChannels = Math.max(0, mask.channels.length - 2);
4536
+ writeInt32(writer, maxChannels);
4537
+
4538
+ for (let i = 0; i < (maxChannels + 2); i++) {
4539
+ const channel = mask.channels[i];
4540
+ writeInt32(writer, channel ? 1 : 0);
4541
+ if (channel) {
4542
+ writeUint32(writer, 0);
4543
+ writeUint32(writer, channel.data.length + 2);
4544
+ writeUint16(writer, channel.compressionMode);
4545
+ writeBytes(writer, channel.data);
4546
+ }
4547
+ }
4548
+
4549
+ writer.view.setUint32(length2Offset - 4, writer.offset - length2Offset, false);
4550
+ }
4551
+
4552
+ const extra = target.filterEffectsMasks![target.filterEffectsMasks!.length - 1]?.extra;
4553
+ if (extra) {
4554
+ writeUint8(writer, 1);
4555
+ writeUint16(writer, extra.compressionMode);
4556
+ writeBytes(writer, extra.data);
4557
+ }
4558
+
4559
+ writer.view.setUint32(lengthOffset - 4, writer.offset - lengthOffset, false);
4560
+ },
4561
+ );
4562
+
4563
+ addHandlerAlias('FXid', 'FEid');
4564
+
2762
4565
  addHandler(
2763
4566
  'FMsk',
2764
4567
  hasKey('filterMask'),
@@ -2871,14 +4674,18 @@ addHandler(
2871
4674
  const desc = readVersionAndDescriptor(reader) as CinfDescriptor;
2872
4675
  // console.log(require('util').inspect(desc, false, 99, true));
2873
4676
 
4677
+ function enumValue(desc: string): string {
4678
+ return desc.split('.')[1];
4679
+ }
4680
+
2874
4681
  target.compositorUsed = {
2875
4682
  description: desc.description,
2876
4683
  reason: desc.reason,
2877
- engine: desc.Engn.split('.')[1],
2878
- enableCompCore: desc.enableCompCore.split('.')[1],
2879
- enableCompCoreGPU: desc.enableCompCoreGPU.split('.')[1],
2880
- compCoreSupport: desc.compCoreSupport.split('.')[1],
2881
- compCoreGPUSupport: desc.compCoreGPUSupport.split('.')[1],
4684
+ engine: enumValue(desc.Engn),
4685
+ enableCompCore: enumValue(desc.enableCompCore),
4686
+ enableCompCoreGPU: enumValue(desc.enableCompCoreGPU),
4687
+ compCoreSupport: enumValue(desc.compCoreSupport),
4688
+ compCoreGPUSupport: enumValue(desc.compCoreGPUSupport),
2882
4689
  };
2883
4690
 
2884
4691
  skipBytes(reader, left());
@@ -2959,85 +4766,3 @@ addHandler(
2959
4766
  writeZeros(writer, 3);
2960
4767
  },
2961
4768
  );
2962
-
2963
- /*addHandler(
2964
- 'FEid',
2965
- hasKey('filterEffects'),
2966
- (reader, _target) => {
2967
- const version = readInt32(reader);
2968
- if (version < 1 || version > 3) throw new Error(`Invalid filterEffects version ${version}`);
2969
-
2970
- if (readUint32(reader)) throw new Error('filterEffects: 64 bit length is not supported');
2971
- const length = readUint32(reader);
2972
- const end = reader.offset + length;
2973
-
2974
- while (reader.offset < end) {
2975
- console.log('bytes to go', end - reader.offset, 'at', reader.offset.toString(16));
2976
- //
2977
- const id = readPascalString(reader, 1);
2978
- const effectVersion = readInt32(reader);
2979
- if (effectVersion !== 1) throw new Error(`Invalid filterEffect version ${effectVersion}`);
2980
- if (readUint32(reader)) throw new Error('filterEffect: 64 bit length is not supported');
2981
- const effectLength = readUint32(reader);
2982
- const endOfEffect = reader.offset + effectLength;
2983
- const top = readInt32(reader);
2984
- const left = readInt32(reader);
2985
- const bottom = readInt32(reader);
2986
- const right = readInt32(reader);
2987
- const depth = readInt32(reader);
2988
- const maxChannels = readInt32(reader);
2989
- const channels: any[] = [];
2990
-
2991
- for (let i = 0; i < (maxChannels + 2); i++) {
2992
- const exists = readInt32(reader);
2993
- if (exists) {
2994
- if (readUint32(reader)) throw new Error('filterEffect: 64 bit length is not supported');
2995
- const channelLength = readUint32(reader);
2996
- const compressionMode = readUint16(reader);
2997
- const data = readBytes(reader, channelLength - 2);
2998
- channels.push({ channelLength, compressionMode, data: data?.length + ' bytes' });
2999
- // if (c < 3 || c == 25) e_ = _F.Cn(!0, rL, m, b.rect.F, b.rect.V, X, rp);
3000
- // if (c == 0) _c.S = e_;
3001
- // if (c == 1) _c.v = e_;
3002
- // if (c == 2) _c.e = e_;
3003
- // if (c == 25) _c.w = e_;
3004
- } else {
3005
- channels.push(undefined);
3006
- }
3007
- }
3008
-
3009
- console.log('left at the end', endOfEffect - reader.offset);
3010
- if (endOfEffect > reader.offset) {
3011
- if (readUint8(reader)) {
3012
- const compressionMode = readUint16(reader);
3013
- const data = endOfEffect > reader.offset ? readBytes(reader, endOfEffect - reader.offset) : undefined;
3014
- console.log('extra data', { compressionMode, data: data?.length + ' bytes' });
3015
- } else {
3016
- console.log('no extra');
3017
- }
3018
- }
3019
-
3020
- console.log('effect', {
3021
- id,
3022
- effectVersion,
3023
- effectLength,
3024
- top,
3025
- left,
3026
- bottom,
3027
- right,
3028
- depth,
3029
- maxChannels,
3030
- channels,
3031
- });
3032
-
3033
- console.log('bytes left after effect', endOfEffect - reader.offset);
3034
- // if (length % 4) skipBytes(reader, 4 - length % 4);
3035
- }
3036
-
3037
- console.log({ version, length });
3038
- },
3039
- (_writer, _target) => {
3040
- },
3041
- );
3042
-
3043
- addHandlerAlias('FXid', 'FEid');*/