w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

graphics.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  - This software is distributed in the hope that it will be
4  - useful, but with NO WARRANTY OF ANY KIND.
5  - No author or distributor accepts responsibility to anyone for the
6  - consequences of using this software, or for whether it serves any
7  - particular purpose or works at all, unless he or she says so in
8  - writing. Everyone is granted permission to copy, modify and
9  - redistribute this source code, for commercial or non-commercial
10  - purposes, with the following restrictions: (1) the origin of this
11  - source code must not be misrepresented; (2) modified versions must
12  - be plainly marked as such; and (3) this notice may not be removed
13  - or altered from any source or modified source distribution.
14  *====================================================================*/
15 
16 /*
17  * graphics.c
18  *
19  * Pta generation for arbitrary shapes built with lines
20  *
21  * PTA *ptaGenerateLine()
22  * PTA *ptaGenerateWideLine()
23  * PTA *ptaGenerateBox()
24  * PTA *ptaGenerateBoxa()
25  * PTA *ptaGeneratePolyline()
26  *
27  * Pta rendering
28  *
29  * l_int32 pixRenderPta()
30  * l_int32 pixRenderPtaArb()
31  * l_int32 pixRenderPtaBlend()
32  *
33  * Rendering of arbitrary shapes built with lines
34  *
35  * l_int32 pixRenderLine()
36  * l_int32 pixRenderLineArb()
37  * l_int32 pixRenderLineBlend()
38  *
39  * l_int32 pixRenderBox()
40  * l_int32 pixRenderBoxArb()
41  * l_int32 pixRenderBoxBlend()
42  *
43  * l_int32 pixRenderBoxa()
44  * l_int32 pixRenderBoxaArb()
45  * l_int32 pixRenderBoxaBlend()
46  *
47  * l_int32 pixRenderPolyline()
48  * l_int32 pixRenderPolylineArb()
49  * l_int32 pixRenderPolylineBlend()
50  *
51  * Contour rendering on grayscale images
52  *
53  * PIX *pixRenderContours()
54  *
55  * The line rendering functions are relatively crude, but they
56  * get the job done for most simple situations. We use the pta
57  * as an intermediate data structure. A pta is generated
58  * for a line. One of two rendering functions are used to
59  * render this onto a Pix.
60  */
61 
62 #include <stdio.h>
63 #include <string.h>
64 #include <math.h>
65 #include "allheaders.h"
66 
67 
68 
69 /*------------------------------------------------------------------*
70  * Pta generation for arbitrary shapes built with lines *
71  *------------------------------------------------------------------*/
72 /*!
73  * ptaGenerateLine()
74  *
75  * Input: x1, y1 (end point 1)
76  * x2, y2 (end point 2)
77  * Return: pta, or null on error
78  */
79 PTA *
81  l_int32 y1,
82  l_int32 x2,
83  l_int32 y2)
84 {
85 l_int32 npts, diff, getyofx, sign, i, x, y;
86 l_float32 slope;
87 PTA *pta;
88 
89  PROCNAME("ptaGenerateLine");
90 
91  /* generate line parameters */
92  if (L_ABS(x2 - x1) >= L_ABS(y2 - y1)) {
93  getyofx = TRUE;
94  npts = L_ABS(x2 - x1) + 1;
95  diff = x2 - x1;
96  sign = L_SIGN(x2 - x1);
97  slope = (l_float32)(sign * (y2 - y1)) / (l_float32)diff;
98  }
99  else {
100  getyofx = FALSE;
101  npts = L_ABS(y2 - y1) + 1;
102  diff = y2 - y1;
103  sign = L_SIGN(y2 - y1);
104  slope = (l_float32)(sign * (x2 - x1)) / (l_float32)diff;
105  }
106 
107  if ((pta = ptaCreate(npts)) == NULL)
108  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
109 
110  if (npts == 1) { /* degenerate case */
111  ptaAddPt(pta, x1, y1);
112  return pta;
113  }
114 
115  /* generate the set of points */
116  if (getyofx) { /* y = y(x) */
117  for (i = 0; i < npts; i++) {
118  x = x1 + sign * i;
119  y = (l_int32)(y1 + (l_float32)i * slope + 0.5);
120  ptaAddPt(pta, x, y);
121  }
122  }
123  else { /* x = x(y) */
124  for (i = 0; i < npts; i++) {
125  x = (l_int32)(x1 + (l_float32)i * slope + 0.5);
126  y = y1 + sign * i;
127  ptaAddPt(pta, x, y);
128  }
129  }
130 
131  return pta;
132 }
133 
134 
135 /*!
136  * ptaGenerateWideLine()
137  *
138  * Input: x1, y1 (end point 1)
139  * x2, y2 (end point 2)
140  * Return: ptaj, or null on error
141  */
142 PTA *
144  l_int32 y1,
145  l_int32 x2,
146  l_int32 y2,
147  l_int32 width)
148 {
149 l_int32 i, x1a, x2a, y1a, y2a;
150 PTA *pta, *ptaj;
151 
152  PROCNAME("ptaGenerateWideLine");
153 
154  if (width < 1) {
155  L_WARNING("width < 1; setting to 1", procName);
156  width = 1;
157  }
158 
159  if ((ptaj = ptaGenerateLine(x1, y1, x2, y2)) == NULL)
160  return (PTA *)ERROR_PTR("ptaj not made", procName, NULL);
161  if (width == 1)
162  return ptaj;
163 
164  /* width > 1; estimate line direction & join */
165  if (L_ABS(x1 - x2) > L_ABS(y1 - y2)) { /* "horizontal" line */
166  for (i = 1; i < width; i++) {
167  if ((i & 1) == 1) { /* place above */
168  y1a = y1 - (i + 1) / 2;
169  y2a = y2 - (i + 1) / 2;
170  }
171  else { /* place below */
172  y1a = y1 + (i + 1) / 2;
173  y2a = y2 + (i + 1) / 2;
174  }
175  if ((pta = ptaGenerateLine(x1, y1a, x2, y2a)) == NULL)
176  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
177  ptaJoin(ptaj, pta, 0, 0);
178  ptaDestroy(&pta);
179  }
180  }
181  else { /* "vertical" line */
182  for (i = 1; i < width; i++) {
183  if ((i & 1) == 1) { /* place to left */
184  x1a = x1 - (i + 1) / 2;
185  x2a = x2 - (i + 1) / 2;
186  }
187  else { /* place to right */
188  x1a = x1 + (i + 1) / 2;
189  x2a = x2 + (i + 1) / 2;
190  }
191  if ((pta = ptaGenerateLine(x1a, y1, x2a, y2)) == NULL)
192  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
193  ptaJoin(ptaj, pta, 0, 0);
194  ptaDestroy(&pta);
195  }
196  }
197 
198  return ptaj;
199 }
200 
201 
202 /*!
203  * ptaGenerateBox()
204  *
205  * Input: box
206  * width
207  * Return: ptad, or null on error
208  *
209  * Notes:
210  * (1) Because the box is constructed so that we don't have any
211  * overlapping lines, there is no need to remove duplicates.
212  */
213 PTA *
215  l_int32 width)
216 {
217 l_int32 x, y, w, h;
218 PTA *ptad, *pta;
219 
220  PROCNAME("ptaGenerateBox");
221 
222  if (!box)
223  return (PTA *)ERROR_PTR("box not defined", procName, NULL);
224 
225  /* Generate line points and add them to the pta. */
226  x = box->x;
227  y = box->y;
228  w = box->w;
229  h = box->h;
230  ptad = ptaCreate(0);
231  if ((width & 1) == 1) { /* odd width */
232  pta = ptaGenerateWideLine(x - width / 2, y,
233  x + w - 1 + width / 2, y, width);
234  ptaJoin(ptad, pta, 0, 0);
235  ptaDestroy(&pta);
236  pta = ptaGenerateWideLine(x - width / 2, y + h - 1,
237  x + w - 1 + width / 2, y + h - 1, width);
238  ptaJoin(ptad, pta, 0, 0);
239  ptaDestroy(&pta);
240  pta = ptaGenerateWideLine(x, y + 1 + width / 2,
241  x, y + h - 2 - width / 2, width);
242  ptaJoin(ptad, pta, 0, 0);
243  ptaDestroy(&pta);
244  pta = ptaGenerateWideLine(x + w - 1, y + 1 + width / 2,
245  x + w - 1, y + h - 2 - width / 2, width);
246  ptaJoin(ptad, pta, 0, 0);
247  ptaDestroy(&pta);
248  }
249  else { /* even width */
250  pta = ptaGenerateWideLine(x - width / 2, y,
251  x + w - 2 + width / 2, y, width);
252  ptaJoin(ptad, pta, 0, 0);
253  ptaDestroy(&pta);
254  pta = ptaGenerateWideLine(x - width / 2, y + h - 1,
255  x + w - 2 + width / 2, y + h - 1, width);
256  ptaJoin(ptad, pta, 0, 0);
257  ptaDestroy(&pta);
258  pta = ptaGenerateWideLine(x, y + 0 + width / 2,
259  x, y + h - 2 - width / 2, width);
260  ptaJoin(ptad, pta, 0, 0);
261  ptaDestroy(&pta);
262  pta = ptaGenerateWideLine(x + w - 1, y + 0 + width / 2,
263  x + w - 1, y + h - 2 - width / 2, width);
264  ptaJoin(ptad, pta, 0, 0);
265  ptaDestroy(&pta);
266  }
267 
268  return ptad;
269 }
270 
271 
272 /*!
273  * ptaGenerateBoxa()
274  *
275  * Input: boxa
276  * width
277  * removedups (1 to remove, 0 to leave)
278  * Return: ptad, or null on error
279  *
280  * Notes:
281  * (1) If the boxa has overlapping boxes, and if blending will
282  * be used to give a transparent effect, transparency
283  * artifacts at line intersections can be removed using
284  * removedups = 1.
285  */
286 PTA *
288  l_int32 width,
289  l_int32 removedups)
290 {
291 l_int32 i, n;
292 BOX *box;
293 PTA *ptad, *ptat, *pta;
294 
295  PROCNAME("ptaGenerateBoxa");
296 
297  if (!boxa)
298  return (PTA *)ERROR_PTR("boxa not defined", procName, NULL);
299 
300  n = boxaGetCount(boxa);
301  ptat = ptaCreate(0);
302  for (i = 0; i < n; i++) {
303  box = boxaGetBox(boxa, i, L_CLONE);
304  pta = ptaGenerateBox(box, width);
305  ptaJoin(ptat, pta, 0, 0);
306  ptaDestroy(&pta);
307  boxDestroy(&box);
308  }
309 
310  if (removedups)
311  ptad = ptaRemoveDuplicates(ptat, 0);
312  else
313  ptad = ptaClone(ptat);
314 
315  ptaDestroy(&ptat);
316  return ptad;
317 }
318 
319 
320 /*!
321  * ptaGeneratePolyline()
322  *
323  * Input: pta (vertices of polyline)
324  * width
325  * removedups (1 to remove, 0 to leave)
326  * Return: ptad, or null on error
327  *
328  * Notes:
329  * (1) If the boxa has overlapping boxes, and if blending will
330  * be used to give a transparent effect, transparency
331  * artifacts at line intersections can be removed using
332  * removedups = 1.
333  */
334 PTA *
336  l_int32 width,
337  l_int32 removedups)
338 {
339 l_int32 i, n, x1, y1, x2, y2;
340 PTA *ptad, *ptat, *pta;
341 
342  PROCNAME("ptaGeneratePolyline");
343 
344  if (!ptas)
345  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
346 
347  n = ptaGetCount(ptas);
348  ptat = ptaCreate(0);
349  if (n < 2) /* nothing to do */
350  return ptat;
351 
352  ptaGetIPt(ptas, 0, &x1, &y1);
353  for (i = 1; i < n; i++) {
354  ptaGetIPt(ptas, i, &x2, &y2);
355  pta = ptaGenerateWideLine(x1, y1, x2, y2, width);
356  ptaJoin(ptat, pta, 0, 0);
357  ptaDestroy(&pta);
358  x1 = x2;
359  y1 = y2;
360  }
361 
362  /* Close the contour */
363  ptaGetIPt(ptas, 0, &x2, &y2);
364  pta = ptaGenerateWideLine(x1, y1, x2, y2, width);
365  ptaJoin(ptat, pta, 0, 0);
366  ptaDestroy(&pta);
367 
368  if (removedups)
369  ptad = ptaRemoveDuplicates(ptat, 0);
370  else
371  ptad = ptaClone(ptat);
372 
373  ptaDestroy(&ptat);
374  return ptad;
375 }
376 
377 
378 /*------------------------------------------------------------------*
379  * Pta generation for arbitrary shapes built with lines *
380  *------------------------------------------------------------------*/
381 /*!
382  * pixRenderPta()
383  *
384  * Input: pix
385  * pta (arbitrary set of points)
386  * op (one of L_SET_PIXELS, L_CLEAR_PIXELS, L_FLIP_PIXELS)
387  * Return: 0 if OK, 1 on error
388  *
389  * Notes:
390  * (1) L_SET_PIXELS puts all image bits in each pixel to 1
391  * (black for 1 bpp; white for depth > 1)
392  * (2) L_CLEAR_PIXELS puts all image bits in each pixel to 0
393  * (white for 1 bpp; black for depth > 1)
394  * (3) L_FLIP_PIXELS reverses all image bits in each pixel
395  * (4) This function clips the rendering to the pix. It performs
396  * clipping for functions such as pixRenderLine(),
397  * pixRenderBox() and pixRenderBoxa(), that call pixRenderPta().
398  */
399 l_int32
401  PTA *pta,
402  l_int32 op)
403 {
404 l_int32 i, n, x, y, w, h, d, maxval;
405 
406  PROCNAME("pixRenderPta");
407 
408  if (!pix)
409  return ERROR_INT("pix not defined", procName, 1);
410  if (!pta)
411  return ERROR_INT("pta not defined", procName, 1);
412  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
413  return ERROR_INT("invalid op", procName, 1);
414 
415  w = pixGetWidth(pix);
416  h = pixGetHeight(pix);
417  maxval = 1;
418  if (op == L_SET_PIXELS) {
419  d = pixGetDepth(pix);
420  switch (d)
421  {
422  case 2:
423  maxval = 0x3;
424  break;
425  case 4:
426  maxval = 0xf;
427  break;
428  case 8:
429  maxval = 0xff;
430  break;
431  case 16:
432  maxval = 0xffff;
433  break;
434  case 32:
435  maxval = 0xffffffff;
436  break;
437  }
438  }
439 
440  n = ptaGetCount(pta);
441  for (i = 0; i < n; i++) {
442  ptaGetIPt(pta, i, &x, &y);
443  if (x < 0 || x >= w)
444  continue;
445  if (y < 0 || y >= h)
446  continue;
447  switch (op)
448  {
449  case L_SET_PIXELS:
450  pixSetPixel(pix, x, y, maxval);
451  break;
452  case L_CLEAR_PIXELS:
453  pixClearPixel(pix, x, y);
454  break;
455  case L_FLIP_PIXELS:
456  pixFlipPixel(pix, x, y);
457  break;
458  default:
459  break;
460  }
461  }
462 
463  return 0;
464 }
465 
466 
467 /*!
468  * pixRenderPtaArb()
469  *
470  * Input: pix
471  * pta (arbitrary set of points)
472  * rval, gval, bval
473  * Return: 0 if OK, 1 on error
474  *
475  * Notes:
476  * (1) If pix is colormapped, render this color on each pixel.
477  * (2) If pix is not colormapped, do the best job you can using
478  * the input colors:
479  * - d = 1: set the pixels
480  * - d = 2, 4, 8: average the input rgb value
481  * - d = 32: use the input rgb value
482  * (3) This function clips the rendering to the pix.
483  */
484 l_int32
486  PTA *pta,
487  l_uint8 rval,
488  l_uint8 gval,
489  l_uint8 bval)
490 {
491 l_int32 i, n, x, y, w, h, d, index;
492 l_uint8 val;
493 l_uint32 val32;
494 PIXCMAP *cmap;
495 
496  PROCNAME("pixRenderPtaArb");
497 
498  if (!pix)
499  return ERROR_INT("pix not defined", procName, 1);
500  if (!pta)
501  return ERROR_INT("pta not defined", procName, 1);
502  d = pixGetDepth(pix);
503  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 32)
504  return ERROR_INT("depth not in {1,2,4,8,32}", procName, 1);
505 
506  if (d == 1) {
508  return 0;
509  }
510 
512  d = pixGetDepth(pix);
513  if (cmap) {
514  if (pixcmapAddNewColor(cmap, rval, gval, bval, &index))
515  return ERROR_INT("colormap is full", procName, 1);
516  }
517  else {
518  if (d == 2)
519  val = (rval + gval + bval) / (3 * 64);
520  else if (d == 4)
521  val = (rval + gval + bval) / (3 * 16);
522  else if (d == 8)
523  val = (rval + gval + bval) / 3;
524  else /* d == 32 */
525  composeRGBPixel(rval, gval, bval, &val32);
526  }
527 
528  w = pixGetWidth(pix);
529  h = pixGetHeight(pix);
530  n = ptaGetCount(pta);
531  for (i = 0; i < n; i++) {
532  ptaGetIPt(pta, i, &x, &y);
533  if (x < 0 || x >= w)
534  continue;
535  if (y < 0 || y >= h)
536  continue;
537  if (cmap)
538  pixSetPixel(pix, x, y, index);
539  else if (d == 32)
540  pixSetPixel(pix, x, y, val32);
541  else
542  pixSetPixel(pix, x, y, val);
543  }
544 
545  return 0;
546 }
547 
548 
549 /*!
550  * pixRenderPtaBlend()
551  *
552  * Input: pix (32 bpp rgb)
553  * pta (arbitrary set of points)
554  * rval, gval, bval
555  * Return: 0 if OK, 1 on error
556  *
557  * Notes:
558  * (1) This function clips the rendering to the pix.
559  */
560 l_int32
562  PTA *pta,
563  l_uint8 rval,
564  l_uint8 gval,
565  l_uint8 bval,
567 {
568 l_int32 i, n, x, y, w, h;
569 l_uint8 nrval, ngval, nbval;
570 l_uint32 val32;
571 l_float32 frval, fgval, fbval;
572 
573  PROCNAME("pixRenderPtaBlend");
574 
575  if (!pix)
576  return ERROR_INT("pix not defined", procName, 1);
577  if (!pta)
578  return ERROR_INT("pta not defined", procName, 1);
579  if (pixGetDepth(pix) != 32)
580  return ERROR_INT("depth not 32 bpp", procName, 1);
581  if (fract < 0.0 || fract > 1.0) {
582  L_WARNING("fract must be in [0.0, 1.0]; setting to 0.5", procName);
583  fract = 0.5;
584  }
585 
586  w = pixGetWidth(pix);
587  h = pixGetHeight(pix);
588  n = ptaGetCount(pta);
589  frval = fract * rval;
590  fgval = fract * gval;
591  fbval = fract * bval;
592  for (i = 0; i < n; i++) {
593  ptaGetIPt(pta, i, &x, &y);
594  if (x < 0 || x >= w)
595  continue;
596  if (y < 0 || y >= h)
597  continue;
598  pixGetPixel(pix, x, y, &val32);
599  nrval = GET_DATA_BYTE(&val32, COLOR_RED);
600  nrval = (l_uint8)((1. - fract) * nrval + frval);
601  ngval = GET_DATA_BYTE(&val32, COLOR_GREEN);
602  ngval = (l_uint8)((1. - fract) * ngval + fgval);
603  nbval = GET_DATA_BYTE(&val32, COLOR_BLUE);
604  nbval = (l_uint8)((1. - fract) * nbval + fbval);
605  composeRGBPixel(nrval, ngval, nbval, &val32);
606  pixSetPixel(pix, x, y, val32);
607  }
608 
609  return 0;
610 }
611 
612 
613 /*------------------------------------------------------------------*
614  * Rendering of arbitrary shapes built with lines *
615  *------------------------------------------------------------------*/
616 /*!
617  * pixRenderLine()
618  *
619  * Input: pix
620  * x1, y1
621  * x2, y2
622  * width (thickness of line)
623  * op (one of L_SET_PIXELS, L_CLEAR_PIXELS, L_FLIP_PIXELS)
624  * Return: 0 if OK, 1 on error
625  */
626 l_int32
628  l_int32 x1,
629  l_int32 y1,
630  l_int32 x2,
631  l_int32 y2,
632  l_int32 width,
633  l_int32 op)
634 {
635 PTA *pta;
636 
637  PROCNAME("pixRenderLine");
638 
639  if (!pix)
640  return ERROR_INT("pix not defined", procName, 1);
641  if (width < 1) {
642  L_WARNING("width must be > 0; setting to 1", procName);
643  width = 1;
644  }
645  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
646  return ERROR_INT("invalid op", procName, 1);
647 
648  if ((pta = ptaGenerateWideLine(x1, y1, x2, y2, width)) == NULL)
649  return ERROR_INT("pta not made", procName, 1);
650  pixRenderPta(pix, pta, op);
651  ptaDestroy(&pta);
652  return 0;
653 }
654 
655 
656 /*!
657  * pixRenderLineArb()
658  *
659  * Input: pix
660  * x1, y1
661  * x2, y2
662  * width (thickness of line)
663  * rval, gval, bval
664  * Return: 0 if OK, 1 on error
665  */
666 l_int32
668  l_int32 x1,
669  l_int32 y1,
670  l_int32 x2,
671  l_int32 y2,
672  l_int32 width,
673  l_uint8 rval,
674  l_uint8 gval,
675  l_uint8 bval)
676 {
677 PTA *pta;
678 
679  PROCNAME("pixRenderLineArb");
680 
681  if (!pix)
682  return ERROR_INT("pix not defined", procName, 1);
683  if (width < 1) {
684  L_WARNING("width must be > 0; setting to 1", procName);
685  width = 1;
686  }
687 
688  if ((pta = ptaGenerateWideLine(x1, y1, x2, y2, width)) == NULL)
689  return ERROR_INT("pta not made", procName, 1);
690  pixRenderPtaArb(pix, pta, rval, gval, bval);
691  ptaDestroy(&pta);
692  return 0;
693 }
694 
695 
696 /*!
697  * pixRenderLineBlend()
698  *
699  * Input: pix
700  * x1, y1
701  * x2, y2
702  * width (thickness of line)
703  * rval, gval, bval
704  * fract
705  * Return: 0 if OK, 1 on error
706  */
707 l_int32
709  l_int32 x1,
710  l_int32 y1,
711  l_int32 x2,
712  l_int32 y2,
713  l_int32 width,
714  l_uint8 rval,
715  l_uint8 gval,
716  l_uint8 bval,
718 {
719 PTA *pta;
720 
721  PROCNAME("pixRenderLineBlend");
722 
723  if (!pix)
724  return ERROR_INT("pix not defined", procName, 1);
725  if (width < 1) {
726  L_WARNING("width must be > 0; setting to 1", procName);
727  width = 1;
728  }
729 
730  if ((pta = ptaGenerateWideLine(x1, y1, x2, y2, width)) == NULL)
731  return ERROR_INT("pta not made", procName, 1);
732  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
733  ptaDestroy(&pta);
734  return 0;
735 }
736 
737 
738 /*!
739  * pixRenderBox()
740  *
741  * Input: pix
742  * box
743  * width (thickness of box lines)
744  * op (one of L_SET_PIXELS, L_CLEAR_PIXELS, L_FLIP_PIXELS)
745  * Return: 0 if OK, 1 on error
746  */
747 l_int32
749  BOX *box,
750  l_int32 width,
751  l_int32 op)
752 {
753 PTA *pta;
754 
755  PROCNAME("pixRenderBox");
756 
757  if (!pix)
758  return ERROR_INT("pix not defined", procName, 1);
759  if (!box)
760  return ERROR_INT("box not defined", procName, 1);
761  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
762  return ERROR_INT("invalid op", procName, 1);
763 
764  if ((pta = ptaGenerateBox(box, width)) == NULL)
765  return ERROR_INT("pta not made", procName, 1);
766  pixRenderPta(pix, pta, op);
767  ptaDestroy(&pta);
768  return 0;
769 }
770 
771 
772 /*!
773  * pixRenderBoxArb()
774  *
775  * Input: pix
776  * box
777  * width (thickness of box lines)
778  * rval, gval, bval
779  * Return: 0 if OK, 1 on error
780  */
781 l_int32
783  BOX *box,
784  l_int32 width,
785  l_uint8 rval,
786  l_uint8 gval,
787  l_uint8 bval)
788 {
789 PTA *pta;
790 
791  PROCNAME("pixRenderBoxArb");
792 
793  if (!pix)
794  return ERROR_INT("pix not defined", procName, 1);
795  if (!box)
796  return ERROR_INT("box not defined", procName, 1);
797 
798  if ((pta = ptaGenerateBox(box, width)) == NULL)
799  return ERROR_INT("pta not made", procName, 1);
800  pixRenderPtaArb(pix, pta, rval, gval, bval);
801  ptaDestroy(&pta);
802  return 0;
803 }
804 
805 
806 /*!
807  * pixRenderBoxBlend()
808  *
809  * Input: pix
810  * box
811  * width (thickness of box lines)
812  * rval, gval, bval
813  * fract (in [0.0 - 1.0]; complete transparency (no effect)
814  * if 0.0; no transparency if 1.0)
815  * Return: 0 if OK, 1 on error
816  */
817 l_int32
819  BOX *box,
820  l_int32 width,
821  l_uint8 rval,
822  l_uint8 gval,
823  l_uint8 bval,
825 {
826 PTA *pta;
827 
828  PROCNAME("pixRenderBoxBlend");
829 
830  if (!pix)
831  return ERROR_INT("pix not defined", procName, 1);
832  if (!box)
833  return ERROR_INT("box not defined", procName, 1);
834 
835  if ((pta = ptaGenerateBox(box, width)) == NULL)
836  return ERROR_INT("pta not made", procName, 1);
837  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
838  ptaDestroy(&pta);
839  return 0;
840 }
841 
842 
843 /*!
844  * pixRenderBoxa()
845  *
846  * Input: pix
847  * boxa
848  * width (thickness of line)
849  * op (one of L_SET_PIXELS, L_CLEAR_PIXELS, L_FLIP_PIXELS)
850  * Return: 0 if OK, 1 on error
851  */
852 l_int32
854  BOXA *boxa,
855  l_int32 width,
856  l_int32 op)
857 {
858 PTA *pta;
859 
860  PROCNAME("pixRenderBoxa");
861 
862  if (!pix)
863  return ERROR_INT("pix not defined", procName, 1);
864  if (!boxa)
865  return ERROR_INT("boxa not defined", procName, 1);
866  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
867  return ERROR_INT("invalid op", procName, 1);
868 
869  if ((pta = ptaGenerateBoxa(boxa, width, 0)) == NULL)
870  return ERROR_INT("pta not made", procName, 1);
871  pixRenderPta(pix, pta, op);
872  ptaDestroy(&pta);
873  return 0;
874 }
875 
876 
877 /*!
878  * pixRenderBoxaArb()
879  *
880  * Input: pix
881  * boxa
882  * width (thickness of line)
883  * rval, gval, bval
884  * Return: 0 if OK, 1 on error
885  */
886 l_int32
888  BOXA *boxa,
889  l_int32 width,
890  l_uint8 rval,
891  l_uint8 gval,
892  l_uint8 bval)
893 {
894 PTA *pta;
895 
896  PROCNAME("pixRenderBoxaArb");
897 
898  if (!pix)
899  return ERROR_INT("pix not defined", procName, 1);
900  if (!boxa)
901  return ERROR_INT("boxa not defined", procName, 1);
902 
903  if ((pta = ptaGenerateBoxa(boxa, width, 0)) == NULL)
904  return ERROR_INT("pta not made", procName, 1);
905  pixRenderPtaArb(pix, pta, rval, gval, bval);
906  ptaDestroy(&pta);
907  return 0;
908 }
909 
910 
911 /*!
912  * pixRenderBoxaBlend()
913  *
914  * Input: pix
915  * boxa
916  * width (thickness of line)
917  * rval, gval, bval
918  * fract (in [0.0 - 1.0]; complete transparency (no effect)
919  * if 0.0; no transparency if 1.0)
920  * removedups (1 to remove; 0 otherwise)
921  * Return: 0 if OK, 1 on error
922  */
923 l_int32
925  BOXA *boxa,
926  l_int32 width,
927  l_uint8 rval,
928  l_uint8 gval,
929  l_uint8 bval,
931  l_int32 removedups)
932 {
933 PTA *pta;
934 
935  PROCNAME("pixRenderBoxaBlend");
936 
937  if (!pix)
938  return ERROR_INT("pix not defined", procName, 1);
939  if (!boxa)
940  return ERROR_INT("boxa not defined", procName, 1);
941 
942  if ((pta = ptaGenerateBoxa(boxa, width, removedups)) == NULL)
943  return ERROR_INT("pta not made", procName, 1);
944  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
945  ptaDestroy(&pta);
946  return 0;
947 }
948 
949 
950 /*!
951  * pixRenderPolyline()
952  *
953  * Input: pix
954  * ptas
955  * width (thickness of line)
956  * op (one of L_SET_PIXELS, L_CLEAR_PIXELS, L_FLIP_PIXELS)
957  * Return: 0 if OK, 1 on error
958  *
959  * Note: this renders a closed contour.
960  */
961 l_int32
963  PTA *ptas,
964  l_int32 width,
965  l_int32 op)
966 {
967 PTA *pta;
968 
969  PROCNAME("pixRenderPolyline");
970 
971  if (!pix)
972  return ERROR_INT("pix not defined", procName, 1);
973  if (!ptas)
974  return ERROR_INT("ptas not defined", procName, 1);
975  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
976  return ERROR_INT("invalid op", procName, 1);
977 
978  if ((pta = ptaGeneratePolyline(ptas, width, 0)) == NULL)
979  return ERROR_INT("pta not made", procName, 1);
980  pixRenderPta(pix, pta, op);
981  ptaDestroy(&pta);
982  return 0;
983 }
984 
985 
986 /*!
987  * pixRenderPolylineArb()
988  *
989  * Input: pix
990  * ptas
991  * width (thickness of line)
992  * rval, gval, bval
993  * Return: 0 if OK, 1 on error
994  *
995  * Note: this renders a closed contour.
996  */
997 l_int32
999  PTA *ptas,
1000  l_int32 width,
1001  l_uint8 rval,
1002  l_uint8 gval,
1003  l_uint8 bval)
1004 {
1005 PTA *pta;
1006 
1007  PROCNAME("pixRenderPolylineArb");
1008 
1009  if (!pix)
1010  return ERROR_INT("pix not defined", procName, 1);
1011  if (!ptas)
1012  return ERROR_INT("ptas not defined", procName, 1);
1013 
1014  if ((pta = ptaGeneratePolyline(ptas, width, 0)) == NULL)
1015  return ERROR_INT("pta not made", procName, 1);
1016  pixRenderPtaArb(pix, pta, rval, gval, bval);
1017  ptaDestroy(&pta);
1018  return 0;
1019 }
1020 
1021 
1022 /*!
1023  * pixRenderPolylineBlend()
1024  *
1025  * Input: pix
1026  * ptas
1027  * width (thickness of line)
1028  * rval, gval, bval
1029  * fract (in [0.0 - 1.0]; complete transparency (no effect)
1030  * if 0.0; no transparency if 1.0)
1031  * removedups (1 to remove; 0 otherwise)
1032  * Return: 0 if OK, 1 on error
1033  */
1034 l_int32
1036  PTA *ptas,
1037  l_int32 width,
1038  l_uint8 rval,
1039  l_uint8 gval,
1040  l_uint8 bval,
1041  l_float32 fract,
1042  l_int32 removedups)
1043 {
1044 PTA *pta;
1045 
1046  PROCNAME("pixRenderPolylineBlend");
1047 
1048  if (!pix)
1049  return ERROR_INT("pix not defined", procName, 1);
1050  if (!ptas)
1051  return ERROR_INT("ptas not defined", procName, 1);
1052 
1053  if ((pta = ptaGeneratePolyline(ptas, width, removedups)) == NULL)
1054  return ERROR_INT("pta not made", procName, 1);
1055  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1056  ptaDestroy(&pta);
1057  return 0;
1058 }
1059 
1060 
1061 
1062 /*------------------------------------------------------------------*
1063  * Contour rendering on grayscale images *
1064  *------------------------------------------------------------------*/
1065 /*!
1066  * pixRenderContours()
1067  *
1068  * Input: pixs (8 or 16 bpp)
1069  * startval (value of lowest contour; must be in [0 ... maxval])
1070  * incr (increment to next contour; must be > 0)
1071  * outdepth (either 1 or depth of pixs)
1072  * Return: pixd, or null on error
1073  *
1074  * The output can be either 1 bpp, showing just the contour
1075  * lines, or a copy of the input pixs with the contour lines
1076  * superposed.
1077  */
1078 PIX *
1080  l_int32 startval,
1081  l_int32 incr,
1082  l_int32 outdepth)
1083 {
1084 l_int32 w, h, d, maxval, wpls, wpld, i, j, val, test;
1085 l_uint32 *datas, *datad, *lines, *lined;
1086 PIX *pixd;
1087 
1088  PROCNAME("pixRenderContours");
1089 
1090  if (!pixs)
1091  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1092  if (pixGetColormap(pixs))
1093  return (PIX *)ERROR_PTR("pixs has colormap", procName, NULL);
1094  d = pixGetDepth(pixs);
1095  if (d != 8 && d != 16)
1096  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", procName, NULL);
1097  if (outdepth != 1 && outdepth != d) {
1098  L_WARNING("invalid outdepth; setting to 1", procName);
1099  outdepth = 1;
1100  }
1101  maxval = (1 << d) - 1;
1102  if (startval < 0 || startval > maxval)
1103  return (PIX *)ERROR_PTR("startval not in [0 ... maxval]",
1104  procName, NULL);
1105  if (incr < 1)
1106  return (PIX *)ERROR_PTR("incr < 1", procName, NULL);
1107 
1108  w = pixGetWidth(pixs);
1109  h = pixGetHeight(pixs);
1110  if (outdepth == d)
1111  pixd = pixCopy(NULL, pixs);
1112  else
1113  pixd = pixCreate(w, h, 1);
1114 
1115  pixCopyResolution(pixd, pixs);
1116  datad = pixGetData(pixd);
1117  wpld = pixGetWpl(pixd);
1118  datas = pixGetData(pixs);
1119  wpls = pixGetWpl(pixs);
1120 
1121  switch (d)
1122  {
1123  case 8:
1124  if (outdepth == 1) {
1125  for (i = 0; i < h; i++) {
1126  lines = datas + i * wpls;
1127  lined = datad + i * wpld;
1128  for (j = 0; j < w; j++) {
1129  val = GET_DATA_BYTE(lines, j);
1130  if (val < startval)
1131  continue;
1132  test = (val - startval) % incr;
1133  if (!test)
1134  SET_DATA_BIT(lined, j);
1135  }
1136  }
1137  }
1138  else { /* outdepth == d */
1139  for (i = 0; i < h; i++) {
1140  lines = datas + i * wpls;
1141  lined = datad + i * wpld;
1142  for (j = 0; j < w; j++) {
1143  val = GET_DATA_BYTE(lines, j);
1144  if (val < startval)
1145  continue;
1146  test = (val - startval) % incr;
1147  if (!test)
1148  SET_DATA_BYTE(lined, j, 0);
1149  }
1150  }
1151  }
1152  break;
1153 
1154  case 16:
1155  if (outdepth == 1) {
1156  for (i = 0; i < h; i++) {
1157  lines = datas + i * wpls;
1158  lined = datad + i * wpld;
1159  for (j = 0; j < w; j++) {
1161  if (val < startval)
1162  continue;
1163  test = (val - startval) % incr;
1164  if (!test)
1165  SET_DATA_BIT(lined, j);
1166  }
1167  }
1168  }
1169  else { /* outdepth == d */
1170  for (i = 0; i < h; i++) {
1171  lines = datas + i * wpls;
1172  lined = datad + i * wpld;
1173  for (j = 0; j < w; j++) {
1175  if (val < startval)
1176  continue;
1177  test = (val - startval) % incr;
1178  if (!test)
1179  SET_DATA_TWO_BYTES(lined, j, 0);
1180  }
1181  }
1182  }
1183  break;
1184 
1185  default:
1186  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", procName, NULL);
1187  }
1188 
1189  return pixd;
1190 }
1191 
integer fract(integer x, integer n, integer d, integer max_answer)
Definition: aptex-src.c:38726
#define width(a)
Definition: aptex-macros.h:198
#define box(a)
Definition: aptex-macros.h:675
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:118
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:50
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:126
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:98
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:106
static gray maxval
Definition: asciitopgm.c:38
void boxDestroy(BOX **pbox)
Definition: box.c:192
l_int32 boxaGetCount(BOXA *boxa)
Definition: box.c:631
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
Definition: box.c:652
#define n
Definition: t4ht.c:1290
l_int32 pixcmapAddNewColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
Definition: colormap.c:202
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
int w
Definition: dviconv.c:26
int h
Definition: dviconv.c:9
#define PROCNAME(name)
Definition: environ.h:131
#define ERROR_PTR(a, b, c)
Definition: environ.h:132
unsigned int l_uint32
Definition: environ.h:33
unsigned char l_uint8
Definition: environ.h:29
#define L_WARNING(a, b)
Definition: environ.h:136
#define ERROR_INT(a, b, c)
Definition: environ.h:133
int l_int32
Definition: environ.h:32
#define L_SIGN(x)
Definition: environ.h:54
#define L_ABS(x)
Definition: environ.h:50
float l_float32
Definition: environ.h:34
#define d(n)
Definition: gpos-common.c:151
pix
Definition: in_pcx.cpp:383
#define NULL
Definition: ftobjs.h:61
small capitals from c petite p scientific i
Definition: afcover.h:80
kerning y
Definition: ttdriver.c:212
int lines
Definition: var.h:5
#define incr(x)
Definition: cpascal.h:92
#define test
Definition: tie.c:129
l_uint32 * pixGetData(PIX *pix)
Definition: pix1.c:793
l_int32 ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
Definition: pts.c:232
l_int32 pixGetWpl(PIX *pix)
Definition: pix1.c:477
l_int32 pixCopyResolution(PIX *pixd, PIX *pixs)
Definition: pix1.c:567
PTA * ptaClone(PTA *pta)
Definition: pts.c:189
l_int32 pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
Definition: pix2.c:197
l_int32 pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
Definition: pix2.c:128
l_int32 pixGetDepth(PIX *pix)
Definition: pix1.c:449
PIX * pixCopy(PIX *pixd, PIX *pixs)
Definition: pix1.c:276
PIXCMAP * pixGetColormap(PIX *pix)
Definition: pix1.c:766
PTA * ptaRemoveDuplicates(PTA *ptas, l_uint32 factor)
Definition: pts.c:506
l_int32 ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
Definition: pts.c:654
l_int32 ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
Definition: pts.c:300
l_int32 composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
Definition: pix2.c:2230
l_int32 pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
Definition: pix2.c:322
l_int32 ptaGetCount(PTA *pta)
Definition: pts.c:609
l_int32 pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
Definition: pix2.c:262
PTA * ptaCreate(l_int32 n)
Definition: pts.c:91
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
Definition: pix1.c:90
void ptaDestroy(PTA **ppta)
Definition: pts.c:126
l_int32 pixGetHeight(PIX *pix)
Definition: pix1.c:419
l_int32 pixGetWidth(PIX *pix)
Definition: pix1.c:389
float x
Definition: cordic.py:15
#define sign(x)
@ L_FLIP_PIXELS
Definition: pix.h:413
@ L_SET_PIXELS
Definition: pix.h:411
@ L_CLEAR_PIXELS
Definition: pix.h:412
@ L_CLONE
Definition: pix.h:363
@ COLOR_BLUE
Definition: pix.h:102
@ COLOR_RED
Definition: pix.h:100
@ COLOR_GREEN
Definition: pix.h:101
#define index(s, c)
Definition: plain2.h:351
#define x1
#define y1
#define y2
#define x2
#define gval(n)
Definition: ltable.h:14
test
Definition: parser.c:257
Definition: pix.h:292
Definition: pix.h:303
Definition: pix.h:51
Definition: pix.h:316
Definition: jquant2.c:258
Definition: mendex.h:20
Definition: sh.h:1226
Definition: strexpr.c:21
int j
Definition: t4ht.c:1589
val
Definition: tex4ht.c:3227
int diff
Definition: tex4ht.c:3815
TT_CharMap cmap
Definition: ttf2pfb.c:163
l_int32 pixRenderBoxaBlend(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract, l_int32 removedups)
Definition: graphics.c:924
l_int32 pixRenderBox(PIX *pix, BOX *box, l_int32 width, l_int32 op)
Definition: graphics.c:748
l_int32 pixRenderLineBlend(PIX *pix, l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
Definition: graphics.c:708
l_int32 pixRenderPolylineArb(PIX *pix, PTA *ptas, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
Definition: graphics.c:998
l_int32 pixRenderPolyline(PIX *pix, PTA *ptas, l_int32 width, l_int32 op)
Definition: graphics.c:962
l_int32 pixRenderBoxArb(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
Definition: graphics.c:782
l_int32 pixRenderLine(PIX *pix, l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width, l_int32 op)
Definition: graphics.c:627
PTA * ptaGeneratePolyline(PTA *ptas, l_int32 width, l_int32 removedups)
Definition: graphics.c:335
l_int32 pixRenderPta(PIX *pix, PTA *pta, l_int32 op)
Definition: graphics.c:400
l_int32 pixRenderPtaArb(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval)
Definition: graphics.c:485
l_int32 pixRenderLineArb(PIX *pix, l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
Definition: graphics.c:667
PTA * ptaGenerateBoxa(BOXA *boxa, l_int32 width, l_int32 removedups)
Definition: graphics.c:287
l_int32 pixRenderPtaBlend(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
Definition: graphics.c:561
PTA * ptaGenerateBox(BOX *box, l_int32 width)
Definition: graphics.c:214
l_int32 pixRenderBoxBlend(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
Definition: graphics.c:818
PTA * ptaGenerateLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2)
Definition: graphics.c:80
l_int32 pixRenderPolylineBlend(PIX *pix, PTA *ptas, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract, l_int32 removedups)
Definition: graphics.c:1035
l_int32 pixRenderBoxa(PIX *pix, BOXA *boxa, l_int32 width, l_int32 op)
Definition: graphics.c:853
l_int32 pixRenderBoxaArb(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
Definition: graphics.c:887
PIX * pixRenderContours(PIX *pixs, l_int32 startval, l_int32 incr, l_int32 outdepth)
Definition: graphics.c:1079
PTA * ptaGenerateWideLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width)
Definition: graphics.c:143