File: smooth.c

package info (click to toggle)
xli 1.17.0+20061110-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 1,540 kB
  • sloc: ansic: 25,840; makefile: 11
file content (129 lines) | stat: -rw-r--r-- 3,636 bytes parent folder | download | duplicates (6)
1
2
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
51
52
53
54
55
56
57
58
59
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/* #ident	"@(#)x11:contrib/clients/xloadimage/smooth.c 1.10 94/07/29 Labtam" */
/* smooth.c:
 *
 * this performs a smoothing convolution using a 3x3 area.
 *
 * jim frost 09.20.90
 *
 * Copyright 1990, 1991 Jim Frost.
 * See included file "copyright.h" for complete copyright information.
 */

#include "copyright.h"
#include "xli.h"

static Image *doSmooth(Image *isrc)
{ Image *src = isrc, *dest, *tmp;
  int    x, y, x1, y1, linelen;
  int    xindex[3];
  byte  *yindex[3];
  byte  *srcptr, *destptr;
  unsigned long avgred, avggreen, avgblue;

  /* build true color image from old image and allocate new image
   */

  tmp= expandtotrue(src);
  if (src != tmp && src != isrc)
    freeImage(src);
  src = tmp;

  dest= newTrueImage(src->width, src->height);
  dest->title= (char *)lmalloc(strlen(src->title) + 12);
  sprintf(dest->title, "%s (smoothed)", src->title);
  dest->gamma= src->gamma;

  /* run through src and take a guess as to what the color should
   * actually be.
   */

  destptr= dest->data;
  linelen= src->pixlen * src->width;
  if(dest->pixlen == 3 && src->pixlen == 3) {	/* usual case */
    for (y= 0; y < src->height; y++) {
      yindex[1]= src->data + (y * linelen);
      yindex[0]= yindex[1] - (y > 0 ? linelen : 0);
      yindex[2]= yindex[1] + (y < src->height - 1 ? linelen : 0);
      for (x= 0; x < src->width; x++) {
        avgred= avggreen= avgblue= 0;
        xindex[1]= x * 3;
        xindex[0]= xindex[1] - (x > 0 ? 3 : 0);
        xindex[2]= xindex[1] + (x < src->width - 1 ? 3 : 0);
        for (y1= 0; y1 < 3; y1++) {
          for (x1= 0; x1 < 3; x1++) {
            srcptr = yindex[y1] + xindex[x1];
            avgred += *srcptr;
            avggreen += *(srcptr + 1);
            avgblue += *(srcptr + 2);
          }
        }
  
        /* average the pixel values
         */
  
        *destptr++ = ((avgred + 8) / 9);
        *destptr++ = ((avggreen + 8) / 9);
        *destptr++ = ((avgblue + 8) / 9);
      }
    }
  } else {	/* less usual */
    Pixel  pixval;
    for (y= 0; y < src->height; y++) {
      yindex[1]= src->data + (y * linelen);
      yindex[0]= yindex[1] - (y > 0 ? linelen : 0);
      yindex[2]= yindex[1] + (y < src->height - 1 ? linelen : 0);
      for (x= 0; x < src->width; x++) {
        avgred= avggreen= avgblue= 0;
        xindex[1]= x * src->pixlen;
        xindex[0]= xindex[1] - (x > 0 ? src->pixlen : 0);
        xindex[2]= xindex[1] + (x < src->width - 1 ? src->pixlen : 0);
        for (y1= 0; y1 < 3; y1++) {
          for (x1= 0; x1 < 3; x1++) {
            pixval= memToVal(yindex[y1] + xindex[x1], src->pixlen);
            avgred += TRUE_RED(pixval);
            avggreen += TRUE_GREEN(pixval);
            avgblue += TRUE_BLUE(pixval);
          }
        }
  
        /* average the pixel values
         */
  
        avgred= ((avgred + 8) / 9);
        avggreen= ((avggreen + 8) / 9);
        avgblue= ((avgblue + 8) / 9);
        pixval= (avgred << 16) | (avggreen << 8) | avgblue;
        valToMem(pixval, destptr, dest->pixlen);
        destptr += dest->pixlen;
      }
    }
  }
  if (src != isrc)	/* Free possible intermediate image */
    freeImage(src);
  return(dest);
}

Image *smooth(Image *isrc, int iterations, int verbose)
{ int a;
  Image *src=isrc,*tmp;

  if(GAMMA_NOT_EQUAL(src->gamma, 1.0))
    gammacorrect(src, 1.0, verbose);

  if (verbose) {
    printf("  Smoothing...");
    fflush(stdout);
  }

  for (a= 0; a < iterations; a++) {
    tmp= doSmooth(src);
    if(src != tmp && src != isrc)	/* free imtermediate image */
      freeImage(src);
    src= tmp;
  }

  if (verbose)
    printf("done\n");

  return(src);
}