Leptonica  1.82.0
Image processing and image analysis suite
colorspace.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
85 #ifdef HAVE_CONFIG_H
86 #include <config_auto.h>
87 #endif /* HAVE_CONFIG_H */
88 
89 #include <string.h>
90 #include <math.h>
91 #include "allheaders.h"
92 
93 #ifndef NO_CONSOLE_IO
94 #define DEBUG_HISTO 0
95 #define SLOW_CUBE_ROOT 0
96 #endif /* ~NO_CONSOLE_IO */
97 
98  /* Functions used in xyz <--> lab conversions */
99 static l_float32 lab_forward(l_float32 v);
100 static l_float32 lab_reverse(l_float32 v);
101 
102 /*---------------------------------------------------------------------------*
103  * Colorspace conversion between RGB and HSB *
104  *---------------------------------------------------------------------------*/
141 PIX *
143  PIX *pixs)
144 {
145 l_int32 w, h, d, wpl, i, j, rval, gval, bval, hval, sval, vval;
146 l_uint32 *line, *data;
147 PIXCMAP *cmap;
148 
149  PROCNAME("pixConvertRGBToHSV");
150 
151  if (!pixs)
152  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
153  if (pixd && pixd != pixs)
154  return (PIX *)ERROR_PTR("pixd defined and not inplace", procName, pixd);
155 
156  d = pixGetDepth(pixs);
157  cmap = pixGetColormap(pixs);
158  if (!cmap && d != 32)
159  return (PIX *)ERROR_PTR("not cmapped or rgb", procName, pixd);
160 
161  if (!pixd)
162  pixd = pixCopy(NULL, pixs);
163 
164  cmap = pixGetColormap(pixd);
165  if (cmap) { /* just convert the colormap */
167  return pixd;
168  }
169 
170  /* Convert RGB image */
171  pixGetDimensions(pixd, &w, &h, NULL);
172  wpl = pixGetWpl(pixd);
173  data = pixGetData(pixd);
174  for (i = 0; i < h; i++) {
175  line = data + i * wpl;
176  for (j = 0; j < w; j++) {
177  extractRGBValues(line[j], &rval, &gval, &bval);
178  convertRGBToHSV(rval, gval, bval, &hval, &sval, &vval);
179  line[j] = (hval << 24) | (sval << 16) | (vval << 8);
180  }
181  }
182 
183  return pixd;
184 }
185 
186 
205 PIX *
207  PIX *pixs)
208 {
209 l_int32 w, h, d, wpl, i, j, rval, gval, bval, hval, sval, vval;
210 l_uint32 pixel;
211 l_uint32 *line, *data;
212 PIXCMAP *cmap;
213 
214  PROCNAME("pixConvertHSVToRGB");
215 
216  if (!pixs)
217  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
218  if (pixd && pixd != pixs)
219  return (PIX *)ERROR_PTR("pixd defined and not inplace", procName, pixd);
220 
221  d = pixGetDepth(pixs);
222  cmap = pixGetColormap(pixs);
223  if (!cmap && d != 32)
224  return (PIX *)ERROR_PTR("not cmapped or hsv", procName, pixd);
225 
226  if (!pixd)
227  pixd = pixCopy(NULL, pixs);
228 
229  cmap = pixGetColormap(pixd);
230  if (cmap) { /* just convert the colormap */
232  return pixd;
233  }
234 
235  /* Convert HSV image */
236  pixGetDimensions(pixd, &w, &h, NULL);
237  wpl = pixGetWpl(pixd);
238  data = pixGetData(pixd);
239  for (i = 0; i < h; i++) {
240  line = data + i * wpl;
241  for (j = 0; j < w; j++) {
242  pixel = line[j];
243  hval = pixel >> 24;
244  sval = (pixel >> 16) & 0xff;
245  vval = (pixel >> 8) & 0xff;
246  convertHSVToRGB(hval, sval, vval, &rval, &gval, &bval);
247  composeRGBPixel(rval, gval, bval, line + j);
248  }
249  }
250 
251  return pixd;
252 }
253 
254 
280 l_ok
281 convertRGBToHSV(l_int32 rval,
282  l_int32 gval,
283  l_int32 bval,
284  l_int32 *phval,
285  l_int32 *psval,
286  l_int32 *pvval)
287 {
288 l_int32 minrg, maxrg, min, max, delta;
289 l_float32 h;
290 
291  PROCNAME("convertRGBToHSV");
292 
293  if (phval) *phval = 0;
294  if (psval) *psval = 0;
295  if (pvval) *pvval = 0;
296  if (!phval || !psval || !pvval)
297  return ERROR_INT("&hval, &sval, &vval not all defined", procName, 1);
298 
299  minrg = L_MIN(rval, gval);
300  min = L_MIN(minrg, bval);
301  maxrg = L_MAX(rval, gval);
302  max = L_MAX(maxrg, bval);
303  delta = max - min;
304 
305  *pvval = max;
306  if (delta == 0) { /* gray; no chroma */
307  *phval = 0;
308  *psval = 0;
309  } else {
310  *psval = (l_int32)(255. * (l_float32)delta / (l_float32)max + 0.5);
311  if (rval == max) /* between magenta and yellow */
312  h = (l_float32)(gval - bval) / (l_float32)delta;
313  else if (gval == max) /* between yellow and cyan */
314  h = 2. + (l_float32)(bval - rval) / (l_float32)delta;
315  else /* between cyan and magenta */
316  h = 4. + (l_float32)(rval - gval) / (l_float32)delta;
317  h *= 40.0;
318  if (h < 0.0)
319  h += 240.0;
320  if (h >= 239.5)
321  h = 0.0;
322  *phval = (l_int32)(h + 0.5);
323  }
324 
325  return 0;
326 }
327 
328 
342 l_ok
343 convertHSVToRGB(l_int32 hval,
344  l_int32 sval,
345  l_int32 vval,
346  l_int32 *prval,
347  l_int32 *pgval,
348  l_int32 *pbval)
349 {
350 l_int32 i, x, y, z;
351 l_float32 h, f, s;
352 
353  PROCNAME("convertHSVToRGB");
354 
355  if (prval) *prval = 0;
356  if (pgval) *pgval = 0;
357  if (pbval) *pbval = 0;
358  if (!prval || !pgval || !pbval)
359  return ERROR_INT("&rval, &gval, &bval not all defined", procName, 1);
360 
361  if (sval == 0) { /* gray */
362  *prval = vval;
363  *pgval = vval;
364  *pbval = vval;
365  } else {
366  if (hval < 0 || hval > 240)
367  return ERROR_INT("invalid hval", procName, 1);
368  if (hval == 240)
369  hval = 0;
370  h = (l_float32)hval / 40.;
371  i = (l_int32)h;
372  f = h - i;
373  s = (l_float32)sval / 255.;
374  x = (l_int32)(vval * (1. - s) + 0.5);
375  y = (l_int32)(vval * (1. - s * f) + 0.5);
376  z = (l_int32)(vval * (1. - s * (1. - f)) + 0.5);
377  switch (i)
378  {
379  case 0:
380  *prval = vval;
381  *pgval = z;
382  *pbval = x;
383  break;
384  case 1:
385  *prval = y;
386  *pgval = vval;
387  *pbval = x;
388  break;
389  case 2:
390  *prval = x;
391  *pgval = vval;
392  *pbval = z;
393  break;
394  case 3:
395  *prval = x;
396  *pgval = y;
397  *pbval = vval;
398  break;
399  case 4:
400  *prval = z;
401  *pgval = x;
402  *pbval = vval;
403  break;
404  case 5:
405  *prval = vval;
406  *pgval = x;
407  *pbval = y;
408  break;
409  default: /* none possible */
410  return 1;
411  }
412  }
413 
414  return 0;
415 }
416 
417 
431 l_ok
433 {
434 l_int32 i, ncolors, rval, gval, bval, hval, sval, vval;
435 
436  PROCNAME("pixcmapConvertRGBToHSV");
437 
438  if (!cmap)
439  return ERROR_INT("cmap not defined", procName, 1);
440 
441  ncolors = pixcmapGetCount(cmap);
442  for (i = 0; i < ncolors; i++) {
443  pixcmapGetColor(cmap, i, &rval, &gval, &bval);
444  convertRGBToHSV(rval, gval, bval, &hval, &sval, &vval);
445  pixcmapResetColor(cmap, i, hval, sval, vval);
446  }
447  return 0;
448 }
449 
450 
464 l_ok
466 {
467 l_int32 i, ncolors, rval, gval, bval, hval, sval, vval;
468 
469  PROCNAME("pixcmapConvertHSVToRGB");
470 
471  if (!cmap)
472  return ERROR_INT("cmap not defined", procName, 1);
473 
474  ncolors = pixcmapGetCount(cmap);
475  for (i = 0; i < ncolors; i++) {
476  pixcmapGetColor(cmap, i, &hval, &sval, &vval);
477  convertHSVToRGB(hval, sval, vval, &rval, &gval, &bval);
478  pixcmapResetColor(cmap, i, rval, gval, bval);
479  }
480  return 0;
481 }
482 
483 
499 PIX *
501 {
502 l_int32 w, h, d, wplt, wpld;
503 l_int32 i, j, rval, gval, bval, hval, minrg, min, maxrg, max, delta;
504 l_float32 fh;
505 l_uint32 pixel;
506 l_uint32 *linet, *lined, *datat, *datad;
507 PIX *pixt, *pixd;
508 
509  PROCNAME("pixConvertRGBToHue");
510 
511  if (!pixs)
512  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
513 
514  pixGetDimensions(pixs, &w, &h, &d);
515  if (d != 32 && !pixGetColormap(pixs))
516  return (PIX *)ERROR_PTR("not cmapped or rgb", procName, NULL);
518 
519  /* Convert RGB image */
520  pixd = pixCreate(w, h, 8);
521  pixCopyResolution(pixd, pixs);
522  wplt = pixGetWpl(pixt);
523  datat = pixGetData(pixt);
524  wpld = pixGetWpl(pixd);
525  datad = pixGetData(pixd);
526  for (i = 0; i < h; i++) {
527  linet = datat + i * wplt;
528  lined = datad + i * wpld;
529  for (j = 0; j < w; j++) {
530  pixel = linet[j];
531  extractRGBValues(pixel, &rval, &gval, &bval);
532  minrg = L_MIN(rval, gval);
533  min = L_MIN(minrg, bval);
534  maxrg = L_MAX(rval, gval);
535  max = L_MAX(maxrg, bval);
536  delta = max - min;
537  if (delta == 0) { /* gray; no chroma */
538  hval = 0;
539  } else {
540  if (rval == max) /* between magenta and yellow */
541  fh = (l_float32)(gval - bval) / (l_float32)delta;
542  else if (gval == max) /* between yellow and cyan */
543  fh = 2. + (l_float32)(bval - rval) / (l_float32)delta;
544  else /* between cyan and magenta */
545  fh = 4. + (l_float32)(rval - gval) / (l_float32)delta;
546  fh *= 40.0;
547  if (fh < 0.0)
548  fh += 240.0;
549  hval = (l_int32)(fh + 0.5);
550  }
551  SET_DATA_BYTE(lined, j, hval);
552  }
553  }
554  pixDestroy(&pixt);
555 
556  return pixd;
557 }
558 
559 
560 
575 PIX *
577 {
578 l_int32 w, h, d, wplt, wpld;
579 l_int32 i, j, rval, gval, bval, sval, minrg, min, maxrg, max, delta;
580 l_uint32 pixel;
581 l_uint32 *linet, *lined, *datat, *datad;
582 PIX *pixt, *pixd;
583 
584  PROCNAME("pixConvertRGBToSaturation");
585 
586  if (!pixs)
587  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
588 
589  pixGetDimensions(pixs, &w, &h, &d);
590  if (d != 32 && !pixGetColormap(pixs))
591  return (PIX *)ERROR_PTR("not cmapped or rgb", procName, NULL);
593 
594  /* Convert RGB image */
595  pixd = pixCreate(w, h, 8);
596  pixCopyResolution(pixd, pixs);
597  wplt = pixGetWpl(pixt);
598  datat = pixGetData(pixt);
599  wpld = pixGetWpl(pixd);
600  datad = pixGetData(pixd);
601  for (i = 0; i < h; i++) {
602  linet = datat + i * wplt;
603  lined = datad + i * wpld;
604  for (j = 0; j < w; j++) {
605  pixel = linet[j];
606  extractRGBValues(pixel, &rval, &gval, &bval);
607  minrg = L_MIN(rval, gval);
608  min = L_MIN(minrg, bval);
609  maxrg = L_MAX(rval, gval);
610  max = L_MAX(maxrg, bval);
611  delta = max - min;
612  if (delta == 0) /* gray; no chroma */
613  sval = 0;
614  else
615  sval = (l_int32)(255. *
616  (l_float32)delta / (l_float32)max + 0.5);
617  SET_DATA_BYTE(lined, j, sval);
618  }
619  }
620 
621  pixDestroy(&pixt);
622  return pixd;
623 }
624 
625 
640 PIX *
642 {
643 l_int32 w, h, d, wplt, wpld;
644 l_int32 i, j, rval, gval, bval, maxrg, max;
645 l_uint32 pixel;
646 l_uint32 *linet, *lined, *datat, *datad;
647 PIX *pixt, *pixd;
648 
649  PROCNAME("pixConvertRGBToValue");
650 
651  if (!pixs)
652  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
653 
654  pixGetDimensions(pixs, &w, &h, &d);
655  if (d != 32 && !pixGetColormap(pixs))
656  return (PIX *)ERROR_PTR("not cmapped or rgb", procName, NULL);
658 
659  /* Convert RGB image */
660  pixd = pixCreate(w, h, 8);
661  pixCopyResolution(pixd, pixs);
662  wplt = pixGetWpl(pixt);
663  datat = pixGetData(pixt);
664  wpld = pixGetWpl(pixd);
665  datad = pixGetData(pixd);
666  for (i = 0; i < h; i++) {
667  linet = datat + i * wplt;
668  lined = datad + i * wpld;
669  for (j = 0; j < w; j++) {
670  pixel = linet[j];
671  extractRGBValues(pixel, &rval, &gval, &bval);
672  maxrg = L_MAX(rval, gval);
673  max = L_MAX(maxrg, bval);
674  SET_DATA_BYTE(lined, j, max);
675  }
676  }
677 
678  pixDestroy(&pixt);
679  return pixd;
680 }
681 
682 
683 /*---------------------------------------------------------------------------*
684  * Selection and display of range of colors in HSV space *
685  *---------------------------------------------------------------------------*/
709 PIX *
711  l_int32 huecenter,
712  l_int32 huehw,
713  l_int32 satcenter,
714  l_int32 sathw,
715  l_int32 regionflag)
716 {
717 l_int32 i, j, w, h, wplt, wpld, hstart, hend, sstart, send, hval, sval;
718 l_int32 *hlut, *slut;
719 l_uint32 pixel;
720 l_uint32 *datat, *datad, *linet, *lined;
721 PIX *pixt, *pixd;
722 
723  PROCNAME("pixMakeRangeMaskHS");
724 
725  if (!pixs || pixGetDepth(pixs) != 32)
726  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
727  if (regionflag != L_INCLUDE_REGION && regionflag != L_EXCLUDE_REGION)
728  return (PIX *)ERROR_PTR("invalid regionflag", procName, NULL);
729 
730  /* Set up LUTs for hue and saturation. These have the value 1
731  * within the specified intervals of hue and saturation. */
732  hlut = (l_int32 *)LEPT_CALLOC(240, sizeof(l_int32));
733  slut = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
734  sstart = L_MAX(0, satcenter - sathw);
735  send = L_MIN(255, satcenter + sathw);
736  for (i = sstart; i <= send; i++)
737  slut[i] = 1;
738  hstart = (huecenter - huehw + 240) % 240;
739  hend = (huecenter + huehw + 240) % 240;
740  if (hstart < hend) {
741  for (i = hstart; i <= hend; i++)
742  hlut[i] = 1;
743  } else { /* wrap */
744  for (i = hstart; i < 240; i++)
745  hlut[i] = 1;
746  for (i = 0; i <= hend; i++)
747  hlut[i] = 1;
748  }
749 
750  /* Generate the mask */
751  pixt = pixConvertRGBToHSV(NULL, pixs);
752  pixGetDimensions(pixs, &w, &h, NULL);
753  pixd = pixCreate(w, h, 1);
754  if (regionflag == L_INCLUDE_REGION)
755  pixClearAll(pixd);
756  else /* L_EXCLUDE_REGION */
757  pixSetAll(pixd);
758  datat = pixGetData(pixt);
759  datad = pixGetData(pixd);
760  wplt = pixGetWpl(pixt);
761  wpld = pixGetWpl(pixd);
762  for (i = 0; i < h; i++) {
763  linet = datat + i * wplt;
764  lined = datad + i * wpld;
765  for (j = 0; j < w; j++) {
766  pixel = linet[j];
767  hval = (pixel >> L_RED_SHIFT) & 0xff;
768  sval = (pixel >> L_GREEN_SHIFT) & 0xff;
769  if (hlut[hval] == 1 && slut[sval] == 1) {
770  if (regionflag == L_INCLUDE_REGION)
771  SET_DATA_BIT(lined, j);
772  else /* L_EXCLUDE_REGION */
773  CLEAR_DATA_BIT(lined, j);
774  }
775  }
776  }
777 
778  LEPT_FREE(hlut);
779  LEPT_FREE(slut);
780  pixDestroy(&pixt);
781  return pixd;
782 }
783 
784 
808 PIX *
810  l_int32 huecenter,
811  l_int32 huehw,
812  l_int32 valcenter,
813  l_int32 valhw,
814  l_int32 regionflag)
815 {
816 l_int32 i, j, w, h, wplt, wpld, hstart, hend, vstart, vend, hval, vval;
817 l_int32 *hlut, *vlut;
818 l_uint32 pixel;
819 l_uint32 *datat, *datad, *linet, *lined;
820 PIX *pixt, *pixd;
821 
822  PROCNAME("pixMakeRangeMaskHV");
823 
824  if (!pixs || pixGetDepth(pixs) != 32)
825  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
826  if (regionflag != L_INCLUDE_REGION && regionflag != L_EXCLUDE_REGION)
827  return (PIX *)ERROR_PTR("invalid regionflag", procName, NULL);
828 
829  /* Set up LUTs for hue and maximum intensity (val). These have
830  * the value 1 within the specified intervals of hue and value. */
831  hlut = (l_int32 *)LEPT_CALLOC(240, sizeof(l_int32));
832  vlut = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
833  vstart = L_MAX(0, valcenter - valhw);
834  vend = L_MIN(255, valcenter + valhw);
835  for (i = vstart; i <= vend; i++)
836  vlut[i] = 1;
837  hstart = (huecenter - huehw + 240) % 240;
838  hend = (huecenter + huehw + 240) % 240;
839  if (hstart < hend) {
840  for (i = hstart; i <= hend; i++)
841  hlut[i] = 1;
842  } else {
843  for (i = hstart; i < 240; i++)
844  hlut[i] = 1;
845  for (i = 0; i <= hend; i++)
846  hlut[i] = 1;
847  }
848 
849  /* Generate the mask */
850  pixt = pixConvertRGBToHSV(NULL, pixs);
851  pixGetDimensions(pixs, &w, &h, NULL);
852  pixd = pixCreate(w, h, 1);
853  if (regionflag == L_INCLUDE_REGION)
854  pixClearAll(pixd);
855  else /* L_EXCLUDE_REGION */
856  pixSetAll(pixd);
857  datat = pixGetData(pixt);
858  datad = pixGetData(pixd);
859  wplt = pixGetWpl(pixt);
860  wpld = pixGetWpl(pixd);
861  for (i = 0; i < h; i++) {
862  linet = datat + i * wplt;
863  lined = datad + i * wpld;
864  for (j = 0; j < w; j++) {
865  pixel = linet[j];
866  hval = (pixel >> L_RED_SHIFT) & 0xff;
867  vval = (pixel >> L_BLUE_SHIFT) & 0xff;
868  if (hlut[hval] == 1 && vlut[vval] == 1) {
869  if (regionflag == L_INCLUDE_REGION)
870  SET_DATA_BIT(lined, j);
871  else /* L_EXCLUDE_REGION */
872  CLEAR_DATA_BIT(lined, j);
873  }
874  }
875  }
876 
877  LEPT_FREE(hlut);
878  LEPT_FREE(vlut);
879  pixDestroy(&pixt);
880  return pixd;
881 }
882 
883 
906 PIX *
908  l_int32 satcenter,
909  l_int32 sathw,
910  l_int32 valcenter,
911  l_int32 valhw,
912  l_int32 regionflag)
913 {
914 l_int32 i, j, w, h, wplt, wpld, sval, vval, sstart, send, vstart, vend;
915 l_int32 *slut, *vlut;
916 l_uint32 pixel;
917 l_uint32 *datat, *datad, *linet, *lined;
918 PIX *pixt, *pixd;
919 
920  PROCNAME("pixMakeRangeMaskSV");
921 
922  if (!pixs || pixGetDepth(pixs) != 32)
923  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
924  if (regionflag != L_INCLUDE_REGION && regionflag != L_EXCLUDE_REGION)
925  return (PIX *)ERROR_PTR("invalid regionflag", procName, NULL);
926 
927  /* Set up LUTs for saturation and max intensity (val).
928  * These have the value 1 within the specified intervals of
929  * saturation and max intensity. */
930  slut = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
931  vlut = (l_int32 *)LEPT_CALLOC(256, sizeof(l_int32));
932  sstart = L_MAX(0, satcenter - sathw);
933  send = L_MIN(255, satcenter + sathw);
934  vstart = L_MAX(0, valcenter - valhw);
935  vend = L_MIN(255, valcenter + valhw);
936  for (i = sstart; i <= send; i++)
937  slut[i] = 1;
938  for (i = vstart; i <= vend; i++)
939  vlut[i] = 1;
940 
941  /* Generate the mask */
942  pixt = pixConvertRGBToHSV(NULL, pixs);
943  pixGetDimensions(pixs, &w, &h, NULL);
944  pixd = pixCreate(w, h, 1);
945  if (regionflag == L_INCLUDE_REGION)
946  pixClearAll(pixd);
947  else /* L_EXCLUDE_REGION */
948  pixSetAll(pixd);
949  datat = pixGetData(pixt);
950  datad = pixGetData(pixd);
951  wplt = pixGetWpl(pixt);
952  wpld = pixGetWpl(pixd);
953  for (i = 0; i < h; i++) {
954  linet = datat + i * wplt;
955  lined = datad + i * wpld;
956  for (j = 0; j < w; j++) {
957  pixel = linet[j];
958  sval = (pixel >> L_GREEN_SHIFT) & 0xff;
959  vval = (pixel >> L_BLUE_SHIFT) & 0xff;
960  if (slut[sval] == 1 && vlut[vval] == 1) {
961  if (regionflag == L_INCLUDE_REGION)
962  SET_DATA_BIT(lined, j);
963  else /* L_EXCLUDE_REGION */
964  CLEAR_DATA_BIT(lined, j);
965  }
966  }
967  }
968 
969  LEPT_FREE(slut);
970  LEPT_FREE(vlut);
971  pixDestroy(&pixt);
972  return pixd;
973 }
974 
975 
995 PIX *
997  l_int32 factor,
998  NUMA **pnahue,
999  NUMA **pnasat)
1000 {
1001 l_int32 i, j, w, h, wplt, hval, sval, nd;
1002 l_uint32 pixel;
1003 l_uint32 *datat, *linet;
1004 void **lined32;
1005 NUMA *nahue, *nasat;
1006 PIX *pixt, *pixd;
1007 
1008  PROCNAME("pixMakeHistoHS");
1009 
1010  if (pnahue) *pnahue = NULL;
1011  if (pnasat) *pnasat = NULL;
1012  if (!pixs || pixGetDepth(pixs) != 32)
1013  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
1014 
1015  if (pnahue) {
1016  nahue = numaCreate(240);
1017  numaSetCount(nahue, 240);
1018  *pnahue = nahue;
1019  }
1020  if (pnasat) {
1021  nasat = numaCreate(256);
1022  numaSetCount(nasat, 256);
1023  *pnasat = nasat;
1024  }
1025 
1026  if (factor <= 1)
1027  pixt = pixClone(pixs);
1028  else
1029  pixt = pixScaleBySampling(pixs, 1.0 / (l_float32)factor,
1030  1.0 / (l_float32)factor);
1031 
1032  /* Create the hue-saturation histogram */
1033  pixd = pixCreate(256, 240, 32);
1034  lined32 = pixGetLinePtrs(pixd, NULL);
1035  pixGetDimensions(pixt, &w, &h, NULL);
1036  datat = pixGetData(pixt);
1037  wplt = pixGetWpl(pixt);
1038  for (i = 0; i < h; i++) {
1039  linet = datat + i * wplt;
1040  for (j = 0; j < w; j++) {
1041  pixel = linet[j];
1042  hval = (pixel >> L_RED_SHIFT) & 0xff;
1043 
1044 #if DEBUG_HISTO
1045  if (hval > 239) {
1046  lept_stderr("hval = %d for (%d,%d)\n", hval, i, j);
1047  continue;
1048  }
1049 #endif /* DEBUG_HISTO */
1050 
1051  sval = (pixel >> L_GREEN_SHIFT) & 0xff;
1052  if (pnahue)
1053  numaShiftValue(nahue, hval, 1.0);
1054  if (pnasat)
1055  numaShiftValue(nasat, sval, 1.0);
1056  nd = GET_DATA_FOUR_BYTES(lined32[hval], sval);
1057  SET_DATA_FOUR_BYTES(lined32[hval], sval, nd + 1);
1058  }
1059  }
1060 
1061  LEPT_FREE(lined32);
1062  pixDestroy(&pixt);
1063  return pixd;
1064 }
1065 
1066 
1086 PIX *
1088  l_int32 factor,
1089  NUMA **pnahue,
1090  NUMA **pnaval)
1091 {
1092 l_int32 i, j, w, h, wplt, hval, vval, nd;
1093 l_uint32 pixel;
1094 l_uint32 *datat, *linet;
1095 void **lined32;
1096 NUMA *nahue, *naval;
1097 PIX *pixt, *pixd;
1098 
1099  PROCNAME("pixMakeHistoHV");
1100 
1101  if (pnahue) *pnahue = NULL;
1102  if (pnaval) *pnaval = NULL;
1103  if (!pixs || pixGetDepth(pixs) != 32)
1104  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
1105 
1106  if (pnahue) {
1107  nahue = numaCreate(240);
1108  numaSetCount(nahue, 240);
1109  *pnahue = nahue;
1110  }
1111  if (pnaval) {
1112  naval = numaCreate(256);
1113  numaSetCount(naval, 256);
1114  *pnaval = naval;
1115  }
1116 
1117  if (factor <= 1)
1118  pixt = pixClone(pixs);
1119  else
1120  pixt = pixScaleBySampling(pixs, 1.0 / (l_float32)factor,
1121  1.0 / (l_float32)factor);
1122 
1123  /* Create the hue-value histogram */
1124  pixd = pixCreate(256, 240, 32);
1125  lined32 = pixGetLinePtrs(pixd, NULL);
1126  pixGetDimensions(pixt, &w, &h, NULL);
1127  datat = pixGetData(pixt);
1128  wplt = pixGetWpl(pixt);
1129  for (i = 0; i < h; i++) {
1130  linet = datat + i * wplt;
1131  for (j = 0; j < w; j++) {
1132  pixel = linet[j];
1133  hval = (pixel >> L_RED_SHIFT) & 0xff;
1134  vval = (pixel >> L_BLUE_SHIFT) & 0xff;
1135  if (pnahue)
1136  numaShiftValue(nahue, hval, 1.0);
1137  if (pnaval)
1138  numaShiftValue(naval, vval, 1.0);
1139  nd = GET_DATA_FOUR_BYTES(lined32[hval], vval);
1140  SET_DATA_FOUR_BYTES(lined32[hval], vval, nd + 1);
1141  }
1142  }
1143 
1144  LEPT_FREE(lined32);
1145  pixDestroy(&pixt);
1146  return pixd;
1147 }
1148 
1149 
1169 PIX *
1171  l_int32 factor,
1172  NUMA **pnasat,
1173  NUMA **pnaval)
1174 {
1175 l_int32 i, j, w, h, wplt, sval, vval, nd;
1176 l_uint32 pixel;
1177 l_uint32 *datat, *linet;
1178 void **lined32;
1179 NUMA *nasat, *naval;
1180 PIX *pixt, *pixd;
1181 
1182  PROCNAME("pixMakeHistoSV");
1183 
1184  if (pnasat) *pnasat = NULL;
1185  if (pnaval) *pnaval = NULL;
1186  if (!pixs || pixGetDepth(pixs) != 32)
1187  return (PIX *)ERROR_PTR("pixs undefined or not 32 bpp", procName, NULL);
1188 
1189  if (pnasat) {
1190  nasat = numaCreate(256);
1191  numaSetCount(nasat, 256);
1192  *pnasat = nasat;
1193  }
1194  if (pnaval) {
1195  naval = numaCreate(256);
1196  numaSetCount(naval, 256);
1197  *pnaval = naval;
1198  }
1199 
1200  if (factor <= 1)
1201  pixt = pixClone(pixs);
1202  else
1203  pixt = pixScaleBySampling(pixs, 1.0 / (l_float32)factor,
1204  1.0 / (l_float32)factor);
1205 
1206  /* Create the hue-value histogram */
1207  pixd = pixCreate(256, 256, 32);
1208  lined32 = pixGetLinePtrs(pixd, NULL);
1209  pixGetDimensions(pixt, &w, &h, NULL);
1210  datat = pixGetData(pixt);
1211  wplt = pixGetWpl(pixt);
1212  for (i = 0; i < h; i++) {
1213  linet = datat + i * wplt;
1214  for (j = 0; j < w; j++) {
1215  pixel = linet[j];
1216  sval = (pixel >> L_GREEN_SHIFT) & 0xff;
1217  vval = (pixel >> L_BLUE_SHIFT) & 0xff;
1218  if (pnasat)
1219  numaShiftValue(nasat, sval, 1.0);
1220  if (pnaval)
1221  numaShiftValue(naval, vval, 1.0);
1222  nd = GET_DATA_FOUR_BYTES(lined32[sval], vval);
1223  SET_DATA_FOUR_BYTES(lined32[sval], vval, nd + 1);
1224  }
1225  }
1226 
1227  LEPT_FREE(lined32);
1228  pixDestroy(&pixt);
1229  return pixd;
1230 }
1231 
1232 
1260 l_ok
1262  l_int32 type,
1263  l_int32 width,
1264  l_int32 height,
1265  l_int32 npeaks,
1266  l_float32 erasefactor,
1267  PTA **ppta,
1268  NUMA **pnatot,
1269  PIXA **ppixa)
1270 {
1271 l_int32 i, xmax, ymax, ewidth, eheight;
1272 l_uint32 maxval;
1273 BOX *box;
1274 NUMA *natot;
1275 PIX *pixh, *pixw, *pix1, *pix2, *pix3;
1276 PTA *pta;
1277 
1278  PROCNAME("pixFindHistoPeaksHSV");
1279 
1280  if (ppixa) *ppixa = NULL;
1281  if (ppta) *ppta = NULL;
1282  if (pnatot) *pnatot = NULL;
1283  if (!pixs || pixGetDepth(pixs) != 32)
1284  return ERROR_INT("pixs undefined or not 32 bpp", procName, 1);
1285  if (!ppta || !pnatot)
1286  return ERROR_INT("&pta and &natot not both defined", procName, 1);
1287  if (type != L_HS_HISTO && type != L_HV_HISTO && type != L_SV_HISTO)
1288  return ERROR_INT("invalid HSV histo type", procName, 1);
1289 
1290  if ((pta = ptaCreate(npeaks)) == NULL)
1291  return ERROR_INT("pta not made", procName, 1);
1292  *ppta = pta;
1293  if ((natot = numaCreate(npeaks)) == NULL)
1294  return ERROR_INT("natot not made", procName, 1);
1295  *pnatot = natot;
1296 
1297  *ppta = pta;
1298  if (type == L_SV_HISTO)
1299  pixh = pixAddMirroredBorder(pixs, width + 1, width + 1, height + 1,
1300  height + 1);
1301  else /* type == L_HS_HISTO or type == L_HV_HISTO */
1302  pixh = pixAddMixedBorder(pixs, width + 1, width + 1, height + 1,
1303  height + 1);
1304 
1305  /* Get the total count in the sliding window. If the window
1306  * fully covers the peak, this will be the integrated
1307  * volume under the peak. */
1308  pixw = pixWindowedMean(pixh, width, height, 1, 0);
1309  pixDestroy(&pixh);
1310 
1311  /* Sequentially identify and erase peaks in the histogram.
1312  * If requested for debugging, save a pixa of the sequence of
1313  * false color histograms. */
1314  if (ppixa)
1315  *ppixa = pixaCreate(0);
1316  for (i = 0; i < npeaks; i++) {
1317  pixGetMaxValueInRect(pixw, NULL, &maxval, &xmax, &ymax);
1318  if (maxval == 0) break;
1319  numaAddNumber(natot, maxval);
1320  ptaAddPt(pta, xmax, ymax);
1321  ewidth = (l_int32)(width * erasefactor);
1322  eheight = (l_int32)(height * erasefactor);
1323  box = boxCreate(xmax - ewidth, ymax - eheight, 2 * ewidth + 1,
1324  2 * eheight + 1);
1325 
1326  if (ppixa) {
1327  pix1 = pixMaxDynamicRange(pixw, L_LINEAR_SCALE);
1328  pixaAddPix(*ppixa, pix1, L_INSERT);
1329  pix2 = pixConvertGrayToFalseColor(pix1, 1.0);
1330  pixaAddPix(*ppixa, pix2, L_INSERT);
1331  pix1 = pixMaxDynamicRange(pixw, L_LOG_SCALE);
1332  pix2 = pixConvertGrayToFalseColor(pix1, 1.0);
1333  pixaAddPix(*ppixa, pix2, L_INSERT);
1334  pix3 = pixConvertTo32(pix1);
1335  pixRenderHashBoxArb(pix3, box, 6, 2, L_NEG_SLOPE_LINE,
1336  1, 255, 100, 100);
1337  pixaAddPix(*ppixa, pix3, L_INSERT);
1338  pixDestroy(&pix1);
1339  }
1340 
1341  pixClearInRect(pixw, box);
1342  boxDestroy(&box);
1343  if (type == L_HS_HISTO || type == L_HV_HISTO) {
1344  /* clear wraps at bottom and top */
1345  if (ymax - eheight < 0) { /* overlap to bottom */
1346  box = boxCreate(xmax - ewidth, 240 + ymax - eheight,
1347  2 * ewidth + 1, eheight - ymax);
1348  } else if (ymax + eheight > 239) { /* overlap to top */
1349  box = boxCreate(xmax - ewidth, 0, 2 * ewidth + 1,
1350  ymax + eheight - 239);
1351  } else {
1352  box = NULL;
1353  }
1354  if (box) {
1355  pixClearInRect(pixw, box);
1356  boxDestroy(&box);
1357  }
1358  }
1359  }
1360 
1361  pixDestroy(&pixw);
1362  return 0;
1363 }
1364 
1365 
1384 PIX *
1386  l_int32 sval,
1387  l_int32 vval,
1388  l_int32 huehw,
1389  l_int32 sathw,
1390  l_int32 nsamp,
1391  l_int32 factor)
1392 {
1393 l_int32 i, j, w, huedelta, satdelta, hue, sat, rval, gval, bval;
1394 PIX *pixt, *pixd;
1395 
1396  PROCNAME("displayHSVColorRange");
1397 
1398  if (hval < 0 || hval > 240)
1399  return (PIX *)ERROR_PTR("invalid hval", procName, NULL);
1400  if (huehw < 5 || huehw > 120)
1401  return (PIX *)ERROR_PTR("invalid huehw", procName, NULL);
1402  if (sval - sathw < 0 || sval + sathw > 255)
1403  return (PIX *)ERROR_PTR("invalid sval/sathw", procName, NULL);
1404  if (nsamp < 1 || factor < 3)
1405  return (PIX *)ERROR_PTR("invalid nsamp or rep. factor", procName, NULL);
1406  if (vval < 0 || vval > 255)
1407  return (PIX *)ERROR_PTR("invalid vval", procName, NULL);
1408 
1409  w = (2 * nsamp + 1);
1410  huedelta = (l_int32)((l_float32)huehw / (l_float32)nsamp);
1411  satdelta = (l_int32)((l_float32)sathw / (l_float32)nsamp);
1412  pixt = pixCreate(w, w, 32);
1413  for (i = 0; i < w; i++) {
1414  hue = hval + huedelta * (i - nsamp);
1415  if (hue < 0) hue += 240;
1416  if (hue >= 240) hue -= 240;
1417  for (j = 0; j < w; j++) {
1418  sat = sval + satdelta * (j - nsamp);
1419  convertHSVToRGB(hue, sat, vval, &rval, &gval, &bval);
1420  pixSetRGBPixel(pixt, j, i, rval, gval, bval);
1421  }
1422  }
1423 
1424  pixd = pixExpandReplicate(pixt, factor);
1425  pixDestroy(&pixt);
1426  return pixd;
1427 }
1428 
1429 
1430 /*---------------------------------------------------------------------------*
1431  * Colorspace conversion between RGB and YUV *
1432  *---------------------------------------------------------------------------*/
1460 PIX *
1462  PIX *pixs)
1463 {
1464 l_int32 w, h, d, wpl, i, j, rval, gval, bval, yval, uval, vval;
1465 l_uint32 *line, *data;
1466 PIXCMAP *cmap;
1467 
1468  PROCNAME("pixConvertRGBToYUV");
1469 
1470  if (!pixs)
1471  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
1472  if (pixd && pixd != pixs)
1473  return (PIX *)ERROR_PTR("pixd defined and not inplace", procName, pixd);
1474 
1475  d = pixGetDepth(pixs);
1476  cmap = pixGetColormap(pixs);
1477  if (!cmap && d != 32)
1478  return (PIX *)ERROR_PTR("not cmapped or rgb", procName, pixd);
1479 
1480  if (!pixd)
1481  pixd = pixCopy(NULL, pixs);
1482 
1483  cmap = pixGetColormap(pixd);
1484  if (cmap) { /* just convert the colormap */
1485  pixcmapConvertRGBToYUV(cmap);
1486  return pixd;
1487  }
1488 
1489  /* Convert RGB image */
1490  pixGetDimensions(pixd, &w, &h, NULL);
1491  wpl = pixGetWpl(pixd);
1492  data = pixGetData(pixd);
1493  for (i = 0; i < h; i++) {
1494  line = data + i * wpl;
1495  for (j = 0; j < w; j++) {
1496  extractRGBValues(line[j], &rval, &gval, &bval);
1497  convertRGBToYUV(rval, gval, bval, &yval, &uval, &vval);
1498  line[j] = (yval << 24) | (uval << 16) | (vval << 8);
1499  }
1500  }
1501 
1502  return pixd;
1503 }
1504 
1505 
1523 PIX *
1525  PIX *pixs)
1526 {
1527 l_int32 w, h, d, wpl, i, j, rval, gval, bval, yval, uval, vval;
1528 l_uint32 pixel;
1529 l_uint32 *line, *data;
1530 PIXCMAP *cmap;
1531 
1532  PROCNAME("pixConvertYUVToRGB");
1533 
1534  if (!pixs)
1535  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
1536  if (pixd && pixd != pixs)
1537  return (PIX *)ERROR_PTR("pixd defined and not inplace", procName, pixd);
1538 
1539  d = pixGetDepth(pixs);
1540  cmap = pixGetColormap(pixs);
1541  if (!cmap && d != 32)
1542  return (PIX *)ERROR_PTR("not cmapped or hsv", procName, pixd);
1543 
1544  if (!pixd)
1545  pixd = pixCopy(NULL, pixs);
1546 
1547  cmap = pixGetColormap(pixd);
1548  if (cmap) { /* just convert the colormap */
1549  pixcmapConvertYUVToRGB(cmap);
1550  return pixd;
1551  }
1552 
1553  /* Convert YUV image */
1554  pixGetDimensions(pixd, &w, &h, NULL);
1555  wpl = pixGetWpl(pixd);
1556  data = pixGetData(pixd);
1557  for (i = 0; i < h; i++) {
1558  line = data + i * wpl;
1559  for (j = 0; j < w; j++) {
1560  pixel = line[j];
1561  yval = pixel >> 24;
1562  uval = (pixel >> 16) & 0xff;
1563  vval = (pixel >> 8) & 0xff;
1564  convertYUVToRGB(yval, uval, vval, &rval, &gval, &bval);
1565  composeRGBPixel(rval, gval, bval, line + j);
1566  }
1567  }
1568 
1569  return pixd;
1570 }
1571 
1572 
1588 l_ok
1589 convertRGBToYUV(l_int32 rval,
1590  l_int32 gval,
1591  l_int32 bval,
1592  l_int32 *pyval,
1593  l_int32 *puval,
1594  l_int32 *pvval)
1595 {
1596 l_float32 norm;
1597 
1598  PROCNAME("convertRGBToYUV");
1599 
1600  if (pyval) *pyval = 0;
1601  if (puval) *puval = 0;
1602  if (pvval) *pvval = 0;
1603  if (!pyval || !puval || !pvval)
1604  return ERROR_INT("&yval, &uval, &vval not all defined", procName, 1);
1605 
1606  norm = 1.0 / 256.;
1607  *pyval = (l_int32)(16.0 +
1608  norm * (65.738 * rval + 129.057 * gval + 25.064 * bval) + 0.5);
1609  *puval = (l_int32)(128.0 +
1610  norm * (-37.945 * rval -74.494 * gval + 112.439 * bval) + 0.5);
1611  *pvval = (l_int32)(128.0 +
1612  norm * (112.439 * rval - 94.154 * gval - 18.285 * bval) + 0.5);
1613  return 0;
1614 }
1615 
1616 
1636 l_ok
1637 convertYUVToRGB(l_int32 yval,
1638  l_int32 uval,
1639  l_int32 vval,
1640  l_int32 *prval,
1641  l_int32 *pgval,
1642  l_int32 *pbval)
1643 {
1644 l_int32 rval, gval, bval;
1645 l_float32 norm, ym, um, vm;
1646 
1647  PROCNAME("convertYUVToRGB");
1648 
1649  if (prval) *prval = 0;
1650  if (pgval) *pgval = 0;
1651  if (pbval) *pbval = 0;
1652  if (!prval || !pgval || !pbval)
1653  return ERROR_INT("&rval, &gval, &bval not all defined", procName, 1);
1654 
1655  norm = 1.0 / 256.;
1656  ym = yval - 16.0;
1657  um = uval - 128.0;
1658  vm = vval - 128.0;
1659  rval = (l_int32)(norm * (298.082 * ym + 408.583 * vm) + 0.5);
1660  gval = (l_int32)(norm * (298.082 * ym - 100.291 * um - 208.120 * vm) +
1661  0.5);
1662  bval = (l_int32)(norm * (298.082 * ym + 516.411 * um) + 0.5);
1663  *prval = L_MIN(255, L_MAX(0, rval));
1664  *pgval = L_MIN(255, L_MAX(0, gval));
1665  *pbval = L_MIN(255, L_MAX(0, bval));
1666 
1667  return 0;
1668 }
1669 
1670 
1684 l_ok
1686 {
1687 l_int32 i, ncolors, rval, gval, bval, yval, uval, vval;
1688 
1689  PROCNAME("pixcmapConvertRGBToYUV");
1690 
1691  if (!cmap)
1692  return ERROR_INT("cmap not defined", procName, 1);
1693 
1694  ncolors = pixcmapGetCount(cmap);
1695  for (i = 0; i < ncolors; i++) {
1696  pixcmapGetColor(cmap, i, &rval, &gval, &bval);
1697  convertRGBToYUV(rval, gval, bval, &yval, &uval, &vval);
1698  pixcmapResetColor(cmap, i, yval, uval, vval);
1699  }
1700  return 0;
1701 }
1702 
1703 
1717 l_ok
1719 {
1720 l_int32 i, ncolors, rval, gval, bval, yval, uval, vval;
1721 
1722  PROCNAME("pixcmapConvertYUVToRGB");
1723 
1724  if (!cmap)
1725  return ERROR_INT("cmap not defined", procName, 1);
1726 
1727  ncolors = pixcmapGetCount(cmap);
1728  for (i = 0; i < ncolors; i++) {
1729  pixcmapGetColor(cmap, i, &yval, &uval, &vval);
1730  convertYUVToRGB(yval, uval, vval, &rval, &gval, &bval);
1731  pixcmapResetColor(cmap, i, rval, gval, bval);
1732  }
1733  return 0;
1734 }
1735 
1736 
1737 /*---------------------------------------------------------------------------*
1738  * Colorspace conversion between RGB and XYZ *
1739  *---------------------------------------------------------------------------*/
1768 FPIXA *
1770 {
1771 l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
1772 l_uint32 *lines, *datas;
1773 l_float32 fxval, fyval, fzval;
1774 l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
1775 FPIX *fpix;
1776 FPIXA *fpixa;
1777 
1778  PROCNAME("pixConvertRGBToXYZ");
1779 
1780  if (!pixs || pixGetDepth(pixs) != 32)
1781  return (FPIXA *)ERROR_PTR("pixs undefined or not rgb", procName, NULL);
1782 
1783  /* Convert RGB image */
1784  pixGetDimensions(pixs, &w, &h, NULL);
1785  fpixa = fpixaCreate(3);
1786  for (i = 0; i < 3; i++) {
1787  fpix = fpixCreate(w, h);
1788  fpixaAddFPix(fpixa, fpix, L_INSERT);
1789  }
1790  wpls = pixGetWpl(pixs);
1791  wpld = fpixGetWpl(fpix);
1792  datas = pixGetData(pixs);
1793  datax = fpixaGetData(fpixa, 0);
1794  datay = fpixaGetData(fpixa, 1);
1795  dataz = fpixaGetData(fpixa, 2);
1796  for (i = 0; i < h; i++) {
1797  lines = datas + i * wpls;
1798  linex = datax + i * wpld;
1799  liney = datay + i * wpld;
1800  linez = dataz + i * wpld;
1801  for (j = 0; j < w; j++) {
1802  extractRGBValues(lines[j], &rval, &gval, &bval);
1803  convertRGBToXYZ(rval, gval, bval, &fxval, &fyval, &fzval);
1804  *(linex + j) = fxval;
1805  *(liney + j) = fyval;
1806  *(linez + j) = fzval;
1807  }
1808  }
1809 
1810  return fpixa;
1811 }
1812 
1813 
1827 PIX *
1829 {
1830 l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
1831 l_float32 fxval, fyval, fzval;
1832 l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
1833 l_uint32 *lined, *datad;
1834 PIX *pixd;
1835 FPIX *fpix;
1836 
1837  PROCNAME("fpixaConvertXYZToRGB");
1838 
1839  if (!fpixa || fpixaGetCount(fpixa) != 3)
1840  return (PIX *)ERROR_PTR("fpixa undefined or invalid", procName, NULL);
1841 
1842  /* Convert XYZ image */
1843  if (fpixaGetFPixDimensions(fpixa, 0, &w, &h))
1844  return (PIX *)ERROR_PTR("fpixa dimensions not found", procName, NULL);
1845  pixd = pixCreate(w, h, 32);
1846  wpld = pixGetWpl(pixd);
1847  datad = pixGetData(pixd);
1848  datax = fpixaGetData(fpixa, 0);
1849  datay = fpixaGetData(fpixa, 1);
1850  dataz = fpixaGetData(fpixa, 2);
1851  fpix = fpixaGetFPix(fpixa, 0, L_CLONE);
1852  wpls = fpixGetWpl(fpix);
1853  fpixDestroy(&fpix);
1854  for (i = 0; i < h; i++) {
1855  linex = datax + i * wpls;
1856  liney = datay + i * wpls;
1857  linez = dataz + i * wpls;
1858  lined = datad + i * wpld;
1859  for (j = 0; j < w; j++) {
1860  fxval = linex[j];
1861  fyval = liney[j];
1862  fzval = linez[j];
1863  convertXYZToRGB(fxval, fyval, fzval, 0, &rval, &gval, &bval);
1864  composeRGBPixel(rval, gval, bval, lined + j);
1865  }
1866  }
1867 
1868  return pixd;
1869 }
1870 
1871 
1885 l_ok
1886 convertRGBToXYZ(l_int32 rval,
1887  l_int32 gval,
1888  l_int32 bval,
1889  l_float32 *pfxval,
1890  l_float32 *pfyval,
1891  l_float32 *pfzval)
1892 {
1893  PROCNAME("convertRGBToXYZ");
1894 
1895  if (pfxval) *pfxval = 0.0;
1896  if (pfyval) *pfyval = 0.0;
1897  if (pfzval) *pfzval = 0.0;
1898  if (!pfxval || !pfyval || !pfzval)
1899  return ERROR_INT("&xval, &yval, &zval not all defined", procName, 1);
1900 
1901  *pfxval = 0.4125 * rval + 0.3576 * gval + 0.1804 * bval;
1902  *pfyval = 0.2127 * rval + 0.7152 * gval + 0.0722 * bval;
1903  *pfzval = 0.0193 * rval + 0.1192 * gval + 0.9502 * bval;
1904  return 0;
1905 }
1906 
1907 
1927 l_ok
1928 convertXYZToRGB(l_float32 fxval,
1929  l_float32 fyval,
1930  l_float32 fzval,
1931  l_int32 blackout,
1932  l_int32 *prval,
1933  l_int32 *pgval,
1934  l_int32 *pbval)
1935 {
1936 l_int32 rval, gval, bval;
1937 
1938  PROCNAME("convertXYZToRGB");
1939 
1940  if (prval) *prval = 0;
1941  if (pgval) *pgval = 0;
1942  if (pbval) *pbval = 0;
1943  if (!prval || !pgval ||!pbval)
1944  return ERROR_INT("&rval, &gval, &bval not all defined", procName, 1);
1945  *prval = *pgval = *pbval = 0;
1946 
1947  rval = (l_int32)(3.2405 * fxval - 1.5372 * fyval - 0.4985 * fzval + 0.5);
1948  gval = (l_int32)(-0.9693 * fxval + 1.8760 * fyval + 0.0416 * fzval + 0.5);
1949  bval = (l_int32)(0.0556 * fxval - 0.2040 * fyval + 1.0573 * fzval + 0.5);
1950  if (blackout == 0) { /* the usual situation; use nearest rgb color */
1951  *prval = L_MAX(0, L_MIN(rval, 255));
1952  *pgval = L_MAX(0, L_MIN(gval, 255));
1953  *pbval = L_MAX(0, L_MIN(bval, 255));
1954  } else { /* use black for out of gamut */
1955  if (rval >= 0 && rval < 256 && gval >= 0 && gval < 256 &&
1956  bval >= 0 && bval < 256) { /* in gamut */
1957  *prval = rval;
1958  *pgval = gval;
1959  *pbval = bval;
1960  }
1961  }
1962  return 0;
1963 }
1964 
1965 
1966 /*---------------------------------------------------------------------------*
1967  * Colorspace conversion between XYZ and LAB *
1968  *---------------------------------------------------------------------------*/
1988 FPIXA *
1990 {
1991 l_int32 w, h, wpl, i, j;
1992 l_float32 fxval, fyval, fzval, flval, faval, fbval;
1993 l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
1994 l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
1995 FPIX *fpix;
1996 FPIXA *fpixad;
1997 
1998  PROCNAME("fpixaConvertXYZToLAB");
1999 
2000  if (!fpixas || fpixaGetCount(fpixas) != 3)
2001  return (FPIXA *)ERROR_PTR("fpixas undefined/invalid", procName, NULL);
2002 
2003  /* Convert XYZ image */
2004  if (fpixaGetFPixDimensions(fpixas, 0, &w, &h))
2005  return (FPIXA *)ERROR_PTR("fpixas sizes not found", procName, NULL);
2006  fpixad = fpixaCreate(3);
2007  for (i = 0; i < 3; i++) {
2008  fpix = fpixCreate(w, h);
2009  fpixaAddFPix(fpixad, fpix, L_INSERT);
2010  }
2011  wpl = fpixGetWpl(fpix);
2012  datax = fpixaGetData(fpixas, 0);
2013  datay = fpixaGetData(fpixas, 1);
2014  dataz = fpixaGetData(fpixas, 2);
2015  datal = fpixaGetData(fpixad, 0);
2016  dataa = fpixaGetData(fpixad, 1);
2017  datab = fpixaGetData(fpixad, 2);
2018 
2019  /* Convert XYZ image */
2020  for (i = 0; i < h; i++) {
2021  linex = datax + i * wpl;
2022  liney = datay + i * wpl;
2023  linez = dataz + i * wpl;
2024  linel = datal + i * wpl;
2025  linea = dataa + i * wpl;
2026  lineb = datab + i * wpl;
2027  for (j = 0; j < w; j++) {
2028  fxval = *(linex + j);
2029  fyval = *(liney + j);
2030  fzval = *(linez + j);
2031  convertXYZToLAB(fxval, fyval, fzval, &flval, &faval, &fbval);
2032  *(linel + j) = flval;
2033  *(linea + j) = faval;
2034  *(lineb + j) = fbval;
2035  }
2036  }
2037 
2038  return fpixad;
2039 }
2040 
2041 
2054 FPIXA *
2056 {
2057 l_int32 w, h, wpl, i, j;
2058 l_float32 fxval, fyval, fzval, flval, faval, fbval;
2059 l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
2060 l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
2061 FPIX *fpix;
2062 FPIXA *fpixad;
2063 
2064  PROCNAME("fpixaConvertLABToXYZ");
2065 
2066  if (!fpixas || fpixaGetCount(fpixas) != 3)
2067  return (FPIXA *)ERROR_PTR("fpixas undefined/invalid", procName, NULL);
2068 
2069  /* Convert LAB image */
2070  if (fpixaGetFPixDimensions(fpixas, 0, &w, &h))
2071  return (FPIXA *)ERROR_PTR("fpixas sizes not found", procName, NULL);
2072  fpixad = fpixaCreate(3);
2073  for (i = 0; i < 3; i++) {
2074  fpix = fpixCreate(w, h);
2075  fpixaAddFPix(fpixad, fpix, L_INSERT);
2076  }
2077  wpl = fpixGetWpl(fpix);
2078  datal = fpixaGetData(fpixas, 0);
2079  dataa = fpixaGetData(fpixas, 1);
2080  datab = fpixaGetData(fpixas, 2);
2081  datax = fpixaGetData(fpixad, 0);
2082  datay = fpixaGetData(fpixad, 1);
2083  dataz = fpixaGetData(fpixad, 2);
2084 
2085  /* Convert XYZ image */
2086  for (i = 0; i < h; i++) {
2087  linel = datal + i * wpl;
2088  linea = dataa + i * wpl;
2089  lineb = datab + i * wpl;
2090  linex = datax + i * wpl;
2091  liney = datay + i * wpl;
2092  linez = dataz + i * wpl;
2093  for (j = 0; j < w; j++) {
2094  flval = *(linel + j);
2095  faval = *(linea + j);
2096  fbval = *(lineb + j);
2097  convertLABToXYZ(flval, faval, fbval, &fxval, &fyval, &fzval);
2098  *(linex + j) = fxval;
2099  *(liney + j) = fyval;
2100  *(linez + j) = fzval;
2101  }
2102  }
2103 
2104  return fpixad;
2105 }
2106 
2107 
2115 l_ok
2116 convertXYZToLAB(l_float32 xval,
2117  l_float32 yval,
2118  l_float32 zval,
2119  l_float32 *plval,
2120  l_float32 *paval,
2121  l_float32 *pbval)
2122 {
2123 l_float32 xn, yn, zn, fx, fy, fz;
2124 
2125  PROCNAME("convertXYZToLAB");
2126 
2127  if (plval) *plval = 0.0;
2128  if (paval) *paval = 0.0;
2129  if (pbval) *pbval = 0.0;
2130  if (!plval || !paval || !pbval)
2131  return ERROR_INT("&lval, &aval, &bval not all defined", procName, 1);
2132 
2133  /* First normalize to the corresponding white values */
2134  xn = 0.0041259 * xval;
2135  yn = 0.0039216 * yval;
2136  zn = 0.0036012 * zval;
2137  /* Then apply the lab_forward function */
2138  fx = lab_forward(xn);
2139  fy = lab_forward(yn);
2140  fz = lab_forward(zn);
2141  *plval = 116.0 * fy - 16.0;
2142  *paval = 500.0 * (fx - fy);
2143  *pbval = 200.0 * (fy - fz);
2144  return 0;
2145 }
2146 
2147 
2155 l_ok
2156 convertLABToXYZ(l_float32 lval,
2157  l_float32 aval,
2158  l_float32 bval,
2159  l_float32 *pxval,
2160  l_float32 *pyval,
2161  l_float32 *pzval)
2162 {
2163 l_float32 fx, fy, fz;
2164 l_float32 xw = 242.37; /* x component corresponding to rgb white */
2165 l_float32 yw = 255.0; /* y component corresponding to rgb white */
2166 l_float32 zw = 277.69; /* z component corresponding to rgb white */
2167 
2168  PROCNAME("convertLABToXYZ");
2169 
2170  if (pxval) *pxval = 0.0;
2171  if (pyval) *pyval = 0.0;
2172  if (pzval) *pzval = 0.0;
2173  if (!pxval || !pyval || !pzval)
2174  return ERROR_INT("&xval, &yval, &zval not all defined", procName, 1);
2175 
2176  fy = 0.0086207 * (16.0 + lval);
2177  fx = fy + 0.002 * aval;
2178  fz = fy - 0.005 * bval;
2179  *pxval = xw * lab_reverse(fx);
2180  *pyval = yw * lab_reverse(fy);
2181  *pzval = zw * lab_reverse(fz);
2182  return 0;
2183 }
2184 
2185 
2186 /*
2187  * See http://en.wikipedia.org/wiki/Lab_color_space for formulas.
2188  * This is the forward function: from xyz to lab. It includes a rational
2189  * function approximation over [0.008856 ... 1] to the cube root, from
2190  * "Fast Color Space Transformations Using Minimax Approximations",
2191  * M. Celebi et al, http://arxiv.org/pdf/1009.0854v1.pdf.
2192  */
2193 static l_float32
2194 lab_forward(l_float32 v)
2195 {
2196 const l_float32 f_thresh = 0.008856; /* (6/29)^3 */
2197 const l_float32 f_factor = 7.787; /* (1/3) * (29/6)^2) */
2198 const l_float32 f_offset = 0.13793; /* 4/29 */
2199 
2200  if (v > f_thresh) {
2201 #if SLOW_CUBE_ROOT
2202  return powf(v, 0.333333);
2203 #else
2204  l_float32 num, den;
2205  num = 4.37089e-04 + v * (9.52695e-02 + v * (1.25201 + v * 1.30273));
2206  den = 3.91236e-03 + v * (2.95408e-01 + v * (1.71714 + v * 6.34341e-01));
2207  return num / den;
2208 #endif
2209  } else {
2210  return f_factor * v + f_offset;
2211  }
2212 }
2213 
2214 
2215 /*
2216  * See http://en.wikipedia.org/wiki/Lab_color_space for formulas.
2217  * This is the reverse (inverse) function: from lab to xyz.
2218  */
2219 static l_float32
2220 lab_reverse(l_float32 v)
2221 {
2222 const l_float32 r_thresh = 0.20690; /* 6/29 */
2223 const l_float32 r_factor = 0.12842; /* 3 * (6/29)^2 */
2224 const l_float32 r_offset = 0.13793; /* 4/29 */
2225 
2226  if (v > r_thresh) {
2227  return v * v * v;
2228  } else {
2229  return r_factor * (v - r_offset);
2230  }
2231 }
2232 
2233 
2234 /*---------------------------------------------------------------------------*
2235  * Colorspace conversion between RGB and LAB *
2236  *---------------------------------------------------------------------------*/
2249 FPIXA *
2251 {
2252 l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
2253 l_uint32 *lines, *datas;
2254 l_float32 flval, faval, fbval;
2255 l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
2256 FPIX *fpix;
2257 FPIXA *fpixa;
2258 
2259  PROCNAME("pixConvertRGBToLAB");
2260 
2261  if (!pixs || pixGetDepth(pixs) != 32)
2262  return (FPIXA *)ERROR_PTR("pixs undefined or not rgb", procName, NULL);
2263 
2264  /* Convert RGB image */
2265  pixGetDimensions(pixs, &w, &h, NULL);
2266  fpixa = fpixaCreate(3);
2267  for (i = 0; i < 3; i++) {
2268  fpix = fpixCreate(w, h);
2269  fpixaAddFPix(fpixa, fpix, L_INSERT);
2270  }
2271  wpls = pixGetWpl(pixs);
2272  wpld = fpixGetWpl(fpix);
2273  datas = pixGetData(pixs);
2274  datal = fpixaGetData(fpixa, 0);
2275  dataa = fpixaGetData(fpixa, 1);
2276  datab = fpixaGetData(fpixa, 2);
2277  for (i = 0; i < h; i++) {
2278  lines = datas + i * wpls;
2279  linel = datal + i * wpld;
2280  linea = dataa + i * wpld;
2281  lineb = datab + i * wpld;
2282  for (j = 0; j < w; j++) {
2283  extractRGBValues(lines[j], &rval, &gval, &bval);
2284  convertRGBToLAB(rval, gval, bval, &flval, &faval, &fbval);
2285  *(linel + j) = flval;
2286  *(linea + j) = faval;
2287  *(lineb + j) = fbval;
2288  }
2289  }
2290 
2291  return fpixa;
2292 }
2293 
2294 
2306 PIX *
2308 {
2309 l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
2310 l_float32 flval, faval, fbval;
2311 l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
2312 l_uint32 *lined, *datad;
2313 PIX *pixd;
2314 FPIX *fpix;
2315 
2316  PROCNAME("fpixaConvertLABToRGB");
2317 
2318  if (!fpixa || fpixaGetCount(fpixa) != 3)
2319  return (PIX *)ERROR_PTR("fpixa undefined or invalid", procName, NULL);
2320 
2321  /* Convert LAB image */
2322  if (fpixaGetFPixDimensions(fpixa, 0, &w, &h))
2323  return (PIX *)ERROR_PTR("fpixa dimensions not found", procName, NULL);
2324  pixd = pixCreate(w, h, 32);
2325  wpld = pixGetWpl(pixd);
2326  datad = pixGetData(pixd);
2327  datal = fpixaGetData(fpixa, 0);
2328  dataa = fpixaGetData(fpixa, 1);
2329  datab = fpixaGetData(fpixa, 2);
2330  fpix = fpixaGetFPix(fpixa, 0, L_CLONE);
2331  wpls = fpixGetWpl(fpix);
2332  fpixDestroy(&fpix);
2333  for (i = 0; i < h; i++) {
2334  linel = datal + i * wpls;
2335  linea = dataa + i * wpls;
2336  lineb = datab + i * wpls;
2337  lined = datad + i * wpld;
2338  for (j = 0; j < w; j++) {
2339  flval = linel[j];
2340  faval = linea[j];
2341  fbval = lineb[j];
2342  convertLABToRGB(flval, faval, fbval, &rval, &gval, &bval);
2343  composeRGBPixel(rval, gval, bval, lined + j);
2344  }
2345  }
2346 
2347  return pixd;
2348 }
2349 
2350 
2364 l_ok
2365 convertRGBToLAB(l_int32 rval,
2366  l_int32 gval,
2367  l_int32 bval,
2368  l_float32 *pflval,
2369  l_float32 *pfaval,
2370  l_float32 *pfbval)
2371 {
2372 l_float32 fxval, fyval, fzval;
2373 
2374  PROCNAME("convertRGBToLAB");
2375 
2376  if (pflval) *pflval = 0.0;
2377  if (pfaval) *pfaval = 0.0;
2378  if (pfbval) *pfbval = 0.0;
2379  if (!pflval || !pfaval || !pfbval)
2380  return ERROR_INT("&flval, &faval, &fbval not all defined", procName, 1);
2381 
2382  convertRGBToXYZ(rval, gval, bval, &fxval, &fyval, &fzval);
2383  convertXYZToLAB(fxval, fyval, fzval, pflval, pfaval, pfbval);
2384  return 0;
2385 }
2386 
2387 
2401 l_ok
2402 convertLABToRGB(l_float32 flval,
2403  l_float32 faval,
2404  l_float32 fbval,
2405  l_int32 *prval,
2406  l_int32 *pgval,
2407  l_int32 *pbval)
2408 {
2409 l_float32 fxval, fyval, fzval;
2410 
2411  PROCNAME("convertLABToRGB");
2412 
2413  if (prval) *prval = 0;
2414  if (pgval) *pgval = 0;
2415  if (pbval) *pbval = 0;
2416  if (!prval || !pgval || !pbval)
2417  return ERROR_INT("&rval, &gval, &bval not all defined", procName, 1);
2418 
2419  convertLABToXYZ(flval, faval, fbval, &fxval, &fyval, &fzval);
2420  convertXYZToRGB(fxval, fyval, fzval, 0, prval, pgval, pbval);
2421  return 0;
2422 }
2423 
2424 
2425 /*---------------------------------------------------------------------------*
2426  * Gamut display of RGB color space *
2427  *---------------------------------------------------------------------------*/
2447 PIX *
2448 pixMakeGamutRGB(l_int32 scale)
2449 {
2450 l_int32 i, j, k;
2451 l_uint32 val32;
2452 PIX *pix1, *pix2;
2453 PIXA *pixa;
2454 
2455  if (scale <= 0) scale = 8; /* default */
2456 
2457  pixa = pixaCreate(32);
2458  for (k = 0; k < 32; k++) {
2459  pix1 = pixCreate(32, 32, 32);
2460  for (i = 0; i < 32; i++) {
2461  for (j = 0; j < 32; j++) {
2462  composeRGBPixel(8 * j, 8 * i, 8 * k, &val32);
2463  pixSetPixel(pix1, j, i, val32);
2464  }
2465  }
2466  pixaAddPix(pixa, pix1, L_INSERT);
2467  }
2468  pix2 = pixaDisplayTiledInColumns(pixa, 8, scale, 5, 0);
2469  pixaDestroy(&pixa);
2470  return pix2;
2471 }
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
#define SET_DATA_FOUR_BYTES(pdata, n, val)
Definition: arrayaccess.h:235
#define GET_DATA_FOUR_BYTES(pdata, n)
Definition: arrayaccess.h:231
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
#define CLEAR_DATA_BIT(pdata, n)
Definition: arrayaccess.h:131
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:708
l_ok pixcmapResetColor(PIXCMAP *cmap, l_int32 index, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapResetColor()
Definition: colormap.c:966
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:824
PIX * fpixaConvertXYZToRGB(FPIXA *fpixa)
fpixaConvertXYZToRGB()
Definition: colorspace.c:1828
l_ok pixFindHistoPeaksHSV(PIX *pixs, l_int32 type, l_int32 width, l_int32 height, l_int32 npeaks, l_float32 erasefactor, PTA **ppta, NUMA **pnatot, PIXA **ppixa)
pixFindHistoPeaksHSV()
Definition: colorspace.c:1261
PIX * pixMakeRangeMaskHV(PIX *pixs, l_int32 huecenter, l_int32 huehw, l_int32 valcenter, l_int32 valhw, l_int32 regionflag)
pixMakeRangeMaskHV()
Definition: colorspace.c:809
l_ok convertLABToRGB(l_float32 flval, l_float32 faval, l_float32 fbval, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
convertLABToRGB()
Definition: colorspace.c:2402
PIX * pixConvertRGBToHSV(PIX *pixd, PIX *pixs)
pixConvertRGBToHSV()
Definition: colorspace.c:142
FPIXA * fpixaConvertXYZToLAB(FPIXA *fpixas)
fpixaConvertXYZToLAB()
Definition: colorspace.c:1989
l_ok convertXYZToRGB(l_float32 fxval, l_float32 fyval, l_float32 fzval, l_int32 blackout, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
convertXYZToRGB()
Definition: colorspace.c:1928
FPIXA * fpixaConvertLABToXYZ(FPIXA *fpixas)
fpixaConvertLABToXYZ()
Definition: colorspace.c:2055
FPIXA * pixConvertRGBToLAB(PIX *pixs)
pixConvertRGBToLAB()
Definition: colorspace.c:2250
PIX * pixConvertRGBToValue(PIX *pixs)
pixConvertRGBToValue()
Definition: colorspace.c:641
PIX * displayHSVColorRange(l_int32 hval, l_int32 sval, l_int32 vval, l_int32 huehw, l_int32 sathw, l_int32 nsamp, l_int32 factor)
displayHSVColorRange()
Definition: colorspace.c:1385
l_ok convertHSVToRGB(l_int32 hval, l_int32 sval, l_int32 vval, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
convertHSVToRGB()
Definition: colorspace.c:343
PIX * pixConvertRGBToHue(PIX *pixs)
pixConvertRGBToHue()
Definition: colorspace.c:500
PIX * pixMakeHistoHV(PIX *pixs, l_int32 factor, NUMA **pnahue, NUMA **pnaval)
pixMakeHistoHV()
Definition: colorspace.c:1087
l_ok convertRGBToHSV(l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *phval, l_int32 *psval, l_int32 *pvval)
convertRGBToHSV()
Definition: colorspace.c:281
l_ok pixcmapConvertHSVToRGB(PIXCMAP *cmap)
pixcmapConvertHSVToRGB()
Definition: colorspace.c:465
l_ok pixcmapConvertRGBToHSV(PIXCMAP *cmap)
pixcmapConvertRGBToHSV()
Definition: colorspace.c:432
PIX * pixConvertYUVToRGB(PIX *pixd, PIX *pixs)
pixConvertYUVToRGB()
Definition: colorspace.c:1524
l_ok convertRGBToYUV(l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pyval, l_int32 *puval, l_int32 *pvval)
convertRGBToYUV()
Definition: colorspace.c:1589
PIX * pixMakeGamutRGB(l_int32 scale)
pixMakeGamutRGB()
Definition: colorspace.c:2448
PIX * fpixaConvertLABToRGB(FPIXA *fpixa)
fpixaConvertLABToRGB()
Definition: colorspace.c:2307
l_ok pixcmapConvertRGBToYUV(PIXCMAP *cmap)
pixcmapConvertRGBToYUV()
Definition: colorspace.c:1685
l_ok convertLABToXYZ(l_float32 lval, l_float32 aval, l_float32 bval, l_float32 *pxval, l_float32 *pyval, l_float32 *pzval)
convertLABToXYZ()
Definition: colorspace.c:2156
l_ok convertXYZToLAB(l_float32 xval, l_float32 yval, l_float32 zval, l_float32 *plval, l_float32 *paval, l_float32 *pbval)
convertXYZToLAB()
Definition: colorspace.c:2116
FPIXA * pixConvertRGBToXYZ(PIX *pixs)
pixConvertRGBToXYZ()
Definition: colorspace.c:1769
PIX * pixConvertHSVToRGB(PIX *pixd, PIX *pixs)
pixConvertHSVToRGB()
Definition: colorspace.c:206
PIX * pixMakeRangeMaskHS(PIX *pixs, l_int32 huecenter, l_int32 huehw, l_int32 satcenter, l_int32 sathw, l_int32 regionflag)
pixMakeRangeMaskHS()
Definition: colorspace.c:710
PIX * pixMakeRangeMaskSV(PIX *pixs, l_int32 satcenter, l_int32 sathw, l_int32 valcenter, l_int32 valhw, l_int32 regionflag)
pixMakeRangeMaskSV()
Definition: colorspace.c:907
l_ok convertRGBToLAB(l_int32 rval, l_int32 gval, l_int32 bval, l_float32 *pflval, l_float32 *pfaval, l_float32 *pfbval)
convertRGBToLAB()
Definition: colorspace.c:2365
PIX * pixConvertRGBToYUV(PIX *pixd, PIX *pixs)
pixConvertRGBToYUV()
Definition: colorspace.c:1461
PIX * pixMakeHistoHS(PIX *pixs, l_int32 factor, NUMA **pnahue, NUMA **pnasat)
pixMakeHistoHS()
Definition: colorspace.c:996
l_ok convertYUVToRGB(l_int32 yval, l_int32 uval, l_int32 vval, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
convertYUVToRGB()
Definition: colorspace.c:1637
l_ok convertRGBToXYZ(l_int32 rval, l_int32 gval, l_int32 bval, l_float32 *pfxval, l_float32 *pfyval, l_float32 *pfzval)
convertRGBToXYZ()
Definition: colorspace.c:1886
l_ok pixcmapConvertYUVToRGB(PIXCMAP *cmap)
pixcmapConvertYUVToRGB()
Definition: colorspace.c:1718
PIX * pixConvertRGBToSaturation(PIX *pixs)
pixConvertRGBToSaturation()
Definition: colorspace.c:576
PIX * pixMakeHistoSV(PIX *pixs, l_int32 factor, NUMA **pnasat, NUMA **pnaval)
pixMakeHistoSV()
Definition: colorspace.c:1170
PIX * pixWindowedMean(PIX *pixs, l_int32 wc, l_int32 hc, l_int32 hasborder, l_int32 normflag)
pixWindowedMean()
Definition: convolve.c:1073
l_ok fpixaAddFPix(FPIXA *fpixa, FPIX *fpix, l_int32 copyflag)
fpixaAddFPix()
Definition: fpix1.c:751
l_float32 * fpixaGetData(FPIXA *fpixa, l_int32 index)
fpixaGetData()
Definition: fpix1.c:970
FPIX * fpixaGetFPix(FPIXA *fpixa, l_int32 index, l_int32 accesstype)
fpixaGetFPix()
Definition: fpix1.c:907
l_int32 fpixGetWpl(FPIX *fpix)
fpixGetWpl()
Definition: fpix1.c:376
FPIXA * fpixaCreate(l_int32 n)
fpixaCreate()
Definition: fpix1.c:631
void fpixDestroy(FPIX **pfpix)
fpixDestroy()
Definition: fpix1.c:292
l_int32 fpixaGetCount(FPIXA *fpixa)
fpixaGetCount()
Definition: fpix1.c:866
FPIX * fpixCreate(l_int32 width, l_int32 height)
fpixCreate()
Definition: fpix1.c:156
l_ok fpixaGetFPixDimensions(FPIXA *fpixa, l_int32 index, l_int32 *pw, l_int32 *ph)
fpixaGetFPixDimensions()
Definition: fpix1.c:936
l_ok pixRenderHashBoxArb(PIX *pix, BOX *box, l_int32 spacing, l_int32 width, l_int32 orient, l_int32 outline, l_int32 rval, l_int32 gval, l_int32 bval)
pixRenderHashBoxArb()
Definition: graphics.c:1906
l_ok numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
Definition: numabasic.c:478
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_ok numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition: numabasic.c:685
l_ok numaShiftValue(NUMA *na, l_int32 index, l_float32 diff)
numaShiftValue()
Definition: numabasic.c:811
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1949
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:263
l_ok pixClearAll(PIX *pix)
pixClearAll()
Definition: pix2.c:789
l_ok pixClearInRect(PIX *pix, BOX *box)
pixClearInRect()
Definition: pix2.c:1118
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition: pix2.c:2210
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 pixSetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetRGBPixel()
Definition: pix2.c:382
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition: pix2.c:2101
l_ok pixGetMaxValueInRect(PIX *pixs, BOX *box, l_uint32 *pmaxval, l_int32 *pxmax, l_int32 *pymax)
pixGetMaxValueInRect()
Definition: pix4.c:2352
@ L_HS_HISTO
Definition: pix.h:1190
@ L_SV_HISTO
Definition: pix.h:1192
@ L_HV_HISTO
Definition: pix.h:1191
@ L_NEG_SLOPE_LINE
Definition: pix.h:1016
@ REMOVE_CMAP_TO_FULL_COLOR
Definition: pix.h:258
@ L_CLONE
Definition: pix.h:713
@ L_INSERT
Definition: pix.h:711
@ L_EXCLUDE_REGION
Definition: pix.h:1201
@ L_INCLUDE_REGION
Definition: pix.h:1200
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:506
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
PIX * pixaDisplayTiledInColumns(PIXA *pixas, l_int32 nx, l_float32 scalefactor, l_int32 spacing, l_int32 border)
pixaDisplayTiledInColumns()
Definition: pixafunc2.c:930
PIX * pixMaxDynamicRange(PIX *pixs, l_int32 type)
pixMaxDynamicRange()
Definition: pixarith.c:1253
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
PIX * pixConvertGrayToFalseColor(PIX *pixs, l_float32 gamma)
pixConvertGrayToFalseColor()
Definition: pixconv.c:1858
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:343
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
PIX * pixScaleBySampling(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBySampling()
Definition: scale1.c:1338
PIX * pixExpandReplicate(PIX *pixs, l_int32 factor)
pixExpandReplicate()
Definition: scale2.c:872
Definition: pix.h:481
Definition: pix.h:579
Definition: pix.h:594
Definition: array.h:71
Definition: pix.h:139
Definition: pix.h:456
Definition: pix.h:517
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306