Xmipp  v3.23.11-Nereus
Macros | Typedefs | Functions
xvsmooth.cpp File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "xmipp_error.h"
Include dependency graph for xvsmooth.cpp:

Go to the source code of this file.

Macros

#define RANGE(a, b, c)   { if (a < b) a = b; if (a > c) a = c; }
 
#define xvbzero(s, l)   memset(s, 0, l)
 

Typedefs

typedef unsigned char byte
 

Functions

byteSmooth (byte *picSrc8, size_t swide, size_t shigh, size_t dwide, size_t dhigh)
 
void DoColorDither (byte *picSmooth, byte *&picDithered, size_t w, size_t h)
 
int SmoothXY ()
 
void SmoothResize (byte *picSrc8, byte *destpic8, size_t swide, size_t shigh, size_t dwide, size_t dhigh)
 
int SmoothXY (byte *picSmooth, byte *picSrc8, int swide, int shigh, int dwide, int dhigh)
 

Macro Definition Documentation

◆ RANGE

#define RANGE (   a,
  b,
  c 
)    { if (a < b) a = b; if (a > c) a = c; }

Definition at line 72 of file xvsmooth.cpp.

◆ xvbzero

#define xvbzero (   s,
 
)    memset(s, 0, l)

Definition at line 91 of file xvsmooth.cpp.

Typedef Documentation

◆ byte

typedef unsigned char byte

Definition at line 73 of file xvsmooth.cpp.

Function Documentation

◆ DoColorDither()

void DoColorDither ( byte picSmooth,
byte *&  picDithered,
size_t  w,
size_t  h 
)

Definition at line 297 of file xvsmooth.cpp.

297  {
298  /* takes a 24 bit picture, of size w*h, dithers with the colors in
299  rdisp, gdisp, bdisp (which have already been allocated),
300  and generates an 8-bit w*h image, which it returns.
301  ignores input value 'pic8'
302  returns NULL on error
303 
304  note: the rdisp,gdisp,bdisp arrays should be the 'displayed' colors,
305  not the 'desired' colors
306 
307  if picSrc is NULL, uses the passed-in pic8 (an 8-bit image) as
308  the source, and the rmap,gmap,bmap arrays as the desired colors */
309 
310  byte *np, *ep;
311  short *cache;
312  int r2;
313  int *thisline, *nextline, *thisptr, *nextptr, *tmpptr;
314  size_t i, j;
315  int rerr;
316  size_t imax, jmax;
317  int key;
318  long cnt1, cnt2;
319 
320  cnt1 = cnt2 = 0;
321  imax = h - 1;
322  jmax = w - 1;
323  ep = picSmooth;
324 
325  /* attempt to malloc things */
326  cache = (short *) calloc(2 << 14, sizeof(short));
327  thisline = (int *) malloc(w * sizeof(int));
328  nextline = (int *) malloc(w * sizeof(int));
329  if (!cache || !picDithered || !thisline || !nextline)
330  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Cannot allocate memory for smoothing");
331 
332  np = picDithered;
333 
334  /* get first line of picture */
335 
336  for (j = w, tmpptr = nextline; j; j--, ep++)
337  *tmpptr++ = (int) *ep;
338 
339  for (i = 0; i < h; i++) {
340  np = picDithered + i * w;
341  tmpptr = thisline;
342  thisline = nextline;
343  nextline = tmpptr; /* swap */
344 
345  if (i != imax)
346  for (j = w, tmpptr = nextline; j; j--, ep++)
347  *tmpptr++ = (int) *ep;
348 
349  /* dither a line, doing odd-lines right-to-left (serpentine) */
350  thisptr = (i & 1) ? thisline + w - 1 : thisline;
351  nextptr = (i & 1) ? nextline + w - 1 : nextline;
352  if (i & 1)
353  np += w - 1;
354 
355  for (j = 0; j < w; j++) {
356  int k, d, mind, closest;
357 
358  r2 = *thisptr;
359  if (i & 1)
360  thisptr -= 1; /* move left */
361  else
362  thisptr += 1; /* move right */
363 
364  if (r2 < 0)
365  r2 = 0;
366 
367  if (r2 > 255)
368  r2 = 255;
369  key = ((r2 & 0xf8) << 6) | ((r2 & 0xf8) << 1) | (r2 >> 4);
370  /*
371  const int maxKey=2 << 14;
372  if (key >= maxKey)
373  REPORT_ERROR(ERR_INDEX_OUTOFBOUNDS,
374  "overflow in DoColorDither");
375  */
376 
377  if (cache[key]) {
378  *np = (byte) (cache[key] - 1);
379  cnt1++;
380  } else {
381  /* not in cache, have to search the colortable */
382  cnt2++;
383 
384  mind = 10000;
385  for (k = closest = 0; k < 256 && mind > 7; k++) {
386  d = 3*abs(r2 - k);
387  if (d < mind) {
388  mind = d;
389  closest = k;
390  }
391  }
392  cache[key] = closest + 1;
393  *np = closest;
394  }
395 
396  /* propagate the error */
397  rerr = r2 - *np;
398 
399  if (j != jmax) { /* adjust LEFT/RIGHT pixel */
400  int rerr_2 = rerr / 2;
401  thisptr[0] += rerr_2;
402  rerr -= rerr_2;
403  }
404 
405  if (i != imax) { /* adjust BOTTOM pixel */
406  nextptr[0] += rerr; /* possibly all err if we're at l/r edge */
407  }
408 
409  if (i & 1) {
410  nextptr -= 1;
411  np--;
412  } else {
413  nextptr += 1;
414  np++;
415  }
416  }
417  }
418 
419  free(thisline);
420  free(nextline);
421  free(cache);
422 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
There is not enough memory for allocation.
Definition: xmipp_error.h:166
doublereal * w
void abs(Image< double > &op)
#define i
ql0001_ & k(htemp+1),(cvec+1),(atemp+1),(bj+1),(bl+1),(bu+1),(x+1),(clamda+1), &iout, infoqp, &zero,(w+1), &lenw,(iw+1), &leniw, &glob_grd.epsmac
doublereal * d
free((char *) ob)
#define j
unsigned char byte
Definition: xvsmooth.cpp:73
float r2

◆ Smooth()

byte * Smooth ( byte picSrc8,
size_t  swide,
size_t  shigh,
size_t  dwide,
size_t  dhigh 
)

Definition at line 108 of file xvsmooth.cpp.

108  {
109  /* does a SMOOTH resize from pic824 (which is either a swide*shigh, 8-bit
110  pic, with colormap rmap,gmap,bmap OR a swide*shigh, 24-bit image, based
111  on whether 'is24' is set) into a dwide * dhigh 24-bit image
112 
113  returns a dwide*dhigh 24bit image, or NULL on failure (malloc) */
114  /* rmap,gmap,bmap should be 'desired' colors */
115 
116  byte *picSmooth, *ptrPicSmooth;
117  int *cxtab, *pxtab;
118  size_t y1Off, cyOff;
119  size_t ex, ey, cx, cy, px, py, apx, apy, apx_100, apy_100, x1, y1;
120  size_t cA, cB, cC, cD;
121  size_t pA, pB, pC, pD;
122  int retval;
123 
124  cA = cB = cC = cD = 0;
125  size_t picSmoothSize = ((size_t) dwide) * dhigh;
126  ptrPicSmooth = picSmooth = (byte *) malloc(picSmoothSize);
127  if (!picSmooth)
129  formatString("Unable to alloc: %lu",picSmoothSize));
130 
131  /* decide which smoothing routine to use based on type of expansion */
132  if (dwide < swide && dhigh < shigh)
133  retval = SmoothXY(picSmooth, picSrc8, swide, shigh, dwide, dhigh);
134  else {
135  /* dwide >= swide && dhigh >= shigh */
136 
137  /* cx,cy = original pixel in pic824. px,py = relative position
138  of pixel ex,ey inside of cx,cy as percentages +-50%, +-50%.
139  0,0 = middle of pixel */
140 
141  /* we can save a lot of time by precomputing cxtab[] and pxtab[], both
142  dwide arrays of ints that contain values for the equations:
143  cx = (ex * swide) / dwide;
144  px = ((ex * swide * 100) / dwide) - (cx * 100) - 50; */
145 
146  cxtab = (int *) malloc(dwide * sizeof(int));
147  if (!cxtab)
148  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Unable to alloc for smoothing");
149 
150  pxtab = (int *) malloc(dwide * sizeof(int));
151  if (!pxtab)
152  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Unable to alloc for smoothing");
153 
154  for (ex = 0; ex < dwide; ex++) {
155  cxtab[ex] = (ex * swide) / dwide;
156  pxtab[ex] = (((ex * swide) * 100) / dwide) - (cxtab[ex] * 100) - 50;
157  }
158 
159  for (ey = 0; ey < dhigh; ey++) {
160  cy = (ey * shigh) / dhigh;
161  py = (((ey * shigh) * 100) / dhigh) - (cy * 100) - 50;
162  if (py < 0) {
163  y1 = cy - 1;
164  if (y1 < 0)
165  y1 = 0;
166  } else {
167  y1 = cy + 1;
168  if (y1 > shigh - 1)
169  y1 = shigh - 1;
170  }
171  apy = abs((int) py);//apy = abs(py);
172  apy_100 = 100 - apy;
173 
174  cyOff = (size_t) cy * swide; /* current line */
175  y1Off = (size_t) y1 * swide; /* up or down one line, depending */
176 
177  /* if ((ey&15) == 0) WaitCursor(); */
178 
179  for (ex = 0; ex < dwide; ex++) {
180  cx = cxtab[ex];
181  px = pxtab[ex];
182 
183  if (px < 0) {
184  x1 = cx - 1;
185  if (x1 < 0)
186  x1 = 0;
187  } else {
188  x1 = cx + 1;
189  if (x1 > swide - 1)
190  x1 = swide - 1;
191  }
192 
193  cA = picSrc8[y1Off + x1]; /* corner pixel */
194  cB = picSrc8[y1Off + cx]; /* up/down center pixel */
195  cC = picSrc8[cyOff + x1]; /* left/right center pixel */
196  cD = picSrc8[cyOff + cx]; /* center pixel */
197 
198  /* quick check */
199  if (cA == cB && cB == cC && cC == cD)
200  /* set this pixel to the same color as in pic8 */
201  *ptrPicSmooth++ = cD;
202  else {
203  /* compute weighting factors */
204  apx = abs((int) px);//apx = abs(px);
205  apx_100 = 100 - apx;
206  pA = apx * apy;
207  pB = apy * apx_100;
208  pC = apx * apy_100;
209  pD = apx_100*apy_100;
210 
211  byte val = (byte) (((pA * cA) + (pB * cB) + (pC * cC) + (pD * cD)) / 10000);
212  *ptrPicSmooth++ = val;
213  }
214  }
215  }
216 
217  free(cxtab);
218  free(pxtab);
219  retval = 0; /* okay */
220  }
221 
222  if (retval) { /* one of the Smooth**() methods failed */
223  free(picSmooth);
224  picSmooth = (byte *) NULL;
225  }
226 
227  return picSmooth;
228 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
int SmoothXY()
There is not enough memory for allocation.
Definition: xmipp_error.h:166
void abs(Image< double > &op)
free((char *) ob)
unsigned char byte
Definition: xvsmooth.cpp:73
String formatString(const char *format,...)

◆ SmoothXY() [1/2]

int SmoothXY ( )

◆ SmoothXY() [2/2]

int SmoothXY ( byte picSmooth,
byte picSrc8,
int  swide,
int  shigh,
int  dwide,
int  dhigh 
)

Definition at line 231 of file xvsmooth.cpp.

232  {
233  byte *cptr;
234  int i, j;
235  int *lbuf;
236  int pix;
237  int lastline, thisline, lastpix, linecnt, pixcnt;
238  int *pixarr, *paptr;
239 
240  /* returns '0' if okay, '1' if failed (malloc) */
241 
242  /* shrinks pic8 into a dwide * dhigh 24-bit picture. Only works correctly
243  when swide>=dwide and shigh>=dhigh (ie, the picture is shrunk on both
244  axes) */
245 
246  /* malloc some arrays */
247  lbuf = (int *) calloc(swide, sizeof(int));
248  pixarr = (int *) calloc(swide + 1, sizeof(int));
249  if (!lbuf || !pixarr)
250  REPORT_ERROR(ERR_MEM_NOTENOUGH, "Cannot allocate memory for smoothing");
251 
252  for (j = 0; j <= swide; j++)
253  pixarr[j] = (j * dwide + (15 * swide) / 16) / swide;
254 
255  lastline = linecnt = pix = 0;
256  cptr = picSrc8;
257 
258  for (i = 0; i <= shigh; i++) {
259  thisline = (i * dhigh + (15 * shigh) / 16) / shigh;
260 
261  if ((thisline != lastline)) {
262  pix = pixcnt = lastpix = 0;
263 
264  for (j = 0, paptr = pixarr; j <= swide; j++, paptr++) {
265  if (*paptr != lastpix) { /* write a pixel to pic24 */
266  *picSmooth++ = (pix / linecnt) / pixcnt;
267  lastpix = *paptr;
268  pix = pixcnt = 0;
269  }
270 
271  if (j < swide) {
272  pix += lbuf[j];
273  pixcnt++;
274  }
275  }
276 
277  lastline = thisline;
278  xvbzero((char *) lbuf, swide * sizeof(int));
279  /* clear out line bufs */
280  linecnt = 0;
281  }
282 
283  if (i < shigh) {
284  for (j = 0; j < swide; j++, cptr++)
285  lbuf[j] += *cptr;
286 
287  linecnt++;
288  }
289  }
290 
291  free(lbuf);
292  free(pixarr);
293  return 0;
294 }
#define REPORT_ERROR(nerr, ErrormMsg)
Definition: xmipp_error.h:211
There is not enough memory for allocation.
Definition: xmipp_error.h:166
#define i
free((char *) ob)
#define xvbzero(s, l)
Definition: xvsmooth.cpp:91
#define j
unsigned char byte
Definition: xvsmooth.cpp:73