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 */
129static PIX *pixErodeGray3h(PIX *pixs);
130static PIX *pixErodeGray3v(PIX *pixs);
131static PIX *pixDilateGray3h(PIX *pixs);
132static PIX *pixDilateGray3v(PIX *pixs);
133
134 /* Low-level gray morphological operations */
135static 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);
139static 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 *-----------------------------------------------------------------*/
161PIX *
163 l_int32 hsize,
164 l_int32 vsize)
165{
166l_uint8 *buffer, *minarray;
167l_int32 w, h, wplb, wplt;
168l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
169l_uint32 *datab, *datat;
170PIX *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
254cleanup:
255 LEPT_FREE(buffer);
256 LEPT_FREE(minarray);
257 pixDestroy(&pixb);
258 pixDestroy(&pixt);
259 return pixd;
260}
261
262
277PIX *
279 l_int32 hsize,
280 l_int32 vsize)
281{
282l_uint8 *buffer, *maxarray;
283l_int32 w, h, wplb, wplt;
284l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
285l_uint32 *datab, *datat;
286PIX *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
370cleanup:
371 LEPT_FREE(buffer);
372 LEPT_FREE(maxarray);
373 pixDestroy(&pixb);
374 pixDestroy(&pixt);
375 return pixd;
376}
377
378
393PIX *
395 l_int32 hsize,
396 l_int32 vsize)
397{
398l_uint8 *buffer;
399l_uint8 *array; /* used to find either min or max in interval */
400l_int32 w, h, wplb, wplt;
401l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
402l_uint32 *datab, *datat;
403PIX *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
502cleanup:
503 LEPT_FREE(buffer);
504 LEPT_FREE(array);
505 pixDestroy(&pixb);
506 pixDestroy(&pixt);
507 return pixd;
508}
509
510
525PIX *
527 l_int32 hsize,
528 l_int32 vsize)
529{
530l_uint8 *buffer;
531l_uint8 *array; /* used to find either min or max in interval */
532l_int32 w, h, wplb, wplt;
533l_int32 leftpix, rightpix, toppix, bottompix, maxsize;
534l_uint32 *datab, *datat;
535PIX *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
633cleanup:
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 *-----------------------------------------------------------------*/
664PIX *
666 l_int32 hsize,
667 l_int32 vsize)
668{
669PIX *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
717static PIX *
719{
720l_uint32 *datas, *datad, *lines, *lined;
721l_int32 w, h, wpl, i, j;
722l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, minval;
723PIX *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
784static PIX *
786{
787l_uint32 *datas, *datad, *linesi, *linedi;
788l_int32 w, h, wpl, i, j;
789l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, minval;
790PIX *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
850PIX *
852 l_int32 hsize,
853 l_int32 vsize)
854{
855PIX *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
903static PIX *
905{
906l_uint32 *datas, *datad, *lines, *lined;
907l_int32 w, h, wpl, i, j;
908l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, maxval;
909PIX *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
967static PIX *
969{
970l_uint32 *datas, *datad, *linesi, *linedi;
971l_int32 w, h, wpl, i, j;
972l_int32 val0, val1, val2, val3, val4, val5, val6, val7, val8, val9, maxval;
973PIX *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
1035PIX *
1037 l_int32 hsize,
1038 l_int32 vsize)
1039{
1040PIX *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
1101PIX *
1103 l_int32 hsize,
1104 l_int32 vsize)
1105{
1106PIX *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 *-----------------------------------------------------------------*/
1184static void
1185dilateGrayLow(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{
1196l_int32 i, j, k;
1197l_int32 hsize, nsteps, startmax, startx, starty;
1198l_uint8 maxval;
1199l_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
1291static void
1292erodeGrayLow(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{
1303l_int32 i, j, k;
1304l_int32 hsize, nsteps, startmin, startx, starty;
1305l_uint8 minval;
1306l_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
PIX * pixDilateGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixDilateGray()
Definition: graymorph.c:278
PIX * pixErodeGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeGray()
Definition: graymorph.c:162
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 * pixDilateGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixDilateGray3()
Definition: graymorph.c:851
PIX * pixCloseGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixCloseGray3()
Definition: graymorph.c:1102
PIX * pixCloseGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixCloseGray()
Definition: graymorph.c:526
static PIX * pixDilateGray3h(PIX *pixs)
pixDilateGray3h()
Definition: graymorph.c:904
PIX * pixErodeGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixErodeGray3()
Definition: graymorph.c:665
PIX * pixOpenGray3(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixOpenGray3()
Definition: graymorph.c:1036
static PIX * pixDilateGray3v(PIX *pixs)
pixDilateGray3v()
Definition: graymorph.c:968
PIX * pixOpenGray(PIX *pixs, l_int32 hsize, l_int32 vsize)
pixOpenGray()
Definition: graymorph.c:394
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 * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
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
PIX * pixRemoveBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixRemoveBorderGeneral()
Definition: pix2.c:1993
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
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1917
#define PIX_CLR
Definition: pix.h:333
#define PIX_SET
Definition: pix.h:334
Definition: pix.h:139