DIRECTORY AIS, Environment, FileIO, ImagerColor, ImagerBasic, IO, Rope, Scaled ; ImagerAISImpl: CEDAR PROGRAM IMPORTS AIS, FileIO, IO, Rope, Scaled EXPORTS ImagerColor ~ BEGIN blockHeight: NAT ~ 32; blockWidth: NAT ~ 64; Block: TYPE ~ REF BlockRep; BlockRep: TYPE ~ ARRAY [0..blockHeight) OF ChunkRep; ChunkRep: TYPE ~ PACKED ARRAY [0..blockWidth) OF [0..256); BufferRep: TYPE ~ RECORD [ SEQUENCE numberOfChunks: NAT OF ChunkRep ]; LoadAISData: PROC [aisName: Rope.ROPE] RETURNS [reblockedAIS: ReblockedAIS] ~ TRUSTED { text: Rope.Text _ aisName.Flatten; ais: AIS.FRef _ AIS.OpenFile[LOOPHOLE[text], FALSE]; window: AIS.WRef _ AIS.OpenWindow[ais]; numberOfChunksAcross: NAT _ MAX[(ais.raster.scanLength+blockWidth-1)/blockWidth, 1]; bufferRef: REF BufferRep _ NEW[BufferRep[numberOfChunksAcross]]; buffer: AIS.Buffer _ [numberOfChunksAcross*SIZE[ChunkRep], @bufferRef[0]]; rowNumber: NAT _ 0; file: IO.STREAM _ FileIO.Open[aisName.Concat[".reblocked$"], write]; numberOfBuffers: NAT _ MAX[numberOfChunksAcross, ais.raster.scanCount/blockHeight] + 2; block: REF BufferSeqRep _ NEW[BufferSeqRep[numberOfBuffers]]; FlushBuffers: PROC ~ TRUSTED { byteSize: INT ~ INT[Environment.bytesPerWord]*SIZE[BlockRep]; FOR i: NAT IN [0..numberOfChunksAcross) DO file.UnsafePutBlock[[base: @(block[i].block[0]), startIndex: 0, stopIndexPlusOne: byteSize]]; ENDLOOP; rowNumber _ 0; }; IF ais.raster.bitsPerPixel # 8 THEN ERROR; FOR i: NAT IN [0..numberOfBuffers) DO block[i] _ [LAST[NAT], LAST[NAT], NEW[BlockRep]] ENDLOOP; FOR line: NAT IN [0..ais.raster.scanCount) DO window.ReadLine[buffer, line]; FOR chunkNumber: NAT IN [0..numberOfChunksAcross) DO block[chunkNumber].block[rowNumber] _ bufferRef[chunkNumber]; ENDLOOP; rowNumber _ rowNumber + 1; IF rowNumber >= blockHeight THEN FlushBuffers[]; ENDLOOP; IF rowNumber > 0 THEN FlushBuffers[]; reblockedAIS _ NEW[ReblockedAISRep]; reblockedAIS.file _ file; reblockedAIS.scanCount _ ais.raster.scanCount; reblockedAIS.scanLength _ ais.raster.scanLength; reblockedAIS.scanMode _ ais.raster.scanMode; reblockedAIS.numberOfChunksAcross _ numberOfChunksAcross; ais.CloseFile; reblockedAIS.nextBufferToAllocate _ 0; reblockedAIS.bufferSeq _ block; }; ReblockedAIS: TYPE ~ REF ReblockedAISRep; ReblockedAISRep: TYPE ~ RECORD [ file: IO.STREAM, scanLength: NAT, scanCount: NAT, scanMode: AIS.ScanMode, numberOfChunksAcross: NAT, nextBufferToAllocate: NAT _ 0, bufferSeq: REF BufferSeqRep ]; BufferSeqRep: TYPE ~ RECORD [ SEQUENCE length: NAT OF BufferDescriptor ]; BufferDescriptor: TYPE ~ RECORD [ xDivBlockWidth, yDivBlockHeight: NAT, block: Block ]; AISToColor: PUBLIC PROC [aisName: Rope.ROPE] RETURNS [ImagerBasic.Color] ~ { pixelArray: ImagerBasic.PixelArray _ NEW[ImagerBasic.PixelArrayRep]; color: ImagerBasic.SampledColor _ NEW[ImagerBasic.SampledColorRep]; reblockedAIS: ReblockedAIS _ LoadAISData[aisName]; SELECT reblockedAIS.scanMode FROM ru, lu, rd, ld => {pixelArray.xPixels _ reblockedAIS.scanLength; pixelArray.yPixels _ reblockedAIS.scanCount}; ur, ul, dr, dl => {pixelArray.xPixels _ reblockedAIS.scanCount; pixelArray.yPixels _ reblockedAIS.scanLength}; ENDCASE => ERROR; pixelArray.maxSampleValue _ 255; pixelArray.samplesPerPixel _ 1; pixelArray.get _ GetOne; pixelArray.data _ reblockedAIS; color.transparent _ FALSE; color.pa _ pixelArray; color.m _ [1, 0, 0, 0, 1, 0, identity]; color.colorMap _ $Intensity8bpp; RETURN [color]; }; GetOne: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ { reblockedAIS: ReblockedAIS _ NARROW[self.data]; curBuf: BufferDescriptor; SELECT reblockedAIS.scanMode FROM ru => NULL; rd => {yStart _ Scaled.FromInt[reblockedAIS.scanCount].MINUS[yStart]; yDelta _ yDelta.UMINUS}; ENDCASE => ERROR; FOR i: NAT IN [0..nSamples) DO y: INTEGER _ yStart.Floor; x: INTEGER _ xStart.Floor; IF NOT x IN [0..reblockedAIS.scanLength) THEN { WHILE x < 0 DO x _ x + reblockedAIS.scanLength ENDLOOP; WHILE x >= reblockedAIS.scanLength DO x _ x - reblockedAIS.scanLength ENDLOOP; xStart.integerPart _ x; }; IF NOT y IN [0..reblockedAIS.scanCount) THEN { WHILE y < 0 DO y _ y + reblockedAIS.scanCount ENDLOOP; WHILE y >= reblockedAIS.scanCount DO y _ y - reblockedAIS.scanCount ENDLOOP; yStart.integerPart _ y; }; IF NAT[x]/blockWidth # curBuf.xDivBlockWidth OR NAT[y]/blockHeight # curBuf.yDivBlockHeight THEN { xDivBlockWidth: NAT _ NAT[x]/blockWidth; yDivBlockHeight: NAT _ NAT[y]/blockHeight; FOR j: NAT IN [0..reblockedAIS.bufferSeq.length) DO curBuf _ reblockedAIS.bufferSeq[j]; IF xDivBlockWidth = curBuf.xDivBlockWidth AND yDivBlockHeight = curBuf.yDivBlockHeight THEN EXIT; ENDLOOP; IF xDivBlockWidth # curBuf.xDivBlockWidth OR yDivBlockHeight # curBuf.yDivBlockHeight THEN TRUSTED { byteSize: INT ~ INT[Environment.bytesPerWord]*SIZE[BlockRep]; curBuf _ reblockedAIS.bufferSeq[reblockedAIS.nextBufferToAllocate]; curBuf.xDivBlockWidth _ xDivBlockWidth; curBuf.yDivBlockHeight _ yDivBlockHeight; reblockedAIS.file.SetIndex[(INT[yDivBlockHeight]*reblockedAIS.numberOfChunksAcross+xDivBlockWidth)*(INT[Environment.bytesPerWord]*SIZE[BlockRep])]; [] _ reblockedAIS.file.UnsafeGetBlock[[base: @(curBuf.block[0]), startIndex: 0, stopIndexPlusOne: byteSize]]; reblockedAIS.bufferSeq[reblockedAIS.nextBufferToAllocate] _ curBuf; reblockedAIS.nextBufferToAllocate _ reblockedAIS.nextBufferToAllocate + 1; IF reblockedAIS.nextBufferToAllocate >= reblockedAIS.bufferSeq.length THEN reblockedAIS.nextBufferToAllocate _ 0; }; }; buffer[i] _ curBuf.block[NAT[y] MOD blockHeight][NAT[x] MOD blockWidth]; xStart _ xStart.PLUS[xDelta]; yStart _ yStart.PLUS[yDelta]; ENDLOOP; }; END. žImagerAISImpl.mesa Michael Plass, July 12, 1983 1:45 pm LoadAISData: PROC [aisName: Rope.ROPE] RETURNS [file: IO.STREAM] ~ TRUSTED { text: Rope.Text _ aisName.Flatten; ais: AIS.FRef _ AIS.OpenFile[LOOPHOLE[text], FALSE]; window: AIS.WRef _ NIL; AIS.OpenWindow[ais]; xPixels: NAT; yPixels: NAT; pixelArray: ImagerBasic.PixelArray _ NEW[ImagerBasic.PixelArrayRep]; color: ImagerBasic.SampledColor _ NEW[ImagerBasic.SampledColorRep]; curLine, curPixel, xNextLine, xNextPixel, yNextLine, yNextPixel: INTEGER; SELECT ais.raster.scanMode FROM ru, lu, rd, ld => {xPixels _ ais.raster.scanLength; yPixels _ ais.raster.scanCount}; ur, ul, dr, dl => {xPixels _ ais.raster.scanCount; yPixels _ ais.raster.scanLength}; ENDCASE => ERROR; SELECT ais.raster.scanMode FROM ru => {curLine_0; curPixel_0; xNextLine_0; xNextPixel_1; yNextLine_1; yNextPixel_0}; ul => {curLine_xPixels-1; curPixel_0; xNextLine_-1; xNextPixel_0; yNextLine_0; yNextPixel_1}; ld => {curLine_yPixels-1; curPixel_xPixels-1; xNextLine_0; xNextPixel_-1; yNextLine_-1; yNextPixel_0}; dr => {curLine_0; curPixel_yPixels-1; xNextLine_1; xNextPixel_0; yNextLine_0; yNextPixel_-1}; rd => {curLine_yPixels-1; curPixel_0; xNextLine_0; xNextPixel_1; yNextLine_-1; yNextPixel_0}; ur => {curLine_0; curPixel_0; xNextLine_1; xNextPixel_0; yNextLine_0; yNextPixel_1}; lu => {curLine_0; curPixel_xPixels-1; xNextLine_0; xNextPixel_-1; yNextLine_1; yNextPixel_0}; dl => {curLine_curLine_xPixels-1; curPixel_yPixels-1; xNextLine_-1; xNextPixel_0; yNextLine_0; yNextPixel_-1}; ENDCASE => ERROR; array _ NEW[ArrayRep[yPixels]]; FOR y: NAT IN [0..yPixels) DO row: Row _ array[y] _ NEW[RowRep[xPixels]]; savedLine: NAT _ curLine; savedPixel: NAT _ curPixel; FOR x: NAT IN [0..xPixels) DO row[x] _ window.ReadSample[curLine, curPixel]; curLine _ curLine + xNextLine; curPixel _ curPixel + xNextPixel; ENDLOOP; curLine _ savedLine + yNextLine; curPixel _ savedPixel + yNextPixel; ENDLOOP; ais.CloseFile; }; ÊL˜J™J™$J˜šÏk ˜ Jšœ˜J˜ J˜J˜ Jšœ ˜ Jšœ˜Jšœ˜J˜J˜—šœ ˜Jšœœ œ˜%Jšœ ˜Jšœ˜—Jšœ œ˜Jšœ œ˜Jšœœœ ˜Jšœ œœœ ˜4Jš œ œœœœ ˜:šœ œœ˜Jšœœœ ˜(Jšœ˜—š Ïn œœœœœœ˜WJšœ"˜"Jš œœœ œœ˜4Jšœœœ˜'Jšœœœ5˜TJšœ œ œ"˜@Jšœœ œ˜JJšœ œ˜Jšœœœ5˜DJšœœœ=˜WJšœœœ ˜=šž œœœ˜Jšœ œœœ ˜=šœœœ˜*Jšœ]˜]Jšœ˜—Jšœ˜Jšœ˜—Jšœœœ˜*šœœœ˜%Jš œ œœœœœ ˜0Jšœ˜—šœœœ˜-Jšœ˜šœœœ˜4Jšœ=˜=Jšœ˜—Jšœ˜Jšœœ˜0Jšœ˜—Jšœœ˜%Jšœœ˜$Jšœ˜Jšœ.˜.Jšœ0˜0Jšœ,˜,Jšœ9˜9J˜Jšœ&˜&Jšœ˜Jšœ˜—šž œœœœœœœ™LJšœ"™"Jš œœœ œœ™4Jšœœœ™J™Jšœ™Jšœ œ™ Jšœ œ™ Jšœ%œ™DJšœ"œ™CJšœAœ™Išœ™JšœT™TJšœT™TJšœœ™—šœ™JšœT™TJšœ]™]Jšœf™fJšœ]™]Jšœ]™]JšœT™TJšœ]™]Jšœn™nJšœœ™—Jšœœ™šœœœ™Jšœœ™+Jšœ œ ™Jšœ œ ™šœœœ™Jšœ.™.Jšœ™Jšœ!™!Jšœ™—Jšœ ™ Jšœ#™#Jšœ™—J™Jšœ™—Jšœœœ˜)šœœœ˜ Jšœœœ˜Jšœ œ˜Jšœ œ˜Jšœ œ ˜Jšœœ˜Jšœœ˜Jšœ œ ˜Jšœ˜—šœœœ˜Jšœ œœ˜(Jšœ˜—šœœœ˜!Jšœ!œ˜%J˜ Jšœ˜—š ž œœœœœ˜LJšœ%œ˜DJšœ"œ˜CJšœ2˜2šœ˜!Jšœn˜nJšœn˜nJšœœ˜—Jšœ ˜ Jšœ˜Jšœ˜Jšœ˜Jšœœ˜Jšœ˜Jšœ'˜'Jšœ ˜ Jšœ ˜Jšœ˜—šžœœKœ œA˜§Jšœœ ˜/Jšœ˜šœ˜!Jšœœ˜ Jšœ7œœ˜^Jšœœ˜—šœœœ˜Jšœœ˜Jšœœ˜šœœœœ˜/Jšœœ!œ˜7Jšœœ!œ˜NJšœ˜J˜—šœœœœ˜.Jšœœ œ˜6Jšœœ œ˜LJšœ˜J˜—š œœ'œœ)œ˜bJšœœœ˜(Jšœœœ˜*šœœœ$˜3Jšœ#˜#Jšœ(œ*œœ˜aJšœ˜—šœ(œ*œœ˜dJšœ œœœ ˜=JšœC˜CJšœ'˜'Jšœ)˜)JšœœEœœ ˜“Jšœm˜mJšœC˜CJšœJ˜JJšœDœ'˜qJšœ˜—Jšœ˜—Jš œœœœœ ˜HJšœœ ˜Jšœœ ˜Jšœ˜—Jšœ˜—Jšœ˜—…—%þ