/* --------------- main.c Time-stamp: <06 Dec 96 -- 14:20:16 siome> Dith - Special Dither of image pieces Siome Klein Goldenstein ---------------- */ /* the following declare allows the program to compile and work with different version of TK (4.0 for Red Hat 3.0.3 and 4.1 for Red Hat 4.0 for example) */ #define TK_IS_40 0 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #if TK_IS_40 #include <tcl/tcl.h> #include <tcl/tk.h> #else #include <tcl.h> #include <tk.h> #endif #include "dither.h" int flx, frx, fuy, fdy; int ftx, fty; double *filter; #if TK_IS_40 static Tk_Window mainWindow;a #endif int main (int argc, char **argv) { Tcl_Interp *interp; char s[100]; #if TK_IS_40 static char *display = NULL; #endif if (argc != 2) { fprintf(stderr, "%s: wrong number of arguments\n", argv[0]); exit (1); } /* Here begins the first step on C and TCL integration: The Tcl/Tk initialization. Notice that mainWindow is global variable */ interp = Tcl_CreateInterp(); #if TK_IS_40 mainWindow = Tk_CreateMainWindow(interp, display, argv[0], "Tk"); if (mainWindow == NULL) { fprintf(stderr, "%s\n", interp->result); exit(1); } #endif if (Tcl_Init(interp) == TCL_ERROR) { fprintf(stderr, "Tcl_Init failed: %s\n", interp->result); exit (1); } if (Tk_Init(interp) == TCL_ERROR) { fprintf(stderr, "Tk_Init failed: %s\n", interp->result); exit (1); } /* The second step, creation of your Tcl commands. The creation of a similar initialization routine is just to keep the same style. */ if (Dith_Init(interp) == TCL_ERROR) { fprintf(stderr,"Recon_Init failed: %s\n", interp->result); exit(1); } /* Now we create the original image and ask TCL to evaluate our "interface description" file. */ sprintf(s, "image create photo original -file %s\n", argv[1]); Tcl_GlobalEval (interp,s); Tcl_EvalFile (interp,"./int-dither.tcl";<\n>) /* Finally, we let Tk take care of main loop */ Tk_MainLoop(); return (0); } /* The initalization Routine */ int Dith_Init (Tcl_Interp *interp) { Tcl_CreateCommand (interp, "CDith", Dith_cdither, (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL); return TCL_OK; } int Dith_cdither (ClientData cd, Tcl_Interp *interp, int argc, char **argv) Tk_PhotoHandle todith; Tk_PhotoImageBlock blorig, blnew; int tx, ty; int step; int x, y, i; int ct; double intens; /* get the image handle */ todith = Tk_FindPhoto (argv[1]); /* get the vertical size of dithering cluster */ step = atoi (argv[2]); /* Obtain the image itself from the handle */ Tk_PhotoGetSize (todith, &tx, &ty); Tk_PhotoGetImage (todith, &blorig); /* Create new "image" for placing the dither */ blnew.width = tx; blnew.height = ty; blnew.pitch = tx; blnew.pixelSize = 1; blnew.offset[0] = 0; blnew.offset[1] = 0; blnew.offset[2] = 0; if ( (blnew.pixelPtr = (unsigned char*) calloc (tx * ty, sizeof (unsigned char)))== NULL) { fprintf (stderr, "Error in memory allocation\n"); exit (1); } for (y=step-1; y<ty; y+=step) { for (x=0; x<tx; x++) { for (intens=0.0, ct = 0; ct< step; ct++) intens += ( RED(&blorig,x,y-ct) + GREEN(&blorig,x,y-ct) + BLUE(&blorig,x,y-ct) ) / 3.0; intens /= (255.0 * step); i = rint(intens * (step-2)) + 1; for (ct=0; ct < (i/2); ct++) { /* for the sake of clarity, no optimization is done */ RED(&blnew, x, y-step+1+ct) = 255; RED(&blnew, x, y-ct) = 255; } if (i%2) RED(&blnew, x, y-step+1+(i/2)) = 255; } } Tk_PhotoPutBlock (todith,&blnew,0,0,tx,ty); free (blnew.pixelPtr); return TCL_OK; }