Leptonica  1.83.1
Image processing and image analysis suite
pix4.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 
85 #ifdef HAVE_CONFIG_H
86 #include <config_auto.h>
87 #endif /* HAVE_CONFIG_H */
88 
89 #include <string.h>
90 #include <math.h>
91 #include "allheaders.h"
92 
93 
94 /*------------------------------------------------------------------*
95  * Pixel histogram and averaging *
96  *------------------------------------------------------------------*/
114 NUMA *
116  l_int32 factor)
117 {
118 l_int32 i, j, w, h, d, wpl, val, size, count;
119 l_uint32 *data, *line;
120 l_float32 *array;
121 NUMA *na;
122 PIX *pixg;
123 
124  if (!pixs)
125  return (NUMA *)ERROR_PTR("pixs not defined", __func__, NULL);
126  d = pixGetDepth(pixs);
127  if (d > 16)
128  return (NUMA *)ERROR_PTR("depth not in {1,2,4,8,16}", __func__, NULL);
129  if (factor < 1)
130  return (NUMA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
131 
132  if (pixGetColormap(pixs))
134  else
135  pixg = pixClone(pixs);
136 
137  pixGetDimensions(pixg, &w, &h, &d);
138  size = 1 << d;
139  if ((na = numaCreate(size)) == NULL) {
140  pixDestroy(&pixg);
141  return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
142  }
143  numaSetCount(na, size); /* all initialized to 0.0 */
144  array = numaGetFArray(na, L_NOCOPY);
145 
146  if (d == 1) { /* special case */
147  pixCountPixels(pixg, &count, NULL);
148  array[0] = w * h - count;
149  array[1] = count;
150  pixDestroy(&pixg);
151  return na;
152  }
153 
154  wpl = pixGetWpl(pixg);
155  data = pixGetData(pixg);
156  for (i = 0; i < h; i += factor) {
157  line = data + i * wpl;
158  if (d == 2) {
159  for (j = 0; j < w; j += factor) {
160  val = GET_DATA_DIBIT(line, j);
161  array[val] += 1.0;
162  }
163  } else if (d == 4) {
164  for (j = 0; j < w; j += factor) {
165  val = GET_DATA_QBIT(line, j);
166  array[val] += 1.0;
167  }
168  } else if (d == 8) {
169  for (j = 0; j < w; j += factor) {
170  val = GET_DATA_BYTE(line, j);
171  array[val] += 1.0;
172  }
173  } else { /* d == 16 */
174  for (j = 0; j < w; j += factor) {
175  val = GET_DATA_TWO_BYTES(line, j);
176  array[val] += 1.0;
177  }
178  }
179  }
180 
181  pixDestroy(&pixg);
182  return na;
183 }
184 
185 
208 NUMA *
210  PIX *pixm,
211  l_int32 x,
212  l_int32 y,
213  l_int32 factor)
214 {
215 l_int32 i, j, w, h, wm, hm, dm, wplg, wplm, val;
216 l_uint32 *datag, *datam, *lineg, *linem;
217 l_float32 *array;
218 NUMA *na;
219 PIX *pixg;
220 
221  if (!pixm)
222  return pixGetGrayHistogram(pixs, factor);
223  if (!pixs)
224  return (NUMA *)ERROR_PTR("pixs not defined", __func__, NULL);
225  if (pixGetDepth(pixs) != 8 && !pixGetColormap(pixs))
226  return (NUMA *)ERROR_PTR("pixs neither 8 bpp nor colormapped",
227  __func__, NULL);
228  pixGetDimensions(pixm, &wm, &hm, &dm);
229  if (dm != 1)
230  return (NUMA *)ERROR_PTR("pixm not 1 bpp", __func__, NULL);
231  if (factor < 1)
232  return (NUMA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
233 
234  if ((na = numaCreate(256)) == NULL)
235  return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
236  numaSetCount(na, 256); /* all initialized to 0.0 */
237  array = numaGetFArray(na, L_NOCOPY);
238 
239  if (pixGetColormap(pixs))
241  else
242  pixg = pixClone(pixs);
243  pixGetDimensions(pixg, &w, &h, NULL);
244  datag = pixGetData(pixg);
245  wplg = pixGetWpl(pixg);
246  datam = pixGetData(pixm);
247  wplm = pixGetWpl(pixm);
248 
249  /* Generate the histogram */
250  for (i = 0; i < hm; i += factor) {
251  if (y + i < 0 || y + i >= h) continue;
252  lineg = datag + (y + i) * wplg;
253  linem = datam + i * wplm;
254  for (j = 0; j < wm; j += factor) {
255  if (x + j < 0 || x + j >= w) continue;
256  if (GET_DATA_BIT(linem, j)) {
257  val = GET_DATA_BYTE(lineg, x + j);
258  array[val] += 1.0;
259  }
260  }
261  }
262 
263  pixDestroy(&pixg);
264  return na;
265 }
266 
267 
286 NUMA *
288  BOX *box,
289  l_int32 factor)
290 {
291 l_int32 i, j, bx, by, bw, bh, w, h, wplg, val;
292 l_uint32 *datag, *lineg;
293 l_float32 *array;
294 NUMA *na;
295 PIX *pixg;
296 
297  if (!box)
298  return pixGetGrayHistogram(pixs, factor);
299  if (!pixs)
300  return (NUMA *)ERROR_PTR("pixs not defined", __func__, NULL);
301  if (pixGetDepth(pixs) != 8 && !pixGetColormap(pixs))
302  return (NUMA *)ERROR_PTR("pixs neither 8 bpp nor colormapped",
303  __func__, NULL);
304  if (factor < 1)
305  return (NUMA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
306 
307  if ((na = numaCreate(256)) == NULL)
308  return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
309  numaSetCount(na, 256); /* all initialized to 0.0 */
310  array = numaGetFArray(na, L_NOCOPY);
311 
312  if (pixGetColormap(pixs))
314  else
315  pixg = pixClone(pixs);
316  pixGetDimensions(pixg, &w, &h, NULL);
317  datag = pixGetData(pixg);
318  wplg = pixGetWpl(pixg);
319  boxGetGeometry(box, &bx, &by, &bw, &bh);
320 
321  /* Generate the histogram */
322  for (i = 0; i < bh; i += factor) {
323  if (by + i < 0 || by + i >= h) continue;
324  lineg = datag + (by + i) * wplg;
325  for (j = 0; j < bw; j += factor) {
326  if (bx + j < 0 || bx + j >= w) continue;
327  val = GET_DATA_BYTE(lineg, bx + j);
328  array[val] += 1.0;
329  }
330  }
331 
332  pixDestroy(&pixg);
333  return na;
334 }
335 
336 
352 NUMAA *
354  l_int32 factor,
355  l_int32 nx,
356  l_int32 ny)
357 {
358 l_int32 i, n;
359 NUMA *na;
360 NUMAA *naa;
361 PIX *pix1, *pix2;
362 PIXA *pixa;
363 
364  if (!pixs)
365  return (NUMAA *)ERROR_PTR("pixs not defined", __func__, NULL);
366  if (factor < 1)
367  return (NUMAA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
368  if (nx < 1 || ny < 1)
369  return (NUMAA *)ERROR_PTR("nx and ny must both be > 0", __func__, NULL);
370 
371  n = nx * ny;
372  if ((naa = numaaCreate(n)) == NULL)
373  return (NUMAA *)ERROR_PTR("naa not made", __func__, NULL);
374 
375  pix1 = pixConvertTo8(pixs, FALSE);
376  pixa = pixaSplitPix(pix1, nx, ny, 0, 0);
377  for (i = 0; i < n; i++) {
378  pix2 = pixaGetPix(pixa, i, L_CLONE);
379  na = pixGetGrayHistogram(pix2, factor);
380  numaaAddNuma(naa, na, L_INSERT);
381  pixDestroy(&pix2);
382  }
383 
384  pixDestroy(&pix1);
385  pixaDestroy(&pixa);
386  return naa;
387 }
388 
389 
407 l_ok
409  l_int32 factor,
410  NUMA **pnar,
411  NUMA **pnag,
412  NUMA **pnab)
413 {
414 l_int32 i, j, w, h, d, wpl, index, rval, gval, bval;
415 l_uint32 *data, *line;
416 l_float32 *rarray, *garray, *barray;
417 NUMA *nar, *nag, *nab;
418 PIXCMAP *cmap;
419 
420  if (pnar) *pnar = NULL;
421  if (pnag) *pnag = NULL;
422  if (pnab) *pnab = NULL;
423  if (!pnar || !pnag || !pnab)
424  return ERROR_INT("&nar, &nag, &nab not all defined", __func__, 1);
425  if (!pixs)
426  return ERROR_INT("pixs not defined", __func__, 1);
427  pixGetDimensions(pixs, &w, &h, &d);
428  cmap = pixGetColormap(pixs);
429  if (cmap && (d != 2 && d != 4 && d != 8))
430  return ERROR_INT("colormap and not 2, 4, or 8 bpp", __func__, 1);
431  if (!cmap && d != 32)
432  return ERROR_INT("no colormap and not rgb", __func__, 1);
433  if (factor < 1)
434  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
435 
436  /* Set up the histogram arrays */
437  nar = numaCreate(256);
438  nag = numaCreate(256);
439  nab = numaCreate(256);
440  numaSetCount(nar, 256);
441  numaSetCount(nag, 256);
442  numaSetCount(nab, 256);
443  rarray = numaGetFArray(nar, L_NOCOPY);
444  garray = numaGetFArray(nag, L_NOCOPY);
445  barray = numaGetFArray(nab, L_NOCOPY);
446  *pnar = nar;
447  *pnag = nag;
448  *pnab = nab;
449 
450  /* Generate the color histograms */
451  data = pixGetData(pixs);
452  wpl = pixGetWpl(pixs);
453  if (cmap) {
454  for (i = 0; i < h; i += factor) {
455  line = data + i * wpl;
456  for (j = 0; j < w; j += factor) {
457  if (d == 8)
458  index = GET_DATA_BYTE(line, j);
459  else if (d == 4)
460  index = GET_DATA_QBIT(line, j);
461  else /* 2 bpp */
462  index = GET_DATA_DIBIT(line, j);
463  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
464  rarray[rval] += 1.0;
465  garray[gval] += 1.0;
466  barray[bval] += 1.0;
467  }
468  }
469  } else { /* 32 bpp rgb */
470  for (i = 0; i < h; i += factor) {
471  line = data + i * wpl;
472  for (j = 0; j < w; j += factor) {
473  extractRGBValues(line[j], &rval, &gval, &bval);
474  rarray[rval] += 1.0;
475  garray[gval] += 1.0;
476  barray[bval] += 1.0;
477  }
478  }
479  }
480 
481  return 0;
482 }
483 
484 
507 l_ok
509  PIX *pixm,
510  l_int32 x,
511  l_int32 y,
512  l_int32 factor,
513  NUMA **pnar,
514  NUMA **pnag,
515  NUMA **pnab)
516 {
517 l_int32 i, j, w, h, d, wm, hm, dm, wpls, wplm, index, rval, gval, bval;
518 l_uint32 *datas, *datam, *lines, *linem;
519 l_float32 *rarray, *garray, *barray;
520 NUMA *nar, *nag, *nab;
521 PIXCMAP *cmap;
522 
523  if (!pixm)
524  return pixGetColorHistogram(pixs, factor, pnar, pnag, pnab);
525 
526  if (pnar) *pnar = NULL;
527  if (pnag) *pnag = NULL;
528  if (pnab) *pnab = NULL;
529  if (!pnar || !pnag || !pnab)
530  return ERROR_INT("&nar, &nag, &nab not all defined", __func__, 1);
531  if (!pixs)
532  return ERROR_INT("pixs not defined", __func__, 1);
533  pixGetDimensions(pixs, &w, &h, &d);
534  cmap = pixGetColormap(pixs);
535  if (cmap && (d != 2 && d != 4 && d != 8))
536  return ERROR_INT("colormap and not 2, 4, or 8 bpp", __func__, 1);
537  if (!cmap && d != 32)
538  return ERROR_INT("no colormap and not rgb", __func__, 1);
539  pixGetDimensions(pixm, &wm, &hm, &dm);
540  if (dm != 1)
541  return ERROR_INT("pixm not 1 bpp", __func__, 1);
542  if (factor < 1)
543  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
544 
545  /* Set up the histogram arrays */
546  nar = numaCreate(256);
547  nag = numaCreate(256);
548  nab = numaCreate(256);
549  numaSetCount(nar, 256);
550  numaSetCount(nag, 256);
551  numaSetCount(nab, 256);
552  rarray = numaGetFArray(nar, L_NOCOPY);
553  garray = numaGetFArray(nag, L_NOCOPY);
554  barray = numaGetFArray(nab, L_NOCOPY);
555  *pnar = nar;
556  *pnag = nag;
557  *pnab = nab;
558 
559  /* Generate the color histograms */
560  datas = pixGetData(pixs);
561  wpls = pixGetWpl(pixs);
562  datam = pixGetData(pixm);
563  wplm = pixGetWpl(pixm);
564  if (cmap) {
565  for (i = 0; i < hm; i += factor) {
566  if (y + i < 0 || y + i >= h) continue;
567  lines = datas + (y + i) * wpls;
568  linem = datam + i * wplm;
569  for (j = 0; j < wm; j += factor) {
570  if (x + j < 0 || x + j >= w) continue;
571  if (GET_DATA_BIT(linem, j)) {
572  if (d == 8)
573  index = GET_DATA_BYTE(lines, x + j);
574  else if (d == 4)
575  index = GET_DATA_QBIT(lines, x + j);
576  else /* 2 bpp */
577  index = GET_DATA_DIBIT(lines, x + j);
578  pixcmapGetColor(cmap, index, &rval, &gval, &bval);
579  rarray[rval] += 1.0;
580  garray[gval] += 1.0;
581  barray[bval] += 1.0;
582  }
583  }
584  }
585  } else { /* 32 bpp rgb */
586  for (i = 0; i < hm; i += factor) {
587  if (y + i < 0 || y + i >= h) continue;
588  lines = datas + (y + i) * wpls;
589  linem = datam + i * wplm;
590  for (j = 0; j < wm; j += factor) {
591  if (x + j < 0 || x + j >= w) continue;
592  if (GET_DATA_BIT(linem, j)) {
593  extractRGBValues(lines[x + j], &rval, &gval, &bval);
594  rarray[rval] += 1.0;
595  garray[gval] += 1.0;
596  barray[bval] += 1.0;
597  }
598  }
599  }
600  }
601 
602  return 0;
603 }
604 
605 
620 NUMA *
622  l_int32 factor)
623 {
624 l_int32 i, j, w, h, d, wpl, val, size;
625 l_uint32 *data, *line;
626 l_float32 *array;
627 NUMA *na;
628 
629  if (!pixs)
630  return (NUMA *)ERROR_PTR("pixs not defined", __func__, NULL);
631  if (pixGetColormap(pixs) == NULL)
632  return (NUMA *)ERROR_PTR("pixs not cmapped", __func__, NULL);
633  if (factor < 1)
634  return (NUMA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
635  pixGetDimensions(pixs, &w, &h, &d);
636  if (d != 2 && d != 4 && d != 8)
637  return (NUMA *)ERROR_PTR("d not 2, 4 or 8", __func__, NULL);
638 
639  size = 1 << d;
640  if ((na = numaCreate(size)) == NULL)
641  return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
642  numaSetCount(na, size); /* all initialized to 0.0 */
643  array = numaGetFArray(na, L_NOCOPY);
644 
645  wpl = pixGetWpl(pixs);
646  data = pixGetData(pixs);
647  for (i = 0; i < h; i += factor) {
648  line = data + i * wpl;
649  for (j = 0; j < w; j += factor) {
650  if (d == 8)
651  val = GET_DATA_BYTE(line, j);
652  else if (d == 4)
653  val = GET_DATA_QBIT(line, j);
654  else /* d == 2 */
655  val = GET_DATA_DIBIT(line, j);
656  array[val] += 1.0;
657  }
658  }
659 
660  return na;
661 }
662 
663 
683 NUMA *
685  PIX *pixm,
686  l_int32 x,
687  l_int32 y,
688  l_int32 factor)
689 {
690 l_int32 i, j, w, h, d, wm, hm, dm, wpls, wplm, val, size;
691 l_uint32 *datas, *datam, *lines, *linem;
692 l_float32 *array;
693 NUMA *na;
694 
695  if (!pixm)
696  return pixGetCmapHistogram(pixs, factor);
697 
698  if (!pixs)
699  return (NUMA *)ERROR_PTR("pixs not defined", __func__, NULL);
700  if (pixGetColormap(pixs) == NULL)
701  return (NUMA *)ERROR_PTR("pixs not cmapped", __func__, NULL);
702  pixGetDimensions(pixm, &wm, &hm, &dm);
703  if (dm != 1)
704  return (NUMA *)ERROR_PTR("pixm not 1 bpp", __func__, NULL);
705  if (factor < 1)
706  return (NUMA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
707  pixGetDimensions(pixs, &w, &h, &d);
708  if (d != 2 && d != 4 && d != 8)
709  return (NUMA *)ERROR_PTR("d not 2, 4 or 8", __func__, NULL);
710 
711  size = 1 << d;
712  if ((na = numaCreate(size)) == NULL)
713  return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
714  numaSetCount(na, size); /* all initialized to 0.0 */
715  array = numaGetFArray(na, L_NOCOPY);
716 
717  datas = pixGetData(pixs);
718  wpls = pixGetWpl(pixs);
719  datam = pixGetData(pixm);
720  wplm = pixGetWpl(pixm);
721 
722  for (i = 0; i < hm; i += factor) {
723  if (y + i < 0 || y + i >= h) continue;
724  lines = datas + (y + i) * wpls;
725  linem = datam + i * wplm;
726  for (j = 0; j < wm; j += factor) {
727  if (x + j < 0 || x + j >= w) continue;
728  if (GET_DATA_BIT(linem, j)) {
729  if (d == 8)
730  val = GET_DATA_BYTE(lines, x + j);
731  else if (d == 4)
732  val = GET_DATA_QBIT(lines, x + j);
733  else /* d == 2 */
734  val = GET_DATA_DIBIT(lines, x + j);
735  array[val] += 1.0;
736  }
737  }
738  }
739 
740  return na;
741 }
742 
743 
761 NUMA *
763  BOX *box,
764  l_int32 factor)
765 {
766 l_int32 i, j, bx, by, bw, bh, w, h, d, wpls, val, size;
767 l_uint32 *datas, *lines;
768 l_float32 *array;
769 NUMA *na;
770 
771  if (!box)
772  return pixGetCmapHistogram(pixs, factor);
773  if (!pixs)
774  return (NUMA *)ERROR_PTR("pixs not defined", __func__, NULL);
775  if (pixGetColormap(pixs) == NULL)
776  return (NUMA *)ERROR_PTR("pixs not cmapped", __func__, NULL);
777  if (factor < 1)
778  return (NUMA *)ERROR_PTR("sampling must be >= 1", __func__, NULL);
779  pixGetDimensions(pixs, &w, &h, &d);
780  if (d != 2 && d != 4 && d != 8)
781  return (NUMA *)ERROR_PTR("d not 2, 4 or 8", __func__, NULL);
782 
783  size = 1 << d;
784  if ((na = numaCreate(size)) == NULL)
785  return (NUMA *)ERROR_PTR("na not made", __func__, NULL);
786  numaSetCount(na, size); /* all initialized to 0.0 */
787  array = numaGetFArray(na, L_NOCOPY);
788 
789  datas = pixGetData(pixs);
790  wpls = pixGetWpl(pixs);
791  boxGetGeometry(box, &bx, &by, &bw, &bh);
792 
793  for (i = 0; i < bh; i += factor) {
794  if (by + i < 0 || by + i >= h) continue;
795  lines = datas + (by + i) * wpls;
796  for (j = 0; j < bw; j += factor) {
797  if (bx + j < 0 || bx + j >= w) continue;
798  if (d == 8)
799  val = GET_DATA_BYTE(lines, bx + j);
800  else if (d == 4)
801  val = GET_DATA_QBIT(lines, bx + j);
802  else /* d == 2 */
803  val = GET_DATA_DIBIT(lines, bx + j);
804  array[val] += 1.0;
805  }
806  }
807 
808  return na;
809 }
810 
811 
825 l_ok
827  l_int32 *pncolors)
828 {
829 L_DNA *da1, *da2;
830 
831  if (!pncolors)
832  return ERROR_INT("&ncolors not defined", __func__, 1);
833  *pncolors = 0;
834  if (!pixs || pixGetDepth(pixs) != 32)
835  return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
836  da1 = pixConvertDataToDna(pixs);
837  l_dnaRemoveDupsByHmap(da1, &da2, NULL);
838  *pncolors = l_dnaGetCount(da2);
839  l_dnaDestroy(&da1);
840  l_dnaDestroy(&da2);
841  return 0;
842 }
843 
844 
859 l_ok
861  l_int32 factor,
862  l_int32 *pncolors)
863 {
864 L_AMAP *amap;
865 
866  if (!pncolors)
867  return ERROR_INT("&ncolors not defined", __func__, 1);
868  *pncolors = 0;
869  if (!pixs || pixGetDepth(pixs) != 32)
870  return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
871  if (factor <= 0)
872  return ERROR_INT("factor must be > 0", __func__, 1);
873  amap = pixGetColorAmapHistogram(pixs, factor);
874  *pncolors = l_amapSize(amap);
875  l_amapDestroy(&amap);
876  return 0;
877 }
878 
879 
893 L_AMAP *
895  l_int32 factor)
896 {
897 l_int32 i, j, w, h, wpl;
898 l_uint32 *data, *line;
899 L_AMAP *amap;
900 RB_TYPE key, value;
901 RB_TYPE *pval;
902 
903  if (!pixs)
904  return (L_AMAP *)ERROR_PTR("pixs not defined", __func__, NULL);
905  if (pixGetDepth(pixs) != 32)
906  return (L_AMAP *)ERROR_PTR("pixs not 32 bpp", __func__, NULL);
907  if (factor <= 0)
908  return (L_AMAP *)ERROR_PTR("factor must be > 0", __func__, NULL);
909  pixGetDimensions(pixs, &w, &h, NULL);
910  data = pixGetData(pixs);
911  wpl = pixGetWpl(pixs);
912  amap = l_amapCreate(L_UINT_TYPE);
913  for (i = 0; i < h; i += factor) {
914  line = data + i * wpl;
915  for (j = 0; j < w; j += factor) {
916  key.utype = line[j];
917  pval = l_amapFind(amap, key);
918  if (!pval)
919  value.itype = 1;
920  else
921  value.itype = 1 + pval->itype;
922  l_amapInsert(amap, key, value);
923  }
924  }
925 
926  return amap;
927 }
928 
929 
942 l_int32
944  l_uint32 val)
945 {
946 RB_TYPE key;
947 RB_TYPE *pval;
948 
949  if (!amap)
950  return ERROR_INT("amap not defined", __func__, -1);
951 
952  key.utype = val;
953  pval = l_amapFind(amap, key);
954  return (pval) ? pval->itype : 0;
955 }
956 
957 
979 l_ok
981  l_int32 factor,
982  l_float32 rank,
983  l_uint32 *pvalue)
984 {
985 l_int32 d;
986 l_float32 val, rval, gval, bval;
987 PIX *pixt;
988 PIXCMAP *cmap;
989 
990  if (!pvalue)
991  return ERROR_INT("&value not defined", __func__, 1);
992  *pvalue = 0;
993  if (!pixs)
994  return ERROR_INT("pixs not defined", __func__, 1);
995  d = pixGetDepth(pixs);
996  cmap = pixGetColormap(pixs);
997  if (d != 8 && d != 32 && !cmap)
998  return ERROR_INT("pixs not 8 or 32 bpp, or cmapped", __func__, 1);
999  if (cmap)
1001  else
1002  pixt = pixClone(pixs);
1003  d = pixGetDepth(pixt);
1004 
1005  if (d == 8) {
1006  pixGetRankValueMasked(pixt, NULL, 0, 0, factor, rank, &val, NULL);
1007  *pvalue = lept_roundftoi(val);
1008  } else {
1009  pixGetRankValueMaskedRGB(pixt, NULL, 0, 0, factor, rank,
1010  &rval, &gval, &bval);
1012  lept_roundftoi(bval), pvalue);
1013  }
1014 
1015  pixDestroy(&pixt);
1016  return 0;
1017 }
1018 
1019 
1047 l_ok
1049  PIX *pixm,
1050  l_int32 x,
1051  l_int32 y,
1052  l_int32 factor,
1053  l_float32 rank,
1054  l_float32 *prval,
1055  l_float32 *pgval,
1056  l_float32 *pbval)
1057 {
1058 l_float32 scale;
1059 PIX *pixmt, *pixt;
1060 
1061  if (prval) *prval = 0.0;
1062  if (pgval) *pgval = 0.0;
1063  if (pbval) *pbval = 0.0;
1064  if (!prval && !pgval && !pbval)
1065  return ERROR_INT("no results requested", __func__, 1);
1066  if (!pixs)
1067  return ERROR_INT("pixs not defined", __func__, 1);
1068  if (pixGetDepth(pixs) != 32)
1069  return ERROR_INT("pixs not 32 bpp", __func__, 1);
1070  if (pixm && pixGetDepth(pixm) != 1)
1071  return ERROR_INT("pixm not 1 bpp", __func__, 1);
1072  if (factor < 1)
1073  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
1074  if (rank < 0.0 || rank > 1.0)
1075  return ERROR_INT("rank not in [0.0 ... 1.0]", __func__, 1);
1076 
1077  pixmt = NULL;
1078  if (pixm) {
1079  scale = 1.0 / (l_float32)factor;
1080  pixmt = pixScale(pixm, scale, scale);
1081  }
1082  if (prval) {
1083  pixt = pixScaleRGBToGrayFast(pixs, factor, COLOR_RED);
1084  pixGetRankValueMasked(pixt, pixmt, x / factor, y / factor,
1085  factor, rank, prval, NULL);
1086  pixDestroy(&pixt);
1087  }
1088  if (pgval) {
1089  pixt = pixScaleRGBToGrayFast(pixs, factor, COLOR_GREEN);
1090  pixGetRankValueMasked(pixt, pixmt, x / factor, y / factor,
1091  factor, rank, pgval, NULL);
1092  pixDestroy(&pixt);
1093  }
1094  if (pbval) {
1095  pixt = pixScaleRGBToGrayFast(pixs, factor, COLOR_BLUE);
1096  pixGetRankValueMasked(pixt, pixmt, x / factor, y / factor,
1097  factor, rank, pbval, NULL);
1098  pixDestroy(&pixt);
1099  }
1100  pixDestroy(&pixmt);
1101  return 0;
1102 }
1103 
1104 
1137 l_ok
1139  PIX *pixm,
1140  l_int32 x,
1141  l_int32 y,
1142  l_int32 factor,
1143  l_float32 rank,
1144  l_float32 *pval,
1145  NUMA **pna)
1146 {
1147 NUMA *na;
1148 
1149  if (pna) *pna = NULL;
1150  if (!pval)
1151  return ERROR_INT("&val not defined", __func__, 1);
1152  *pval = 0.0;
1153  if (!pixs)
1154  return ERROR_INT("pixs not defined", __func__, 1);
1155  if (pixGetDepth(pixs) != 8 && !pixGetColormap(pixs))
1156  return ERROR_INT("pixs neither 8 bpp nor colormapped", __func__, 1);
1157  if (pixm && pixGetDepth(pixm) != 1)
1158  return ERROR_INT("pixm not 1 bpp", __func__, 1);
1159  if (factor < 1)
1160  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
1161  if (rank < 0.0 || rank > 1.0)
1162  return ERROR_INT("rank not in [0.0 ... 1.0]", __func__, 1);
1163 
1164  if ((na = pixGetGrayHistogramMasked(pixs, pixm, x, y, factor)) == NULL)
1165  return ERROR_INT("na not made", __func__, 1);
1166  numaHistogramGetValFromRank(na, rank, pval);
1167  if (pna)
1168  *pna = na;
1169  else
1170  numaDestroy(&na);
1171 
1172  return 0;
1173 }
1174 
1175 
1206 l_ok
1208  PIX *pixm,
1209  l_int32 x,
1210  l_int32 y,
1211  l_int32 factor,
1212  l_uint32 *pval)
1213 {
1214 l_int32 i, j, w, h, d, wm, hm, wpl1, wplm, val, rval, gval, bval, count;
1215 l_uint32 *data1, *datam, *line1, *linem;
1216 l_float64 sum, rsum, gsum, bsum;
1217 PIX *pix1;
1218 
1219  if (!pval)
1220  return ERROR_INT("&val not defined", __func__, 1);
1221  *pval = 0;
1222  if (!pixs)
1223  return ERROR_INT("pixs not defined", __func__, 1);
1224  d = pixGetDepth(pixs);
1225  if (d != 32 && !pixGetColormap(pixs))
1226  return ERROR_INT("pixs not rgb or colormapped", __func__, 1);
1227  if (pixm && pixGetDepth(pixm) != 1)
1228  return ERROR_INT("pixm not 1 bpp", __func__, 1);
1229  if (factor < 1)
1230  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
1231 
1232  if (pixGetColormap(pixs))
1234  else
1235  pix1 = pixClone(pixs);
1236  pixGetDimensions(pix1, &w, &h, &d);
1237  if (d == 1) {
1238  pixDestroy(&pix1);
1239  return ERROR_INT("pix1 is just 1 bpp", __func__, 1);
1240  }
1241  data1 = pixGetData(pix1);
1242  wpl1 = pixGetWpl(pix1);
1243 
1244  sum = rsum = gsum = bsum = 0.0;
1245  count = 0;
1246  if (!pixm) {
1247  for (i = 0; i < h; i += factor) {
1248  line1 = data1 + i * wpl1;
1249  for (j = 0; j < w; j += factor) {
1250  if (d == 8) {
1251  val = GET_DATA_BYTE(line1, j);
1252  sum += val;
1253  } else { /* rgb */
1254  extractRGBValues(*(line1 + j), &rval, &gval, &bval);
1255  rsum += rval;
1256  gsum += gval;
1257  bsum += bval;
1258  }
1259  count++;
1260  }
1261  }
1262  } else { /* masked */
1263  pixGetDimensions(pixm, &wm, &hm, NULL);
1264  datam = pixGetData(pixm);
1265  wplm = pixGetWpl(pixm);
1266  for (i = 0; i < hm; i += factor) {
1267  if (y + i < 0 || y + i >= h) continue;
1268  line1 = data1 + (y + i) * wpl1;
1269  linem = datam + i * wplm;
1270  for (j = 0; j < wm; j += factor) {
1271  if (x + j < 0 || x + j >= w) continue;
1272  if (GET_DATA_BIT(linem, j)) {
1273  if (d == 8) {
1274  val = GET_DATA_BYTE(line1, x + j);
1275  sum += val;
1276  } else { /* rgb */
1277  extractRGBValues(*(line1 + x + j), &rval, &gval, &bval);
1278  rsum += rval;
1279  gsum += gval;
1280  bsum += bval;
1281  }
1282  count++;
1283  }
1284  }
1285  }
1286  }
1287 
1288  pixDestroy(&pix1);
1289  if (count == 0)
1290  return ERROR_INT("no pixels sampled", __func__, 1);
1291  if (d == 8) {
1292  *pval = (l_uint32)(sum / (l_float64)count);
1293  } else { /* d == 32 */
1294  rval = (l_uint32)(rsum / (l_float64)count);
1295  gval = (l_uint32)(gsum / (l_float64)count);
1296  bval = (l_uint32)(bsum / (l_float64)count);
1297  composeRGBPixel(rval, gval, bval, pval);
1298  }
1299 
1300  return 0;
1301 }
1302 
1303 
1322 l_ok
1324  l_int32 factor,
1325  l_int32 type,
1326  l_uint32 *pvalue)
1327 {
1328 l_int32 d;
1329 l_float32 val, rval, gval, bval;
1330 PIX *pixt;
1331 PIXCMAP *cmap;
1332 
1333  if (!pvalue)
1334  return ERROR_INT("&value not defined", __func__, 1);
1335  *pvalue = 0;
1336  if (!pixs)
1337  return ERROR_INT("pixs not defined", __func__, 1);
1338  d = pixGetDepth(pixs);
1339  cmap = pixGetColormap(pixs);
1340  if (d != 8 && d != 32 && !cmap)
1341  return ERROR_INT("pixs not 8 or 32 bpp, or cmapped", __func__, 1);
1342  if (cmap)
1344  else
1345  pixt = pixClone(pixs);
1346  d = pixGetDepth(pixt);
1347 
1348  if (d == 8) {
1349  pixGetAverageMasked(pixt, NULL, 0, 0, factor, type, &val);
1350  *pvalue = lept_roundftoi(val);
1351  } else {
1352  pixGetAverageMaskedRGB(pixt, NULL, 0, 0, factor, type,
1353  &rval, &gval, &bval);
1355  lept_roundftoi(bval), pvalue);
1356  }
1357 
1358  pixDestroy(&pixt);
1359  return 0;
1360 }
1361 
1362 
1387 l_ok
1389  PIX *pixm,
1390  l_int32 x,
1391  l_int32 y,
1392  l_int32 factor,
1393  l_int32 type,
1394  l_float32 *prval,
1395  l_float32 *pgval,
1396  l_float32 *pbval)
1397 {
1398 l_int32 empty;
1399 PIX *pixt;
1400 PIXCMAP *cmap;
1401 
1402  if (prval) *prval = 0.0;
1403  if (pgval) *pgval = 0.0;
1404  if (pbval) *pbval = 0.0;
1405  if (!prval && !pgval && !pbval)
1406  return ERROR_INT("no values requested", __func__, 1);
1407  if (!pixs)
1408  return ERROR_INT("pixs not defined", __func__, 1);
1409  cmap = pixGetColormap(pixs);
1410  if (pixGetDepth(pixs) != 32 && !cmap)
1411  return ERROR_INT("pixs neither 32 bpp nor colormapped", __func__, 1);
1412  if (pixm && pixGetDepth(pixm) != 1)
1413  return ERROR_INT("pixm not 1 bpp", __func__, 1);
1414  if (factor < 1)
1415  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
1416  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1417  type != L_STANDARD_DEVIATION && type != L_VARIANCE)
1418  return ERROR_INT("invalid measure type", __func__, 1);
1419  if (pixm) {
1420  pixZero(pixm, &empty);
1421  if (empty)
1422  return ERROR_INT("empty mask", __func__, 1);
1423  }
1424 
1425  if (prval) {
1426  if (cmap)
1427  pixt = pixGetRGBComponentCmap(pixs, COLOR_RED);
1428  else
1429  pixt = pixGetRGBComponent(pixs, COLOR_RED);
1430  pixGetAverageMasked(pixt, pixm, x, y, factor, type, prval);
1431  pixDestroy(&pixt);
1432  }
1433  if (pgval) {
1434  if (cmap)
1435  pixt = pixGetRGBComponentCmap(pixs, COLOR_GREEN);
1436  else
1437  pixt = pixGetRGBComponent(pixs, COLOR_GREEN);
1438  pixGetAverageMasked(pixt, pixm, x, y, factor, type, pgval);
1439  pixDestroy(&pixt);
1440  }
1441  if (pbval) {
1442  if (cmap)
1443  pixt = pixGetRGBComponentCmap(pixs, COLOR_BLUE);
1444  else
1445  pixt = pixGetRGBComponent(pixs, COLOR_BLUE);
1446  pixGetAverageMasked(pixt, pixm, x, y, factor, type, pbval);
1447  pixDestroy(&pixt);
1448  }
1449 
1450  return 0;
1451 }
1452 
1453 
1487 l_ok
1489  PIX *pixm,
1490  l_int32 x,
1491  l_int32 y,
1492  l_int32 factor,
1493  l_int32 type,
1494  l_float32 *pval)
1495 {
1496 l_int32 i, j, w, h, d, wm, hm, wplg, wplm, val, count, empty;
1497 l_uint32 *datag, *datam, *lineg, *linem;
1498 l_float64 sumave, summs, ave, meansq, var;
1499 PIX *pixg;
1500 
1501  if (!pval)
1502  return ERROR_INT("&val not defined", __func__, 1);
1503  *pval = 0.0;
1504  if (!pixs)
1505  return ERROR_INT("pixs not defined", __func__, 1);
1506  d = pixGetDepth(pixs);
1507  if (d != 8 && d != 16 && !pixGetColormap(pixs))
1508  return ERROR_INT("pixs not 8 or 16 bpp or colormapped", __func__, 1);
1509  if (pixm && pixGetDepth(pixm) != 1)
1510  return ERROR_INT("pixm not 1 bpp", __func__, 1);
1511  if (factor < 1)
1512  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
1513  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1514  type != L_STANDARD_DEVIATION && type != L_VARIANCE)
1515  return ERROR_INT("invalid measure type", __func__, 1);
1516  if (pixm) {
1517  pixZero(pixm, &empty);
1518  if (empty)
1519  return ERROR_INT("empty mask", __func__, 1);
1520  }
1521 
1522  if (pixGetColormap(pixs))
1524  else
1525  pixg = pixClone(pixs);
1526  pixGetDimensions(pixg, &w, &h, &d);
1527  datag = pixGetData(pixg);
1528  wplg = pixGetWpl(pixg);
1529 
1530  sumave = summs = 0.0;
1531  count = 0;
1532  if (!pixm) {
1533  for (i = 0; i < h; i += factor) {
1534  lineg = datag + i * wplg;
1535  for (j = 0; j < w; j += factor) {
1536  if (d == 8)
1537  val = GET_DATA_BYTE(lineg, j);
1538  else /* d == 16 */
1539  val = GET_DATA_TWO_BYTES(lineg, j);
1540  if (type != L_ROOT_MEAN_SQUARE)
1541  sumave += val;
1542  if (type != L_MEAN_ABSVAL)
1543  summs += (l_float64)(val) * val;
1544  count++;
1545  }
1546  }
1547  } else {
1548  pixGetDimensions(pixm, &wm, &hm, NULL);
1549  datam = pixGetData(pixm);
1550  wplm = pixGetWpl(pixm);
1551  for (i = 0; i < hm; i += factor) {
1552  if (y + i < 0 || y + i >= h) continue;
1553  lineg = datag + (y + i) * wplg;
1554  linem = datam + i * wplm;
1555  for (j = 0; j < wm; j += factor) {
1556  if (x + j < 0 || x + j >= w) continue;
1557  if (GET_DATA_BIT(linem, j)) {
1558  if (d == 8)
1559  val = GET_DATA_BYTE(lineg, x + j);
1560  else /* d == 16 */
1561  val = GET_DATA_TWO_BYTES(lineg, x + j);
1562  if (type != L_ROOT_MEAN_SQUARE)
1563  sumave += val;
1564  if (type != L_MEAN_ABSVAL)
1565  summs += (l_float64)(val) * val;
1566  count++;
1567  }
1568  }
1569  }
1570  }
1571 
1572  pixDestroy(&pixg);
1573  if (count == 0)
1574  return ERROR_INT("no pixels sampled", __func__, 1);
1575  ave = sumave / (l_float64)count;
1576  meansq = summs / (l_float64)count;
1577  var = meansq - ave * ave;
1578  if (type == L_MEAN_ABSVAL)
1579  *pval = (l_float32)ave;
1580  else if (type == L_ROOT_MEAN_SQUARE)
1581  *pval = (l_float32)sqrt(meansq);
1582  else if (type == L_STANDARD_DEVIATION)
1583  *pval = (l_float32)sqrt(var);
1584  else /* type == L_VARIANCE */
1585  *pval = (l_float32)var;
1586 
1587  return 0;
1588 }
1589 
1590 
1609 l_ok
1611  l_int32 sx,
1612  l_int32 sy,
1613  l_int32 type,
1614  PIX **ppixr,
1615  PIX **ppixg,
1616  PIX **ppixb)
1617 {
1618 PIX *pixt;
1619 PIXCMAP *cmap;
1620 
1621  if (ppixr) *ppixr = NULL;
1622  if (ppixg) *ppixg = NULL;
1623  if (ppixb) *ppixb = NULL;
1624  if (!ppixr && !ppixg && !ppixb)
1625  return ERROR_INT("no data requested", __func__, 1);
1626  if (!pixs)
1627  return ERROR_INT("pixs not defined", __func__, 1);
1628  cmap = pixGetColormap(pixs);
1629  if (pixGetDepth(pixs) != 32 && !cmap)
1630  return ERROR_INT("pixs neither 32 bpp nor colormapped", __func__, 1);
1631  if (sx < 2 || sy < 2)
1632  return ERROR_INT("sx and sy not both > 1", __func__, 1);
1633  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1634  type != L_STANDARD_DEVIATION)
1635  return ERROR_INT("invalid measure type", __func__, 1);
1636 
1637  if (ppixr) {
1638  if (cmap)
1639  pixt = pixGetRGBComponentCmap(pixs, COLOR_RED);
1640  else
1641  pixt = pixGetRGBComponent(pixs, COLOR_RED);
1642  *ppixr = pixGetAverageTiled(pixt, sx, sy, type);
1643  pixDestroy(&pixt);
1644  }
1645  if (ppixg) {
1646  if (cmap)
1647  pixt = pixGetRGBComponentCmap(pixs, COLOR_GREEN);
1648  else
1649  pixt = pixGetRGBComponent(pixs, COLOR_GREEN);
1650  *ppixg = pixGetAverageTiled(pixt, sx, sy, type);
1651  pixDestroy(&pixt);
1652  }
1653  if (ppixb) {
1654  if (cmap)
1655  pixt = pixGetRGBComponentCmap(pixs, COLOR_BLUE);
1656  else
1657  pixt = pixGetRGBComponent(pixs, COLOR_BLUE);
1658  *ppixb = pixGetAverageTiled(pixt, sx, sy, type);
1659  pixDestroy(&pixt);
1660  }
1661 
1662  return 0;
1663 }
1664 
1665 
1684 PIX *
1686  l_int32 sx,
1687  l_int32 sy,
1688  l_int32 type)
1689 {
1690 l_int32 i, j, k, m, w, h, wd, hd, d, pos, wplt, wpld, valt;
1691 l_uint32 *datat, *datad, *linet, *lined, *startt;
1692 l_float64 sumave, summs, ave, meansq, normfact;
1693 PIX *pixt, *pixd;
1694 
1695  if (!pixs)
1696  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1697  pixGetDimensions(pixs, &w, &h, &d);
1698  if (d != 8 && !pixGetColormap(pixs))
1699  return (PIX *)ERROR_PTR("pixs not 8 bpp or cmapped", __func__, NULL);
1700  if (sx < 2 || sy < 2)
1701  return (PIX *)ERROR_PTR("sx and sy not both > 1", __func__, NULL);
1702  wd = w / sx;
1703  hd = h / sy;
1704  if (wd < 1 || hd < 1)
1705  return (PIX *)ERROR_PTR("wd or hd == 0", __func__, NULL);
1706  if (type != L_MEAN_ABSVAL && type != L_ROOT_MEAN_SQUARE &&
1707  type != L_STANDARD_DEVIATION)
1708  return (PIX *)ERROR_PTR("invalid measure type", __func__, NULL);
1709 
1711  pixd = pixCreate(wd, hd, 8);
1712  datat = pixGetData(pixt);
1713  wplt = pixGetWpl(pixt);
1714  datad = pixGetData(pixd);
1715  wpld = pixGetWpl(pixd);
1716  normfact = 1. / (l_float64)(sx * sy);
1717  for (i = 0; i < hd; i++) {
1718  lined = datad + i * wpld;
1719  linet = datat + i * sy * wplt;
1720  for (j = 0; j < wd; j++) {
1721  if (type == L_MEAN_ABSVAL || type == L_STANDARD_DEVIATION) {
1722  sumave = 0.0;
1723  for (k = 0; k < sy; k++) {
1724  startt = linet + k * wplt;
1725  for (m = 0; m < sx; m++) {
1726  pos = j * sx + m;
1727  valt = GET_DATA_BYTE(startt, pos);
1728  sumave += valt;
1729  }
1730  }
1731  ave = normfact * sumave;
1732  }
1733  if (type == L_ROOT_MEAN_SQUARE || type == L_STANDARD_DEVIATION) {
1734  summs = 0.0;
1735  for (k = 0; k < sy; k++) {
1736  startt = linet + k * wplt;
1737  for (m = 0; m < sx; m++) {
1738  pos = j * sx + m;
1739  valt = GET_DATA_BYTE(startt, pos);
1740  summs += (l_float64)(valt) * valt;
1741  }
1742  }
1743  meansq = normfact * summs;
1744  }
1745  if (type == L_MEAN_ABSVAL)
1746  valt = (l_int32)(ave + 0.5);
1747  else if (type == L_ROOT_MEAN_SQUARE)
1748  valt = (l_int32)(sqrt(meansq) + 0.5);
1749  else /* type == L_STANDARD_DEVIATION */
1750  valt = (l_int32)(sqrt(meansq - ave * ave) + 0.5);
1751  SET_DATA_BYTE(lined, j, valt);
1752  }
1753  }
1754 
1755  pixDestroy(&pixt);
1756  return pixd;
1757 }
1758 
1759 
1785 l_int32
1787  BOX *box,
1788  NUMA **pnamean,
1789  NUMA **pnamedian,
1790  NUMA **pnamode,
1791  NUMA **pnamodecount,
1792  NUMA **pnavar,
1793  NUMA **pnarootvar)
1794 {
1795 l_int32 i, j, k, w, h, val, wpls, sum, sumsq, target, max, modeval;
1796 l_int32 xstart, xend, ystart, yend, bw, bh;
1797 l_int32 *histo;
1798 l_uint32 *lines, *datas;
1799 l_float32 norm;
1800 l_float32 *famean, *fameansq, *favar, *farootvar;
1801 l_float32 *famedian, *famode, *famodecount;
1802 
1803  if (pnamean) *pnamean = NULL;
1804  if (pnamedian) *pnamedian = NULL;
1805  if (pnamode) *pnamode = NULL;
1806  if (pnamodecount) *pnamodecount = NULL;
1807  if (pnavar) *pnavar = NULL;
1808  if (pnarootvar) *pnarootvar = NULL;
1809  if (!pixs || pixGetDepth(pixs) != 8)
1810  return ERROR_INT("pixs undefined or not 8 bpp", __func__, 1);
1811  famean = fameansq = favar = farootvar = NULL;
1812  famedian = famode = famodecount = NULL;
1813 
1814  pixGetDimensions(pixs, &w, &h, NULL);
1815  if (boxClipToRectangleParams(box, w, h, &xstart, &ystart, &xend, &yend,
1816  &bw, &bh) == 1)
1817  return ERROR_INT("invalid clipping box", __func__, 1);
1818 
1819  /* We need the mean for variance and root variance */
1820  datas = pixGetData(pixs);
1821  wpls = pixGetWpl(pixs);
1822  if (pnamean || pnavar || pnarootvar) {
1823  norm = 1. / (l_float32)bw;
1824  famean = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1825  fameansq = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1826  if (pnavar || pnarootvar) {
1827  favar = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1828  if (pnarootvar)
1829  farootvar = (l_float32 *)LEPT_CALLOC(bh, sizeof(l_float32));
1830  }
1831  for (i = ystart; i < yend; i++) {
1832  sum = sumsq = 0;
1833  lines = datas + i * wpls;
1834  for (j = xstart; j < xend; j++) {
1835  val = GET_DATA_BYTE(lines, j);
1836  sum += val;
1837  sumsq += val * val;
1838  }
1839  famean[i] = norm * sum;
1840  fameansq[i] = norm * sumsq;
1841  if (pnavar || pnarootvar) {
1842  favar[i] = fameansq[i] - famean[i] * famean[i];
1843  if (pnarootvar)
1844  farootvar[i] = sqrtf(favar[i]);
1845  }
1846  }
1847  LEPT_FREE(fameansq);
1848  if (pnamean)
1849  *pnamean = numaCreateFromFArray(famean, bh, L_INSERT);
1850  else
1851  LEPT_FREE(famean);
1852  if (pnavar)
1853  *pnavar = numaCreateFromFArray(favar, bh, L_INSERT);
1854  else
1855  LEPT_FREE(favar);
1856  if (pnarootvar)
1857  *pnarootvar = numaCreateFromFArray(farootvar, bh, L_INSERT);
1858  }
1859 
1860  /* We need a histogram to find the median and/or mode values */
1861  if (pnamedian || pnamode || pnamodecount) {
1862  histo = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
1863  if (pnamedian) {
1864  *pnamedian = numaMakeConstant(0, bh);
1865  famedian = numaGetFArray(*pnamedian, L_NOCOPY);
1866  }
1867  if (pnamode) {
1868  *pnamode = numaMakeConstant(0, bh);
1869  famode = numaGetFArray(*pnamode, L_NOCOPY);
1870  }
1871  if (pnamodecount) {
1872  *pnamodecount = numaMakeConstant(0, bh);
1873  famodecount = numaGetFArray(*pnamodecount, L_NOCOPY);
1874  }
1875  for (i = ystart; i < yend; i++) {
1876  lines = datas + i * wpls;
1877  memset(histo, 0, 1024);
1878  for (j = xstart; j < xend; j++) {
1879  val = GET_DATA_BYTE(lines, j);
1880  histo[val]++;
1881  }
1882 
1883  if (pnamedian) {
1884  sum = 0;
1885  target = (bw + 1) / 2;
1886  for (k = 0; k < 256; k++) {
1887  sum += histo[k];
1888  if (sum >= target) {
1889  famedian[i] = k;
1890  break;
1891  }
1892  }
1893  }
1894 
1895  if (pnamode || pnamodecount) {
1896  max = 0;
1897  modeval = 0;
1898  for (k = 0; k < 256; k++) {
1899  if (histo[k] > max) {
1900  max = histo[k];
1901  modeval = k;
1902  }
1903  }
1904  if (pnamode)
1905  famode[i] = modeval;
1906  if (pnamodecount)
1907  famodecount[i] = max;
1908  }
1909  }
1910  LEPT_FREE(histo);
1911  }
1912 
1913  return 0;
1914 }
1915 
1916 
1943 l_int32
1945  BOX *box,
1946  NUMA **pnamean,
1947  NUMA **pnamedian,
1948  NUMA **pnamode,
1949  NUMA **pnamodecount,
1950  NUMA **pnavar,
1951  NUMA **pnarootvar)
1952 {
1953 l_int32 i, j, k, w, h, val, wpls, sum, sumsq, target, max, modeval;
1954 l_int32 xstart, xend, ystart, yend, bw, bh;
1955 l_int32 *histo;
1956 l_uint32 *lines, *datas;
1957 l_float32 norm;
1958 l_float32 *famean, *fameansq, *favar, *farootvar;
1959 l_float32 *famedian, *famode, *famodecount;
1960 
1961  if (pnamean) *pnamean = NULL;
1962  if (pnamedian) *pnamedian = NULL;
1963  if (pnamode) *pnamode = NULL;
1964  if (pnamodecount) *pnamodecount = NULL;
1965  if (pnavar) *pnavar = NULL;
1966  if (pnarootvar) *pnarootvar = NULL;
1967  if (!pixs || pixGetDepth(pixs) != 8)
1968  return ERROR_INT("pixs undefined or not 8 bpp", __func__, 1);
1969  famean = fameansq = favar = farootvar = NULL;
1970  famedian = famode = famodecount = NULL;
1971 
1972  pixGetDimensions(pixs, &w, &h, NULL);
1973  if (boxClipToRectangleParams(box, w, h, &xstart, &ystart, &xend, &yend,
1974  &bw, &bh) == 1)
1975  return ERROR_INT("invalid clipping box", __func__, 1);
1976 
1977  /* We need the mean for variance and root variance */
1978  datas = pixGetData(pixs);
1979  wpls = pixGetWpl(pixs);
1980  if (pnamean || pnavar || pnarootvar) {
1981  norm = 1. / (l_float32)bh;
1982  famean = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
1983  fameansq = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
1984  if (pnavar || pnarootvar) {
1985  favar = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
1986  if (pnarootvar)
1987  farootvar = (l_float32 *)LEPT_CALLOC(bw, sizeof(l_float32));
1988  }
1989  for (j = xstart; j < xend; j++) {
1990  sum = sumsq = 0;
1991  for (i = ystart, lines = datas; i < yend; lines += wpls, i++) {
1992  val = GET_DATA_BYTE(lines, j);
1993  sum += val;
1994  sumsq += val * val;
1995  }
1996  famean[j] = norm * sum;
1997  fameansq[j] = norm * sumsq;
1998  if (pnavar || pnarootvar) {
1999  favar[j] = fameansq[j] - famean[j] * famean[j];
2000  if (pnarootvar)
2001  farootvar[j] = sqrtf(favar[j]);
2002  }
2003  }
2004  LEPT_FREE(fameansq);
2005  if (pnamean)
2006  *pnamean = numaCreateFromFArray(famean, bw, L_INSERT);
2007  else
2008  LEPT_FREE(famean);
2009  if (pnavar)
2010  *pnavar = numaCreateFromFArray(favar, bw, L_INSERT);
2011  else
2012  LEPT_FREE(favar);
2013  if (pnarootvar)
2014  *pnarootvar = numaCreateFromFArray(farootvar, bw, L_INSERT);
2015  }
2016 
2017  /* We need a histogram to find the median and/or mode values */
2018  if (pnamedian || pnamode || pnamodecount) {
2019  histo = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
2020  if (pnamedian) {
2021  *pnamedian = numaMakeConstant(0, bw);
2022  famedian = numaGetFArray(*pnamedian, L_NOCOPY);
2023  }
2024  if (pnamode) {
2025  *pnamode = numaMakeConstant(0, bw);
2026  famode = numaGetFArray(*pnamode, L_NOCOPY);
2027  }
2028  if (pnamodecount) {
2029  *pnamodecount = numaMakeConstant(0, bw);
2030  famodecount = numaGetFArray(*pnamodecount, L_NOCOPY);
2031  }
2032  for (j = xstart; j < xend; j++) {
2033  memset(histo, 0, 1024);
2034  for (i = ystart, lines = datas; i < yend; lines += wpls, i++) {
2035  val = GET_DATA_BYTE(lines, j);
2036  histo[val]++;
2037  }
2038 
2039  if (pnamedian) {
2040  sum = 0;
2041  target = (bh + 1) / 2;
2042  for (k = 0; k < 256; k++) {
2043  sum += histo[k];
2044  if (sum >= target) {
2045  famedian[j] = k;
2046  break;
2047  }
2048  }
2049  }
2050 
2051  if (pnamode || pnamodecount) {
2052  max = 0;
2053  modeval = 0;
2054  for (k = 0; k < 256; k++) {
2055  if (histo[k] > max) {
2056  max = histo[k];
2057  modeval = k;
2058  }
2059  }
2060  if (pnamode)
2061  famode[j] = modeval;
2062  if (pnamodecount)
2063  famodecount[j] = max;
2064  }
2065  }
2066  LEPT_FREE(histo);
2067  }
2068 
2069  return 0;
2070 }
2071 
2072 
2088 l_ok
2090  l_int32 factor,
2091  l_int32 color,
2092  l_int32 *pminval,
2093  l_int32 *pmaxval)
2094 {
2095 l_int32 d;
2096 PIXCMAP *cmap;
2097 
2098  if (pminval) *pminval = 0;
2099  if (pmaxval) *pmaxval = 0;
2100  if (!pminval && !pmaxval)
2101  return ERROR_INT("no result requested", __func__, 1);
2102  if (!pixs)
2103  return ERROR_INT("pixs not defined", __func__, 1);
2104 
2105  cmap = pixGetColormap(pixs);
2106  if (cmap)
2107  return pixcmapGetRangeValues(cmap, color, pminval, pmaxval,
2108  NULL, NULL);
2109 
2110  if (factor < 1)
2111  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
2112  d = pixGetDepth(pixs);
2113  if (d != 8 && d != 32)
2114  return ERROR_INT("pixs not 8 or 32 bpp", __func__, 1);
2115 
2116  if (d == 8) {
2117  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2118  NULL, NULL, NULL, pminval);
2119  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2120  NULL, NULL, NULL, pmaxval);
2121  } else if (color == L_SELECT_RED) {
2122  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2123  pminval, NULL, NULL, NULL);
2124  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2125  pmaxval, NULL, NULL, NULL);
2126  } else if (color == L_SELECT_GREEN) {
2127  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2128  NULL, pminval, NULL, NULL);
2129  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2130  NULL, pmaxval, NULL, NULL);
2131  } else if (color == L_SELECT_BLUE) {
2132  pixGetExtremeValue(pixs, factor, L_SELECT_MIN,
2133  NULL, NULL, pminval, NULL);
2134  pixGetExtremeValue(pixs, factor, L_SELECT_MAX,
2135  NULL, NULL, pmaxval, NULL);
2136  } else {
2137  return ERROR_INT("invalid color", __func__, 1);
2138  }
2139 
2140  return 0;
2141 }
2142 
2143 
2164 l_ok
2166  l_int32 factor,
2167  l_int32 type,
2168  l_int32 *prval,
2169  l_int32 *pgval,
2170  l_int32 *pbval,
2171  l_int32 *pgrayval)
2172 {
2173 l_int32 i, j, w, h, d, wpl;
2174 l_int32 val, extval, rval, gval, bval, extrval, extgval, extbval;
2175 l_uint32 pixel;
2176 l_uint32 *data, *line;
2177 PIXCMAP *cmap;
2178 
2179  if (prval) *prval = -1;
2180  if (pgval) *pgval = -1;
2181  if (pbval) *pbval = -1;
2182  if (pgrayval) *pgrayval = -1;
2183  if (!pixs)
2184  return ERROR_INT("pixs not defined", __func__, 1);
2185  if (type != L_SELECT_MIN && type != L_SELECT_MAX)
2186  return ERROR_INT("invalid type", __func__, 1);
2187 
2188  cmap = pixGetColormap(pixs);
2189  if (cmap) {
2190  if (type == L_SELECT_MIN) {
2191  if (prval) pixcmapGetRangeValues(cmap, L_SELECT_RED, prval, NULL,
2192  NULL, NULL);
2193  if (pgval) pixcmapGetRangeValues(cmap, L_SELECT_GREEN, pgval, NULL,
2194  NULL, NULL);
2195  if (pbval) pixcmapGetRangeValues(cmap, L_SELECT_BLUE, pbval, NULL,
2196  NULL, NULL);
2197  } else { /* type == L_SELECT_MAX */
2198  if (prval) pixcmapGetRangeValues(cmap, L_SELECT_RED, NULL, prval,
2199  NULL, NULL);
2200  if (pgval) pixcmapGetRangeValues(cmap, L_SELECT_GREEN, NULL, pgval,
2201  NULL, NULL);
2202  if (pbval) pixcmapGetRangeValues(cmap, L_SELECT_BLUE, NULL, pbval,
2203  NULL, NULL);
2204  }
2205  return 0;
2206  }
2207 
2208  pixGetDimensions(pixs, &w, &h, &d);
2209  if (factor < 1)
2210  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
2211  if (d != 8 && d != 32)
2212  return ERROR_INT("pixs not 8 or 32 bpp", __func__, 1);
2213  if (d == 8 && !pgrayval)
2214  return ERROR_INT("can't return result in grayval", __func__, 1);
2215  if (d == 32 && !prval && !pgval && !pbval)
2216  return ERROR_INT("can't return result in r/g/b-val", __func__, 1);
2217 
2218  data = pixGetData(pixs);
2219  wpl = pixGetWpl(pixs);
2220  if (d == 8) {
2221  if (type == L_SELECT_MIN)
2222  extval = 100000;
2223  else /* get max */
2224  extval = -1;
2225 
2226  for (i = 0; i < h; i += factor) {
2227  line = data + i * wpl;
2228  for (j = 0; j < w; j += factor) {
2229  val = GET_DATA_BYTE(line, j);
2230  if ((type == L_SELECT_MIN && val < extval) ||
2231  (type == L_SELECT_MAX && val > extval))
2232  extval = val;
2233  }
2234  }
2235  *pgrayval = extval;
2236  return 0;
2237  }
2238 
2239  /* 32 bpp rgb */
2240  if (type == L_SELECT_MIN) {
2241  extrval = 100000;
2242  extgval = 100000;
2243  extbval = 100000;
2244  } else {
2245  extrval = -1;
2246  extgval = -1;
2247  extbval = -1;
2248  }
2249  for (i = 0; i < h; i += factor) {
2250  line = data + i * wpl;
2251  for (j = 0; j < w; j += factor) {
2252  pixel = line[j];
2253  if (prval) {
2254  rval = (pixel >> L_RED_SHIFT) & 0xff;
2255  if ((type == L_SELECT_MIN && rval < extrval) ||
2256  (type == L_SELECT_MAX && rval > extrval))
2257  extrval = rval;
2258  }
2259  if (pgval) {
2260  gval = (pixel >> L_GREEN_SHIFT) & 0xff;
2261  if ((type == L_SELECT_MIN && gval < extgval) ||
2262  (type == L_SELECT_MAX && gval > extgval))
2263  extgval = gval;
2264  }
2265  if (pbval) {
2266  bval = (pixel >> L_BLUE_SHIFT) & 0xff;
2267  if ((type == L_SELECT_MIN && bval < extbval) ||
2268  (type == L_SELECT_MAX && bval > extbval))
2269  extbval = bval;
2270  }
2271  }
2272  }
2273  if (prval) *prval = extrval;
2274  if (pgval) *pgval = extgval;
2275  if (pbval) *pbval = extbval;
2276  return 0;
2277 }
2278 
2279 
2299 l_ok
2301  BOX *box,
2302  l_uint32 *pmaxval,
2303  l_int32 *pxmax,
2304  l_int32 *pymax)
2305 {
2306 l_int32 i, j, w, h, d, wpl, bw, bh;
2307 l_int32 xstart, ystart, xend, yend, xmax, ymax;
2308 l_uint32 val, maxval;
2309 l_uint32 *data, *line;
2310 
2311  if (pmaxval) *pmaxval = 0;
2312  if (pxmax) *pxmax = 0;
2313  if (pymax) *pymax = 0;
2314  if (!pmaxval && !pxmax && !pymax)
2315  return ERROR_INT("no data requested", __func__, 1);
2316  if (!pixs)
2317  return ERROR_INT("pixs not defined", __func__, 1);
2318  if (pixGetColormap(pixs) != NULL)
2319  return ERROR_INT("pixs has colormap", __func__, 1);
2320  pixGetDimensions(pixs, &w, &h, &d);
2321  if (d != 8 && d != 16 && d != 32)
2322  return ERROR_INT("pixs not 8, 16 or 32 bpp", __func__, 1);
2323 
2324  xstart = ystart = 0;
2325  xend = w - 1;
2326  yend = h - 1;
2327  if (box) {
2328  boxGetGeometry(box, &xstart, &ystart, &bw, &bh);
2329  xend = xstart + bw - 1;
2330  yend = ystart + bh - 1;
2331  }
2332 
2333  data = pixGetData(pixs);
2334  wpl = pixGetWpl(pixs);
2335  maxval = 0;
2336  xmax = ymax = 0;
2337  for (i = ystart; i <= yend; i++) {
2338  line = data + i * wpl;
2339  for (j = xstart; j <= xend; j++) {
2340  if (d == 8)
2341  val = GET_DATA_BYTE(line, j);
2342  else if (d == 16)
2343  val = GET_DATA_TWO_BYTES(line, j);
2344  else /* d == 32 */
2345  val = line[j];
2346  if (val > maxval) {
2347  maxval = val;
2348  xmax = j;
2349  ymax = i;
2350  }
2351  }
2352  }
2353  if (maxval == 0) { /* no counts; pick the center of the rectangle */
2354  xmax = (xstart + xend) / 2;
2355  ymax = (ystart + yend) / 2;
2356  }
2357 
2358  if (pmaxval) *pmaxval = maxval;
2359  if (pxmax) *pxmax = xmax;
2360  if (pymax) *pymax = ymax;
2361  return 0;
2362 }
2363 
2364 
2372 l_ok
2374  l_int32 *pmaxindex)
2375 {
2376 l_int32 i, j, w, h, d, wpl, val, max, maxval, empty;
2377 l_uint32 *data, *line;
2378 
2379  if (!pmaxindex)
2380  return ERROR_INT("&maxindex not defined", __func__, 1);
2381  *pmaxindex = 0;
2382  if (!pixs)
2383  return ERROR_INT("pixs not defined", __func__, 1);
2384  pixGetDimensions(pixs, &w, &h, &d);
2385  if (d != 1 && d != 2 && d != 4 && d != 8)
2386  return ERROR_INT("invalid pixs depth; not in (1,2,4,8}", __func__, 1);
2387 
2388  wpl = pixGetWpl(pixs);
2389  data = pixGetData(pixs);
2390  max = 0;
2391  maxval = (1 << d) - 1;
2392  if (d == 1) {
2393  pixZero(pixs, &empty);
2394  if (!empty) max = 1;
2395  *pmaxindex = max;
2396  return 0;
2397  }
2398  for (i = 0; i < h; i++) {
2399  line = data + i * wpl;
2400  if (d == 2) {
2401  for (j = 0; j < w; j++) {
2402  val = GET_DATA_DIBIT(line, j);
2403  if (val > max) max = val;
2404  }
2405  } else if (d == 4) {
2406  for (j = 0; j < w; j++) {
2407  val = GET_DATA_QBIT(line, j);
2408  if (val > max) max = val;
2409  }
2410  } else if (d == 8) {
2411  for (j = 0; j < w; j++) {
2412  val = GET_DATA_BYTE(line, j);
2413  if (val > max) max = val;
2414  }
2415  }
2416  if (max == maxval) break;
2417  }
2418  *pmaxindex = max;
2419  return 0;
2420 }
2421 
2422 
2444 l_ok
2446  l_int32 nbins,
2447  l_int32 factor,
2448  l_int32 color,
2449  l_int32 *pminval,
2450  l_int32 *pmaxval,
2451  l_uint32 **pcarray,
2452  l_int32 fontsize)
2453 {
2454 l_int32 i, minval, maxval, rval, gval, bval;
2455 l_uint32 *carray;
2456 PIX *pixt;
2457 
2458  if (pminval) *pminval = 0;
2459  if (pmaxval) *pmaxval = 0;
2460  if (pcarray) *pcarray = NULL;
2461  if (!pminval && !pmaxval)
2462  return ERROR_INT("no result requested", __func__, 1);
2463  if (!pixs || pixGetDepth(pixs) != 32)
2464  return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
2465  if (factor < 1)
2466  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
2467  if (color != L_SELECT_RED && color != L_SELECT_GREEN &&
2468  color != L_SELECT_BLUE)
2469  return ERROR_INT("invalid color", __func__, 1);
2470  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2471  return ERROR_INT("invalid fontsize", __func__, 1);
2472 
2473  pixGetRankColorArray(pixs, nbins, color, factor, &carray, NULL, 0);
2474  if (!carray)
2475  return ERROR_INT("carray not made", __func__, 1);
2476 
2477  if (fontsize > 0) {
2478  for (i = 0; i < nbins; i++)
2479  L_INFO("c[%d] = %x\n", __func__, i, carray[i]);
2480  pixt = pixDisplayColorArray(carray, nbins, 200, 5, fontsize);
2481  pixDisplay(pixt, 100, 100);
2482  pixDestroy(&pixt);
2483  }
2484 
2485  extractRGBValues(carray[0], &rval, &gval, &bval);
2486  minval = rval;
2487  if (color == L_SELECT_GREEN)
2488  minval = gval;
2489  else if (color == L_SELECT_BLUE)
2490  minval = bval;
2491  extractRGBValues(carray[nbins - 1], &rval, &gval, &bval);
2492  maxval = rval;
2493  if (color == L_SELECT_GREEN)
2494  maxval = gval;
2495  else if (color == L_SELECT_BLUE)
2496  maxval = bval;
2497 
2498  if (pminval) *pminval = minval;
2499  if (pmaxval) *pmaxval = maxval;
2500  if (pcarray)
2501  *pcarray = carray;
2502  else
2503  LEPT_FREE(carray);
2504  return 0;
2505 }
2506 
2507 
2541 l_ok
2543  l_int32 nbins,
2544  l_int32 type,
2545  l_int32 factor,
2546  l_uint32 **pcarray,
2547  PIXA *pixadb,
2548  l_int32 fontsize)
2549 {
2550 l_int32 ret, w, h, samplesperbin;
2551 l_uint32 *array;
2552 PIX *pix1, *pixc, *pixg, *pixd;
2553 PIXCMAP *cmap;
2554 
2555  if (!pcarray)
2556  return ERROR_INT("&carray not defined", __func__, 1);
2557  *pcarray = NULL;
2558  if (factor < 1)
2559  return ERROR_INT("sampling factor must be >= 1", __func__, 1);
2560  if (nbins < 2)
2561  return ERROR_INT("nbins must be at least 2", __func__, 1);
2562  if (!pixs)
2563  return ERROR_INT("pixs not defined", __func__, 1);
2564  cmap = pixGetColormap(pixs);
2565  if (pixGetDepth(pixs) != 32 && !cmap)
2566  return ERROR_INT("pixs neither 32 bpp nor cmapped", __func__, 1);
2567  if (type != L_SELECT_RED && type != L_SELECT_GREEN &&
2568  type != L_SELECT_BLUE && type != L_SELECT_MIN &&
2569  type != L_SELECT_MAX && type != L_SELECT_AVERAGE &&
2570  type != L_SELECT_HUE && type != L_SELECT_SATURATION)
2571  return ERROR_INT("invalid type", __func__, 1);
2572  if (pixadb) {
2573  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2) {
2574  L_WARNING("invalid fontsize %d; setting to 6\n", __func__,
2575  fontsize);
2576  fontsize = 6;
2577  }
2578  }
2579  pixGetDimensions(pixs, &w, &h, NULL);
2580  samplesperbin = (w * h) / (factor * factor * nbins);
2581  if (samplesperbin < 10) {
2582  L_ERROR("samplesperbin = %d < 10\n", __func__, samplesperbin);
2583  return 1;
2584  }
2585 
2586  /* Downscale by factor and remove colormap if it exists */
2587  pix1 = pixScaleByIntSampling(pixs, factor);
2588  if (cmap)
2590  else
2591  pixc = pixClone(pix1);
2592  pixDestroy(&pix1);
2593 
2594  /* Convert to an 8 bit version for ordering the pixels */
2595  pixg = pixConvertRGBToGrayGeneral(pixc, type, 0.0, 0.0, 0.0);
2596 
2597  /* Get the average color in each bin for pixels whose grayscale
2598  * values are in the range for that bin. */
2599  pixGetBinnedColor(pixc, pixg, 1, nbins, pcarray, pixadb);
2600  ret = 0;
2601  if ((array = *pcarray) == NULL) {
2602  L_ERROR("color array not returned\n", __func__);
2603  ret = 1;
2604  }
2605  if (array && pixadb) {
2606  pixd = pixDisplayColorArray(array, nbins, 200, 5, fontsize);
2607  pixWriteDebug("/tmp/lept/regout/rankhisto.png", pixd, IFF_PNG);
2608  pixDestroy(&pixd);
2609  }
2610 
2611  pixDestroy(&pixc);
2612  pixDestroy(&pixg);
2613  return ret;
2614 }
2615 
2616 
2644 l_ok
2646  PIX *pixg,
2647  l_int32 factor,
2648  l_int32 nbins,
2649  l_uint32 **pcarray,
2650  PIXA *pixadb)
2651 {
2652 l_int32 i, j, w, h, wpls, wplg;
2653 l_int32 count, bincount, binindex, binsize, npts, avepts, ntot;
2654 l_int32 rval, gval, bval, grayval, rave, gave, bave;
2655 l_uint32 *datas, *datag, *lines, *lineg, *carray;
2656 l_float64 val64, rsum, gsum, bsum;
2657 L_DNAA *daa;
2658 NUMA *naeach;
2659 PIX *pix1;
2660 
2661  if (!pcarray)
2662  return ERROR_INT("&carray not defined", __func__, 1);
2663  *pcarray = NULL;
2664  if (!pixs || pixGetDepth(pixs) != 32)
2665  return ERROR_INT("pixs undefined or not 32 bpp", __func__, 1);
2666  if (!pixg || pixGetDepth(pixg) != 8)
2667  return ERROR_INT("pixg undefined or not 8 bpp", __func__, 1);
2668  if (factor < 1) {
2669  L_WARNING("sampling factor less than 1; setting to 1\n", __func__);
2670  factor = 1;
2671  }
2672  if (nbins < 1 || nbins > 100)
2673  return ERROR_INT("nbins not in [1,100]", __func__, 1);
2674 
2675  /* Require that each bin has at least 5 pixels. */
2676  pixGetDimensions(pixs, &w, &h, NULL);
2677  npts = (w + factor - 1) * (h + factor - 1) / (factor * factor);
2678  avepts = (npts + nbins - 1) / nbins; /* average number of pts in a bin */
2679  if (avepts < 5) {
2680  L_ERROR("avepts = %d; must be >= 5\n", __func__, avepts);
2681  return 1;
2682  }
2683 
2684  /* ------------------------------------------------------------ *
2685  * Find the average color for each bin. The colors are ordered *
2686  * by the gray value in the corresponding pixel in %pixg. *
2687  * The bins have equal numbers of pixels (within 1). *
2688  * ------------------------------------------------------------ */
2689 
2690  /* Generate a dnaa, where each dna has the colors corresponding
2691  * to the grayscale value given by the index of the dna in the dnaa */
2692  datas = pixGetData(pixs);
2693  wpls = pixGetWpl(pixs);
2694  datag = pixGetData(pixg);
2695  wplg = pixGetWpl(pixg);
2696  daa = l_dnaaCreateFull(256, 0);
2697  for (i = 0; i < h; i += factor) {
2698  lines = datas + i * wpls;
2699  lineg = datag + i * wplg;
2700  for (j = 0; j < w; j += factor) {
2701  grayval = GET_DATA_BYTE(lineg, j);
2702  l_dnaaAddNumber(daa, grayval, lines[j]);
2703  }
2704  }
2705 
2706  if (pixadb) {
2707  NUMA *na, *nabinval, *narank;
2708  na = numaCreate(256); /* grayscale histogram */
2709  for (i = 0; i < 256; i++)
2710  numaAddNumber(na, l_dnaaGetDnaCount(daa, i));
2711 
2712  /* Plot the gray bin value and the rank(gray) values */
2713  numaDiscretizeHistoInBins(na, nbins, &nabinval, &narank);
2714  pix1 = gplotSimplePix1(nabinval, "Gray value in each bin");
2715  pixaAddPix(pixadb, pix1, L_INSERT);
2716  pix1 = gplotSimplePix1(narank, "rank as function of gray value");
2717  pixaAddPix(pixadb, pix1, L_INSERT);
2718  numaDestroy(&na);
2719  numaDestroy(&nabinval);
2720  numaDestroy(&narank);
2721  }
2722 
2723  /* Get the number of items in each bin */
2724  ntot = l_dnaaGetNumberCount(daa);
2725  if ((naeach = numaGetUniformBinSizes(ntot, nbins)) == NULL) {
2726  l_dnaaDestroy(&daa);
2727  return ERROR_INT("naeach not made", __func__, 1);
2728  }
2729 
2730  /* Get the average color in each bin. This algorithm is
2731  * esssentially the same as in numaDiscretizeHistoInBins() */
2732  carray = (l_uint32 *)LEPT_CALLOC(nbins, sizeof(l_uint32));
2733  rsum = gsum = bsum = 0.0;
2734  bincount = 0;
2735  binindex = 0;
2736  numaGetIValue(naeach, 0, &binsize);
2737  for (i = 0; i < 256; i++) {
2738  count = l_dnaaGetDnaCount(daa, i);
2739  for (j = 0; j < count; j++) {
2740  bincount++;
2741  l_dnaaGetValue(daa, i, j, &val64);
2742  extractRGBValues((l_uint32)val64, &rval, &gval, &bval);
2743  rsum += rval;
2744  gsum += gval;
2745  bsum += bval;
2746  if (bincount == binsize) { /* add bin entry */
2747  rave = (l_int32)(rsum / binsize + 0.5);
2748  gave = (l_int32)(gsum / binsize + 0.5);
2749  bave = (l_int32)(bsum / binsize + 0.5);
2750  composeRGBPixel(rave, gave, bave, carray + binindex);
2751  rsum = gsum = bsum = 0.0;
2752  bincount = 0;
2753  binindex++;
2754  if (binindex == nbins) break;
2755  numaGetIValue(naeach, binindex, &binsize);
2756  }
2757  }
2758  if (binindex == nbins) break;
2759  }
2760  if (binindex != nbins)
2761  L_ERROR("binindex = %d != nbins = %d\n", __func__, binindex, nbins);
2762 
2763  if (pixadb) {
2764  NUMA *nared, *nagreen, *nablue;
2765  nared = numaCreate(nbins);
2766  nagreen = numaCreate(nbins);
2767  nablue = numaCreate(nbins);
2768  for (i = 0; i < nbins; i++) {
2769  extractRGBValues(carray[i], &rval, &gval, &bval);
2770  numaAddNumber(nared, rval);
2771  numaAddNumber(nagreen, gval);
2772  numaAddNumber(nablue, bval);
2773  }
2774  lept_mkdir("lept/regout");
2775  pix1 = gplotSimplePix1(nared, "Average red val vs. rank bin");
2776  pixaAddPix(pixadb, pix1, L_INSERT);
2777  pix1 = gplotSimplePix1(nagreen, "Average green val vs. rank bin");
2778  pixaAddPix(pixadb, pix1, L_INSERT);
2779  pix1 = gplotSimplePix1(nablue, "Average blue val vs. rank bin");
2780  pixaAddPix(pixadb, pix1, L_INSERT);
2781  numaDestroy(&nared);
2782  numaDestroy(&nagreen);
2783  numaDestroy(&nablue);
2784  }
2785 
2786  *pcarray = carray;
2787  numaDestroy(&naeach);
2788  l_dnaaDestroy(&daa);
2789  return 0;
2790 }
2791 
2792 
2812 PIX *
2813 pixDisplayColorArray(l_uint32 *carray,
2814  l_int32 ncolors,
2815  l_int32 side,
2816  l_int32 ncols,
2817  l_int32 fontsize)
2818 {
2819 char textstr[256];
2820 l_int32 i, rval, gval, bval;
2821 L_BMF *bmf;
2822 PIX *pix1, *pix2, *pix3, *pix4;
2823 PIXA *pixa;
2824 
2825  if (!carray)
2826  return (PIX *)ERROR_PTR("carray not defined", __func__, NULL);
2827  if (fontsize < 0 || fontsize > 20 || fontsize & 1 || fontsize == 2)
2828  return (PIX *)ERROR_PTR("invalid fontsize", __func__, NULL);
2829 
2830  bmf = (fontsize == 0) ? NULL : bmfCreate(NULL, fontsize);
2831  pixa = pixaCreate(ncolors);
2832  for (i = 0; i < ncolors; i++) {
2833  pix1 = pixCreate(side, side, 32);
2834  pixSetAllArbitrary(pix1, carray[i]);
2835  pix2 = pixAddBorder(pix1, 2, 1);
2836  if (bmf) {
2837  extractRGBValues(carray[i], &rval, &gval, &bval);
2838  snprintf(textstr, sizeof(textstr),
2839  "%d: (%d %d %d)", i, rval, gval, bval);
2840  pix3 = pixAddSingleTextblock(pix2, bmf, textstr, 0xff000000,
2841  L_ADD_BELOW, NULL);
2842  } else {
2843  pix3 = pixClone(pix2);
2844  }
2845  pixaAddPix(pixa, pix3, L_INSERT);
2846  pixDestroy(&pix1);
2847  pixDestroy(&pix2);
2848  }
2849  pix4 = pixaDisplayTiledInColumns(pixa, ncols, 1.0, 20, 2);
2850  pixaDestroy(&pixa);
2851  bmfDestroy(&bmf);
2852  return pix4;
2853 }
2854 
2855 
2886 PIX *
2888  l_int32 direction,
2889  l_int32 size,
2890  l_int32 nbins,
2891  l_int32 type)
2892 {
2893 l_int32 i, j, w, h, mindim, nstrips;
2894 l_uint32 *array;
2895 BOXA *boxa;
2896 PIX *pix1, *pix2, *pixd;
2897 PIXA *pixa;
2898 PIXCMAP *cmap;
2899 
2900  if (!pixs)
2901  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2902  cmap = pixGetColormap(pixs);
2903  if (pixGetDepth(pixs) != 32 && !cmap)
2904  return (PIX *)ERROR_PTR("pixs neither 32 bpp nor cmapped",
2905  __func__, NULL);
2906  if (direction != L_SCAN_HORIZONTAL && direction != L_SCAN_VERTICAL)
2907  return (PIX *)ERROR_PTR("invalid direction", __func__, NULL);
2908  if (size < 1)
2909  return (PIX *)ERROR_PTR("size < 1", __func__, NULL);
2910  if (nbins < 2)
2911  return (PIX *)ERROR_PTR("nbins must be at least 2", __func__, NULL);
2912  if (type != L_SELECT_RED && type != L_SELECT_GREEN &&
2913  type != L_SELECT_BLUE && type != L_SELECT_MIN &&
2914  type != L_SELECT_MAX && type != L_SELECT_AVERAGE &&
2915  type != L_SELECT_HUE && type != L_SELECT_SATURATION)
2916  return (PIX *)ERROR_PTR("invalid type", __func__, NULL);
2917  pixGetDimensions(pixs, &w, &h, NULL);
2918  mindim = L_MIN(w, h);
2919  if (mindim < 20 || nbins > mindim)
2920  return (PIX *)ERROR_PTR("pix too small and/or too many bins",
2921  __func__, NULL);
2922 
2923  /* Remove colormap if it exists */
2924  if (cmap)
2926  else
2927  pix1 = pixClone(pixs);
2928  pixGetDimensions(pixs, &w, &h, NULL);
2929 
2930  pixd = NULL;
2931  boxa = makeMosaicStrips(w, h, direction, size);
2932  pixa = pixClipRectangles(pix1, boxa);
2933  nstrips = pixaGetCount(pixa);
2934  if (direction == L_SCAN_HORIZONTAL) {
2935  pixd = pixCreate(nstrips, nbins, 32);
2936  for (i = 0; i < nstrips; i++) {
2937  pix2 = pixaGetPix(pixa, i, L_CLONE);
2938  pixGetRankColorArray(pix2, nbins, type, 1, &array, NULL, 0);
2939  if (array) {
2940  for (j = 0; j < nbins; j++)
2941  pixSetPixel(pixd, i, j, array[j]);
2942  LEPT_FREE(array);
2943  }
2944  pixDestroy(&pix2);
2945  }
2946  } else { /* L_SCAN_VERTICAL */
2947  pixd = pixCreate(nbins, nstrips, 32);
2948  for (i = 0; i < nstrips; i++) {
2949  pix2 = pixaGetPix(pixa, i, L_CLONE);
2950  pixGetRankColorArray(pix2, nbins, type, 1, &array, NULL, 0);
2951  if (array) {
2952  for (j = 0; j < nbins; j++)
2953  pixSetPixel(pixd, j, i, array[j]);
2954  LEPT_FREE(array);
2955  }
2956  pixDestroy(&pix2);
2957  }
2958  }
2959  pixDestroy(&pix1);
2960  boxaDestroy(&boxa);
2961  pixaDestroy(&pixa);
2962  return pixd;
2963 }
2964 
2965 
2966 
2967 /*-------------------------------------------------------------*
2968  * Pixelwise aligned statistics *
2969  *-------------------------------------------------------------*/
2991 PIX *
2993  l_int32 type,
2994  l_int32 nbins,
2995  l_int32 thresh)
2996 {
2997 l_int32 j, n, w, h, d;
2998 l_float32 *colvect;
2999 PIX *pixt, *pixd;
3000 
3001  if (!pixa)
3002  return (PIX *)ERROR_PTR("pixa not defined", __func__, NULL);
3003  if (type != L_MEAN_ABSVAL && type != L_MEDIAN_VAL &&
3004  type != L_MODE_VAL && type != L_MODE_COUNT)
3005  return (PIX *)ERROR_PTR("invalid type", __func__, NULL);
3006  n = pixaGetCount(pixa);
3007  if (n == 0)
3008  return (PIX *)ERROR_PTR("no pix in pixa", __func__, NULL);
3009  pixaGetPixDimensions(pixa, 0, &w, &h, &d);
3010  if (d != 8)
3011  return (PIX *)ERROR_PTR("pix not 8 bpp", __func__, NULL);
3012 
3013  pixd = pixCreate(w, h, 8);
3014  pixt = pixCreate(n, h, 8);
3015  colvect = (l_float32 *)LEPT_CALLOC(h, sizeof(l_float32));
3016  for (j = 0; j < w; j++) {
3017  pixaExtractColumnFromEachPix(pixa, j, pixt);
3018  pixGetRowStats(pixt, type, nbins, thresh, colvect);
3019  pixSetPixelColumn(pixd, j, colvect);
3020  }
3021 
3022  LEPT_FREE(colvect);
3023  pixDestroy(&pixt);
3024  return pixd;
3025 }
3026 
3027 
3036 l_ok
3038  l_int32 col,
3039  PIX *pixd)
3040 {
3041 l_int32 i, k, n, w, h, ht, val, wplt, wpld;
3042 l_uint32 *datad, *datat;
3043 PIX *pixt;
3044 
3045  if (!pixa)
3046  return ERROR_INT("pixa not defined", __func__, 1);
3047  if (!pixd || pixGetDepth(pixd) != 8)
3048  return ERROR_INT("pixd not defined or not 8 bpp", __func__, 1);
3049  n = pixaGetCount(pixa);
3050  pixGetDimensions(pixd, &w, &h, NULL);
3051  if (n != w)
3052  return ERROR_INT("pix width != n", __func__, 1);
3053  pixt = pixaGetPix(pixa, 0, L_CLONE);
3054  wplt = pixGetWpl(pixt);
3055  pixGetDimensions(pixt, NULL, &ht, NULL);
3056  pixDestroy(&pixt);
3057  if (h != ht)
3058  return ERROR_INT("pixd height != column height", __func__, 1);
3059 
3060  datad = pixGetData(pixd);
3061  wpld = pixGetWpl(pixd);
3062  for (k = 0; k < n; k++) {
3063  pixt = pixaGetPix(pixa, k, L_CLONE);
3064  datat = pixGetData(pixt);
3065  for (i = 0; i < h; i++) {
3066  val = GET_DATA_BYTE(datat, col);
3067  SET_DATA_BYTE(datad + i * wpld, k, val);
3068  datat += wplt;
3069  }
3070  pixDestroy(&pixt);
3071  }
3072 
3073  return 0;
3074 }
3075 
3076 
3109 l_ok
3111  l_int32 type,
3112  l_int32 nbins,
3113  l_int32 thresh,
3114  l_float32 *colvect)
3115 {
3116 l_int32 i, j, k, w, h, val, wpls, sum, target, max, modeval;
3117 l_int32 *histo, *gray2bin, *bin2gray;
3118 l_uint32 *lines, *datas;
3119 
3120  if (!pixs || pixGetDepth(pixs) != 8)
3121  return ERROR_INT("pixs not defined or not 8 bpp", __func__, 1);
3122  if (!colvect)
3123  return ERROR_INT("colvect not defined", __func__, 1);
3124  if (type != L_MEAN_ABSVAL && type != L_MEDIAN_VAL &&
3125  type != L_MODE_VAL && type != L_MODE_COUNT)
3126  return ERROR_INT("invalid type", __func__, 1);
3127  if (type != L_MEAN_ABSVAL && (nbins < 1 || nbins > 256))
3128  return ERROR_INT("invalid nbins", __func__, 1);
3129  pixGetDimensions(pixs, &w, &h, NULL);
3130 
3131  datas = pixGetData(pixs);
3132  wpls = pixGetWpl(pixs);
3133  if (type == L_MEAN_ABSVAL) {
3134  for (i = 0; i < h; i++) {
3135  sum = 0;
3136  lines = datas + i * wpls;
3137  for (j = 0; j < w; j++)
3138  sum += GET_DATA_BYTE(lines, j);
3139  colvect[i] = (l_float32)sum / (l_float32)w;
3140  }
3141  return 0;
3142  }
3143 
3144  /* We need a histogram; binwidth ~ 256 / nbins */
3145  histo = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3146  gray2bin = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
3147  bin2gray = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3148  for (i = 0; i < 256; i++) /* gray value --> histo bin */
3149  gray2bin[i] = (i * nbins) / 256;
3150  for (i = 0; i < nbins; i++) /* histo bin --> gray value */
3151  bin2gray[i] = (i * 256 + 128) / nbins;
3152 
3153  for (i = 0; i < h; i++) {
3154  lines = datas + i * wpls;
3155  for (k = 0; k < nbins; k++)
3156  histo[k] = 0;
3157  for (j = 0; j < w; j++) {
3158  val = GET_DATA_BYTE(lines, j);
3159  histo[gray2bin[val]]++;
3160  }
3161 
3162  if (type == L_MEDIAN_VAL) {
3163  sum = 0;
3164  target = (w + 1) / 2;
3165  for (k = 0; k < nbins; k++) {
3166  sum += histo[k];
3167  if (sum >= target) {
3168  colvect[i] = bin2gray[k];
3169  break;
3170  }
3171  }
3172  } else if (type == L_MODE_VAL) {
3173  max = 0;
3174  modeval = 0;
3175  for (k = 0; k < nbins; k++) {
3176  if (histo[k] > max) {
3177  max = histo[k];
3178  modeval = k;
3179  }
3180  }
3181  if (max < thresh)
3182  colvect[i] = 0;
3183  else
3184  colvect[i] = bin2gray[modeval];
3185  } else { /* type == L_MODE_COUNT */
3186  max = 0;
3187  for (k = 0; k < nbins; k++) {
3188  if (histo[k] > max)
3189  max = histo[k];
3190  }
3191  colvect[i] = max;
3192  }
3193  }
3194 
3195  LEPT_FREE(histo);
3196  LEPT_FREE(gray2bin);
3197  LEPT_FREE(bin2gray);
3198  return 0;
3199 }
3200 
3201 
3229 l_ok
3231  l_int32 type,
3232  l_int32 nbins,
3233  l_int32 thresh,
3234  l_float32 *rowvect)
3235 {
3236 l_int32 i, j, k, w, h, val, wpls, sum, target, max, modeval;
3237 l_int32 *histo, *gray2bin, *bin2gray;
3238 l_uint32 *datas;
3239 
3240  if (!pixs || pixGetDepth(pixs) != 8)
3241  return ERROR_INT("pixs not defined or not 8 bpp", __func__, 1);
3242  if (!rowvect)
3243  return ERROR_INT("rowvect not defined", __func__, 1);
3244  if (type != L_MEAN_ABSVAL && type != L_MEDIAN_VAL &&
3245  type != L_MODE_VAL && type != L_MODE_COUNT)
3246  return ERROR_INT("invalid type", __func__, 1);
3247  if (type != L_MEAN_ABSVAL && (nbins < 1 || nbins > 256))
3248  return ERROR_INT("invalid nbins", __func__, 1);
3249  pixGetDimensions(pixs, &w, &h, NULL);
3250 
3251  datas = pixGetData(pixs);
3252  wpls = pixGetWpl(pixs);
3253  if (type == L_MEAN_ABSVAL) {
3254  for (j = 0; j < w; j++) {
3255  sum = 0;
3256  for (i = 0; i < h; i++)
3257  sum += GET_DATA_BYTE(datas + i * wpls, j);
3258  rowvect[j] = (l_float32)sum / (l_float32)h;
3259  }
3260  return 0;
3261  }
3262 
3263  /* We need a histogram; binwidth ~ 256 / nbins */
3264  histo = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3265  gray2bin = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
3266  bin2gray = (l_int32 *)LEPT_CALLOC(nbins, sizeof(l_int32));
3267  for (i = 0; i < 256; i++) /* gray value --> histo bin */
3268  gray2bin[i] = (i * nbins) / 256;
3269  for (i = 0; i < nbins; i++) /* histo bin --> gray value */
3270  bin2gray[i] = (i * 256 + 128) / nbins;
3271 
3272  for (j = 0; j < w; j++) {
3273  for (i = 0; i < h; i++) {
3274  val = GET_DATA_BYTE(datas + i * wpls, j);
3275  histo[gray2bin[val]]++;
3276  }
3277 
3278  if (type == L_MEDIAN_VAL) {
3279  sum = 0;
3280  target = (h + 1) / 2;
3281  for (k = 0; k < nbins; k++) {
3282  sum += histo[k];
3283  if (sum >= target) {
3284  rowvect[j] = bin2gray[k];
3285  break;
3286  }
3287  }
3288  } else if (type == L_MODE_VAL) {
3289  max = 0;
3290  modeval = 0;
3291  for (k = 0; k < nbins; k++) {
3292  if (histo[k] > max) {
3293  max = histo[k];
3294  modeval = k;
3295  }
3296  }
3297  if (max < thresh)
3298  rowvect[j] = 0;
3299  else
3300  rowvect[j] = bin2gray[modeval];
3301  } else { /* type == L_MODE_COUNT */
3302  max = 0;
3303  for (k = 0; k < nbins; k++) {
3304  if (histo[k] > max)
3305  max = histo[k];
3306  }
3307  rowvect[j] = max;
3308  }
3309  for (k = 0; k < nbins; k++)
3310  histo[k] = 0;
3311  }
3312 
3313  LEPT_FREE(histo);
3314  LEPT_FREE(gray2bin);
3315  LEPT_FREE(bin2gray);
3316  return 0;
3317 }
3318 
3319 
3328 l_ok
3330  l_int32 col,
3331  l_float32 *colvect)
3332 {
3333 l_int32 i, w, h, wpl;
3334 l_uint32 *data;
3335 
3336  if (!pix || pixGetDepth(pix) != 8)
3337  return ERROR_INT("pix not defined or not 8 bpp", __func__, 1);
3338  if (!colvect)
3339  return ERROR_INT("colvect not defined", __func__, 1);
3340  pixGetDimensions(pix, &w, &h, NULL);
3341  if (col < 0 || col > w)
3342  return ERROR_INT("invalid col", __func__, 1);
3343 
3344  data = pixGetData(pix);
3345  wpl = pixGetWpl(pix);
3346  for (i = 0; i < h; i++)
3347  SET_DATA_BYTE(data + i * wpl, col, (l_int32)colvect[i]);
3348 
3349  return 0;
3350 }
3351 
3352 
3353 /*-------------------------------------------------------------*
3354  * Foreground/background estimation *
3355  *-------------------------------------------------------------*/
3366 l_ok
3368  l_int32 factor,
3369  l_int32 thresh,
3370  l_int32 *pfgval,
3371  l_int32 *pbgval)
3372 {
3373 l_float32 fval;
3374 PIX *pixg, *pixm;
3375 
3376  if (pfgval) *pfgval = 0;
3377  if (pbgval) *pbgval = 0;
3378  if (!pfgval && !pbgval)
3379  return ERROR_INT("no data requested", __func__, 1);
3380  if (!pixs)
3381  return ERROR_INT("pixs not defined", __func__, 1);
3382 
3383  /* Generate a subsampled 8 bpp version and a mask over the fg */
3384  pixg = pixConvertTo8BySampling(pixs, factor, 0);
3385  pixm = pixThresholdToBinary(pixg, thresh);
3386 
3387  if (pfgval) {
3388  pixGetAverageMasked(pixg, pixm, 0, 0, 1, L_MEAN_ABSVAL, &fval);
3389  *pfgval = (l_int32)(fval + 0.5);
3390  }
3391 
3392  if (pbgval) {
3393  pixInvert(pixm, pixm);
3394  pixGetAverageMasked(pixg, pixm, 0, 0, 1, L_MEAN_ABSVAL, &fval);
3395  *pbgval = (l_int32)(fval + 0.5);
3396  }
3397 
3398  pixDestroy(&pixg);
3399  pixDestroy(&pixm);
3400  return 0;
3401 }
3402 
3403 
3423 l_ok
3425  l_float32 scorefract,
3426  l_int32 factor,
3427  l_int32 *pthresh,
3428  l_int32 *pfgval,
3429  l_int32 *pbgval,
3430  PIX **ppixdb)
3431 {
3432 char buf[256];
3433 l_int32 thresh;
3434 l_float32 avefg, avebg, maxnum;
3435 GPLOT *gplot;
3436 NUMA *na, *nascore, *nax, *nay;
3437 PIX *pixg;
3438 
3439  if (pthresh) *pthresh = 0;
3440  if (pfgval) *pfgval = 0;
3441  if (pbgval) *pbgval = 0;
3442  if (ppixdb) *ppixdb = NULL;
3443  if (!pthresh && !pfgval && !pbgval)
3444  return ERROR_INT("no data requested", __func__, 1);
3445  if (!pixs)
3446  return ERROR_INT("pixs not defined", __func__, 1);
3447 
3448  /* Generate a subsampled 8 bpp version */
3449  pixg = pixConvertTo8BySampling(pixs, factor, 0);
3450 
3451  /* Make the fg/bg estimates */
3452  na = pixGetGrayHistogram(pixg, 1);
3453  if (ppixdb) {
3454  numaSplitDistribution(na, scorefract, &thresh, &avefg, &avebg,
3455  NULL, NULL, &nascore);
3456  numaDestroy(&nascore);
3457  } else {
3458  numaSplitDistribution(na, scorefract, &thresh, &avefg, &avebg,
3459  NULL, NULL, NULL);
3460  }
3461 
3462  if (pthresh) *pthresh = thresh;
3463  if (pfgval) *pfgval = (l_int32)(avefg + 0.5);
3464  if (pbgval) *pbgval = (l_int32)(avebg + 0.5);
3465 
3466  if (ppixdb) {
3467  lept_mkdir("lept/redout");
3468  gplot = gplotCreate("/tmp/lept/redout/histplot", GPLOT_PNG, "Histogram",
3469  "Grayscale value", "Number of pixels");
3470  gplotAddPlot(gplot, NULL, na, GPLOT_LINES, NULL);
3471  nax = numaMakeConstant(thresh, 2);
3472  numaGetMax(na, &maxnum, NULL);
3473  nay = numaMakeConstant(0, 2);
3474  numaReplaceNumber(nay, 1, (l_int32)(0.5 * maxnum));
3475  snprintf(buf, sizeof(buf), "score fract = %3.1f", scorefract);
3476  gplotAddPlot(gplot, nax, nay, GPLOT_LINES, buf);
3477  *ppixdb = gplotMakeOutputPix(gplot);
3478  gplotDestroy(&gplot);
3479  numaDestroy(&nax);
3480  numaDestroy(&nay);
3481  }
3482 
3483  pixDestroy(&pixg);
3484  numaDestroy(&na);
3485  return 0;
3486 }
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:145
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:168
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:118
l_ok boxGetGeometry(const BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:301
void boxaDestroy(BOXA **pboxa)
boxaDestroy()
Definition: boxbasic.c:519
l_ok boxClipToRectangleParams(BOX *box, l_int32 w, l_int32 h, l_int32 *pxstart, l_int32 *pystart, l_int32 *pxend, l_int32 *pyend, l_int32 *pbw, l_int32 *pbh)
boxClipToRectangleParams()
Definition: boxfunc1.c:1734
BOXA * makeMosaicStrips(l_int32 w, l_int32 h, l_int32 direction, l_int32 size)
makeMosaicStrips()
Definition: boxfunc3.c:1285
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:789
l_ok pixcmapGetRangeValues(PIXCMAP *cmap, l_int32 select, l_int32 *pminval, l_int32 *pmaxval, l_int32 *pminindex, l_int32 *pmaxindex)
pixcmapGetRangeValues()
Definition: colormap.c:1453
l_int32 l_dnaaGetDnaCount(L_DNAA *daa, l_int32 index)
l_dnaaGetDnaCount()
Definition: dnabasic.c:1412
L_DNAA * l_dnaaCreateFull(l_int32 nptr, l_int32 n)
l_dnaaCreateFull()
Definition: dnabasic.c:1218
l_ok l_dnaaAddNumber(L_DNAA *daa, l_int32 index, l_float64 val)
l_dnaaAddNumber()
Definition: dnabasic.c:1561
l_int32 l_dnaaGetNumberCount(L_DNAA *daa)
l_dnaaGetNumberCount()
Definition: dnabasic.c:1431
l_ok l_dnaaGetValue(L_DNAA *daa, l_int32 i, l_int32 j, l_float64 *pval)
l_dnaaGetValue()
Definition: dnabasic.c:1523
void l_dnaDestroy(L_DNA **pda)
l_dnaDestroy()
Definition: dnabasic.c:323
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:603
void l_dnaaDestroy(L_DNAA **pdaa)
l_dnaaDestroy()
Definition: dnabasic.c:1281
l_ok l_dnaRemoveDupsByHmap(L_DNA *das, L_DNA **pdad, L_HASHMAP **phmap)
l_dnaRemoveDupsByHmap()
Definition: dnafunc1.c:545
L_DNA * pixConvertDataToDna(PIX *pix)
pixConvertDataToDna()
Definition: dnafunc1.c:288
l_ok gplotAddPlot(GPLOT *gplot, NUMA *nax, NUMA *nay, l_int32 plotstyle, const char *plotlabel)
gplotAddPlot()
Definition: gplot.c:316
GPLOT * gplotCreate(const char *rootname, l_int32 outformat, const char *title, const char *xlabel, const char *ylabel)
gplotCreate()
Definition: gplot.c:187
PIX * gplotMakeOutputPix(GPLOT *gplot)
gplotMakeOutputPix()
Definition: gplot.c:423
void gplotDestroy(GPLOT **pgplot)
gplotDestroy()
Definition: gplot.c:253
PIX * gplotSimplePix1(NUMA *na, const char *title)
gplotSimplePix1()
Definition: gplot.c:754
PIX * pixThresholdToBinary(PIX *pixs, l_int32 thresh)
pixThresholdToBinary()
Definition: grayquant.c:443
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:460
l_ok numaReplaceNumber(NUMA *na, l_int32 index, l_float32 val)
numaReplaceNumber()
Definition: numabasic.c:601
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:193
l_ok numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition: numabasic.c:655
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:357
NUMAA * numaaCreate(l_int32 n)
numaaCreate()
Definition: numabasic.c:1302
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:720
l_ok numaaAddNuma(NUMAA *naa, NUMA *na, l_int32 copyflag)
numaaAddNuma()
Definition: numabasic.c:1435
NUMA * numaCreateFromFArray(l_float32 *farray, l_int32 size, l_int32 copyflag)
numaCreateFromFArray()
Definition: numabasic.c:266
l_float32 * numaGetFArray(NUMA *na, l_int32 copyflag)
numaGetFArray()
Definition: numabasic.c:850
NUMA * numaMakeConstant(l_float32 val, l_int32 size)
numaMakeConstant()
Definition: numafunc1.c:820
l_ok numaGetMax(NUMA *na, l_float32 *pmaxval, l_int32 *pimaxloc)
numaGetMax()
Definition: numafunc1.c:485
l_ok numaDiscretizeHistoInBins(NUMA *na, l_int32 nbins, NUMA **pnabinval, NUMA **pnarank)
numaDiscretizeHistoInBins()
Definition: numafunc2.c:1735
l_ok numaSplitDistribution(NUMA *na, l_float32 scorefract, l_int32 *psplitindex, l_float32 *pave1, l_float32 *pave2, l_float32 *pnum1, l_float32 *pnum2, NUMA **pnascore)
numaSplitDistribution()
Definition: numafunc2.c:1966
l_ok numaHistogramGetValFromRank(NUMA *na, l_float32 rank, l_float32 *prval)
numaHistogramGetValFromRank()
Definition: numafunc2.c:1590
NUMA * numaGetUniformBinSizes(l_int32 ntotal, l_int32 nbins)
numaGetUniformBinSizes()
Definition: numafunc2.c:1890
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1642
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 * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:582
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2464
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:263
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1773
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
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:929
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition: pix2.c:2581
l_ok pixZero(PIX *pix, l_int32 *pempty)
pixZero()
Definition: pix3.c:1777
PIX * pixInvert(PIX *pixd, PIX *pixs)
pixInvert()
Definition: pix3.c:1481
l_ok pixCountPixels(PIX *pixs, l_int32 *pcount, l_int32 *tab8)
pixCountPixels()
Definition: pix3.c:1893
l_ok pixCountRGBColorsByHash(PIX *pixs, l_int32 *pncolors)
pixCountRGBColorsByHash()
Definition: pix4.c:826
l_ok pixGetAverageMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_int32 type, l_float32 *pval)
pixGetAverageMasked()
Definition: pix4.c:1488
NUMA * pixGetGrayHistogramInRect(PIX *pixs, BOX *box, l_int32 factor)
pixGetGrayHistogramInRect()
Definition: pix4.c:287
l_ok pixGetColorHistogram(PIX *pixs, l_int32 factor, NUMA **pnar, NUMA **pnag, NUMA **pnab)
pixGetColorHistogram()
Definition: pix4.c:408
PIX * pixDisplayColorArray(l_uint32 *carray, l_int32 ncolors, l_int32 side, l_int32 ncols, l_int32 fontsize)
pixDisplayColorArray()
Definition: pix4.c:2813
PIX * pixRankBinByStrip(PIX *pixs, l_int32 direction, l_int32 size, l_int32 nbins, l_int32 type)
pixRankBinByStrip()
Definition: pix4.c:2887
l_ok pixGetRankValueMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_float32 rank, l_float32 *pval, NUMA **pna)
pixGetRankValueMasked()
Definition: pix4.c:1138
L_AMAP * pixGetColorAmapHistogram(PIX *pixs, l_int32 factor)
pixGetColorAmapHistogram()
Definition: pix4.c:894
l_ok pixGetBinnedComponentRange(PIX *pixs, l_int32 nbins, l_int32 factor, l_int32 color, l_int32 *pminval, l_int32 *pmaxval, l_uint32 **pcarray, l_int32 fontsize)
pixGetBinnedComponentRange()
Definition: pix4.c:2445
NUMA * pixGetGrayHistogram(PIX *pixs, l_int32 factor)
pixGetGrayHistogram()
Definition: pix4.c:115
NUMA * pixGetCmapHistogramInRect(PIX *pixs, BOX *box, l_int32 factor)
pixGetCmapHistogramInRect()
Definition: pix4.c:762
NUMA * pixGetGrayHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor)
pixGetGrayHistogramMasked()
Definition: pix4.c:209
l_ok pixGetColorHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, NUMA **pnar, NUMA **pnag, NUMA **pnab)
pixGetColorHistogramMasked()
Definition: pix4.c:508
l_ok pixGetMaxColorIndex(PIX *pixs, l_int32 *pmaxindex)
pixGetMaxColorIndex()
Definition: pix4.c:2373
l_ok pixGetRangeValues(PIX *pixs, l_int32 factor, l_int32 color, l_int32 *pminval, l_int32 *pmaxval)
pixGetRangeValues()
Definition: pix4.c:2089
l_ok pixGetRankValueMaskedRGB(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_float32 rank, l_float32 *prval, l_float32 *pgval, l_float32 *pbval)
pixGetRankValueMaskedRGB()
Definition: pix4.c:1048
l_ok pixSplitDistributionFgBg(PIX *pixs, l_float32 scorefract, l_int32 factor, l_int32 *pthresh, l_int32 *pfgval, l_int32 *pbgval, PIX **ppixdb)
pixSplitDistributionFgBg()
Definition: pix4.c:3424
l_ok pixGetRowStats(PIX *pixs, l_int32 type, l_int32 nbins, l_int32 thresh, l_float32 *colvect)
pixGetRowStats()
Definition: pix4.c:3110
NUMA * pixGetCmapHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor)
pixGetCmapHistogramMasked()
Definition: pix4.c:684
l_ok pixaExtractColumnFromEachPix(PIXA *pixa, l_int32 col, PIX *pixd)
pixaExtractColumnFromEachPix()
Definition: pix4.c:3037
l_ok pixGetRankColorArray(PIX *pixs, l_int32 nbins, l_int32 type, l_int32 factor, l_uint32 **pcarray, PIXA *pixadb, l_int32 fontsize)
pixGetRankColorArray()
Definition: pix4.c:2542
l_ok pixGetAverageTiledRGB(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 type, PIX **ppixr, PIX **ppixg, PIX **ppixb)
pixGetAverageTiledRGB()
Definition: pix4.c:1610
PIX * pixGetAverageTiled(PIX *pixs, l_int32 sx, l_int32 sy, l_int32 type)
pixGetAverageTiled()
Definition: pix4.c:1685
l_int32 pixColumnStats(PIX *pixs, BOX *box, NUMA **pnamean, NUMA **pnamedian, NUMA **pnamode, NUMA **pnamodecount, NUMA **pnavar, NUMA **pnarootvar)
pixColumnStats()
Definition: pix4.c:1944
l_ok pixGetPixelStats(PIX *pixs, l_int32 factor, l_int32 type, l_uint32 *pvalue)
pixGetPixelStats()
Definition: pix4.c:1323
l_ok pixCountRGBColors(PIX *pixs, l_int32 factor, l_int32 *pncolors)
pixCountRGBColors()
Definition: pix4.c:860
l_ok pixGetBinnedColor(PIX *pixs, PIX *pixg, l_int32 factor, l_int32 nbins, l_uint32 **pcarray, PIXA *pixadb)
pixGetBinnedColor()
Definition: pix4.c:2645
l_ok pixGetExtremeValue(PIX *pixs, l_int32 factor, l_int32 type, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *pgrayval)
pixGetExtremeValue()
Definition: pix4.c:2165
NUMAA * pixGetGrayHistogramTiled(PIX *pixs, l_int32 factor, l_int32 nx, l_int32 ny)
pixGetGrayHistogramTiled()
Definition: pix4.c:353
l_ok pixSetPixelColumn(PIX *pix, l_int32 col, l_float32 *colvect)
pixSetPixelColumn()
Definition: pix4.c:3329
l_ok pixThresholdForFgBg(PIX *pixs, l_int32 factor, l_int32 thresh, l_int32 *pfgval, l_int32 *pbgval)
pixThresholdForFgBg()
Definition: pix4.c:3367
l_ok pixGetRankValue(PIX *pixs, l_int32 factor, l_float32 rank, l_uint32 *pvalue)
pixGetRankValue()
Definition: pix4.c:980
l_int32 pixRowStats(PIX *pixs, BOX *box, NUMA **pnamean, NUMA **pnamedian, NUMA **pnamode, NUMA **pnamodecount, NUMA **pnavar, NUMA **pnarootvar)
pixRowStats()
Definition: pix4.c:1786
NUMA * pixGetCmapHistogram(PIX *pixs, l_int32 factor)
pixGetCmapHistogram()
Definition: pix4.c:621
PIX * pixaGetAlignedStats(PIXA *pixa, l_int32 type, l_int32 nbins, l_int32 thresh)
pixaGetAlignedStats()
Definition: pix4.c:2992
l_ok pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2300
l_ok pixGetAverageMaskedRGB(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_int32 type, l_float32 *prval, l_float32 *pgval, l_float32 *pbval)
pixGetAverageMaskedRGB()
Definition: pix4.c:1388
l_int32 amapGetCountForColor(L_AMAP *amap, l_uint32 val)
amapGetCountForColor()
Definition: pix4.c:943
l_ok pixGetPixelAverage(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor, l_uint32 *pval)
pixGetPixelAverage()
Definition: pix4.c:1207
l_ok pixGetColumnStats(PIX *pixs, l_int32 type, l_int32 nbins, l_int32 thresh, l_float32 *rowvect)
pixGetColumnStats()
Definition: pix4.c:3230
PIXA * pixClipRectangles(PIX *pixs, BOXA *boxa)
pixClipRectangles()
Definition: pix5.c:930
@ COLOR_BLUE
Definition: pix.h:330
@ COLOR_RED
Definition: pix.h:328
@ COLOR_GREEN
Definition: pix.h:329
@ L_SELECT_MAX
Definition: pix.h:619
@ L_SELECT_GREEN
Definition: pix.h:616
@ L_SELECT_SATURATION
Definition: pix.h:622
@ L_SELECT_BLUE
Definition: pix.h:617
@ L_SELECT_AVERAGE
Definition: pix.h:620
@ L_SELECT_MIN
Definition: pix.h:618
@ L_SELECT_HUE
Definition: pix.h:621
@ L_SELECT_RED
Definition: pix.h:615
@ REMOVE_CMAP_TO_FULL_COLOR
Definition: pix.h:382
@ REMOVE_CMAP_TO_GRAYSCALE
Definition: pix.h:381
@ REMOVE_CMAP_BASED_ON_SRC
Definition: pix.h:384
@ L_ADD_BELOW
Definition: pix.h:1003
@ L_CLONE
Definition: pix.h:506
@ L_NOCOPY
Definition: pix.h:503
@ L_INSERT
Definition: pix.h:504
@ L_SCAN_VERTICAL
Definition: pix.h:835
@ L_SCAN_HORIZONTAL
Definition: pix.h:834
@ L_MODE_VAL
Definition: pix.h:763
@ L_ROOT_MEAN_SQUARE
Definition: pix.h:765
@ L_MODE_COUNT
Definition: pix.h:764
@ L_MEAN_ABSVAL
Definition: pix.h:761
@ L_VARIANCE
Definition: pix.h:767
@ L_STANDARD_DEVIATION
Definition: pix.h:766
@ L_MEDIAN_VAL
Definition: pix.h:762
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:493
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:404
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
PIXA * pixaSplitPix(PIX *pixs, l_int32 nx, l_int32 ny, l_int32 borderwidth, l_uint32 bordercolor)
pixaSplitPix()
Definition: pixabasic.c:344
l_ok pixaGetPixDimensions(PIXA *pixa, l_int32 index, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixaGetPixDimensions()
Definition: pixabasic.c:680
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:629
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:647
PIX * pixaDisplayTiledInColumns(PIXA *pixas, l_int32 nx, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayTiledInColumns()
Definition: pixafunc2.c:912
PIX * pixConvertRGBToGrayGeneral(PIX *pixs, l_int32 type, l_float32 rwt, l_float32 gwt, l_float32 bwt)
pixConvertRGBToGrayGeneral()
Definition: pixconv.c:756
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:324
PIX * pixConvertTo8BySampling(PIX *pixs, l_int32 factor, l_int32 cmapflag)
pixConvertTo8BySampling()
Definition: pixconv.c:3124
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3055
PIX * pixScaleRGBToGrayFast(PIX *pixs, l_int32 factor, l_int32 color)
pixScaleRGBToGrayFast()
Definition: scale1.c:1448
PIX * pixScale(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScale()
Definition: scale1.c:250
PIX * pixScaleByIntSampling(PIX *pixs, l_int32 factor)
pixScaleByIntSampling()
Definition: scale1.c:1408
Definition: gplot.h:77
Definition: bmf.h:47
PIX * pixAddSingleTextblock(PIX *pixs, L_BMF *bmf, const char *textstr, l_uint32 val, l_int32 location, l_int32 *poverflow)
pixAddSingleTextblock()
Definition: textops.c:120
Definition: rbtree.h:62
l_int32 lept_roundftoi(l_float32 fval)
lept_roundftoi()
Definition: utils1.c:690
l_int32 lept_mkdir(const char *subdir)
lept_mkdir()
Definition: utils2.c:2138