Leptonica  1.77.0
Image processing and image analysis suite
graphics.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
117 #include <string.h>
118 #include <math.h>
119 #include "allheaders.h"
120 
121 
122 /*------------------------------------------------------------------*
123  * Pta generation for arbitrary shapes built with lines *
124  *------------------------------------------------------------------*/
137 PTA *
138 generatePtaLine(l_int32 x1,
139  l_int32 y1,
140  l_int32 x2,
141  l_int32 y2)
142 {
143 l_int32 npts, diff, getyofx, sign, i, x, y;
144 l_float32 slope;
145 PTA *pta;
146 
147  PROCNAME("generatePtaLine");
148 
149  /* Generate line parameters */
150  if (x1 == x2 && y1 == y2) { /* same point */
151  getyofx = TRUE;
152  npts = 1;
153  } else if (L_ABS(x2 - x1) >= L_ABS(y2 - y1)) {
154  getyofx = TRUE;
155  npts = L_ABS(x2 - x1) + 1;
156  diff = x2 - x1;
157  sign = L_SIGN(x2 - x1);
158  slope = (l_float32)(sign * (y2 - y1)) / (l_float32)diff;
159  } else {
160  getyofx = FALSE;
161  npts = L_ABS(y2 - y1) + 1;
162  diff = y2 - y1;
163  sign = L_SIGN(y2 - y1);
164  slope = (l_float32)(sign * (x2 - x1)) / (l_float32)diff;
165  }
166 
167  if ((pta = ptaCreate(npts)) == NULL)
168  return (PTA *)ERROR_PTR("pta not made", procName, NULL);
169 
170  if (npts == 1) { /* degenerate case */
171  ptaAddPt(pta, x1, y1);
172  return pta;
173  }
174 
175  /* Generate the set of points */
176  if (getyofx) { /* y = y(x) */
177  for (i = 0; i < npts; i++) {
178  x = x1 + sign * i;
179  y = (l_int32)(y1 + (l_float32)i * slope + 0.5);
180  ptaAddPt(pta, x, y);
181  }
182  } else { /* x = x(y) */
183  for (i = 0; i < npts; i++) {
184  x = (l_int32)(x1 + (l_float32)i * slope + 0.5);
185  y = y1 + sign * i;
186  ptaAddPt(pta, x, y);
187  }
188  }
189 
190  return pta;
191 }
192 
193 
202 PTA *
204  l_int32 y1,
205  l_int32 x2,
206  l_int32 y2,
207  l_int32 width)
208 {
209 l_int32 i, x1a, x2a, y1a, y2a;
210 PTA *pta, *ptaj;
211 
212  PROCNAME("generatePtaWideLine");
213 
214  if (width < 1) {
215  L_WARNING("width < 1; setting to 1\n", procName);
216  width = 1;
217  }
218 
219  if ((ptaj = generatePtaLine(x1, y1, x2, y2)) == NULL)
220  return (PTA *)ERROR_PTR("ptaj not made", procName, NULL);
221  if (width == 1)
222  return ptaj;
223 
224  /* width > 1; estimate line direction & join */
225  if (L_ABS(x1 - x2) > L_ABS(y1 - y2)) { /* "horizontal" line */
226  for (i = 1; i < width; i++) {
227  if ((i & 1) == 1) { /* place above */
228  y1a = y1 - (i + 1) / 2;
229  y2a = y2 - (i + 1) / 2;
230  } else { /* place below */
231  y1a = y1 + (i + 1) / 2;
232  y2a = y2 + (i + 1) / 2;
233  }
234  if ((pta = generatePtaLine(x1, y1a, x2, y2a)) != NULL) {
235  ptaJoin(ptaj, pta, 0, -1);
236  ptaDestroy(&pta);
237  }
238  }
239  } else { /* "vertical" line */
240  for (i = 1; i < width; i++) {
241  if ((i & 1) == 1) { /* place to left */
242  x1a = x1 - (i + 1) / 2;
243  x2a = x2 - (i + 1) / 2;
244  } else { /* place to right */
245  x1a = x1 + (i + 1) / 2;
246  x2a = x2 + (i + 1) / 2;
247  }
248  if ((pta = generatePtaLine(x1a, y1, x2a, y2)) != NULL) {
249  ptaJoin(ptaj, pta, 0, -1);
250  ptaDestroy(&pta);
251  }
252  }
253  }
254 
255  return ptaj;
256 }
257 
258 
272 PTA *
274  l_int32 width)
275 {
276 l_int32 x, y, w, h;
277 PTA *ptad, *pta;
278 
279  PROCNAME("generatePtaBox");
280 
281  if (!box)
282  return (PTA *)ERROR_PTR("box not defined", procName, NULL);
283  if (width < 1) {
284  L_WARNING("width < 1; setting to 1\n", procName);
285  width = 1;
286  }
287 
288  /* Generate line points and add them to the pta. */
289  boxGetGeometry(box, &x, &y, &w, &h);
290  if (w == 0 || h == 0)
291  return (PTA *)ERROR_PTR("box has w = 0 or h = 0", procName, NULL);
292  ptad = ptaCreate(0);
293  if ((width & 1) == 1) { /* odd width */
294  pta = generatePtaWideLine(x - width / 2, y,
295  x + w - 1 + width / 2, y, width);
296  ptaJoin(ptad, pta, 0, -1);
297  ptaDestroy(&pta);
298  pta = generatePtaWideLine(x + w - 1, y + 1 + width / 2,
299  x + w - 1, y + h - 2 - width / 2, width);
300  ptaJoin(ptad, pta, 0, -1);
301  ptaDestroy(&pta);
302  pta = generatePtaWideLine(x + w - 1 + width / 2, y + h - 1,
303  x - width / 2, y + h - 1, width);
304  ptaJoin(ptad, pta, 0, -1);
305  ptaDestroy(&pta);
306  pta = generatePtaWideLine(x, y + h - 2 - width / 2,
307  x, y + 1 + width / 2, width);
308  ptaJoin(ptad, pta, 0, -1);
309  ptaDestroy(&pta);
310  } else { /* even width */
311  pta = generatePtaWideLine(x - width / 2, y,
312  x + w - 2 + width / 2, y, width);
313  ptaJoin(ptad, pta, 0, -1);
314  ptaDestroy(&pta);
315  pta = generatePtaWideLine(x + w - 1, y + 0 + width / 2,
316  x + w - 1, y + h - 2 - width / 2, width);
317  ptaJoin(ptad, pta, 0, -1);
318  ptaDestroy(&pta);
319  pta = generatePtaWideLine(x + w - 2 + width / 2, y + h - 1,
320  x - width / 2, y + h - 1, width);
321  ptaJoin(ptad, pta, 0, -1);
322  ptaDestroy(&pta);
323  pta = generatePtaWideLine(x, y + h - 2 - width / 2,
324  x, y + 0 + width / 2, width);
325  ptaJoin(ptad, pta, 0, -1);
326  ptaDestroy(&pta);
327  }
328 
329  return ptad;
330 }
331 
332 
349 PTA *
351  l_int32 width,
352  l_int32 removedups)
353 {
354 l_int32 i, n;
355 BOX *box;
356 PTA *ptad, *ptat, *pta;
357 
358  PROCNAME("generatePtaBoxa");
359 
360  if (!boxa)
361  return (PTA *)ERROR_PTR("boxa not defined", procName, NULL);
362  if (width < 1) {
363  L_WARNING("width < 1; setting to 1\n", procName);
364  width = 1;
365  }
366 
367  n = boxaGetCount(boxa);
368  ptat = ptaCreate(0);
369  for (i = 0; i < n; i++) {
370  box = boxaGetBox(boxa, i, L_CLONE);
371  pta = generatePtaBox(box, width);
372  ptaJoin(ptat, pta, 0, -1);
373  ptaDestroy(&pta);
374  boxDestroy(&box);
375  }
376 
377  if (removedups)
378  ptad = ptaRemoveDupsByAset(ptat);
379  else
380  ptad = ptaClone(ptat);
381 
382  ptaDestroy(&ptat);
383  return ptad;
384 }
385 
386 
404 PTA *
406  l_int32 spacing,
407  l_int32 width,
408  l_int32 orient,
409  l_int32 outline)
410 {
411 l_int32 bx, by, bh, bw, x, y, x1, y1, x2, y2, i, n, npts;
412 PTA *ptad, *pta;
413 
414  PROCNAME("generatePtaHashBox");
415 
416  if (!box)
417  return (PTA *)ERROR_PTR("box not defined", procName, NULL);
418  if (spacing <= 1)
419  return (PTA *)ERROR_PTR("spacing not > 1", procName, NULL);
420  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
421  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
422  return (PTA *)ERROR_PTR("invalid line orientation", procName, NULL);
423  boxGetGeometry(box, &bx, &by, &bw, &bh);
424  if (bw == 0 || bh == 0)
425  return (PTA *)ERROR_PTR("box has bw = 0 or bh = 0", procName, NULL);
426  if (width < 1) {
427  L_WARNING("width < 1; setting to 1\n", procName);
428  width = 1;
429  }
430 
431  /* Generate line points and add them to the pta. */
432  ptad = ptaCreate(0);
433  if (outline) {
434  pta = generatePtaBox(box, width);
435  ptaJoin(ptad, pta, 0, -1);
436  ptaDestroy(&pta);
437  }
438  if (orient == L_HORIZONTAL_LINE) {
439  n = 1 + bh / spacing;
440  for (i = 0; i < n; i++) {
441  y = by + (i * (bh - 1)) / (n - 1);
442  pta = generatePtaWideLine(bx, y, bx + bw - 1, y, width);
443  ptaJoin(ptad, pta, 0, -1);
444  ptaDestroy(&pta);
445  }
446  } else if (orient == L_VERTICAL_LINE) {
447  n = 1 + bw / spacing;
448  for (i = 0; i < n; i++) {
449  x = bx + (i * (bw - 1)) / (n - 1);
450  pta = generatePtaWideLine(x, by, x, by + bh - 1, width);
451  ptaJoin(ptad, pta, 0, -1);
452  ptaDestroy(&pta);
453  }
454  } else if (orient == L_POS_SLOPE_LINE) {
455  n = 2 + (l_int32)((bw + bh) / (1.4 * spacing));
456  for (i = 0; i < n; i++) {
457  x = (l_int32)(bx + (i + 0.5) * 1.4 * spacing);
458  boxIntersectByLine(box, x, by - 1, 1.0, &x1, &y1, &x2, &y2, &npts);
459  if (npts == 2) {
460  pta = generatePtaWideLine(x1, y1, x2, y2, width);
461  ptaJoin(ptad, pta, 0, -1);
462  ptaDestroy(&pta);
463  }
464  }
465  } else { /* orient == L_NEG_SLOPE_LINE */
466  n = 2 + (l_int32)((bw + bh) / (1.4 * spacing));
467  for (i = 0; i < n; i++) {
468  x = (l_int32)(bx - bh + (i + 0.5) * 1.4 * spacing);
469  boxIntersectByLine(box, x, by - 1, -1.0, &x1, &y1, &x2, &y2, &npts);
470  if (npts == 2) {
471  pta = generatePtaWideLine(x1, y1, x2, y2, width);
472  ptaJoin(ptad, pta, 0, -1);
473  ptaDestroy(&pta);
474  }
475  }
476  }
477 
478  return ptad;
479 }
480 
481 
504 PTA *
506  l_int32 spacing,
507  l_int32 width,
508  l_int32 orient,
509  l_int32 outline,
510  l_int32 removedups)
511 {
512 l_int32 i, n;
513 BOX *box;
514 PTA *ptad, *ptat, *pta;
515 
516  PROCNAME("generatePtaHashBoxa");
517 
518  if (!boxa)
519  return (PTA *)ERROR_PTR("boxa not defined", procName, NULL);
520  if (spacing <= 1)
521  return (PTA *)ERROR_PTR("spacing not > 1", procName, NULL);
522  if (width < 1) {
523  L_WARNING("width < 1; setting to 1\n", procName);
524  width = 1;
525  }
526  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
527  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
528  return (PTA *)ERROR_PTR("invalid line orientation", procName, NULL);
529 
530  n = boxaGetCount(boxa);
531  ptat = ptaCreate(0);
532  for (i = 0; i < n; i++) {
533  box = boxaGetBox(boxa, i, L_CLONE);
534  pta = generatePtaHashBox(box, spacing, width, orient, outline);
535  ptaJoin(ptat, pta, 0, -1);
536  ptaDestroy(&pta);
537  boxDestroy(&box);
538  }
539 
540  if (removedups)
541  ptad = ptaRemoveDupsByAset(ptat);
542  else
543  ptad = ptaClone(ptat);
544 
545  ptaDestroy(&ptat);
546  return ptad;
547 }
548 
549 
564 PTAA *
566 {
567 l_int32 i, n, x, y, w, h;
568 BOX *box;
569 PTA *pta;
570 PTAA *ptaa;
571 
572  PROCNAME("generatePtaaBoxa");
573 
574  if (!boxa)
575  return (PTAA *)ERROR_PTR("boxa not defined", procName, NULL);
576 
577  n = boxaGetCount(boxa);
578  ptaa = ptaaCreate(n);
579  for (i = 0; i < n; i++) {
580  box = boxaGetBox(boxa, i, L_CLONE);
581  boxGetGeometry(box, &x, &y, &w, &h);
582  pta = ptaCreate(4);
583  ptaAddPt(pta, x, y);
584  ptaAddPt(pta, x + w - 1, y);
585  ptaAddPt(pta, x + w - 1, y + h - 1);
586  ptaAddPt(pta, x, y + h - 1);
587  ptaaAddPta(ptaa, pta, L_INSERT);
588  boxDestroy(&box);
589  }
590 
591  return ptaa;
592 }
593 
594 
615 PTAA *
617  l_int32 spacing,
618  l_int32 width,
619  l_int32 orient,
620  l_int32 outline)
621 {
622 l_int32 i, n;
623 BOX *box;
624 PTA *pta;
625 PTAA *ptaa;
626 
627  PROCNAME("generatePtaaHashBoxa");
628 
629  if (!boxa)
630  return (PTAA *)ERROR_PTR("boxa not defined", procName, NULL);
631  if (spacing <= 1)
632  return (PTAA *)ERROR_PTR("spacing not > 1", procName, NULL);
633  if (width < 1) {
634  L_WARNING("width < 1; setting to 1\n", procName);
635  width = 1;
636  }
637  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
638  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
639  return (PTAA *)ERROR_PTR("invalid line orientation", procName, NULL);
640 
641  n = boxaGetCount(boxa);
642  ptaa = ptaaCreate(n);
643  for (i = 0; i < n; i++) {
644  box = boxaGetBox(boxa, i, L_CLONE);
645  pta = generatePtaHashBox(box, spacing, width, orient, outline);
646  ptaaAddPta(ptaa, pta, L_INSERT);
647  boxDestroy(&box);
648  }
649 
650  return ptaa;
651 }
652 
653 
663 PTA *
665  l_int32 width,
666  l_int32 closeflag,
667  l_int32 removedups)
668 {
669 l_int32 i, n, x1, y1, x2, y2;
670 PTA *ptad, *ptat, *pta;
671 
672  PROCNAME("generatePtaPolyline");
673 
674  if (!ptas)
675  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
676  if (width < 1) {
677  L_WARNING("width < 1; setting to 1\n", procName);
678  width = 1;
679  }
680 
681  n = ptaGetCount(ptas);
682  ptat = ptaCreate(0);
683  if (n < 2) /* nothing to do */
684  return ptat;
685 
686  ptaGetIPt(ptas, 0, &x1, &y1);
687  for (i = 1; i < n; i++) {
688  ptaGetIPt(ptas, i, &x2, &y2);
689  pta = generatePtaWideLine(x1, y1, x2, y2, width);
690  ptaJoin(ptat, pta, 0, -1);
691  ptaDestroy(&pta);
692  x1 = x2;
693  y1 = y2;
694  }
695 
696  if (closeflag) {
697  ptaGetIPt(ptas, 0, &x2, &y2);
698  pta = generatePtaWideLine(x1, y1, x2, y2, width);
699  ptaJoin(ptat, pta, 0, -1);
700  ptaDestroy(&pta);
701  }
702 
703  if (removedups)
704  ptad = ptaRemoveDupsByAset(ptat);
705  else
706  ptad = ptaClone(ptat);
707 
708  ptaDestroy(&ptat);
709  return ptad;
710 }
711 
712 
721 PTA *
722 generatePtaGrid(l_int32 w,
723  l_int32 h,
724  l_int32 nx,
725  l_int32 ny,
726  l_int32 width)
727 {
728 l_int32 i, j, bx, by, x1, x2, y1, y2;
729 BOX *box;
730 BOXA *boxa;
731 PTA *pta;
732 
733  PROCNAME("generatePtaGrid");
734 
735  if (nx < 1 || ny < 1)
736  return (PTA *)ERROR_PTR("nx and ny must be > 0", procName, NULL);
737  if (w < 2 * nx || h < 2 * ny)
738  return (PTA *)ERROR_PTR("w and/or h too small", procName, NULL);
739  if (width < 1) {
740  L_WARNING("width < 1; setting to 1\n", procName);
741  width = 1;
742  }
743 
744  boxa = boxaCreate(nx * ny);
745  bx = (w + nx - 1) / nx;
746  by = (h + ny - 1) / ny;
747  for (i = 0; i < ny; i++) {
748  y1 = by * i;
749  y2 = L_MIN(y1 + by, h - 1);
750  for (j = 0; j < nx; j++) {
751  x1 = bx * j;
752  x2 = L_MIN(x1 + bx, w - 1);
753  box = boxCreate(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
754  boxaAddBox(boxa, box, L_INSERT);
755  }
756  }
757 
758  pta = generatePtaBoxa(boxa, width, 1);
759  boxaDestroy(&boxa);
760  return pta;
761 }
762 
763 
779 PTA *
781 {
782 l_int32 i, n, x, y, xp, yp;
783 PTA *ptad;
784 
785  PROCNAME("convertPtaLineTo4cc");
786 
787  if (!ptas)
788  return (PTA *)ERROR_PTR("ptas not defined", procName, NULL);
789 
790  n = ptaGetCount(ptas);
791  ptad = ptaCreate(n);
792  ptaGetIPt(ptas, 0, &xp, &yp);
793  ptaAddPt(ptad, xp, yp);
794  for (i = 1; i < n; i++) {
795  ptaGetIPt(ptas, i, &x, &y);
796  if (x != xp && y != yp) /* diagonal */
797  ptaAddPt(ptad, x, yp);
798  ptaAddPt(ptad, x, y);
799  xp = x;
800  yp = y;
801  }
802 
803  return ptad;
804 }
805 
806 
822 PTA *
823 generatePtaFilledCircle(l_int32 radius)
824 {
825 l_int32 x, y;
826 l_float32 radthresh, sqdist;
827 PTA *pta;
828 
829  PROCNAME("generatePtaFilledCircle");
830 
831  if (radius < 1)
832  return (PTA *)ERROR_PTR("radius must be >= 1", procName, NULL);
833 
834  pta = ptaCreate(0);
835  radthresh = (radius + 0.5) * (radius + 0.5);
836  for (y = 0; y <= 2 * radius; y++) {
837  for (x = 0; x <= 2 * radius; x++) {
838  sqdist = (l_float32)((y - radius) * (y - radius) +
839  (x - radius) * (x - radius));
840  if (sqdist <= radthresh)
841  ptaAddPt(pta, x, y);
842  }
843  }
844 
845  return pta;
846 }
847 
848 
862 PTA *
864 {
865 l_int32 x, y;
866 PTA *pta;
867 
868  PROCNAME("generatePtaFilledSquare");
869  if (side < 1)
870  return (PTA *)ERROR_PTR("side must be > 0", procName, NULL);
871 
872  pta = ptaCreate(0);
873  for (y = 0; y < side; y++)
874  for (x = 0; x < side; x++)
875  ptaAddPt(pta, x, y);
876 
877  return pta;
878 }
879 
880 
896 PTA *
898  l_int32 y,
899  l_float64 length,
900  l_float64 radang)
901 {
902 l_int32 x2, y2; /* the point at the other end of the line */
903 
904  x2 = x + (l_int32)((length - 1.0) * cos(radang));
905  y2 = y + (l_int32)((length - 1.0) * sin(radang));
906  return generatePtaLine(x, y, x2, y2);
907 }
908 
909 
920 l_ok
921 locatePtRadially(l_int32 xr,
922  l_int32 yr,
923  l_float64 dist,
924  l_float64 radang,
925  l_float64 *px,
926  l_float64 *py)
927 {
928  PROCNAME("locatePtRadially");
929 
930  if (!px || !py)
931  return ERROR_INT("&x and &y not both defined", procName, 1);
932 
933  *px = xr + dist * cos(radang);
934  *py = yr + dist * sin(radang);
935  return 0;
936 }
937 
938 
939 /*------------------------------------------------------------------*
940  * Rendering function plots directly on images *
941  *------------------------------------------------------------------*/
962 l_ok
964  NUMA *na,
965  l_int32 plotloc,
966  l_int32 linewidth,
967  l_int32 max,
968  l_uint32 color)
969 {
970 l_int32 w, h, size, rval, gval, bval;
971 PIX *pix1;
972 PTA *pta;
973 
974  PROCNAME("pixRenderPlotFromNuma");
975 
976  if (!ppix)
977  return ERROR_INT("&pix not defined", procName, 1);
978  if (*ppix == NULL)
979  return ERROR_INT("pix not defined", procName, 1);
980 
981  pixGetDimensions(*ppix, &w, &h, NULL);
982  size = (plotloc == L_PLOT_AT_TOP || plotloc == L_PLOT_AT_MID_HORIZ ||
983  plotloc == L_PLOT_AT_BOT) ? h : w;
984  pta = makePlotPtaFromNuma(na, size, plotloc, linewidth, max);
985  if (!pta)
986  return ERROR_INT("pta not made", procName, 1);
987 
988  if (pixGetDepth(*ppix) != 32) {
989  pix1 = pixConvertTo32(*ppix);
990  pixDestroy(ppix);
991  *ppix = pix1;
992  }
993  extractRGBValues(color, &rval, &gval, &bval);
994  pixRenderPtaArb(*ppix, pta, rval, gval, bval);
995  ptaDestroy(&pta);
996  return 0;
997 }
998 
999 
1020 PTA *
1022  l_int32 size,
1023  l_int32 plotloc,
1024  l_int32 linewidth,
1025  l_int32 max)
1026 {
1027 l_int32 orient, refpos;
1028 
1029  PROCNAME("makePlotPtaFromNuma");
1030 
1031  if (!na)
1032  return (PTA *)ERROR_PTR("na not defined", procName, NULL);
1033  if (plotloc == L_PLOT_AT_TOP || plotloc == L_PLOT_AT_MID_HORIZ ||
1034  plotloc == L_PLOT_AT_BOT) {
1035  orient = L_HORIZONTAL_LINE;
1036  } else if (plotloc == L_PLOT_AT_LEFT || plotloc == L_PLOT_AT_MID_VERT ||
1037  plotloc == L_PLOT_AT_RIGHT) {
1038  orient = L_VERTICAL_LINE;
1039  } else {
1040  return (PTA *)ERROR_PTR("invalid plotloc", procName, NULL);
1041  }
1042 
1043  if (plotloc == L_PLOT_AT_LEFT || plotloc == L_PLOT_AT_TOP)
1044  refpos = max;
1045  else if (plotloc == L_PLOT_AT_MID_VERT || plotloc == L_PLOT_AT_MID_HORIZ)
1046  refpos = size / 2;
1047  else /* L_PLOT_AT_RIGHT || L_PLOT_AT_BOT */
1048  refpos = size - max - 1;
1049 
1050  return makePlotPtaFromNumaGen(na, orient, linewidth, refpos, max, 1);
1051 }
1052 
1053 
1076 l_ok
1078  NUMA *na,
1079  l_int32 orient,
1080  l_int32 linewidth,
1081  l_int32 refpos,
1082  l_int32 max,
1083  l_int32 drawref,
1084  l_uint32 color)
1085 {
1086 l_int32 rval, gval, bval;
1087 PIX *pix1;
1088 PTA *pta;
1089 
1090  PROCNAME("pixRenderPlotFromNumaGen");
1091 
1092  if (!ppix)
1093  return ERROR_INT("&pix not defined", procName, 1);
1094  if (*ppix == NULL)
1095  return ERROR_INT("pix not defined", procName, 1);
1096 
1097  pta = makePlotPtaFromNumaGen(na, orient, linewidth, refpos, max, drawref);
1098  if (!pta)
1099  return ERROR_INT("pta not made", procName, 1);
1100 
1101  if (pixGetDepth(*ppix) != 32) {
1102  pix1 = pixConvertTo32(*ppix);
1103  pixDestroy(ppix);
1104  *ppix = pix1;
1105  }
1106  extractRGBValues(color, &rval, &gval, &bval);
1107  pixRenderPtaArb(*ppix, pta, rval, gval, bval);
1108  ptaDestroy(&pta);
1109  return 0;
1110 }
1111 
1112 
1141 PTA *
1143  l_int32 orient,
1144  l_int32 linewidth,
1145  l_int32 refpos,
1146  l_int32 max,
1147  l_int32 drawref)
1148 {
1149 l_int32 i, n, maxw, maxh;
1150 l_float32 minval, maxval, absval, val, scale, start, del;
1151 PTA *pta1, *pta2, *ptad;
1152 
1153  PROCNAME("makePlotPtaFromNumaGen");
1154 
1155  if (!na)
1156  return (PTA *)ERROR_PTR("na not defined", procName, NULL);
1157  if (orient != L_HORIZONTAL_LINE && orient != L_VERTICAL_LINE)
1158  return (PTA *)ERROR_PTR("invalid orient", procName, NULL);
1159  if (linewidth < 1) {
1160  L_WARNING("linewidth < 1; setting to 1\n", procName);
1161  linewidth = 1;
1162  }
1163  if (linewidth > 7) {
1164  L_WARNING("linewidth > 7; setting to 7\n", procName);
1165  linewidth = 7;
1166  }
1167 
1168  numaGetMin(na, &minval, NULL);
1169  numaGetMax(na, &maxval, NULL);
1170  absval = L_MAX(L_ABS(minval), L_ABS(maxval));
1171  scale = (l_float32)max / (l_float32)absval;
1172  n = numaGetCount(na);
1173  numaGetParameters(na, &start, &del);
1174 
1175  /* Generate the plot points */
1176  pta1 = ptaCreate(n);
1177  for (i = 0; i < n; i++) {
1178  numaGetFValue(na, i, &val);
1179  if (orient == L_HORIZONTAL_LINE) {
1180  ptaAddPt(pta1, start + i * del, refpos + scale * val);
1181  maxw = (del >= 0) ? start + n * del + linewidth
1182  : start + linewidth;
1183  maxh = refpos + max + linewidth;
1184  } else { /* vertical line */
1185  ptaAddPt(pta1, refpos + scale * val, start + i * del);
1186  maxw = refpos + max + linewidth;
1187  maxh = (del >= 0) ? start + n * del + linewidth
1188  : start + linewidth;
1189  }
1190  }
1191 
1192  /* Optionally, widen the plot */
1193  if (linewidth > 1) {
1194  if (linewidth % 2 == 0) /* even linewidth; use side of a square */
1195  pta2 = generatePtaFilledSquare(linewidth);
1196  else /* odd linewidth; use radius of a circle */
1197  pta2 = generatePtaFilledCircle(linewidth / 2);
1198  ptad = ptaReplicatePattern(pta1, NULL, pta2, linewidth / 2,
1199  linewidth / 2, maxw, maxh);
1200  ptaDestroy(&pta2);
1201  } else {
1202  ptad = ptaClone(pta1);
1203  }
1204  ptaDestroy(&pta1);
1205 
1206  /* Optionally, add the reference lines */
1207  if (drawref) {
1208  if (orient == L_HORIZONTAL_LINE) {
1209  pta1 = generatePtaLine(start, refpos, start + n * del, refpos);
1210  ptaJoin(ptad, pta1, 0, -1);
1211  ptaDestroy(&pta1);
1212  pta1 = generatePtaLine(start, refpos - max,
1213  start, refpos + max);
1214  ptaJoin(ptad, pta1, 0, -1);
1215  } else { /* vertical line */
1216  pta1 = generatePtaLine(refpos, start, refpos, start + n * del);
1217  ptaJoin(ptad, pta1, 0, -1);
1218  ptaDestroy(&pta1);
1219  pta1 = generatePtaLine(refpos - max, start,
1220  refpos + max, start);
1221  ptaJoin(ptad, pta1, 0, -1);
1222  }
1223  ptaDestroy(&pta1);
1224  }
1225 
1226  return ptad;
1227 }
1228 
1229 
1230 /*------------------------------------------------------------------*
1231  * Pta generation for arbitrary shapes built with lines *
1232  *------------------------------------------------------------------*/
1253 l_ok
1255  PTA *pta,
1256  l_int32 op)
1257 {
1258 l_int32 i, n, x, y, w, h, d, maxval;
1259 
1260  PROCNAME("pixRenderPta");
1261 
1262  if (!pix)
1263  return ERROR_INT("pix not defined", procName, 1);
1264  if (pixGetColormap(pix))
1265  return ERROR_INT("pix is colormapped", procName, 1);
1266  if (!pta)
1267  return ERROR_INT("pta not defined", procName, 1);
1268  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1269  return ERROR_INT("invalid op", procName, 1);
1270 
1271  pixGetDimensions(pix, &w, &h, &d);
1272  maxval = 1;
1273  if (op == L_SET_PIXELS) {
1274  switch (d)
1275  {
1276  case 2:
1277  maxval = 0x3;
1278  break;
1279  case 4:
1280  maxval = 0xf;
1281  break;
1282  case 8:
1283  maxval = 0xff;
1284  break;
1285  case 16:
1286  maxval = 0xffff;
1287  break;
1288  case 32:
1289  maxval = 0xffffffff;
1290  break;
1291  }
1292  }
1293 
1294  n = ptaGetCount(pta);
1295  for (i = 0; i < n; i++) {
1296  ptaGetIPt(pta, i, &x, &y);
1297  if (x < 0 || x >= w)
1298  continue;
1299  if (y < 0 || y >= h)
1300  continue;
1301  switch (op)
1302  {
1303  case L_SET_PIXELS:
1304  pixSetPixel(pix, x, y, maxval);
1305  break;
1306  case L_CLEAR_PIXELS:
1307  pixClearPixel(pix, x, y);
1308  break;
1309  case L_FLIP_PIXELS:
1310  pixFlipPixel(pix, x, y);
1311  break;
1312  default:
1313  break;
1314  }
1315  }
1316 
1317  return 0;
1318 }
1319 
1320 
1342 l_ok
1344  PTA *pta,
1345  l_uint8 rval,
1346  l_uint8 gval,
1347  l_uint8 bval)
1348 {
1349 l_int32 i, n, x, y, w, h, d, index;
1350 l_uint8 val;
1351 l_uint32 val32;
1352 PIXCMAP *cmap;
1353 
1354  PROCNAME("pixRenderPtaArb");
1355 
1356  if (!pix)
1357  return ERROR_INT("pix not defined", procName, 1);
1358  if (!pta)
1359  return ERROR_INT("pta not defined", procName, 1);
1360  d = pixGetDepth(pix);
1361  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 32)
1362  return ERROR_INT("depth not in {1,2,4,8,32}", procName, 1);
1363 
1364  if (d == 1) {
1365  pixRenderPta(pix, pta, L_SET_PIXELS);
1366  return 0;
1367  }
1368 
1369  cmap = pixGetColormap(pix);
1370  pixGetDimensions(pix, &w, &h, &d);
1371  if (cmap) {
1372  pixcmapAddNearestColor(cmap, rval, gval, bval, &index);
1373  } else {
1374  if (d == 2)
1375  val = (rval + gval + bval) / (3 * 64);
1376  else if (d == 4)
1377  val = (rval + gval + bval) / (3 * 16);
1378  else if (d == 8)
1379  val = (rval + gval + bval) / 3;
1380  else /* d == 32 */
1381  composeRGBPixel(rval, gval, bval, &val32);
1382  }
1383 
1384  n = ptaGetCount(pta);
1385  for (i = 0; i < n; i++) {
1386  ptaGetIPt(pta, i, &x, &y);
1387  if (x < 0 || x >= w)
1388  continue;
1389  if (y < 0 || y >= h)
1390  continue;
1391  if (cmap)
1392  pixSetPixel(pix, x, y, index);
1393  else if (d == 32)
1394  pixSetPixel(pix, x, y, val32);
1395  else
1396  pixSetPixel(pix, x, y, val);
1397  }
1398 
1399  return 0;
1400 }
1401 
1402 
1417 l_ok
1419  PTA *pta,
1420  l_uint8 rval,
1421  l_uint8 gval,
1422  l_uint8 bval,
1423  l_float32 fract)
1424 {
1425 l_int32 i, n, x, y, w, h;
1426 l_uint8 nrval, ngval, nbval;
1427 l_uint32 val32;
1428 l_float32 frval, fgval, fbval;
1429 
1430  PROCNAME("pixRenderPtaBlend");
1431 
1432  if (!pix)
1433  return ERROR_INT("pix not defined", procName, 1);
1434  if (!pta)
1435  return ERROR_INT("pta not defined", procName, 1);
1436  if (pixGetDepth(pix) != 32)
1437  return ERROR_INT("depth not 32 bpp", procName, 1);
1438  if (fract < 0.0 || fract > 1.0) {
1439  L_WARNING("fract must be in [0.0, 1.0]; setting to 0.5\n", procName);
1440  fract = 0.5;
1441  }
1442 
1443  pixGetDimensions(pix, &w, &h, NULL);
1444  n = ptaGetCount(pta);
1445  frval = fract * rval;
1446  fgval = fract * gval;
1447  fbval = fract * bval;
1448  for (i = 0; i < n; i++) {
1449  ptaGetIPt(pta, i, &x, &y);
1450  if (x < 0 || x >= w)
1451  continue;
1452  if (y < 0 || y >= h)
1453  continue;
1454  pixGetPixel(pix, x, y, &val32);
1455  nrval = GET_DATA_BYTE(&val32, COLOR_RED);
1456  nrval = (l_uint8)((1. - fract) * nrval + frval);
1457  ngval = GET_DATA_BYTE(&val32, COLOR_GREEN);
1458  ngval = (l_uint8)((1. - fract) * ngval + fgval);
1459  nbval = GET_DATA_BYTE(&val32, COLOR_BLUE);
1460  nbval = (l_uint8)((1. - fract) * nbval + fbval);
1461  composeRGBPixel(nrval, ngval, nbval, &val32);
1462  pixSetPixel(pix, x, y, val32);
1463  }
1464 
1465  return 0;
1466 }
1467 
1468 
1469 /*------------------------------------------------------------------*
1470  * Rendering of arbitrary shapes built with lines *
1471  *------------------------------------------------------------------*/
1482 l_ok
1484  l_int32 x1,
1485  l_int32 y1,
1486  l_int32 x2,
1487  l_int32 y2,
1488  l_int32 width,
1489  l_int32 op)
1490 {
1491 PTA *pta;
1492 
1493  PROCNAME("pixRenderLine");
1494 
1495  if (!pix)
1496  return ERROR_INT("pix not defined", procName, 1);
1497  if (width < 1) {
1498  L_WARNING("width must be > 0; setting to 1\n", procName);
1499  width = 1;
1500  }
1501  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1502  return ERROR_INT("invalid op", procName, 1);
1503 
1504  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1505  return ERROR_INT("pta not made", procName, 1);
1506  pixRenderPta(pix, pta, op);
1507  ptaDestroy(&pta);
1508  return 0;
1509 }
1510 
1511 
1522 l_ok
1524  l_int32 x1,
1525  l_int32 y1,
1526  l_int32 x2,
1527  l_int32 y2,
1528  l_int32 width,
1529  l_uint8 rval,
1530  l_uint8 gval,
1531  l_uint8 bval)
1532 {
1533 PTA *pta;
1534 
1535  PROCNAME("pixRenderLineArb");
1536 
1537  if (!pix)
1538  return ERROR_INT("pix not defined", procName, 1);
1539  if (width < 1) {
1540  L_WARNING("width must be > 0; setting to 1\n", procName);
1541  width = 1;
1542  }
1543 
1544  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1545  return ERROR_INT("pta not made", procName, 1);
1546  pixRenderPtaArb(pix, pta, rval, gval, bval);
1547  ptaDestroy(&pta);
1548  return 0;
1549 }
1550 
1551 
1563 l_ok
1565  l_int32 x1,
1566  l_int32 y1,
1567  l_int32 x2,
1568  l_int32 y2,
1569  l_int32 width,
1570  l_uint8 rval,
1571  l_uint8 gval,
1572  l_uint8 bval,
1573  l_float32 fract)
1574 {
1575 PTA *pta;
1576 
1577  PROCNAME("pixRenderLineBlend");
1578 
1579  if (!pix)
1580  return ERROR_INT("pix not defined", procName, 1);
1581  if (width < 1) {
1582  L_WARNING("width must be > 0; setting to 1\n", procName);
1583  width = 1;
1584  }
1585 
1586  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1587  return ERROR_INT("pta not made", procName, 1);
1588  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1589  ptaDestroy(&pta);
1590  return 0;
1591 }
1592 
1593 
1603 l_ok
1605  BOX *box,
1606  l_int32 width,
1607  l_int32 op)
1608 {
1609 PTA *pta;
1610 
1611  PROCNAME("pixRenderBox");
1612 
1613  if (!pix)
1614  return ERROR_INT("pix not defined", procName, 1);
1615  if (!box)
1616  return ERROR_INT("box not defined", procName, 1);
1617  if (width < 1) {
1618  L_WARNING("width < 1; setting to 1\n", procName);
1619  width = 1;
1620  }
1621  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1622  return ERROR_INT("invalid op", procName, 1);
1623 
1624  if ((pta = generatePtaBox(box, width)) == NULL)
1625  return ERROR_INT("pta not made", procName, 1);
1626  pixRenderPta(pix, pta, op);
1627  ptaDestroy(&pta);
1628  return 0;
1629 }
1630 
1631 
1641 l_ok
1643  BOX *box,
1644  l_int32 width,
1645  l_uint8 rval,
1646  l_uint8 gval,
1647  l_uint8 bval)
1648 {
1649 PTA *pta;
1650 
1651  PROCNAME("pixRenderBoxArb");
1652 
1653  if (!pix)
1654  return ERROR_INT("pix not defined", procName, 1);
1655  if (!box)
1656  return ERROR_INT("box not defined", procName, 1);
1657  if (width < 1) {
1658  L_WARNING("width < 1; setting to 1\n", procName);
1659  width = 1;
1660  }
1661 
1662  if ((pta = generatePtaBox(box, width)) == NULL)
1663  return ERROR_INT("pta not made", procName, 1);
1664  pixRenderPtaArb(pix, pta, rval, gval, bval);
1665  ptaDestroy(&pta);
1666  return 0;
1667 }
1668 
1669 
1681 l_ok
1683  BOX *box,
1684  l_int32 width,
1685  l_uint8 rval,
1686  l_uint8 gval,
1687  l_uint8 bval,
1688  l_float32 fract)
1689 {
1690 PTA *pta;
1691 
1692  PROCNAME("pixRenderBoxBlend");
1693 
1694  if (!pix)
1695  return ERROR_INT("pix not defined", procName, 1);
1696  if (!box)
1697  return ERROR_INT("box not defined", procName, 1);
1698  if (width < 1) {
1699  L_WARNING("width < 1; setting to 1\n", procName);
1700  width = 1;
1701  }
1702 
1703  if ((pta = generatePtaBox(box, width)) == NULL)
1704  return ERROR_INT("pta not made", procName, 1);
1705  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1706  ptaDestroy(&pta);
1707  return 0;
1708 }
1709 
1710 
1720 l_ok
1722  BOXA *boxa,
1723  l_int32 width,
1724  l_int32 op)
1725 {
1726 PTA *pta;
1727 
1728  PROCNAME("pixRenderBoxa");
1729 
1730  if (!pix)
1731  return ERROR_INT("pix not defined", procName, 1);
1732  if (!boxa)
1733  return ERROR_INT("boxa not defined", procName, 1);
1734  if (width < 1) {
1735  L_WARNING("width < 1; setting to 1\n", procName);
1736  width = 1;
1737  }
1738  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1739  return ERROR_INT("invalid op", procName, 1);
1740 
1741  if ((pta = generatePtaBoxa(boxa, width, 0)) == NULL)
1742  return ERROR_INT("pta not made", procName, 1);
1743  pixRenderPta(pix, pta, op);
1744  ptaDestroy(&pta);
1745  return 0;
1746 }
1747 
1748 
1758 l_ok
1760  BOXA *boxa,
1761  l_int32 width,
1762  l_uint8 rval,
1763  l_uint8 gval,
1764  l_uint8 bval)
1765 {
1766 PTA *pta;
1767 
1768  PROCNAME("pixRenderBoxaArb");
1769 
1770  if (!pix)
1771  return ERROR_INT("pix not defined", procName, 1);
1772  if (!boxa)
1773  return ERROR_INT("boxa not defined", procName, 1);
1774  if (width < 1) {
1775  L_WARNING("width < 1; setting to 1\n", procName);
1776  width = 1;
1777  }
1778 
1779  if ((pta = generatePtaBoxa(boxa, width, 0)) == NULL)
1780  return ERROR_INT("pta not made", procName, 1);
1781  pixRenderPtaArb(pix, pta, rval, gval, bval);
1782  ptaDestroy(&pta);
1783  return 0;
1784 }
1785 
1786 
1799 l_ok
1801  BOXA *boxa,
1802  l_int32 width,
1803  l_uint8 rval,
1804  l_uint8 gval,
1805  l_uint8 bval,
1806  l_float32 fract,
1807  l_int32 removedups)
1808 {
1809 PTA *pta;
1810 
1811  PROCNAME("pixRenderBoxaBlend");
1812 
1813  if (!pix)
1814  return ERROR_INT("pix not defined", procName, 1);
1815  if (!boxa)
1816  return ERROR_INT("boxa not defined", procName, 1);
1817  if (width < 1) {
1818  L_WARNING("width < 1; setting to 1\n", procName);
1819  width = 1;
1820  }
1821 
1822  if ((pta = generatePtaBoxa(boxa, width, removedups)) == NULL)
1823  return ERROR_INT("pta not made", procName, 1);
1824  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1825  ptaDestroy(&pta);
1826  return 0;
1827 }
1828 
1829 
1842 l_ok
1844  BOX *box,
1845  l_int32 spacing,
1846  l_int32 width,
1847  l_int32 orient,
1848  l_int32 outline,
1849  l_int32 op)
1850 {
1851 PTA *pta;
1852 
1853  PROCNAME("pixRenderHashBox");
1854 
1855  if (!pix)
1856  return ERROR_INT("pix not defined", procName, 1);
1857  if (!box)
1858  return ERROR_INT("box not defined", procName, 1);
1859  if (spacing <= 1)
1860  return ERROR_INT("spacing not > 1", procName, 1);
1861  if (width < 1) {
1862  L_WARNING("width < 1; setting to 1\n", procName);
1863  width = 1;
1864  }
1865  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1866  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1867  return ERROR_INT("invalid line orientation", procName, 1);
1868  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1869  return ERROR_INT("invalid op", procName, 1);
1870 
1871  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1872  if (!pta)
1873  return ERROR_INT("pta not made", procName, 1);
1874  pixRenderPta(pix, pta, op);
1875  ptaDestroy(&pta);
1876  return 0;
1877 }
1878 
1879 
1892 l_ok
1894  BOX *box,
1895  l_int32 spacing,
1896  l_int32 width,
1897  l_int32 orient,
1898  l_int32 outline,
1899  l_int32 rval,
1900  l_int32 gval,
1901  l_int32 bval)
1902 {
1903 PTA *pta;
1904 
1905  PROCNAME("pixRenderHashBoxArb");
1906 
1907  if (!pix)
1908  return ERROR_INT("pix not defined", procName, 1);
1909  if (!box)
1910  return ERROR_INT("box not defined", procName, 1);
1911  if (spacing <= 1)
1912  return ERROR_INT("spacing not > 1", procName, 1);
1913  if (width < 1) {
1914  L_WARNING("width < 1; setting to 1\n", procName);
1915  width = 1;
1916  }
1917  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1918  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1919  return ERROR_INT("invalid line orientation", procName, 1);
1920 
1921  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1922  if (!pta)
1923  return ERROR_INT("pta not made", procName, 1);
1924  pixRenderPtaArb(pix, pta, rval, gval, bval);
1925  ptaDestroy(&pta);
1926  return 0;
1927 }
1928 
1929 
1944 l_ok
1946  BOX *box,
1947  l_int32 spacing,
1948  l_int32 width,
1949  l_int32 orient,
1950  l_int32 outline,
1951  l_int32 rval,
1952  l_int32 gval,
1953  l_int32 bval,
1954  l_float32 fract)
1955 {
1956 PTA *pta;
1957 
1958  PROCNAME("pixRenderHashBoxBlend");
1959 
1960  if (!pix)
1961  return ERROR_INT("pix not defined", procName, 1);
1962  if (!box)
1963  return ERROR_INT("box not defined", procName, 1);
1964  if (spacing <= 1)
1965  return ERROR_INT("spacing not > 1", procName, 1);
1966  if (width < 1) {
1967  L_WARNING("width < 1; setting to 1\n", procName);
1968  width = 1;
1969  }
1970  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1971  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1972  return ERROR_INT("invalid line orientation", procName, 1);
1973 
1974  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1975  if (!pta)
1976  return ERROR_INT("pta not made", procName, 1);
1977  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1978  ptaDestroy(&pta);
1979  return 0;
1980 }
1981 
1982 
2002 l_ok
2004  PIX *pixm,
2005  l_int32 x,
2006  l_int32 y,
2007  l_int32 spacing,
2008  l_int32 width,
2009  l_int32 orient,
2010  l_int32 outline,
2011  l_int32 rval,
2012  l_int32 gval,
2013  l_int32 bval)
2014 {
2015 l_int32 w, h;
2016 BOX *box1, *box2;
2017 PIX *pix1;
2018 PTA *pta1, *pta2;
2019 
2020  PROCNAME("pixRenderHashMaskArb");
2021 
2022  if (!pix)
2023  return ERROR_INT("pix not defined", procName, 1);
2024  if (!pixm || pixGetDepth(pixm) != 1)
2025  return ERROR_INT("pixm not defined or not 1 bpp", procName, 1);
2026  if (spacing <= 1)
2027  return ERROR_INT("spacing not > 1", procName, 1);
2028  if (width < 1) {
2029  L_WARNING("width < 1; setting to 1\n", procName);
2030  width = 1;
2031  }
2032  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2033  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2034  return ERROR_INT("invalid line orientation", procName, 1);
2035 
2036  /* Get the points for masked hash lines */
2037  pixGetDimensions(pixm, &w, &h, NULL);
2038  box1 = boxCreate(0, 0, w, h);
2039  pta1 = generatePtaHashBox(box1, spacing, width, orient, outline);
2040  pta2 = ptaCropToMask(pta1, pixm);
2041  boxDestroy(&box1);
2042  ptaDestroy(&pta1);
2043 
2044  /* Clip out the region and apply the hash lines */
2045  box2 = boxCreate(x, y, w, h);
2046  pix1 = pixClipRectangle(pix, box2, NULL);
2047  pixRenderPtaArb(pix1, pta2, rval, gval, bval);
2048  ptaDestroy(&pta2);
2049  boxDestroy(&box2);
2050 
2051  /* Rasterop the altered rectangle back in place */
2052  pixRasterop(pix, x, y, w, h, PIX_SRC, pix1, 0, 0);
2053  pixDestroy(&pix1);
2054  return 0;
2055 }
2056 
2057 
2070 l_ok
2072  BOXA *boxa,
2073  l_int32 spacing,
2074  l_int32 width,
2075  l_int32 orient,
2076  l_int32 outline,
2077  l_int32 op)
2078  {
2079 PTA *pta;
2080 
2081  PROCNAME("pixRenderHashBoxa");
2082 
2083  if (!pix)
2084  return ERROR_INT("pix not defined", procName, 1);
2085  if (!boxa)
2086  return ERROR_INT("boxa not defined", procName, 1);
2087  if (spacing <= 1)
2088  return ERROR_INT("spacing not > 1", procName, 1);
2089  if (width < 1) {
2090  L_WARNING("width < 1; setting to 1\n", procName);
2091  width = 1;
2092  }
2093  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2094  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2095  return ERROR_INT("invalid line orientation", procName, 1);
2096  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
2097  return ERROR_INT("invalid op", procName, 1);
2098 
2099  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2100  if (!pta)
2101  return ERROR_INT("pta not made", procName, 1);
2102  pixRenderPta(pix, pta, op);
2103  ptaDestroy(&pta);
2104  return 0;
2105 }
2106 
2107 
2120 l_ok
2122  BOXA *boxa,
2123  l_int32 spacing,
2124  l_int32 width,
2125  l_int32 orient,
2126  l_int32 outline,
2127  l_int32 rval,
2128  l_int32 gval,
2129  l_int32 bval)
2130 {
2131 PTA *pta;
2132 
2133  PROCNAME("pixRenderHashBoxArb");
2134 
2135  if (!pix)
2136  return ERROR_INT("pix not defined", procName, 1);
2137  if (!boxa)
2138  return ERROR_INT("boxa not defined", procName, 1);
2139  if (spacing <= 1)
2140  return ERROR_INT("spacing not > 1", procName, 1);
2141  if (width < 1) {
2142  L_WARNING("width < 1; setting to 1\n", procName);
2143  width = 1;
2144  }
2145  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2146  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2147  return ERROR_INT("invalid line orientation", procName, 1);
2148 
2149  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2150  if (!pta)
2151  return ERROR_INT("pta not made", procName, 1);
2152  pixRenderPtaArb(pix, pta, rval, gval, bval);
2153  ptaDestroy(&pta);
2154  return 0;
2155 }
2156 
2157 
2172 l_ok
2174  BOXA *boxa,
2175  l_int32 spacing,
2176  l_int32 width,
2177  l_int32 orient,
2178  l_int32 outline,
2179  l_int32 rval,
2180  l_int32 gval,
2181  l_int32 bval,
2182  l_float32 fract)
2183 {
2184 PTA *pta;
2185 
2186  PROCNAME("pixRenderHashBoxaBlend");
2187 
2188  if (!pix)
2189  return ERROR_INT("pix not defined", procName, 1);
2190  if (!boxa)
2191  return ERROR_INT("boxa not defined", procName, 1);
2192  if (spacing <= 1)
2193  return ERROR_INT("spacing not > 1", procName, 1);
2194  if (width < 1) {
2195  L_WARNING("width < 1; setting to 1\n", procName);
2196  width = 1;
2197  }
2198  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2199  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2200  return ERROR_INT("invalid line orientation", procName, 1);
2201 
2202  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2203  if (!pta)
2204  return ERROR_INT("pta not made", procName, 1);
2205  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
2206  ptaDestroy(&pta);
2207  return 0;
2208 }
2209 
2210 
2226 l_ok
2228  PTA *ptas,
2229  l_int32 width,
2230  l_int32 op,
2231  l_int32 closeflag)
2232 {
2233 PTA *pta;
2234 
2235  PROCNAME("pixRenderPolyline");
2236 
2237  if (!pix)
2238  return ERROR_INT("pix not defined", procName, 1);
2239  if (!ptas)
2240  return ERROR_INT("ptas not defined", procName, 1);
2241  if (width < 1) {
2242  L_WARNING("width < 1; setting to 1\n", procName);
2243  width = 1;
2244  }
2245  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
2246  return ERROR_INT("invalid op", procName, 1);
2247 
2248  if ((pta = generatePtaPolyline(ptas, width, closeflag, 0)) == NULL)
2249  return ERROR_INT("pta not made", procName, 1);
2250  pixRenderPta(pix, pta, op);
2251  ptaDestroy(&pta);
2252  return 0;
2253 }
2254 
2255 
2271 l_ok
2273  PTA *ptas,
2274  l_int32 width,
2275  l_uint8 rval,
2276  l_uint8 gval,
2277  l_uint8 bval,
2278  l_int32 closeflag)
2279 {
2280 PTA *pta;
2281 
2282  PROCNAME("pixRenderPolylineArb");
2283 
2284  if (!pix)
2285  return ERROR_INT("pix not defined", procName, 1);
2286  if (!ptas)
2287  return ERROR_INT("ptas not defined", procName, 1);
2288  if (width < 1) {
2289  L_WARNING("width < 1; setting to 1\n", procName);
2290  width = 1;
2291  }
2292 
2293  if ((pta = generatePtaPolyline(ptas, width, closeflag, 0)) == NULL)
2294  return ERROR_INT("pta not made", procName, 1);
2295  pixRenderPtaArb(pix, pta, rval, gval, bval);
2296  ptaDestroy(&pta);
2297  return 0;
2298 }
2299 
2300 
2314 l_ok
2316  PTA *ptas,
2317  l_int32 width,
2318  l_uint8 rval,
2319  l_uint8 gval,
2320  l_uint8 bval,
2321  l_float32 fract,
2322  l_int32 closeflag,
2323  l_int32 removedups)
2324 {
2325 PTA *pta;
2326 
2327  PROCNAME("pixRenderPolylineBlend");
2328 
2329  if (!pix)
2330  return ERROR_INT("pix not defined", procName, 1);
2331  if (!ptas)
2332  return ERROR_INT("ptas not defined", procName, 1);
2333  if (width < 1) {
2334  L_WARNING("width < 1; setting to 1\n", procName);
2335  width = 1;
2336  }
2337 
2338  if ((pta = generatePtaPolyline(ptas, width, closeflag, removedups)) == NULL)
2339  return ERROR_INT("pta not made", procName, 1);
2340  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
2341  ptaDestroy(&pta);
2342  return 0;
2343 }
2344 
2345 
2355 l_ok
2357  l_int32 nx,
2358  l_int32 ny,
2359  l_int32 width,
2360  l_uint8 rval,
2361  l_uint8 gval,
2362  l_uint8 bval)
2363 {
2364 l_int32 w, h;
2365 PTA *pta;
2366 
2367  PROCNAME("pixRenderGridArb");
2368 
2369  if (!pix)
2370  return ERROR_INT("pix not defined", procName, 1);
2371  if (nx < 1 || ny < 1)
2372  return ERROR_INT("nx, ny must be > 0", procName, 1);
2373  if (width < 1) {
2374  L_WARNING("width < 1; setting to 1\n", procName);
2375  width = 1;
2376  }
2377 
2378  pixGetDimensions(pix, &w, &h, NULL);
2379  if ((pta = generatePtaGrid(w, h, nx, ny, width)) == NULL)
2380  return ERROR_INT("pta not made", procName, 1);
2381  pixRenderPtaArb(pix, pta, rval, gval, bval);
2382  ptaDestroy(&pta);
2383  return 0;
2384 }
2385 
2386 
2415 PIX *
2417  PTAA *ptaa,
2418  l_int32 polyflag,
2419  l_int32 width,
2420  l_int32 closeflag)
2421 {
2422 l_int32 i, n, index, rval, gval, bval;
2423 PIXCMAP *cmap;
2424 PTA *pta, *ptat;
2425 PIX *pixd;
2426 
2427  PROCNAME("pixRenderRandomCmapPtaa");
2428 
2429  if (!pix)
2430  return (PIX *)ERROR_PTR("pix not defined", procName, NULL);
2431  if (!ptaa)
2432  return (PIX *)ERROR_PTR("ptaa not defined", procName, NULL);
2433  if (polyflag != 0 && width < 1) {
2434  L_WARNING("width < 1; setting to 1\n", procName);
2435  width = 1;
2436  }
2437 
2438  pixd = pixConvertTo8(pix, FALSE);
2439  cmap = pixcmapCreateRandom(8, 1, 1);
2440  pixSetColormap(pixd, cmap);
2441 
2442  if ((n = ptaaGetCount(ptaa)) == 0)
2443  return pixd;
2444 
2445  for (i = 0; i < n; i++) {
2446  index = 1 + (i % 254);
2447  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
2448  pta = ptaaGetPta(ptaa, i, L_CLONE);
2449  if (polyflag)
2450  ptat = generatePtaPolyline(pta, width, closeflag, 0);
2451  else
2452  ptat = ptaClone(pta);
2453  pixRenderPtaArb(pixd, ptat, rval, gval, bval);
2454  ptaDestroy(&pta);
2455  ptaDestroy(&ptat);
2456  }
2457 
2458  return pixd;
2459 }
2460 
2461 
2462 
2463 /*------------------------------------------------------------------*
2464  * Rendering and filling of polygons *
2465  *------------------------------------------------------------------*/
2484 PIX *
2486  l_int32 width,
2487  l_int32 *pxmin,
2488  l_int32 *pymin)
2489 {
2490 l_float32 fxmin, fxmax, fymin, fymax;
2491 PIX *pixd;
2492 PTA *pta1, *pta2;
2493 
2494  PROCNAME("pixRenderPolygon");
2495 
2496  if (pxmin) *pxmin = 0;
2497  if (pymin) *pymin = 0;
2498  if (!ptas)
2499  return (PIX *)ERROR_PTR("ptas not defined", procName, NULL);
2500 
2501  /* Generate a 4-connected polygon line */
2502  if ((pta1 = generatePtaPolyline(ptas, width, 1, 0)) == NULL)
2503  return (PIX *)ERROR_PTR("pta1 not made", procName, NULL);
2504  if (width < 2)
2505  pta2 = convertPtaLineTo4cc(pta1);
2506  else
2507  pta2 = ptaClone(pta1);
2508 
2509  /* Render onto a minimum-sized pix */
2510  ptaGetRange(pta2, &fxmin, &fxmax, &fymin, &fymax);
2511  if (pxmin) *pxmin = (l_int32)(fxmin + 0.5);
2512  if (pymin) *pymin = (l_int32)(fymin + 0.5);
2513  pixd = pixCreate((l_int32)(fxmax + 0.5) + 1, (l_int32)(fymax + 0.5) + 1, 1);
2514  pixRenderPolyline(pixd, pta2, width, L_SET_PIXELS, 1);
2515  ptaDestroy(&pta1);
2516  ptaDestroy(&pta2);
2517  return pixd;
2518 }
2519 
2520 
2539 PIX *
2541  PTA *pta,
2542  l_int32 xmin,
2543  l_int32 ymin)
2544 {
2545 l_int32 w, h, i, n, inside, found;
2546 l_int32 *xstart, *xend;
2547 PIX *pixi, *pixd;
2548 
2549  PROCNAME("pixFillPolygon");
2550 
2551  if (!pixs || (pixGetDepth(pixs) != 1))
2552  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2553  if (!pta)
2554  return (PIX *)ERROR_PTR("pta not defined", procName, NULL);
2555 
2556  pixGetDimensions(pixs, &w, &h, NULL);
2557  xstart = (l_int32 *)LEPT_CALLOC(w / 2, sizeof(l_int32));
2558  xend = (l_int32 *)LEPT_CALLOC(w / 2, sizeof(l_int32));
2559 
2560  /* Find a raster with 2 or more black runs. The first background
2561  * pixel after the end of the first run is likely to be inside
2562  * the polygon, and can be used as a seed pixel. */
2563  found = FALSE;
2564  for (i = ymin + 1; i < h; i++) {
2565  pixFindHorizontalRuns(pixs, i, xstart, xend, &n);
2566  if (n > 1) {
2567  ptaPtInsidePolygon(pta, xend[0] + 1, i, &inside);
2568  if (inside) {
2569  found = TRUE;
2570  break;
2571  }
2572  }
2573  }
2574  if (!found) {
2575  L_WARNING("nothing found to fill\n", procName);
2576  LEPT_FREE(xstart);
2577  LEPT_FREE(xend);
2578  return 0;
2579  }
2580 
2581  /* Place the seed pixel in the output image */
2582  pixd = pixCreateTemplate(pixs);
2583  pixSetPixel(pixd, xend[0] + 1, i, 1);
2584 
2585  /* Invert pixs to make a filling mask, and fill from the seed */
2586  pixi = pixInvert(NULL, pixs);
2587  pixSeedfillBinary(pixd, pixd, pixi, 4);
2588 
2589  /* Add the pixels of the original polygon outline */
2590  pixOr(pixd, pixd, pixs);
2591 
2592  pixDestroy(&pixi);
2593  LEPT_FREE(xstart);
2594  LEPT_FREE(xend);
2595  return pixd;
2596 }
2597 
2598 
2599 /*------------------------------------------------------------------*
2600  * Contour rendering on grayscale images *
2601  *------------------------------------------------------------------*/
2618 PIX *
2620  l_int32 startval,
2621  l_int32 incr,
2622  l_int32 outdepth)
2623 {
2624 l_int32 w, h, d, maxval, wpls, wpld, i, j, val, test;
2625 l_uint32 *datas, *datad, *lines, *lined;
2626 PIX *pixd;
2627 
2628  PROCNAME("pixRenderContours");
2629 
2630  if (!pixs)
2631  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2632  if (pixGetColormap(pixs))
2633  return (PIX *)ERROR_PTR("pixs has colormap", procName, NULL);
2634  pixGetDimensions(pixs, &w, &h, &d);
2635  if (d != 8 && d != 16)
2636  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", procName, NULL);
2637  if (outdepth != 1 && outdepth != d) {
2638  L_WARNING("invalid outdepth; setting to 1\n", procName);
2639  outdepth = 1;
2640  }
2641  maxval = (1 << d) - 1;
2642  if (startval < 0 || startval > maxval)
2643  return (PIX *)ERROR_PTR("startval not in [0 ... maxval]",
2644  procName, NULL);
2645  if (incr < 1)
2646  return (PIX *)ERROR_PTR("incr < 1", procName, NULL);
2647 
2648  if (outdepth == d)
2649  pixd = pixCopy(NULL, pixs);
2650  else
2651  pixd = pixCreate(w, h, 1);
2652 
2653  pixCopyResolution(pixd, pixs);
2654  datad = pixGetData(pixd);
2655  wpld = pixGetWpl(pixd);
2656  datas = pixGetData(pixs);
2657  wpls = pixGetWpl(pixs);
2658 
2659  switch (d)
2660  {
2661  case 8:
2662  if (outdepth == 1) {
2663  for (i = 0; i < h; i++) {
2664  lines = datas + i * wpls;
2665  lined = datad + i * wpld;
2666  for (j = 0; j < w; j++) {
2667  val = GET_DATA_BYTE(lines, j);
2668  if (val < startval)
2669  continue;
2670  test = (val - startval) % incr;
2671  if (!test)
2672  SET_DATA_BIT(lined, j);
2673  }
2674  }
2675  } else { /* outdepth == d */
2676  for (i = 0; i < h; i++) {
2677  lines = datas + i * wpls;
2678  lined = datad + i * wpld;
2679  for (j = 0; j < w; j++) {
2680  val = GET_DATA_BYTE(lines, j);
2681  if (val < startval)
2682  continue;
2683  test = (val - startval) % incr;
2684  if (!test)
2685  SET_DATA_BYTE(lined, j, 0);
2686  }
2687  }
2688  }
2689  break;
2690 
2691  case 16:
2692  if (outdepth == 1) {
2693  for (i = 0; i < h; i++) {
2694  lines = datas + i * wpls;
2695  lined = datad + i * wpld;
2696  for (j = 0; j < w; j++) {
2697  val = GET_DATA_TWO_BYTES(lines, j);
2698  if (val < startval)
2699  continue;
2700  test = (val - startval) % incr;
2701  if (!test)
2702  SET_DATA_BIT(lined, j);
2703  }
2704  }
2705  } else { /* outdepth == d */
2706  for (i = 0; i < h; i++) {
2707  lines = datas + i * wpls;
2708  lined = datad + i * wpld;
2709  for (j = 0; j < w; j++) {
2710  val = GET_DATA_TWO_BYTES(lines, j);
2711  if (val < startval)
2712  continue;
2713  test = (val - startval) % incr;
2714  if (!test)
2715  SET_DATA_TWO_BYTES(lined, j, 0);
2716  }
2717  }
2718  }
2719  break;
2720 
2721  default:
2722  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", procName, NULL);
2723  }
2724 
2725  return pixd;
2726 }
2727 
2728 
2744 PIX *
2746  l_int32 ncontours)
2747 {
2748 l_float32 minval, maxval, incr;
2749 
2750  PROCNAME("fpixAutoRenderContours");
2751 
2752  if (!fpix)
2753  return (PIX *)ERROR_PTR("fpix not defined", procName, NULL);
2754  if (ncontours < 2 || ncontours > 500)
2755  return (PIX *)ERROR_PTR("ncontours < 2 or > 500", procName, NULL);
2756 
2757  fpixGetMin(fpix, &minval, NULL, NULL);
2758  fpixGetMax(fpix, &maxval, NULL, NULL);
2759  if (minval == maxval)
2760  return (PIX *)ERROR_PTR("all values in fpix are equal", procName, NULL);
2761  incr = (maxval - minval) / ((l_float32)ncontours - 1);
2762  return fpixRenderContours(fpix, incr, 0.15);
2763 }
2764 
2765 
2782 PIX *
2784  l_float32 incr,
2785  l_float32 proxim)
2786 {
2787 l_int32 i, j, w, h, wpls, wpld;
2788 l_float32 val, invincr, finter, above, below, diff;
2789 l_uint32 *datad, *lined;
2790 l_float32 *datas, *lines;
2791 PIX *pixd;
2792 PIXCMAP *cmap;
2793 
2794  PROCNAME("fpixRenderContours");
2795 
2796  if (!fpixs)
2797  return (PIX *)ERROR_PTR("fpixs not defined", procName, NULL);
2798  if (incr <= 0.0)
2799  return (PIX *)ERROR_PTR("incr <= 0.0", procName, NULL);
2800  if (proxim <= 0.0)
2801  proxim = 0.15; /* default */
2802 
2803  fpixGetDimensions(fpixs, &w, &h);
2804  if ((pixd = pixCreate(w, h, 8)) == NULL)
2805  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2806  cmap = pixcmapCreate(8);
2807  pixSetColormap(pixd, cmap);
2808  pixcmapAddColor(cmap, 255, 255, 255); /* white */
2809  pixcmapAddColor(cmap, 0, 0, 0); /* black */
2810  pixcmapAddColor(cmap, 255, 0, 0); /* red */
2811 
2812  datas = fpixGetData(fpixs);
2813  wpls = fpixGetWpl(fpixs);
2814  datad = pixGetData(pixd);
2815  wpld = pixGetWpl(pixd);
2816  invincr = 1.0 / incr;
2817  for (i = 0; i < h; i++) {
2818  lines = datas + i * wpls;
2819  lined = datad + i * wpld;
2820  for (j = 0; j < w; j++) {
2821  val = lines[j];
2822  finter = invincr * val;
2823  above = finter - floorf(finter);
2824  below = ceilf(finter) - finter;
2825  diff = L_MIN(above, below);
2826  if (diff <= proxim) {
2827  if (val < 0.0)
2828  SET_DATA_BYTE(lined, j, 2);
2829  else
2830  SET_DATA_BYTE(lined, j, 1);
2831  }
2832  }
2833  }
2834 
2835  return pixd;
2836 }
2837 
2838 
2839 /*------------------------------------------------------------------*
2840  * Boundary pt generation on 1 bpp images *
2841  *------------------------------------------------------------------*/
2861 PTA *
2863  l_int32 width)
2864 {
2865 PIX *pix1;
2866 PTA *pta;
2867 
2868  PROCNAME("pixGeneratePtaBoundary");
2869 
2870  if (!pixs || pixGetDepth(pixs) != 1)
2871  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2872  if (width < 1) {
2873  L_WARNING("width < 1; setting to 1\n", procName);
2874  width = 1;
2875  }
2876 
2877  pix1 = pixErodeBrick(NULL, pixs, 2 * width + 1, 2 * width + 1);
2878  pixXor(pix1, pix1, pixs);
2879  pta = ptaGetPixelsFromPix(pix1, NULL);
2880  pixDestroy(&pix1);
2881  return pta;
2882 }
PTA * generatePtaHashBox(BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline)
generatePtaHashBox()
Definition: graphics.c:405
PIX * fpixAutoRenderContours(FPIX *fpix, l_int32 ncontours)
fpixAutoRenderContours()
Definition: graphics.c:2745
l_ok fpixGetMax(FPIX *fpix, l_float32 *pmaxval, l_int32 *pxmaxloc, l_int32 *pymaxloc)
fpixGetMax()
Definition: fpix2.c:744
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:692
l_ok pixRenderPolylineArb(PIX *pix, PTA *ptas, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_int32 closeflag)
pixRenderPolylineArb()
Definition: graphics.c:2272
l_ok pixRenderBoxaBlend(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract, l_int32 removedups)
pixRenderBoxaBlend()
Definition: graphics.c:1800
PIX * pixFillPolygon(PIX *pixs, PTA *pta, l_int32 xmin, l_int32 ymin)
pixFillPolygon()
Definition: graphics.c:2540
Definition: pix.h:717
l_ok pixRenderHashBox(PIX *pix, BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 op)
pixRenderHashBox()
Definition: graphics.c:1843
l_ok 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)
pixRenderLineBlend()
Definition: graphics.c:1564
l_ok pixRenderBox(PIX *pix, BOX *box, l_int32 width, l_int32 op)
pixRenderBox()
Definition: graphics.c:1604
PTA * convertPtaLineTo4cc(PTA *ptas)
convertPtaLineTo4cc()
Definition: graphics.c:780
PTA * generatePtaBoxa(BOXA *boxa, l_int32 width, l_int32 removedups)
generatePtaBoxa()
Definition: graphics.c:350
l_ok pixRenderPlotFromNumaGen(PIX **ppix, NUMA *na, l_int32 orient, l_int32 linewidth, l_int32 refpos, l_int32 max, l_int32 drawref, l_uint32 color)
pixRenderPlotFromNumaGen()
Definition: graphics.c:1077
PTAA * generatePtaaBoxa(BOXA *boxa)
generatePtaaBoxa()
Definition: graphics.c:565
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
l_ok pixRenderPtaBlend(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
pixRenderPtaBlend()
Definition: graphics.c:1418
PIX * pixRenderContours(PIX *pixs, l_int32 startval, l_int32 incr, l_int32 outdepth)
pixRenderContours()
Definition: graphics.c:2619
PTA * generatePtaLineFromPt(l_int32 x, l_int32 y, l_float64 length, l_float64 radang)
generatePtaLineFromPt()
Definition: graphics.c:897
l_ok pixRenderPolyline(PIX *pix, PTA *ptas, l_int32 width, l_int32 op, l_int32 closeflag)
pixRenderPolyline()
Definition: graphics.c:2227
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:342
l_ok pixRenderPta(PIX *pix, PTA *pta, l_int32 op)
pixRenderPta()
Definition: graphics.c:1254
l_ok pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
Definition: rop.c:193
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:116
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3041
PIX * pixRenderPolygon(PTA *ptas, l_int32 width, l_int32 *pxmin, l_int32 *pymin)
pixRenderPolygon()
Definition: graphics.c:2485
l_ok pixRenderBoxa(PIX *pix, BOXA *boxa, l_int32 width, l_int32 op)
pixRenderBoxa()
Definition: graphics.c:1721
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
l_ok pixRenderBoxBlend(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
pixRenderBoxBlend()
Definition: graphics.c:1682
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1395
l_ok fpixGetDimensions(FPIX *fpix, l_int32 *pw, l_int32 *ph)
fpixGetDimensions()
Definition: fpix1.c:412
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:504
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:580
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PTA * makePlotPtaFromNumaGen(NUMA *na, l_int32 orient, l_int32 linewidth, l_int32 refpos, l_int32 max, l_int32 drawref)
makePlotPtaFromNumaGen()
Definition: graphics.c:1142
l_ok pixRenderGridArb(PIX *pix, l_int32 nx, l_int32 ny, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderGridArb()
Definition: graphics.c:2356
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
PTA * ptaRemoveDupsByAset(PTA *ptas)
ptaRemoveDupsByAset()
Definition: ptafunc2.c:361
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1020
Definition: pix.h:492
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:977
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1573
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:164
l_ok pixFindHorizontalRuns(PIX *pix, l_int32 y, l_int32 *xstart, l_int32 *xend, l_int32 *pn)
pixFindHorizontalRuns()
Definition: runlength.c:372
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:111
l_ok 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)
pixRenderLineArb()
Definition: graphics.c:1523
PTAA * generatePtaaHashBoxa(BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline)
generatePtaaHashBoxa()
Definition: graphics.c:616
PTA * generatePtaGrid(l_int32 w, l_int32 h, l_int32 nx, l_int32 ny, l_int32 width)
generatePtaGrid()
Definition: graphics.c:722
l_ok pixRenderPolylineBlend(PIX *pix, PTA *ptas, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract, l_int32 closeflag, l_int32 removedups)
pixRenderPolylineBlend()
Definition: graphics.c:2315
l_ok fpixGetMin(FPIX *fpix, l_float32 *pminval, l_int32 *pxminloc, l_int32 *pyminloc)
fpixGetMin()
Definition: fpix2.c:691
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:775
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1094
Definition: array.h:59
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1574
l_ok pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
pixFlipPixel()
Definition: pix2.c:523
PTA * generatePtaLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2)
generatePtaLine()
Definition: graphics.c:138
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:631
l_ok pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
pixClearPixel()
Definition: pix2.c:463
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:296
Definition: pix.h:532
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:253
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:751
PTA * generatePtaWideLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width)
generatePtaWideLine()
Definition: graphics.c:203
PTA * makePlotPtaFromNuma(NUMA *na, l_int32 size, l_int32 plotloc, l_int32 linewidth, l_int32 max)
makePlotPtaFromNuma()
Definition: graphics.c:1021
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:618
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
l_ok locatePtRadially(l_int32 xr, l_int32 yr, l_float64 dist, l_float64 radang, l_float64 *px, l_float64 *py)
locatePtRadially()
Definition: graphics.c:921
PTA * generatePtaFilledSquare(l_int32 side)
generatePtaFilledSquare()
Definition: graphics.c:863
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
l_int32 fpixGetWpl(FPIX *fpix)
fpixGetWpl()
Definition: fpix1.c:459
PTA * pixGeneratePtaBoundary(PIX *pixs, l_int32 width)
pixGeneratePtaBoundary()
Definition: graphics.c:2862
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:936
l_ok pixRenderHashBoxa(PIX *pix, BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 op)
pixRenderHashBoxa()
Definition: graphics.c:2071
PTA * generatePtaHashBoxa(BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 removedups)
generatePtaHashBoxa()
Definition: graphics.c:505
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixcmapAddNearestColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNearestColor()
Definition: colormap.c:472
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:763
PIX * pixRenderRandomCmapPtaa(PIX *pix, PTAA *ptaa, l_int32 polyflag, l_int32 width, l_int32 closeflag)
pixRenderRandomCmapPtaa()
Definition: graphics.c:2416
l_float32 * fpixGetData(FPIX *fpix)
fpixGetData()
Definition: fpix1.c:602
l_ok ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:483
l_ok pixRenderHashBoxaArb(PIX *pix, BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval)
pixRenderHashBoxaArb()
Definition: graphics.c:2121
l_ok pixRenderLine(PIX *pix, l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width, l_int32 op)
pixRenderLine()
Definition: graphics.c:1483
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:180
PIX * pixSeedfillBinary(PIX *pixd, PIX *pixs, PIX *pixm, l_int32 connectivity)
pixSeedfillBinary()
Definition: seedfill.c:243
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
l_ok numaGetMin(NUMA *na, l_float32 *pminval, l_int32 *piminloc)
numaGetMin()
Definition: numafunc1.c:444
l_ok pixRenderPlotFromNuma(PIX **ppix, NUMA *na, l_int32 plotloc, l_int32 linewidth, l_int32 max, l_uint32 color)
pixRenderPlotFromNuma()
Definition: graphics.c:963
PIX * pixOr(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixOr()
Definition: pix3.c:1446
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1074
l_ok pixRenderHashBoxArb(PIX *pix, BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval)
pixRenderHashBoxArb()
Definition: graphics.c:1893
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2557
l_ok pixRenderBoxaArb(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxaArb()
Definition: graphics.c:1759
PTA * generatePtaPolyline(PTA *ptas, l_int32 width, l_int32 closeflag, l_int32 removedups)
generatePtaPolyline()
Definition: graphics.c:664
l_ok pixRenderBoxArb(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxArb()
Definition: graphics.c:1642
l_ok boxIntersectByLine(BOX *box, l_int32 x, l_int32 y, l_float32 slope, l_int32 *px1, l_int32 *py1, l_int32 *px2, l_int32 *py2, l_int32 *pn)
boxIntersectByLine()
Definition: boxfunc1.c:1485
l_ok pixRenderHashBoxaBlend(PIX *pix, BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval, l_float32 fract)
pixRenderHashBoxaBlend()
Definition: graphics.c:2173
l_ok pixRenderHashBoxBlend(PIX *pix, BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval, l_float32 fract)
pixRenderHashBoxBlend()
Definition: graphics.c:1945
Definition: pix.h:134
Definition: pix.h:719
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:192
l_ok pixRenderHashMaskArb(PIX *pix, PIX *pixm, l_int32 x, l_int32 y, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval)
pixRenderHashMaskArb()
Definition: graphics.c:2003
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:499
#define PIX_SRC
Definition: pix.h:327
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:278
Definition: pix.h:201
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:718
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:555
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:1004
l_ok pixRenderPtaArb(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderPtaArb()
Definition: graphics.c:1343
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:486
PIX * pixErodeBrick(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeBrick()
Definition: morph.c:748
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2671
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1908
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
Definition: colormap.c:341
PTA * generatePtaFilledCircle(l_int32 radius)
generatePtaFilledCircle()
Definition: graphics.c:823
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:310
Definition: pix.h:480
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2737
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:165
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:939
PTA * generatePtaBox(BOX *box, l_int32 width)
generatePtaBox()
Definition: graphics.c:273
Definition: pix.h:517
Definition: pix.h:582
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:158
PIX * fpixRenderContours(FPIX *fpixs, l_float32 incr, l_float32 proxim)
fpixRenderContours()
Definition: graphics.c:2783