Listing 1
/*
---------------
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;
}
Copyright © 1994 - 2019 Linux Journal. All rights reserved.