DIRECTORY Basics, Commander, CommanderOps, Convert, FS, Imager, ImagerColor, ImagerError, ImagerDither, ImagerDitherContext, ImagerInterpress, ImagerPixel, ImagerSample, InterpressInterpreter, IO, RasterfileConverters, Real, RefText, Rope, SF; RasterfileConvertersImpl: CEDAR PROGRAM IMPORTS Basics, Commander, CommanderOps, Convert, FS, Imager, ImagerColor, ImagerError, ImagerDitherContext, ImagerInterpress, ImagerPixel, ImagerSample, InterpressInterpreter, IO, Real, RefText, Rope EXPORTS RasterfileConverters = BEGIN ROPE: TYPE ~ Rope.ROPE; Error: PUBLIC ERROR [explanation: ROPE] ~ CODE; WriteRasterfile: PUBLIC PROC [filename: ROPE, rsm: ImagerSample.RasterSampleMap, ime: ImagerDither.MapEntries] ~ { out: IO.STREAM ~ FS.StreamOpen[filename, create]; size: SF.Vec ~ rsm.GetSize[]; lineBits, lineBytes: INT; rBuf: REF TEXT ¬ RefText.ObtainScratch[256]; gBuf: REF TEXT ¬ RefText.ObtainScratch[256]; bBuf: REF TEXT ¬ RefText.ObtainScratch[256]; maxIndex, nIndex: NAT ¬ 0; ub: Basics.UnsafeBlock; PutInt[out, 59a66a95h]; PutInt[out, size.f]; PutInt[out, size.s]; IF rsm.GetBitsPerSample[] # 8 THEN ERROR; PutInt[out, 8]; lineBytes ¬ ((size.f+1)/2) * 2; PutInt[out, lineBytes*size.s]; PutInt[out, 1--RT¬STANDARD--]; PutInt[out, 1--RMT¬EQUAL¬RGB--]; FOR ime ¬ ime, ime.rest WHILE ime#NIL DO rBuf[ime.first.mapIndex] ¬ VAL[ime.first.red]; gBuf[ime.first.mapIndex] ¬ VAL[ime.first.green]; bBuf[ime.first.mapIndex] ¬ VAL[ime.first.blue]; maxIndex ¬ MAX[maxIndex, ime.first.mapIndex]; nIndex ¬ nIndex.SUCC; ENDLOOP; IF maxIndex # nIndex.PRED THEN Error["Colormap to output has gaps"]; PutInt[out, nIndex*3]; out.PutBlock[rBuf, 0, nIndex]; out.PutBlock[gBuf, 0, nIndex]; out.PutBlock[bBuf, 0, nIndex]; lineBits ¬ rsm.GetBitsPerLine[]; IF lineBits/8 # lineBytes THEN Error["Unimplemented sample map layout"]; ub ¬ rsm.GetUnsafeBlock[]; TRUSTED {IO.UnsafePutBlock[out, ub]}; out.Close[]; RefText.ReleaseScratch[rBuf]; RefText.ReleaseScratch[gBuf]; RefText.ReleaseScratch[bBuf]; RETURN}; ReadRasterfile: PROC [filename: ROPE, wantImage, wantCo, wantIme: BOOL] RETURNS [size: SF.Vec, rsm: ImagerSample.RasterSampleMap, co: ImagerColor.ColorOperator, ime: ImagerDither.MapEntries] ~ { in: IO.STREAM ~ FS.StreamOpen[filename]; magic: INT ~ GetInt[in]; IF magic # 59a66a95h THEN Error[IO.PutFR["%g not a rasterfile (magic number is %xh instead of 59a66a95h)", [rope[filename]], [integer[magic]] ]]; {width: INT ~ GetInt[in]; height: INT ~ GetInt[in]; depth: INT ~ GetInt[in]; length: INT ¬ GetInt[in]; type: INT ¬ GetInt[in]; maptype: INT ¬ GetInt[in]; maplength: INT ¬ GetInt[in]; lineBits, bytesRead: INT; ub: Basics.UnsafeBlock; IF width<0 OR height<0 OR depth<0 THEN Error["negative width, height, or depth"]; size ¬ [s: height, f: width]; IF maplength<0 OR length<0 THEN Error["negative image or colormap length"]; IF type#1 AND type#0 THEN Error[IO.PutFR1["unsupported type (%g)", [integer[type]] ]]; lineBits ¬ (((width * depth) + 15) / 16) * 16; IF length=0 THEN length ¬ (lineBits/8) * height ELSE IF length # (lineBits/8) * height THEN Error[IO.PutFLR["image length (%g) inconsistent with width, height, depth (%g, %g, %g)", LIST[ [integer[length]], [integer[width]], [integer[height]], [integer[depth]]] ]]; IF maptype#1 AND maptype#0 THEN Error[IO.PutFR1["unsupported colormap type (%g)", [integer[maptype]] ]]; IF (maptype=1) # (maplength>0) THEN Error["malformed rasterfile (colormap length inconsistent with type)"]; IF maptype=1 THEN { n: CARD ~ maplength/3; mapStart: INT ~ IO.GetIndex[in]; rBuf: REF TEXT ¬ RefText.ObtainScratch[256]; gBuf: REF TEXT ¬ RefText.ObtainScratch[256]; bBuf: REF TEXT ¬ RefText.ObtainScratch[256]; Map: PROC [i: CARD] RETURNS [color: ImagerColor.ConstantColor] ~ { IF i >= n THEN RETURN [Imager.white]; RETURN [ImagerColor.ColorFromRGB[[R: rBuf[i].ORD/255.0, G: gBuf[i].ORD/255.0, B: bBuf[i].ORD/255.0]]]}; IF n*3 # CARD[maplength] THEN Error["malformed rasterfile (colormap length not a multiple of 3)"]; IF n # in.GetBlock[rBuf, 0, n] THEN Error["rasterfile eof in red colormap entries"]; IF n # in.GetBlock[gBuf, 0, n] THEN Error["rasterfile eof in green colormap entries"]; IF n # in.GetBlock[bBuf, 0, n] THEN Error["rasterfile eof in blue colormap entries"]; IF wantIme THEN { ime ¬ NIL; FOR i: CARD IN [0..n) DO ime ¬ CONS[[i, rBuf[i].ORD, gBuf[i].ORD, bBuf[i].ORD], ime]; ENDLOOP; ime ¬ ime} ELSE ime ¬ NIL; IF wantCo THEN co ¬ ImagerColor.NewColorOperatorMap[2**depth - 1, Map] ELSE co ¬ NIL; RefText.ReleaseScratch[rBuf]; RefText.ReleaseScratch[gBuf]; RefText.ReleaseScratch[bBuf]; } ELSE {co ¬ NIL; ime ¬ NIL}; IF wantImage THEN { rsm ¬ ImagerSample.NewSampleMap[box: [min: [0, 0], max: [s: height, f: width]], bitsPerSample: depth, bitsPerLine: lineBits]; ub ¬ rsm.GetUnsafeBlock[]; IF ub.count # length THEN Error[IO.PutFR["raster sample map created with inconsistent format (count %g # length %g)", [cardinal[ub.count]], [integer[length]] ]]; TRUSTED {bytesRead ¬ IO.UnsafeGetBlock[in, ub]}; IF bytesRead#length THEN Error[IO.PutFR["wrong number of image bytes read (%g instead of %g)", [integer[bytesRead]], [integer[length]] ]]; } ELSE rsm ¬ NIL; in.Close[]; RETURN}}; RasterfileToIp: PROC [cmd: Commander.Handle] RETURNS [result: REF ¬ NIL, msg: ROPE ¬ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; rsm: ImagerSample.RasterSampleMap; pSize: SF.Vec; co: ImagerColor.ColorOperator; pm: ImagerPixel.PixelMap; master: ImagerInterpress.Ref; ppi: REAL; PaintPage: PROC [context: Imager.Context] ~ { Imager.DrawPixels[context, pm, co, [0, 0], [slow: down, fast: right], [x: 0, y: pSize.s] ]; RETURN}; IF argv.argc#5 OR NOT argv[2].Equal["_"] THEN RETURN [$Failue, "Usage: RasterfileToIp _ "]; ppi ¬ Convert.RealFromRope[argv[4]]; [, rsm, co, ] ¬ ReadRasterfile[argv[3], TRUE, TRUE, FALSE ! Error => CommanderOps.Failed[explanation] ]; pSize ¬ rsm.GetSize[]; pm ¬ ImagerPixel.MakePixelMap[rsm]; master ¬ ImagerInterpress.Create[argv[1]]; master.DoPage[PaintPage, Imager.metersPerInch/ppi]; master.Close[]; cmd.out.PutFL["%g _ %g pixel, %g inch by %g pixel, %g inch image.\n", LIST[ [rope[argv[1]]], [integer[pSize.f]], [real[pSize.f/ppi]], [integer[pSize.s]], [real[pSize.s/ppi]]] ]; RETURN}; DitherLikeRasterfile: PROC [cmd: Commander.Handle] RETURNS [result: REF ¬ NIL, msg: ROPE ¬ NIL] --Commander.CommandProc-- ~ { argv: CommanderOps.ArgumentVector ~ CommanderOps.Parse[cmd]; ime: ImagerDither.MapEntries; master: InterpressInterpreter.Master; ppi, widthI, heightI: REAL; widthP, heightP, lineBits: INT; iSize: SF.Vec; rsm: ImagerSample.RasterSampleMap; context: Imager.Context; Log: InterpressInterpreter.LogProc ~ { cmd.out.PutF["Interpress message: class=%g, code=%g, explanation=%g\n", [integer[class]], [atom[ImagerError.AtomFromErrorCode[code]]], [rope[explanation]] ]; RETURN}; IF (argv.argc#6 AND argv.argc#8) OR NOT argv[2].Equal["_"] THEN RETURN [$Failue, "Usage: DitherLikeRasterfile _ [ ]"]; master ¬ InterpressInterpreter.Open[argv[3], Log]; [iSize,,,ime] ¬ ReadRasterfile[argv[4], FALSE, FALSE, TRUE ! Error => CommanderOps.Failed[explanation] ]; ppi ¬ Convert.RealFromRope[argv[5]]; IF argv.argc>6 THEN { widthI ¬ Convert.RealFromRope[argv[6]]; heightI ¬ Convert.RealFromRope[argv[7]]; widthP ¬ Real.Round[widthI*ppi]; heightP ¬ Real.Round[heightI*ppi]} ELSE { widthP ¬ iSize.f; widthI ¬ widthP/ppi; heightP ¬ iSize.s; heightI ¬ heightP/ppi}; lineBits ¬ ((widthP+1)/2)*16; IF lineBits # widthP*8 THEN RETURN [$Failure, "Not an even number of pixels per scan line."]; rsm ¬ ImagerSample.NewSampleMap[box: [min: [0, 0], max: [s: heightP, f: widthP]], bitsPerSample: 8, bitsPerLine: lineBits]; context ¬ ImagerDitherContext.Create[deviceSpaceSize: [s: heightP, f: widthP], scanMode: [slow: down, fast: right], surfaceUnitsPerInch: [ppi, ppi], pixelUnits: FALSE]; ImagerDitherContext.SetSampleMap[context, rsm]; ImagerDitherContext.SetDitherMap[context, ime]; master.DoPage[1, context, Log]; master.Close[]; WriteRasterfile[argv[1], rsm, ime ! Error => CommanderOps.Failed[explanation] ]; RETURN}; GetInt: PROC [in: IO.STREAM] RETURNS [INT] ~ { buf: Basics.FWORD; nRead: INT; TRUSTED {nRead ¬ in.UnsafeGetBlock[[base: LOOPHOLE[@buf], count: BYTES[Basics.FWORD]]]}; IF nRead # 4 THEN IO.EndOfStream[in]; RETURN [Basics.Int32FromF[buf]]}; PutInt: PROC [out: IO.STREAM, i: INT] ~ { buf: Basics.FWORD ¬ Basics.FFromInt32[i]; TRUSTED {out.UnsafePutBlock[[base: LOOPHOLE[@buf], count: BYTES[Basics.FWORD]]]}; RETURN}; Commander.Register["RasterfileToIp", RasterfileToIp, " _ --- make Interpress file with a sampled color"]; Commander.Register["DitherLikeRasterfile", DitherLikeRasterfile, " _ [ ] --- dither an IP file against the colormap in a rasterfile, producing another rasterfile"]; END. Ά RasterfileConvertersImpl.mesa Copyright Σ 1991, 1992 by Xerox Corporation. All rights reserved. Spreitze, September 11, 1991 2:58 pm PDT Willie-s, April 2, 1992 7:51 pm PST Κy•NewlineDelimiter –(cedarcode) style™codešœ™Kšœ Οeœ7™BK™(K™#—K˜KšΟk œ+žœ‹žœ-žœ˜σK˜šΟnœžœž˜'Kšžœ+žœ}žœ˜ΘKšžœ˜—Kšœž˜K˜Kšžœžœžœ˜K˜Kš Ÿœžœžœžœžœ˜/K˜šŸœžœžœ žœF˜rKšœžœžœžœ˜1Kšœžœ˜Kšœžœ˜Kšœžœžœ˜,Kšœžœžœ˜,Kšœžœžœ˜,Kšœžœ˜K˜K˜K˜K˜Kšžœžœžœ˜)K˜K˜K˜Kšœ Οcœ  œ˜Kšœ  œ œ œ˜ šžœžœžœž˜(Kšœžœ˜.Kšœžœ˜0Kšœžœ˜/Kšœ žœ˜-Kšœžœ˜Kšžœ˜—Kšžœžœžœ&˜DKšœ˜Kšœ˜Kšœ˜Kšœ˜K˜ Kšžœžœ*˜HK˜Kšžœžœ˜%K˜ Kšœ˜Kšœ˜Kšœ˜Kšžœ˜—K˜š Ÿœžœ žœžœžœžœi˜ΒKšœžœžœžœ˜(Kšœžœ˜Kšžœžœžœo˜‘Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœ žœ˜Kšœ žœ˜Kšœžœ˜Kšœ˜Kšžœ žœ žœ žœ+˜QK˜Kšžœ žœ žœ,˜KKšžœžœžœžœ4˜VK˜.šžœ ˜ Kšžœ˜#Kš žœžœ žœžœQžœO˜Ψ—Kšžœ žœ žœžœ@˜hKšžœžœH˜kšžœ žœ˜Kšœžœ˜Kšœ žœžœ˜ Kšœžœžœ˜,Kšœžœžœ˜,Kšœžœžœ˜,šŸœžœžœžœ'˜BKšžœžœžœ˜%Kšžœ'žœžœžœ ˜g—Kšžœžœ žœE˜bKšžœžœ1˜TKšžœžœ3˜VKšžœžœ2˜Ušžœ žœ˜Kšœžœ˜ šžœžœžœž˜Kš œžœ žœ žœ žœ˜