<> <> DIRECTORY Basics, ImagerPixelMaps, ImagerBasic, AIS, Rope, Scaled, ImagerTransform, ImagerAISUtil; ImagerAISUtilImpl: CEDAR PROGRAM IMPORTS Basics, ImagerPixelMaps, AIS, Scaled, ImagerTransform EXPORTS ImagerAISUtil ~ BEGIN ROPE: TYPE ~ Rope.ROPE; PixelMapFromAIS: PUBLIC PROC [aisName: ROPE] RETURNS [pixelMap: ImagerPixelMaps.PixelMap, raster: AIS.Raster] ~ TRUSTED { ais: AIS.FRef _ AIS.OpenFile[aisName]; window: AIS.WRef _ AIS.OpenWindow[ais]; lgBitsPerPixel: [0..4] _ SELECT (raster _ AIS.ReadRaster[ais]).bitsPerPixel FROM 0, 1 => 0, 2 => 1, 4 => 2, 8 => 3, 16 => 4, ENDCASE => ERROR; lineMap: ImagerPixelMaps.PixelMap _ ImagerPixelMaps.Create[lgBitsPerPixel, [0, 0, 1, raster.scanLength]]; lineBufferDesc: AIS.Buffer _ [length: lineMap.refRep.words, addr: lineMap.refRep.pointer]; pixelMap _ ImagerPixelMaps.Create[lgBitsPerPixel, [0, 0, raster.scanCount, raster.scanLength]]; FOR i: NAT IN [0..raster.scanCount) DO AIS.UnsafeReadLine[window, lineBufferDesc, i]; pixelMap.Transfer[lineMap]; lineMap.sOrigin _ lineMap.sOrigin + 1; ENDLOOP; AIS.CloseWindow[window]; AIS.CloseFile[ais]; }; TransformationFromScanMode: PROC [scanMode: AIS.ScanMode, lines, pixelsPerLine: INT] RETURNS [ImagerTransform.Transformation] ~ { pixelDeltaX: REAL _ SELECT scanMode FROM ru, rd => 1, lu, ld => -1, ENDCASE => 0; pixelDeltaY: REAL _ SELECT scanMode FROM ul, ur => 1, dr, dl => -1, ENDCASE => 0; lineDeltaX: REAL _ SELECT scanMode FROM dr, ur => 1, ul, dl => -1, ENDCASE => 0; lineDeltaY: REAL _ SELECT scanMode FROM ru, lu => 1, ld, rd => -1, ENDCASE => 0; t: ImagerTransform.TransformationRec _ [ a: lineDeltaX, b: pixelDeltaX, c: MAX[-(pixelDeltaX*pixelsPerLine + lineDeltaX*lines), 0], d: lineDeltaY, e: pixelDeltaY, f: MAX[-(pixelDeltaY*pixelsPerLine + lineDeltaY*lines), 0] ]; RETURN [ImagerTransform.FromRec[t]] }; AISToColor: PUBLIC PROC [aisName: Rope.ROPE] RETURNS [ImagerBasic.SampledColor] ~ { pixelArray: ImagerBasic.PixelArray _ NEW[ImagerBasic.PixelArrayRep]; color: ImagerBasic.SampledColor _ NEW[ImagerBasic.ColorRep.sampled]; pixelMap: ImagerPixelMaps.PixelMap; raster: AIS.Raster; [pixelMap, raster] _ PixelMapFromAIS[aisName]; IF ABS[pixelMap.sOrigin]+ABS[pixelMap.sMin]+ABS[pixelMap.fOrigin]+ABS[pixelMap.fMin] # 0 THEN ERROR; pixelArray.xPixels _ pixelMap.sSize; pixelArray.yPixels _ pixelMap.fSize; pixelArray.m _ TransformationFromScanMode[raster.scanMode, pixelMap.sSize, pixelMap.fSize]; pixelArray.maxSampleValue _ Basics.BITSHIFT[1, Basics.BITSHIFT[1, pixelMap.refRep.lgBitsPerPixel]]-1; pixelArray.samplesPerPixel _ 1; pixelArray.get _ SELECT pixelMap.refRep.lgBitsPerPixel FROM 0 => GetBitPixels, 3 => GetBytePixels, ENDCASE => GetPixels; pixelArray.data _ NEW[ImagerPixelMaps.PixelMap _ pixelMap]; color.transparent _ FALSE; color.pa _ pixelArray; color.m _ ImagerTransform.Rotate[0]; color.colorOperator _ IF raster.bitsPerPixel = 0 THEN $SampledBlack ELSE $Intensity; RETURN [color]; }; GetBitPixels: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ { pixelArrayRef: REF ImagerPixelMaps.PixelMap ~ NARROW[self.data]; pixelArray: ImagerPixelMaps.PixelMap ~ pixelArrayRef^; IF layer#0 THEN ERROR; FOR i: NAT IN [0..nSamples) DO WHILE yStart.Floor < 0 DO yStart _ yStart.PLUS[Scaled.FromInt[pixelArray.fSize]]; ENDLOOP; WHILE yStart.Floor >= pixelArray.fSize DO yStart _ yStart.MINUS[Scaled.FromInt[pixelArray.fSize]]; ENDLOOP; WHILE xStart.Floor < 0 DO xStart _ xStart.PLUS[Scaled.FromInt[pixelArray.sSize]]; ENDLOOP; WHILE xStart.Floor >= pixelArray.sSize DO xStart _ xStart.MINUS[Scaled.FromInt[pixelArray.sSize]]; ENDLOOP; buffer[i] _ pixelArray.GetBit[xStart.Floor, yStart.Floor]; xStart _ xStart.PLUS[xDelta]; yStart _ yStart.PLUS[yDelta]; ENDLOOP; }; GetBytePixels: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ { pixelArrayRef: REF ImagerPixelMaps.PixelMap ~ NARROW[self.data]; pixelArray: ImagerPixelMaps.PixelMap ~ pixelArrayRef^; IF layer#0 THEN ERROR; FOR i: NAT IN [0..nSamples) DO WHILE yStart.Floor < 0 DO yStart _ yStart.PLUS[Scaled.FromInt[pixelArray.fSize]]; ENDLOOP; WHILE yStart.Floor >= pixelArray.fSize DO yStart _ yStart.MINUS[Scaled.FromInt[pixelArray.fSize]]; ENDLOOP; WHILE xStart.Floor < 0 DO xStart _ xStart.PLUS[Scaled.FromInt[pixelArray.sSize]]; ENDLOOP; WHILE xStart.Floor >= pixelArray.sSize DO xStart _ xStart.MINUS[Scaled.FromInt[pixelArray.sSize]]; ENDLOOP; buffer[i] _ pixelArray.Get8Bits[xStart.Floor, yStart.Floor]; xStart _ xStart.PLUS[xDelta]; yStart _ yStart.PLUS[yDelta]; ENDLOOP; }; GetPixels: PROC [self: ImagerBasic.PixelArray, buffer: ImagerBasic.PixelBuffer, nSamples: NAT, layer: INT, xStart, yStart: Scaled.Value, xDelta, yDelta: Scaled.Value] ~ { pixelArrayRef: REF ImagerPixelMaps.PixelMap ~ NARROW[self.data]; pixelArray: ImagerPixelMaps.PixelMap ~ pixelArrayRef^; IF layer#0 THEN ERROR; FOR i: NAT IN [0..nSamples) DO WHILE yStart.Floor < 0 DO yStart _ yStart.PLUS[Scaled.FromInt[pixelArray.fSize]]; ENDLOOP; WHILE yStart.Floor >= pixelArray.fSize DO yStart _ yStart.MINUS[Scaled.FromInt[pixelArray.fSize]]; ENDLOOP; WHILE xStart.Floor < 0 DO xStart _ xStart.PLUS[Scaled.FromInt[pixelArray.sSize]]; ENDLOOP; WHILE xStart.Floor >= pixelArray.sSize DO xStart _ xStart.MINUS[Scaled.FromInt[pixelArray.sSize]]; ENDLOOP; buffer[i] _ pixelArray.GetPixel[xStart.Floor, yStart.Floor]; xStart _ xStart.PLUS[xDelta]; yStart _ yStart.PLUS[yDelta]; ENDLOOP; }; END.