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