Leptonica  1.77.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 
90 #include <string.h>
91 #include <math.h>
92 #include "allheaders.h"
93 
94 
95 /*-------------------------------------------------------------*
96  * One-image grayscale arithmetic operations *
97  *-------------------------------------------------------------*/
114 l_ok
116  l_int32 val)
117 {
118 l_int32 i, j, w, h, d, wpl, pval;
119 l_uint32 *data, *line;
120 
121  PROCNAME("pixAddConstantGray");
122 
123  if (!pixs)
124  return ERROR_INT("pixs not defined", procName, 1);
125  pixGetDimensions(pixs, &w, &h, &d);
126  if (d != 8 && d != 16 && d != 32)
127  return ERROR_INT("pixs not 8, 16 or 32 bpp", procName, 1);
128 
129  data = pixGetData(pixs);
130  wpl = pixGetWpl(pixs);
131  for (i = 0; i < h; i++) {
132  line = data + i * wpl;
133  if (d == 8) {
134  if (val < 0) {
135  for (j = 0; j < w; j++) {
136  pval = GET_DATA_BYTE(line, j);
137  pval = L_MAX(0, pval + val);
138  SET_DATA_BYTE(line, j, pval);
139  }
140  } else { /* val >= 0 */
141  for (j = 0; j < w; j++) {
142  pval = GET_DATA_BYTE(line, j);
143  pval = L_MIN(255, pval + val);
144  SET_DATA_BYTE(line, j, pval);
145  }
146  }
147  } else if (d == 16) {
148  if (val < 0) {
149  for (j = 0; j < w; j++) {
150  pval = GET_DATA_TWO_BYTES(line, j);
151  pval = L_MAX(0, pval + val);
152  SET_DATA_TWO_BYTES(line, j, pval);
153  }
154  } else { /* val >= 0 */
155  for (j = 0; j < w; j++) {
156  pval = GET_DATA_TWO_BYTES(line, j);
157  pval = L_MIN(0xffff, pval + val);
158  SET_DATA_TWO_BYTES(line, j, pval);
159  }
160  }
161  } else { /* d == 32; no check for overflow (< 0 or > 0xffffffff) */
162  for (j = 0; j < w; j++)
163  *(line + j) += val;
164  }
165  }
166 
167  return 0;
168 }
169 
170 
185 l_ok
187  l_float32 val)
188 {
189 l_int32 i, j, w, h, d, wpl, pval;
190 l_uint32 upval;
191 l_uint32 *data, *line;
192 
193  PROCNAME("pixMultConstantGray");
194 
195  if (!pixs)
196  return ERROR_INT("pixs not defined", procName, 1);
197  pixGetDimensions(pixs, &w, &h, &d);
198  if (d != 8 && d != 16 && d != 32)
199  return ERROR_INT("pixs not 8, 16 or 32 bpp", procName, 1);
200  if (val < 0.0)
201  return ERROR_INT("val < 0.0", procName, 1);
202 
203  data = pixGetData(pixs);
204  wpl = pixGetWpl(pixs);
205  for (i = 0; i < h; i++) {
206  line = data + i * wpl;
207  if (d == 8) {
208  for (j = 0; j < w; j++) {
209  pval = GET_DATA_BYTE(line, j);
210  pval = (l_int32)(val * pval);
211  pval = L_MIN(255, pval);
212  SET_DATA_BYTE(line, j, pval);
213  }
214  } else if (d == 16) {
215  for (j = 0; j < w; j++) {
216  pval = GET_DATA_TWO_BYTES(line, j);
217  pval = (l_int32)(val * pval);
218  pval = L_MIN(0xffff, pval);
219  SET_DATA_TWO_BYTES(line, j, pval);
220  }
221  } else { /* d == 32; no clipping */
222  for (j = 0; j < w; j++) {
223  upval = *(line + j);
224  upval = (l_uint32)(val * upval);
225  *(line + j) = upval;
226  }
227  }
228  }
229 
230  return 0;
231 }
232 
233 
234 /*-------------------------------------------------------------*
235  * Two-image grayscale arithmetic ops *
236  *-------------------------------------------------------------*/
260 PIX *
262  PIX *pixs1,
263  PIX *pixs2)
264 {
265 l_int32 i, j, d, ws, hs, w, h, wpls, wpld, val, sum;
266 l_uint32 *datas, *datad, *lines, *lined;
267 
268  PROCNAME("pixAddGray");
269 
270  if (!pixs1)
271  return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
272  if (!pixs2)
273  return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
274  if (pixs2 == pixs1)
275  return (PIX *)ERROR_PTR("pixs2 and pixs1 must differ", procName, pixd);
276  if (pixs2 == pixd)
277  return (PIX *)ERROR_PTR("pixs2 and pixd must differ", procName, pixd);
278  d = pixGetDepth(pixs1);
279  if (d != 8 && d != 16 && d != 32)
280  return (PIX *)ERROR_PTR("pix are not 8, 16 or 32 bpp", procName, pixd);
281  if (pixGetDepth(pixs2) != d)
282  return (PIX *)ERROR_PTR("depths differ (pixs1, pixs2)", procName, pixd);
283  if (pixd && (pixGetDepth(pixd) != d))
284  return (PIX *)ERROR_PTR("depths differ (pixs1, pixd)", procName, pixd);
285 
286  if (!pixSizesEqual(pixs1, pixs2))
287  L_WARNING("pixs1 and pixs2 not equal in size\n", procName);
288  if (pixd && !pixSizesEqual(pixs1, pixd))
289  L_WARNING("pixs1 and pixd not equal in size\n", procName);
290 
291  if (pixs1 != pixd)
292  pixd = pixCopy(pixd, pixs1);
293 
294  /* pixd + pixs2 ==> pixd */
295  datas = pixGetData(pixs2);
296  datad = pixGetData(pixd);
297  wpls = pixGetWpl(pixs2);
298  wpld = pixGetWpl(pixd);
299  pixGetDimensions(pixs2, &ws, &hs, NULL);
300  pixGetDimensions(pixd, &w, &h, NULL);
301  w = L_MIN(ws, w);
302  h = L_MIN(hs, h);
303  for (i = 0; i < h; i++) {
304  lined = datad + i * wpld;
305  lines = datas + i * wpls;
306  if (d == 8) {
307  for (j = 0; j < w; j++) {
308  sum = GET_DATA_BYTE(lines, j) + GET_DATA_BYTE(lined, j);
309  val = L_MIN(sum, 255);
310  SET_DATA_BYTE(lined, j, val);
311  }
312  } else if (d == 16) {
313  for (j = 0; j < w; j++) {
314  sum = GET_DATA_TWO_BYTES(lines, j)
315  + GET_DATA_TWO_BYTES(lined, j);
316  val = L_MIN(sum, 0xffff);
317  SET_DATA_TWO_BYTES(lined, j, val);
318  }
319  } else { /* d == 32; no clipping */
320  for (j = 0; j < w; j++)
321  *(lined + j) += *(lines + j);
322  }
323  }
324 
325  return pixd;
326 }
327 
328 
352 PIX *
354  PIX *pixs1,
355  PIX *pixs2)
356 {
357 l_int32 i, j, w, h, ws, hs, d, wpls, wpld, val, diff;
358 l_uint32 *datas, *datad, *lines, *lined;
359 
360  PROCNAME("pixSubtractGray");
361 
362  if (!pixs1)
363  return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
364  if (!pixs2)
365  return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
366  if (pixs2 == pixs1)
367  return (PIX *)ERROR_PTR("pixs2 and pixs1 must differ", procName, pixd);
368  if (pixs2 == pixd)
369  return (PIX *)ERROR_PTR("pixs2 and pixd must differ", procName, pixd);
370  d = pixGetDepth(pixs1);
371  if (d != 8 && d != 16 && d != 32)
372  return (PIX *)ERROR_PTR("pix are not 8, 16 or 32 bpp", procName, pixd);
373  if (pixGetDepth(pixs2) != d)
374  return (PIX *)ERROR_PTR("depths differ (pixs1, pixs2)", procName, pixd);
375  if (pixd && (pixGetDepth(pixd) != d))
376  return (PIX *)ERROR_PTR("depths differ (pixs1, pixd)", procName, pixd);
377 
378  if (!pixSizesEqual(pixs1, pixs2))
379  L_WARNING("pixs1 and pixs2 not equal in size\n", procName);
380  if (pixd && !pixSizesEqual(pixs1, pixd))
381  L_WARNING("pixs1 and pixd not equal in size\n", procName);
382 
383  if (pixs1 != pixd)
384  pixd = pixCopy(pixd, pixs1);
385 
386  /* pixd - pixs2 ==> pixd */
387  datas = pixGetData(pixs2);
388  datad = pixGetData(pixd);
389  wpls = pixGetWpl(pixs2);
390  wpld = pixGetWpl(pixd);
391  pixGetDimensions(pixs2, &ws, &hs, NULL);
392  pixGetDimensions(pixd, &w, &h, NULL);
393  w = L_MIN(ws, w);
394  h = L_MIN(hs, h);
395  for (i = 0; i < h; i++) {
396  lined = datad + i * wpld;
397  lines = datas + i * wpls;
398  if (d == 8) {
399  for (j = 0; j < w; j++) {
400  diff = GET_DATA_BYTE(lined, j) - GET_DATA_BYTE(lines, j);
401  val = L_MAX(diff, 0);
402  SET_DATA_BYTE(lined, j, val);
403  }
404  } else if (d == 16) {
405  for (j = 0; j < w; j++) {
406  diff = GET_DATA_TWO_BYTES(lined, j)
407  - GET_DATA_TWO_BYTES(lines, j);
408  val = L_MAX(diff, 0);
409  SET_DATA_TWO_BYTES(lined, j, val);
410  }
411  } else { /* d == 32; no clipping */
412  for (j = 0; j < w; j++)
413  *(lined + j) -= *(lines + j);
414  }
415  }
416 
417  return pixd;
418 }
419 
420 
421 /*-------------------------------------------------------------*
422  * Grayscale threshold operation *
423  *-------------------------------------------------------------*/
441 PIX *
443  PIX *pixs,
444  l_int32 threshval,
445  l_int32 setval)
446 {
447 l_int32 i, j, w, h, d, wpld, setabove;
448 l_uint32 *datad, *lined;
449 
450  PROCNAME("pixThresholdToValue");
451 
452  if (!pixs)
453  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
454  d = pixGetDepth(pixs);
455  if (d != 8 && d != 16 && d != 32)
456  return (PIX *)ERROR_PTR("pixs not 8, 16 or 32 bpp", procName, pixd);
457  if (pixd && (pixs != pixd))
458  return (PIX *)ERROR_PTR("pixd exists and is not pixs", procName, pixd);
459  if (threshval < 0 || setval < 0)
460  return (PIX *)ERROR_PTR("threshval & setval not < 0", procName, pixd);
461  if (d == 8 && setval > 255)
462  return (PIX *)ERROR_PTR("setval > 255 for 8 bpp", procName, pixd);
463  if (d == 16 && setval > 0xffff)
464  return (PIX *)ERROR_PTR("setval > 0xffff for 16 bpp", procName, pixd);
465 
466  if (!pixd)
467  pixd = pixCopy(NULL, pixs);
468  if (setval == threshval) {
469  L_WARNING("setval == threshval; no operation\n", procName);
470  return pixd;
471  }
472 
473  datad = pixGetData(pixd);
474  pixGetDimensions(pixd, &w, &h, NULL);
475  wpld = pixGetWpl(pixd);
476  if (setval > threshval)
477  setabove = TRUE;
478  else
479  setabove = FALSE;
480 
481  for (i = 0; i < h; i++) {
482  lined = datad + i * wpld;
483  if (setabove == TRUE) {
484  if (d == 8) {
485  for (j = 0; j < w; j++) {
486  if (GET_DATA_BYTE(lined, j) - threshval >= 0)
487  SET_DATA_BYTE(lined, j, setval);
488  }
489  } else if (d == 16) {
490  for (j = 0; j < w; j++) {
491  if (GET_DATA_TWO_BYTES(lined, j) - threshval >= 0)
492  SET_DATA_TWO_BYTES(lined, j, setval);
493  }
494  } else { /* d == 32 */
495  for (j = 0; j < w; j++) {
496  if (*(lined + j) >= threshval)
497  *(lined + j) = setval;
498  }
499  }
500  } else { /* set if below or at threshold */
501  if (d == 8) {
502  for (j = 0; j < w; j++) {
503  if (GET_DATA_BYTE(lined, j) - threshval <= 0)
504  SET_DATA_BYTE(lined, j, setval);
505  }
506  } else if (d == 16) {
507  for (j = 0; j < w; j++) {
508  if (GET_DATA_TWO_BYTES(lined, j) - threshval <= 0)
509  SET_DATA_TWO_BYTES(lined, j, setval);
510  }
511  } else { /* d == 32 */
512  for (j = 0; j < w; j++) {
513  if (*(lined + j) <= threshval)
514  *(lined + j) = setval;
515  }
516  }
517  }
518  }
519 
520  return pixd;
521 }
522 
523 
524 /*-------------------------------------------------------------*
525  * Image accumulator arithmetic operations *
526  *-------------------------------------------------------------*/
550 PIX *
552  l_int32 h,
553  l_uint32 offset)
554 {
555 PIX *pixd;
556 
557  PROCNAME("pixInitAccumulate");
558 
559  if ((pixd = pixCreate(w, h, 32)) == NULL)
560  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
561  if (offset > 0x40000000)
562  offset = 0x40000000;
563  pixSetAllArbitrary(pixd, offset);
564  return pixd;
565 }
566 
567 
584 PIX *
586  l_uint32 offset,
587  l_int32 depth)
588 {
589 l_int32 i, j, w, h, wpls, wpld, val;
590 l_uint32 *datas, *datad, *lines, *lined;
591 PIX *pixd;
592 
593  PROCNAME("pixFinalAccumulate");
594 
595  if (!pixs)
596  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
597  if (pixGetDepth(pixs) != 32)
598  return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
599  if (depth != 8 && depth != 16 && depth != 32)
600  return (PIX *)ERROR_PTR("dest depth not 8, 16, 32 bpp", procName, NULL);
601  if (offset > 0x40000000)
602  offset = 0x40000000;
603 
604  pixGetDimensions(pixs, &w, &h, NULL);
605  if ((pixd = pixCreate(w, h, depth)) == NULL)
606  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
607  pixCopyResolution(pixd, pixs); /* but how did pixs get it initially? */
608  datas = pixGetData(pixs);
609  datad = pixGetData(pixd);
610  wpls = pixGetWpl(pixs);
611  wpld = pixGetWpl(pixd);
612  if (depth == 8) {
613  for (i = 0; i < h; i++) {
614  lines = datas + i * wpls;
615  lined = datad + i * wpld;
616  for (j = 0; j < w; j++) {
617  val = lines[j] - offset;
618  val = L_MAX(0, val);
619  val = L_MIN(255, val);
620  SET_DATA_BYTE(lined, j, (l_uint8)val);
621  }
622  }
623  } else if (depth == 16) {
624  for (i = 0; i < h; i++) {
625  lines = datas + i * wpls;
626  lined = datad + i * wpld;
627  for (j = 0; j < w; j++) {
628  val = lines[j] - offset;
629  val = L_MAX(0, val);
630  val = L_MIN(0xffff, val);
631  SET_DATA_TWO_BYTES(lined, j, (l_uint16)val);
632  }
633  }
634  } else { /* depth == 32 */
635  for (i = 0; i < h; i++) {
636  lines = datas + i * wpls;
637  lined = datad + i * wpld;
638  for (j = 0; j < w; j++)
639  lined[j] = lines[j] - offset;
640  }
641  }
642 
643  return pixd;
644 }
645 
646 
661 PIX *
663  l_uint32 offset,
664  l_uint32 threshold)
665 {
666 l_int32 i, j, w, h, wpls, wpld, val;
667 l_uint32 *datas, *datad, *lines, *lined;
668 PIX *pixd;
669 
670  PROCNAME("pixFinalAccumulateThreshold");
671 
672  if (!pixs)
673  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
674  if (pixGetDepth(pixs) != 32)
675  return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
676  if (offset > 0x40000000)
677  offset = 0x40000000;
678 
679  pixGetDimensions(pixs, &w, &h, NULL);
680  if ((pixd = pixCreate(w, h, 1)) == NULL)
681  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
682  pixCopyResolution(pixd, pixs); /* but how did pixs get it initially? */
683  datas = pixGetData(pixs);
684  datad = pixGetData(pixd);
685  wpls = pixGetWpl(pixs);
686  wpld = pixGetWpl(pixd);
687  for (i = 0; i < h; i++) {
688  lines = datas + i * wpls;
689  lined = datad + i * wpld;
690  for (j = 0; j < w; j++) {
691  val = lines[j] - offset;
692  if (val >= threshold) {
693  SET_DATA_BIT(lined, j);
694  }
695  }
696  }
697 
698  return pixd;
699 }
700 
701 
718 l_ok
720  PIX *pixs,
721  l_int32 op)
722 {
723 l_int32 i, j, w, h, d, wd, hd, wpls, wpld;
724 l_uint32 *datas, *datad, *lines, *lined;
725 
726 
727  PROCNAME("pixAccumulate");
728 
729  if (!pixd || (pixGetDepth(pixd) != 32))
730  return ERROR_INT("pixd not defined or not 32 bpp", procName, 1);
731  if (!pixs)
732  return ERROR_INT("pixs not defined", procName, 1);
733  d = pixGetDepth(pixs);
734  if (d != 1 && d != 8 && d != 16 && d != 32)
735  return ERROR_INT("pixs not 1, 8, 16 or 32 bpp", procName, 1);
736  if (op != L_ARITH_ADD && op != L_ARITH_SUBTRACT)
737  return ERROR_INT("op must be in {L_ARITH_ADD, L_ARITH_SUBTRACT}",
738  procName, 1);
739 
740  datas = pixGetData(pixs);
741  datad = pixGetData(pixd);
742  wpls = pixGetWpl(pixs);
743  wpld = pixGetWpl(pixd);
744  pixGetDimensions(pixs, &w, &h, NULL);
745  pixGetDimensions(pixd, &wd, &hd, NULL);
746  w = L_MIN(w, wd);
747  h = L_MIN(h, hd);
748  if (d == 1) {
749  for (i = 0; i < h; i++) {
750  lines = datas + i * wpls;
751  lined = datad + i * wpld;
752  if (op == L_ARITH_ADD) {
753  for (j = 0; j < w; j++)
754  lined[j] += GET_DATA_BIT(lines, j);
755  } else { /* op == L_ARITH_SUBTRACT */
756  for (j = 0; j < w; j++)
757  lined[j] -= GET_DATA_BIT(lines, j);
758  }
759  }
760  } else if (d == 8) {
761  for (i = 0; i < h; i++) {
762  lines = datas + i * wpls;
763  lined = datad + i * wpld;
764  if (op == L_ARITH_ADD) {
765  for (j = 0; j < w; j++)
766  lined[j] += GET_DATA_BYTE(lines, j);
767  } else { /* op == L_ARITH_SUBTRACT */
768  for (j = 0; j < w; j++)
769  lined[j] -= GET_DATA_BYTE(lines, j);
770  }
771  }
772  } else if (d == 16) {
773  for (i = 0; i < h; i++) {
774  lines = datas + i * wpls;
775  lined = datad + i * wpld;
776  if (op == L_ARITH_ADD) {
777  for (j = 0; j < w; j++)
778  lined[j] += GET_DATA_TWO_BYTES(lines, j);
779  } else { /* op == L_ARITH_SUBTRACT */
780  for (j = 0; j < w; j++)
781  lined[j] -= GET_DATA_TWO_BYTES(lines, j);
782  }
783  }
784  } else { /* d == 32 */
785  for (i = 0; i < h; i++) {
786  lines = datas + i * wpls;
787  lined = datad + i * wpld;
788  if (op == L_ARITH_ADD) {
789  for (j = 0; j < w; j++)
790  lined[j] += lines[j];
791  } else { /* op == L_ARITH_SUBTRACT */
792  for (j = 0; j < w; j++)
793  lined[j] -= lines[j];
794  }
795  }
796  }
797 
798  return 0;
799 }
800 
801 
817 l_ok
819  l_float32 factor,
820  l_uint32 offset)
821 {
822 l_int32 i, j, w, h, wpl, val;
823 l_uint32 *data, *line;
824 
825  PROCNAME("pixMultConstAccumulate");
826 
827  if (!pixs)
828  return ERROR_INT("pixs not defined", procName, 1);
829  if (pixGetDepth(pixs) != 32)
830  return ERROR_INT("pixs not 32 bpp", procName, 1);
831  if (offset > 0x40000000)
832  offset = 0x40000000;
833 
834  pixGetDimensions(pixs, &w, &h, NULL);
835  data = pixGetData(pixs);
836  wpl = pixGetWpl(pixs);
837  for (i = 0; i < h; i++) {
838  line = data + i * wpl;
839  for (j = 0; j < w; j++) {
840  val = line[j] - offset;
841  val = (l_int32)(val * factor);
842  val += offset;
843  line[j] = (l_uint32)val;
844  }
845  }
846 
847  return 0;
848 }
849 
850 
851 /*-----------------------------------------------------------------------*
852  * Absolute value of difference *
853  *-----------------------------------------------------------------------*/
871 PIX *
873  PIX *pixs2)
874 {
875 l_int32 i, j, w, h, w2, h2, d, wpls1, wpls2, wpld, val1, val2, diff;
876 l_int32 rval1, gval1, bval1, rval2, gval2, bval2, rdiff, gdiff, bdiff;
877 l_uint32 *datas1, *datas2, *datad, *lines1, *lines2, *lined;
878 PIX *pixd;
879 
880  PROCNAME("pixAbsDifference");
881 
882  if (!pixs1)
883  return (PIX *)ERROR_PTR("pixs1 not defined", procName, NULL);
884  if (!pixs2)
885  return (PIX *)ERROR_PTR("pixs2 not defined", procName, NULL);
886  d = pixGetDepth(pixs1);
887  if (d != pixGetDepth(pixs2))
888  return (PIX *)ERROR_PTR("src1 and src2 depths unequal", procName, NULL);
889  if (d != 8 && d != 16 && d != 32)
890  return (PIX *)ERROR_PTR("depths not in {8, 16, 32}", procName, NULL);
891 
892  pixGetDimensions(pixs1, &w, &h, NULL);
893  pixGetDimensions(pixs2, &w2, &h2, NULL);
894  w = L_MIN(w, w2);
895  h = L_MIN(h, h2);
896  if ((pixd = pixCreate(w, h, d)) == NULL)
897  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
898  pixCopyResolution(pixd, pixs1);
899  datas1 = pixGetData(pixs1);
900  datas2 = pixGetData(pixs2);
901  datad = pixGetData(pixd);
902  wpls1 = pixGetWpl(pixs1);
903  wpls2 = pixGetWpl(pixs2);
904  wpld = pixGetWpl(pixd);
905  if (d == 8) {
906  for (i = 0; i < h; i++) {
907  lines1 = datas1 + i * wpls1;
908  lines2 = datas2 + i * wpls2;
909  lined = datad + i * wpld;
910  for (j = 0; j < w; j++) {
911  val1 = GET_DATA_BYTE(lines1, j);
912  val2 = GET_DATA_BYTE(lines2, j);
913  diff = L_ABS(val1 - val2);
914  SET_DATA_BYTE(lined, j, diff);
915  }
916  }
917  } else if (d == 16) {
918  for (i = 0; i < h; i++) {
919  lines1 = datas1 + i * wpls1;
920  lines2 = datas2 + i * wpls2;
921  lined = datad + i * wpld;
922  for (j = 0; j < w; j++) {
923  val1 = GET_DATA_TWO_BYTES(lines1, j);
924  val2 = GET_DATA_TWO_BYTES(lines2, j);
925  diff = L_ABS(val1 - val2);
926  SET_DATA_TWO_BYTES(lined, j, diff);
927  }
928  }
929  } else { /* d == 32 */
930  for (i = 0; i < h; i++) {
931  lines1 = datas1 + i * wpls1;
932  lines2 = datas2 + i * wpls2;
933  lined = datad + i * wpld;
934  for (j = 0; j < w; j++) {
935  extractRGBValues(lines1[j], &rval1, &gval1, &bval1);
936  extractRGBValues(lines2[j], &rval2, &gval2, &bval2);
937  rdiff = L_ABS(rval1 - rval2);
938  gdiff = L_ABS(gval1 - gval2);
939  bdiff = L_ABS(bval1 - bval2);
940  composeRGBPixel(rdiff, gdiff, bdiff, lined + j);
941  }
942  }
943  }
944 
945  return pixd;
946 }
947 
948 
949 /*-----------------------------------------------------------------------*
950  * Sum of color images *
951  *-----------------------------------------------------------------------*/
968 PIX *
969 pixAddRGB(PIX *pixs1,
970  PIX *pixs2)
971 {
972 l_int32 i, j, w, h, d, w2, h2, d2, wplc1, wplc2, wpld;
973 l_int32 rval1, gval1, bval1, rval2, gval2, bval2, rval, gval, bval;
974 l_uint32 *datac1, *datac2, *datad, *linec1, *linec2, *lined;
975 PIX *pixc1, *pixc2, *pixd;
976 
977  PROCNAME("pixAddRGB");
978 
979  if (!pixs1)
980  return (PIX *)ERROR_PTR("pixs1 not defined", procName, NULL);
981  if (!pixs2)
982  return (PIX *)ERROR_PTR("pixs2 not defined", procName, NULL);
983  pixGetDimensions(pixs1, &w, &h, &d);
984  pixGetDimensions(pixs2, &w2, &h2, &d2);
985  if (!pixGetColormap(pixs1) && d != 32)
986  return (PIX *)ERROR_PTR("pixs1 not cmapped or rgb", procName, NULL);
987  if (!pixGetColormap(pixs2) && d2 != 32)
988  return (PIX *)ERROR_PTR("pixs2 not cmapped or rgb", procName, NULL);
989  if (pixGetColormap(pixs1))
991  else
992  pixc1 = pixClone(pixs1);
993  if (pixGetColormap(pixs2))
995  else
996  pixc2 = pixClone(pixs2);
997 
998  w = L_MIN(w, w2);
999  h = L_MIN(h, h2);
1000  pixd = pixCreate(w, h, 32);
1001  pixCopyResolution(pixd, pixs1);
1002  datac1 = pixGetData(pixc1);
1003  datac2 = pixGetData(pixc2);
1004  datad = pixGetData(pixd);
1005  wplc1 = pixGetWpl(pixc1);
1006  wplc2 = pixGetWpl(pixc2);
1007  wpld = pixGetWpl(pixd);
1008  for (i = 0; i < h; i++) {
1009  linec1 = datac1 + i * wplc1;
1010  linec2 = datac2 + i * wplc2;
1011  lined = datad + i * wpld;
1012  for (j = 0; j < w; j++) {
1013  extractRGBValues(linec1[j], &rval1, &gval1, &bval1);
1014  extractRGBValues(linec2[j], &rval2, &gval2, &bval2);
1015  rval = L_MIN(255, rval1 + rval2);
1016  gval = L_MIN(255, gval1 + gval2);
1017  bval = L_MIN(255, bval1 + bval2);
1018  composeRGBPixel(rval, gval, bval, lined + j);
1019  }
1020  }
1021 
1022  pixDestroy(&pixc1);
1023  pixDestroy(&pixc2);
1024  return pixd;
1025 }
1026 
1027 
1028 /*-----------------------------------------------------------------------*
1029  * Two-image min and max operations (8 and 16 bpp) *
1030  *-----------------------------------------------------------------------*/
1053 PIX *
1055  PIX *pixs1,
1056  PIX *pixs2,
1057  l_int32 type)
1058 {
1059 l_int32 d, ws, hs, w, h, wpls, wpld, i, j, vals, vald, val;
1060 l_int32 rval1, gval1, bval1, rval2, gval2, bval2, rval, gval, bval;
1061 l_uint32 *datas, *datad, *lines, *lined;
1062 
1063  PROCNAME("pixMinOrMax");
1064 
1065  if (!pixs1)
1066  return (PIX *)ERROR_PTR("pixs1 not defined", procName, pixd);
1067  if (!pixs2)
1068  return (PIX *)ERROR_PTR("pixs2 not defined", procName, pixd);
1069  if (pixs1 == pixs2)
1070  return (PIX *)ERROR_PTR("pixs1 and pixs2 must differ", procName, pixd);
1071  if (type != L_CHOOSE_MIN && type != L_CHOOSE_MAX)
1072  return (PIX *)ERROR_PTR("invalid type", procName, pixd);
1073  d = pixGetDepth(pixs1);
1074  if (pixGetDepth(pixs2) != d)
1075  return (PIX *)ERROR_PTR("depths unequal", procName, pixd);
1076  if (d != 8 && d != 16 && d != 32)
1077  return (PIX *)ERROR_PTR("depth not 8, 16 or 32 bpp", procName, pixd);
1078 
1079  if (pixs1 != pixd)
1080  pixd = pixCopy(pixd, pixs1);
1081 
1082  pixGetDimensions(pixs2, &ws, &hs, NULL);
1083  pixGetDimensions(pixd, &w, &h, NULL);
1084  w = L_MIN(w, ws);
1085  h = L_MIN(h, hs);
1086  datas = pixGetData(pixs2);
1087  datad = pixGetData(pixd);
1088  wpls = pixGetWpl(pixs2);
1089  wpld = pixGetWpl(pixd);
1090  for (i = 0; i < h; i++) {
1091  lines = datas + i * wpls;
1092  lined = datad + i * wpld;
1093  if (d == 8) {
1094  for (j = 0; j < w; j++) {
1095  vals = GET_DATA_BYTE(lines, j);
1096  vald = GET_DATA_BYTE(lined, j);
1097  if (type == L_CHOOSE_MIN)
1098  val = L_MIN(vals, vald);
1099  else /* type == L_CHOOSE_MAX */
1100  val = L_MAX(vals, vald);
1101  SET_DATA_BYTE(lined, j, val);
1102  }
1103  } else if (d == 16) {
1104  for (j = 0; j < w; j++) {
1105  vals = GET_DATA_TWO_BYTES(lines, j);
1106  vald = GET_DATA_TWO_BYTES(lined, j);
1107  if (type == L_CHOOSE_MIN)
1108  val = L_MIN(vals, vald);
1109  else /* type == L_CHOOSE_MAX */
1110  val = L_MAX(vals, vald);
1111  SET_DATA_TWO_BYTES(lined, j, val);
1112  }
1113  } else { /* d == 32 */
1114  for (j = 0; j < w; j++) {
1115  extractRGBValues(lines[j], &rval1, &gval1, &bval1);
1116  extractRGBValues(lined[j], &rval2, &gval2, &bval2);
1117  if (type == L_CHOOSE_MIN) {
1118  rval = L_MIN(rval1, rval2);
1119  gval = L_MIN(gval1, gval2);
1120  bval = L_MIN(bval1, bval2);
1121  } else { /* type == L_CHOOSE_MAX */
1122  rval = L_MAX(rval1, rval2);
1123  gval = L_MAX(gval1, gval2);
1124  bval = L_MAX(bval1, bval2);
1125  }
1126  composeRGBPixel(rval, gval, bval, lined + j);
1127  }
1128  }
1129  }
1130 
1131  return pixd;
1132 }
1133 
1134 
1135 /*-----------------------------------------------------------------------*
1136  * Scale for maximum dynamic range *
1137  *-----------------------------------------------------------------------*/
1154 PIX *
1156  l_int32 type)
1157 {
1158 l_uint8 dval;
1159 l_int32 i, j, w, h, d, wpls, wpld, max;
1160 l_uint32 *datas, *datad;
1161 l_uint32 word, sval;
1162 l_uint32 *lines, *lined;
1163 l_float32 factor;
1164 l_float32 *tab;
1165 PIX *pixd;
1166 
1167  PROCNAME("pixMaxDynamicRange");
1168 
1169  if (!pixs)
1170  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1171  pixGetDimensions(pixs, &w, &h, &d);
1172  if (d != 4 && d != 8 && d != 16 && d != 32)
1173  return (PIX *)ERROR_PTR("pixs not in {4,8,16,32} bpp", procName, NULL);
1174  if (type != L_LINEAR_SCALE && type != L_LOG_SCALE)
1175  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1176 
1177  if ((pixd = pixCreate(w, h, 8)) == NULL)
1178  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1179  pixCopyResolution(pixd, pixs);
1180  datas = pixGetData(pixs);
1181  datad = pixGetData(pixd);
1182  wpls = pixGetWpl(pixs);
1183  wpld = pixGetWpl(pixd);
1184 
1185  /* Get max */
1186  max = 0;
1187  for (i = 0; i < h; i++) {
1188  lines = datas + i * wpls;
1189  for (j = 0; j < wpls; j++) {
1190  word = *(lines + j);
1191  if (d == 4) {
1192  max = L_MAX(max, word >> 28);
1193  max = L_MAX(max, (word >> 24) & 0xf);
1194  max = L_MAX(max, (word >> 20) & 0xf);
1195  max = L_MAX(max, (word >> 16) & 0xf);
1196  max = L_MAX(max, (word >> 12) & 0xf);
1197  max = L_MAX(max, (word >> 8) & 0xf);
1198  max = L_MAX(max, (word >> 4) & 0xf);
1199  max = L_MAX(max, word & 0xf);
1200  } else if (d == 8) {
1201  max = L_MAX(max, word >> 24);
1202  max = L_MAX(max, (word >> 16) & 0xff);
1203  max = L_MAX(max, (word >> 8) & 0xff);
1204  max = L_MAX(max, word & 0xff);
1205  } else if (d == 16) {
1206  max = L_MAX(max, word >> 16);
1207  max = L_MAX(max, word & 0xffff);
1208  } else { /* d == 32 (rgb) */
1209  max = L_MAX(max, word);
1210  }
1211  }
1212  }
1213 
1214  /* Map to the full dynamic range */
1215  if (d == 4) {
1216  if (type == L_LINEAR_SCALE) {
1217  factor = 255. / (l_float32)max;
1218  for (i = 0; i < h; i++) {
1219  lines = datas + i * wpls;
1220  lined = datad + i * wpld;
1221  for (j = 0; j < w; j++) {
1222  sval = GET_DATA_QBIT(lines, j);
1223  dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1224  SET_DATA_QBIT(lined, j, dval);
1225  }
1226  }
1227  } else { /* type == L_LOG_SCALE) */
1228  tab = makeLogBase2Tab();
1229  factor = 255. / getLogBase2(max, tab);
1230  for (i = 0; i < h; i++) {
1231  lines = datas + i * wpls;
1232  lined = datad + i * wpld;
1233  for (j = 0; j < w; j++) {
1234  sval = GET_DATA_QBIT(lines, j);
1235  dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1236  SET_DATA_BYTE(lined, j, dval);
1237  }
1238  }
1239  LEPT_FREE(tab);
1240  }
1241  } else if (d == 8) {
1242  if (type == L_LINEAR_SCALE) {
1243  factor = 255. / (l_float32)max;
1244  for (i = 0; i < h; i++) {
1245  lines = datas + i * wpls;
1246  lined = datad + i * wpld;
1247  for (j = 0; j < w; j++) {
1248  sval = GET_DATA_BYTE(lines, j);
1249  dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1250  SET_DATA_BYTE(lined, j, dval);
1251  }
1252  }
1253  } else { /* type == L_LOG_SCALE) */
1254  tab = makeLogBase2Tab();
1255  factor = 255. / getLogBase2(max, tab);
1256  for (i = 0; i < h; i++) {
1257  lines = datas + i * wpls;
1258  lined = datad + i * wpld;
1259  for (j = 0; j < w; j++) {
1260  sval = GET_DATA_BYTE(lines, j);
1261  dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1262  SET_DATA_BYTE(lined, j, dval);
1263  }
1264  }
1265  LEPT_FREE(tab);
1266  }
1267  } else if (d == 16) {
1268  if (type == L_LINEAR_SCALE) {
1269  factor = 255. / (l_float32)max;
1270  for (i = 0; i < h; i++) {
1271  lines = datas + i * wpls;
1272  lined = datad + i * wpld;
1273  for (j = 0; j < w; j++) {
1274  sval = GET_DATA_TWO_BYTES(lines, j);
1275  dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1276  SET_DATA_BYTE(lined, j, dval);
1277  }
1278  }
1279  } else { /* type == L_LOG_SCALE) */
1280  tab = makeLogBase2Tab();
1281  factor = 255. / getLogBase2(max, tab);
1282  for (i = 0; i < h; i++) {
1283  lines = datas + i * wpls;
1284  lined = datad + i * wpld;
1285  for (j = 0; j < w; j++) {
1286  sval = GET_DATA_TWO_BYTES(lines, j);
1287  dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1288  SET_DATA_BYTE(lined, j, dval);
1289  }
1290  }
1291  LEPT_FREE(tab);
1292  }
1293  } else { /* d == 32 */
1294  if (type == L_LINEAR_SCALE) {
1295  factor = 255. / (l_float32)max;
1296  for (i = 0; i < h; i++) {
1297  lines = datas + i * wpls;
1298  lined = datad + i * wpld;
1299  for (j = 0; j < w; j++) {
1300  sval = lines[j];
1301  dval = (l_uint8)(factor * (l_float32)sval + 0.5);
1302  SET_DATA_BYTE(lined, j, dval);
1303  }
1304  }
1305  } else { /* type == L_LOG_SCALE) */
1306  tab = makeLogBase2Tab();
1307  factor = 255. / getLogBase2(max, tab);
1308  for (i = 0; i < h; i++) {
1309  lines = datas + i * wpls;
1310  lined = datad + i * wpld;
1311  for (j = 0; j < w; j++) {
1312  sval = lines[j];
1313  dval = (l_uint8)(factor * getLogBase2(sval, tab) + 0.5);
1314  SET_DATA_BYTE(lined, j, dval);
1315  }
1316  }
1317  LEPT_FREE(tab);
1318  }
1319  }
1320 
1321  return pixd;
1322 }
1323 
1324 
1342 PIX *
1344  l_int32 type)
1345 {
1346 l_int32 i, j, w, h, wpls, wpld, max;
1347 l_uint32 sval, dval, word;
1348 l_uint32 *datas, *datad;
1349 l_uint32 *lines, *lined;
1350 l_float32 factor;
1351 l_float32 *tab;
1352 PIX *pixd;
1353 
1354  PROCNAME("pixMaxDynamicRangeRGB");
1355 
1356  if (!pixs || pixGetDepth(pixs) != 32)
1357  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
1358  if (type != L_LINEAR_SCALE && type != L_LOG_SCALE)
1359  return (PIX *)ERROR_PTR("invalid type", procName, NULL);
1360 
1361  /* Get max */
1362  pixd = pixCreateTemplate(pixs);
1363  datas = pixGetData(pixs);
1364  datad = pixGetData(pixd);
1365  wpls = pixGetWpl(pixs);
1366  wpld = pixGetWpl(pixd);
1367  pixGetDimensions(pixs, &w, &h, NULL);
1368  max = 0;
1369  for (i = 0; i < h; i++) {
1370  lines = datas + i * wpls;
1371  for (j = 0; j < wpls; j++) {
1372  word = lines[j];
1373  max = L_MAX(max, word >> 24);
1374  max = L_MAX(max, (word >> 16) & 0xff);
1375  max = L_MAX(max, (word >> 8) & 0xff);
1376  }
1377  }
1378 
1379  /* Map to the full dynamic range */
1380  if (type == L_LINEAR_SCALE) {
1381  factor = 255. / (l_float32)max;
1382  for (i = 0; i < h; i++) {
1383  lines = datas + i * wpls;
1384  lined = datad + i * wpld;
1385  for (j = 0; j < w; j++) {
1386  sval = lines[j];
1387  dval = linearScaleRGBVal(sval, factor);
1388  lined[j] = dval;
1389  }
1390  }
1391  } else { /* type == L_LOG_SCALE) */
1392  tab = makeLogBase2Tab();
1393  factor = 255. / getLogBase2(max, tab);
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 = logScaleRGBVal(sval, tab, factor);
1400  lined[j] = dval;
1401  }
1402  }
1403  LEPT_FREE(tab);
1404  }
1405 
1406  return pixd;
1407 }
1408 
1409 
1410 /*-----------------------------------------------------------------------*
1411  * RGB pixel value scaling *
1412  *-----------------------------------------------------------------------*/
1429 l_uint32
1430 linearScaleRGBVal(l_uint32 sval,
1431  l_float32 factor)
1432 {
1433 l_uint32 dval;
1434 
1435  dval = ((l_uint8)(factor * (sval >> 24) + 0.5) << 24) |
1436  ((l_uint8)(factor * ((sval >> 16) & 0xff) + 0.5) << 16) |
1437  ((l_uint8)(factor * ((sval >> 8) & 0xff) + 0.5) << 8) |
1438  (sval & 0xff);
1439  return dval;
1440 }
1441 
1442 
1462 l_uint32
1463 logScaleRGBVal(l_uint32 sval,
1464  l_float32 *tab,
1465  l_float32 factor)
1466 {
1467 l_uint32 dval;
1468 
1469  dval = ((l_uint8)(factor * getLogBase2(sval >> 24, tab) + 0.5) << 24) |
1470  ((l_uint8)(factor * getLogBase2(((sval >> 16) & 0xff), tab) + 0.5)
1471  << 16) |
1472  ((l_uint8)(factor * getLogBase2(((sval >> 8) & 0xff), tab) + 0.5)
1473  << 8) |
1474  (sval & 0xff);
1475  return dval;
1476 }
1477 
1478 
1479 /*-----------------------------------------------------------------------*
1480  * Log base2 lookup *
1481  *-----------------------------------------------------------------------*/
1482 /*
1483  * \brief makeLogBase2Tab()
1484  *
1485  * \return tab table giving the log[base2] of values from 1 to 255
1486  */
1487 l_float32 *
1488 makeLogBase2Tab(void)
1489 {
1490 l_int32 i;
1491 l_float32 log2;
1492 l_float32 *tab;
1493 
1494  PROCNAME("makeLogBase2Tab");
1495 
1496  if ((tab = (l_float32 *)LEPT_CALLOC(256, sizeof(l_float32))) == NULL)
1497  return (l_float32 *)ERROR_PTR("tab not made", procName, NULL);
1498 
1499  log2 = (l_float32)log((l_float32)2);
1500  for (i = 0; i < 256; i++)
1501  tab[i] = (l_float32)log((l_float32)i) / log2;
1502 
1503  return tab;
1504 }
1505 
1506 
1507 /*
1508  * \brief getLogBase2()
1509  *
1510  * \param[in] val in range [0 ... 255]
1511  * \param[in] logtab 256-entry table of logs
1512  * \return logval log[base2] of %val, or 0 on error
1513  */
1514 l_float32
1515 getLogBase2(l_int32 val,
1516  l_float32 *logtab)
1517 {
1518  PROCNAME("getLogBase2");
1519 
1520  if (!logtab)
1521  return ERROR_INT("logtab not defined", procName, 0);
1522 
1523  if (val < 0x100)
1524  return logtab[val];
1525  else if (val < 0x10000)
1526  return 8.0 + logtab[val >> 8];
1527  else if (val < 0x1000000)
1528  return 16.0 + logtab[val >> 16];
1529  else
1530  return 24.0 + logtab[val >> 24];
1531 }
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:322
l_ok pixMultConstAccumulate(PIX *pixs, l_float32 factor, l_uint32 offset)
pixMultConstAccumulate()
Definition: pixarith.c:818
l_uint32 linearScaleRGBVal(l_uint32 sval, l_float32 factor)
linearScaleRGBVal()
Definition: pixarith.c:1430
PIX * pixMaxDynamicRange(PIX *pixs, l_int32 type)
pixMaxDynamicRange()
Definition: pixarith.c:1155
PIX * pixFinalAccumulateThreshold(PIX *pixs, l_uint32 offset, l_uint32 threshold)
pixFinalAccumulateThreshold()
Definition: pixarith.c:662
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:168
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PIX * pixAddRGB(PIX *pixs1, PIX *pixs2)
pixAddRGB()
Definition: pixarith.c:969
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
PIX * pixMaxDynamicRangeRGB(PIX *pixs, l_int32 type)
pixMaxDynamicRangeRGB()
Definition: pixarith.c:1343
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:876
PIX * pixSubtractGray(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixSubtractGray()
Definition: pixarith.c:353
PIX * pixAbsDifference(PIX *pixs1, PIX *pixs2)
pixAbsDifference()
Definition: pixarith.c:872
PIX * pixInitAccumulate(l_int32 w, l_int32 h, l_uint32 offset)
pixInitAccumulate()
Definition: pixarith.c:551
l_ok pixAccumulate(PIX *pixd, PIX *pixs, l_int32 op)
pixAccumulate()
Definition: pixarith.c:719
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
PIX * pixFinalAccumulate(PIX *pixs, l_uint32 offset, l_int32 depth)
pixFinalAccumulate()
Definition: pixarith.c:585
PIX * pixThresholdToValue(PIX *pixd, PIX *pixs, l_int32 threshval, l_int32 setval)
pixThresholdToValue()
Definition: pixarith.c:442
l_uint32 logScaleRGBVal(l_uint32 sval, l_float32 *tab, l_float32 factor)
logScaleRGBVal()
Definition: pixarith.c:1463
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
PIX * pixAddGray(PIX *pixd, PIX *pixs1, PIX *pixs2)
pixAddGray()
Definition: pixarith.c:261
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
Definition: pix.h:134
l_ok pixMultConstantGray(PIX *pixs, l_float32 val)
pixMultConstantGray()
Definition: pixarith.c:186
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
PIX * pixMinOrMax(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 type)
pixMinOrMax()
Definition: pixarith.c:1054
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2671
l_int32 pixSizesEqual(const PIX *pix1, const PIX *pix2)
pixSizesEqual()
Definition: pix1.c:781
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2737
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
l_ok pixAddConstantGray(PIX *pixs, l_int32 val)
pixAddConstantGray()
Definition: pixarith.c:115