Leptonica  1.73
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_int32
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_int32
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_int32
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_int32
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_int32
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 
1416 l_int32
1418  PTA *pta,
1419  l_uint8 rval,
1420  l_uint8 gval,
1421  l_uint8 bval,
1422  l_float32 fract)
1423 {
1424 l_int32 i, n, x, y, w, h;
1425 l_uint8 nrval, ngval, nbval;
1426 l_uint32 val32;
1427 l_float32 frval, fgval, fbval;
1428 
1429  PROCNAME("pixRenderPtaBlend");
1430 
1431  if (!pix)
1432  return ERROR_INT("pix not defined", procName, 1);
1433  if (!pta)
1434  return ERROR_INT("pta not defined", procName, 1);
1435  if (pixGetDepth(pix) != 32)
1436  return ERROR_INT("depth not 32 bpp", procName, 1);
1437  if (fract < 0.0 || fract > 1.0) {
1438  L_WARNING("fract must be in [0.0, 1.0]; setting to 0.5\n", procName);
1439  fract = 0.5;
1440  }
1441 
1442  pixGetDimensions(pix, &w, &h, NULL);
1443  n = ptaGetCount(pta);
1444  frval = fract * rval;
1445  fgval = fract * gval;
1446  fbval = fract * bval;
1447  for (i = 0; i < n; i++) {
1448  ptaGetIPt(pta, i, &x, &y);
1449  if (x < 0 || x >= w)
1450  continue;
1451  if (y < 0 || y >= h)
1452  continue;
1453  pixGetPixel(pix, x, y, &val32);
1454  nrval = GET_DATA_BYTE(&val32, COLOR_RED);
1455  nrval = (l_uint8)((1. - fract) * nrval + frval);
1456  ngval = GET_DATA_BYTE(&val32, COLOR_GREEN);
1457  ngval = (l_uint8)((1. - fract) * ngval + fgval);
1458  nbval = GET_DATA_BYTE(&val32, COLOR_BLUE);
1459  nbval = (l_uint8)((1. - fract) * nbval + fbval);
1460  composeRGBPixel(nrval, ngval, nbval, &val32);
1461  pixSetPixel(pix, x, y, val32);
1462  }
1463 
1464  return 0;
1465 }
1466 
1467 
1468 /*------------------------------------------------------------------*
1469  * Rendering of arbitrary shapes built with lines *
1470  *------------------------------------------------------------------*/
1481 l_int32
1483  l_int32 x1,
1484  l_int32 y1,
1485  l_int32 x2,
1486  l_int32 y2,
1487  l_int32 width,
1488  l_int32 op)
1489 {
1490 PTA *pta;
1491 
1492  PROCNAME("pixRenderLine");
1493 
1494  if (!pix)
1495  return ERROR_INT("pix not defined", procName, 1);
1496  if (width < 1) {
1497  L_WARNING("width must be > 0; setting to 1\n", procName);
1498  width = 1;
1499  }
1500  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1501  return ERROR_INT("invalid op", procName, 1);
1502 
1503  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1504  return ERROR_INT("pta not made", procName, 1);
1505  pixRenderPta(pix, pta, op);
1506  ptaDestroy(&pta);
1507  return 0;
1508 }
1509 
1510 
1521 l_int32
1523  l_int32 x1,
1524  l_int32 y1,
1525  l_int32 x2,
1526  l_int32 y2,
1527  l_int32 width,
1528  l_uint8 rval,
1529  l_uint8 gval,
1530  l_uint8 bval)
1531 {
1532 PTA *pta;
1533 
1534  PROCNAME("pixRenderLineArb");
1535 
1536  if (!pix)
1537  return ERROR_INT("pix not defined", procName, 1);
1538  if (width < 1) {
1539  L_WARNING("width must be > 0; setting to 1\n", procName);
1540  width = 1;
1541  }
1542 
1543  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1544  return ERROR_INT("pta not made", procName, 1);
1545  pixRenderPtaArb(pix, pta, rval, gval, bval);
1546  ptaDestroy(&pta);
1547  return 0;
1548 }
1549 
1550 
1562 l_int32
1564  l_int32 x1,
1565  l_int32 y1,
1566  l_int32 x2,
1567  l_int32 y2,
1568  l_int32 width,
1569  l_uint8 rval,
1570  l_uint8 gval,
1571  l_uint8 bval,
1572  l_float32 fract)
1573 {
1574 PTA *pta;
1575 
1576  PROCNAME("pixRenderLineBlend");
1577 
1578  if (!pix)
1579  return ERROR_INT("pix not defined", procName, 1);
1580  if (width < 1) {
1581  L_WARNING("width must be > 0; setting to 1\n", procName);
1582  width = 1;
1583  }
1584 
1585  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1586  return ERROR_INT("pta not made", procName, 1);
1587  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1588  ptaDestroy(&pta);
1589  return 0;
1590 }
1591 
1592 
1602 l_int32
1604  BOX *box,
1605  l_int32 width,
1606  l_int32 op)
1607 {
1608 PTA *pta;
1609 
1610  PROCNAME("pixRenderBox");
1611 
1612  if (!pix)
1613  return ERROR_INT("pix not defined", procName, 1);
1614  if (!box)
1615  return ERROR_INT("box not defined", procName, 1);
1616  if (width < 1) {
1617  L_WARNING("width < 1; setting to 1\n", procName);
1618  width = 1;
1619  }
1620  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1621  return ERROR_INT("invalid op", procName, 1);
1622 
1623  if ((pta = generatePtaBox(box, width)) == NULL)
1624  return ERROR_INT("pta not made", procName, 1);
1625  pixRenderPta(pix, pta, op);
1626  ptaDestroy(&pta);
1627  return 0;
1628 }
1629 
1630 
1640 l_int32
1642  BOX *box,
1643  l_int32 width,
1644  l_uint8 rval,
1645  l_uint8 gval,
1646  l_uint8 bval)
1647 {
1648 PTA *pta;
1649 
1650  PROCNAME("pixRenderBoxArb");
1651 
1652  if (!pix)
1653  return ERROR_INT("pix not defined", procName, 1);
1654  if (!box)
1655  return ERROR_INT("box not defined", procName, 1);
1656  if (width < 1) {
1657  L_WARNING("width < 1; setting to 1\n", procName);
1658  width = 1;
1659  }
1660 
1661  if ((pta = generatePtaBox(box, width)) == NULL)
1662  return ERROR_INT("pta not made", procName, 1);
1663  pixRenderPtaArb(pix, pta, rval, gval, bval);
1664  ptaDestroy(&pta);
1665  return 0;
1666 }
1667 
1668 
1680 l_int32
1682  BOX *box,
1683  l_int32 width,
1684  l_uint8 rval,
1685  l_uint8 gval,
1686  l_uint8 bval,
1687  l_float32 fract)
1688 {
1689 PTA *pta;
1690 
1691  PROCNAME("pixRenderBoxBlend");
1692 
1693  if (!pix)
1694  return ERROR_INT("pix not defined", procName, 1);
1695  if (!box)
1696  return ERROR_INT("box not defined", procName, 1);
1697  if (width < 1) {
1698  L_WARNING("width < 1; setting to 1\n", procName);
1699  width = 1;
1700  }
1701 
1702  if ((pta = generatePtaBox(box, width)) == NULL)
1703  return ERROR_INT("pta not made", procName, 1);
1704  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1705  ptaDestroy(&pta);
1706  return 0;
1707 }
1708 
1709 
1719 l_int32
1721  BOXA *boxa,
1722  l_int32 width,
1723  l_int32 op)
1724 {
1725 PTA *pta;
1726 
1727  PROCNAME("pixRenderBoxa");
1728 
1729  if (!pix)
1730  return ERROR_INT("pix not defined", procName, 1);
1731  if (!boxa)
1732  return ERROR_INT("boxa not defined", procName, 1);
1733  if (width < 1) {
1734  L_WARNING("width < 1; setting to 1\n", procName);
1735  width = 1;
1736  }
1737  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1738  return ERROR_INT("invalid op", procName, 1);
1739 
1740  if ((pta = generatePtaBoxa(boxa, width, 0)) == NULL)
1741  return ERROR_INT("pta not made", procName, 1);
1742  pixRenderPta(pix, pta, op);
1743  ptaDestroy(&pta);
1744  return 0;
1745 }
1746 
1747 
1757 l_int32
1759  BOXA *boxa,
1760  l_int32 width,
1761  l_uint8 rval,
1762  l_uint8 gval,
1763  l_uint8 bval)
1764 {
1765 PTA *pta;
1766 
1767  PROCNAME("pixRenderBoxaArb");
1768 
1769  if (!pix)
1770  return ERROR_INT("pix not defined", procName, 1);
1771  if (!boxa)
1772  return ERROR_INT("boxa not defined", procName, 1);
1773  if (width < 1) {
1774  L_WARNING("width < 1; setting to 1\n", procName);
1775  width = 1;
1776  }
1777 
1778  if ((pta = generatePtaBoxa(boxa, width, 0)) == NULL)
1779  return ERROR_INT("pta not made", procName, 1);
1780  pixRenderPtaArb(pix, pta, rval, gval, bval);
1781  ptaDestroy(&pta);
1782  return 0;
1783 }
1784 
1785 
1798 l_int32
1800  BOXA *boxa,
1801  l_int32 width,
1802  l_uint8 rval,
1803  l_uint8 gval,
1804  l_uint8 bval,
1805  l_float32 fract,
1806  l_int32 removedups)
1807 {
1808 PTA *pta;
1809 
1810  PROCNAME("pixRenderBoxaBlend");
1811 
1812  if (!pix)
1813  return ERROR_INT("pix not defined", procName, 1);
1814  if (!boxa)
1815  return ERROR_INT("boxa not defined", procName, 1);
1816  if (width < 1) {
1817  L_WARNING("width < 1; setting to 1\n", procName);
1818  width = 1;
1819  }
1820 
1821  if ((pta = generatePtaBoxa(boxa, width, removedups)) == NULL)
1822  return ERROR_INT("pta not made", procName, 1);
1823  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1824  ptaDestroy(&pta);
1825  return 0;
1826 }
1827 
1828 
1841 l_int32
1843  BOX *box,
1844  l_int32 spacing,
1845  l_int32 width,
1846  l_int32 orient,
1847  l_int32 outline,
1848  l_int32 op)
1849 {
1850 PTA *pta;
1851 
1852  PROCNAME("pixRenderHashBox");
1853 
1854  if (!pix)
1855  return ERROR_INT("pix not defined", procName, 1);
1856  if (!box)
1857  return ERROR_INT("box not defined", procName, 1);
1858  if (spacing <= 1)
1859  return ERROR_INT("spacing not > 1", procName, 1);
1860  if (width < 1) {
1861  L_WARNING("width < 1; setting to 1\n", procName);
1862  width = 1;
1863  }
1864  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1865  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1866  return ERROR_INT("invalid line orientation", procName, 1);
1867  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1868  return ERROR_INT("invalid op", procName, 1);
1869 
1870  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1871  if (!pta)
1872  return ERROR_INT("pta not made", procName, 1);
1873  pixRenderPta(pix, pta, op);
1874  ptaDestroy(&pta);
1875  return 0;
1876 }
1877 
1878 
1891 l_int32
1893  BOX *box,
1894  l_int32 spacing,
1895  l_int32 width,
1896  l_int32 orient,
1897  l_int32 outline,
1898  l_int32 rval,
1899  l_int32 gval,
1900  l_int32 bval)
1901 {
1902 PTA *pta;
1903 
1904  PROCNAME("pixRenderHashBoxArb");
1905 
1906  if (!pix)
1907  return ERROR_INT("pix not defined", procName, 1);
1908  if (!box)
1909  return ERROR_INT("box not defined", procName, 1);
1910  if (spacing <= 1)
1911  return ERROR_INT("spacing not > 1", procName, 1);
1912  if (width < 1) {
1913  L_WARNING("width < 1; setting to 1\n", procName);
1914  width = 1;
1915  }
1916  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1917  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1918  return ERROR_INT("invalid line orientation", procName, 1);
1919 
1920  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1921  if (!pta)
1922  return ERROR_INT("pta not made", procName, 1);
1923  pixRenderPtaArb(pix, pta, rval, gval, bval);
1924  ptaDestroy(&pta);
1925  return 0;
1926 }
1927 
1928 
1943 l_int32
1945  BOX *box,
1946  l_int32 spacing,
1947  l_int32 width,
1948  l_int32 orient,
1949  l_int32 outline,
1950  l_int32 rval,
1951  l_int32 gval,
1952  l_int32 bval,
1953  l_float32 fract)
1954 {
1955 PTA *pta;
1956 
1957  PROCNAME("pixRenderHashBoxBlend");
1958 
1959  if (!pix)
1960  return ERROR_INT("pix not defined", procName, 1);
1961  if (!box)
1962  return ERROR_INT("box not defined", procName, 1);
1963  if (spacing <= 1)
1964  return ERROR_INT("spacing not > 1", procName, 1);
1965  if (width < 1) {
1966  L_WARNING("width < 1; setting to 1\n", procName);
1967  width = 1;
1968  }
1969  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1970  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1971  return ERROR_INT("invalid line orientation", procName, 1);
1972 
1973  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1974  if (!pta)
1975  return ERROR_INT("pta not made", procName, 1);
1976  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1977  ptaDestroy(&pta);
1978  return 0;
1979 }
1980 
1981 
2001 l_int32
2003  PIX *pixm,
2004  l_int32 x,
2005  l_int32 y,
2006  l_int32 spacing,
2007  l_int32 width,
2008  l_int32 orient,
2009  l_int32 outline,
2010  l_int32 rval,
2011  l_int32 gval,
2012  l_int32 bval)
2013 {
2014 l_int32 w, h;
2015 BOX *box1, *box2;
2016 PIX *pix1;
2017 PTA *pta1, *pta2;
2018 
2019  PROCNAME("pixRenderHashMaskArb");
2020 
2021  if (!pix)
2022  return ERROR_INT("pix not defined", procName, 1);
2023  if (!pixm || pixGetDepth(pixm) != 1)
2024  return ERROR_INT("pixm not defined or not 1 bpp", procName, 1);
2025  if (spacing <= 1)
2026  return ERROR_INT("spacing not > 1", procName, 1);
2027  if (width < 1) {
2028  L_WARNING("width < 1; setting to 1\n", procName);
2029  width = 1;
2030  }
2031  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2032  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2033  return ERROR_INT("invalid line orientation", procName, 1);
2034 
2035  /* Get the points for masked hash lines */
2036  pixGetDimensions(pixm, &w, &h, NULL);
2037  box1 = boxCreate(0, 0, w, h);
2038  pta1 = generatePtaHashBox(box1, spacing, width, orient, outline);
2039  pta2 = ptaCropToMask(pta1, pixm);
2040  boxDestroy(&box1);
2041  ptaDestroy(&pta1);
2042 
2043  /* Clip out the region and apply the hash lines */
2044  box2 = boxCreate(x, y, w, h);
2045  pix1 = pixClipRectangle(pix, box2, NULL);
2046  pixRenderPtaArb(pix1, pta2, rval, gval, bval);
2047  ptaDestroy(&pta2);
2048  boxDestroy(&box2);
2049 
2050  /* Rasterop the altered rectangle back in place */
2051  pixRasterop(pix, x, y, w, h, PIX_SRC, pix1, 0, 0);
2052  pixDestroy(&pix1);
2053  return 0;
2054 }
2055 
2056 
2069 l_int32
2071  BOXA *boxa,
2072  l_int32 spacing,
2073  l_int32 width,
2074  l_int32 orient,
2075  l_int32 outline,
2076  l_int32 op)
2077  {
2078 PTA *pta;
2079 
2080  PROCNAME("pixRenderHashBoxa");
2081 
2082  if (!pix)
2083  return ERROR_INT("pix not defined", procName, 1);
2084  if (!boxa)
2085  return ERROR_INT("boxa not defined", procName, 1);
2086  if (spacing <= 1)
2087  return ERROR_INT("spacing not > 1", procName, 1);
2088  if (width < 1) {
2089  L_WARNING("width < 1; setting to 1\n", procName);
2090  width = 1;
2091  }
2092  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2093  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2094  return ERROR_INT("invalid line orientation", procName, 1);
2095  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
2096  return ERROR_INT("invalid op", procName, 1);
2097 
2098  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2099  if (!pta)
2100  return ERROR_INT("pta not made", procName, 1);
2101  pixRenderPta(pix, pta, op);
2102  ptaDestroy(&pta);
2103  return 0;
2104 }
2105 
2106 
2119 l_int32
2121  BOXA *boxa,
2122  l_int32 spacing,
2123  l_int32 width,
2124  l_int32 orient,
2125  l_int32 outline,
2126  l_int32 rval,
2127  l_int32 gval,
2128  l_int32 bval)
2129 {
2130 PTA *pta;
2131 
2132  PROCNAME("pixRenderHashBoxArb");
2133 
2134  if (!pix)
2135  return ERROR_INT("pix not defined", procName, 1);
2136  if (!boxa)
2137  return ERROR_INT("boxa not defined", procName, 1);
2138  if (spacing <= 1)
2139  return ERROR_INT("spacing not > 1", procName, 1);
2140  if (width < 1) {
2141  L_WARNING("width < 1; setting to 1\n", procName);
2142  width = 1;
2143  }
2144  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2145  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2146  return ERROR_INT("invalid line orientation", procName, 1);
2147 
2148  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2149  if (!pta)
2150  return ERROR_INT("pta not made", procName, 1);
2151  pixRenderPtaArb(pix, pta, rval, gval, bval);
2152  ptaDestroy(&pta);
2153  return 0;
2154 }
2155 
2156 
2171 l_int32
2173  BOXA *boxa,
2174  l_int32 spacing,
2175  l_int32 width,
2176  l_int32 orient,
2177  l_int32 outline,
2178  l_int32 rval,
2179  l_int32 gval,
2180  l_int32 bval,
2181  l_float32 fract)
2182 {
2183 PTA *pta;
2184 
2185  PROCNAME("pixRenderHashBoxaBlend");
2186 
2187  if (!pix)
2188  return ERROR_INT("pix not defined", procName, 1);
2189  if (!boxa)
2190  return ERROR_INT("boxa not defined", procName, 1);
2191  if (spacing <= 1)
2192  return ERROR_INT("spacing not > 1", procName, 1);
2193  if (width < 1) {
2194  L_WARNING("width < 1; setting to 1\n", procName);
2195  width = 1;
2196  }
2197  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2198  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2199  return ERROR_INT("invalid line orientation", procName, 1);
2200 
2201  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2202  if (!pta)
2203  return ERROR_INT("pta not made", procName, 1);
2204  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
2205  ptaDestroy(&pta);
2206  return 0;
2207 }
2208 
2209 
2225 l_int32
2227  PTA *ptas,
2228  l_int32 width,
2229  l_int32 op,
2230  l_int32 closeflag)
2231 {
2232 PTA *pta;
2233 
2234  PROCNAME("pixRenderPolyline");
2235 
2236  if (!pix)
2237  return ERROR_INT("pix not defined", procName, 1);
2238  if (!ptas)
2239  return ERROR_INT("ptas not defined", procName, 1);
2240  if (width < 1) {
2241  L_WARNING("width < 1; setting to 1\n", procName);
2242  width = 1;
2243  }
2244  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
2245  return ERROR_INT("invalid op", procName, 1);
2246 
2247  if ((pta = generatePtaPolyline(ptas, width, closeflag, 0)) == NULL)
2248  return ERROR_INT("pta not made", procName, 1);
2249  pixRenderPta(pix, pta, op);
2250  ptaDestroy(&pta);
2251  return 0;
2252 }
2253 
2254 
2270 l_int32
2272  PTA *ptas,
2273  l_int32 width,
2274  l_uint8 rval,
2275  l_uint8 gval,
2276  l_uint8 bval,
2277  l_int32 closeflag)
2278 {
2279 PTA *pta;
2280 
2281  PROCNAME("pixRenderPolylineArb");
2282 
2283  if (!pix)
2284  return ERROR_INT("pix not defined", procName, 1);
2285  if (!ptas)
2286  return ERROR_INT("ptas not defined", procName, 1);
2287  if (width < 1) {
2288  L_WARNING("width < 1; setting to 1\n", procName);
2289  width = 1;
2290  }
2291 
2292  if ((pta = generatePtaPolyline(ptas, width, closeflag, 0)) == NULL)
2293  return ERROR_INT("pta not made", procName, 1);
2294  pixRenderPtaArb(pix, pta, rval, gval, bval);
2295  ptaDestroy(&pta);
2296  return 0;
2297 }
2298 
2299 
2313 l_int32
2315  PTA *ptas,
2316  l_int32 width,
2317  l_uint8 rval,
2318  l_uint8 gval,
2319  l_uint8 bval,
2320  l_float32 fract,
2321  l_int32 closeflag,
2322  l_int32 removedups)
2323 {
2324 PTA *pta;
2325 
2326  PROCNAME("pixRenderPolylineBlend");
2327 
2328  if (!pix)
2329  return ERROR_INT("pix not defined", procName, 1);
2330  if (!ptas)
2331  return ERROR_INT("ptas not defined", procName, 1);
2332  if (width < 1) {
2333  L_WARNING("width < 1; setting to 1\n", procName);
2334  width = 1;
2335  }
2336 
2337  if ((pta = generatePtaPolyline(ptas, width, closeflag, removedups)) == NULL)
2338  return ERROR_INT("pta not made", procName, 1);
2339  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
2340  ptaDestroy(&pta);
2341  return 0;
2342 }
2343 
2344 
2354 l_int32
2356  l_int32 nx,
2357  l_int32 ny,
2358  l_int32 width,
2359  l_uint8 rval,
2360  l_uint8 gval,
2361  l_uint8 bval)
2362 {
2363 l_int32 w, h;
2364 PTA *pta;
2365 
2366  PROCNAME("pixRenderGridArb");
2367 
2368  if (!pix)
2369  return ERROR_INT("pix not defined", procName, 1);
2370  if (nx < 1 || ny < 1)
2371  return ERROR_INT("nx, ny must be > 0", procName, 1);
2372  if (width < 1) {
2373  L_WARNING("width < 1; setting to 1\n", procName);
2374  width = 1;
2375  }
2376 
2377  pixGetDimensions(pix, &w, &h, NULL);
2378  if ((pta = generatePtaGrid(w, h, nx, ny, width)) == NULL)
2379  return ERROR_INT("pta not made", procName, 1);
2380  pixRenderPtaArb(pix, pta, rval, gval, bval);
2381  ptaDestroy(&pta);
2382  return 0;
2383 }
2384 
2385 
2414 PIX *
2416  PTAA *ptaa,
2417  l_int32 polyflag,
2418  l_int32 width,
2419  l_int32 closeflag)
2420 {
2421 l_int32 i, n, index, rval, gval, bval;
2422 PIXCMAP *cmap;
2423 PTA *pta, *ptat;
2424 PIX *pixd;
2425 
2426  PROCNAME("pixRenderRandomCmapPtaa");
2427 
2428  if (!pix)
2429  return (PIX *)ERROR_PTR("pix not defined", procName, NULL);
2430  if (!ptaa)
2431  return (PIX *)ERROR_PTR("ptaa not defined", procName, NULL);
2432  if (polyflag != 0 && width < 1) {
2433  L_WARNING("width < 1; setting to 1\n", procName);
2434  width = 1;
2435  }
2436 
2437  pixd = pixConvertTo8(pix, FALSE);
2438  cmap = pixcmapCreateRandom(8, 1, 1);
2439  pixSetColormap(pixd, cmap);
2440 
2441  if ((n = ptaaGetCount(ptaa)) == 0)
2442  return pixd;
2443 
2444  for (i = 0; i < n; i++) {
2445  index = 1 + (i % 254);
2446  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
2447  pta = ptaaGetPta(ptaa, i, L_CLONE);
2448  if (polyflag)
2449  ptat = generatePtaPolyline(pta, width, closeflag, 0);
2450  else
2451  ptat = ptaClone(pta);
2452  pixRenderPtaArb(pixd, ptat, rval, gval, bval);
2453  ptaDestroy(&pta);
2454  ptaDestroy(&ptat);
2455  }
2456 
2457  return pixd;
2458 }
2459 
2460 
2461 
2462 /*------------------------------------------------------------------*
2463  * Rendering and filling of polygons *
2464  *------------------------------------------------------------------*/
2483 PIX *
2485  l_int32 width,
2486  l_int32 *pxmin,
2487  l_int32 *pymin)
2488 {
2489 l_float32 fxmin, fxmax, fymin, fymax;
2490 PIX *pixd;
2491 PTA *pta1, *pta2;
2492 
2493  PROCNAME("pixRenderPolygon");
2494 
2495  if (pxmin) *pxmin = 0;
2496  if (pymin) *pymin = 0;
2497  if (!ptas)
2498  return (PIX *)ERROR_PTR("ptas not defined", procName, NULL);
2499 
2500  /* Generate a 4-connected polygon line */
2501  if ((pta1 = generatePtaPolyline(ptas, width, 1, 0)) == NULL)
2502  return (PIX *)ERROR_PTR("pta1 not made", procName, NULL);
2503  if (width < 2)
2504  pta2 = convertPtaLineTo4cc(pta1);
2505  else
2506  pta2 = ptaClone(pta1);
2507 
2508  /* Render onto a minimum-sized pix */
2509  ptaGetRange(pta2, &fxmin, &fxmax, &fymin, &fymax);
2510  if (pxmin) *pxmin = (l_int32)(fxmin + 0.5);
2511  if (pymin) *pymin = (l_int32)(fymin + 0.5);
2512  pixd = pixCreate((l_int32)(fxmax + 0.5) + 1, (l_int32)(fymax + 0.5) + 1, 1);
2513  pixRenderPolyline(pixd, pta2, width, L_SET_PIXELS, 1);
2514  ptaDestroy(&pta1);
2515  ptaDestroy(&pta2);
2516  return pixd;
2517 }
2518 
2519 
2538 PIX *
2540  PTA *pta,
2541  l_int32 xmin,
2542  l_int32 ymin)
2543 {
2544 l_int32 w, h, i, n, inside, found;
2545 l_int32 *xstart, *xend;
2546 PIX *pixi, *pixd;
2547 
2548  PROCNAME("pixFillPolygon");
2549 
2550  if (!pixs || (pixGetDepth(pixs) != 1))
2551  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2552  if (!pta)
2553  return (PIX *)ERROR_PTR("pta not defined", procName, NULL);
2554 
2555  pixGetDimensions(pixs, &w, &h, NULL);
2556  xstart = (l_int32 *)LEPT_CALLOC(w / 2, sizeof(l_int32));
2557  xend = (l_int32 *)LEPT_CALLOC(w / 2, sizeof(l_int32));
2558 
2559  /* Find a raster with 2 or more black runs. The first background
2560  * pixel after the end of the first run is likely to be inside
2561  * the polygon, and can be used as a seed pixel. */
2562  found = FALSE;
2563  for (i = ymin + 1; i < h; i++) {
2564  pixFindHorizontalRuns(pixs, i, xstart, xend, &n);
2565  if (n > 1) {
2566  ptaPtInsidePolygon(pta, xend[0] + 1, i, &inside);
2567  if (inside) {
2568  found = TRUE;
2569  break;
2570  }
2571  }
2572  }
2573  if (!found) {
2574  L_WARNING("nothing found to fill\n", procName);
2575  LEPT_FREE(xstart);
2576  LEPT_FREE(xend);
2577  return 0;
2578  }
2579 
2580  /* Place the seed pixel in the output image */
2581  pixd = pixCreateTemplate(pixs);
2582  pixSetPixel(pixd, xend[0] + 1, i, 1);
2583 
2584  /* Invert pixs to make a filling mask, and fill from the seed */
2585  pixi = pixInvert(NULL, pixs);
2586  pixSeedfillBinary(pixd, pixd, pixi, 4);
2587 
2588  /* Add the pixels of the original polygon outline */
2589  pixOr(pixd, pixd, pixs);
2590 
2591  pixDestroy(&pixi);
2592  LEPT_FREE(xstart);
2593  LEPT_FREE(xend);
2594  return pixd;
2595 }
2596 
2597 
2598 /*------------------------------------------------------------------*
2599  * Contour rendering on grayscale images *
2600  *------------------------------------------------------------------*/
2617 PIX *
2619  l_int32 startval,
2620  l_int32 incr,
2621  l_int32 outdepth)
2622 {
2623 l_int32 w, h, d, maxval, wpls, wpld, i, j, val, test;
2624 l_uint32 *datas, *datad, *lines, *lined;
2625 PIX *pixd;
2626 
2627  PROCNAME("pixRenderContours");
2628 
2629  if (!pixs)
2630  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2631  if (pixGetColormap(pixs))
2632  return (PIX *)ERROR_PTR("pixs has colormap", procName, NULL);
2633  pixGetDimensions(pixs, &w, &h, &d);
2634  if (d != 8 && d != 16)
2635  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", procName, NULL);
2636  if (outdepth != 1 && outdepth != d) {
2637  L_WARNING("invalid outdepth; setting to 1\n", procName);
2638  outdepth = 1;
2639  }
2640  maxval = (1 << d) - 1;
2641  if (startval < 0 || startval > maxval)
2642  return (PIX *)ERROR_PTR("startval not in [0 ... maxval]",
2643  procName, NULL);
2644  if (incr < 1)
2645  return (PIX *)ERROR_PTR("incr < 1", procName, NULL);
2646 
2647  if (outdepth == d)
2648  pixd = pixCopy(NULL, pixs);
2649  else
2650  pixd = pixCreate(w, h, 1);
2651 
2652  pixCopyResolution(pixd, pixs);
2653  datad = pixGetData(pixd);
2654  wpld = pixGetWpl(pixd);
2655  datas = pixGetData(pixs);
2656  wpls = pixGetWpl(pixs);
2657 
2658  switch (d)
2659  {
2660  case 8:
2661  if (outdepth == 1) {
2662  for (i = 0; i < h; i++) {
2663  lines = datas + i * wpls;
2664  lined = datad + i * wpld;
2665  for (j = 0; j < w; j++) {
2666  val = GET_DATA_BYTE(lines, j);
2667  if (val < startval)
2668  continue;
2669  test = (val - startval) % incr;
2670  if (!test)
2671  SET_DATA_BIT(lined, j);
2672  }
2673  }
2674  } else { /* outdepth == d */
2675  for (i = 0; i < h; i++) {
2676  lines = datas + i * wpls;
2677  lined = datad + i * wpld;
2678  for (j = 0; j < w; j++) {
2679  val = GET_DATA_BYTE(lines, j);
2680  if (val < startval)
2681  continue;
2682  test = (val - startval) % incr;
2683  if (!test)
2684  SET_DATA_BYTE(lined, j, 0);
2685  }
2686  }
2687  }
2688  break;
2689 
2690  case 16:
2691  if (outdepth == 1) {
2692  for (i = 0; i < h; i++) {
2693  lines = datas + i * wpls;
2694  lined = datad + i * wpld;
2695  for (j = 0; j < w; j++) {
2696  val = GET_DATA_TWO_BYTES(lines, j);
2697  if (val < startval)
2698  continue;
2699  test = (val - startval) % incr;
2700  if (!test)
2701  SET_DATA_BIT(lined, j);
2702  }
2703  }
2704  } else { /* outdepth == d */
2705  for (i = 0; i < h; i++) {
2706  lines = datas + i * wpls;
2707  lined = datad + i * wpld;
2708  for (j = 0; j < w; j++) {
2709  val = GET_DATA_TWO_BYTES(lines, j);
2710  if (val < startval)
2711  continue;
2712  test = (val - startval) % incr;
2713  if (!test)
2714  SET_DATA_TWO_BYTES(lined, j, 0);
2715  }
2716  }
2717  }
2718  break;
2719 
2720  default:
2721  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", procName, NULL);
2722  }
2723 
2724  return pixd;
2725 }
2726 
2727 
2743 PIX *
2745  l_int32 ncontours)
2746 {
2747 l_float32 minval, maxval, incr;
2748 
2749  PROCNAME("fpixAutoRenderContours");
2750 
2751  if (!fpix)
2752  return (PIX *)ERROR_PTR("fpix not defined", procName, NULL);
2753  if (ncontours < 2 || ncontours > 500)
2754  return (PIX *)ERROR_PTR("ncontours < 2 or > 500", procName, NULL);
2755 
2756  fpixGetMin(fpix, &minval, NULL, NULL);
2757  fpixGetMax(fpix, &maxval, NULL, NULL);
2758  if (minval == maxval)
2759  return (PIX *)ERROR_PTR("all values in fpix are equal", procName, NULL);
2760  incr = (maxval - minval) / ((l_float32)ncontours - 1);
2761  return fpixRenderContours(fpix, incr, 0.15);
2762 }
2763 
2764 
2781 PIX *
2783  l_float32 incr,
2784  l_float32 proxim)
2785 {
2786 l_int32 i, j, w, h, wpls, wpld;
2787 l_float32 val, invincr, finter, above, below, diff;
2788 l_uint32 *datad, *lined;
2789 l_float32 *datas, *lines;
2790 PIX *pixd;
2791 PIXCMAP *cmap;
2792 
2793  PROCNAME("fpixRenderContours");
2794 
2795  if (!fpixs)
2796  return (PIX *)ERROR_PTR("fpixs not defined", procName, NULL);
2797  if (incr <= 0.0)
2798  return (PIX *)ERROR_PTR("incr <= 0.0", procName, NULL);
2799  if (proxim <= 0.0)
2800  proxim = 0.15; /* default */
2801 
2802  fpixGetDimensions(fpixs, &w, &h);
2803  if ((pixd = pixCreate(w, h, 8)) == NULL)
2804  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2805  cmap = pixcmapCreate(8);
2806  pixSetColormap(pixd, cmap);
2807  pixcmapAddColor(cmap, 255, 255, 255); /* white */
2808  pixcmapAddColor(cmap, 0, 0, 0); /* black */
2809  pixcmapAddColor(cmap, 255, 0, 0); /* red */
2810 
2811  datas = fpixGetData(fpixs);
2812  wpls = fpixGetWpl(fpixs);
2813  datad = pixGetData(pixd);
2814  wpld = pixGetWpl(pixd);
2815  invincr = 1.0 / incr;
2816  for (i = 0; i < h; i++) {
2817  lines = datas + i * wpls;
2818  lined = datad + i * wpld;
2819  for (j = 0; j < w; j++) {
2820  val = lines[j];
2821  finter = invincr * val;
2822  above = finter - floorf(finter);
2823  below = ceilf(finter) - finter;
2824  diff = L_MIN(above, below);
2825  if (diff <= proxim) {
2826  if (val < 0.0)
2827  SET_DATA_BYTE(lined, j, 2);
2828  else
2829  SET_DATA_BYTE(lined, j, 1);
2830  }
2831  }
2832  }
2833 
2834  return pixd;
2835 }
2836 
2837 
2838 /*------------------------------------------------------------------*
2839  * Boundary pt generation on 1 bpp images *
2840  *------------------------------------------------------------------*/
2860 PTA *
2862  l_int32 width)
2863 {
2864 PIX *pix1;
2865 PTA *pta;
2866 
2867  PROCNAME("pixGeneratePtaBoundary");
2868 
2869  if (!pixs || pixGetDepth(pixs) != 1)
2870  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
2871  if (width < 1) {
2872  L_WARNING("width < 1; setting to 1\n", procName);
2873  width = 1;
2874  }
2875 
2876  pix1 = pixErodeBrick(NULL, pixs, 2 * width + 1, 2 * width + 1);
2877  pixXor(pix1, pix1, pixs);
2878  pta = ptaGetPixelsFromPix(pix1, NULL);
2879  pixDestroy(&pix1);
2880  return pta;
2881 }
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:2744
l_int32 pixRenderHashBox(PIX *pix, BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 op)
pixRenderHashBox()
Definition: graphics.c:1842
l_int32 ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:970
l_int32 pixRenderPtaArb(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderPtaArb()
Definition: graphics.c:1343
PIX * pixFillPolygon(PIX *pixs, PTA *pta, l_int32 xmin, l_int32 ymin)
pixFillPolygon()
Definition: graphics.c:2539
l_int32 locatePtRadially(l_int32 xr, l_int32 yr, l_float64 dist, l_float64 radang, l_float64 *px, l_float64 *py)
locatePtRadially()
Definition: graphics.c:921
l_int32 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:2172
PTA * convertPtaLineTo4cc(PTA *ptas)
convertPtaLineTo4cc()
Definition: graphics.c:780
PTA * generatePtaBoxa(BOXA *boxa, l_int32 width, l_int32 removedups)
generatePtaBoxa()
Definition: graphics.c:350
PTAA * generatePtaaBoxa(BOXA *boxa)
generatePtaaBoxa()
Definition: graphics.c:565
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
l_int32 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:2120
l_int32 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:1482
l_int32 fpixGetMax(FPIX *fpix, l_float32 *pmaxval, l_int32 *pxmaxloc, l_int32 *pymaxloc)
fpixGetMax()
Definition: fpix2.c:742
PIX * pixRenderContours(PIX *pixs, l_int32 startval, l_int32 incr, l_int32 outdepth)
pixRenderContours()
Definition: graphics.c:2618
PTA * generatePtaLineFromPt(l_int32 x, l_int32 y, l_float64 length, l_float64 radang)
generatePtaLineFromPt()
Definition: graphics.c:897
l_int32 fpixGetMin(FPIX *fpix, l_float32 *pminval, l_int32 *pxminloc, l_int32 *pyminloc)
fpixGetMin()
Definition: fpix2.c:689
l_int32 ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:341
l_int32 pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:180
l_int32 numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:473
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:115
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:2484
l_int32 pixRenderPolyline(PIX *pix, PTA *ptas, l_int32 width, l_int32 op, l_int32 closeflag)
pixRenderPolyline()
Definition: graphics.c:2226
l_int32 boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:615
l_int32 numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:691
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
l_int32 pixRenderPtaBlend(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
pixRenderPtaBlend()
Definition: graphics.c:1417
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1395
l_int32 pixRenderPta(PIX *pix, PTA *pta, l_int32 op)
pixRenderPta()
Definition: graphics.c:1254
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:503
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:577
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1602
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_int32 pixRenderBoxaArb(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxaArb()
Definition: graphics.c:1758
l_int32 pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:709
l_int32 pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
pixClearPixel()
Definition: pix2.c:455
l_int32 numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:935
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
PTA * ptaRemoveDupsByAset(PTA *ptas)
ptaRemoveDupsByAset()
Definition: ptafunc2.c:354
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1013
Definition: pix.h:492
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:962
l_int32 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:2355
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)
pixRenderBoxaBlend()
Definition: graphics.c:1799
l_int32 pixRenderBoxArb(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxArb()
Definition: graphics.c:1641
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:110
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_int32 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
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:760
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1060
l_int32 pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
pixFlipPixel()
Definition: pix2.c:511
Definition: array.h:59
static const l_int32 L_INSERT
Definition: pix.h:710
l_int32 pixRenderBoxBlend(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
pixRenderBoxBlend()
Definition: graphics.c:1681
l_int32 pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
Definition: colormap.c:299
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1574
PTA * generatePtaLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2)
generatePtaLine()
Definition: graphics.c:138
l_int32 ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:154
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_int32 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:1892
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:295
Definition: pix.h:532
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
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:192
l_int32 pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1556
l_int32 boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:309
PTA * generatePtaFilledSquare(l_int32 side)
generatePtaFilledSquare()
Definition: graphics.c:863
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:182
l_int32 fpixGetWpl(FPIX *fpix)
fpixGetWpl()
Definition: fpix1.c:456
PTA * pixGeneratePtaBoundary(PIX *pixs, l_int32 width)
pixGeneratePtaBoundary()
Definition: graphics.c:2861
l_int32 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:1944
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:545
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:760
PIX * pixRenderRandomCmapPtaa(PIX *pix, PTAA *ptaa, l_int32 polyflag, l_int32 width, l_int32 closeflag)
pixRenderRandomCmapPtaa()
Definition: graphics.c:2415
l_float32 * fpixGetData(FPIX *fpix)
fpixGetData()
Definition: fpix1.c:599
l_int32 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_int32 pixcmapAddNearestColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNearestColor()
Definition: colormap.c:430
l_int32 pixRenderPlotFromNuma(PIX **ppix, NUMA *na, l_int32 plotloc, l_int32 linewidth, l_int32 max, l_uint32 color)
pixRenderPlotFromNuma()
Definition: graphics.c:963
l_int32 pixRenderPolylineArb(PIX *pix, PTA *ptas, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_int32 closeflag)
pixRenderPolylineArb()
Definition: graphics.c:2271
l_int32 pixRenderHashBoxa(PIX *pix, BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 op)
pixRenderHashBoxa()
Definition: graphics.c:2070
PIX * pixSeedfillBinary(PIX *pixd, PIX *pixs, PIX *pixm, l_int32 connectivity)
pixSeedfillBinary()
Definition: seedfill.c:243
l_int32 fpixGetDimensions(FPIX *fpix, l_int32 *pw, l_int32 *ph)
fpixGetDimensions()
Definition: fpix1.c:409
l_int32 ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:554
PIX * pixOr(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixOr()
Definition: pix3.c:1446
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1040
l_int32 pixFindHorizontalRuns(PIX *pix, l_int32 y, l_int32 *xstart, l_int32 *xend, l_int32 *pn)
pixFindHorizontalRuns()
Definition: runlength.c:372
l_int32 pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:251
l_int32 numaGetMin(NUMA *na, l_float32 *pminval, l_int32 *piminloc)
numaGetMin()
Definition: numafunc1.c:431
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:206
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2542
l_int32 pixRenderBox(PIX *pix, BOX *box, l_int32 width, l_int32 op)
pixRenderBox()
Definition: graphics.c:1603
PTA * generatePtaPolyline(PTA *ptas, l_int32 width, l_int32 closeflag, l_int32 removedups)
generatePtaPolyline()
Definition: graphics.c:664
l_int32 composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2659
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)
pixRenderLineArb()
Definition: graphics.c:1522
l_int32 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
Definition: pix.h:134
Definition: pix.h:706
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:496
l_int32 ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:468
#define PIX_SRC
Definition: pix.h:327
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:630
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)
pixRenderLineBlend()
Definition: graphics.c:1563
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:277
Definition: pix.h:201
l_int32 boxaGetCount(BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:715
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1052
l_int32 pixRenderBoxa(PIX *pix, BOXA *boxa, l_int32 width, l_int32 op)
pixRenderBoxa()
Definition: graphics.c:1720
PIX * pixErodeBrick(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeBrick()
Definition: morph.c:748
l_int32 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:2314
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1893
PTA * generatePtaFilledCircle(l_int32 radius)
generatePtaFilledCircle()
Definition: graphics.c:823
Definition: pix.h:480
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:216
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2725
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:164
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:121
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
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:157
l_int32 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:2002
PIX * fpixRenderContours(FPIX *fpixs, l_float32 incr, l_float32 proxim)
fpixRenderContours()
Definition: graphics.c:2782