DIRECTORY PrintColorTransformations, PrintColor USING [ColorCorrection, CorrectionProc, ColorCorrectionRep], ImagerSample USING [PointerToSamples], ImagerPixel USING [PixelBuffer], NewInterpressCC, Real, RealFns, Basics, FS USING [StreamOpen], IO USING [STREAM, GetCard, GetLineRope, Close, GetID], Rope USING [ROPE]; PrintColorTransformationsImpl: CEDAR PROGRAM IMPORTS Real, RealFns, ImagerSample, FS, IO, NewInterpressCC EXPORTS PrintColorTransformations ~ BEGIN OPEN PrintColorTransformations; ROPE: TYPE ~ Rope.ROPE; ColorCorrection: TYPE ~ PrintColor.ColorCorrection; Matrix3: TYPE = ARRAY[0..3) OF ARRAY[0..3) OF REAL; SWOPData: TYPE = REF SWOPDataRec; RGBToCMYProc: TYPE = PROC[maxSampleIn: ARRAY [0..3) OF CARDINAL, rgbIn, cmyOut: ImagerPixel.PixelBuffer, data: REF]; SWOPDataRec: TYPE = RECORD[gcTable, cyanTable, magentaTable, yellowTable, blackTable: TRCTable _ NIL, rgbToCMY: RGBToCMYProc, rgbToCMYData: REF _ NIL]; SWOPLinearDotArea: PUBLIC PROC RETURNS[ColorCorrection] = { maxSampleOut: NAT = 255; cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $SWOP, correctionProc: SWOPColorCorrectionProc, maxSampleIn: [255, 255, 255], samplesPerPixelOut: maxSampleOut, data: NEW[SWOPDataRec _ [ cyanTable: cyanTable, magentaTable: magentaTable, yellowTable: yellowTable, blackTable: blackTable, gcTable: IdentityTRC[], rgbToCMY: FlipRGBCMYProc, rgbToCMYData: NIL ]] ]]; RETURN[cc]; }; SWOPWithGCLinearLStar: PUBLIC PROC RETURNS[ColorCorrection] = { maxSampleOut: NAT = 255; cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $SWOPLinearLStar, correctionProc: SWOPColorCorrectionProc, maxSampleIn: [255, 255, 255], samplesPerPixelOut: maxSampleOut, data: NEW[SWOPDataRec _ [ cyanTable: cyanTable, magentaTable: magentaTable, yellowTable: yellowTable, blackTable: blackTable, gcTable: convertToLStar, rgbToCMY: FlipRGBCMYProc, rgbToCMYData: NIL ]] ]]; RETURN[cc]; }; FlipRGBCMYProc: RGBToCMYProc = { --CMY _ [255,255, 255] -RGB maxRed: CARDINAL _ maxSampleIn[0]; maxGreen: CARDINAL _ maxSampleIn[1]; maxBlue: CARDINAL _ maxSampleIn[2]; FOR i: NAT IN [0..rgbIn.length) DO cmyOut[0][i] _ maxRed-rgbIn[0][i]; cmyOut[1][i] _ maxGreen-rgbIn[1][i]; cmyOut[2][i] _ maxBlue-rgbIn[2][i]; ENDLOOP; }; SWOPWithMatrix: PUBLIC PROC[matrixTables: MatrixTables] RETURNS[ColorCorrection] = { maxSampleOut: NAT = 255; cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $SWOPWithMatrix, correctionProc: SWOPColorCorrectionProc, maxSampleIn: [255, 255, 255], samplesPerPixelOut: maxSampleOut, data: NEW[SWOPDataRec _ [ cyanTable: cyanTable, magentaTable: magentaTable, yellowTable: yellowTable, blackTable: blackTable, gcTable: convertToLStar, rgbToCMY: MatrixTransform, rgbToCMYData: matrixTables ]] ]]; RETURN[cc]; }; SWOPColorCorrectionProc: PrintColor.CorrectionProc = { c,m,y,k, gc: NAT; data: SWOPData _ NARROW[self.data]; data.rgbToCMY[maxSampleIn: self.maxSampleIn, rgbIn: rgbIn, cmyOut: pixelsOut, data: data.rgbToCMYData]; FOR i: NAT IN [0..pixelsOut.length) DO c _ pixelsOut[0][i]; m _ pixelsOut[1][i]; y _ pixelsOut[2][i]; gc _ data.gcTable[MIN[c,m,y]]; c _ MAX[0, MIN[255, c-gc+data.cyanTable[gc]]]; m _ MAX[0, MIN[255, m-gc+data.magentaTable[gc]]]; y _ MAX[0, MIN[255, y-gc+data.yellowTable[gc]]]; k _ data.blackTable[gc]; pixelsOut[0][i] _ c; pixelsOut[1][i] _ m; pixelsOut[2][i] _ y; pixelsOut[3][i] _ k; ENDLOOP; }; Largest24bitNumber: INT ~ 77777777B; BYTE: TYPE ~ [0..377B]; InitMatrixTables: PUBLIC PROC[rgbToLStar, densityToDotArea: TRCTable, printerDMax, saturation, contrast: REAL, values: Values] RETURNS[MatrixTables] ~ { LToDTable: PROC [matrixEl:REAL, trc:TRCTable _ NIL] RETURNS [table: MatrixEltTable] ~ { Dens24FromLStarRel : PROC [pixel:NAT] RETURNS [tableValue: INT] ~ { dens: REAL _ LStarToDens[printerLStarMin + (printerRange * (pixel / 255.0))] * matrixEl; tableValue _ Real.InlineRound[ (dens / printerDMax) * Largest24bitNumber]; }; table _ NEW[MatrixEltTableRec]; FOR i: NAT IN [0..255] DO table[i] _ Dens24FromLStarRel[trc[i]]; ENDLOOP }; blackValue:NAT = 255; printerLStarMin, printerRange: REAL; tables: MatrixTables _ NEW[MatrixTablesRec]; matrix: Matrix3 _ MatrixFromValues[values]; FOR i:NAT IN [0..2] DO -- add required saturation boost FOR j:NAT IN [0..2] DO IF i=j THEN matrix[i][j] _ matrix[i][j] + saturation*2 ELSE matrix[i][j] _ matrix[i][j] - saturation ENDLOOP; ENDLOOP; FOR i:NAT IN [0..2] DO -- add required contrast boost matrix[i][i] _ matrix[i][i] + contrast; ENDLOOP; printerLStarMin _ DensToLStar[printerDMax]; printerRange _ 100.0 - printerLStarMin; tables.m00 _ LToDTable[matrix[0][0], rgbToLStar]; tables.m10 _ LToDTable[matrix[1][0], rgbToLStar]; tables.m20 _ LToDTable[matrix[2][0], rgbToLStar]; tables.m01 _ LToDTable[matrix[0][1], rgbToLStar]; tables.m11 _ LToDTable[matrix[1][1], rgbToLStar]; tables.m21 _ LToDTable[matrix[2][1], rgbToLStar]; tables.m02 _ LToDTable[matrix[0][2], rgbToLStar]; tables.m12 _ LToDTable[matrix[1][2], rgbToLStar]; tables.m22 _ LToDTable[matrix[2][2], rgbToLStar]; tables.cyan _ densityToDotArea; tables.magenta _ densityToDotArea; tables.yellow _ densityToDotArea; RETURN [tables] }; ProcFromCCSpec: PUBLIC PROC[ccSpec: ROPE, correctionType: CorrectionType, maxSampleOut, maxSampleIn: NAT _ 255] RETURNS[ColorCorrection] = { RETURN[NewInterpressCC.InitCC[file: ccSpec, colorCorrect: correctionType=full]]; }; MatrixTransform: RGBToCMYProc = { tables: MatrixTables _ NARROW[data]; rPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[rgbIn[0], 0, rgbIn.length]]; gPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[rgbIn[1], 0, rgbIn.length]]; bPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[rgbIn[2], 0, rgbIn.length]]; yPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[cmyOut[2], 0, cmyOut.length]]; mPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[cmyOut[1], 0, cmyOut.length]]; cPtr: LONG POINTER TO WORD _ LOOPHOLE[ImagerSample.PointerToSamples[cmyOut[0], 0, cmyOut.length]]; m00: MatrixEltTable _ tables.m00; m01: MatrixEltTable _ tables.m01; m02: MatrixEltTable _ tables.m02; m10: MatrixEltTable _ tables.m10; m11: MatrixEltTable _ tables.m11; m12: MatrixEltTable _ tables.m12; m20: MatrixEltTable _ tables.m20; m21: MatrixEltTable _ tables.m21; m22: MatrixEltTable _ tables.m22; yellow: TRCTable _ tables.yellow; magenta: TRCTable _ tables.magenta; cyan: TRCTable _ tables.cyan; FOR j: NAT IN [0..cmyOut.length) DO TRUSTED { r: CARDINAL _ rPtr^; g: CARDINAL _ gPtr^; b: CARDINAL _ bPtr^; cyan24: INT ~ MAX[ MIN[m00[r] + m01[g] + m02[b], Largest24bitNumber], 0]; mag24: INT ~ MAX[ MIN[m10[r] + m11[g] + m12[b], Largest24bitNumber], 0]; yel24: INT ~ MAX[ MIN[m20[r] + m21[g] + m22[b], Largest24bitNumber], 0]; yPtr^ _ 255-yellow[LOOPHOLE[yel24, Basics.LongNumber].hl]; mPtr^ _ 255-magenta[LOOPHOLE[mag24, Basics.LongNumber].hl]; cPtr^ _ 255-cyan[LOOPHOLE[cyan24, Basics.LongNumber].hl]; rPtr _ rPtr + 1; gPtr _ gPtr + 1; bPtr _ bPtr + 1; yPtr _ yPtr + 1; mPtr _ mPtr + 1; cPtr _ cPtr + 1; } ENDLOOP; }; LStarToRef: PROC [lstar: REAL] RETURNS [ref: REAL] ~ { IF lstar<8.9 THEN ref _ lstar / 903.29 ELSE { t: REAL _ (lstar+16) / 116.0; ref _ t * t * t; } }; RefToLstar: PROC [ref: REAL] RETURNS [lstar: REAL] ~ { IF ref<0.01 THEN lstar _ ref * 903.29 ELSE { lstar _ 116.0 * RealFns.Root[3, ref] - 16; } }; RefToDens: PROC [ref: REAL] RETURNS [dens: REAL] ~ { IF ref=0 THEN RETURN [Real.LargestNumber]; dens _ -RealFns.Log[10, ref] }; LStarToDens: PROC [lstar: REAL] RETURNS [dens: REAL] ~ { dens _ RefToDens[LStarToRef[lstar]]; }; DensToLStar: PROC [dens: REAL] RETURNS [lstar: REAL] ~ { lstar _ RefToLstar[DensToRef[dens]]; }; DensToRef: PROC [dens: REAL] RETURNS [ref: REAL] ~ { ref _ RealFns.Power[10, -dens]; }; LuminanceToDotArea: PUBLIC PROC[maxSampleOut, maxSampleIn: NAT _ 255] RETURNS[ColorCorrection] = { cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $LuminanceToDotArea, correctionProc: LuminanceToDotAreaProc, maxSampleIn: [maxSampleIn, maxSampleIn, maxSampleIn], samplesPerPixelOut: maxSampleOut, data: NIL ]]; RETURN[cc]; }; LuminanceToDotAreaProc: PrintColor.CorrectionProc = { FOR i: NAT IN [0..rgbIn.length) DO l: NAT _ Real.Round[0.30*rgbIn[0][i]+0.59*rgbIn[1][i]+0.11*rgbIn[2][i]]; pixelsOut[0][i] _ 0; pixelsOut[1][i] _ 0; pixelsOut[2][i] _ 0; pixelsOut[3][i] _ l; ENDLOOP; }; NullRGB: PUBLIC PROC[maxSampleOut, maxSampleIn: NAT _ 255] RETURNS[ColorCorrection] = { cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $NullRGB, correctionProc: NullRGBProc, maxSampleIn: [maxSampleIn, maxSampleIn, maxSampleIn], samplesPerPixelOut: maxSampleOut, data: NIL ]]; RETURN[cc]; }; NullRGBProc: PrintColor.CorrectionProc = { FOR i: NAT IN [0..rgbIn.length) DO pixelsOut[0][i] _ rgbIn[0][i]; pixelsOut[1][i] _ rgbIn[1][i]; pixelsOut[2][i] _ rgbIn[2][i]; IF pixelsOut.length=4 THEN pixelsOut[3][i] _ 0; ENDLOOP; }; FlipRGB: PUBLIC PROC[maxSampleOut, maxSampleIn: NAT _ 255] RETURNS[ColorCorrection] = { cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $FlipRGB, correctionProc: FlipRGBProc, maxSampleIn: [maxSampleIn, maxSampleIn, maxSampleIn], samplesPerPixelOut: maxSampleOut, data: NIL ]]; RETURN[cc]; }; FlipRGBProc: PrintColor.CorrectionProc = { FOR i: NAT IN [0..rgbIn.length) DO pixelsOut[0][i] _ self.maxSampleIn[0]-rgbIn[0][i]; pixelsOut[1][i] _ self.maxSampleIn[1]-rgbIn[1][i]; pixelsOut[2][i] _ self.maxSampleIn[2]-rgbIn[2][i]; pixelsOut[3][i] _ 0; ENDLOOP; }; FlipAndFullGCR: PUBLIC PROC[maxSampleOut, maxSampleIn: NAT _ 255] RETURNS[ColorCorrection] = { cc: ColorCorrection _ NEW[PrintColor.ColorCorrectionRep _ [ type: $FlipRGB, correctionProc: FlipAndFullGCRProc, maxSampleIn: [maxSampleIn, maxSampleIn, maxSampleIn], samplesPerPixelOut: maxSampleOut, data: NIL ]]; RETURN[cc]; }; FlipAndFullGCRProc: PrintColor.CorrectionProc = { c,m,y,k: NAT; FOR i: NAT IN [0..rgbIn.length) DO c _ self.maxSampleIn[0]-rgbIn[0][i]; m _ self.maxSampleIn[1]-rgbIn[1][i]; y _ self.maxSampleIn[2]-rgbIn[2][i]; k _ MIN[c,m,y]; pixelsOut[0][i] _ c-k; pixelsOut[1][i] _ m-k; pixelsOut[2][i] _ y-k; pixelsOut[3][i] _ k; ENDLOOP; }; ReadTRC: PUBLIC PROC [trcFn: ROPE] RETURNS [trc: TRCTable] ~ { in: IO.STREAM; in _ FS.StreamOpen[trcFn]; trc _ NEW[TRCTableRec _ ALL[0]]; [] _ in.GetID[]; FOR i:CARDINAL IN [0..255] DO index:CARDINAL; prev:CARDINAL _ index; index _ in.GetCard[]; IF index>0 AND prev+1#index THEN ERROR; prev _ index; trc[index] _ IO.GetCard[in]; [] _ in.GetLineRope[]; ENDLOOP; in.Close[]; }; DensityToLStar: PUBLIC PROC [dMax: REAL] RETURNS [trc:TRCTable] ~ { minLStar: REAL _ DensToLStar[dMax]; scale: REAL _ 2.55*100.0/(100-minLStar); trc _ NEW[TRCTableRec _ ALL[0]]; FOR i: NAT IN [0..255] DO trc[i] _ Real.Round[scale*(DensToLStar[dMax*(i/255.0)]-minLStar)]; ENDLOOP }; RGBToLStar: PUBLIC PROC [] RETURNS [convertRGB:TRCTable] = { getLStar: PROC [rel: REAL] RETURNS[lStar: REAL] = { --val in [0..1] IF rel > 0.008856 THEN lStar _ 116.0*RealFns.Power[base: rel, exponent: 1.0/3.0] -16.0 ELSE lStar _ 903.29*rel; }; step: REAL _ 1.0/255.0; convertRGB _ NEW[TRCTableRec]; FOR val: INT IN [0..256) DO convertRGB[val] _ Real.Round[2.55*getLStar[val*step]]; ENDLOOP; }; IdentityTRC: PUBLIC PROC [] RETURNS [initTrc:TRCTable] ~ { initTrc _ NEW[TRCTableRec _ ALL[0]]; FOR i: NAT IN [0..255] DO initTrc[i] _ i; ENDLOOP }; IdentityValues: PUBLIC PROC RETURNS[Values] = { RETURN[[c0: 1,m0: 0,y0: 0,c1: 0,m1: 1,y1: 0,c2: 0,m2: 0,y2: 1]]; }; MatrixFromValues: PROC[v: Values] RETURNS[matrix: Matrix3] = { matrix[0][0] _ v.c0; matrix[0][1] _ v.m0; matrix[0][2] _ v.y0; matrix[1][0] _ v.c1; matrix[1][1] _ v.m1; matrix[1][2] _ v.y1; matrix[2][0] _ v.c2; matrix[2][1] _ v.m2; matrix[2][2] _ v.y2; RETURN[matrix]; }; BuildTables: PROC = { --use of this is odd. Run it to read the TRC's, print result and copy it into the code below. Prefer to keep result pickled in code. Data comes from measuring and processing a gray wedge produced by Kedie-Orent. cyanTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-cyan.trc"]; magentaTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-magenta.trc"]; yellowTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-yellow.trc"]; blackTable _ ReadTRC["/ivy/stone/coloroffset/SWOP-black.trc"]; }; cyanTable: TRCTable _ NEW[TRCTableRec _ [0, 1, 3, 4, 6, 7, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 36, 37, 38, 39, 40, 42, 43, 44, 46, 47, 48, 50, 51, 52, 54, 55, 57, 58, 59, 61, 62, 63, 65, 66, 67, 69, 70, 72, 73, 75, 76, 77, 79, 80, 82, 83, 85, 86, 87, 89, 90, 92, 93, 95, 96, 97, 98, 99, 100, 101, 102, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, 178, 178, 179, 180, 181, 181, 182, 183, 184, 184, 185, 186, 187, 187, 188, 189, 190, 190, 191, 192, 193, 193, 194, 195, 196, 196, 197, 198, 199, 199, 200, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, 207, 208, 208, 209, 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216, 216, 217, 217, 218, 218, 219, 219, 219, 220, 220, 221, 221, 221, 222, 222, 223, 223, 223, 224, 224, 225, 225, 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 234, 235]]; magentaTable: TRCTable _ NEW[TRCTableRec _ [0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 52, 53, 54, 55, 56, 58, 59, 60, 61, 62, 63, 65, 66, 67, 68, 69, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 79, 80, 81, 82, 83, 84, 84, 85, 86, 87, 88, 88, 89, 90, 91, 92, 92, 93, 94, 95, 96, 97, 97, 98, 99, 100, 101, 102, 102, 103, 104, 105, 106, 107, 108, 108, 109, 110, 111, 112, 113, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 138, 139, 140, 141, 141, 142, 143, 144, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, 152, 153, 153, 154, 155, 155, 156, 157, 157, 158, 159, 159, 160, 160, 161, 162, 162, 163, 164, 164, 165, 166, 166, 167, 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, 174, 174, 175, 175, 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 182, 182, 183, 183, 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 198, 198, 199, 199, 200, 200, 201]]; yellowTable: TRCTable _ NEW[TRCTableRec _ [0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 62, 63, 64, 65, 66, 67, 69, 70, 71, 72, 73, 75, 76, 77, 78, 79, 80, 81, 82, 83, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, 99, 100, 101, 102, 103, 103, 104, 105, 106, 107, 107, 108, 109, 110, 111, 112, 112, 113, 114, 115, 116, 116, 117, 118, 119, 120, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 143, 144, 145, 145, 146, 147, 147, 148, 149, 149, 150, 151, 151, 152, 153, 153, 154, 155, 155, 156, 157, 157, 158, 158, 159, 160, 160, 161, 161, 162, 163, 163, 164, 165, 165, 166, 166, 167, 168, 168, 169, 169, 170, 170, 171, 171, 172, 172, 172, 173, 173, 174, 174, 174, 175, 175, 176, 176, 177, 177, 177, 178, 178, 179, 179, 179, 180, 180, 181, 181, 181, 182, 182, 183, 183, 183, 184, 184, 185, 185, 185, 186, 186, 187, 187, 187, 188, 188, 189, 189, 189, 190, 190, 191, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 198, 199]]; blackTable: TRCTable _ NEW[TRCTableRec _ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 134, 135, 136, 137, 138, 139, 140, 142, 144, 146, 147, 149, 151, 153, 155, 157, 158, 160, 162, 164]]; convertToLStar: TRCTable _ NEW[TRCTableRec _ [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53, 54, 55, 56, 56, 57, 58, 59, 59, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 67, 68, 68, 69, 70, 70, 71, 71, 72, 72, 73, 74, 75, 76, 77, 79, 80, 81, 82, 83, 84, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 116, 117, 118, 119, 120, 121, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 137, 138, 139, 140, 141, 141, 142, 143, 144, 144, 145, 146, 147, 148, 150, 151, 152, 154, 155, 156, 158, 159, 160, 162, 163, 164, 165, 167, 168, 169, 170, 171, 172, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 214, 216, 218, 221, 224, 228, 231, 234, 236, 239, 241, 243, 245, 247, 248, 250, 251, 253, 254, 255]]; END. BPrintColorTransformationsImpl.mesa Copyright ำ 1987 by Xerox Corporation. All rights reserved. Maureen Stone, June 4, 1989 3:31:17 pm PDT Color Transformation routines for printing monitor images SWOP Transformation SWOP Standard GCR and black Rhodes-Lamming color correction -- table values range from -LAST[INT]...LAST[INT] -- representation for printerDMax = Largest24bitNumber -- trc=NIL means that no mapping is to be performed. i.e. inputs are density coded Calls NewInterpressCC to get the color correction NewInterpressCC is just like InterpressCC except for the color correction type Black only RBG => luminance => dot area. Good if images are designed already in dot area Trivial CC procs RGB _ RGB CMYK = [C: 255-R, M: 255-G, Y: 255-B, K: 0]. Also the default color correction behavior C,M,Y computed as for flipRGB, then modified such that K= MIN[C, M, Y]. [C: C-K, M: M-K, Y: M-K, K: K] Utility Procedures Define the TRC along the gray axis, that is, where R=G=B. This is independent of the monitor phosphors because Y/Yn = f(YR+YG+YB)/(YR+YG+YB) = f for R=G=B ส๕˜code•Mark outsideHeaderšœ"™"Kšœ<™Kšœœ˜"Kšœ œ˜$Kšœ œ˜#šœœœ˜"Kšœ"˜"Kšœ$˜$Kšœ#˜#Kšœ˜—J˜—š œ œœ˜TKšœœ˜šœœ"˜;Kšœ˜Kšœ(˜(Kšœ˜Kšœ"˜"šœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜—Kšœ˜ K˜—šะbnœ˜6Kšœ œ˜Kšœœ ˜#Kšœg˜gšœœœ˜&Kšœ˜Kšœ˜Kšœ˜Kšœœ ˜Kšœœœ ˜.Kšœœœ#˜1Kšœœœ"˜0K˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜—K˜—™Jšœœ ˜$Kšœœ ˜K˜Kš  œœœLœœ˜˜˜š   œœ œœœ˜WJšœ2™2Jšœ6™6JšœR™Rš  ฯlœœœœœ˜CKšœœN˜XKšœJ˜JK˜—Jšœœ˜šœœœ ˜J•StartOfExpansion[]šœ&˜&Jš˜—J˜—J˜Kšœ œ˜Kšœœ˜$Kšœœ˜,K˜+K˜š œœœœก ˜8šœœœ˜šœ˜ Kšœ*˜*—šœ˜Kšœ(˜(—Jšœ˜—Jšœ˜J˜—š œœœœก˜6Kšœ'˜'Jšœ˜—J˜Kšœ+˜+Kšœ'˜'K˜Jšœ1˜1Jšœ1˜1Jšœ1˜1J˜Jšœ1˜1Jšœ1˜1šœ1˜1K˜—Jšœ1˜1Jšœ1˜1Jšœ1˜1J˜Kšœ˜Kšœ"˜"Kšœ!˜!Kšœ ˜K˜—K˜š  œ œ œ=œœ˜ŒKšœ1™1K™NKšœJ˜PK˜K˜—š œ˜!Kšœœ˜$Kš œœœœœœ;˜`Kš œœœœœœ;˜`Kš œœœœœœ;˜`Kš œœœœœœ=˜bKš œœœœœœ=˜bKš œœœœœœ=˜bKšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ!˜!Kšœ#˜#Kšœ˜š œœœœœ˜-Kšœœ œ œ ˜>šœœœ˜Kšœ/˜2Kšœ˜—šœœœ˜Kšœ/˜2K˜—šœœœ˜Kšœ/˜2K˜—Kšœœ˜:Kšœœ˜;Kšœœ ˜9Kšœ2˜2Kšœ3˜3Kšœœ˜ —K˜—K˜š   œœ œœœ˜6Kšœ œ˜&šœ˜Kšœœ˜K˜Kšœ˜—K˜K˜—š   œœœœ œ˜6Kšœ œ˜%šœ˜Kšœ*˜*Kšœ˜—K˜K˜—š   œœœœœ˜4Kšœœœ˜*Kšœ˜K˜—K˜š   œœ œœœ˜8Kšœ$˜$K˜—K˜š   œœœœ œ˜8Kšœ$˜$K˜K˜—š   œœœœœ˜4Kšœ˜K˜—J˜—™ š Ÿ ข œ œœœ˜bK™Nšœœ"˜;Kšœ˜Kšœ'˜'Kšœ5˜5Kšœ"˜"Kšœ˜ K˜—Kšœ˜ K˜—šŸขœ˜5šœœœ˜"KšœœB˜HKšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜——™š œ œœœ˜WKšœ ™ šœœ"˜;Kšœ˜Kšœ˜Kšœ5˜5Kšœ"˜"Kšœ˜ K˜—Kšœ˜ K˜K™—š  œ˜*šœœœ˜"Kšœ˜Kšœ˜Kšœ˜Kšœœ˜/Kšœ˜—K˜—š œ œœœ˜WKšœX™Xšœœ"˜;Kšœ˜Kšœ˜Kšœ5˜5Kšœ"˜"Kšœ˜ K˜—Kšœ˜ K˜—š  œ˜*šœœœ˜"Kšœ2˜2Kšœ2˜2Kšœ2˜2Kšœ˜Kšœ˜—K˜—š œ œœœ˜^Kšœ6™6Kšœ0™0šœœ"˜;Kšœ˜Kšœ#˜#Kšœ5˜5Kšœ"˜"Kšœ˜ K˜—Kšœ˜ K˜—š œ˜1Kšœ œ˜ šœœœ˜"Kšœ$˜$Kšœ$˜$Kšœ$˜$Kšœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜——™š œ œ œœ˜>Jšœœ˜Kšœœ˜Jšœœœ˜ J˜šœœœ ˜Jšœœ˜Jšœœ ˜Jšœ˜Jšœ œœœ˜'J˜ Jšœ œ ˜Jšœ˜Jšœ˜—J˜ J˜J˜—š ขœœœœœ˜CJšœ œ˜#Jšœœ˜(Jšœœœ˜ šœœœ ˜JšœC˜CJš˜—J˜—šข œœœœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ ˜J˜—J˜š  œœกึ˜์Kšœ<˜˜>J˜——˜šœœ˜'Jšœฎ ˜ฎ —šœœ˜*Jšœ‹ ˜‹ —šœœ˜)Jšœ“ ˜“ —šœœ˜(Jšœี˜ี—šœœ˜,Jšœไ˜ไ——Kšœ˜—…—FฐZ็