<> <> <> <> <<>> DIRECTORY Basics USING [bitsPerWord], Imager, ImagerColor USING [], ImagerColorDefs USING [Color, ConstantColor, ColorOperator, ColorOperatorRep], ImagerColorOperator USING [ColorFromPixel, GrayLinearColorModel, GrayVisualColorModel, MapColorModel, PixelProc, RGBLinearColorModel], ImagerFont, ImagerPixelArrayDefs USING [PixelArray, PixelArrayClassRep, PixelArrayRep], ImagerPixelArrayPrivate USING [PixelArrayClass, PixelArrayClassRep], ImagerSample USING [Sample, UnsafeSamples], ImagerTransformation USING [Transformation], IPImager USING [], IPInterpreter, PrincOps USING [BitAddress, DstFunc, SrcFunc], Rope USING [Equal, ROPE], RuntimeError USING [BoundsFault]; IPImagerImpl: CEDAR PROGRAM IMPORTS ImagerColorOperator, ImagerFont, IPInterpreter, Rope, RuntimeError EXPORTS IPImager, ImagerPixelArrayDefs = BEGIN OPEN IPInterpreter; <<>> ROPE: TYPE ~ Rope.ROPE; Font: TYPE ~ ImagerFont.Font; XChar: TYPE ~ ImagerFont.XChar; XCharProc: TYPE ~ ImagerFont.XCharProc; XStringProc: TYPE ~ ImagerFont.XStringProc; Transformation: TYPE ~ ImagerTransformation.Transformation; MaskChar: PUBLIC PROC [self: Ref, fd: Vector, i: Cardinal] ~ { characterMasks: Vector ~ VectorFromAny[GetPR[fd, "characterMasks"]]; found: BOOL; value: Any; [found, value] _ GetPropC[characterMasks, i]; IF found THEN { maskOp: PROC ~ { Do[self, OperatorFromAny[value]] }; Mark[self, 0]; PushVector[self, fd]; DoSaveAll[self, maskOp]; WHILE Count[self]>0 DO Pop[self] ENDLOOP; Unmark[self, 0]; }; }; FindFont: PUBLIC PROC [self: Ref, v: Vector] RETURNS [Font] ~ { name: ROPE ~ NameFromVector[v]; font: Font ~ ImagerFont.Find[name]; RETURN[font]; }; <> <> <> <> <> <> <> <<];>> <<>> <> <<>> <> <> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <<}>> <> <> <> <<};>> <> <<}>> <> <<};>> <<>> <> <> <> <> <> <> <> <<}>> <> <<};>> <<>> PixelArray: TYPE ~ ImagerPixelArrayDefs.PixelArray; PixelArrayRep: TYPE ~ ImagerPixelArrayDefs.PixelArrayRep; Sample: TYPE ~ ImagerSample.Sample; UnsafeSamples: TYPE ~ ImagerSample.UnsafeSamples; PixelArrayData: TYPE ~ REF PixelArrayDataRep; PixelArrayDataRep: TYPE ~ RECORD[ samplesPerLayer: INT, maxSampleValue: Vector, maxSampleValueI: Cardinal, <> sampleVector: Vector ]; MakePixelArray: PUBLIC PROC [ xPixels, yPixels: Cardinal, -- number of pixels in slow and fast directions samplesPerPixel: Cardinal, -- number of sample values for each pixel maxSampleValue: Vector, -- maximum sample value; if NIL, use maxSampleValueI maxSampleValueI: Cardinal, -- constant maximum sample value, if maxSampleValue=NIL samplesInterleaved: BOOL, -- if true, samples for one pixel are contiguous m: Transformation, -- transformation from pixel coordinates to master coordinates samples: Vector -- the actual samples ] RETURNS [PixelArray] ~ { sampleShape: VectorShape ~ Shape[samples]; data: PixelArrayData ~ NEW[PixelArrayDataRep]; IF maxSampleValue#NIL THEN { shape: VectorShape ~ Shape[maxSampleValue]; IF shape.lowerBound#0 OR shape.size#samplesPerPixel THEN ERROR; maxSampleValueI _ 0; FOR i: Cardinal IN[0..samplesPerPixel) DO maxSampleValueI _ MAX[GetCardinal[maxSampleValue, i], maxSampleValueI]; ENDLOOP; }; IF samplesInterleaved AND samplesPerPixel>1 THEN { MasterError[$unimplemented, "Not implemented: interleaved samples"]; }; IF sampleShape.lowerBound#0 OR (samplesPerPixel*xPixels*yPixels)#sampleShape.size THEN { MasterError[$wrongShape, "samples vector has wrong shape for MAKEPIXELARRAY"]; }; data^ _ [ samplesPerLayer: xPixels*yPixels, maxSampleValue: maxSampleValue, maxSampleValueI: maxSampleValueI, sampleVector: samples ]; RETURN[NEW[PixelArrayRep _ [class: IF samples.class.type = $PackedBits THEN pixelArrayBitmapClass ELSE pixelArrayClass, data: data, sSize: xPixels, fSize: yPixels, samplesPerPixel: samplesPerPixel, m: m]]]; }; PixelArrayClass: TYPE ~ ImagerPixelArrayPrivate.PixelArrayClass; PixelArrayClassRep: PUBLIC TYPE ~ ImagerPixelArrayPrivate.PixelArrayClassRep; pixelArrayBitmapClass: PixelArrayClass ~ NEW[PixelArrayClassRep _ [ type: $InterpressBits, MaxSampleValue: IPMaxSampleValue, UnsafeGetSamples: IPUnsafeGetSamples, UnsafeGetBits: IPUnsafeGetBits ]]; pixelArrayClass: PixelArrayClass ~ NEW[PixelArrayClassRep _ [ type: $Interpress, MaxSampleValue: IPMaxSampleValue, UnsafeGetSamples: IPUnsafeGetSamples ]]; IPMaxSampleValue: PROC [pa: PixelArray, i: NAT] RETURNS [Sample] ~ { data: PixelArrayData ~ NARROW[pa.data]; IF i IN[0..pa.samplesPerPixel) THEN { IF data.maxSampleValue = NIL THEN RETURN [data.maxSampleValueI] ELSE RETURN [GetCardinal[data.maxSampleValue, i]]; } ELSE ERROR RuntimeError.BoundsFault; }; IPUnsafeGetSamples: UNSAFE PROC [pa: PixelArray, i: NAT _ 0, s, f: INT, samples: UnsafeSamples, count: NAT] ~ UNCHECKED { data: PixelArrayData ~ NARROW[pa.data]; layerOffset: INT ~ data.samplesPerLayer*i; IF i NOT IN[0..pa.samplesPerPixel) THEN ERROR RuntimeError.BoundsFault; IF s NOT IN[0..pa.sSize) THEN ERROR RuntimeError.BoundsFault; IF f NOT IN[0..pa.fSize) THEN ERROR RuntimeError.BoundsFault; IF f+count NOT IN[0..pa.fSize] THEN ERROR RuntimeError.BoundsFault; UnsafeGetElements[vector: data.sampleVector, buffer: samples, start: layerOffset+s*pa.fSize+f, count: count]; }; bitsPerWord: NAT ~ Basics.bitsPerWord; IPUnsafeGetBits: 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: PixelArrayData ~ NARROW[pa.data]; layerOffset: INT ~ data.samplesPerLayer*i; lineIndex: INT _ layerOffset+s*pa.fSize+f; dstBase: LONG POINTER _ dst.word; dstBit: NAT _ dst.bit; delta: NAT ~ dstBpl; IF i NOT IN[0..pa.samplesPerPixel) THEN ERROR RuntimeError.BoundsFault; IF s NOT IN[0..pa.sSize) THEN ERROR RuntimeError.BoundsFault; IF s+height NOT IN[0..pa.sSize] THEN ERROR RuntimeError.BoundsFault; IF f NOT IN[0..pa.fSize) THEN ERROR RuntimeError.BoundsFault; IF f+width NOT IN[0..pa.fSize] THEN ERROR RuntimeError.BoundsFault; THROUGH [0..height) DO IPInterpreter.UnsafeGetBits[vector: data.sampleVector, dst: [word: dstBase, bit: dstBit], start: lineIndex, count: width, srcFunc: srcFunc, dstFunc: dstFunc]; lineIndex _ lineIndex + pa.fSize; dstBase _ dstBase + NAT[dstBit + delta] / bitsPerWord; dstBit _ NAT[dstBit + delta] MOD bitsPerWord; ENDLOOP; }; FindDecompressor: PUBLIC PROC [self: Ref, v: Vector] RETURNS [Operator] ~ { name: ROPE ~ NameFromVector[v]; ERROR; }; <<>> <> <<>> Color: TYPE ~ ImagerColorDefs.Color; ConstantColor: TYPE ~ ImagerColorDefs.ConstantColor; ColorOperator: TYPE ~ ImagerColorDefs.ColorOperator; ColorOperatorRep: TYPE ~ ImagerColorDefs.ColorOperatorRep; FindColor: PUBLIC PROC [self: Ref, v: Vector] RETURNS [Color] ~ { name: ROPE ~ NameFromVector[v]; ERROR; }; ColorOperatorDo: PROC [op: Operator, state: Ref] ~ { colorOperator: ColorOperator ~ NARROW[op.data]; coords: Vector ~ PopVector[state]; pixel: ImagerColorOperator.PixelProc ~ { RETURN[GetCardinal[coords, i]] }; PushAny[state, ImagerColorOperator.ColorFromPixel[colorOperator, pixel]]; }; colorOperatorClass: OperatorClass ~ NEW[OperatorClassRep _ [ type: $ColorOperator, do: ColorOperatorDo]]; OperatorFromColorOperator: PUBLIC PROC [colorOperator: ColorOperator] RETURNS [Operator] ~ { RETURN[NEW[OperatorRep _ [class: colorOperatorClass, data: colorOperator]]]; }; ColorOperatorFromOperator: PUBLIC PROC [op: Operator] RETURNS [ColorOperator] ~ { IF op.class.type=$ColorOperator THEN WITH op.data SELECT FROM colorOp: ColorOperator => RETURN[colorOp]; ENDCASE; RETURN[NIL]; }; FindColorOperator: PUBLIC PROC [self: Ref, v: Vector] RETURNS [Operator] ~ { name: ROPE ~ NameFromVector[v]; ERROR; }; <> ColorModelOperator: TYPE ~ PROC [parameters: Vector] RETURNS [colorOperator: Operator]; ColorModelOperatorData: TYPE ~ REF ColorModelOperatorDataRep; ColorModelOperatorDataRep: TYPE ~ RECORD[ name: ROPE, operator: ColorModelOperator ]; ColorModelOperatorDo: PROC [op: Operator, state: Ref] ~ { data: ColorModelOperatorData ~ NARROW[op.data]; parameters: Vector ~ PopVector[state]; PushOperator[state, data.operator[parameters]]; }; colorModelOperatorClass: OperatorClass ~ NEW[OperatorClassRep _ [ type: $ColorModelOperator, do: ColorModelOperatorDo]]; FindColorModelOperator: PUBLIC PROC [self: Ref, v: Vector] RETURNS [Operator] ~ { name: ROPE ~ NameFromVector[v]; data: ColorModelOperatorData ~ NEW[ColorModelOperatorDataRep _ [ name: name, operator: NIL]]; SELECT TRUE FROM Rope.Equal[name, "Xerox/grayLinear", FALSE] => data.operator _ XeroxGrayLinear; < data.operator _ XeroxGrayDensity;>> Rope.Equal[name, "Xerox/grayVisual", FALSE] => data.operator _ XeroxGrayVisual; Rope.Equal[name, "Xerox/Research/RGBLinear", FALSE] => data.operator _ XeroxResearchRGBLinear; Rope.Equal[name, "Xerox/Map", FALSE] => data.operator _ XeroxMap; < op _ xxx;>> < op _ xxx;>> ENDCASE; IF data.operator=NIL THEN ERROR; RETURN[NEW[OperatorRep _ [class: colorModelOperatorClass, data: data]]]; }; CheckSize: PROC [v: Vector, size: Cardinal] ~ { shape: VectorShape ~ Shape[v]; IF shape.lowerBound=0 AND shape.size=size THEN RETURN; ERROR; }; GetPixelMap: PROC [parameters: Vector, i: Cardinal] RETURNS [Vector] ~ { x: Any ~ Get[parameters, i]; IF Type[x]=number AND RealFromAny[x]=0 THEN RETURN[NIL] ELSE { pixelMap: Vector ~ VectorFromAny[x]; shape: VectorShape ~ Shape[pixelMap]; IF shape.lowerBound#0 THEN ERROR; RETURN[pixelMap]; }; }; XeroxGrayLinear: PROC [parameters: Vector] RETURNS [Operator] ~ { colorOp: ColorOperator _ NIL; sWhite: REAL ~ GetReal[parameters, 0]; sBlack: REAL ~ GetReal[parameters, 1]; pixelMap: Vector ~ GetPixelMap[parameters, 2]; mapSize: CARDINAL ~ IF pixelMap#NIL THEN Shape[pixelMap].size-1 ELSE 0; mapProc: PROC [i: CARDINAL] RETURNS [REAL] ~ { RETURN[GetReal[pixelMap, i]] }; CheckSize[parameters, 3]; colorOp _ ImagerColorOperator.GrayLinearColorModel[sWhite: sWhite, sBlack: sBlack, maxSampleValue: mapSize, sampleMap: mapProc]; RETURN[OperatorFromColorOperator[colorOp]]; }; <> <> <> <> <> <> <> <> <> <> <> <<};>> <<>> XeroxGrayVisual: PROC [parameters: Vector] RETURNS [Operator] ~ { colorOp: ColorOperator _ NIL; sWhite: REAL ~ GetReal[parameters, 0]; sBlack: REAL ~ GetReal[parameters, 1]; pixelMap: Vector ~ GetPixelMap[parameters, 2]; mapSize: CARDINAL ~ IF pixelMap#NIL THEN Shape[pixelMap].size-1 ELSE 0; mapProc: PROC [i: CARDINAL] RETURNS [REAL] ~ { RETURN[GetReal[pixelMap, i]] }; CheckSize[parameters, 3]; colorOp _ ImagerColorOperator.GrayVisualColorModel[sWhite: sWhite, sBlack: sBlack, maxSampleValue: mapSize, sampleMap: mapProc]; RETURN[OperatorFromColorOperator[colorOp]]; }; XeroxResearchRGBLinear: PROC [parameters: Vector] RETURNS [Operator] ~ { maxSampleValue: Cardinal ~ GetCardinal[parameters, 0]; colorOp: ColorOperator _ ImagerColorOperator.RGBLinearColorModel[maxSampleValue]; RETURN[OperatorFromColorOperator[colorOp]]; }; XeroxMap: PROC [parameters: Vector] RETURNS [Operator] ~ { maxSampleValue: Cardinal ~ Shape[parameters].size-1; map: PROC [s: CARDINAL] RETURNS [ConstantColor] ~ {RETURN [NARROW[Get[parameters, s]]]}; colorOp: ColorOperator ~ ImagerColorOperator.MapColorModel[maxSampleValue, map]; RETURN[OperatorFromColorOperator[colorOp]]; }; <> <> <> <> <> <> <<};>> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<}>> <> <> <> <<}>> <> <<};>> <<>> END.