OPEN SampleArrays;
ROPE: TYPE ~ Rope.ROPE;
Error: PUBLIC ERROR [error: ErrorDesc] ~ CODE;
GetSamples:
PUBLIC
PROC [buffer: Buffer, start:
NAT ← 0, count:
NAT ← maxCount,
sa: SampleArray, i:
NAT, s, f:
NAT ← 0, ds:
NAT ← 0, df:
NAT ← 1] ~ {
SampleMapOps.Get[buffer: buffer, start: start, count: count, sampleMap: sa.layer[i].sm, s: s, f: f, ds: ds, df: df];
};
! BoundsFault if any index into sa is out of range
PutSamples:
PUBLIC
PROC [buffer: Buffer, start:
NAT ← 0, count:
NAT ← maxCount,
sa: SampleArray, i:
NAT, s, f:
NAT ← 0, ds:
NAT ← 0, df:
NAT ← 1, function: Function ← nullFunction] ~ {
SampleMapOps.Put[buffer: buffer, start: start, count: count, sampleMap: sa.layer[i].sm, s: s, f: f, ds: ds, df: df, function: function];
};
! BoundsFault if any index into sa is out of range
Join3Maps:
PUBLIC PROC [sm1, sm2, sm3: SampleMapEntry]
RETURNS [SampleArray] ~ {
sa: SampleArray ~ NEW[SampleArrayRep[3]];
sa.layer[0] ← sm1;
sa.layer[1] ← sm2;
sa.layer[2] ← sm3;
sa.sSize ← sa.layer[0].sm.sSize;
sa.fSize ← sa.layer[0].sm.fSize;
FOR i:
NAT
IN [0..3)
DO
IF sa.sSize#sa.layer[i].sm.sSize OR sa.fSize#sa.layer[0].sm.fSize THEN Error[[$incompatibleJoin, "Sample maps not of consistent sSize and fSize"]];
ENDLOOP;
RETURN [sa];
};
FromAIS:
PUBLIC PROC [name:
ROPE]
RETURNS [SampleArray] ~ {
sm: SampleMapEntry ~ MapFromAIS[name];
sa: SampleArray ~ NEW[SampleArrayRep[1]];
sa.layer[0] ← sm;
sa.sSize ← sa.layer[0].sm.sSize;
sa.fSize ← sa.layer[0].sm.fSize;
RETURN [sa];
};
MapFromAIS:
PUBLIC PROC [name:
ROPE]
RETURNS [SampleMapEntry] ~ {
fref: AIS.FRef ~ AIS.OpenFile[name: name];
wref: AIS.WRef ~ AIS.OpenWindow[f: fref];
sSize: NAT ~ fref.raster.scanCount;
fSize: NAT ~ fref.raster.scanLength;
sm: SampleMap ~ SampleMapOps.Create[sSize: sSize, fSize: fSize, bitsPerSample: fref.raster.bitsPerPixel];
check: [0..0] ~ sm.base.bit; --Better be zero
ptr: LONG POINTER ← sm.base.word;
words: CARDINAL ~ sm.bitsPerLine/16;
FOR scan:
NAT
IN [0 .. sSize)
DO
TRUSTED {AIS.UnsafeReadLine[w: wref, buffer: [length: fSize, addr: ptr], line: scan]};
TRUSTED {ptr ← ptr+words};
ENDLOOP;
RETURN [[sm: sm, class: $AIS, data: fref]];
};
CreateAISFromMap:
PUBLIC
PROC [sm: SampleMap, name:
ROPE] ~ {
raster: AIS.Raster ~ NEW[AIS.RasterPart ← [
scanCount: sm.sSize,
scanLength: sm.fSize,
scanMode: dr,
bitsPerPixel: sm.bitsPerSample,
linesPerBlock: -1,
paddingPerBlock: 0
]];
fref: AIS.FRef ~ AIS.CreateFile[name: name, raster: raster];
sme: SampleMapEntry ~ [sm: sm, class: $AIS, data: fref];
sa: SampleArray ~ NEW[SampleArrayRep[1]];
sa.sSize ← sm.sSize;
sa.fSize ← sm.fSize;
sa[0] ← sme;
Save[sa];
};
Join3AIS:
PUBLIC PROC [name1, name2, name3:
ROPE]
RETURNS [SampleArray] ~ {
sm1: SampleMapEntry ~ MapFromAIS[name1];
sm2: SampleMapEntry ~ MapFromAIS[name2];
sm3: SampleMapEntry ~ MapFromAIS[name3];
RETURN [Join3Maps[sm1, sm2, sm3]];
};
HackOffVersionPart:
PROC [name:
ROPE]
RETURNS [result:
ROPE] ~ {
RETURN [Rope.Substr[base: name, len: Rope.Index[s1: name, s2: "!"]]];
};
HackOffExtension:
PROC [name:
ROPE]
RETURNS [result:
ROPE] ~ {
result ← HackOffVersionPart[name];
RETURN [Rope.Substr[base: result, len: Rope.Index[s1: result, s2: "."]]];
};
ROPESEQ: TYPE ~ RECORD [SEQUENCE n: NAT OF ROPE];
FileNameRoot:
PUBLIC
PROC [sa: SampleArray]
RETURNS [root:
ROPE] ~ {
AllCharsTheSame:
PROC [i:
INT]
RETURNS [
BOOL ←
TRUE] ~ {
char: CHAR ~ Rope.Fetch[base: ropes[0], index: i];
FOR layer:
NAT
IN [1..ropes.n)
DO
IF Rope.Fetch[base: ropes[layer], index: i]#char THEN RETURN [FALSE];
ENDLOOP;
};
length: INT ← INT.LAST;
matches: INT ← 0;
ropes: REF ROPESEQ ← NEW[ROPESEQ[sa.n]];
FOR i:
NAT
IN [0..ropes.n)
DO
ropes[i] ← HackOffExtension[BackingFileOf[sa[i]]];
length ← MIN[length, Rope.Length[base: ropes[i]]];
ENDLOOP;
WHILE matches<length
AND AllCharsTheSame[matches]
DO
matches ← matches+1;
ENDLOOP;
length ← MIN[length, matches];
root ← Rope.Substr[base: ropes[0], len: length];
IF Rope.Fetch[base: root, index: length-1]='- THEN root ← Rope.Substr[base: root, len: length-1];
};
BackingFileOf:
PUBLIC PROC [sme: SampleMapEntry]
RETURNS [backingFileName:
ROPE] ~ {
RETURN [FS.GetName[file: NARROW[sme.data, AIS.FRef].file].fullFName];
};
Save:
PUBLIC
PROC [sa: SampleArray] ~ {
FOR layer:
NAT
IN [0..sa.n)
DO
sme: SampleMapEntry ~ sa.layer[layer];
IF sme.class#$AIS THEN LOOP;
TRUSTED {
old: AIS.FRef ~ NARROW[sme.data];
fileName: ROPE ~ HackOffVersionPart[FS.GetName[file: old.file].fullFName];
new: AIS.FRef ~ AIS.CreateFile[name: fileName, raster: old.raster];
wref: AIS.WRef ~ AIS.OpenWindow[f: new];
sSize: NAT ~ new.raster.scanCount;
fSize: NAT ~ new.raster.scanLength;
check: [0..0] ~ sme.sm.base.bit; --Better be zero
ptr: LONG POINTER ← sme.sm.base.word;
words: CARDINAL ~ sme.sm.bitsPerLine/16;
FOR scan:
NAT
IN [0 .. sSize)
DO
AIS.UnsafeWriteLine[w: wref, buffer: [length: fSize, addr: ptr], line: scan];
ptr ← ptr+words;
ENDLOOP;
AIS.CloseWindow[w: wref];
AIS.CloseFile[f: new];
};
ENDLOOP;
};