Leptonica  1.83.1
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 #ifdef HAVE_CONFIG_H
118 #include <config_auto.h>
119 #endif /* HAVE_CONFIG_H */
120 
121 #include <string.h>
122 #include <math.h>
123 #include "allheaders.h"
124 
125 /*------------------------------------------------------------------*
126  * Pta generation for arbitrary shapes built with lines *
127  *------------------------------------------------------------------*/
140 PTA *
141 generatePtaLine(l_int32 x1,
142  l_int32 y1,
143  l_int32 x2,
144  l_int32 y2)
145 {
146 l_int32 npts, diff, getyofx, sign, i, x, y;
147 l_float32 slope;
148 PTA *pta;
149 
150  /* Generate line parameters */
151  if (x1 == x2 && y1 == y2) { /* same point */
152  getyofx = TRUE;
153  npts = 1;
154  } else if (L_ABS(x2 - x1) >= L_ABS(y2 - y1)) {
155  getyofx = TRUE;
156  npts = L_ABS(x2 - x1) + 1;
157  diff = x2 - x1;
158  sign = L_SIGN(x2 - x1);
159  slope = (l_float32)(sign * (y2 - y1)) / (l_float32)diff;
160  } else {
161  getyofx = FALSE;
162  npts = L_ABS(y2 - y1) + 1;
163  diff = y2 - y1;
164  sign = L_SIGN(y2 - y1);
165  slope = (l_float32)(sign * (x2 - x1)) / (l_float32)diff;
166  }
167 
168  if ((pta = ptaCreate(npts)) == NULL)
169  return (PTA *)ERROR_PTR("pta not made", __func__, NULL);
170 
171  if (npts == 1) { /* degenerate case */
172  ptaAddPt(pta, x1, y1);
173  return pta;
174  }
175 
176  /* Generate the set of points */
177  if (getyofx) { /* y = y(x) */
178  for (i = 0; i < npts; i++) {
179  x = x1 + sign * i;
180  y = (l_int32)(y1 + (l_float32)i * slope + 0.5);
181  ptaAddPt(pta, x, y);
182  }
183  } else { /* x = x(y) */
184  for (i = 0; i < npts; i++) {
185  x = (l_int32)(x1 + (l_float32)i * slope + 0.5);
186  y = y1 + sign * i;
187  ptaAddPt(pta, x, y);
188  }
189  }
190 
191  return pta;
192 }
193 
194 
203 PTA *
205  l_int32 y1,
206  l_int32 x2,
207  l_int32 y2,
208  l_int32 width)
209 {
210 l_int32 i, x1a, x2a, y1a, y2a;
211 PTA *pta, *ptaj;
212 
213  if (width < 1) {
214  L_WARNING("width < 1; setting to 1\n", __func__);
215  width = 1;
216  }
217 
218  if ((ptaj = generatePtaLine(x1, y1, x2, y2)) == NULL)
219  return (PTA *)ERROR_PTR("ptaj not made", __func__, NULL);
220  if (width == 1)
221  return ptaj;
222 
223  /* width > 1; estimate line direction & join */
224  if (L_ABS(x1 - x2) > L_ABS(y1 - y2)) { /* "horizontal" line */
225  for (i = 1; i < width; i++) {
226  if ((i & 1) == 1) { /* place above */
227  y1a = y1 - (i + 1) / 2;
228  y2a = y2 - (i + 1) / 2;
229  } else { /* place below */
230  y1a = y1 + (i + 1) / 2;
231  y2a = y2 + (i + 1) / 2;
232  }
233  if ((pta = generatePtaLine(x1, y1a, x2, y2a)) != NULL) {
234  ptaJoin(ptaj, pta, 0, -1);
235  ptaDestroy(&pta);
236  }
237  }
238  } else { /* "vertical" line */
239  for (i = 1; i < width; i++) {
240  if ((i & 1) == 1) { /* place to left */
241  x1a = x1 - (i + 1) / 2;
242  x2a = x2 - (i + 1) / 2;
243  } else { /* place to right */
244  x1a = x1 + (i + 1) / 2;
245  x2a = x2 + (i + 1) / 2;
246  }
247  if ((pta = generatePtaLine(x1a, y1, x2a, y2)) != NULL) {
248  ptaJoin(ptaj, pta, 0, -1);
249  ptaDestroy(&pta);
250  }
251  }
252  }
253 
254  return ptaj;
255 }
256 
257 
271 PTA *
273  l_int32 width)
274 {
275 l_int32 x, y, w, h;
276 PTA *ptad, *pta;
277 
278  if (!box)
279  return (PTA *)ERROR_PTR("box not defined", __func__, NULL);
280  if (width < 1) {
281  L_WARNING("width < 1; setting to 1\n", __func__);
282  width = 1;
283  }
284 
285  /* Generate line points and add them to the pta. */
286  boxGetGeometry(box, &x, &y, &w, &h);
287  if (w == 0 || h == 0)
288  return (PTA *)ERROR_PTR("box has w = 0 or h = 0", __func__, NULL);
289  ptad = ptaCreate(0);
290  if ((width & 1) == 1) { /* odd width */
291  pta = generatePtaWideLine(x - width / 2, y,
292  x + w - 1 + width / 2, y, width);
293  ptaJoin(ptad, pta, 0, -1);
294  ptaDestroy(&pta);
295  pta = generatePtaWideLine(x + w - 1, y + 1 + width / 2,
296  x + w - 1, y + h - 2 - width / 2, width);
297  ptaJoin(ptad, pta, 0, -1);
298  ptaDestroy(&pta);
299  pta = generatePtaWideLine(x + w - 1 + width / 2, y + h - 1,
300  x - width / 2, y + h - 1, width);
301  ptaJoin(ptad, pta, 0, -1);
302  ptaDestroy(&pta);
303  pta = generatePtaWideLine(x, y + h - 2 - width / 2,
304  x, y + 1 + width / 2, width);
305  ptaJoin(ptad, pta, 0, -1);
306  ptaDestroy(&pta);
307  } else { /* even width */
308  pta = generatePtaWideLine(x - width / 2, y,
309  x + w - 2 + width / 2, y, width);
310  ptaJoin(ptad, pta, 0, -1);
311  ptaDestroy(&pta);
312  pta = generatePtaWideLine(x + w - 1, y + 0 + width / 2,
313  x + w - 1, y + h - 2 - width / 2, width);
314  ptaJoin(ptad, pta, 0, -1);
315  ptaDestroy(&pta);
316  pta = generatePtaWideLine(x + w - 2 + width / 2, y + h - 1,
317  x - width / 2, y + h - 1, width);
318  ptaJoin(ptad, pta, 0, -1);
319  ptaDestroy(&pta);
320  pta = generatePtaWideLine(x, y + h - 2 - width / 2,
321  x, y + 0 + width / 2, width);
322  ptaJoin(ptad, pta, 0, -1);
323  ptaDestroy(&pta);
324  }
325 
326  return ptad;
327 }
328 
329 
346 PTA *
348  l_int32 width,
349  l_int32 removedups)
350 {
351 l_int32 i, n;
352 BOX *box;
353 PTA *ptad, *ptat, *pta;
354 
355  if (!boxa)
356  return (PTA *)ERROR_PTR("boxa not defined", __func__, NULL);
357  if (width < 1) {
358  L_WARNING("width < 1; setting to 1\n", __func__);
359  width = 1;
360  }
361 
362  n = boxaGetCount(boxa);
363  ptat = ptaCreate(0);
364  for (i = 0; i < n; i++) {
365  box = boxaGetBox(boxa, i, L_CLONE);
366  pta = generatePtaBox(box, width);
367  ptaJoin(ptat, pta, 0, -1);
368  ptaDestroy(&pta);
369  boxDestroy(&box);
370  }
371 
372  if (removedups)
373  ptaRemoveDupsByAset(ptat, &ptad);
374  else
375  ptad = ptaClone(ptat);
376 
377  ptaDestroy(&ptat);
378  return ptad;
379 }
380 
381 
401 PTA *
403  l_int32 spacing,
404  l_int32 width,
405  l_int32 orient,
406  l_int32 outline)
407 {
408 l_int32 bx, by, bh, bw, x, y, x1, y1, x2, y2, i, n, npts;
409 PTA *ptad, *pta;
410 
411  if (!box)
412  return (PTA *)ERROR_PTR("box not defined", __func__, NULL);
413  if (spacing <= 1)
414  return (PTA *)ERROR_PTR("spacing not > 1", __func__, NULL);
415  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
416  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
417  return (PTA *)ERROR_PTR("invalid line orientation", __func__, NULL);
418  boxGetGeometry(box, &bx, &by, &bw, &bh);
419  if (bw == 0 || bh == 0)
420  return (PTA *)ERROR_PTR("box has bw = 0 or bh = 0", __func__, NULL);
421  if (width < 1) {
422  L_WARNING("width < 1; setting to 1\n", __func__);
423  width = 1;
424  }
425 
426  /* Generate line points and add them to the pta. */
427  ptad = ptaCreate(0);
428  if (outline) {
429  pta = generatePtaBox(box, width);
430  ptaJoin(ptad, pta, 0, -1);
431  ptaDestroy(&pta);
432  }
433  if (orient == L_HORIZONTAL_LINE) {
434  n = 1 + bh / spacing;
435  for (i = 0; i < n; i++) {
436  y = by + (i * (bh - 1)) / (n - 1);
437  pta = generatePtaWideLine(bx, y, bx + bw - 1, y, width);
438  ptaJoin(ptad, pta, 0, -1);
439  ptaDestroy(&pta);
440  }
441  } else if (orient == L_VERTICAL_LINE) {
442  n = 1 + bw / spacing;
443  for (i = 0; i < n; i++) {
444  x = bx + (i * (bw - 1)) / (n - 1);
445  pta = generatePtaWideLine(x, by, x, by + bh - 1, width);
446  ptaJoin(ptad, pta, 0, -1);
447  ptaDestroy(&pta);
448  }
449  } else if (orient == L_POS_SLOPE_LINE) {
450  n = 2 + (l_int32)((bw + bh) / (1.4 * spacing));
451  for (i = 0; i < n; i++) {
452  x = (l_int32)(bx + (i + 0.5) * 1.4 * spacing);
453  boxIntersectByLine(box, x, by - 1, 1.0, &x1, &y1, &x2, &y2, &npts);
454  if (npts == 2) {
455  pta = generatePtaWideLine(x1, y1, x2, y2, width);
456  ptaJoin(ptad, pta, 0, -1);
457  ptaDestroy(&pta);
458  }
459  }
460  } else { /* orient == L_NEG_SLOPE_LINE */
461  n = 2 + (l_int32)((bw + bh) / (1.4 * spacing));
462  for (i = 0; i < n; i++) {
463  x = (l_int32)(bx - bh + (i + 0.5) * 1.4 * spacing);
464  boxIntersectByLine(box, x, by - 1, -1.0, &x1, &y1, &x2, &y2, &npts);
465  if (npts == 2) {
466  pta = generatePtaWideLine(x1, y1, x2, y2, width);
467  ptaJoin(ptad, pta, 0, -1);
468  ptaDestroy(&pta);
469  }
470  }
471  }
472 
473  return ptad;
474 }
475 
476 
502 PTA *
504  l_int32 spacing,
505  l_int32 width,
506  l_int32 orient,
507  l_int32 outline,
508  l_int32 removedups)
509 {
510 l_int32 i, n;
511 BOX *box;
512 PTA *ptad, *ptat, *pta;
513 
514  if (!boxa)
515  return (PTA *)ERROR_PTR("boxa not defined", __func__, NULL);
516  if (spacing <= 1)
517  return (PTA *)ERROR_PTR("spacing not > 1", __func__, NULL);
518  if (width < 1) {
519  L_WARNING("width < 1; setting to 1\n", __func__);
520  width = 1;
521  }
522  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
523  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
524  return (PTA *)ERROR_PTR("invalid line orientation", __func__, NULL);
525 
526  n = boxaGetCount(boxa);
527  ptat = ptaCreate(0);
528  for (i = 0; i < n; i++) {
529  box = boxaGetBox(boxa, i, L_CLONE);
530  pta = generatePtaHashBox(box, spacing, width, orient, outline);
531  ptaJoin(ptat, pta, 0, -1);
532  ptaDestroy(&pta);
533  boxDestroy(&box);
534  }
535 
536  if (removedups)
537  ptaRemoveDupsByAset(ptat, &ptad);
538  else
539  ptad = ptaClone(ptat);
540 
541  ptaDestroy(&ptat);
542  return ptad;
543 }
544 
545 
560 PTAA *
562 {
563 l_int32 i, n, x, y, w, h;
564 BOX *box;
565 PTA *pta;
566 PTAA *ptaa;
567 
568  if (!boxa)
569  return (PTAA *)ERROR_PTR("boxa not defined", __func__, NULL);
570 
571  n = boxaGetCount(boxa);
572  ptaa = ptaaCreate(n);
573  for (i = 0; i < n; i++) {
574  box = boxaGetBox(boxa, i, L_CLONE);
575  boxGetGeometry(box, &x, &y, &w, &h);
576  pta = ptaCreate(4);
577  ptaAddPt(pta, x, y);
578  ptaAddPt(pta, x + w - 1, y);
579  ptaAddPt(pta, x + w - 1, y + h - 1);
580  ptaAddPt(pta, x, y + h - 1);
581  ptaaAddPta(ptaa, pta, L_INSERT);
582  boxDestroy(&box);
583  }
584 
585  return ptaa;
586 }
587 
588 
611 PTAA *
613  l_int32 spacing,
614  l_int32 width,
615  l_int32 orient,
616  l_int32 outline)
617 {
618 l_int32 i, n;
619 BOX *box;
620 PTA *pta;
621 PTAA *ptaa;
622 
623  if (!boxa)
624  return (PTAA *)ERROR_PTR("boxa not defined", __func__, NULL);
625  if (spacing <= 1)
626  return (PTAA *)ERROR_PTR("spacing not > 1", __func__, NULL);
627  if (width < 1) {
628  L_WARNING("width < 1; setting to 1\n", __func__);
629  width = 1;
630  }
631  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
632  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
633  return (PTAA *)ERROR_PTR("invalid line orientation", __func__, NULL);
634 
635  n = boxaGetCount(boxa);
636  ptaa = ptaaCreate(n);
637  for (i = 0; i < n; i++) {
638  box = boxaGetBox(boxa, i, L_CLONE);
639  pta = generatePtaHashBox(box, spacing, width, orient, outline);
640  ptaaAddPta(ptaa, pta, L_INSERT);
641  boxDestroy(&box);
642  }
643 
644  return ptaa;
645 }
646 
647 
657 PTA *
659  l_int32 width,
660  l_int32 closeflag,
661  l_int32 removedups)
662 {
663 l_int32 i, n, x1, y1, x2, y2;
664 PTA *ptad, *ptat, *pta;
665 
666  if (!ptas)
667  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
668  if (width < 1) {
669  L_WARNING("width < 1; setting to 1\n", __func__);
670  width = 1;
671  }
672 
673  n = ptaGetCount(ptas);
674  ptat = ptaCreate(0);
675  if (n < 2) /* nothing to do */
676  return ptat;
677 
678  ptaGetIPt(ptas, 0, &x1, &y1);
679  for (i = 1; i < n; i++) {
680  ptaGetIPt(ptas, i, &x2, &y2);
681  pta = generatePtaWideLine(x1, y1, x2, y2, width);
682  ptaJoin(ptat, pta, 0, -1);
683  ptaDestroy(&pta);
684  x1 = x2;
685  y1 = y2;
686  }
687 
688  if (closeflag) {
689  ptaGetIPt(ptas, 0, &x2, &y2);
690  pta = generatePtaWideLine(x1, y1, x2, y2, width);
691  ptaJoin(ptat, pta, 0, -1);
692  ptaDestroy(&pta);
693  }
694 
695  if (removedups)
696  ptaRemoveDupsByAset(ptat, &ptad);
697  else
698  ptad = ptaClone(ptat);
699 
700  ptaDestroy(&ptat);
701  return ptad;
702 }
703 
704 
713 PTA *
714 generatePtaGrid(l_int32 w,
715  l_int32 h,
716  l_int32 nx,
717  l_int32 ny,
718  l_int32 width)
719 {
720 l_int32 i, j, bx, by, x1, x2, y1, y2;
721 BOX *box;
722 BOXA *boxa;
723 PTA *pta;
724 
725  if (nx < 1 || ny < 1)
726  return (PTA *)ERROR_PTR("nx and ny must be > 0", __func__, NULL);
727  if (w < 2 * nx || h < 2 * ny)
728  return (PTA *)ERROR_PTR("w and/or h too small", __func__, NULL);
729  if (width < 1) {
730  L_WARNING("width < 1; setting to 1\n", __func__);
731  width = 1;
732  }
733 
734  boxa = boxaCreate(nx * ny);
735  bx = (w + nx - 1) / nx;
736  by = (h + ny - 1) / ny;
737  for (i = 0; i < ny; i++) {
738  y1 = by * i;
739  y2 = L_MIN(y1 + by, h - 1);
740  for (j = 0; j < nx; j++) {
741  x1 = bx * j;
742  x2 = L_MIN(x1 + bx, w - 1);
743  box = boxCreate(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
744  boxaAddBox(boxa, box, L_INSERT);
745  }
746  }
747 
748  pta = generatePtaBoxa(boxa, width, 1);
749  boxaDestroy(&boxa);
750  return pta;
751 }
752 
753 
769 PTA *
771 {
772 l_int32 i, n, x, y, xp, yp;
773 PTA *ptad;
774 
775  if (!ptas)
776  return (PTA *)ERROR_PTR("ptas not defined", __func__, NULL);
777 
778  n = ptaGetCount(ptas);
779  ptad = ptaCreate(n);
780  ptaGetIPt(ptas, 0, &xp, &yp);
781  ptaAddPt(ptad, xp, yp);
782  for (i = 1; i < n; i++) {
783  ptaGetIPt(ptas, i, &x, &y);
784  if (x != xp && y != yp) /* diagonal */
785  ptaAddPt(ptad, x, yp);
786  ptaAddPt(ptad, x, y);
787  xp = x;
788  yp = y;
789  }
790 
791  return ptad;
792 }
793 
794 
810 PTA *
811 generatePtaFilledCircle(l_int32 radius)
812 {
813 l_int32 x, y;
814 l_float32 radthresh, sqdist;
815 PTA *pta;
816 
817  if (radius < 1)
818  return (PTA *)ERROR_PTR("radius must be >= 1", __func__, NULL);
819 
820  pta = ptaCreate(0);
821  radthresh = (radius + 0.5) * (radius + 0.5);
822  for (y = 0; y <= 2 * radius; y++) {
823  for (x = 0; x <= 2 * radius; x++) {
824  sqdist = (l_float32)((y - radius) * (y - radius) +
825  (x - radius) * (x - radius));
826  if (sqdist <= radthresh)
827  ptaAddPt(pta, x, y);
828  }
829  }
830 
831  return pta;
832 }
833 
834 
848 PTA *
850 {
851 l_int32 x, y;
852 PTA *pta;
853 
854  if (side < 1)
855  return (PTA *)ERROR_PTR("side must be > 0", __func__, NULL);
856 
857  pta = ptaCreate(0);
858  for (y = 0; y < side; y++)
859  for (x = 0; x < side; x++)
860  ptaAddPt(pta, x, y);
861 
862  return pta;
863 }
864 
865 
881 PTA *
883  l_int32 y,
884  l_float64 length,
885  l_float64 radang)
886 {
887 l_int32 x2, y2; /* the point at the other end of the line */
888 
889  x2 = x + (l_int32)((length - 1.0) * cos(radang));
890  y2 = y + (l_int32)((length - 1.0) * sin(radang));
891  return generatePtaLine(x, y, x2, y2);
892 }
893 
894 
905 l_ok
906 locatePtRadially(l_int32 xr,
907  l_int32 yr,
908  l_float64 dist,
909  l_float64 radang,
910  l_float64 *px,
911  l_float64 *py)
912 {
913  if (!px || !py)
914  return ERROR_INT("&x and &y not both defined", __func__, 1);
915 
916  *px = xr + dist * cos(radang);
917  *py = yr + dist * sin(radang);
918  return 0;
919 }
920 
921 
922 /*------------------------------------------------------------------*
923  * Rendering function plots directly on images *
924  *------------------------------------------------------------------*/
945 l_ok
947  NUMA *na,
948  l_int32 plotloc,
949  l_int32 linewidth,
950  l_int32 max,
951  l_uint32 color)
952 {
953 l_int32 w, h, size, rval, gval, bval;
954 PIX *pix1;
955 PTA *pta;
956 
957  if (!ppix)
958  return ERROR_INT("&pix not defined", __func__, 1);
959  if (*ppix == NULL)
960  return ERROR_INT("pix not defined", __func__, 1);
961 
962  pixGetDimensions(*ppix, &w, &h, NULL);
963  size = (plotloc == L_PLOT_AT_TOP || plotloc == L_PLOT_AT_MID_HORIZ ||
964  plotloc == L_PLOT_AT_BOT) ? h : w;
965  pta = makePlotPtaFromNuma(na, size, plotloc, linewidth, max);
966  if (!pta)
967  return ERROR_INT("pta not made", __func__, 1);
968 
969  if (pixGetDepth(*ppix) != 32) {
970  pix1 = pixConvertTo32(*ppix);
971  pixDestroy(ppix);
972  *ppix = pix1;
973  }
974  extractRGBValues(color, &rval, &gval, &bval);
975  pixRenderPtaArb(*ppix, pta, rval, gval, bval);
976  ptaDestroy(&pta);
977  return 0;
978 }
979 
980 
1002 PTA *
1004  l_int32 size,
1005  l_int32 plotloc,
1006  l_int32 linewidth,
1007  l_int32 max)
1008 {
1009 l_int32 orient, refpos;
1010 
1011  if (!na)
1012  return (PTA *)ERROR_PTR("na not defined", __func__, NULL);
1013  if (plotloc == L_PLOT_AT_TOP || plotloc == L_PLOT_AT_MID_HORIZ ||
1014  plotloc == L_PLOT_AT_BOT) {
1015  orient = L_HORIZONTAL_LINE;
1016  } else if (plotloc == L_PLOT_AT_LEFT || plotloc == L_PLOT_AT_MID_VERT ||
1017  plotloc == L_PLOT_AT_RIGHT) {
1018  orient = L_VERTICAL_LINE;
1019  } else {
1020  return (PTA *)ERROR_PTR("invalid plotloc", __func__, NULL);
1021  }
1022 
1023  if (plotloc == L_PLOT_AT_LEFT || plotloc == L_PLOT_AT_TOP)
1024  refpos = max;
1025  else if (plotloc == L_PLOT_AT_MID_VERT || plotloc == L_PLOT_AT_MID_HORIZ)
1026  refpos = size / 2;
1027  else /* L_PLOT_AT_RIGHT || L_PLOT_AT_BOT */
1028  refpos = size - max - 1;
1029 
1030  return makePlotPtaFromNumaGen(na, orient, linewidth, refpos, max, 1);
1031 }
1032 
1033 
1057 l_ok
1059  NUMA *na,
1060  l_int32 orient,
1061  l_int32 linewidth,
1062  l_int32 refpos,
1063  l_int32 max,
1064  l_int32 drawref,
1065  l_uint32 color)
1066 {
1067 l_int32 rval, gval, bval;
1068 PIX *pix1;
1069 PTA *pta;
1070 
1071  if (!ppix)
1072  return ERROR_INT("&pix not defined", __func__, 1);
1073  if (*ppix == NULL)
1074  return ERROR_INT("pix not defined", __func__, 1);
1075 
1076  pta = makePlotPtaFromNumaGen(na, orient, linewidth, refpos, max, drawref);
1077  if (!pta)
1078  return ERROR_INT("pta not made", __func__, 1);
1079 
1080  if (pixGetDepth(*ppix) != 32) {
1081  pix1 = pixConvertTo32(*ppix);
1082  pixDestroy(ppix);
1083  *ppix = pix1;
1084  }
1085  extractRGBValues(color, &rval, &gval, &bval);
1086  pixRenderPtaArb(*ppix, pta, rval, gval, bval);
1087  ptaDestroy(&pta);
1088  return 0;
1089 }
1090 
1091 
1121 PTA *
1123  l_int32 orient,
1124  l_int32 linewidth,
1125  l_int32 refpos,
1126  l_int32 max,
1127  l_int32 drawref)
1128 {
1129 l_int32 i, n, maxw, maxh;
1130 l_float32 minval, maxval, absval, val, scale, start, del;
1131 PTA *pta1, *pta2, *ptad;
1132 
1133  if (!na)
1134  return (PTA *)ERROR_PTR("na not defined", __func__, NULL);
1135  if (orient != L_HORIZONTAL_LINE && orient != L_VERTICAL_LINE)
1136  return (PTA *)ERROR_PTR("invalid orient", __func__, NULL);
1137  if (linewidth < 1) {
1138  L_WARNING("linewidth < 1; setting to 1\n", __func__);
1139  linewidth = 1;
1140  }
1141  if (linewidth > 7) {
1142  L_WARNING("linewidth > 7; setting to 7\n", __func__);
1143  linewidth = 7;
1144  }
1145 
1146  numaGetMin(na, &minval, NULL);
1147  numaGetMax(na, &maxval, NULL);
1148  absval = L_MAX(L_ABS(minval), L_ABS(maxval));
1149  scale = (l_float32)max / (l_float32)absval;
1150  n = numaGetCount(na);
1151  numaGetParameters(na, &start, &del);
1152 
1153  /* Generate the plot points */
1154  pta1 = ptaCreate(n);
1155  for (i = 0; i < n; i++) {
1156  numaGetFValue(na, i, &val);
1157  if (orient == L_HORIZONTAL_LINE) {
1158  ptaAddPt(pta1, start + i * del, refpos + scale * val);
1159  maxw = (del >= 0) ? start + n * del + linewidth
1160  : start + linewidth;
1161  maxh = refpos + max + linewidth;
1162  } else { /* vertical line */
1163  ptaAddPt(pta1, refpos + scale * val, start + i * del);
1164  maxw = refpos + max + linewidth;
1165  maxh = (del >= 0) ? start + n * del + linewidth
1166  : start + linewidth;
1167  }
1168  }
1169 
1170  /* Optionally, widen the plot */
1171  if (linewidth > 1) {
1172  if (linewidth % 2 == 0) /* even linewidth; use side of a square */
1173  pta2 = generatePtaFilledSquare(linewidth);
1174  else /* odd linewidth; use radius of a circle */
1175  pta2 = generatePtaFilledCircle(linewidth / 2);
1176  ptad = ptaReplicatePattern(pta1, NULL, pta2, linewidth / 2,
1177  linewidth / 2, maxw, maxh);
1178  ptaDestroy(&pta2);
1179  } else {
1180  ptad = ptaClone(pta1);
1181  }
1182  ptaDestroy(&pta1);
1183 
1184  /* Optionally, add the reference lines */
1185  if (drawref) {
1186  if (orient == L_HORIZONTAL_LINE) {
1187  pta1 = generatePtaLine(start, refpos, start + n * del, refpos);
1188  ptaJoin(ptad, pta1, 0, -1);
1189  ptaDestroy(&pta1);
1190  pta1 = generatePtaLine(start, refpos - max,
1191  start, refpos + max);
1192  ptaJoin(ptad, pta1, 0, -1);
1193  } else { /* vertical line */
1194  pta1 = generatePtaLine(refpos, start, refpos, start + n * del);
1195  ptaJoin(ptad, pta1, 0, -1);
1196  ptaDestroy(&pta1);
1197  pta1 = generatePtaLine(refpos - max, start,
1198  refpos + max, start);
1199  ptaJoin(ptad, pta1, 0, -1);
1200  }
1201  ptaDestroy(&pta1);
1202  }
1203 
1204  return ptad;
1205 }
1206 
1207 
1208 /*------------------------------------------------------------------*
1209  * Pta generation for arbitrary shapes built with lines *
1210  *------------------------------------------------------------------*/
1231 l_ok
1233  PTA *pta,
1234  l_int32 op)
1235 {
1236 l_int32 i, n, x, y, w, h, d, maxval;
1237 
1238  if (!pix)
1239  return ERROR_INT("pix not defined", __func__, 1);
1240  if (pixGetColormap(pix))
1241  return ERROR_INT("pix is colormapped", __func__, 1);
1242  if (!pta)
1243  return ERROR_INT("pta not defined", __func__, 1);
1244  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1245  return ERROR_INT("invalid op", __func__, 1);
1246 
1247  pixGetDimensions(pix, &w, &h, &d);
1248  maxval = 1;
1249  if (op == L_SET_PIXELS) {
1250  switch (d)
1251  {
1252  case 2:
1253  maxval = 0x3;
1254  break;
1255  case 4:
1256  maxval = 0xf;
1257  break;
1258  case 8:
1259  maxval = 0xff;
1260  break;
1261  case 16:
1262  maxval = 0xffff;
1263  break;
1264  case 32:
1265  maxval = 0xffffffff;
1266  break;
1267  }
1268  }
1269 
1270  n = ptaGetCount(pta);
1271  for (i = 0; i < n; i++) {
1272  ptaGetIPt(pta, i, &x, &y);
1273  if (x < 0 || x >= w)
1274  continue;
1275  if (y < 0 || y >= h)
1276  continue;
1277  switch (op)
1278  {
1279  case L_SET_PIXELS:
1280  pixSetPixel(pix, x, y, maxval);
1281  break;
1282  case L_CLEAR_PIXELS:
1283  pixClearPixel(pix, x, y);
1284  break;
1285  case L_FLIP_PIXELS:
1286  pixFlipPixel(pix, x, y);
1287  break;
1288  default:
1289  break;
1290  }
1291  }
1292 
1293  return 0;
1294 }
1295 
1296 
1318 l_ok
1320  PTA *pta,
1321  l_uint8 rval,
1322  l_uint8 gval,
1323  l_uint8 bval)
1324 {
1325 l_int32 i, n, x, y, w, h, d, index;
1326 l_uint8 val;
1327 l_uint32 val32;
1328 PIXCMAP *cmap;
1329 
1330  if (!pix)
1331  return ERROR_INT("pix not defined", __func__, 1);
1332  if (!pta)
1333  return ERROR_INT("pta not defined", __func__, 1);
1334  d = pixGetDepth(pix);
1335  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 32)
1336  return ERROR_INT("depth not in {1,2,4,8,32}", __func__, 1);
1337 
1338  if (d == 1) {
1339  pixRenderPta(pix, pta, L_SET_PIXELS);
1340  return 0;
1341  }
1342 
1343  cmap = pixGetColormap(pix);
1344  pixGetDimensions(pix, &w, &h, &d);
1345  if (cmap) {
1346  pixcmapAddNearestColor(cmap, rval, gval, bval, &index);
1347  } else {
1348  if (d == 2)
1349  val = (rval + gval + bval) / (3 * 64);
1350  else if (d == 4)
1351  val = (rval + gval + bval) / (3 * 16);
1352  else if (d == 8)
1353  val = (rval + gval + bval) / 3;
1354  else /* d == 32 */
1355  composeRGBPixel(rval, gval, bval, &val32);
1356  }
1357 
1358  n = ptaGetCount(pta);
1359  for (i = 0; i < n; i++) {
1360  ptaGetIPt(pta, i, &x, &y);
1361  if (x < 0 || x >= w)
1362  continue;
1363  if (y < 0 || y >= h)
1364  continue;
1365  if (cmap)
1366  pixSetPixel(pix, x, y, index);
1367  else if (d == 32)
1368  pixSetPixel(pix, x, y, val32);
1369  else
1370  pixSetPixel(pix, x, y, val);
1371  }
1372 
1373  return 0;
1374 }
1375 
1376 
1391 l_ok
1393  PTA *pta,
1394  l_uint8 rval,
1395  l_uint8 gval,
1396  l_uint8 bval,
1397  l_float32 fract)
1398 {
1399 l_int32 i, n, x, y, w, h;
1400 l_uint8 nrval, ngval, nbval;
1401 l_uint32 val32;
1402 l_float32 frval, fgval, fbval;
1403 
1404  if (!pix)
1405  return ERROR_INT("pix not defined", __func__, 1);
1406  if (!pta)
1407  return ERROR_INT("pta not defined", __func__, 1);
1408  if (pixGetDepth(pix) != 32)
1409  return ERROR_INT("depth not 32 bpp", __func__, 1);
1410  if (fract < 0.0 || fract > 1.0) {
1411  L_WARNING("fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
1412  fract = 0.5;
1413  }
1414 
1415  pixGetDimensions(pix, &w, &h, NULL);
1416  n = ptaGetCount(pta);
1417  frval = fract * rval;
1418  fgval = fract * gval;
1419  fbval = fract * bval;
1420  for (i = 0; i < n; i++) {
1421  ptaGetIPt(pta, i, &x, &y);
1422  if (x < 0 || x >= w)
1423  continue;
1424  if (y < 0 || y >= h)
1425  continue;
1426  pixGetPixel(pix, x, y, &val32);
1427  nrval = GET_DATA_BYTE(&val32, COLOR_RED);
1428  nrval = (l_uint8)((1. - fract) * nrval + frval);
1429  ngval = GET_DATA_BYTE(&val32, COLOR_GREEN);
1430  ngval = (l_uint8)((1. - fract) * ngval + fgval);
1431  nbval = GET_DATA_BYTE(&val32, COLOR_BLUE);
1432  nbval = (l_uint8)((1. - fract) * nbval + fbval);
1433  composeRGBPixel(nrval, ngval, nbval, &val32);
1434  pixSetPixel(pix, x, y, val32);
1435  }
1436 
1437  return 0;
1438 }
1439 
1440 
1441 /*------------------------------------------------------------------*
1442  * Rendering of arbitrary shapes built with lines *
1443  *------------------------------------------------------------------*/
1454 l_ok
1456  l_int32 x1,
1457  l_int32 y1,
1458  l_int32 x2,
1459  l_int32 y2,
1460  l_int32 width,
1461  l_int32 op)
1462 {
1463 PTA *pta;
1464 
1465  if (!pix)
1466  return ERROR_INT("pix not defined", __func__, 1);
1467  if (width < 1) {
1468  L_WARNING("width must be > 0; setting to 1\n", __func__);
1469  width = 1;
1470  }
1471  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1472  return ERROR_INT("invalid op", __func__, 1);
1473 
1474  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1475  return ERROR_INT("pta not made", __func__, 1);
1476  pixRenderPta(pix, pta, op);
1477  ptaDestroy(&pta);
1478  return 0;
1479 }
1480 
1481 
1492 l_ok
1494  l_int32 x1,
1495  l_int32 y1,
1496  l_int32 x2,
1497  l_int32 y2,
1498  l_int32 width,
1499  l_uint8 rval,
1500  l_uint8 gval,
1501  l_uint8 bval)
1502 {
1503 PTA *pta;
1504 
1505  if (!pix)
1506  return ERROR_INT("pix not defined", __func__, 1);
1507  if (width < 1) {
1508  L_WARNING("width must be > 0; setting to 1\n", __func__);
1509  width = 1;
1510  }
1511 
1512  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1513  return ERROR_INT("pta not made", __func__, 1);
1514  pixRenderPtaArb(pix, pta, rval, gval, bval);
1515  ptaDestroy(&pta);
1516  return 0;
1517 }
1518 
1519 
1531 l_ok
1533  l_int32 x1,
1534  l_int32 y1,
1535  l_int32 x2,
1536  l_int32 y2,
1537  l_int32 width,
1538  l_uint8 rval,
1539  l_uint8 gval,
1540  l_uint8 bval,
1541  l_float32 fract)
1542 {
1543 PTA *pta;
1544 
1545  if (!pix)
1546  return ERROR_INT("pix not defined", __func__, 1);
1547  if (width < 1) {
1548  L_WARNING("width must be > 0; setting to 1\n", __func__);
1549  width = 1;
1550  }
1551 
1552  if ((pta = generatePtaWideLine(x1, y1, x2, y2, width)) == NULL)
1553  return ERROR_INT("pta not made", __func__, 1);
1554  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1555  ptaDestroy(&pta);
1556  return 0;
1557 }
1558 
1559 
1569 l_ok
1571  BOX *box,
1572  l_int32 width,
1573  l_int32 op)
1574 {
1575 PTA *pta;
1576 
1577  if (!pix)
1578  return ERROR_INT("pix not defined", __func__, 1);
1579  if (!box)
1580  return ERROR_INT("box not defined", __func__, 1);
1581  if (width < 1) {
1582  L_WARNING("width < 1; setting to 1\n", __func__);
1583  width = 1;
1584  }
1585  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1586  return ERROR_INT("invalid op", __func__, 1);
1587 
1588  if ((pta = generatePtaBox(box, width)) == NULL)
1589  return ERROR_INT("pta not made", __func__, 1);
1590  pixRenderPta(pix, pta, op);
1591  ptaDestroy(&pta);
1592  return 0;
1593 }
1594 
1595 
1605 l_ok
1607  BOX *box,
1608  l_int32 width,
1609  l_uint8 rval,
1610  l_uint8 gval,
1611  l_uint8 bval)
1612 {
1613 PTA *pta;
1614 
1615  if (!pix)
1616  return ERROR_INT("pix not defined", __func__, 1);
1617  if (!box)
1618  return ERROR_INT("box not defined", __func__, 1);
1619  if (width < 1) {
1620  L_WARNING("width < 1; setting to 1\n", __func__);
1621  width = 1;
1622  }
1623 
1624  if ((pta = generatePtaBox(box, width)) == NULL)
1625  return ERROR_INT("pta not made", __func__, 1);
1626  pixRenderPtaArb(pix, pta, rval, gval, bval);
1627  ptaDestroy(&pta);
1628  return 0;
1629 }
1630 
1631 
1643 l_ok
1645  BOX *box,
1646  l_int32 width,
1647  l_uint8 rval,
1648  l_uint8 gval,
1649  l_uint8 bval,
1650  l_float32 fract)
1651 {
1652 PTA *pta;
1653 
1654  if (!pix)
1655  return ERROR_INT("pix not defined", __func__, 1);
1656  if (!box)
1657  return ERROR_INT("box not defined", __func__, 1);
1658  if (width < 1) {
1659  L_WARNING("width < 1; setting to 1\n", __func__);
1660  width = 1;
1661  }
1662 
1663  if ((pta = generatePtaBox(box, width)) == NULL)
1664  return ERROR_INT("pta not made", __func__, 1);
1665  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1666  ptaDestroy(&pta);
1667  return 0;
1668 }
1669 
1670 
1680 l_ok
1682  BOXA *boxa,
1683  l_int32 width,
1684  l_int32 op)
1685 {
1686 PTA *pta;
1687 
1688  if (!pix)
1689  return ERROR_INT("pix not defined", __func__, 1);
1690  if (!boxa)
1691  return ERROR_INT("boxa not defined", __func__, 1);
1692  if (width < 1) {
1693  L_WARNING("width < 1; setting to 1\n", __func__);
1694  width = 1;
1695  }
1696  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1697  return ERROR_INT("invalid op", __func__, 1);
1698 
1699  if ((pta = generatePtaBoxa(boxa, width, 0)) == NULL)
1700  return ERROR_INT("pta not made", __func__, 1);
1701  pixRenderPta(pix, pta, op);
1702  ptaDestroy(&pta);
1703  return 0;
1704 }
1705 
1706 
1716 l_ok
1718  BOXA *boxa,
1719  l_int32 width,
1720  l_uint8 rval,
1721  l_uint8 gval,
1722  l_uint8 bval)
1723 {
1724 PTA *pta;
1725 
1726  if (!pix)
1727  return ERROR_INT("pix not defined", __func__, 1);
1728  if (!boxa)
1729  return ERROR_INT("boxa not defined", __func__, 1);
1730  if (width < 1) {
1731  L_WARNING("width < 1; setting to 1\n", __func__);
1732  width = 1;
1733  }
1734 
1735  if ((pta = generatePtaBoxa(boxa, width, 0)) == NULL)
1736  return ERROR_INT("pta not made", __func__, 1);
1737  pixRenderPtaArb(pix, pta, rval, gval, bval);
1738  ptaDestroy(&pta);
1739  return 0;
1740 }
1741 
1742 
1755 l_ok
1757  BOXA *boxa,
1758  l_int32 width,
1759  l_uint8 rval,
1760  l_uint8 gval,
1761  l_uint8 bval,
1762  l_float32 fract,
1763  l_int32 removedups)
1764 {
1765 PTA *pta;
1766 
1767  if (!pix)
1768  return ERROR_INT("pix not defined", __func__, 1);
1769  if (!boxa)
1770  return ERROR_INT("boxa not defined", __func__, 1);
1771  if (width < 1) {
1772  L_WARNING("width < 1; setting to 1\n", __func__);
1773  width = 1;
1774  }
1775 
1776  if ((pta = generatePtaBoxa(boxa, width, removedups)) == NULL)
1777  return ERROR_INT("pta not made", __func__, 1);
1778  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1779  ptaDestroy(&pta);
1780  return 0;
1781 }
1782 
1783 
1796 l_ok
1798  BOX *box,
1799  l_int32 spacing,
1800  l_int32 width,
1801  l_int32 orient,
1802  l_int32 outline,
1803  l_int32 op)
1804 {
1805 PTA *pta;
1806 
1807  if (!pix)
1808  return ERROR_INT("pix not defined", __func__, 1);
1809  if (!box)
1810  return ERROR_INT("box not defined", __func__, 1);
1811  if (spacing <= 1)
1812  return ERROR_INT("spacing not > 1", __func__, 1);
1813  if (width < 1) {
1814  L_WARNING("width < 1; setting to 1\n", __func__);
1815  width = 1;
1816  }
1817  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1818  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1819  return ERROR_INT("invalid line orientation", __func__, 1);
1820  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
1821  return ERROR_INT("invalid op", __func__, 1);
1822 
1823  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1824  if (!pta)
1825  return ERROR_INT("pta not made", __func__, 1);
1826  pixRenderPta(pix, pta, op);
1827  ptaDestroy(&pta);
1828  return 0;
1829 }
1830 
1831 
1844 l_ok
1846  BOX *box,
1847  l_int32 spacing,
1848  l_int32 width,
1849  l_int32 orient,
1850  l_int32 outline,
1851  l_int32 rval,
1852  l_int32 gval,
1853  l_int32 bval)
1854 {
1855 PTA *pta;
1856 
1857  if (!pix)
1858  return ERROR_INT("pix not defined", __func__, 1);
1859  if (!box)
1860  return ERROR_INT("box not defined", __func__, 1);
1861  if (spacing <= 1)
1862  return ERROR_INT("spacing not > 1", __func__, 1);
1863  if (width < 1) {
1864  L_WARNING("width < 1; setting to 1\n", __func__);
1865  width = 1;
1866  }
1867  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1868  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1869  return ERROR_INT("invalid line orientation", __func__, 1);
1870 
1871  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1872  if (!pta)
1873  return ERROR_INT("pta not made", __func__, 1);
1874  pixRenderPtaArb(pix, pta, rval, gval, bval);
1875  ptaDestroy(&pta);
1876  return 0;
1877 }
1878 
1879 
1894 l_ok
1896  BOX *box,
1897  l_int32 spacing,
1898  l_int32 width,
1899  l_int32 orient,
1900  l_int32 outline,
1901  l_int32 rval,
1902  l_int32 gval,
1903  l_int32 bval,
1904  l_float32 fract)
1905 {
1906 PTA *pta;
1907 
1908  if (!pix)
1909  return ERROR_INT("pix not defined", __func__, 1);
1910  if (!box)
1911  return ERROR_INT("box not defined", __func__, 1);
1912  if (spacing <= 1)
1913  return ERROR_INT("spacing not > 1", __func__, 1);
1914  if (width < 1) {
1915  L_WARNING("width < 1; setting to 1\n", __func__);
1916  width = 1;
1917  }
1918  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1919  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1920  return ERROR_INT("invalid line orientation", __func__, 1);
1921 
1922  pta = generatePtaHashBox(box, spacing, width, orient, outline);
1923  if (!pta)
1924  return ERROR_INT("pta not made", __func__, 1);
1925  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
1926  ptaDestroy(&pta);
1927  return 0;
1928 }
1929 
1930 
1952 l_ok
1954  PIX *pixm,
1955  l_int32 x,
1956  l_int32 y,
1957  l_int32 spacing,
1958  l_int32 width,
1959  l_int32 orient,
1960  l_int32 outline,
1961  l_int32 rval,
1962  l_int32 gval,
1963  l_int32 bval)
1964 {
1965 l_int32 w, h;
1966 BOX *box1, *box2;
1967 PIX *pix1;
1968 PTA *pta1, *pta2;
1969 
1970  if (!pix)
1971  return ERROR_INT("pix not defined", __func__, 1);
1972  if (!pixm || pixGetDepth(pixm) != 1)
1973  return ERROR_INT("pixm not defined or not 1 bpp", __func__, 1);
1974  if (spacing <= 1)
1975  return ERROR_INT("spacing not > 1", __func__, 1);
1976  if (width < 1) {
1977  L_WARNING("width < 1; setting to 1\n", __func__);
1978  width = 1;
1979  }
1980  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
1981  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
1982  return ERROR_INT("invalid line orientation", __func__, 1);
1983 
1984  /* Get the points for masked hash lines */
1985  pixGetDimensions(pixm, &w, &h, NULL);
1986  box1 = boxCreate(0, 0, w, h);
1987  pta1 = generatePtaHashBox(box1, spacing, width, orient, outline);
1988  pta2 = ptaCropToMask(pta1, pixm);
1989  boxDestroy(&box1);
1990  ptaDestroy(&pta1);
1991 
1992  /* Clip out the region and apply the hash lines */
1993  box2 = boxCreate(x, y, w, h);
1994  pix1 = pixClipRectangle(pix, box2, NULL);
1995  pixRenderPtaArb(pix1, pta2, rval, gval, bval);
1996  ptaDestroy(&pta2);
1997  boxDestroy(&box2);
1998 
1999  /* Rasterop the altered rectangle back in place */
2000  pixRasterop(pix, x, y, w, h, PIX_SRC, pix1, 0, 0);
2001  pixDestroy(&pix1);
2002  return 0;
2003 }
2004 
2005 
2020 l_ok
2022  BOXA *boxa,
2023  l_int32 spacing,
2024  l_int32 width,
2025  l_int32 orient,
2026  l_int32 outline,
2027  l_int32 op)
2028  {
2029 PTA *pta;
2030 
2031  if (!pix)
2032  return ERROR_INT("pix not defined", __func__, 1);
2033  if (!boxa)
2034  return ERROR_INT("boxa not defined", __func__, 1);
2035  if (spacing <= 1)
2036  return ERROR_INT("spacing not > 1", __func__, 1);
2037  if (width < 1) {
2038  L_WARNING("width < 1; setting to 1\n", __func__);
2039  width = 1;
2040  }
2041  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2042  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2043  return ERROR_INT("invalid line orientation", __func__, 1);
2044  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
2045  return ERROR_INT("invalid op", __func__, 1);
2046 
2047  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2048  if (!pta)
2049  return ERROR_INT("pta not made", __func__, 1);
2050  pixRenderPta(pix, pta, op);
2051  ptaDestroy(&pta);
2052  return 0;
2053 }
2054 
2055 
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 rval,
2078  l_int32 gval,
2079  l_int32 bval)
2080 {
2081 PTA *pta;
2082 
2083  if (!pix)
2084  return ERROR_INT("pix not defined", __func__, 1);
2085  if (!boxa)
2086  return ERROR_INT("boxa not defined", __func__, 1);
2087  if (spacing <= 1)
2088  return ERROR_INT("spacing not > 1", __func__, 1);
2089  if (width < 1) {
2090  L_WARNING("width < 1; setting to 1\n", __func__);
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", __func__, 1);
2096 
2097  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2098  if (!pta)
2099  return ERROR_INT("pta not made", __func__, 1);
2100  pixRenderPtaArb(pix, pta, rval, gval, bval);
2101  ptaDestroy(&pta);
2102  return 0;
2103 }
2104 
2105 
2122 l_ok
2124  BOXA *boxa,
2125  l_int32 spacing,
2126  l_int32 width,
2127  l_int32 orient,
2128  l_int32 outline,
2129  l_int32 rval,
2130  l_int32 gval,
2131  l_int32 bval,
2132  l_float32 fract)
2133 {
2134 PTA *pta;
2135 
2136  if (!pix)
2137  return ERROR_INT("pix not defined", __func__, 1);
2138  if (!boxa)
2139  return ERROR_INT("boxa not defined", __func__, 1);
2140  if (spacing <= 1)
2141  return ERROR_INT("spacing not > 1", __func__, 1);
2142  if (width < 1) {
2143  L_WARNING("width < 1; setting to 1\n", __func__);
2144  width = 1;
2145  }
2146  if (orient != L_HORIZONTAL_LINE && orient != L_POS_SLOPE_LINE &&
2147  orient != L_VERTICAL_LINE && orient != L_NEG_SLOPE_LINE)
2148  return ERROR_INT("invalid line orientation", __func__, 1);
2149 
2150  pta = generatePtaHashBoxa(boxa, spacing, width, orient, outline, 1);
2151  if (!pta)
2152  return ERROR_INT("pta not made", __func__, 1);
2153  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
2154  ptaDestroy(&pta);
2155  return 0;
2156 }
2157 
2158 
2174 l_ok
2176  PTA *ptas,
2177  l_int32 width,
2178  l_int32 op,
2179  l_int32 closeflag)
2180 {
2181 PTA *pta;
2182 
2183  if (!pix)
2184  return ERROR_INT("pix not defined", __func__, 1);
2185  if (!ptas)
2186  return ERROR_INT("ptas not defined", __func__, 1);
2187  if (width < 1) {
2188  L_WARNING("width < 1; setting to 1\n", __func__);
2189  width = 1;
2190  }
2191  if (op != L_SET_PIXELS && op != L_CLEAR_PIXELS && op != L_FLIP_PIXELS)
2192  return ERROR_INT("invalid op", __func__, 1);
2193 
2194  if ((pta = generatePtaPolyline(ptas, width, closeflag, 0)) == NULL)
2195  return ERROR_INT("pta not made", __func__, 1);
2196  pixRenderPta(pix, pta, op);
2197  ptaDestroy(&pta);
2198  return 0;
2199 }
2200 
2201 
2217 l_ok
2219  PTA *ptas,
2220  l_int32 width,
2221  l_uint8 rval,
2222  l_uint8 gval,
2223  l_uint8 bval,
2224  l_int32 closeflag)
2225 {
2226 PTA *pta;
2227 
2228  if (!pix)
2229  return ERROR_INT("pix not defined", __func__, 1);
2230  if (!ptas)
2231  return ERROR_INT("ptas not defined", __func__, 1);
2232  if (width < 1) {
2233  L_WARNING("width < 1; setting to 1\n", __func__);
2234  width = 1;
2235  }
2236 
2237  if ((pta = generatePtaPolyline(ptas, width, closeflag, 0)) == NULL)
2238  return ERROR_INT("pta not made", __func__, 1);
2239  pixRenderPtaArb(pix, pta, rval, gval, bval);
2240  ptaDestroy(&pta);
2241  return 0;
2242 }
2243 
2244 
2258 l_ok
2260  PTA *ptas,
2261  l_int32 width,
2262  l_uint8 rval,
2263  l_uint8 gval,
2264  l_uint8 bval,
2265  l_float32 fract,
2266  l_int32 closeflag,
2267  l_int32 removedups)
2268 {
2269 PTA *pta;
2270 
2271  if (!pix)
2272  return ERROR_INT("pix not defined", __func__, 1);
2273  if (!ptas)
2274  return ERROR_INT("ptas not defined", __func__, 1);
2275  if (width < 1) {
2276  L_WARNING("width < 1; setting to 1\n", __func__);
2277  width = 1;
2278  }
2279 
2280  if ((pta = generatePtaPolyline(ptas, width, closeflag, removedups)) == NULL)
2281  return ERROR_INT("pta not made", __func__, 1);
2282  pixRenderPtaBlend(pix, pta, rval, gval, bval, fract);
2283  ptaDestroy(&pta);
2284  return 0;
2285 }
2286 
2287 
2297 l_ok
2299  l_int32 nx,
2300  l_int32 ny,
2301  l_int32 width,
2302  l_uint8 rval,
2303  l_uint8 gval,
2304  l_uint8 bval)
2305 {
2306 l_int32 w, h;
2307 PTA *pta;
2308 
2309  if (!pix)
2310  return ERROR_INT("pix not defined", __func__, 1);
2311  if (nx < 1 || ny < 1)
2312  return ERROR_INT("nx, ny must be > 0", __func__, 1);
2313  if (width < 1) {
2314  L_WARNING("width < 1; setting to 1\n", __func__);
2315  width = 1;
2316  }
2317 
2318  pixGetDimensions(pix, &w, &h, NULL);
2319  if ((pta = generatePtaGrid(w, h, nx, ny, width)) == NULL)
2320  return ERROR_INT("pta not made", __func__, 1);
2321  pixRenderPtaArb(pix, pta, rval, gval, bval);
2322  ptaDestroy(&pta);
2323  return 0;
2324 }
2325 
2326 
2355 PIX *
2357  PTAA *ptaa,
2358  l_int32 polyflag,
2359  l_int32 width,
2360  l_int32 closeflag)
2361 {
2362 l_int32 i, n, index, rval, gval, bval;
2363 PIXCMAP *cmap;
2364 PTA *pta, *ptat;
2365 PIX *pixd;
2366 
2367  if (!pix)
2368  return (PIX *)ERROR_PTR("pix not defined", __func__, NULL);
2369  if (!ptaa)
2370  return (PIX *)ERROR_PTR("ptaa not defined", __func__, NULL);
2371  if (polyflag != 0 && width < 1) {
2372  L_WARNING("width < 1; setting to 1\n", __func__);
2373  width = 1;
2374  }
2375 
2376  pixd = pixConvertTo8(pix, FALSE);
2377  cmap = pixcmapCreateRandom(8, 1, 1);
2378  pixSetColormap(pixd, cmap);
2379 
2380  if ((n = ptaaGetCount(ptaa)) == 0)
2381  return pixd;
2382 
2383  for (i = 0; i < n; i++) {
2384  index = 1 + (i % 254);
2385  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
2386  pta = ptaaGetPta(ptaa, i, L_CLONE);
2387  if (polyflag)
2388  ptat = generatePtaPolyline(pta, width, closeflag, 0);
2389  else
2390  ptat = ptaClone(pta);
2391  pixRenderPtaArb(pixd, ptat, rval, gval, bval);
2392  ptaDestroy(&pta);
2393  ptaDestroy(&ptat);
2394  }
2395 
2396  return pixd;
2397 }
2398 
2399 
2400 
2401 /*------------------------------------------------------------------*
2402  * Rendering and filling of polygons *
2403  *------------------------------------------------------------------*/
2422 PIX *
2424  l_int32 width,
2425  l_int32 *pxmin,
2426  l_int32 *pymin)
2427 {
2428 l_float32 fxmin, fxmax, fymin, fymax;
2429 PIX *pixd;
2430 PTA *pta1, *pta2;
2431 
2432  if (pxmin) *pxmin = 0;
2433  if (pymin) *pymin = 0;
2434  if (!ptas)
2435  return (PIX *)ERROR_PTR("ptas not defined", __func__, NULL);
2436 
2437  /* Generate a 4-connected polygon line */
2438  if ((pta1 = generatePtaPolyline(ptas, width, 1, 0)) == NULL)
2439  return (PIX *)ERROR_PTR("pta1 not made", __func__, NULL);
2440  if (width < 2)
2441  pta2 = convertPtaLineTo4cc(pta1);
2442  else
2443  pta2 = ptaClone(pta1);
2444 
2445  /* Render onto a minimum-sized pix */
2446  ptaGetRange(pta2, &fxmin, &fxmax, &fymin, &fymax);
2447  if (pxmin) *pxmin = (l_int32)(fxmin + 0.5);
2448  if (pymin) *pymin = (l_int32)(fymin + 0.5);
2449  pixd = pixCreate((l_int32)(fxmax + 0.5) + 1, (l_int32)(fymax + 0.5) + 1, 1);
2450  pixRenderPolyline(pixd, pta2, width, L_SET_PIXELS, 1);
2451  ptaDestroy(&pta1);
2452  ptaDestroy(&pta2);
2453  return pixd;
2454 }
2455 
2456 
2475 PIX *
2477  PTA *pta,
2478  l_int32 xmin,
2479  l_int32 ymin)
2480 {
2481 l_int32 w, h, i, n, inside, found;
2482 l_int32 *xstart, *xend;
2483 PIX *pixi, *pixd;
2484 
2485  if (!pixs || (pixGetDepth(pixs) != 1))
2486  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
2487  if (!pta)
2488  return (PIX *)ERROR_PTR("pta not defined", __func__, NULL);
2489  if (ptaGetCount(pta) < 2)
2490  return (PIX *)ERROR_PTR("pta has < 2 pts", __func__, NULL);
2491 
2492  pixGetDimensions(pixs, &w, &h, NULL);
2493  xstart = (l_int32 *)LEPT_CALLOC(L_MAX(1, w / 2), sizeof(l_int32));
2494  xend = (l_int32 *)LEPT_CALLOC(L_MAX(1, w / 2), sizeof(l_int32));
2495  if (!xstart || !xend) {
2496  LEPT_FREE(xstart);
2497  LEPT_FREE(xend);
2498  return (PIX *)ERROR_PTR("xstart and xend not made", __func__, NULL);
2499  }
2500 
2501  /* Find a raster with 2 or more black runs. The first background
2502  * pixel after the end of the first run is likely to be inside
2503  * the polygon, and can be used as a seed pixel. */
2504  found = FALSE;
2505  for (i = ymin + 1; i < h; i++) {
2506  pixFindHorizontalRuns(pixs, i, xstart, xend, &n);
2507  if (n > 1) {
2508  ptaPtInsidePolygon(pta, xend[0] + 1, i, &inside);
2509  if (inside) {
2510  found = TRUE;
2511  break;
2512  }
2513  }
2514  }
2515  if (!found) {
2516  L_WARNING("nothing found to fill\n", __func__);
2517  LEPT_FREE(xstart);
2518  LEPT_FREE(xend);
2519  return 0;
2520  }
2521 
2522  /* Place the seed pixel in the output image */
2523  pixd = pixCreateTemplate(pixs);
2524  pixSetPixel(pixd, xend[0] + 1, i, 1);
2525 
2526  /* Invert pixs to make a filling mask, and fill from the seed */
2527  pixi = pixInvert(NULL, pixs);
2528  pixSeedfillBinary(pixd, pixd, pixi, 4);
2529 
2530  /* Add the pixels of the original polygon outline */
2531  pixOr(pixd, pixd, pixs);
2532 
2533  pixDestroy(&pixi);
2534  LEPT_FREE(xstart);
2535  LEPT_FREE(xend);
2536  return pixd;
2537 }
2538 
2539 
2540 /*------------------------------------------------------------------*
2541  * Contour rendering on grayscale images *
2542  *------------------------------------------------------------------*/
2559 PIX *
2561  l_int32 startval,
2562  l_int32 incr,
2563  l_int32 outdepth)
2564 {
2565 l_int32 w, h, d, maxval, wpls, wpld, i, j, val, test;
2566 l_uint32 *datas, *datad, *lines, *lined;
2567 PIX *pixd;
2568 
2569  if (!pixs)
2570  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2571  if (pixGetColormap(pixs))
2572  return (PIX *)ERROR_PTR("pixs has colormap", __func__, NULL);
2573  pixGetDimensions(pixs, &w, &h, &d);
2574  if (d != 8 && d != 16)
2575  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", __func__, NULL);
2576  if (outdepth != 1 && outdepth != d) {
2577  L_WARNING("invalid outdepth; setting to 1\n", __func__);
2578  outdepth = 1;
2579  }
2580  maxval = (1 << d) - 1;
2581  if (startval < 0 || startval > maxval)
2582  return (PIX *)ERROR_PTR("startval not in [0 ... maxval]",
2583  __func__, NULL);
2584  if (incr < 1)
2585  return (PIX *)ERROR_PTR("incr < 1", __func__, NULL);
2586 
2587  if (outdepth == d)
2588  pixd = pixCopy(NULL, pixs);
2589  else
2590  pixd = pixCreate(w, h, 1);
2591 
2592  pixCopyResolution(pixd, pixs);
2593  datad = pixGetData(pixd);
2594  wpld = pixGetWpl(pixd);
2595  datas = pixGetData(pixs);
2596  wpls = pixGetWpl(pixs);
2597 
2598  switch (d)
2599  {
2600  case 8:
2601  if (outdepth == 1) {
2602  for (i = 0; i < h; i++) {
2603  lines = datas + i * wpls;
2604  lined = datad + i * wpld;
2605  for (j = 0; j < w; j++) {
2606  val = GET_DATA_BYTE(lines, j);
2607  if (val < startval)
2608  continue;
2609  test = (val - startval) % incr;
2610  if (!test)
2611  SET_DATA_BIT(lined, j);
2612  }
2613  }
2614  } else { /* outdepth == d */
2615  for (i = 0; i < h; i++) {
2616  lines = datas + i * wpls;
2617  lined = datad + i * wpld;
2618  for (j = 0; j < w; j++) {
2619  val = GET_DATA_BYTE(lines, j);
2620  if (val < startval)
2621  continue;
2622  test = (val - startval) % incr;
2623  if (!test)
2624  SET_DATA_BYTE(lined, j, 0);
2625  }
2626  }
2627  }
2628  break;
2629 
2630  case 16:
2631  if (outdepth == 1) {
2632  for (i = 0; i < h; i++) {
2633  lines = datas + i * wpls;
2634  lined = datad + i * wpld;
2635  for (j = 0; j < w; j++) {
2636  val = GET_DATA_TWO_BYTES(lines, j);
2637  if (val < startval)
2638  continue;
2639  test = (val - startval) % incr;
2640  if (!test)
2641  SET_DATA_BIT(lined, j);
2642  }
2643  }
2644  } else { /* outdepth == d */
2645  for (i = 0; i < h; i++) {
2646  lines = datas + i * wpls;
2647  lined = datad + i * wpld;
2648  for (j = 0; j < w; j++) {
2649  val = GET_DATA_TWO_BYTES(lines, j);
2650  if (val < startval)
2651  continue;
2652  test = (val - startval) % incr;
2653  if (!test)
2654  SET_DATA_TWO_BYTES(lined, j, 0);
2655  }
2656  }
2657  }
2658  break;
2659 
2660  default:
2661  return (PIX *)ERROR_PTR("pixs not 8 or 16 bpp", __func__, NULL);
2662  }
2663 
2664  return pixd;
2665 }
2666 
2667 
2683 PIX *
2685  l_int32 ncontours)
2686 {
2687 l_float32 minval, maxval, incr;
2688 
2689  if (!fpix)
2690  return (PIX *)ERROR_PTR("fpix not defined", __func__, NULL);
2691  if (ncontours < 2 || ncontours > 500)
2692  return (PIX *)ERROR_PTR("ncontours < 2 or > 500", __func__, NULL);
2693 
2694  fpixGetMin(fpix, &minval, NULL, NULL);
2695  fpixGetMax(fpix, &maxval, NULL, NULL);
2696  if (minval == maxval)
2697  return (PIX *)ERROR_PTR("all values in fpix are equal", __func__, NULL);
2698  incr = (maxval - minval) / ((l_float32)ncontours - 1);
2699  return fpixRenderContours(fpix, incr, 0.15);
2700 }
2701 
2702 
2719 PIX *
2721  l_float32 incr,
2722  l_float32 proxim)
2723 {
2724 l_int32 i, j, w, h, wpls, wpld;
2725 l_float32 val, invincr, finter, above, below, diff;
2726 l_uint32 *datad, *lined;
2727 l_float32 *datas, *lines;
2728 PIX *pixd;
2729 PIXCMAP *cmap;
2730 
2731  if (!fpixs)
2732  return (PIX *)ERROR_PTR("fpixs not defined", __func__, NULL);
2733  if (incr <= 0.0)
2734  return (PIX *)ERROR_PTR("incr <= 0.0", __func__, NULL);
2735  if (proxim <= 0.0)
2736  proxim = 0.15; /* default */
2737 
2738  fpixGetDimensions(fpixs, &w, &h);
2739  if ((pixd = pixCreate(w, h, 8)) == NULL)
2740  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2741  cmap = pixcmapCreate(8);
2742  pixSetColormap(pixd, cmap);
2743  pixcmapAddColor(cmap, 255, 255, 255); /* white */
2744  pixcmapAddColor(cmap, 0, 0, 0); /* black */
2745  pixcmapAddColor(cmap, 255, 0, 0); /* red */
2746 
2747  datas = fpixGetData(fpixs);
2748  wpls = fpixGetWpl(fpixs);
2749  datad = pixGetData(pixd);
2750  wpld = pixGetWpl(pixd);
2751  invincr = 1.0 / incr;
2752  for (i = 0; i < h; i++) {
2753  lines = datas + i * wpls;
2754  lined = datad + i * wpld;
2755  for (j = 0; j < w; j++) {
2756  val = lines[j];
2757  finter = invincr * val;
2758  above = finter - floorf(finter);
2759  below = ceilf(finter) - finter;
2760  diff = L_MIN(above, below);
2761  if (diff <= proxim) {
2762  if (val < 0.0)
2763  SET_DATA_BYTE(lined, j, 2);
2764  else
2765  SET_DATA_BYTE(lined, j, 1);
2766  }
2767  }
2768  }
2769 
2770  return pixd;
2771 }
2772 
2773 
2774 /*------------------------------------------------------------------*
2775  * Boundary pt generation on 1 bpp images *
2776  *------------------------------------------------------------------*/
2796 PTA *
2798  l_int32 width)
2799 {
2800 PIX *pix1;
2801 PTA *pta;
2802 
2803  if (!pixs || pixGetDepth(pixs) != 1)
2804  return (PTA *)ERROR_PTR("pixs undefined or not 1 bpp", __func__, NULL);
2805  if (width < 1) {
2806  L_WARNING("width < 1; setting to 1\n", __func__);
2807  width = 1;
2808  }
2809 
2810  pix1 = pixErodeBrick(NULL, pixs, 2 * width + 1, 2 * width + 1);
2811  pixXor(pix1, pix1, pixs);
2812  pta = ptaGetPixelsFromPix(pix1, NULL);
2813  pixDestroy(&pix1);
2814  return pta;
2815 }
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
l_ok boxGetGeometry(const BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:301
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:273
l_ok boxaAddBox(BOXA *boxa, BOX *box, l_int32 copyflag)
boxaAddBox()
Definition: boxbasic.c:553
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:519
l_int32 boxaGetCount(const BOXA *boxa)
boxaGetCount()
Definition: boxbasic.c:661
BOX * boxaGetBox(BOXA *boxa, l_int32 index, l_int32 accessflag)
boxaGetBox()
Definition: boxbasic.c:702
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:171
BOXA * boxaCreate(l_int32 n)
boxaCreate()
Definition: boxbasic.c:442
l_ok boxIntersectByLine(const 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:1578
PIXCMAP * pixcmapCreateRandom(l_int32 depth, l_int32 hasblack, l_int32 haswhite)
pixcmapCreateRandom()
Definition: colormap.c:171
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
Definition: colormap.c:126
l_ok pixcmapAddNearestColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNearestColor()
Definition: colormap.c:528
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:789
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
Definition: colormap.c:403
l_ok fpixGetDimensions(FPIX *fpix, l_int32 *pw, l_int32 *ph)
fpixGetDimensions()
Definition: fpix1.c:314
l_int32 fpixGetWpl(FPIX *fpix)
fpixGetWpl()
Definition: fpix1.c:357
l_float32 * fpixGetData(FPIX *fpix)
fpixGetData()
Definition: fpix1.c:452
l_ok fpixGetMax(FPIX *fpix, l_float32 *pmaxval, l_int32 *pxmaxloc, l_int32 *pymaxloc)
fpixGetMax()
Definition: fpix2.c:732
l_ok fpixGetMin(FPIX *fpix, l_float32 *pminval, l_int32 *pxminloc, l_int32 *pyminloc)
fpixGetMin()
Definition: fpix2.c:681
l_ok pixRenderPolyline(PIX *pix, PTA *ptas, l_int32 width, l_int32 op, l_int32 closeflag)
pixRenderPolyline()
Definition: graphics.c:2175
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:2123
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:2298
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:1895
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:1797
l_ok pixRenderPtaArb(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderPtaArb()
Definition: graphics.c:1319
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:906
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:1644
l_ok pixRenderPtaBlend(PIX *pix, PTA *pta, l_uint8 rval, l_uint8 gval, l_uint8 bval, l_float32 fract)
pixRenderPtaBlend()
Definition: graphics.c:1392
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:1455
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:2021
PTA * convertPtaLineTo4cc(PTA *ptas)
convertPtaLineTo4cc()
Definition: graphics.c:770
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:2071
PTA * generatePtaBox(BOX *box, l_int32 width)
generatePtaBox()
Definition: graphics.c:272
PIX * pixRenderRandomCmapPtaa(PIX *pix, PTAA *ptaa, l_int32 polyflag, l_int32 width, l_int32 closeflag)
pixRenderRandomCmapPtaa()
Definition: graphics.c:2356
l_ok pixRenderBox(PIX *pix, BOX *box, l_int32 width, l_int32 op)
pixRenderBox()
Definition: graphics.c:1570
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:2218
PTAA * generatePtaaHashBoxa(BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline)
generatePtaaHashBoxa()
Definition: graphics.c:612
PTA * generatePtaGrid(l_int32 w, l_int32 h, l_int32 nx, l_int32 ny, l_int32 width)
generatePtaGrid()
Definition: graphics.c:714
PTA * generatePtaPolyline(PTA *ptas, l_int32 width, l_int32 closeflag, l_int32 removedups)
generatePtaPolyline()
Definition: graphics.c:658
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:2259
l_ok pixRenderPlotFromNuma(PIX **ppix, NUMA *na, l_int32 plotloc, l_int32 linewidth, l_int32 max, l_uint32 color)
pixRenderPlotFromNuma()
Definition: graphics.c:946
PTA * pixGeneratePtaBoundary(PIX *pixs, l_int32 width)
pixGeneratePtaBoundary()
Definition: graphics.c:2797
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:1058
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:1845
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:1953
PTA * makePlotPtaFromNuma(NUMA *na, l_int32 size, l_int32 plotloc, l_int32 linewidth, l_int32 max)
makePlotPtaFromNuma()
Definition: graphics.c:1003
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:1493
PTAA * generatePtaaBoxa(BOXA *boxa)
generatePtaaBoxa()
Definition: graphics.c:561
PTA * generatePtaLineFromPt(l_int32 x, l_int32 y, l_float64 length, l_float64 radang)
generatePtaLineFromPt()
Definition: graphics.c:882
PIX * pixFillPolygon(PIX *pixs, PTA *pta, l_int32 xmin, l_int32 ymin)
pixFillPolygon()
Definition: graphics.c:2476
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:1532
PTA * generatePtaLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2)
generatePtaLine()
Definition: graphics.c:141
PIX * fpixAutoRenderContours(FPIX *fpix, l_int32 ncontours)
fpixAutoRenderContours()
Definition: graphics.c:2684
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:1756
PTA * generatePtaHashBox(BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline)
generatePtaHashBox()
Definition: graphics.c:402
l_ok pixRenderBoxArb(PIX *pix, BOX *box, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxArb()
Definition: graphics.c:1606
l_ok pixRenderBoxa(PIX *pix, BOXA *boxa, l_int32 width, l_int32 op)
pixRenderBoxa()
Definition: graphics.c:1681
PIX * pixRenderPolygon(PTA *ptas, l_int32 width, l_int32 *pxmin, l_int32 *pymin)
pixRenderPolygon()
Definition: graphics.c:2423
PTA * makePlotPtaFromNumaGen(NUMA *na, l_int32 orient, l_int32 linewidth, l_int32 refpos, l_int32 max, l_int32 drawref)
makePlotPtaFromNumaGen()
Definition: graphics.c:1122
PTA * generatePtaHashBoxa(BOXA *boxa, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 removedups)
generatePtaHashBoxa()
Definition: graphics.c:503
PTA * generatePtaWideLine(l_int32 x1, l_int32 y1, l_int32 x2, l_int32 y2, l_int32 width)
generatePtaWideLine()
Definition: graphics.c:204
l_ok pixRenderBoxaArb(PIX *pix, BOXA *boxa, l_int32 width, l_uint8 rval, l_uint8 gval, l_uint8 bval)
pixRenderBoxaArb()
Definition: graphics.c:1717
PTA * generatePtaBoxa(BOXA *boxa, l_int32 width, l_int32 removedups)
generatePtaBoxa()
Definition: graphics.c:347
l_ok pixRenderPta(PIX *pix, PTA *pta, l_int32 op)
pixRenderPta()
Definition: graphics.c:1232
PIX * pixRenderContours(PIX *pixs, l_int32 startval, l_int32 incr, l_int32 outdepth)
pixRenderContours()
Definition: graphics.c:2560
PTA * generatePtaFilledCircle(l_int32 radius)
generatePtaFilledCircle()
Definition: graphics.c:811
PIX * fpixRenderContours(FPIX *fpixs, l_float32 incr, l_float32 proxim)
fpixRenderContours()
Definition: graphics.c:2720
PTA * generatePtaFilledSquare(l_int32 side)
generatePtaFilledSquare()
Definition: graphics.c:849
PIX * pixErodeBrick(PIX *pixd, PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeBrick()
Definition: morph.c:740
l_ok numaGetFValue(NUMA *na, l_int32 index, l_float32 *pval)
numaGetFValue()
Definition: numabasic.c:687
l_int32 numaGetCount(NUMA *na)
numaGetCount()
Definition: numabasic.c:630
l_ok numaGetParameters(NUMA *na, l_float32 *pstartx, l_float32 *pdelx)
numaGetParameters()
Definition: numabasic.c:882
l_ok numaGetMin(NUMA *na, l_float32 *pminval, l_int32 *piminloc)
numaGetMin()
Definition: numafunc1.c:444
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:485
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1642
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
Definition: pix1.c:1582
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:689
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:380
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:263
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:192
l_ok pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
pixClearPixel()
Definition: pix2.c:530
l_ok pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
pixFlipPixel()
Definition: pix2.c:590
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2728
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2793
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1481
PIX * pixOr(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixOr()
Definition: pix3.c:1530
PIX * pixXor(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixXor()
Definition: pix3.c:1654
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:994
@ COLOR_BLUE
Definition: pix.h:330
@ COLOR_RED
Definition: pix.h:328
@ COLOR_GREEN
Definition: pix.h:329
@ L_FLIP_PIXELS
Definition: pix.h:567
@ L_SET_PIXELS
Definition: pix.h:565
@ L_CLEAR_PIXELS
Definition: pix.h:566
@ L_POS_SLOPE_LINE
Definition: pix.h:807
@ L_HORIZONTAL_LINE
Definition: pix.h:806
@ L_NEG_SLOPE_LINE
Definition: pix.h:809
@ L_VERTICAL_LINE
Definition: pix.h:808
@ L_CLONE
Definition: pix.h:506
@ L_INSERT
Definition: pix.h:504
@ L_PLOT_AT_BOT
Definition: pix.h:1019
@ L_PLOT_AT_LEFT
Definition: pix.h:1020
@ L_PLOT_AT_MID_VERT
Definition: pix.h:1021
@ L_PLOT_AT_MID_HORIZ
Definition: pix.h:1018
@ L_PLOT_AT_TOP
Definition: pix.h:1017
@ L_PLOT_AT_RIGHT
Definition: pix.h:1022
#define PIX_SRC
Definition: pix.h:444
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3055
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3246
PTAA * ptaaCreate(l_int32 n)
ptaaCreate()
Definition: ptabasic.c:905
PTA * ptaaGetPta(PTAA *ptaa, l_int32 index, l_int32 accessflag)
ptaaGetPta()
Definition: ptabasic.c:1064
l_ok ptaGetIPt(PTA *pta, l_int32 index, l_int32 *px, l_int32 *py)
ptaGetIPt()
Definition: ptabasic.c:527
l_ok ptaaAddPta(PTAA *ptaa, PTA *pta, l_int32 copyflag)
ptaaAddPta()
Definition: ptabasic.c:963
PTA * ptaClone(PTA *pta)
ptaClone()
Definition: ptabasic.c:286
l_int32 ptaaGetCount(PTAA *ptaa)
ptaaGetCount()
Definition: ptabasic.c:1046
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:328
l_int32 ptaGetCount(PTA *pta)
ptaGetCount()
Definition: ptabasic.c:480
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
PTA * ptaGetPixelsFromPix(PIX *pixs, BOX *box)
ptaGetPixelsFromPix()
Definition: ptafunc1.c:1911
l_int32 ptaPtInsidePolygon(PTA *pta, l_float32 x, l_float32 y, l_int32 *pinside)
ptaPtInsidePolygon()
Definition: ptafunc1.c:753
l_ok ptaJoin(PTA *ptad, PTA *ptas, l_int32 istart, l_int32 iend)
ptaJoin()
Definition: ptafunc1.c:166
l_ok ptaGetRange(PTA *pta, l_float32 *pminx, l_float32 *pmaxx, l_float32 *pminy, l_float32 *pmaxy)
ptaGetRange()
Definition: ptafunc1.c:473
PTA * ptaReplicatePattern(PTA *ptas, PIX *pixp, PTA *ptap, l_int32 cx, l_int32 cy, l_int32 w, l_int32 h)
ptaReplicatePattern()
Definition: ptafunc1.c:2537
PTA * ptaCropToMask(PTA *ptas, PIX *pixm)
ptaCropToMask()
Definition: ptafunc1.c:1004
l_ok ptaRemoveDupsByAset(PTA *ptas, PTA **pptad)
ptaRemoveDupsByAset()
Definition: ptafunc2.c:473
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:204
l_ok pixFindHorizontalRuns(PIX *pix, l_int32 y, l_int32 *xstart, l_int32 *xend, l_int32 *pn)
pixFindHorizontalRuns()
Definition: runlength.c:369
PIX * pixSeedfillBinary(PIX *pixd, PIX *pixs, PIX *pixm, l_int32 connectivity)
pixSeedfillBinary()
Definition: seedfill.c:247