WriteInfo:
PROC [out:
IO.
STREAM, info:
AISIO.Info] ~ {
WritePartHeader:
PROC [type: AISFileFormat.PartType, nBytesInPart:
INT] ~ {
nWordsTotal: INT ¬ (nBytesInPart+AISFileFormat.byteSizePartHeader)/2;
part:
MACHINE DEPENDENT RECORD [
c: PartHeader, p: PACKED ARRAY [0..(BITS[WORD]-(BITS[PartHeader] MOD BITS[WORD])) MOD BITS[WORD]) OF [0..1]];
part.c ¬ [type, nWordsTotal/256, nWordsTotal MOD 256];
IF type = nil THEN part.c.lengthHi ¬ part.c.lengthLo ¬ 0;
TRUSTED {WriteBytes[out, @part, AISFileFormat.byteSizePartHeader]};
};
PartHeader: TYPE ~ AISFileFormat.PartHeader;
UCACoding: TYPE ~ AISFileFormat.UCACoding;
AttributeHeader: TYPE ~ AISFileFormat.AttributeHeader;
RasterPart: TYPE ~ AISFileFormat.RasterPart;
header:
MACHINE DEPENDENT RECORD [
c: AttributeHeader, p: PACKED ARRAY [0..(BITS[WORD]-(BITS[AttributeHeader] MOD BITS[WORD])) MOD BITS[WORD]) OF [0..1]];
raster:
MACHINE DEPENDENT RECORD [
c: RasterPart, p: PACKED ARRAY [0..(BITS[WORD]-(BITS[RasterPart] MOD BITS[WORD])) MOD BITS[WORD]) OF [0..1]];
uca:
MACHINE DEPENDENT RECORD [
c: UCACoding, p: PACKED ARRAY [0..(BITS[WORD]-(BITS[UCACoding] MOD BITS[WORD])) MOD BITS[WORD]) OF [0..1]];
header.c ¬ [AISFileFormat.passwordValue, Card[wordsHeader]];
raster.c ¬ [info.raster.scanCount, info.raster.scanLength, Card[3], Card[1], 0, uca, AISFileFormat.nil];
uca.c ¬ [info.uca.bitsPerSample, info.uca.wordsPerScanLine, AISFileFormat.nil, AISFileFormat.nil];
TRUSTED {WriteBytes[out, @header, AISFileFormat.byteSizeAttributeHeader]};
WritePartHeader[raster, AISFileFormat.byteSizeRasterPart+AISFileFormat.byteSizeUCACoding];
TRUSTED {WriteBytes[out, @raster, AISFileFormat.byteSizeRasterPart]};
TRUSTED {WriteBytes[out, @uca, AISFileFormat.byteSizeUCACoding]};
IF info.placement #
NIL THEN {
part:
MACHINE DEPENDENT RECORD [
c: AISFileFormat.PlacementPart, p: PACKED ARRAY [0..(BITS[WORD]-(BITS[UCACoding] MOD BITS[WORD])) MOD BITS[WORD]) OF [0..1]];
part.c ¬ info.placement;
WritePartHeader[placement, AISFileFormat.byteSizePlacementPart];
TRUSTED {WriteBytes[out, @part, AISFileFormat.byteSizePlacementPart]};
};
IF info.photometry #
NIL THEN {
part:
MACHINE DEPENDENT RECORD [
c: AISFileFormat.PhotometryPart, p: PACKED ARRAY [0..(BITS[WORD]-(BITS[UCACoding] MOD BITS[WORD])) MOD BITS[WORD]) OF [0..1]];
part.c ¬ info.photometry;
WritePartHeader[photometry, AISFileFormat.byteSizePhotometryPart];
TRUSTED {WriteBytes[out, @part, AISFileFormat.byteSizePhotometryPart]};
};
IF info.comments # NIL THEN { -- ugh -- };
WritePartHeader[nil, 0]; -- end header
};
AISChangeHeaderCmd: Commander.CommandProc = {
inA, outA, xA, yA, bppA, numberScanlinesA, pixelsPerLineA, commentA: Args.Arg;
[inA,
outA,
xA,
yA,
bppA,
numberScanlinesA,
pixelsPerLineA,
commentA]
¬
Args.ArgsGet[cmd, "%ss-placement%ii-bitsPerPixel%i-numberScanlines%i-pixelsPerLine%i-comment%s-wordsPerLine%i"
! Args.Error => {msg ¬ reason; CONTINUE}];
IF msg #
NIL
THEN RETURN[$Failure, msg]
ELSE {
info: AISIO.Info ¬ AISIO.ReadInfo[inA.rope];
buffer: REF TEXT ¬ NEW[TEXT[1024]];
in: IO.STREAM ¬ FS.StreamOpen[inA.rope ! FS.Error => GOTO Bad];
out: IO.STREAM ¬ FS.StreamOpen[outA.rope, $create];
IF xA.ok
OR yA.ok
THEN {
IF info.placement = NIL THEN info.placement ¬ NEW[AISFileFormat.PlacementPart];
IF xA.ok THEN info.placement.xLeft ¬ Basics.HFromInt16[xA.int];
IF yA.ok THEN info.placement.yBottom ¬ Basics.HFromInt16[yA.int];
};
IF bppA.ok THEN info.uca.bitsPerSample ¬ Basics.HFromInt16[bppA.int];
IF numberScanlinesA.ok
THEN info.raster.scanCount ¬ Basics.HFromInt16[numberScanlinesA.int];
IF pixelsPerLineA.ok
THEN {
info.raster.scanLength ¬ Basics.HFromInt16[pixelsPerLineA.int];
info.uca.wordsPerScanLine ¬ Basics.HFromInt16[pixelsPerLineA.int/2+(pixelsPerLineA.int MOD 2)];
};
IF commentA.ok THEN info.comments ¬ CONS[commentA.rope, info.comments];
WriteInfo[out, info];
IO.SetIndex[in, wordsHeader];
IO.SetIndex[out, wordsHeader];
DO
nBytes: INT ¬ IO.GetBlock[in, buffer];
IF nBytes = 0 THEN EXIT;
IO.PutBlock[out, buffer];
ENDLOOP;
IO.Close[in];
IO.Close[out];
EXITS Bad => RETURN[$Failure, "can't open file"];
};
};