PressImageImpl.mesa
Last edited by Shore; December 4, 1982 12:25 am
Last edited by Wyatt; December 1, 1983 5:47 pm
Michael Plass, June 6, 1985 3:55:52 pm PDT
Rick Beach, May 23, 1985 10:18:12 pm PDT
DIRECTORY Basics, IO, PressImage, PressReader, ImagerPixelArray, ImagerColorOperator, Imager, ImagerTransformation, ImagerPixelMap, ImagerPixelArrayPrivate, SafeStorage, ImagerPixelArrayDefs, ImagerSample, PrincOps, PrincOpsUtils;
PressImageImpl: CEDAR PROGRAM
IMPORTS Basics, IO, ImagerPixelMap, ImagerPixelArray, ImagerColorOperator, Imager, ImagerTransformation, SafeStorage, ImagerSample, PrincOpsUtils
EXPORTS PressImage, ImagerPixelArrayDefs
= BEGIN
Context: TYPE = Imager.Context;
Transformation: TYPE = ImagerTransformation.Transformation;
PixelArray: TYPE = ImagerPixelArrayDefs.PixelArray;
PixelMap: TYPE = ImagerPixelMap.PixelMap;
ru: NAT = 2;
rd: NAT = 3;
lu: NAT = 6;
ld: NAT = 7;
ul: NAT = 9;
ur: NAT = 8;
dl: NAT = 13;
dr: NAT = 12;
TransformationFromScanMode: PROC [scanMode: NAT, lines, pixelsPerLine: INT] RETURNS [Transformation] ~ {
pixelDeltaX: REALSELECT scanMode FROM
ru, rd => 1,
lu, ld => -1,
ENDCASE => 0;
pixelDeltaY: REALSELECT scanMode FROM
ul, ur => 1,
dr, dl => -1,
ENDCASE => 0;
lineDeltaX: REALSELECT scanMode FROM
dr, ur => 1,
ul, dl => -1,
ENDCASE => 0;
lineDeltaY: REALSELECT scanMode FROM
ru, lu => 1,
ld, rd => -1,
ENDCASE => 0;
RETURN [ImagerTransformation.Create[
a: lineDeltaX,
b: pixelDeltaX,
c: MAX[-(pixelDeltaX*pixelsPerLine + lineDeltaX*lines), 0],
d: lineDeltaY,
e: pixelDeltaY,
f: MAX[-(pixelDeltaY*pixelsPerLine + lineDeltaY*lines), 0]
]]
};
PressImage: PUBLIC TYPE = REF PressImageData;
PressImageData: PUBLIC TYPE = RECORD [
stream: IO.STREAM,
streamIndex: INT,
byteLength: INT,
scanMode: CARDINAL,
scanCount: CARDINAL, -- lines
scanLength: CARDINAL, -- dots
wordsPerLine: CARDINAL, -- words per scan line
passDots: NAT,
displayDots: NAT,
passLines: NAT,
displayLines: NAT,
imageHeight: REAL,
imageWidth: REAL,
lgBitsPerPixel: [0..4],
isBitmap: BOOL
];
PressImageError: PUBLIC ERROR = CODE;
MakePressImage: PUBLIC PROC [sampleType, dots, lines, mode, pd, dd, pl, dl: INT, width, height: REAL, bits: PressReader.Dots] RETURNS [self: PressImage ← NIL] = {
bitsperline: LONG CARDINAL ← Basics.LongMult[dots, IF sampleType IN [1..16] THEN sampleType ELSE 1];
wpl: CARDINAL ← (bitsperline + (bitsPerWord-1)) / bitsPerWord;
lgBitsPerPixel: [0..4] ~ SELECT sampleType FROM
0, 1 => 0,
2 => 1,
4 => 2,
8 => 3,
16 => 4,
ENDCASE => ERROR PressImageError;
IF bitsperline MOD bitsPerWord # 0 THEN ERROR PressImageError;
self ← NEW[PressImageData ← [
stream: bits.file,
streamIndex: LONG[bits.pageNumber]*512+bits.byteOffset,
byteLength: bits.length*Basics.bytesPerWord, -- bits.length is in words!
scanMode: mode,
scanCount: lines,
scanLength: dots,
wordsPerLine: wpl,
passDots: pd,
displayDots: dd,
passLines: pl,
displayLines: dl,
imageHeight: height,
imageWidth: width,
lgBitsPerPixel: lgBitsPerPixel,
isBitmap: sampleType = 0
]];
RETURN [self];
};
PixelArrayImpl: TYPE ~ ImagerPixelArrayPrivate.PixelArrayImpl;
PixelArrayImplRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayImplRep;
Concrete representation of PixelArrayImplRep, exported to ImagerPixelArrayDefs.
PixelArrayClass: TYPE ~ REF PixelArrayClassRep;
PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep;
pixelArrayClass: PixelArrayClass ~ NEW[PixelArrayClassRep ← [
type: $PressImage,
MaxSampleValue: MyMaxSampleValue,
UnsafeGetSamples: MyUnsafeGetSamples,
UnsafeGetBits: MyUnsafeGetBits
]];
MyMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [ImagerPixelArray.Sample] ~ {
impl: PixelArrayImpl ~ pa.impl;
data: REF PixelMap ~ NARROW[pa.data];
pm: PixelMap ~ data^;
lgBitsPerPixel: [0..4] ← pm.refRep.lgBitsPerPixel;
RETURN [Basics.BITSHIFT[1, Basics.BITSHIFT[1, lgBitsPerPixel]]-1]
};
MyUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT, s, f: INT,
samples: ImagerSample.UnsafeSamples, count: NAT] ~ UNCHECKED {
data: REF PixelMap ~ NARROW[pa.data];
ImagerSample.UnsafeGetF[samples: samples, count: count, base: data.refRep.pointer, wordsPerLine: data.refRep.rast, bitsPerSample: Basics.BITSHIFT[1, data.refRep.lgBitsPerPixel], s: s+data.sOrigin, f: f+data.fOrigin];
};
bitsPerWord: NAT ~ Basics.bitsPerWord;
MyUnsafeGetBits: UNSAFE PROC [pa: PixelArray, i: NAT ← 0, s, f: INT,
dst: PrincOps.BitAddress, dstBpl: INTEGER, width, height: CARDINAL,
srcFunc: PrincOps.SrcFunc ← null, dstFunc: PrincOps.DstFunc ← null] ~ UNCHECKED {
data: REF PixelMap ~ NARROW[pa.data];
source: PixelMap ~ data^;
sStartSource: NAT ~ s-source.sOrigin;
fMinSource: NAT ~ f-source.fOrigin;
bbTableSpace: PrincOps.BBTableSpace;
bb: PrincOps.BBptr ~ PrincOpsUtils.AlignedBBTable[@bbTableSpace];
IF source.refRep.lgBitsPerPixel # 0 THEN ERROR;
bb^ ← [
dstBpl: dstBpl,
srcDesc: [srcBpl[source.refRep.rast*bitsPerWord]],
height: height,
width: width,
flags: [direction: forward, disjoint: TRUE, disjointItems: TRUE, gray: FALSE, srcFunc: srcFunc, dstFunc: dstFunc],
dst: dst,
src: [word: (source.refRep.pointer + Basics.LongMult[sStartSource, source.refRep.rast] + (fMinSource/bitsPerWord)), bit: fMinSource MOD bitsPerWord]
];
PrincOpsUtils.BITBLT[bb];
};
identity: Transformation ~ ImagerTransformation.Scale[1];
MakePixelArray: PROC [pressImage: PressImage] RETURNS [ImagerPixelArray.PixelArray] ~ {
pm: PixelMap ~ ImagerPixelMap.Create[lgBitsPerPixel: pressImage.lgBitsPerPixel, bounds: [0, 0, pressImage.scanCount, pressImage.scanLength]];
IF INT[pm.refRep.words*Basics.bytesPerWord] < pressImage.byteLength THEN ERROR PressImageError;
IO.SetIndex[pressImage.stream, pressImage.streamIndex];
TRUSTED {
[] ← IO.UnsafeGetBlock[pressImage.stream, [LOOPHOLE[pm.refRep.pointer], 0, pressImage.byteLength]];
};
RETURN [NEW[ImagerPixelArrayDefs.PixelArrayRep ← [
samplesPerPixel: 1,
sSize: pressImage.displayLines,
fSize: pressImage.displayDots,
m: TransformationFromScanMode[pressImage.scanMode, pressImage.displayLines, pressImage.displayDots],
impl: NIL,
class: pixelArrayClass,
data: NEW[PixelMap ← pm.ShiftMap[-pressImage.passLines, -pressImage.passDots].Clip[[0,0,pressImage.displayLines, pressImage.displayDots]]]
]]];
};
DrawPressImage: PUBLIC PROC [self: Context, image: PressImage] = {
Proc: PROC ~ {
pa: ImagerPixelArray.PixelArray ~ MakePixelArray[image];
paDimen: Imager.VEC ~ ImagerTransformation.TransformVec[pa.m, [pa.sSize, pa.fSize]];
Imager.Move[self];
Imager.Scale2T[self, [image.imageWidth/ABS[paDimen.x], image.imageHeight/ABS[paDimen.y]]];
IF image.isBitmap THEN {
WhiteBackground: PROC ~ {
Imager.SetColor[self, Imager.white];
Imager.MaskRectangle[self, [0, 0, ABS[paDimen.x], ABS[paDimen.y]]];
};
IF TRUE -- NOT show dots opaque -- THEN Imager.DoSave[self, WhiteBackground];
Imager.MaskPixel[context: self, pa: pa];
}
ELSE {
maxSampleValue: INT ~ ImagerPixelArray.MaxSampleValue[pa, 0];
SampleMap: PROC [cardinal: CARDINAL] RETURNS [REAL] ~ {
RETURN [cardinal]
};
colorOperator: ImagerColorOperator.ColorOperator ~ ImagerColorOperator.GrayLinearColorModel[
sWhite: maxSampleValue,
sBlack: 0.0,
maxSampleValue: maxSampleValue,
sampleMap: SampleMap
];
Imager.SetSampledColor[
context: self,
pa: pa,
m: identity,
colorOperator: colorOperator
];
Imager.MaskRectangle[self, [0, 0, ABS[paDimen.x], ABS[paDimen.y]]];
};
};
Imager.DoSave[self, Proc];
SafeStorage.ReclaimCollectibleObjects[];
};
END.
Created by Shore; September 13, 1982 6:45 pm
Changed by Shore; October 14, 1982 9:24 pm
converted to Cedar 3.4 (FileIO) and new PressReader (Dots)
Changed by Shore; December 4, 1982 12:24 am
converted to Cedar.Style
Changed by Wyatt; December 1, 1983 4:14 pm
converted to Cedar 5.0 (Space => VM)
Changed by Plass; February 14, 1984 12:56:51 pm PST
Made images work for multiple bits per pixel
Michael Plass, April 4, 1985 10:42:18 am PST
Imager Conversion