This is ColorView.m in view mode; [Download] [Up]
/* ColorView.m Copyright 1994 Steve Ludtke */ /* This object is basically the entire program. Not very object oriented */ /* but it works. */ #import "ColorView.h" #import <appkit/appkit.h> #import <dpsclient/psops.h> #import <dpsclient/dpsclient.h> #import <misckit/MiscSliderCell.h> #import <misckit/MiscSliderField.h> #import <libc.h> #import <math.h> // This should point to your ghostscript executable char *GSCOM = "/usr/local/bin/gs"; // This is the printer type to send to the GS command char *PRINTYPE= "cdj550"; // This points to the location of the filt.sh used in your printcap entry char *FILTFS = "/usr/local/lib/ghostscript/filt/filt.sh"; // This points to where you installed the pp0cat program char *PP0CAT = "/usr/local/bin/pp0cat"; // This points to the parameter file char *PARMFS = "/usr/local/lib/ghostscript/filt/hpccor.parm"; char *TMPCCOR = "/usr/local/lib/ghostscript/filt/hpccor"; extern id NXApp; @implementation ColorView - initFrame:(NXRect *)myrect { int i,r,g,b; char s[240]; [super initFrame:myrect]; [self setDrawSize:1.3 :1.0]; /* initialize to identity matrix */ for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { CCOR[r][g][b][0]=(float)r*32.0; CCOR[r][g][b][1]=(float)g*32.0; CCOR[r][g][b][2]=(float)b*32.0; } } } sel[0]=sel[1]=sel[2]=dsel=0; bpath=(char *)[[NXBundle mainBundle] directory]; sprintf(s,"%s/Library/HPColorCorrect",getenv("HOME")); if (access(s,0)!=0) mkdir(s,0xffff); colorPanel=nil; return self; } -appDidInit:sender { FILE *in; int a,b,c,d; in=fopen(PARMFS,"r"); if (in!=NULL) { fscanf(in," %d %d %d %d",&a,&b,&c,&d); [bitsperpix selectCellAt:a :0]; [depletion selectCellAt:b :0]; [shingling selectCellAt:c :0]; [resolution selectCellAt:d :0]; fclose(in); } return self; } -loadInfo:sender { [NXApp loadNibSection:"Info.nib" owner:self]; return self; } /* redisplay the plot, used for button attachments */ - display:sender { [self display]; return self; } /* We must rescale when the user changes the box size */ -superviewSizeChanged:(const NXSize *)oldsize { [super superviewSizeChanged:oldsize]; [self setDrawSize:1.3 :1.0]; [self display]; return self; } // does actual drawing. If dsel==1 then only display selected color // if dsel==2 then we're printing so only use 1 color/circle - drawSelf:(NXRect *)rects :(int)rectCount { int ri,gi,bi; float r=0,g=0,b=0,x,y; if (dsel!=1) { PSsetgray(1.0); PSmoveto(0,0); PSlineto(1.3,0); PSlineto(1.3,1.0); PSlineto(0,1.0); PSfill(); } for (x=.05; x<1.3; x+=.1) { for (y=.05; y<1.0; y+=.1) { ri=r*8.0; gi=g*8.0; bi=b*8.0; if (dsel!=1||(ri==sel[0]&&gi==sel[1]&&bi==sel[2])) { /* screen color */ PSsetrgbcolor(r,g,b); PSmoveto(x,y); if (dsel!=2) PSarc(x,y,.05,0,180.0); else PSarc(x,y,.05,0,360.0); PSfill(); /* adjusted color */ if (dsel!=2&&mapsel!=0) { PSsetrgbcolor(CCOR[ri][gi][bi][0]/256.0, CCOR[ri][gi][bi][1]/256.0,CCOR[ri][gi][bi][2]/256.0); PSmoveto(x,y); PSarc(x,y,.05,180.0,360.0); PSfill(); if (ri==sel[0]&&gi==sel[1]&&bi==sel[2]) { PSsetgray(0); PSsetlinewidth(0); PSarc(x,y,.05,0.0,360.0); PSstroke(); } } } r+=.25; if (r>1.0) { r=0; g+=.25; } if (g>1.0) { g=0; b+=.25; } if (b>1.0) break; } } dsel=0; return self; } /* Allows the user to select an area of the plot to be passed to the */ /* delegate via a zoomTo:::: message. We make use of the image we stored */ /* so we don't have to replot every time the rubberband box is moved */ -mouseDown:(NXEvent *)oevent { int oldMask,fl; NXEvent *event,evs; char s[50]; int x,y; if (oevent->flags&NX_ALTERNATEMASK||oevent->flags&NX_COMMANDMASK) fl=1; else fl=0; evs=*oevent; oevent=&evs; [self convertPoint:&oevent->location fromView:nil]; x=floor(evs.location.x/.1); y=floor(evs.location.y/.1); if (x==12&&y>4) x=y=0; x=x*10+y; sel[0]=(x%5)*2; sel[1]=((x/5)%5)*2; sel[2]=((x/25)%5)*2; //printf("select :%d , %d %d %d\n",x,sel[0],sel[1],sel[2]); [self display]; [self updSel]; return self; } -useParms:sender { FILE *out; /* write parms to file so we know what they are next time we are run */ out=fopen(PARMFS,"w"); if (out==NULL) { printf("Can't open PARMFS\n"); return self; } chmod(PARMFS,0666); fprintf(out,"%d %d %d %d\n",[bitsperpix selectedRow],[depletion selectedRow], [shingling selectedRow],[resolution selectedRow]); fclose(out); /* write filt.sh file */ out=fopen(FILTFS,"w"); if (out==NULL) { printf("Can't open filt.sh\n"); return self; } chmod(FILTFS,0777); fprintf(out,"#!/bin/sh\n%s -q -dNOPAUSE -sDEVICE=%s ",GSCOM,PRINTYPE); switch ([bitsperpix selectedRow]) { case 0: fprintf(out,"-dBitsPerPixel=1 "); break; case 1: fprintf(out,"-dBitsPerPixel=3 "); break; case 2: fprintf(out,"-dBitsPerPixel=8 "); break; case 3: fprintf(out,"-dBitsPerPixel=16 "); break; case 4: fprintf(out,"-dBitsPerPixel=24 "); break; case 5: fprintf(out,"-dBitsPerPixel=32 "); break; } fprintf(out,"-dDepletion=%d ",[depletion selectedRow]); fprintf(out,"-dShingling=%d ",[shingling selectedRow]); switch ([resolution selectedRow]) { case 0: fprintf(out,"-r75 "); break; case 1: fprintf(out,"-r150 "); break; case 2: fprintf(out,"-r300 "); break; } fprintf(out,"-sOutputFile=\\|%s -\n",PP0CAT); fclose(out); return self; } -modColor:sender { [colwin makeKeyAndOrderFront:self]; return self; } /* change selected color */ -set1Color:sender { NXColor set; set=[sender color]; NXConvertColorToRGB(set,&CCOR[sel[0]][sel[1]][sel[2]][0],&CCOR[sel[0]][sel[1]][sel[2]][1],&CCOR[sel[0]][sel[1]][sel[2]][2]); CCOR[sel[0]][sel[1]][sel[2]][0]*=255.0; CCOR[sel[0]][sel[1]][sel[2]][1]*=255.0; CCOR[sel[0]][sel[1]][sel[2]][2]*=255.0; dsel=1; [self display]; return self; } /* reset selected color to default */ -resetColor:sender { CCOR[sel[0]][sel[1]][sel[2]][0]=(float)sel[0]*32.0; CCOR[sel[0]][sel[1]][sel[2]][1]=(float)sel[1]*32.0; CCOR[sel[0]][sel[1]][sel[2]][2]=(float)sel[2]*32.0; [self updSel]; dsel=1; [self display]; return self; } /* reset entire matrix to default */ -resetAll:sender { int r,g,b; for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { CCOR[r][g][b][0]=(float)r*32.0; CCOR[r][g][b][1]=(float)g*32.0; CCOR[r][g][b][2]=(float)b*32.0; } } } [self updSel]; [self display]; return self; } /* fills in "odd" colors */ -interp { int r,g,b,a,i,rr,gg,bb; float val,d; float tmp[9][9][9][3]; int ary[7][3] = { 0,0,0 ,1,0,0 ,0,1,0 ,0,0,1 ,-1,0,0 ,0,-1,0 ,0,0,-1 }; bcopy(CCOR,tmp,8748); for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { if (r%2==0&&g%2==0&&b%2==0) continue; for (i=0; i<3; i++) { d=0; val=0; for (a=1; a<7; a++) { rr=r+ary[a][0]; gg=g+ary[a][1]; bb=b+ary[a][2]; if (rr<0||rr>8||gg<0||gg>8||bb<0||bb>8) continue; val+=tmp[rr][gg][bb][i]; d+=1.0; } CCOR[r][g][b][i]=val/d; } } } } return self; } /* smooths the correction matrix */ -smooth:sender { int r,g,b,a,i,rr,gg,bb; float val,d; float tmp[9][9][9][3]; int ary[7][3] = { 0,0,0 ,1,0,0 ,0,1,0 ,0,0,1 ,-1,0,0 ,0,-1,0 ,0,0,-1 }; [self interp]; bcopy(CCOR,tmp,8748); for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { for (i=0; i<3; i++) { d=10.0; /* weight of center color */ val=10.0*tmp[r][g][b][i]; for (a=1; a<7; a++) { rr=r+ary[a][0]; gg=g+ary[a][1]; bb=b+ary[a][2]; if (rr<0||rr>8||gg<0||gg>8||bb<0||bb>8) continue; val+=tmp[rr][gg][bb][i]; d+=1.0; } CCOR[r][g][b][i]=val/d; } } } } [self display]; [self updSel]; return self; } /* save current color map to /tmp/hpccor */ -use:sender { FILE *out; [self interp]; out=fopen(TMPCCOR,"w"); chmod(TMPCCOR,0666); if (mapsel==0) CCOR[0][0][0][0]=-1.0; fwrite(CCOR,sizeof(float),2187,out); fclose(out); return self; } -default:sender { FILE *in; char *fsp; fsp=[self colFileSpec:2]; if (fsp==NULL) { [self resetAll:self]; return self; } in=fopen(fsp,"r"); if (in==NULL) return self; fread(CCOR,sizeof(float),2187,in); fclose(in); [self display]; [self updSel]; return self; } -revert:sender { FILE *in; char *fsp; fsp=[self colFileSpec:0]; if (fsp==NULL) { [self resetAll:self]; return self; } in=fopen(fsp,"r"); if (in==NULL) return self; fread(CCOR,sizeof(float),2187,in); fclose(in); [self display]; [self updSel]; return self; } -newMap:sender { FILE *in; char *fsp; mapsel=[sender selectedRow]; fsp=[self colFileSpec:0]; if (fsp==NULL) { [self resetAll:self]; return self; } in=fopen(fsp,"r"); if (in==NULL) return self; fread(CCOR,sizeof(float),2187,in); fclose(in); [self display]; [self updSel]; return self; } -saveMap:sender { FILE *out; char *fsp; [self use:self]; fsp=[self colFileSpec:1]; if (fsp==NULL) return self; out=fopen(fsp,"w"); if (out==NULL) return self; fwrite(CCOR,sizeof(float),2187,out); fclose(out); return self; } -(char *)colFileSpec:(char)flag { static char s[240]; if (mapsel==0) return (NULL); if (flag!=2) { sprintf(s,"%s/Library/HPColorCorrect/map%d.hpcmap",getenv("HOME"),mapsel); if (access(s,0)==0||flag==1) return (s); // users customized version } sprintf(s,"%s/map%d.hpcmap",bpath,mapsel); if (access(s,0)==0) return (s); // the file in the app return (NULL); //this should never happen } /* make entire map darker */ -darken:sender { int r,g,b,m; m=[rgbmodsel selectedCol]; for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { if (m==3||m==0) CCOR[r][g][b][0]-=5.0; if (m==3||m==1) CCOR[r][g][b][1]-=5.0; if (m==3||m==2) CCOR[r][g][b][2]-=5.0; if (CCOR[r][g][b][0]<0) CCOR[r][g][b][0]=0; if (CCOR[r][g][b][1]<0) CCOR[r][g][b][1]=0; if (CCOR[r][g][b][2]<0) CCOR[r][g][b][2]=0; } } } [self updSel]; [self display]; return self; } -lighten:sender { int r,g,b,m; m=[rgbmodsel selectedCol]; for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { if (m==3||m==0) CCOR[r][g][b][0]+=5.0; if (m==3||m==1) CCOR[r][g][b][1]+=5.0; if (m==3||m==2) CCOR[r][g][b][2]+=5.0; if (CCOR[r][g][b][0]>255.0) CCOR[r][g][b][0]=255.0; if (CCOR[r][g][b][1]>255.0) CCOR[r][g][b][1]=255.0; if (CCOR[r][g][b][2]>255.0) CCOR[r][g][b][2]=255.0; } } } [self updSel]; [self display]; } /* increase contrast of entire map */ -moreContrast:sender { int r,g,b,m; m=[rgbmodsel selectedCol]; for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { if (m==3||m==0) CCOR[r][g][b][0]=(CCOR[r][g][b][0]-128.0)/.95+128.0; if (m==3||m==1) CCOR[r][g][b][1]=(CCOR[r][g][b][1]-128.0)/.95+128.0; if (m==3||m==2) CCOR[r][g][b][2]=(CCOR[r][g][b][2]-128.0)/.95+128.0; if (CCOR[r][g][b][0]<0) CCOR[r][g][b][0]=0; if (CCOR[r][g][b][1]<0) CCOR[r][g][b][1]=0; if (CCOR[r][g][b][2]<0) CCOR[r][g][b][2]=0; if (CCOR[r][g][b][0]>255.0) CCOR[r][g][b][0]=255.0; if (CCOR[r][g][b][1]>255.0) CCOR[r][g][b][1]=255.0; if (CCOR[r][g][b][2]>255.0) CCOR[r][g][b][2]=255.0; } } } [self updSel]; [self display]; } -lessContrast:sender { int r,g,b,m; m=[rgbmodsel selectedCol]; for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { if (m==3||m==0) CCOR[r][g][b][0]=(CCOR[r][g][b][0]-128.0)*.95+128.0; if (m==3||m==1) CCOR[r][g][b][1]=(CCOR[r][g][b][1]-128.0)*.95+128.0; if (m==3||m==2) CCOR[r][g][b][2]=(CCOR[r][g][b][2]-128.0)*.95+128.0; if (CCOR[r][g][b][0]>255.0) CCOR[r][g][b][0]=255.0; if (CCOR[r][g][b][1]>255.0) CCOR[r][g][b][1]=255.0; if (CCOR[r][g][b][2]>255.0) CCOR[r][g][b][2]=255.0; } } } [self updSel]; [self display]; } -gammaAdj:sender { int r,g,b,m; float ga; ga=[gamma floatValue]; m=[rgbmodsel selectedCol]; for (r=0; r<9; r++) { for (g=0; g<9; g++) { for (b=0; b<9; b++) { if (m==3||m==0) CCOR[r][g][b][0]=pow((CCOR[r][g][b][0]/256.0),ga)*256.0; if (m==3||m==1) CCOR[r][g][b][1]=pow((CCOR[r][g][b][1]/256.0),ga)*256.0; if (m==3||m==2) CCOR[r][g][b][2]=pow((CCOR[r][g][b][2]/256.0),ga)*256.0; if (CCOR[r][g][b][0]>255.0) CCOR[r][g][b][0]=255.0; if (CCOR[r][g][b][1]>255.0) CCOR[r][g][b][1]=255.0; if (CCOR[r][g][b][2]>255.0) CCOR[r][g][b][2]=255.0; } } } [self updSel]; [self display]; } -(BOOL)acceptsFirstMouse { return (YES); } /* redisplay RGB values of selected cell */ -updSel { NXColor set; if (colorPanel==nil) { [NXColorPanel setPickerMask:NX_ALLMODESMASK]; [NXColorPanel setPickerMode:NX_HSBMODE]; colorPanel=[NXColorPanel sharedInstance:YES]; [colorPanel setTarget:self]; [colorPanel setAction:@selector(set1Color:)]; [colorPanel setShowAlpha:NO]; [colorPanel setContinuous:YES]; [colorPanel makeKeyAndOrderFront:self]; } set=NXConvertRGBToColor(CCOR[sel[0]][sel[1]][sel[2]][0]/255.0,CCOR[sel[0]][sel[1]][sel[2]][1]/255.0,CCOR[sel[0]][sel[1]][sel[2]][2]/255.0); [colorPanel setColor:set]; return self; } // When printing redraw must be set to 3 so an image isn't printed -printPSCode:sender { dsel=2; /* 1 color per circle */ [super printPSCode:sender]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.