⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 halfadap.c

📁 [Game.Programming].Academic - Graphics Gems (6 books source code)
💻 C
字号:
/*==========================================================================* * Halftoning using Space Filling Curve with adaptive clustering and        * * selective precipitation                                                  * *                                                                          * * Limitation:                                                              * * Only process image with size 2^n x 2^n where n is positive integer.      * *==========================================================================*/#include <stdio.h>#include <stdlib.h>unsigned char **path;	   /* space filling curve path *//* * path[] is a global array storing the information to move along *        the space filling curve. * genspacefill() is a function to generate the information in path[]. *        This function is implemented based on a gem in Graphics Gems II, *        Ken Musgrave, "A Peano Curve Generation Algorithm". * move() is a macro to move along the space filling curve using the *        the information stored in path[]. */extern genspacefill();#define TRUE    1#define FALSE   0#define BLACK   255#define WHITE   0#define LEFT    0#define RIGHT   1#define UP      2#define DOWN    3#define END     255#define move(x,y)  switch (path[x][y])          \                   {                            \                     case UP:   y++; break;     \                     case DOWN: y--; break;     \                     case LEFT: x--; break;     \                     case RIGHT:x++; break;     \                   }/* * Description of parameters: *   picture,         2D array holding the grayscale image. *   out,             2D array holding the dithered image. *   maxclustersize,  Max cluster size, N. *   thresh,          Edge detection threshold T. *   do_sp,           Flag to switch on/off selective precipitation. *                    To switch off the selective precipitation, *                    set do_sp = FALSE. *   do_ac,           Flag to switch on/off adaptive clustering. *                    To switch off the adaptive clustering, set do_ac=FALSE */void spacefilterwindow(int **picture, int **out, int maxclustersize,                       int thresh, char do_sp, char do_ac){  char edge;             /* Flag indicate sudden change detected */  char ending; 	         /* flag indicates end of space filling curve */  int accumulator;       /* Accumulate gray value */  int currclustersize;   /* Record size of current cluster */  int frontx, fronty;    /* Pointer to the front of the cluster */  int windowx, windowy;  /* Pointer to first pixel applied with filter */  int clusterx, clustery;/* Pointer to first pixel in current cluster */  int windowlen;         /* Size of the moving window */  int winsum;            /* Current moving window's sum */  int maxsum;            /* Maximum moving window's sum recorded */  int rightplace;        /* Position of the moving window with max sum */  int *cluster;          /* An array hold the pixel of current cluster */  int last, i, tempx, tempy, currx, curry;    /* temp variables */  long filter[7] = {-1, -5, 0, 13, 0, -5, -1};  /* 1D -ve Lap. Gauss. filter */  long convolution;      /* Convolution value in this turn */  long lastconvolution;  /* Convolution value in last turn */  /*   * Description of the pointer along the space filling curve.   *   * clusterx,                          windowx,    currx,     frontx,   * clustery                           windowy     curry      fronty   *    |                                  |          |           |   *    v                                  v          v           v   *   +----------------------------------------------------------+   *   |                        Cluster                           |   *   +----------------------------------------------------------+   *                                       |                      |   *                                       |                      |   *                                       |          /\          |   *                                       |        /    \        |   *                                       |___   /        \   ___|   *                                       |    \/           \/   |   *                                  -ve Laplacian of Gaussian Filter   */  if ((cluster=(int*)malloc(sizeof(int)*maxclustersize))==NULL)  {    fprintf(stderr,"not enough memory for cluster\n");    return;  }  genspacefill();    /* generates the spacefilling path */    convolution=0;  currclustersize=0;  accumulator=0;  for (frontx=0, fronty=0, i=0 ; i<7 ; i++)  {    if (i<3)    {      cluster[currclustersize] = picture[frontx][fronty];      accumulator += cluster[currclustersize];      currclustersize++;    }    if (i==3)    {  currx = frontx;  curry = fronty;  }    convolution += filter[i]*(long)(picture[frontx][fronty]);    move(frontx,fronty);  /* assume the image at least has 7 pixels */  }  lastconvolution = convolution;  clusterx=0;   clustery=0;  windowx=0;    windowy=0;  edge=FALSE;  ending=FALSE;  while (TRUE)  {    if (do_ac) /* switch on/off adaptive clustering */    {      /* do convolution */      convolution = 0;      for (tempx=windowx, tempy=windowy, i=0 ; i<7 ; i++)      {        convolution += filter[i]*picture[tempx][tempy];        move(tempx,tempy);      }      /* detect sudden change */      if ( (convolution >= 0 && lastconvolution <=0             && abs(convolution-lastconvolution)>thresh)         ||(convolution <= 0  && lastconvolution >=0             && abs(convolution-lastconvolution)>thresh))         edge=TRUE; /* force output dots */    }        /* Output dots if necessary */    if (edge || currclustersize >= maxclustersize || ending)    {      edge=FALSE;            /* Search the best position within cluster to precipitate */      rightplace = 0;      if (do_sp) /* switch on/off selective precipitation */      {        windowlen = accumulator/BLACK;        winsum = 0;        for (i=0; i<windowlen; i++)          winsum += cluster[i];        for (maxsum=winsum, last=0; i<currclustersize; i++, last++)        {          winsum+= cluster[i] - cluster[last];          if (winsum > maxsum)          {            rightplace=last+1;            maxsum=winsum;          }        }      }      /* Output dots */      for (i=0 ; currclustersize!=0 ; currclustersize--, i++)      {        if (accumulator>=BLACK && i>=rightplace)  /* precipitates */        {          out[clusterx][clustery]=BLACK;          accumulator-=BLACK;        }        else          out[clusterx][clustery]=WHITE;        move(clusterx,clustery)      } /* for */      if (ending)        break;    } /* if */    cluster[currclustersize] = picture[currx][curry];    accumulator += cluster[currclustersize];    currclustersize++;    if (path[currx][curry]==END)      ending = TRUE;    move(currx,curry);    move(windowx,windowy);    move(frontx,fronty);  } /* while */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -