CrosfieldTape.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Maureen Stone, Tim Diebert, June 4, 1989 12:51:00 pm PDT
Format to read/write Crosfield tape format (for color separations). CMYK pixels interleaved.
Types setup to coordinate with ConvertToRaster
DIRECTORY
Rope USING [ROPE],
UnixTapeOps USING [TapeHandle, Density],
TapesCommon USING [FileHandleList, FileHandle],
BasicTime USING [GMT],
ImagerPixel USING [PixelBuffer];
CrosfieldTape: CEDAR DEFINITIONS
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
PixelBuffer: TYPE ~ ImagerPixel.PixelBuffer;
TapeHandle: TYPE ~ UnixTapeOps.TapeHandle;
Write Tape
FileSpec: TYPE = REF FileSpecRep;
FileSpecRep: TYPE = RECORD[
pixelsPerInch: PixelsPerInch,
nLines, nPixels: NAT,
note: ROPE,
mapPixel: PixelProc
];
PixelsPerInch: TYPE = {ppi300, ppi450, ppi600};
The ppi are approximate. The actual values are: 300x304.8, 450x406.4, 600x609.6. If the exact size is important (or you want to use ppi450), you must compensate for the difference when you generate the rasters.
FileSpecList: TYPE = LIST OF FileSpec;
From TapesCommon
FileHandle: TYPE = REF FileHandleRep;
FileHandleRep: TYPE = RECORD[
newLine: PROC[self: FileHandle, line: PixelBuffer] RETURNS[eof: BOOLEAN],
data: REF
];
FileHandleList: TYPE = LIST OF FileHandle;
WriteTape: PROC [tapeHandle: TapeHandle, files: FileSpecList, tapeNumber: [1..999] ← 102, name: ROPE] RETURNS [TapesCommon.FileHandleList];
Initializes the tape for writing. Writes the master directory. Returns a list of FileHandle.
Client should use SizeOfList to check that the files will fit on the opened tape.
Client rasterizes into each FileHandle in turn. newLine.eof is TRUE when tape has recorded nLines worth of rasters. Client can check newLine.eof to verify that the client and the tape are still in sync.
WriteTape above requires all the files to be written at once. This guarentees tape integrity.
The following procedures allow you to build up a tape over several sessions.
Note, however, that you must include in the master directory all the files you will want to add.
Then, the files must be added in exactly the same order as they appear in the master directory.
It's ok to leave a tape incomplete, however.
InitializeTape: PROC [tapeHandle: TapeHandle, files: FileSpecList, tapeNumber: [1..999] ← 102, name: ROPE];
Must include correct FileSpecs for every file that may appear on the tape.
AddFileToTape: PROC [tapeHandle: TapeHandle, file: FileSpec, fileNumber, tapeNumber: NAT, inPosition: BOOLEANFALSE] RETURNS [TapesCommon.FileHandle];
File numbers start at 1. Files must be added in the order specified in the master directory.
tapeNumber is included in the local file directory, so it must be included here.
If inPosition, will start writing at the current tape position.
Otherwise, will rewind and use the file number to position the tape.
Read Tape
Identity: TYPE ~ REF IdentityRep;
IdentityRep: TYPE ~ RECORD [
tapeNumber: [1..999],
date: BasicTime.GMT,
name: ROPE
];
Directory: TYPE ~ REF DirectoryRep;
DirectoryRep: TYPE ~ RECORD [
fileNumber: [1..70],
contone: BOOL,
color: Color,
hRes, vRes: PixelsPerInch,
pixelsPerLine: CARDINAL,
lines: CARDINAL,
createDate: BasicTime.GMT,
note: ROPE,
tapeNumber: [0..999],
linesPerCylinder, sectorsPerLine, cylinders, blocks: CARDINAL
];
Color: TYPE ~ MACHINE DEPENDENT RECORD [
cyan(0:7..7): BOOL ← TRUE,
magenta(0:6..6): BOOL ← TRUE,
yellow(0:5..5): BOOL ← TRUE,
black(0:4..4): BOOL ← TRUE,
red(0:3..3): BOOL ← FALSE,
green(0:2..2): BOOL ← FALSE,
blue(0:1..1): BOOL ← FALSE,
ws1(0:0..0): BOOLFALSE, -- filler
negativeImage(0:15..15): BOOL ← FALSE, -- low values represent dark print/film
ws2(0:14..14): BOOLFALSE, -- filler
bytesPerPixel(0:11..13): [0 .. 7) ← 4,
ws3(0:8..10): [0 .. 7) ← 0
];
ReadTapeIdentity: PROC[tapeHandle: TapeHandle] RETURNS[Identity];
Rewinds tape, reads identity record
ReadMasterDirectory: PROC[tapeHandle: TapeHandle] RETURNS [nFiles: NAT, masterDirectory: LIST OF Directory];
Rewinds tape, reads identity record, reads master directory
ReadFile: PROC[tapeHandle: TapeHandle, fileNumber: [1..70] ← 1] RETURNS[Directory];
Reads a file, verifying that the format is consistant.
FileTo4AIS: PROC [tapeHandle: TapeHandle, fileNumber: [1..70] ← 1, aisRootName: ROPE, mapPixel: PixelProc, reduce: NAT ← 4] RETURNS [Directory];
Makes 4 ais files (cyan, magenta, yellow, black) from the information on the tape.
AIS files are 1/reduce2 the size of the original (ie for reduce = 4, 300 spi => 75 spi)
Sizes
A big tape is 2400 feet, a small tape is 600 feet.
SizeOfFile: PROC [fileSpec: FileSpec, density: UnixTapeOps.Density ← GCR6250] RETURNS [sizeInFeet: REAL];
The file and its directory
SizeOfHeader: PROC [density: UnixTapeOps.Density ← GCR6250] RETURNS [sizeInFeet: REAL];
The identity and master directory
SizeOfList: PROC [files: FileSpecList, density: UnixTapeOps.Density ← GCR6250] RETURNS [sizeInFeet: REAL];
Convenience proc. SizeOfFile for each file in list + SizeOfHeaders
Pixel Procs and Utilities
PixelProc: TYPE = PROC[pixel: BYTE] RETURNS[BYTE];
IdentityByte: PixelProc; 
CrosfieldToByte: PixelProc; --(DotPercent*2)+25 in theory, use for read
ByteToCrosfield: PixelProc; --25+2*100*pixel/255.0 use for write
KOToByte: PixelProc; --range [6..245] => [0..255]
ByteToKO: PixelProc; --range [0..255] => [6..245] use for write
END.