Leptonica  1.77.0
Image processing and image analysis suite
runlength.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 
59 #include <string.h>
60 #include <math.h>
61 #include "allheaders.h"
62 
63 static PIX *pixFindMinRunsOrthogonal(PIX *pixs, l_float32 angle, l_int32 depth);
64 
65 
66 /*-----------------------------------------------------------------------*
67  * Label pixels by membership in runs *
68  *-----------------------------------------------------------------------*/
98 PIX *
100  l_int32 color,
101  l_int32 depth,
102  l_int32 nangles)
103 {
104 l_float32 angle, pi;
105 PIX *pixh, *pixv, *pixt, *pixg1, *pixg2, *pixg3, *pixg4;
106 
107  PROCNAME("pixStrokeWidthTransform");
108 
109  if (!pixs || pixGetDepth(pixs) != 1)
110  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
111  if (depth != 8 && depth != 16)
112  return (PIX *)ERROR_PTR("depth must be 8 or 16 bpp", procName, NULL);
113  if (nangles != 2 && nangles != 4 && nangles != 6 && nangles != 8)
114  return (PIX *)ERROR_PTR("nangles not in {2,4,6,8}", procName, NULL);
115 
116  /* Use fg runs for evaluation */
117  if (color == 0)
118  pixt = pixInvert(NULL, pixs);
119  else
120  pixt = pixClone(pixs);
121 
122  /* Find min length at 0 and 90 degrees */
123  pixh = pixRunlengthTransform(pixt, 1, L_HORIZONTAL_RUNS, depth);
124  pixv = pixRunlengthTransform(pixt, 1, L_VERTICAL_RUNS, depth);
125  pixg1 = pixMinOrMax(NULL, pixh, pixv, L_CHOOSE_MIN);
126  pixDestroy(&pixh);
127  pixDestroy(&pixv);
128 
129  pixg2 = pixg3 = pixg4 = NULL;
130  pi = 3.1415926535;
131  if (nangles == 4 || nangles == 8) {
132  /* Find min length at +45 and -45 degrees */
133  angle = pi / 4.0;
134  pixg2 = pixFindMinRunsOrthogonal(pixt, angle, depth);
135  }
136 
137  if (nangles == 6) {
138  /* Find min length at +30 and -60 degrees */
139  angle = pi / 6.0;
140  pixg2 = pixFindMinRunsOrthogonal(pixt, angle, depth);
141 
142  /* Find min length at +60 and -30 degrees */
143  angle = pi / 3.0;
144  pixg3 = pixFindMinRunsOrthogonal(pixt, angle, depth);
145  }
146 
147  if (nangles == 8) {
148  /* Find min length at +22.5 and -67.5 degrees */
149  angle = pi / 8.0;
150  pixg3 = pixFindMinRunsOrthogonal(pixt, angle, depth);
151 
152  /* Find min length at +67.5 and -22.5 degrees */
153  angle = 3.0 * pi / 8.0;
154  pixg4 = pixFindMinRunsOrthogonal(pixt, angle, depth);
155  }
156  pixDestroy(&pixt);
157 
158  if (nangles > 2)
159  pixMinOrMax(pixg1, pixg1, pixg2, L_CHOOSE_MIN);
160  if (nangles > 4)
161  pixMinOrMax(pixg1, pixg1, pixg3, L_CHOOSE_MIN);
162  if (nangles > 6)
163  pixMinOrMax(pixg1, pixg1, pixg4, L_CHOOSE_MIN);
164  pixDestroy(&pixg2);
165  pixDestroy(&pixg3);
166  pixDestroy(&pixg4);
167  return pixg1;
168 }
169 
170 
195 static PIX *
197  l_float32 angle,
198  l_int32 depth)
199 {
200 l_int32 w, h, diag, xoff, yoff;
201 PIX *pixb, *pixr, *pixh, *pixv, *pixg1, *pixg2, *pixd;
202 BOX *box;
203 
204  PROCNAME("pixFindMinRunsOrthogonal");
205 
206  if (!pixs || pixGetDepth(pixs) != 1)
207  return (PIX *)ERROR_PTR("pixs undefined or not 1 bpp", procName, NULL);
208 
209  /* Rasterop into the center of a sufficiently large image
210  * so we don't lose pixels for any rotation angle. */
211  pixGetDimensions(pixs, &w, &h, NULL);
212  diag = (l_int32)(sqrt((l_float64)(w * w + h * h)) + 2.5);
213  xoff = (diag - w) / 2;
214  yoff = (diag - h) / 2;
215  pixb = pixCreate(diag, diag, 1);
216  pixRasterop(pixb, xoff, yoff, w, h, PIX_SRC, pixs, 0, 0);
217 
218  /* Rotate about the 'center', get the min of orthogonal transforms,
219  * rotate back, and crop the part corresponding to pixs. */
220  pixr = pixRotateShear(pixb, diag / 2, diag / 2, angle, L_BRING_IN_WHITE);
221  pixh = pixRunlengthTransform(pixr, 1, L_HORIZONTAL_RUNS, depth);
222  pixv = pixRunlengthTransform(pixr, 1, L_VERTICAL_RUNS, depth);
223  pixg1 = pixMinOrMax(NULL, pixh, pixv, L_CHOOSE_MIN);
224  pixg2 = pixRotateShear(pixg1, diag / 2, diag / 2, -angle, L_BRING_IN_WHITE);
225  box = boxCreate(xoff, yoff, w, h);
226  pixd = pixClipRectangle(pixg2, box, NULL);
227 
228  pixDestroy(&pixb);
229  pixDestroy(&pixr);
230  pixDestroy(&pixh);
231  pixDestroy(&pixv);
232  pixDestroy(&pixg1);
233  pixDestroy(&pixg2);
234  boxDestroy(&box);
235  return pixd;
236 }
237 
238 
261 PIX *
263  l_int32 color,
264  l_int32 direction,
265  l_int32 depth)
266 {
267 l_int32 i, j, w, h, wpld, bufsize, maxsize, n;
268 l_int32 *start, *end, *buffer;
269 l_uint32 *datad, *lined;
270 PIX *pixt, *pixd;
271 
272  PROCNAME("pixRunlengthTransform");
273 
274  if (!pixs)
275  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
276  if (pixGetDepth(pixs) != 1)
277  return (PIX *)ERROR_PTR("pixs not 1 bpp", procName, NULL);
278  if (depth != 8 && depth != 16)
279  return (PIX *)ERROR_PTR("depth must be 8 or 16 bpp", procName, NULL);
280 
281  pixGetDimensions(pixs, &w, &h, NULL);
282  if (direction == L_HORIZONTAL_RUNS)
283  maxsize = 1 + w / 2;
284  else if (direction == L_VERTICAL_RUNS)
285  maxsize = 1 + h / 2;
286  else
287  return (PIX *)ERROR_PTR("invalid direction", procName, NULL);
288  bufsize = L_MAX(w, h);
289  if (bufsize > 1000000) {
290  L_ERROR("largest image dimension = %d; too big\n", procName, bufsize);
291  return NULL;
292  }
293 
294  if ((pixd = pixCreate(w, h, depth)) == NULL)
295  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
296  datad = pixGetData(pixd);
297  wpld = pixGetWpl(pixd);
298 
299  start = (l_int32 *)LEPT_CALLOC(maxsize, sizeof(l_int32));
300  end = (l_int32 *)LEPT_CALLOC(maxsize, sizeof(l_int32));
301  buffer = (l_int32 *)LEPT_CALLOC(bufsize, sizeof(l_int32));
302 
303  /* Use fg runs for evaluation */
304  if (color == 0)
305  pixt = pixInvert(NULL, pixs);
306  else
307  pixt = pixClone(pixs);
308 
309  if (direction == L_HORIZONTAL_RUNS) {
310  for (i = 0; i < h; i++) {
311  pixFindHorizontalRuns(pixt, i, start, end, &n);
312  runlengthMembershipOnLine(buffer, w, depth, start, end, n);
313  lined = datad + i * wpld;
314  if (depth == 8) {
315  for (j = 0; j < w; j++)
316  SET_DATA_BYTE(lined, j, buffer[j]);
317  } else { /* depth == 16 */
318  for (j = 0; j < w; j++)
319  SET_DATA_TWO_BYTES(lined, j, buffer[j]);
320  }
321  }
322  } else { /* L_VERTICAL_RUNS */
323  for (j = 0; j < w; j++) {
324  pixFindVerticalRuns(pixt, j, start, end, &n);
325  runlengthMembershipOnLine(buffer, h, depth, start, end, n);
326  if (depth == 8) {
327  for (i = 0; i < h; i++) {
328  lined = datad + i * wpld;
329  SET_DATA_BYTE(lined, j, buffer[i]);
330  }
331  } else { /* depth == 16 */
332  for (i = 0; i < h; i++) {
333  lined = datad + i * wpld;
334  SET_DATA_TWO_BYTES(lined, j, buffer[i]);
335  }
336  }
337  }
338  }
339 
340  pixDestroy(&pixt);
341  LEPT_FREE(start);
342  LEPT_FREE(end);
343  LEPT_FREE(buffer);
344  return pixd;
345 }
346 
347 
348 /*-----------------------------------------------------------------------*
349  * Find runs along horizontal and vertical lines *
350  *-----------------------------------------------------------------------*/
371 l_ok
373  l_int32 y,
374  l_int32 *xstart,
375  l_int32 *xend,
376  l_int32 *pn)
377 {
378 l_int32 inrun; /* boolean */
379 l_int32 index, w, h, d, j, wpl, val;
380 l_uint32 *line;
381 
382  PROCNAME("pixFindHorizontalRuns");
383 
384  if (!pn)
385  return ERROR_INT("&n not defined", procName, 1);
386  *pn = 0;
387  if (!pix)
388  return ERROR_INT("pix not defined", procName, 1);
389  pixGetDimensions(pix, &w, &h, &d);
390  if (d != 1)
391  return ERROR_INT("pix not 1 bpp", procName, 1);
392  if (y < 0 || y >= h)
393  return ERROR_INT("y not in [0 ... h - 1]", procName, 1);
394  if (!xstart)
395  return ERROR_INT("xstart not defined", procName, 1);
396  if (!xend)
397  return ERROR_INT("xend not defined", procName, 1);
398 
399  wpl = pixGetWpl(pix);
400  line = pixGetData(pix) + y * wpl;
401 
402  inrun = FALSE;
403  index = 0;
404  for (j = 0; j < w; j++) {
405  val = GET_DATA_BIT(line, j);
406  if (!inrun) {
407  if (val) {
408  xstart[index] = j;
409  inrun = TRUE;
410  }
411  } else {
412  if (!val) {
413  xend[index++] = j - 1;
414  inrun = FALSE;
415  }
416  }
417  }
418 
419  /* Finish last run if necessary */
420  if (inrun)
421  xend[index++] = w - 1;
422 
423  *pn = index;
424  return 0;
425 }
426 
427 
448 l_ok
450  l_int32 x,
451  l_int32 *ystart,
452  l_int32 *yend,
453  l_int32 *pn)
454 {
455 l_int32 inrun; /* boolean */
456 l_int32 index, w, h, d, i, wpl, val;
457 l_uint32 *data, *line;
458 
459  PROCNAME("pixFindVerticalRuns");
460 
461  if (!pn)
462  return ERROR_INT("&n not defined", procName, 1);
463  *pn = 0;
464  if (!pix)
465  return ERROR_INT("pix not defined", procName, 1);
466  pixGetDimensions(pix, &w, &h, &d);
467  if (d != 1)
468  return ERROR_INT("pix not 1 bpp", procName, 1);
469  if (x < 0 || x >= w)
470  return ERROR_INT("x not in [0 ... w - 1]", procName, 1);
471  if (!ystart)
472  return ERROR_INT("ystart not defined", procName, 1);
473  if (!yend)
474  return ERROR_INT("yend not defined", procName, 1);
475 
476  wpl = pixGetWpl(pix);
477  data = pixGetData(pix);
478 
479  inrun = FALSE;
480  index = 0;
481  for (i = 0; i < h; i++) {
482  line = data + i * wpl;
483  val = GET_DATA_BIT(line, x);
484  if (!inrun) {
485  if (val) {
486  ystart[index] = i;
487  inrun = TRUE;
488  }
489  } else {
490  if (!val) {
491  yend[index++] = i - 1;
492  inrun = FALSE;
493  }
494  }
495  }
496 
497  /* Finish last run if necessary */
498  if (inrun)
499  yend[index++] = h - 1;
500 
501  *pn = index;
502  return 0;
503 }
504 
505 
506 /*-----------------------------------------------------------------------*
507  * Find max runs along horizontal and vertical lines *
508  *-----------------------------------------------------------------------*/
524 NUMA *
526  l_int32 direction,
527  NUMA **pnastart)
528 {
529 l_int32 w, h, i, start, size;
530 NUMA *nasize;
531 
532  PROCNAME("pixFindMaxRuns");
533 
534  if (pnastart) *pnastart = NULL;
535  if (direction != L_HORIZONTAL_RUNS && direction != L_VERTICAL_RUNS)
536  return (NUMA *)ERROR_PTR("direction invalid", procName, NULL);
537  if (!pix || pixGetDepth(pix) != 1)
538  return (NUMA *)ERROR_PTR("pix undefined or not 1 bpp", procName, NULL);
539 
540  pixGetDimensions(pix, &w, &h, NULL);
541  nasize = numaCreate(w);
542  if (pnastart) *pnastart = numaCreate(w);
543  if (direction == L_HORIZONTAL_RUNS) {
544  for (i = 0; i < h; i++) {
545  pixFindMaxHorizontalRunOnLine(pix, i, &start, &size);
546  numaAddNumber(nasize, size);
547  if (pnastart) numaAddNumber(*pnastart, start);
548  }
549  } else { /* vertical scans */
550  for (i = 0; i < w; i++) {
551  pixFindMaxVerticalRunOnLine(pix, i, &start, &size);
552  numaAddNumber(nasize, size);
553  if (pnastart) numaAddNumber(*pnastart, start);
554  }
555  }
556 
557  return nasize;
558 }
559 
560 
577 l_ok
579  l_int32 y,
580  l_int32 *pxstart,
581  l_int32 *psize)
582 {
583 l_int32 inrun; /* boolean */
584 l_int32 w, h, j, wpl, val, maxstart, maxsize, length, start;
585 l_uint32 *line;
586 
587  PROCNAME("pixFindMaxHorizontalRunOnLine");
588 
589  if (pxstart) *pxstart = 0;
590  if (!psize)
591  return ERROR_INT("&size not defined", procName, 1);
592  *psize = 0;
593  if (!pix || pixGetDepth(pix) != 1)
594  return ERROR_INT("pix not defined or not 1 bpp", procName, 1);
595  pixGetDimensions(pix, &w, &h, NULL);
596  if (y < 0 || y >= h)
597  return ERROR_INT("y not in [0 ... h - 1]", procName, 1);
598 
599  wpl = pixGetWpl(pix);
600  line = pixGetData(pix) + y * wpl;
601  inrun = FALSE;
602  start = 0;
603  maxstart = 0;
604  maxsize = 0;
605  for (j = 0; j < w; j++) {
606  val = GET_DATA_BIT(line, j);
607  if (!inrun) {
608  if (val) {
609  start = j;
610  inrun = TRUE;
611  }
612  } else if (!val) { /* run just ended */
613  length = j - start;
614  if (length > maxsize) {
615  maxsize = length;
616  maxstart = start;
617  }
618  inrun = FALSE;
619  }
620  }
621 
622  if (inrun) { /* a run has continued to the end of the row */
623  length = j - start;
624  if (length > maxsize) {
625  maxsize = length;
626  maxstart = start;
627  }
628  }
629  if (pxstart) *pxstart = maxstart;
630  *psize = maxsize;
631  return 0;
632 }
633 
634 
651 l_ok
653  l_int32 x,
654  l_int32 *pystart,
655  l_int32 *psize)
656 {
657 l_int32 inrun; /* boolean */
658 l_int32 w, h, i, wpl, val, maxstart, maxsize, length, start;
659 l_uint32 *data, *line;
660 
661  PROCNAME("pixFindMaxVerticalRunOnLine");
662 
663  if (pystart) *pystart = 0;
664  if (!psize)
665  return ERROR_INT("&size not defined", procName, 1);
666  *psize = 0;
667  if (!pix || pixGetDepth(pix) != 1)
668  return ERROR_INT("pix not defined or not 1 bpp", procName, 1);
669  pixGetDimensions(pix, &w, &h, NULL);
670  if (x < 0 || x >= w)
671  return ERROR_INT("x not in [0 ... w - 1]", procName, 1);
672 
673  wpl = pixGetWpl(pix);
674  data = pixGetData(pix);
675  inrun = FALSE;
676  start = 0;
677  maxstart = 0;
678  maxsize = 0;
679  for (i = 0; i < h; i++) {
680  line = data + i * wpl;
681  val = GET_DATA_BIT(line, x);
682  if (!inrun) {
683  if (val) {
684  start = i;
685  inrun = TRUE;
686  }
687  } else if (!val) { /* run just ended */
688  length = i - start;
689  if (length > maxsize) {
690  maxsize = length;
691  maxstart = start;
692  }
693  inrun = FALSE;
694  }
695  }
696 
697  if (inrun) { /* a run has continued to the end of the column */
698  length = i - start;
699  if (length > maxsize) {
700  maxsize = length;
701  maxstart = start;
702  }
703  }
704  if (pystart) *pystart = maxstart;
705  *psize = maxsize;
706  return 0;
707 }
708 
709 
710 /*-----------------------------------------------------------------------*
711  * Compute runlength-to-membership transform on a line *
712  *-----------------------------------------------------------------------*/
732 l_ok
734  l_int32 size,
735  l_int32 depth,
736  l_int32 *start,
737  l_int32 *end,
738  l_int32 n)
739 {
740 l_int32 i, j, first, last, diff, max;
741 
742  PROCNAME("runlengthMembershipOnLine");
743 
744  if (!buffer)
745  return ERROR_INT("buffer not defined", procName, 1);
746  if (!start)
747  return ERROR_INT("start not defined", procName, 1);
748  if (!end)
749  return ERROR_INT("end not defined", procName, 1);
750 
751  if (depth == 8)
752  max = 0xff;
753  else /* depth == 16 */
754  max = 0xffff;
755 
756  memset(buffer, 0, 4 * size);
757  for (i = 0; i < n; i++) {
758  first = start[i];
759  last = end[i];
760  diff = last - first + 1;
761  diff = L_MIN(diff, max);
762  for (j = first; j <= last; j++)
763  buffer[j] = diff;
764  }
765 
766  return 0;
767 }
768 
769 
770 
771 /*-----------------------------------------------------------------------*
772  * Make byte position LUT *
773  *-----------------------------------------------------------------------*/
790 l_int32 *
791 makeMSBitLocTab(l_int32 bitval)
792 {
793 l_int32 i, j;
794 l_int32 *tab;
795 l_uint8 byte, mask;
796 
797  PROCNAME("makeMSBitLocTab");
798 
799  if ((tab = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32))) == NULL)
800  return (l_int32 *)ERROR_PTR("tab not made", procName, NULL);
801 
802  for (i = 0; i < 256; i++) {
803  byte = (l_uint8)i;
804  if (bitval == 0)
805  byte = ~byte;
806  tab[i] = 8;
807  mask = 0x80;
808  for (j = 0; j < 8; j++) {
809  if (byte & mask) {
810  tab[i] = j;
811  break;
812  }
813  mask >>= 1;
814  }
815  }
816 
817  return tab;
818 }
PIX * pixRotateShear(PIX *pixs, l_int32 xcen, l_int32 ycen, l_float32 angle, l_int32 incolor)
pixRotateShear()
Definition: rotateshear.c:196
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.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:193
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1395
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:187
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
l_ok pixFindMaxVerticalRunOnLine(PIX *pix, l_int32 x, l_int32 *pystart, l_int32 *psize)
pixFindMaxVerticalRunOnLine()
Definition: runlength.c:652
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1020
l_ok pixFindHorizontalRuns(PIX *pix, l_int32 y, l_int32 *xstart, l_int32 *xend, l_int32 *pn)
pixFindHorizontalRuns()
Definition: runlength.c:372
Definition: array.h:59
l_int32 * makeMSBitLocTab(l_int32 bitval)
makeMSBitLocTab()
Definition: runlength.c:791
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
static PIX * pixFindMinRunsOrthogonal(PIX *pixs, l_float32 angle, l_int32 depth)
pixFindMinRunsOrthogonal()
Definition: runlength.c:196
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
l_ok pixFindVerticalRuns(PIX *pix, l_int32 x, l_int32 *ystart, l_int32 *yend, l_int32 *pn)
pixFindVerticalRuns()
Definition: runlength.c:449
PIX * pixRunlengthTransform(PIX *pixs, l_int32 color, l_int32 direction, l_int32 depth)
pixRunlengthTransform()
Definition: runlength.c:262
l_ok runlengthMembershipOnLine(l_int32 *buffer, l_int32 size, l_int32 depth, l_int32 *start, l_int32 *end, l_int32 n)
runlengthMembershipOnLine()
Definition: runlength.c:733
Definition: pix.h:134
#define PIX_SRC
Definition: pix.h:327
l_ok pixFindMaxHorizontalRunOnLine(PIX *pix, l_int32 y, l_int32 *pxstart, l_int32 *psize)
pixFindMaxHorizontalRunOnLine()
Definition: runlength.c:578
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:278
PIX * pixMinOrMax(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 type)
pixMinOrMax()
Definition: pixarith.c:1054
PIX * pixStrokeWidthTransform(PIX *pixs, l_int32 color, l_int32 depth, l_int32 nangles)
pixStrokeWidthTransform()
Definition: runlength.c:99
NUMA * pixFindMaxRuns(PIX *pix, l_int32 direction, NUMA **pnastart)
pixFindMaxRuns()
Definition: runlength.c:525
Definition: pix.h:480
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:165
l_int32 index
Definition: regutils.h:123