Leptonica 1.82.0
Image processing and image analysis suite
pixarith.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
91#ifdef HAVE_CONFIG_H
92#include <config_auto.h>
93#endif /* HAVE_CONFIG_H */
94
95#include <string.h>
96#include <math.h>
97#include "allheaders.h"
98
99/*-------------------------------------------------------------*
100 * One-image grayscale arithmetic operations *
101 *-------------------------------------------------------------*/
118l_ok
120 l_int32 val)
121{
122l_int32 i, j, w, h, d, wpl, pval;
123l_uint32 *data, *line;
124
125 PROCNAME("pixAddConstantGray");
126
127 if (!pixs)
128 return ERROR_INT("pixs not defined", procName, 1);
129 pixGetDimensions(pixs, &w, &h, &d);
130 if (d != 8 && d != 16 && d != 32)
131 return ERROR_INT("pixs not 8, 16 or 32 bpp", procName, 1);
132
133 data = pixGetData(pixs);
134 wpl = pixGetWpl(pixs);
135 for (i = 0; i < h; i++) {
136 line = data + i * wpl;
137 if (d == 8) {
138 if (val < 0) {
139 for (j = 0; j < w; j++) {
140 pval = GET_DATA_BYTE(line, j);
141 pval = L_MAX(0, pval + val);
142 SET_DATA_BYTE(line, j, pval);
143 }
144 } else { /* val >= 0 */
145 for (j = 0; j < w; j++) {
146 pval = GET_DATA_BYTE(line, j);
147 pval = L_MIN(255, pval + val);
148 SET_DATA_BYTE(line, j, pval);
149 }
150 }
151 } else if (d == 16) {
152 if (val < 0) {
153 for (j = 0; j < w; j++) {
154 pval = GET_DATA_TWO_BYTES(line, j);
155 pval = L_MAX(0, pval + val);
156 SET_DATA_TWO_BYTES(line, j, pval);
157 }
158 } else { /* val >= 0 */
159 for (j = 0; j < w; j++) {
160 pval = GET_DATA_TWO_BYTES(line, j);
161 pval = L_MIN(0xffff, pval + val);
162 SET_DATA_TWO_BYTES(line, j, pval);
163 }
164 }
165 } else { /* d == 32; no check for overflow (< 0 or > 0xffffffff) */
166 for (j = 0; j < w; j++)
167 *(line + j) += val;
168 }
169 }
170
171 return 0;
172}
173
174
189l_ok
191 l_float32 val)
192{
193l_int32 i, j, w, h, d, wpl, pval;
194l_uint32 upval;
195l_uint32 *data, *line;
196
197 PROCNAME("pixMultConstantGray");
198
199 if (!pixs)
200 return ERROR_INT("pixs not defined", procName, 1);
201 pixGetDimensions(pixs, &w, &h, &d);
202 if (d != 8 && d != 16 && d != 32)
203 return ERROR_INT("pixs not 8, 16 or 32 bpp", procName, 1);
204 if (val < 0.0)
205 return ERROR_INT("val < 0.0", procName, 1);
206
207 data = pixGetData(pixs);
208 wpl = pixGetWpl(pixs);
209 for (i = 0; i < h; i++) {
210 line = data + i * wpl;
211 if (d == 8) {
212 for (j = 0; j < w; j++) {
213 pval = GET_DATA_BYTE(line, j);
214 pval = (l_int32)(val * pval);
215 pval = L_MIN(255, pval);
216 SET_DATA_BYTE(line, j, pval);
217 }
218 } else if (d == 16) {
219 for (j = 0; j < w; j++) {
220 pval = GET_DATA_TWO_BYTES(line, j);
221 pval = (l_int32)(val * pval);
222 pval = L_MIN(0xffff, pval);
223 SET_DATA_TWO_BYTES(line, j, pval);
224 }
225 } else { /* d == 32; no clipping */
226 for (j = 0; j < w; j++) {
227 upval = *(line + j);
228 upval = (l_uint32)(val * upval);
229 *(line + j) = upval;
230 }
231 }
232 }
233
234 return 0;
235}
236
237
238/*-------------------------------------------------------------*
239 * Two-image grayscale arithmetic ops *
240 *-------------------------------------------------------------*/
264PIX *
266 PIX *pixs1,
267 PIX *pixs2)
268{
269l_int32 i, j, d, ws, hs, w, h, wpls, wpld, val, sum;
270l_uint32 *datas, *datad, *lines, *lined;
271
272 PROCNAME("pixAddGray");
273
274 if (!pixs1)
275 return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
276 if (!pixs2)
277 return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
278 if (pixs2 == pixs1)
279 return (PIX *)ERROR_PTR("pixs2 and pixs1 must differ", procName, pixd);
280 if (pixs2 == pixd)
281 return (PIX *)ERROR_PTR("pixs2 and pixd must differ", procName, pixd);
282 d = pixGetDepth(pixs1);
283 if (d != 8 && d != 16 && d != 32)
284 return (PIX *)ERROR_PTR("pix are not 8, 16 or 32 bpp", procName, pixd);
285 if (pixGetDepth(pixs2) != d)
286 return (PIX *)ERROR_PTR("depths differ (pixs1, pixs2)", procName, pixd);
287 if (pixd && (pixGetDepth(pixd) != d))
288 return (PIX *)ERROR_PTR("depths differ (pixs1, pixd)", procName, pixd);
289
290 if (!pixSizesEqual(pixs1, pixs2))
291 L_WARNING("pixs1 and pixs2 not equal in size\n", procName);
292 if (pixd && !pixSizesEqual(pixs1, pixd))
293 L_WARNING("pixs1 and pixd not equal in size\n", procName);
294
295 if (pixs1 != pixd)
296 pixd = pixCopy(pixd, pixs1);
297
298 /* pixd + pixs2 ==> pixd */
299 datas = pixGetData(pixs2);
300 datad = pixGetData(pixd);
301 wpls = pixGetWpl(pixs2);
302 wpld = pixGetWpl(pixd);
303 pixGetDimensions(pixs2, &ws, &hs, NULL);
304 pixGetDimensions(pixd, &w, &h, NULL);
305 w = L_MIN(ws, w);
306 h = L_MIN(hs, h);
307 for (i = 0; i < h; i++) {
308 lined = datad + i * wpld;
309 lines = datas + i * wpls;
310 if (d == 8) {
311 for (j = 0; j < w; j++) {
312 sum = GET_DATA_BYTE(lines, j) + GET_DATA_BYTE(lined, j);
313 val = L_MIN(sum, 255);
314 SET_DATA_BYTE(lined, j, val);
315 }
316 } else if (d == 16) {
317 for (j = 0; j < w; j++) {
318 sum = GET_DATA_TWO_BYTES(lines, j)
319 + GET_DATA_TWO_BYTES(lined, j);
320 val = L_MIN(sum, 0xffff);
321 SET_DATA_TWO_BYTES(lined, j, val);
322 }
323 } else { /* d == 32; no clipping */
324 for (j = 0; j < w; j++)
325 *(lined + j) += *(lines + j);
326 }
327 }
328
329 return pixd;
330}
331
332
356PIX *
358 PIX *pixs1,
359 PIX *pixs2)
360{
361l_int32 i, j, w, h, ws, hs, d, wpls, wpld, val, diff;
362l_uint32 *datas, *datad, *lines, *lined;
363
364 PROCNAME("pixSubtractGray");
365
366 if (!pixs1)
367 return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
368 if (!pixs2)
369 return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
370 if (pixs2 == pixs1)
371 return (PIX *)ERROR_PTR("pixs2 and pixs1 must differ", procName, pixd);
372 if (pixs2 == pixd)
373 return (PIX *)ERROR_PTR("pixs2 and pixd must differ", procName, pixd);
374 d = pixGetDepth(pixs1);
375 if (d != 8 && d != 16 && d != 32)
376 return (PIX *)ERROR_PTR("pix are not 8, 16 or 32 bpp", procName, pixd);
377 if (pixGetDepth(pixs2) != d)
378 return (PIX *)ERROR_PTR("depths differ (pixs1, pixs2)", procName, pixd);
379 if (pixd && (pixGetDepth(pixd) != d))
380 return (PIX *)ERROR_PTR("depths differ (pixs1, pixd)", procName, pixd);
381
382 if (!pixSizesEqual(pixs1, pixs2))
383 L_WARNING("pixs1 and pixs2 not equal in size\n", procName);
384 if (pixd && !pixSizesEqual(pixs1, pixd))
385 L_WARNING("pixs1 and pixd not equal in size\n", procName);
386
387 if (pixs1 != pixd)
388 pixd = pixCopy(pixd, pixs1);
389
390 /* pixd - pixs2 ==> pixd */
391 datas = pixGetData(pixs2);
392 datad = pixGetData(pixd);
393 wpls = pixGetWpl(pixs2);
394 wpld = pixGetWpl(pixd);
395 pixGetDimensions(pixs2, &ws, &hs, NULL);
396 pixGetDimensions(pixd, &w, &h, NULL);
397 w = L_MIN(ws, w);
398 h = L_MIN(hs, h);
399 for (i = 0; i < h; i++) {
400 lined = datad + i * wpld;
401 lines = datas + i * wpls;
402 if (d == 8) {
403 for (j = 0; j < w; j++) {
404 diff = GET_DATA_BYTE(lined, j) - GET_DATA_BYTE(lines, j);
405 val = L_MAX(diff, 0);
406 SET_DATA_BYTE(lined, j, val);
407 }
408 } else if (d == 16) {
409 for (j = 0; j < w; j++) {
410 diff = GET_DATA_TWO_BYTES(lined, j)
411 - GET_DATA_TWO_BYTES(lines, j);
412 val = L_MAX(diff, 0);
413 SET_DATA_TWO_BYTES(lined, j, val);
414 }
415 } else { /* d == 32; no clipping */
416 for (j = 0; j < w; j++)
417 *(lined + j) -= *(lines + j);
418 }
419 }
420
421 return pixd;
422}
423
424
448PIX *
450 PIX *pixg,
451 l_float32 norm)
452{
453l_int32 i, j, w, h, d, ws, hs, ds, wpls, wplg, wpld;
454l_int32 rval, gval, bval, rval2, gval2, bval2, vals, valg, val, maxgray;
455l_uint32 val32;
456l_uint32 *datas, *datag, *datad, *lines, *lineg, *lined;
457PIX *pixd;
458
459 PROCNAME("pixMultiplyGray");
460
461 if (!pixs)
462 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
463 pixGetDimensions(pixs, &ws, &hs, &ds);
464 if (ds != 8 && ds != 32)
465 return (PIX *)ERROR_PTR("pixs not 8 or 32 bpp", procName, NULL);
466 if (!pixg)
467 return (PIX *)ERROR_PTR("pixg not defined", procName, NULL);
468 pixGetDimensions(pixg, &w, &h, &d);
469 if (d != 8)
470 return (PIX *)ERROR_PTR("pixg not 8 bpp", procName, NULL);
471
472 if (norm <= 0.0) {
473 pixGetExtremeValue(pixg, 1, L_SELECT_MAX, NULL, NULL, NULL, &maxgray);
474 norm = (maxgray > 0) ? 1.0 / (l_float32)maxgray : 1.0;
475 }
476
477 if ((pixd = pixCreateTemplate(pixs)) == NULL)
478 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
479 datas = pixGetData(pixs);
480 datag = pixGetData(pixg);
481 datad = pixGetData(pixd);
482 wpls = pixGetWpl(pixs);
483 wplg = pixGetWpl(pixg);
484 wpld = pixGetWpl(pixd);
485 w = L_MIN(ws, w);
486 h = L_MIN(hs, h);
487 for (i = 0; i < h; i++) {
488 lines = datas + i * wpls;
489 lineg = datag + i * wplg;
490 lined = datad + i * wpld;
491 if (ds == 8) {
492 for (j = 0; j < w; j++) {
493 vals = GET_DATA_BYTE(lines, j);
494 valg = GET_DATA_BYTE(lineg, j);
495 val = (l_int32)(vals * valg * norm + 0.5);
496 val = L_MIN(255, val);
497 SET_DATA_BYTE(lined, j, val);
498 }
499 } else { /* ds == 32 */
500 for (j = 0; j < w; j++) {
501 val32 = *(lines + j);
502 extractRGBValues(val32, &rval, &gval, &bval);
503 valg = GET_DATA_BYTE(lineg, j);
504 rval2 = (l_int32)(rval * valg * norm + 0.5);
505 rval2 = L_MIN(255, rval2);
506 gval2 = (l_int32)(gval * valg * norm + 0.5);
507 gval2 = L_MIN(255, gval2);
508 bval2 = (l_int32)(bval * valg * norm + 0.5);
509 bval2 = L_MIN(255, bval2);
510 composeRGBPixel(rval2, gval2, bval2, lined + j);
511 }
512 }
513 }
514
515 return pixd;
516}
517
518
519/*-------------------------------------------------------------*
520 * Grayscale threshold operation *
521 *-------------------------------------------------------------*/
539PIX *
541 PIX *pixs,
542 l_int32 threshval,
543 l_int32 setval)
544{
545l_int32 i, j, w, h, d, wpld, setabove;
546l_uint32 *datad, *lined;
547
548 PROCNAME("pixThresholdToValue");
549
550 if (!pixs)
551 return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
552 d = pixGetDepth(pixs);
553 if (d != 8 && d != 16 && d != 32)
554 return (PIX *)ERROR_PTR("pixs not 8, 16 or 32 bpp", procName, pixd);
555 if (pixd && (pixs != pixd))
556 return (PIX *)ERROR_PTR("pixd exists and is not pixs", procName, pixd);
557 if (threshval < 0 || setval < 0)
558 return (PIX *)ERROR_PTR("threshval & setval not < 0", procName, pixd);
559 if (d == 8 && setval > 255)
560 return (PIX *)ERROR_PTR("setval > 255 for 8 bpp", procName, pixd);
561 if (d == 16 && setval > 0xffff)
562 return (PIX *)ERROR_PTR("setval > 0xffff for 16 bpp", procName, pixd);
563
564 if (!pixd)
565 pixd = pixCopy(NULL, pixs);
566 if (setval == threshval) {
567 L_WARNING("setval == threshval; no operation\n", procName);
568 return pixd;
569 }
570
571 datad = pixGetData(pixd);
572 pixGetDimensions(pixd, &w, &h, NULL);
573 wpld = pixGetWpl(pixd);
574 if (setval > threshval)
575 setabove = TRUE;
576 else
577 setabove = FALSE;
578
579 for (i = 0; i < h; i++) {
580 lined = datad + i * wpld;
581 if (setabove == TRUE) {
582 if (d == 8) {
583 for (j = 0; j < w; j++) {
584 if (GET_DATA_BYTE(lined, j) - threshval >= 0)
585 SET_DATA_BYTE(lined, j, setval);
586 }
587 } else if (d == 16) {
588 for (j = 0; j < w; j++) {
589 if (GET_DATA_TWO_BYTES(lined, j) - threshval >= 0)
590 SET_DATA_TWO_BYTES(lined, j, setval);
591 }
592 } else { /* d == 32 */
593 for (j = 0; j < w; j++) {
594 if (*(lined + j) >= threshval)
595 *(lined + j) = setval;
596 }
597 }
598 } else { /* set if below or at threshold */
599 if (d == 8) {
600 for (j = 0; j < w; j++) {
601 if (GET_DATA_BYTE(lined, j) - threshval <= 0)
602 SET_DATA_BYTE(lined, j, setval);
603 }
604 } else if (d == 16) {
605 for (j = 0; j < w; j++) {
606 if (GET_DATA_TWO_BYTES(lined, j) - threshval <= 0)
607 SET_DATA_TWO_BYTES(lined, j, setval);
608 }
609 } else { /* d == 32 */
610 for (j = 0; j < w; j++) {
611 if (*(lined + j) <= threshval)
612 *(lined + j) = setval;
613 }
614 }
615 }
616 }
617
618 return pixd;
619}
620
621
622/*-------------------------------------------------------------*
623 * Image accumulator arithmetic operations *
624 *-------------------------------------------------------------*/
648PIX *
650 l_int32 h,
651 l_uint32 offset)
652{
653PIX *pixd;
654
655 PROCNAME("pixInitAccumulate");
656
657 if ((pixd = pixCreate(w, h, 32)) == NULL)
658 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
659 if (offset > 0x40000000)
660 offset = 0x40000000;
661 pixSetAllArbitrary(pixd, offset);
662 return pixd;
663}
664
665
682PIX *
684 l_uint32 offset,
685 l_int32 depth)
686{
687l_int32 i, j, w, h, wpls, wpld, val;
688l_uint32 *datas, *datad, *lines, *lined;
689PIX *pixd;
690
691 PROCNAME("pixFinalAccumulate");
692
693 if (!pixs)
694 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
695 if (pixGetDepth(pixs) != 32)
696 return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
697 if (depth != 8 && depth != 16 && depth != 32)
698 return (PIX *)ERROR_PTR("dest depth not 8, 16, 32 bpp", procName, NULL);
699 if (offset > 0x40000000)
700 offset = 0x40000000;
701
702 pixGetDimensions(pixs, &w, &h, NULL);
703 if ((pixd = pixCreate(w, h, depth)) == NULL)
704 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
705 pixCopyResolution(pixd, pixs); /* but how did pixs get it initially? */
706 datas = pixGetData(pixs);
707 datad = pixGetData(pixd);
708 wpls = pixGetWpl(pixs);
709 wpld = pixGetWpl(pixd);
710 if (depth == 8) {
711 for (i = 0; i < h; i++) {
712 lines = datas + i * wpls;
713 lined = datad + i * wpld;
714 for (j = 0; j < w; j++) {
715 val = lines[j] - offset;
716 val = L_MAX(0, val);
717 val = L_MIN(255, val);
718 SET_DATA_BYTE(lined, j, (l_uint8)val);
719 }
720 }
721 } else if (depth == 16) {
722 for (i = 0; i < h; i++) {
723 lines = datas + i * wpls;
724 lined = datad + i * wpld;
725 for (j = 0; j < w; j++) {
726 val = lines[j] - offset;
727 val = L_MAX(0, val);
728 val = L_MIN(0xffff, val);
729 SET_DATA_TWO_BYTES(lined, j, (l_uint16)val);
730 }
731 }
732 } else { /* depth == 32 */
733 for (i = 0; i < h; i++) {
734 lines = datas + i * wpls;
735 lined = datad + i * wpld;
736 for (j = 0; j < w; j++)
737 lined[j] = lines[j] - offset;
738 }
739 }
740
741 return pixd;
742}
743
744
759PIX *
761 l_uint32 offset,
762 l_uint32 threshold)
763{
764l_int32 i, j, w, h, wpls, wpld, val;
765l_uint32 *datas, *datad, *lines, *lined;
766PIX *pixd;
767
768 PROCNAME("pixFinalAccumulateThreshold");
769
770 if (!pixs)
771 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
772 if (pixGetDepth(pixs) != 32)
773 return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
774 if (offset > 0x40000000)
775 offset = 0x40000000;
776
777 pixGetDimensions(pixs, &w, &h, NULL);
778 if ((pixd = pixCreate(w, h, 1)) == NULL)
779 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
780 pixCopyResolution(pixd, pixs); /* but how did pixs get it initially? */
781 datas = pixGetData(pixs);
782 datad = pixGetData(pixd);
783 wpls = pixGetWpl(pixs);
784 wpld = pixGetWpl(pixd);
785 for (i = 0; i < h; i++) {
786 lines = datas + i * wpls;
787 lined = datad + i * wpld;
788 for (j = 0; j < w; j++) {
789 val = lines[j] - offset;
790 if (val >= threshold) {
791 SET_DATA_BIT(lined, j);
792 }
793 }
794 }
795
796 return pixd;
797}
798
799
816l_ok
818 PIX *pixs,
819 l_int32 op)
820{
821l_int32 i, j, w, h, d, wd, hd, wpls, wpld;
822l_uint32 *datas, *datad, *lines, *lined;
823
824
825 PROCNAME("pixAccumulate");
826
827 if (!pixd || (pixGetDepth(pixd) != 32))
828 return ERROR_INT("pixd not defined or not 32 bpp", procName, 1);
829 if (!pixs)
830 return ERROR_INT("pixs not defined", procName, 1);
831 d = pixGetDepth(pixs);
832 if (d != 1 && d != 8 && d != 16 && d != 32)
833 return ERROR_INT("pixs not 1, 8, 16 or 32 bpp", procName, 1);
834 if (op != L_ARITH_ADD && op != L_ARITH_SUBTRACT)
835 return ERROR_INT("op must be in {L_ARITH_ADD, L_ARITH_SUBTRACT}",
836 procName, 1);
837
838 datas = pixGetData(pixs);
839 datad = pixGetData(pixd);
840 wpls = pixGetWpl(pixs);
841 wpld = pixGetWpl(pixd);
842 pixGetDimensions(pixs, &w, &h, NULL);
843 pixGetDimensions(pixd, &wd, &hd, NULL);
844 w = L_MIN(w, wd);
845 h = L_MIN(h, hd);
846 if (d == 1) {
847 for (i = 0; i < h; i++) {
848 lines = datas + i * wpls;
849 lined = datad + i * wpld;
850 if (op == L_ARITH_ADD) {
851 for (j = 0; j < w; j++)
852 lined[j] += GET_DATA_BIT(lines, j);
853 } else { /* op == L_ARITH_SUBTRACT */
854 for (j = 0; j < w; j++)
855 lined[j] -= GET_DATA_BIT(lines, j);
856 }
857 }
858 } else if (d == 8) {
859 for (i = 0; i < h; i++) {
860 lines = datas + i * wpls;
861 lined = datad + i * wpld;
862 if (op == L_ARITH_ADD) {
863 for (j = 0; j < w; j++)
864 lined[j] += GET_DATA_BYTE(lines, j);
865 } else { /* op == L_ARITH_SUBTRACT */
866 for (j = 0; j < w; j++)
867 lined[j] -= GET_DATA_BYTE(lines, j);
868 }
869 }
870 } else if (d == 16) {
871 for (i = 0; i < h; i++) {
872 lines = datas + i * wpls;
873 lined = datad + i * wpld;
874 if (op == L_ARITH_ADD) {
875 for (j = 0; j < w; j++)
876 lined[j] += GET_DATA_TWO_BYTES(lines, j);
877 } else { /* op == L_ARITH_SUBTRACT */
878 for (j = 0; j < w; j++)
879 lined[j] -= GET_DATA_TWO_BYTES(lines, j);
880 }
881 }
882 } else { /* d == 32 */
883 for (i = 0; i < h; i++) {
884 lines = datas + i * wpls;
885 lined = datad + i * wpld;
886 if (op == L_ARITH_ADD) {
887 for (j = 0; j < w; j++)
888 lined[j] += lines[j];
889 } else { /* op == L_ARITH_SUBTRACT */
890 for (j = 0; j < w; j++)
891 lined[j] -= lines[j];
892 }
893 }
894 }
895
896 return 0;
897}
898
899
915l_ok
917 l_float32 factor,
918 l_uint32 offset)
919{
920l_int32 i, j, w, h, wpl, val;
921l_uint32 *data, *line;
922
923 PROCNAME("pixMultConstAccumulate");
924
925 if (!pixs)
926 return ERROR_INT("pixs not defined", procName, 1);
927 if (pixGetDepth(pixs) != 32)
928 return ERROR_INT("pixs not 32 bpp", procName, 1);
929 if (offset > 0x40000000)
930 offset = 0x40000000;
931
932 pixGetDimensions(pixs, &w, &h, NULL);
933 data = pixGetData(pixs);
934 wpl = pixGetWpl(pixs);
935 for (i = 0; i < h; i++) {
936 line = data + i * wpl;
937 for (j = 0; j < w; j++) {
938 val = line[j] - offset;
939 val = (l_int32)(val * factor);
940 val += offset;
941 line[j] = (l_uint32)val;
942 }
943 }
944
945 return 0;
946}
947
948
949/*-----------------------------------------------------------------------*
950 * Absolute value of difference *
951 *-----------------------------------------------------------------------*/
969PIX *
971 PIX *pixs2)
972{
973l_int32 i, j, w, h, w2, h2, d, wpls1, wpls2, wpld, val1, val2, diff;
974l_int32 rval1, gval1, bval1, rval2, gval2, bval2, rdiff, gdiff, bdiff;
975l_uint32 *datas1, *datas2, *datad, *lines1, *lines2, *lined;
976PIX *pixd;
977
978 PROCNAME("pixAbsDifference");
979
980 if (!pixs1)
981 return (PIX *)ERROR_PTR("pixs1 not defined", procName, NULL);
982 if (!pixs2)
983 return (PIX *)ERROR_PTR("pixs2 not defined", procName, NULL);
984 d = pixGetDepth(pixs1);
985 if (d != pixGetDepth(pixs2))
986 return (PIX *)ERROR_PTR("src1 and src2 depths unequal", procName, NULL);
987 if (d != 8 && d != 16 && d != 32)
988 return (PIX *)ERROR_PTR("depths not in {8, 16, 32}", procName, NULL);
989
990 pixGetDimensions(pixs1, &w, &h, NULL);
991 pixGetDimensions(pixs2, &w2, &h2, NULL);
992 w = L_MIN(w, w2);
993 h = L_MIN(h, h2);
994 if ((pixd = pixCreate(w, h, d)) == NULL)
995 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
996 pixCopyResolution(pixd, pixs1);
997 datas1 = pixGetData(pixs1);
998 datas2 = pixGetData(pixs2);
999 datad = pixGetData(pixd);
1000 wpls1 = pixGetWpl(pixs1);
1001 wpls2 = pixGetWpl(pixs2);
1002 wpld = pixGetWpl(pixd);
1003 if (d == 8) {
1004 for (i = 0; i < h; i++) {
1005 lines1 = datas1 + i * wpls1;
1006 lines2 = datas2 + i * wpls2;
1007 lined = datad + i * wpld;
1008 for (j = 0; j < w; j++) {
1009 val1 = GET_DATA_BYTE(lines1, j);
1010 val2 = GET_DATA_BYTE(lines2, j);
1011 diff = L_ABS(val1 - val2);
1012 SET_DATA_BYTE(lined, j, diff);
1013 }
1014 }
1015 } else if (d == 16) {
1016 for (i = 0; i < h; i++) {
1017 lines1 = datas1 + i * wpls1;
1018 lines2 = datas2 + i * wpls2;
1019 lined = datad + i * wpld;
1020 for (j = 0; j < w; j++) {
1021 val1 = GET_DATA_TWO_BYTES(lines1, j);
1022 val2 = GET_DATA_TWO_BYTES(lines2, j);
1023 diff = L_ABS(val1 - val2);
1024 SET_DATA_TWO_BYTES(lined, j, diff);
1025 }
1026 }
1027 } else { /* d == 32 */
1028 for (i = 0; i < h; i++) {
1029 lines1 = datas1 + i * wpls1;
1030 lines2 = datas2 + i * wpls2;
1031 lined = datad + i * wpld;
1032 for (j = 0; j < w; j++) {
1033 extractRGBValues(lines1[j], &rval1, &gval1, &bval1);
1034 extractRGBValues(lines2[j], &rval2, &gval2, &bval2);
1035 rdiff = L_ABS(rval1 - rval2);
1036 gdiff = L_ABS(gval1 - gval2);
1037 bdiff = L_ABS(bval1 - bval2);
1038 composeRGBPixel(rdiff, gdiff, bdiff, lined + j);
1039 }
1040 }
1041 }
1042
1043 return pixd;
1044}
1045
1046
1047/*-----------------------------------------------------------------------*
1048 * Sum of color images *
1049 *-----------------------------------------------------------------------*/
1066PIX *
1068 PIX *pixs2)
1069{
1070l_int32 i, j, w, h, d, w2, h2, d2, wplc1, wplc2, wpld;
1071l_int32 rval1, gval1, bval1, rval2, gval2, bval2, rval, gval, bval;
1072l_uint32 *datac1, *datac2, *datad, *linec1, *linec2, *lined;
1073PIX *pixc1, *pixc2, *pixd;
1074
1075 PROCNAME("pixAddRGB");
1076
1077 if (!pixs1)
1078 return (PIX *)ERROR_PTR("pixs1 not defined", procName, NULL);
1079 if (!pixs2)
1080 return (PIX *)ERROR_PTR("pixs2 not defined", procName, NULL);
1081 pixGetDimensions(pixs1, &w, &h, &d);
1082 pixGetDimensions(pixs2, &w2, &h2, &d2);
1083 if (!pixGetColormap(pixs1) && d != 32)
1084 return (PIX *)ERROR_PTR("pixs1 not cmapped or rgb", procName, NULL);
1085 if (!pixGetColormap(pixs2) && d2 != 32)
1086 return (PIX *)ERROR_PTR("pixs2 not cmapped or rgb", procName, NULL);
1087 if (pixGetColormap(pixs1))
1089 else
1090 pixc1 = pixClone(pixs1);
1091 if (pixGetColormap(pixs2))
1093 else
1094 pixc2 = pixClone(pixs2);
1095
1096 w = L_MIN(w, w2);
1097 h = L_MIN(h, h2);
1098 pixd = pixCreate(w, h, 32);
1099 pixCopyResolution(pixd, pixs1);
1100 datac1 = pixGetData(pixc1);
1101 datac2 = pixGetData(pixc2);
1102 datad = pixGetData(pixd);
1103 wplc1 = pixGetWpl(pixc1);
1104 wplc2 = pixGetWpl(pixc2);
1105 wpld = pixGetWpl(pixd);
1106 for (i = 0; i < h; i++) {
1107 linec1 = datac1 + i * wplc1;
1108 linec2 = datac2 + i * wplc2;
1109 lined = datad + i * wpld;
1110 for (j = 0; j < w; j++) {
1111 extractRGBValues(linec1[j], &rval1, &gval1, &bval1);
1112 extractRGBValues(linec2[j], &rval2, &gval2, &bval2);
1113 rval = L_MIN(255, rval1 + rval2);
1114 gval = L_MIN(255, gval1 + gval2);
1115 bval = L_MIN(255, bval1 + bval2);
1116 composeRGBPixel(rval, gval, bval, lined + j);
1117 }
1118 }
1119
1120 pixDestroy(&pixc1);
1121 pixDestroy(&pixc2);
1122 return pixd;
1123}
1124
1125
1126/*-----------------------------------------------------------------------*
1127 * Two-image min and max operations (8 and 16 bpp) *
1128 *-----------------------------------------------------------------------*/
1151PIX *
1153 PIX *pixs1,
1154 PIX *pixs2,
1155 l_int32 type)
1156{
1157l_int32 d, ws, hs, w, h, wpls, wpld, i, j, vals, vald, val;
1158l_int32 rval1, gval1, bval1, rval2, gval2, bval2, rval, gval, bval;
1159l_uint32 *datas, *datad, *lines, *lined;
1160
1161 PROCNAME("pixMinOrMax");
1162
1163 if (!pixs1)
1164 return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
1165 if (!pixs2)
1166 return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
1167 if (pixs1 == pixs2)
1168 return (PIX *)ERROR_PTR("pixs1 and pixs2 must differ", procName, pixd);
1169 if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX)
1170 return (PIX *)ERROR_PTR("invalid type", procName, pixd);
1171 d = pixGetDepth(pixs1);
1172 if (pixGetDepth(pixs2) != d)
1173 return (PIX *)ERROR_PTR("depths unequal", procName, pixd);
1174 if (d != 8 && d != 16 && d != 32)
1175 return (PIX *)ERROR_PTR("depth not 8, 16 or 32 bpp", procName, pixd);
1176
1177 if (pixs1 != pixd)
1178 pixd = pixCopy(pixd, pixs1);
1179
1180 pixGetDimensions(pixs2, &ws, &hs, NULL);
1181 pixGetDimensions(pixd, &w, &h, NULL);
1182 w = L_MIN(w, ws);
1183 h = L_MIN(h, hs);
1184 datas = pixGetData(pixs2);
1185 datad = pixGetData(pixd);
1186 wpls = pixGetWpl(pixs2);
1187 wpld = pixGetWpl(pixd);
1188 for (i = 0; i < h; i++) {
1189 lines = datas + i * wpls;
1190 lined = datad + i * wpld;
1191 if (d == 8) {
1192 for (j = 0; j < w; j++) {
1193 vals = GET_DATA_BYTE(lines, j);
1194 vald = GET_DATA_BYTE(lined, j);
1195 if (type == L_CHOOSE_MIN)
1196 val = L_MIN(vals, vald);
1197 else /* type == L_CHOOSE_MAX */
1198 val = L_MAX(vals, vald);
1199 SET_DATA_BYTE(lined, j, val);
1200 }
1201 } else if (d == 16) {
1202 for (j = 0; j < w; j++) {
1203 vals = GET_DATA_TWO_BYTES(lines, j);
1204 vald = GET_DATA_TWO_BYTES(lined, j);
1205 if (type == L_CHOOSE_MIN)
1206 val = L_MIN(vals, vald);
1207 else /* type == L_CHOOSE_MAX */
1208 val = L_MAX(vals, vald);
1209 SET_DATA_TWO_BYTES(lined, j, val);
1210 }
1211 } else { /* d == 32 */
1212 for (j = 0; j < w; j++) {
1213 extractRGBValues(lines[j], &rval1, &gval1, &bval1);
1214 extractRGBValues(lined[j], &rval2, &gval2, &bval2);
1215 if (type == L_CHOOSE_MIN) {
1216 rval = L_MIN(rval1, rval2);
1217 gval = L_MIN(gval1, gval2);
1218 bval = L_MIN(bval1, bval2);
1219 } else { /* type == L_CHOOSE_MAX */
1220 rval = L_MAX(rval1, rval2);
1221 gval = L_MAX(gval1, gval2);
1222 bval = L_MAX(bval1, bval2);
1223 }
1224 composeRGBPixel(rval, gval, bval, lined + j);
1225 }
1226 }
1227 }
1228
1229 return pixd;
1230}
1231
1232
1233/*-----------------------------------------------------------------------*
1234 * Scale for maximum dynamic range *
1235 *-----------------------------------------------------------------------*/
1252PIX *
1254 l_int32 type)
1255{
1256l_uint8 dval;
1257l_int32 i, j, w, h, d, wpls, wpld, max;
1258l_uint32 *datas, *datad;
1259l_uint32 word, sval;
1260l_uint32 *lines, *lined;
1261l_float32 factor;
1262l_float32 *tab;
1263PIX *pixd;
1264
1265 PROCNAME("pixMaxDynamicRange");
1266
1267 if (!pixs)
1268 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1269 pixGetDimensions(pixs, &w, &h, &d);
1270 if (d != 4 && d != 8 && d != 16 && d != 32)
1271 return (PIX *)ERROR_PTR("pixs not in {4,8,16,32} bpp", procName, NULL);
1272 if (type != L_LINEAR_SCALE && type != L_LOG_SCALE)
1273 return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1274
1275 if ((pixd = pixCreate(w, h, 8)) == NULL)
1276 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1277 pixCopyResolution(pixd, pixs);
1278 datas = pixGetData(pixs);
1279 datad = pixGetData(pixd);
1280 wpls = pixGetWpl(pixs);
1281 wpld = pixGetWpl(pixd);
1282
1283 /* Get max */
1284 max = 0;
1285 for (i = 0; i < h; i++) {
1286 lines = datas + i * wpls;
1287 for (j = 0; j < wpls; j++) {
1288 word = *(lines + j);
1289 if (d == 4) {
1290 max = L_MAX(max, word >> 28);
1291 max = L_MAX(max, (word >> 24) & 0xf);
1292 max = L_MAX(max, (word >> 20) & 0xf);
1293 max = L_MAX(max, (word >> 16) & 0xf);
1294 max = L_MAX(max, (word >> 12) & 0xf);
1295 max = L_MAX(max, (word >> 8) & 0xf);
1296 max = L_MAX(max, (word >> 4) & 0xf);
1297 max = L_MAX(max, word & 0xf);
1298 } else if (d == 8) {
1299 max = L_MAX(max, word >> 24);
1300 max = L_MAX(max, (word >> 16) & 0xff);
1301 max = L_MAX(max, (word >> 8) & 0xff);
1302 max = L_MAX(max, word & 0xff);
1303 } else if (d == 16) {
1304 max = L_MAX(max, word >> 16);
1305 max = L_MAX(max, word & 0xffff);
1306 } else { /* d == 32 (rgb) */
1307 max = L_MAX(max, word);
1308 }
1309 }
1310 }
1311
1312 /* Map to the full dynamic range */
1313 if (d == 4) {
1314 if (type == L_LINEAR_SCALE) {
1315 factor = 255. / (l_float32)max;
1316 for (i = 0; i < h; i++) {
1317 lines = datas + i * wpls;
1318 lined = datad + i * wpld;
1319 for (j = 0; j < w; j++) {
1320 sval = GET_DATA_QBIT(lines, j);
1321 dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1322 SET_DATA_QBIT(lined, j, dval);
1323 }
1324 }
1325 } else { /* type == L_LOG_SCALE) */
1326 tab = makeLogBase2Tab();
1327 factor = 255. / getLogBase2(max, tab);
1328 for (i = 0; i < h; i++) {
1329 lines = datas + i * wpls;
1330 lined = datad + i * wpld;
1331 for (j = 0; j < w; j++) {
1332 sval = GET_DATA_QBIT(lines, j);
1333 dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1334 SET_DATA_BYTE(lined, j, dval);
1335 }
1336 }
1337 LEPT_FREE(tab);
1338 }
1339 } else if (d == 8) {
1340 if (type == L_LINEAR_SCALE) {
1341 factor = 255. / (l_float32)max;
1342 for (i = 0; i < h; i++) {
1343 lines = datas + i * wpls;
1344 lined = datad + i * wpld;
1345 for (j = 0; j < w; j++) {
1346 sval = GET_DATA_BYTE(lines, j);
1347 dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1348 SET_DATA_BYTE(lined, j, dval);
1349 }
1350 }
1351 } else { /* type == L_LOG_SCALE) */
1352 tab = makeLogBase2Tab();
1353 factor = 255. / getLogBase2(max, tab);
1354 for (i = 0; i < h; i++) {
1355 lines = datas + i * wpls;
1356 lined = datad + i * wpld;
1357 for (j = 0; j < w; j++) {
1358 sval = GET_DATA_BYTE(lines, j);
1359 dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1360 SET_DATA_BYTE(lined, j, dval);
1361 }
1362 }
1363 LEPT_FREE(tab);
1364 }
1365 } else if (d == 16) {
1366 if (type == L_LINEAR_SCALE) {
1367 factor = 255. / (l_float32)max;
1368 for (i = 0; i < h; i++) {
1369 lines = datas + i * wpls;
1370 lined = datad + i * wpld;
1371 for (j = 0; j < w; j++) {
1372 sval = GET_DATA_TWO_BYTES(lines, j);
1373 dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1374 SET_DATA_BYTE(lined, j, dval);
1375 }
1376 }
1377 } else { /* type == L_LOG_SCALE) */
1378 tab = makeLogBase2Tab();
1379 factor = 255. / getLogBase2(max, tab);
1380 for (i = 0; i < h; i++) {
1381 lines = datas + i * wpls;
1382 lined = datad + i * wpld;
1383 for (j = 0; j < w; j++) {
1384 sval = GET_DATA_TWO_BYTES(lines, j);
1385 dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1386 SET_DATA_BYTE(lined, j, dval);
1387 }
1388 }
1389 LEPT_FREE(tab);
1390 }
1391 } else { /* d == 32 */
1392 if (type == L_LINEAR_SCALE) {
1393 factor = 255. / (l_float32)max;
1394 for (i = 0; i < h; i++) {
1395 lines = datas + i * wpls;
1396 lined = datad + i * wpld;
1397 for (j = 0; j < w; j++) {
1398 sval = lines[j];
1399 dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1400 SET_DATA_BYTE(lined, j, dval);
1401 }
1402 }
1403 } else { /* type == L_LOG_SCALE) */
1404 tab = makeLogBase2Tab();
1405 factor = 255. / getLogBase2(max, tab);
1406 for (i = 0; i < h; i++) {
1407 lines = datas + i * wpls;
1408 lined = datad + i * wpld;
1409 for (j = 0; j < w; j++) {
1410 sval = lines[j];
1411 dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1412 SET_DATA_BYTE(lined, j, dval);
1413 }
1414 }
1415 LEPT_FREE(tab);
1416 }
1417 }
1418
1419 return pixd;
1420}
1421
1422
1440PIX *
1442 l_int32 type)
1443{
1444l_int32 i, j, w, h, wpls, wpld, max;
1445l_uint32 sval, dval, word;
1446l_uint32 *datas, *datad;
1447l_uint32 *lines, *lined;
1448l_float32 factor;
1449l_float32 *tab;
1450PIX *pixd;
1451
1452 PROCNAME("pixMaxDynamicRangeRGB");
1453
1454 if (!pixs || pixGetDepth(pixs) != 32)
1455 return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
1456 if (type != L_LINEAR_SCALE && type != L_LOG_SCALE)
1457 return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1458
1459 /* Get max */
1460 pixd = pixCreateTemplate(pixs);
1461 datas = pixGetData(pixs);
1462 datad = pixGetData(pixd);
1463 wpls = pixGetWpl(pixs);
1464 wpld = pixGetWpl(pixd);
1465 pixGetDimensions(pixs, &w, &h, NULL);
1466 max = 0;
1467 for (i = 0; i < h; i++) {
1468 lines = datas + i * wpls;
1469 for (j = 0; j < wpls; j++) {
1470 word = lines[j];
1471 max = L_MAX(max, word >> 24);
1472 max = L_MAX(max, (word >> 16) & 0xff);
1473 max = L_MAX(max, (word >> 8) & 0xff);
1474 }
1475 }
1476 if (max == 0) {
1477 L_WARNING("max = 0; setting to 1\n", procName);
1478 max = 1;
1479 }
1480
1481 /* Map to the full dynamic range */
1482 if (type == L_LINEAR_SCALE) {
1483 factor = 255. / (l_float32)max;
1484 for (i = 0; i < h; i++) {
1485 lines = datas + i * wpls;
1486 lined = datad + i * wpld;
1487 for (j = 0; j < w; j++) {
1488 sval = lines[j];
1489 dval = linearScaleRGBVal(sval, factor);
1490 lined[j] = dval;
1491 }
1492 }
1493 } else { /* type == L_LOG_SCALE) */
1494 tab = makeLogBase2Tab();
1495 factor = 255. / getLogBase2(max, tab);
1496 for (i = 0; i < h; i++) {
1497 lines = datas + i * wpls;
1498 lined = datad + i * wpld;
1499 for (j = 0; j < w; j++) {
1500 sval = lines[j];
1501 dval = logScaleRGBVal(sval, tab, factor);
1502 lined[j] = dval;
1503 }
1504 }
1505 LEPT_FREE(tab);
1506 }
1507
1508 return pixd;
1509}
1510
1511
1512/*-----------------------------------------------------------------------*
1513 * RGB pixel value scaling *
1514 *-----------------------------------------------------------------------*/
1531l_uint32
1532linearScaleRGBVal(l_uint32 sval,
1533 l_float32 factor)
1534{
1535l_uint32 dval;
1536
1537 dval = ((l_uint8)(factor * (sval >> 24) + 0.5) << 24) |
1538 ((l_uint8)(factor * ((sval >> 16) & 0xff) + 0.5) << 16) |
1539 ((l_uint8)(factor * ((sval >> 8) & 0xff) + 0.5) << 8) |
1540 (sval & 0xff);
1541 return dval;
1542}
1543
1544
1564l_uint32
1565logScaleRGBVal(l_uint32 sval,
1566 l_float32 *tab,
1567 l_float32 factor)
1568{
1569l_uint32 dval;
1570
1571 dval = ((l_uint8)(factor * getLogBase2(sval >> 24, tab) + 0.5) << 24) |
1572 ((l_uint8)(factor * getLogBase2(((sval >> 16) & 0xff), tab) + 0.5)
1573 << 16) |
1574 ((l_uint8)(factor * getLogBase2(((sval >> 8) & 0xff), tab) + 0.5)
1575 << 8) |
1576 (sval & 0xff);
1577 return dval;
1578}
1579
1580
1581/*-----------------------------------------------------------------------*
1582 * Log base2 lookup *
1583 *-----------------------------------------------------------------------*/
1584/*
1585 * \brief makeLogBase2Tab()
1586 *
1587 * \return tab table giving the log[base2] of values from 1 to 255
1588 */
1589l_float32 *
1590makeLogBase2Tab(void)
1591{
1592l_int32 i;
1593l_float32 log2;
1594l_float32 *tab;
1595
1596 PROCNAME("makeLogBase2Tab");
1597
1598 if ((tab = (l_float32 *)LEPT_CALLOC(256, sizeof(l_float32))) == NULL)
1599 return (l_float32 *)ERROR_PTR("tab not made", procName, NULL);
1600
1601 log2 = (l_float32)log((l_float32)2);
1602 for (i = 0; i < 256; i++)
1603 tab[i] = (l_float32)log((l_float32)i) / log2;
1604
1605 return tab;
1606}
1607
1608
1609/*
1610 * \brief getLogBase2()
1611 *
1612 * \param[in] val in range [0 ... 255]
1613 * \param[in] logtab 256-entry table of logs
1614 * \return logval log[base2] of %val, or 0 on error
1615 */
1616l_float32
1617getLogBase2(l_int32 val,
1618 l_float32 *logtab)
1619{
1620 PROCNAME("getLogBase2");
1621
1622 if (!logtab)
1623 return ERROR_INT("logtab not defined", procName, 0);
1624
1625 if (val < 0x100)
1626 return logtab[val];
1627 else if (val < 0x10000)
1628 return 8.0 + logtab[val >> 8];
1629 else if (val < 0x1000000)
1630 return 16.0 + logtab[val >> 16];
1631 else
1632 return 24.0 + logtab[val >> 24];
1633}
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:168
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
l_int32 pixSizesEqual(const PIX *pix1, const PIX *pix2)
pixSizesEqual()
Definition: pix1.c:1985
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:383
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2751
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2820
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
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:2215
@ L_SELECT_MAX
Definition: pix.h:826
@ REMOVE_CMAP_TO_FULL_COLOR
Definition: pix.h:258
PIX * pixFinalAccumulateThreshold(PIX *pixs, l_uint32 offset, l_uint32 threshold)
pixFinalAccumulateThreshold()
Definition: pixarith.c:760
l_ok pixMultConstAccumulate(PIX *pixs, l_float32 factor, l_uint32 offset)
pixMultConstAccumulate()
Definition: pixarith.c:916
PIX * pixSubtractGray(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixSubtractGray()
Definition: pixarith.c:357
l_ok pixAddConstantGray(PIX *pixs, l_int32 val)
pixAddConstantGray()
Definition: pixarith.c:119
l_uint32 logScaleRGBVal(l_uint32 sval, l_float32 *tab, l_float32 factor)
logScaleRGBVal()
Definition: pixarith.c:1565
PIX * pixAddRGB(PIX *pixs1, PIX *pixs2)
pixAddRGB()
Definition: pixarith.c:1067
PIX * pixMaxDynamicRange(PIX *pixs, l_int32 type)
pixMaxDynamicRange()
Definition: pixarith.c:1253
l_ok pixMultConstantGray(PIX *pixs, l_float32 val)
pixMultConstantGray()
Definition: pixarith.c:190
PIX * pixMaxDynamicRangeRGB(PIX *pixs, l_int32 type)
pixMaxDynamicRangeRGB()
Definition: pixarith.c:1441
l_uint32 linearScaleRGBVal(l_uint32 sval, l_float32 factor)
linearScaleRGBVal()
Definition: pixarith.c:1532
PIX * pixMultiplyGray(PIX *pixs, PIX *pixg, l_float32 norm)
pixMultiplyGray()
Definition: pixarith.c:449
PIX * pixInitAccumulate(l_int32 w, l_int32 h, l_uint32 offset)
pixInitAccumulate()
Definition: pixarith.c:649
PIX * pixAddGray(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAddGray()
Definition: pixarith.c:265
PIX * pixFinalAccumulate(PIX *pixs, l_uint32 offset, l_int32 depth)
pixFinalAccumulate()
Definition: pixarith.c:683
PIX * pixThresholdToValue(PIX *pixd, PIX *pixs, l_int32 threshval, l_int32 setval)
pixThresholdToValue()
Definition: pixarith.c:540
PIX * pixAbsDifference(PIX *pixs1, PIX *pixs2)
pixAbsDifference()
Definition: pixarith.c:970
PIX * pixMinOrMax(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 type)
pixMinOrMax()
Definition: pixarith.c:1152
l_ok pixAccumulate(PIX *pixd, PIX *pixs, l_int32 op)
pixAccumulate()
Definition: pixarith.c:817
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
Definition: pix.h:139