Leptonica  1.82.0
Image processing and image analysis suite
graymorph.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 
27 
122 #ifdef HAVE_CONFIG_H
123 #include <config_auto.h>
124 #endif /* HAVE_CONFIG_H */
125 
126 #include "allheaders.h"
127 
128  /* Special static operations for 3x1, 1x3 and 3x3 structuring elements */
129 static PIX *pixErodeGray3h(PIX *pixs);
130 static PIX *pixErodeGray3v(PIX *pixs);
131 static PIX *pixDilateGray3h(PIX *pixs);
132 static PIX *pixDilateGray3v(PIX *pixs);
133 
134  /* Low-level gray morphological operations */
135 static void dilateGrayLow(l_uint32 *datad, l_int32 w, l_int32 h,
136  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
137  l_int32 size, l_int32 direction, l_uint8 *buffer,
138  l_uint8 *maxarray);
139 static void erodeGrayLow(l_uint32 *datad, l_int32 w, l_int32 h,
140  l_int32 wpld, l_uint32 *datas, l_int32 wpls,
141  l_int32 size, l_int32 direction, l_uint8 *buffer,
142  l_uint8 *minarray);
143 
144 /*-----------------------------------------------------------------*
145  * Top-level grayscale morphological operations *
146  *-----------------------------------------------------------------*/
161 PIX *
163  l_int32 hsize,
164  l_int32 vsize)
165 {
166 l_uint8 *buffer, *minarray;
167 l_int32 w, h, wplb, wplt;
168 l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
169 l_uint32 *datab, *datat;
170 PIX *pixb, *pixt, *pixd;
171 
172  PROCNAME("pixErodeGray");
173 
174  if (!pixs)
175  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
176  if (pixGetDepth(pixs) != 8)
177  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
178  if (hsize < 1 || vsize < 1)
179  return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL);
180  if ((hsize & 1) == 0 ) {
181  L_WARNING("horiz sel size must be odd; increasing by 1\n", procName);
182  hsize++;
183  }
184  if ((vsize & 1) == 0 ) {
185  L_WARNING("vert sel size must be odd; increasing by 1\n", procName);
186  vsize++;
187  }
188 
189  pixb = pixt = pixd = NULL;
190  buffer = minarray = NULL;
191 
192  if (hsize == 1 && vsize == 1)
193  return pixCopy(NULL, pixs);
194 
195  if (vsize == 1) { /* horizontal sel */
196  leftpix = (hsize + 1) / 2;
197  rightpix = (3 * hsize + 1) / 2;
198  toppix = 0;
199  bottompix = 0;
200  } else if (hsize == 1) { /* vertical sel */
201  leftpix = 0;
202  rightpix = 0;
203  toppix = (vsize + 1) / 2;
204  bottompix = (3 * vsize + 1) / 2;
205  } else {
206  leftpix = (hsize + 1) / 2;
207  rightpix = (3 * hsize + 1) / 2;
208  toppix = (vsize + 1) / 2;
209  bottompix = (3 * vsize + 1) / 2;
210  }
211 
212  pixb = pixAddBorderGeneral(pixs, leftpix, rightpix, toppix, bottompix, 255);
213  pixt = pixCreateTemplate(pixb);
214  if (!pixb || !pixt) {
215  L_ERROR("pixb and pixt not made\n", procName);
216  goto cleanup;
217  }
218 
219  pixGetDimensions(pixt, &w, &h, NULL);
220  datab = pixGetData(pixb);
221  datat = pixGetData(pixt);
222  wplb = pixGetWpl(pixb);
223  wplt = pixGetWpl(pixt);
224 
225  buffer = (l_uint8 *)LEPT_CALLOC(L_MAX(w, h), sizeof(l_uint8));
226  maxsize = L_MAX(hsize, vsize);
227  minarray = (l_uint8 *)LEPT_CALLOC(2 * maxsize, sizeof(l_uint8));
228  if (!buffer || !minarray) {
229  L_ERROR("buffer and minarray not made\n", procName);
230  goto cleanup;
231  }
232 
233  if (vsize == 1) {
234  erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
235  buffer, minarray);
236  } else if (hsize == 1) {
237  erodeGrayLow(datat, w, h, wplt, datab, wplb, vsize, L_VERT,
238  buffer, minarray);
239  } else {
240  erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
241  buffer, minarray);
242  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
243  PIX_SET);
244  erodeGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
245  buffer, minarray);
246  pixDestroy(&pixt);
247  pixt = pixClone(pixb);
248  }
249 
250  pixd = pixRemoveBorderGeneral(pixt, leftpix, rightpix, toppix, bottompix);
251  if (!pixd)
252  L_ERROR("pixd not made\n", procName);
253 
254 cleanup:
255  LEPT_FREE(buffer);
256  LEPT_FREE(minarray);
257  pixDestroy(&pixb);
258  pixDestroy(&pixt);
259  return pixd;
260 }
261 
262 
277 PIX *
279  l_int32 hsize,
280  l_int32 vsize)
281 {
282 l_uint8 *buffer, *maxarray;
283 l_int32 w, h, wplb, wplt;
284 l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
285 l_uint32 *datab, *datat;
286 PIX *pixb, *pixt, *pixd;
287 
288  PROCNAME("pixDilateGray");
289 
290  if (!pixs)
291  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
292  if (pixGetDepth(pixs) != 8)
293  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
294  if (hsize < 1 || vsize < 1)
295  return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL);
296  if ((hsize & 1) == 0 ) {
297  L_WARNING("horiz sel size must be odd; increasing by 1\n", procName);
298  hsize++;
299  }
300  if ((vsize & 1) == 0 ) {
301  L_WARNING("vert sel size must be odd; increasing by 1\n", procName);
302  vsize++;
303  }
304 
305  pixb = pixt = pixd = NULL;
306  buffer = maxarray = NULL;
307 
308  if (hsize == 1 && vsize == 1)
309  return pixCopy(NULL, pixs);
310 
311  if (vsize == 1) { /* horizontal sel */
312  leftpix = (hsize + 1) / 2;
313  rightpix = (3 * hsize + 1) / 2;
314  toppix = 0;
315  bottompix = 0;
316  } else if (hsize == 1) { /* vertical sel */
317  leftpix = 0;
318  rightpix = 0;
319  toppix = (vsize + 1) / 2;
320  bottompix = (3 * vsize + 1) / 2;
321  } else {
322  leftpix = (hsize + 1) / 2;
323  rightpix = (3 * hsize + 1) / 2;
324  toppix = (vsize + 1) / 2;
325  bottompix = (3 * vsize + 1) / 2;
326  }
327 
328  pixb = pixAddBorderGeneral(pixs, leftpix, rightpix, toppix, bottompix, 0);
329  pixt = pixCreateTemplate(pixb);
330  if (!pixb || !pixt) {
331  L_ERROR("pixb and pixt not made\n", procName);
332  goto cleanup;
333  }
334 
335  pixGetDimensions(pixt, &w, &h, NULL);
336  datab = pixGetData(pixb);
337  datat = pixGetData(pixt);
338  wplb = pixGetWpl(pixb);
339  wplt = pixGetWpl(pixt);
340 
341  buffer = (l_uint8 *)LEPT_CALLOC(L_MAX(w, h), sizeof(l_uint8));
342  maxsize = L_MAX(hsize, vsize);
343  maxarray = (l_uint8 *)LEPT_CALLOC(2 * maxsize, sizeof(l_uint8));
344  if (!buffer || !maxarray) {
345  L_ERROR("buffer and maxarray not made\n", procName);
346  goto cleanup;
347  }
348 
349  if (vsize == 1) {
350  dilateGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
351  buffer, maxarray);
352  } else if (hsize == 1) {
353  dilateGrayLow(datat, w, h, wplt, datab, wplb, vsize, L_VERT,
354  buffer, maxarray);
355  } else {
356  dilateGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
357  buffer, maxarray);
358  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
359  PIX_CLR);
360  dilateGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
361  buffer, maxarray);
362  pixDestroy(&pixt);
363  pixt = pixClone(pixb);
364  }
365 
366  pixd = pixRemoveBorderGeneral(pixt, leftpix, rightpix, toppix, bottompix);
367  if (!pixd)
368  L_ERROR("pixd not made\n", procName);
369 
370 cleanup:
371  LEPT_FREE(buffer);
372  LEPT_FREE(maxarray);
373  pixDestroy(&pixb);
374  pixDestroy(&pixt);
375  return pixd;
376 }
377 
378 
393 PIX *
395  l_int32 hsize,
396  l_int32 vsize)
397 {
398 l_uint8 *buffer;
399 l_uint8 *array; /* used to find either min or max in interval */
400 l_int32 w, h, wplb, wplt;
401 l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
402 l_uint32 *datab, *datat;
403 PIX *pixb, *pixt, *pixd;
404 
405  PROCNAME("pixOpenGray");
406 
407  if (!pixs)
408  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
409  if (pixGetDepth(pixs) != 8)
410  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
411  if (hsize < 1 || vsize < 1)
412  return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL);
413  if ((hsize & 1) == 0 ) {
414  L_WARNING("horiz sel size must be odd; increasing by 1\n", procName);
415  hsize++;
416  }
417  if ((vsize & 1) == 0 ) {
418  L_WARNING("vert sel size must be odd; increasing by 1\n", procName);
419  vsize++;
420  }
421 
422  pixb = pixt = pixd = NULL;
423  buffer = array = NULL;
424 
425  if (hsize == 1 && vsize == 1)
426  return pixCopy(NULL, pixs);
427 
428  if (vsize == 1) { /* horizontal sel */
429  leftpix = (hsize + 1) / 2;
430  rightpix = (3 * hsize + 1) / 2;
431  toppix = 0;
432  bottompix = 0;
433  } else if (hsize == 1) { /* vertical sel */
434  leftpix = 0;
435  rightpix = 0;
436  toppix = (vsize + 1) / 2;
437  bottompix = (3 * vsize + 1) / 2;
438  } else {
439  leftpix = (hsize + 1) / 2;
440  rightpix = (3 * hsize + 1) / 2;
441  toppix = (vsize + 1) / 2;
442  bottompix = (3 * vsize + 1) / 2;
443  }
444 
445  pixb = pixAddBorderGeneral(pixs, leftpix, rightpix, toppix, bottompix, 255);
446  pixt = pixCreateTemplate(pixb);
447  if (!pixb || !pixt) {
448  L_ERROR("pixb and pixt not made\n", procName);
449  goto cleanup;
450  }
451 
452  pixGetDimensions(pixt, &w, &h, NULL);
453  datab = pixGetData(pixb);
454  datat = pixGetData(pixt);
455  wplb = pixGetWpl(pixb);
456  wplt = pixGetWpl(pixt);
457 
458  buffer = (l_uint8 *)LEPT_CALLOC(L_MAX(w, h), sizeof(l_uint8));
459  maxsize = L_MAX(hsize, vsize);
460  array = (l_uint8 *)LEPT_CALLOC(2 * maxsize, sizeof(l_uint8));
461  if (!buffer || !array) {
462  L_ERROR("buffer and array not made\n", procName);
463  goto cleanup;
464  }
465 
466  if (vsize == 1) {
467  erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
468  buffer, array);
469  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
470  PIX_CLR);
471  dilateGrayLow(datab, w, h, wplb, datat, wplt, hsize, L_HORIZ,
472  buffer, array);
473  }
474  else if (hsize == 1) {
475  erodeGrayLow(datat, w, h, wplt, datab, wplb, vsize, L_VERT,
476  buffer, array);
477  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
478  PIX_CLR);
479  dilateGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
480  buffer, array);
481  } else {
482  erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
483  buffer, array);
484  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
485  PIX_SET);
486  erodeGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
487  buffer, array);
488  pixSetOrClearBorder(pixb, leftpix, rightpix, toppix, bottompix,
489  PIX_CLR);
490  dilateGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
491  buffer, array);
492  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
493  PIX_CLR);
494  dilateGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
495  buffer, array);
496  }
497 
498  pixd = pixRemoveBorderGeneral(pixb, leftpix, rightpix, toppix, bottompix);
499  if (!pixd)
500  L_ERROR("pixd not made\n", procName);
501 
502 cleanup:
503  LEPT_FREE(buffer);
504  LEPT_FREE(array);
505  pixDestroy(&pixb);
506  pixDestroy(&pixt);
507  return pixd;
508 }
509 
510 
525 PIX *
527  l_int32 hsize,
528  l_int32 vsize)
529 {
530 l_uint8 *buffer;
531 l_uint8 *array; /* used to find either min or max in interval */
532 l_int32 w, h, wplb, wplt;
533 l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
534 l_uint32 *datab, *datat;
535 PIX *pixb, *pixt, *pixd;
536 
537  PROCNAME("pixCloseGray");
538 
539  if (!pixs)
540  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
541  if (pixGetDepth(pixs) != 8)
542  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
543  if (hsize < 1 || vsize < 1)
544  return (PIX *)ERROR_PTR("hsize or vsize < 1", procName, NULL);
545  if ((hsize & 1) == 0 ) {
546  L_WARNING("horiz sel size must be odd; increasing by 1\n", procName);
547  hsize++;
548  }
549  if ((vsize & 1) == 0 ) {
550  L_WARNING("vert sel size must be odd; increasing by 1\n", procName);
551  vsize++;
552  }
553 
554  pixb = pixt = pixd = NULL;
555  buffer = array = NULL;
556 
557  if (hsize == 1 && vsize == 1)
558  return pixCopy(NULL, pixs);
559 
560  if (vsize == 1) { /* horizontal sel */
561  leftpix = (hsize + 1) / 2;
562  rightpix = (3 * hsize + 1) / 2;
563  toppix = 0;
564  bottompix = 0;
565  } else if (hsize == 1) { /* vertical sel */
566  leftpix = 0;
567  rightpix = 0;
568  toppix = (vsize + 1) / 2;
569  bottompix = (3 * vsize + 1) / 2;
570  } else {
571  leftpix = (hsize + 1) / 2;
572  rightpix = (3 * hsize + 1) / 2;
573  toppix = (vsize + 1) / 2;
574  bottompix = (3 * vsize + 1) / 2;
575  }
576 
577  pixb = pixAddBorderGeneral(pixs, leftpix, rightpix, toppix, bottompix, 0);
578  pixt = pixCreateTemplate(pixb);
579  if (!pixb || !pixt) {
580  L_ERROR("pixb and pixt not made\n", procName);
581  goto cleanup;
582  }
583 
584  pixGetDimensions(pixt, &w, &h, NULL);
585  datab = pixGetData(pixb);
586  datat = pixGetData(pixt);
587  wplb = pixGetWpl(pixb);
588  wplt = pixGetWpl(pixt);
589 
590  buffer = (l_uint8 *)LEPT_CALLOC(L_MAX(w, h), sizeof(l_uint8));
591  maxsize = L_MAX(hsize, vsize);
592  array = (l_uint8 *)LEPT_CALLOC(2 * maxsize, sizeof(l_uint8));
593  if (!buffer || !array) {
594  L_ERROR("buffer and array not made\n", procName);
595  goto cleanup;
596  }
597 
598  if (vsize == 1) {
599  dilateGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
600  buffer, array);
601  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
602  PIX_SET);
603  erodeGrayLow(datab, w, h, wplb, datat, wplt, hsize, L_HORIZ,
604  buffer, array);
605  } else if (hsize == 1) {
606  dilateGrayLow(datat, w, h, wplt, datab, wplb, vsize, L_VERT,
607  buffer, array);
608  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
609  PIX_SET);
610  erodeGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
611  buffer, array);
612  } else {
613  dilateGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
614  buffer, array);
615  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
616  PIX_CLR);
617  dilateGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
618  buffer, array);
619  pixSetOrClearBorder(pixb, leftpix, rightpix, toppix, bottompix,
620  PIX_SET);
621  erodeGrayLow(datat, w, h, wplt, datab, wplb, hsize, L_HORIZ,
622  buffer, array);
623  pixSetOrClearBorder(pixt, leftpix, rightpix, toppix, bottompix,
624  PIX_SET);
625  erodeGrayLow(datab, w, h, wplb, datat, wplt, vsize, L_VERT,
626  buffer, array);
627  }
628 
629  pixd = pixRemoveBorderGeneral(pixb, leftpix, rightpix, toppix, bottompix);
630  if (!pixd)
631  L_ERROR("pixd not made\n", procName);
632 
633 cleanup:
634  LEPT_FREE(buffer);
635  LEPT_FREE(array);
636  pixDestroy(&pixb);
637  pixDestroy(&pixt);
638  return pixd;
639 }
640 
641 
642 /*-----------------------------------------------------------------*
643  * Special operations for 1x3, 3x1 and 3x3 Sels *
644  *-----------------------------------------------------------------*/
664 PIX *
666  l_int32 hsize,
667  l_int32 vsize)
668 {
669 PIX *pixt, *pixb, *pixbd, *pixd;
670 
671  PROCNAME("pixErodeGray3");
672 
673  if (!pixs)
674  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
675  if (pixGetDepth(pixs) != 8)
676  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
677  if (pixGetColormap(pixs))
678  return (PIX *)ERROR_PTR("pix has colormap", procName, NULL);
679  if ((hsize != 1 && hsize != 3) ||
680  (vsize != 1 && vsize != 3))
681  return (PIX *)ERROR_PTR("invalid size: must be 1 or 3", procName, NULL);
682 
683  if (hsize == 1 && vsize == 1)
684  return pixCopy(NULL, pixs);
685 
686  pixb = pixAddBorderGeneral(pixs, 4, 8, 2, 8, 255);
687 
688  if (vsize == 1)
689  pixbd = pixErodeGray3h(pixb);
690  else if (hsize == 1)
691  pixbd = pixErodeGray3v(pixb);
692  else { /* vize == hsize == 3 */
693  pixt = pixErodeGray3h(pixb);
694  pixbd = pixErodeGray3v(pixt);
695  pixDestroy(&pixt);
696  }
697 
698  pixd = pixRemoveBorderGeneral(pixbd, 4, 8, 2, 8);
699  pixDestroy(&pixb);
700  pixDestroy(&pixbd);
701  return pixd;
702 }
703 
704 
717 static PIX *
719 {
720 l_uint32 *datas, *datad, *lines, *lined;
721 l_int32 w, h, wpl, i, j;
722 l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, minval;
723 PIX *pixd;
724 
725  PROCNAME("pixErodeGray3h");
726 
727  if (!pixs)
728  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
729  if (pixGetDepth(pixs) != 8)
730  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
731 
732  pixd = pixCreateTemplate(pixs);
733  pixGetDimensions(pixs, &w, &h, NULL);
734  datas = pixGetData(pixs);
735  datad = pixGetData(pixd);
736  wpl = pixGetWpl(pixs);
737  for (i = 0; i < h; i++) {
738  lines = datas + i * wpl;
739  lined = datad + i * wpl;
740  for (j = 1; j < w - 8; j += 8) {
741  val0 = GET_DATA_BYTE(lines, j - 1);
742  val1 = GET_DATA_BYTE(lines, j);
743  val2 = GET_DATA_BYTE(lines, j + 1);
744  val3 = GET_DATA_BYTE(lines, j + 2);
745  val4 = GET_DATA_BYTE(lines, j + 3);
746  val5 = GET_DATA_BYTE(lines, j + 4);
747  val6 = GET_DATA_BYTE(lines, j + 5);
748  val7 = GET_DATA_BYTE(lines, j + 6);
749  val8 = GET_DATA_BYTE(lines, j + 7);
750  val9 = GET_DATA_BYTE(lines, j + 8);
751  minval = L_MIN(val1, val2);
752  SET_DATA_BYTE(lined, j, L_MIN(val0, minval));
753  SET_DATA_BYTE(lined, j + 1, L_MIN(minval, val3));
754  minval = L_MIN(val3, val4);
755  SET_DATA_BYTE(lined, j + 2, L_MIN(val2, minval));
756  SET_DATA_BYTE(lined, j + 3, L_MIN(minval, val5));
757  minval = L_MIN(val5, val6);
758  SET_DATA_BYTE(lined, j + 4, L_MIN(val4, minval));
759  SET_DATA_BYTE(lined, j + 5, L_MIN(minval, val7));
760  minval = L_MIN(val7, val8);
761  SET_DATA_BYTE(lined, j + 6, L_MIN(val6, minval));
762  SET_DATA_BYTE(lined, j + 7, L_MIN(minval, val9));
763  }
764  }
765  return pixd;
766 }
767 
768 
784 static PIX *
786 {
787 l_uint32 *datas, *datad, *linesi, *linedi;
788 l_int32 w, h, wpl, i, j;
789 l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, minval;
790 PIX *pixd;
791 
792  PROCNAME("pixErodeGray3v");
793 
794  if (!pixs)
795  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
796  if (pixGetDepth(pixs) != 8)
797  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
798 
799  pixd = pixCreateTemplate(pixs);
800  pixGetDimensions(pixs, &w, &h, NULL);
801  datas = pixGetData(pixs);
802  datad = pixGetData(pixd);
803  wpl = pixGetWpl(pixs);
804  for (j = 0; j < w; j++) {
805  for (i = 1; i < h - 8; i += 8) {
806  linesi = datas + i * wpl;
807  linedi = datad + i * wpl;
808  val0 = GET_DATA_BYTE(linesi - wpl, j);
809  val1 = GET_DATA_BYTE(linesi, j);
810  val2 = GET_DATA_BYTE(linesi + wpl, j);
811  val3 = GET_DATA_BYTE(linesi + 2 * wpl, j);
812  val4 = GET_DATA_BYTE(linesi + 3 * wpl, j);
813  val5 = GET_DATA_BYTE(linesi + 4 * wpl, j);
814  val6 = GET_DATA_BYTE(linesi + 5 * wpl, j);
815  val7 = GET_DATA_BYTE(linesi + 6 * wpl, j);
816  val8 = GET_DATA_BYTE(linesi + 7 * wpl, j);
817  val9 = GET_DATA_BYTE(linesi + 8 * wpl, j);
818  minval = L_MIN(val1, val2);
819  SET_DATA_BYTE(linedi, j, L_MIN(val0, minval));
820  SET_DATA_BYTE(linedi + wpl, j, L_MIN(minval, val3));
821  minval = L_MIN(val3, val4);
822  SET_DATA_BYTE(linedi + 2 * wpl, j, L_MIN(val2, minval));
823  SET_DATA_BYTE(linedi + 3 * wpl, j, L_MIN(minval, val5));
824  minval = L_MIN(val5, val6);
825  SET_DATA_BYTE(linedi + 4 * wpl, j, L_MIN(val4, minval));
826  SET_DATA_BYTE(linedi + 5 * wpl, j, L_MIN(minval, val7));
827  minval = L_MIN(val7, val8);
828  SET_DATA_BYTE(linedi + 6 * wpl, j, L_MIN(val6, minval));
829  SET_DATA_BYTE(linedi + 7 * wpl, j, L_MIN(minval, val9));
830  }
831  }
832  return pixd;
833 }
834 
835 
850 PIX *
852  l_int32 hsize,
853  l_int32 vsize)
854 {
855 PIX *pixt, *pixb, *pixbd, *pixd;
856 
857  PROCNAME("pixDilateGray3");
858 
859  if (!pixs)
860  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
861  if (pixGetDepth(pixs) != 8)
862  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
863  if (pixGetColormap(pixs))
864  return (PIX *)ERROR_PTR("pix has colormap", procName, NULL);
865  if ((hsize != 1 && hsize != 3) ||
866  (vsize != 1 && vsize != 3))
867  return (PIX *)ERROR_PTR("invalid size: must be 1 or 3", procName, NULL);
868 
869  if (hsize == 1 && vsize == 1)
870  return pixCopy(NULL, pixs);
871 
872  pixb = pixAddBorderGeneral(pixs, 4, 8, 2, 8, 0);
873 
874  if (vsize == 1)
875  pixbd = pixDilateGray3h(pixb);
876  else if (hsize == 1)
877  pixbd = pixDilateGray3v(pixb);
878  else { /* vize == hsize == 3 */
879  pixt = pixDilateGray3h(pixb);
880  pixbd = pixDilateGray3v(pixt);
881  pixDestroy(&pixt);
882  }
883 
884  pixd = pixRemoveBorderGeneral(pixbd, 4, 8, 2, 8);
885  pixDestroy(&pixb);
886  pixDestroy(&pixbd);
887  return pixd;
888 }
889 
890 
903 static PIX *
905 {
906 l_uint32 *datas, *datad, *lines, *lined;
907 l_int32 w, h, wpl, i, j;
908 l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, maxval;
909 PIX *pixd;
910 
911  PROCNAME("pixDilateGray3h");
912 
913  if (!pixs)
914  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
915  if (pixGetDepth(pixs) != 8)
916  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
917 
918  pixd = pixCreateTemplate(pixs);
919  pixGetDimensions(pixs, &w, &h, NULL);
920  datas = pixGetData(pixs);
921  datad = pixGetData(pixd);
922  wpl = pixGetWpl(pixs);
923  for (i = 0; i < h; i++) {
924  lines = datas + i * wpl;
925  lined = datad + i * wpl;
926  for (j = 1; j < w - 8; j += 8) {
927  val0 = GET_DATA_BYTE(lines, j - 1);
928  val1 = GET_DATA_BYTE(lines, j);
929  val2 = GET_DATA_BYTE(lines, j + 1);
930  val3 = GET_DATA_BYTE(lines, j + 2);
931  val4 = GET_DATA_BYTE(lines, j + 3);
932  val5 = GET_DATA_BYTE(lines, j + 4);
933  val6 = GET_DATA_BYTE(lines, j + 5);
934  val7 = GET_DATA_BYTE(lines, j + 6);
935  val8 = GET_DATA_BYTE(lines, j + 7);
936  val9 = GET_DATA_BYTE(lines, j + 8);
937  maxval = L_MAX(val1, val2);
938  SET_DATA_BYTE(lined, j, L_MAX(val0, maxval));
939  SET_DATA_BYTE(lined, j + 1, L_MAX(maxval, val3));
940  maxval = L_MAX(val3, val4);
941  SET_DATA_BYTE(lined, j + 2, L_MAX(val2, maxval));
942  SET_DATA_BYTE(lined, j + 3, L_MAX(maxval, val5));
943  maxval = L_MAX(val5, val6);
944  SET_DATA_BYTE(lined, j + 4, L_MAX(val4, maxval));
945  SET_DATA_BYTE(lined, j + 5, L_MAX(maxval, val7));
946  maxval = L_MAX(val7, val8);
947  SET_DATA_BYTE(lined, j + 6, L_MAX(val6, maxval));
948  SET_DATA_BYTE(lined, j + 7, L_MAX(maxval, val9));
949  }
950  }
951  return pixd;
952 }
953 
954 
967 static PIX *
969 {
970 l_uint32 *datas, *datad, *linesi, *linedi;
971 l_int32 w, h, wpl, i, j;
972 l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, maxval;
973 PIX *pixd;
974 
975  PROCNAME("pixDilateGray3v");
976 
977  if (!pixs)
978  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
979  if (pixGetDepth(pixs) != 8)
980  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
981 
982  pixd = pixCreateTemplate(pixs);
983  pixGetDimensions(pixs, &w, &h, NULL);
984  datas = pixGetData(pixs);
985  datad = pixGetData(pixd);
986  wpl = pixGetWpl(pixs);
987  for (j = 0; j < w; j++) {
988  for (i = 1; i < h - 8; i += 8) {
989  linesi = datas + i * wpl;
990  linedi = datad + i * wpl;
991  val0 = GET_DATA_BYTE(linesi - wpl, j);
992  val1 = GET_DATA_BYTE(linesi, j);
993  val2 = GET_DATA_BYTE(linesi + wpl, j);
994  val3 = GET_DATA_BYTE(linesi + 2 * wpl, j);
995  val4 = GET_DATA_BYTE(linesi + 3 * wpl, j);
996  val5 = GET_DATA_BYTE(linesi + 4 * wpl, j);
997  val6 = GET_DATA_BYTE(linesi + 5 * wpl, j);
998  val7 = GET_DATA_BYTE(linesi + 6 * wpl, j);
999  val8 = GET_DATA_BYTE(linesi + 7 * wpl, j);
1000  val9 = GET_DATA_BYTE(linesi + 8 * wpl, j);
1001  maxval = L_MAX(val1, val2);
1002  SET_DATA_BYTE(linedi, j, L_MAX(val0, maxval));
1003  SET_DATA_BYTE(linedi + wpl, j, L_MAX(maxval, val3));
1004  maxval = L_MAX(val3, val4);
1005  SET_DATA_BYTE(linedi + 2 * wpl, j, L_MAX(val2, maxval));
1006  SET_DATA_BYTE(linedi + 3 * wpl, j, L_MAX(maxval, val5));
1007  maxval = L_MAX(val5, val6);
1008  SET_DATA_BYTE(linedi + 4 * wpl, j, L_MAX(val4, maxval));
1009  SET_DATA_BYTE(linedi + 5 * wpl, j, L_MAX(maxval, val7));
1010  maxval = L_MAX(val7, val8);
1011  SET_DATA_BYTE(linedi + 6 * wpl, j, L_MAX(val6, maxval));
1012  SET_DATA_BYTE(linedi + 7 * wpl, j, L_MAX(maxval, val9));
1013  }
1014  }
1015  return pixd;
1016 }
1017 
1018 
1035 PIX *
1037  l_int32 hsize,
1038  l_int32 vsize)
1039 {
1040 PIX *pixt, *pixb, *pixbd, *pixd;
1041 
1042  PROCNAME("pixOpenGray3");
1043 
1044  if (!pixs)
1045  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1046  if (pixGetDepth(pixs) != 8)
1047  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
1048  if (pixGetColormap(pixs))
1049  return (PIX *)ERROR_PTR("pix has colormap", procName, NULL);
1050  if ((hsize != 1 && hsize != 3) ||
1051  (vsize != 1 && vsize != 3))
1052  return (PIX *)ERROR_PTR("invalid size: must be 1 or 3", procName, NULL);
1053 
1054  if (hsize == 1 && vsize == 1)
1055  return pixCopy(NULL, pixs);
1056 
1057  pixb = pixAddBorderGeneral(pixs, 4, 8, 2, 8, 255); /* set to max */
1058 
1059  if (vsize == 1) {
1060  pixt = pixErodeGray3h(pixb);
1061  pixSetBorderVal(pixt, 4, 8, 2, 8, 0); /* set to min */
1062  pixbd = pixDilateGray3h(pixt);
1063  pixDestroy(&pixt);
1064  } else if (hsize == 1) {
1065  pixt = pixErodeGray3v(pixb);
1066  pixSetBorderVal(pixt, 4, 8, 2, 8, 0);
1067  pixbd = pixDilateGray3v(pixt);
1068  pixDestroy(&pixt);
1069  } else { /* vize == hsize == 3 */
1070  pixt = pixErodeGray3h(pixb);
1071  pixbd = pixErodeGray3v(pixt);
1072  pixDestroy(&pixt);
1073  pixSetBorderVal(pixbd, 4, 8, 2, 8, 0);
1074  pixt = pixDilateGray3h(pixbd);
1075  pixDestroy(&pixbd);
1076  pixbd = pixDilateGray3v(pixt);
1077  pixDestroy(&pixt);
1078  }
1079 
1080  pixd = pixRemoveBorderGeneral(pixbd, 4, 8, 2, 8);
1081  pixDestroy(&pixb);
1082  pixDestroy(&pixbd);
1083  return pixd;
1084 }
1085 
1086 
1101 PIX *
1103  l_int32 hsize,
1104  l_int32 vsize)
1105 {
1106 PIX *pixt, *pixb, *pixbd, *pixd;
1107 
1108  PROCNAME("pixCloseGray3");
1109 
1110  if (!pixs)
1111  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1112  if (pixGetDepth(pixs) != 8)
1113  return (PIX *)ERROR_PTR("pixs not 8 bpp", procName, NULL);
1114  if (pixGetColormap(pixs))
1115  return (PIX *)ERROR_PTR("pix has colormap", procName, NULL);
1116  if ((hsize != 1 && hsize != 3) ||
1117  (vsize != 1 && vsize != 3))
1118  return (PIX *)ERROR_PTR("invalid size: must be 1 or 3", procName, NULL);
1119 
1120  if (hsize == 1 && vsize == 1)
1121  return pixCopy(NULL, pixs);
1122 
1123  pixb = pixAddBorderGeneral(pixs, 4, 8, 2, 8, 0); /* set to min */
1124 
1125  if (vsize == 1) {
1126  pixt = pixDilateGray3h(pixb);
1127  pixSetBorderVal(pixt, 4, 8, 2, 8, 255); /* set to max */
1128  pixbd = pixErodeGray3h(pixt);
1129  pixDestroy(&pixt);
1130  } else if (hsize == 1) {
1131  pixt = pixDilateGray3v(pixb);
1132  pixSetBorderVal(pixt, 4, 8, 2, 8, 255);
1133  pixbd = pixErodeGray3v(pixt);
1134  pixDestroy(&pixt);
1135  } else { /* vize == hsize == 3 */
1136  pixt = pixDilateGray3h(pixb);
1137  pixbd = pixDilateGray3v(pixt);
1138  pixDestroy(&pixt);
1139  pixSetBorderVal(pixbd, 4, 8, 2, 8, 255);
1140  pixt = pixErodeGray3h(pixbd);
1141  pixDestroy(&pixbd);
1142  pixbd = pixErodeGray3v(pixt);
1143  pixDestroy(&pixt);
1144  }
1145 
1146  pixd = pixRemoveBorderGeneral(pixbd, 4, 8, 2, 8);
1147  pixDestroy(&pixb);
1148  pixDestroy(&pixbd);
1149  return pixd;
1150 }
1151 
1152 
1153 /*-----------------------------------------------------------------*
1154  * Low-level gray morphological operations *
1155  *-----------------------------------------------------------------*/
1184 static void
1185 dilateGrayLow(l_uint32 *datad,
1186  l_int32 w,
1187  l_int32 h,
1188  l_int32 wpld,
1189  l_uint32 *datas,
1190  l_int32 wpls,
1191  l_int32 size,
1192  l_int32 direction,
1193  l_uint8 *buffer,
1194  l_uint8 *maxarray)
1195 {
1196 l_int32 i, j, k;
1197 l_int32 hsize, nsteps, startmax, startx, starty;
1198 l_uint8 maxval;
1199 l_uint32 *lines, *lined;
1200 
1201  if (direction == L_HORIZ) {
1202  hsize = size / 2;
1203  nsteps = (w - 2 * hsize) / size;
1204  for (i = 0; i < h; i++) {
1205  lines = datas + i * wpls;
1206  lined = datad + i * wpld;
1207 
1208  /* fill buffer with pixels in byte order */
1209  for (j = 0; j < w; j++)
1210  buffer[j] = GET_DATA_BYTE(lines, j);
1211 
1212  for (j = 0; j < nsteps; j++) {
1213  /* refill the minarray */
1214  startmax = (j + 1) * size - 1;
1215  maxarray[size - 1] = buffer[startmax];
1216  for (k = 1; k < size; k++) {
1217  maxarray[size - 1 - k] =
1218  L_MAX(maxarray[size - k], buffer[startmax - k]);
1219  maxarray[size - 1 + k] =
1220  L_MAX(maxarray[size + k - 2], buffer[startmax + k]);
1221  }
1222 
1223  /* compute dilation values */
1224  startx = hsize + j * size;
1225  SET_DATA_BYTE(lined, startx, maxarray[0]);
1226  SET_DATA_BYTE(lined, startx + size - 1, maxarray[2 * size - 2]);
1227  for (k = 1; k < size - 1; k++) {
1228  maxval = L_MAX(maxarray[k], maxarray[k + size - 1]);
1229  SET_DATA_BYTE(lined, startx + k, maxval);
1230  }
1231  }
1232  }
1233  } else { /* direction == L_VERT */
1234  hsize = size / 2;
1235  nsteps = (h - 2 * hsize) / size;
1236  for (j = 0; j < w; j++) {
1237  /* fill buffer with pixels in byte order */
1238  for (i = 0; i < h; i++) {
1239  lines = datas + i * wpls;
1240  buffer[i] = GET_DATA_BYTE(lines, j);
1241  }
1242 
1243  for (i = 0; i < nsteps; i++) {
1244  /* refill the minarray */
1245  startmax = (i + 1) * size - 1;
1246  maxarray[size - 1] = buffer[startmax];
1247  for (k = 1; k < size; k++) {
1248  maxarray[size - 1 - k] =
1249  L_MAX(maxarray[size - k], buffer[startmax - k]);
1250  maxarray[size - 1 + k] =
1251  L_MAX(maxarray[size + k - 2], buffer[startmax + k]);
1252  }
1253 
1254  /* compute dilation values */
1255  starty = hsize + i * size;
1256  lined = datad + starty * wpld;
1257  SET_DATA_BYTE(lined, j, maxarray[0]);
1258  SET_DATA_BYTE(lined + (size - 1) * wpld, j,
1259  maxarray[2 * size - 2]);
1260  for (k = 1; k < size - 1; k++) {
1261  maxval = L_MAX(maxarray[k], maxarray[k + size - 1]);
1262  SET_DATA_BYTE(lined + wpld * k, j, maxval);
1263  }
1264  }
1265  }
1266  }
1267 
1268  return;
1269 }
1270 
1271 
1291 static void
1292 erodeGrayLow(l_uint32 *datad,
1293  l_int32 w,
1294  l_int32 h,
1295  l_int32 wpld,
1296  l_uint32 *datas,
1297  l_int32 wpls,
1298  l_int32 size,
1299  l_int32 direction,
1300  l_uint8 *buffer,
1301  l_uint8 *minarray)
1302 {
1303 l_int32 i, j, k;
1304 l_int32 hsize, nsteps, startmin, startx, starty;
1305 l_uint8 minval;
1306 l_uint32 *lines, *lined;
1307 
1308  if (direction == L_HORIZ) {
1309  hsize = size / 2;
1310  nsteps = (w - 2 * hsize) / size;
1311  for (i = 0; i < h; i++) {
1312  lines = datas + i * wpls;
1313  lined = datad + i * wpld;
1314 
1315  /* fill buffer with pixels in byte order */
1316  for (j = 0; j < w; j++)
1317  buffer[j] = GET_DATA_BYTE(lines, j);
1318 
1319  for (j = 0; j < nsteps; j++) {
1320  /* refill the minarray */
1321  startmin = (j + 1) * size - 1;
1322  minarray[size - 1] = buffer[startmin];
1323  for (k = 1; k < size; k++) {
1324  minarray[size - 1 - k] =
1325  L_MIN(minarray[size - k], buffer[startmin - k]);
1326  minarray[size - 1 + k] =
1327  L_MIN(minarray[size + k - 2], buffer[startmin + k]);
1328  }
1329 
1330  /* compute erosion values */
1331  startx = hsize + j * size;
1332  SET_DATA_BYTE(lined, startx, minarray[0]);
1333  SET_DATA_BYTE(lined, startx + size - 1, minarray[2 * size - 2]);
1334  for (k = 1; k < size - 1; k++) {
1335  minval = L_MIN(minarray[k], minarray[k + size - 1]);
1336  SET_DATA_BYTE(lined, startx + k, minval);
1337  }
1338  }
1339  }
1340  } else { /* direction == L_VERT */
1341  hsize = size / 2;
1342  nsteps = (h - 2 * hsize) / size;
1343  for (j = 0; j < w; j++) {
1344  /* fill buffer with pixels in byte order */
1345  for (i = 0; i < h; i++) {
1346  lines = datas + i * wpls;
1347  buffer[i] = GET_DATA_BYTE(lines, j);
1348  }
1349 
1350  for (i = 0; i < nsteps; i++) {
1351  /* refill the minarray */
1352  startmin = (i + 1) * size - 1;
1353  minarray[size - 1] = buffer[startmin];
1354  for (k = 1; k < size; k++) {
1355  minarray[size - 1 - k] =
1356  L_MIN(minarray[size - k], buffer[startmin - k]);
1357  minarray[size - 1 + k] =
1358  L_MIN(minarray[size + k - 2], buffer[startmin + k]);
1359  }
1360 
1361  /* compute erosion values */
1362  starty = hsize + i * size;
1363  lined = datad + starty * wpld;
1364  SET_DATA_BYTE(lined, j, minarray[0]);
1365  SET_DATA_BYTE(lined + (size - 1) * wpld, j,
1366  minarray[2 * size - 2]);
1367  for (k = 1; k < size - 1; k++) {
1368  minval = L_MIN(minarray[k], minarray[k + size - 1]);
1369  SET_DATA_BYTE(lined + wpld * k, j, minval);
1370  }
1371  }
1372  }
1373  }
1374 
1375  return;
1376 }
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
static void erodeGrayLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 size, l_int32 direction, l_uint8 *buffer, l_uint8 *minarray)
erodeGrayLow()
Definition: graymorph.c:1292
static void dilateGrayLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 size, l_int32 direction, l_uint8 *buffer, l_uint8 *maxarray)
dilateGrayLow()
Definition: graymorph.c:1185
static PIX * pixErodeGray3h(PIX *pixs)
pixErodeGray3h()
Definition: graymorph.c:718
static PIX * pixErodeGray3v(PIX *pixs)
pixErodeGray3v()
Definition: graymorph.c:785
PIX * pixErodeGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeGray3()
Definition: graymorph.c:665
static PIX * pixDilateGray3h(PIX *pixs)
pixDilateGray3h()
Definition: graymorph.c:904
PIX * pixOpenGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixOpenGray3()
Definition: graymorph.c:1036
PIX * pixCloseGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixCloseGray()
Definition: graymorph.c:526
static PIX * pixDilateGray3v(PIX *pixs)
pixDilateGray3v()
Definition: graymorph.c:968
PIX * pixCloseGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixCloseGray3()
Definition: graymorph.c:1102
PIX * pixDilateGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixDilateGray()
Definition: graymorph.c:278
PIX * pixOpenGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixOpenGray()
Definition: graymorph.c:394
PIX * pixErodeGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeGray()
Definition: graymorph.c:162
PIX * pixDilateGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixDilateGray3()
Definition: graymorph.c:851
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixRemoveBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixRemoveBorderGeneral()
Definition: pix2.c:1993
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
l_ok pixSetBorderVal(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixSetBorderVal()
Definition: pix2.c:1563
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition: pix2.c:1514
#define PIX_CLR
Definition: pix.h:333
#define PIX_SET
Definition: pix.h:334
Definition: pix.h:139