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 */
99static l_float32 lab_forward(l_float32 v);
100static l_float32 lab_reverse(l_float32 v);
101
102/*---------------------------------------------------------------------------*
103 * Colorspace conversion between RGB and HSB *
104 *---------------------------------------------------------------------------*/
141PIX *
143 PIX *pixs)
144{
145l_int32 w, h, d, wpl, i, j, rval, gval, bval, hval, sval, vval;
146l_uint32 *line, *data;
147PIXCMAP *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
205PIX *
207 PIX *pixs)
208{
209l_int32 w, h, d, wpl, i, j, rval, gval, bval, hval, sval, vval;
210l_uint32 pixel;
211l_uint32 *line, *data;
212PIXCMAP *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
280l_ok
281convertRGBToHSV(l_int32 rval,
282 l_int32 gval,
283 l_int32 bval,
284 l_int32 *phval,
285 l_int32 *psval,
286 l_int32 *pvval)
287{
288l_int32 minrg, maxrg, min, max, delta;
289l_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
342l_ok
343convertHSVToRGB(l_int32 hval,
344 l_int32 sval,
345 l_int32 vval,
346 l_int32 *prval,
347 l_int32 *pgval,
348 l_int32 *pbval)
349{
350l_int32 i, x, y, z;
351l_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
431l_ok
433{
434l_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
464l_ok
466{
467l_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
499PIX *
501{
502l_int32 w, h, d, wplt, wpld;
503l_int32 i, j, rval, gval, bval, hval, minrg, min, maxrg, max, delta;
504l_float32 fh;
505l_uint32 pixel;
506l_uint32 *linet, *lined, *datat, *datad;
507PIX *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
575PIX *
577{
578l_int32 w, h, d, wplt, wpld;
579l_int32 i, j, rval, gval, bval, sval, minrg, min, maxrg, max, delta;
580l_uint32 pixel;
581l_uint32 *linet, *lined, *datat, *datad;
582PIX *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
640PIX *
642{
643l_int32 w, h, d, wplt, wpld;
644l_int32 i, j, rval, gval, bval, maxrg, max;
645l_uint32 pixel;
646l_uint32 *linet, *lined, *datat, *datad;
647PIX *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 *---------------------------------------------------------------------------*/
709PIX *
711 l_int32 huecenter,
712 l_int32 huehw,
713 l_int32 satcenter,
714 l_int32 sathw,
715 l_int32 regionflag)
716{
717l_int32 i, j, w, h, wplt, wpld, hstart, hend, sstart, send, hval, sval;
718l_int32 *hlut, *slut;
719l_uint32 pixel;
720l_uint32 *datat, *datad, *linet, *lined;
721PIX *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
808PIX *
810 l_int32 huecenter,
811 l_int32 huehw,
812 l_int32 valcenter,
813 l_int32 valhw,
814 l_int32 regionflag)
815{
816l_int32 i, j, w, h, wplt, wpld, hstart, hend, vstart, vend, hval, vval;
817l_int32 *hlut, *vlut;
818l_uint32 pixel;
819l_uint32 *datat, *datad, *linet, *lined;
820PIX *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
906PIX *
908 l_int32 satcenter,
909 l_int32 sathw,
910 l_int32 valcenter,
911 l_int32 valhw,
912 l_int32 regionflag)
913{
914l_int32 i, j, w, h, wplt, wpld, sval, vval, sstart, send, vstart, vend;
915l_int32 *slut, *vlut;
916l_uint32 pixel;
917l_uint32 *datat, *datad, *linet, *lined;
918PIX *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
995PIX *
997 l_int32 factor,
998 NUMA **pnahue,
999 NUMA **pnasat)
1000{
1001l_int32 i, j, w, h, wplt, hval, sval, nd;
1002l_uint32 pixel;
1003l_uint32 *datat, *linet;
1004void **lined32;
1005NUMA *nahue, *nasat;
1006PIX *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
1086PIX *
1088 l_int32 factor,
1089 NUMA **pnahue,
1090 NUMA **pnaval)
1091{
1092l_int32 i, j, w, h, wplt, hval, vval, nd;
1093l_uint32 pixel;
1094l_uint32 *datat, *linet;
1095void **lined32;
1096NUMA *nahue, *naval;
1097PIX *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
1169PIX *
1171 l_int32 factor,
1172 NUMA **pnasat,
1173 NUMA **pnaval)
1174{
1175l_int32 i, j, w, h, wplt, sval, vval, nd;
1176l_uint32 pixel;
1177l_uint32 *datat, *linet;
1178void **lined32;
1179NUMA *nasat, *naval;
1180PIX *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
1260l_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{
1271l_int32 i, xmax, ymax, ewidth, eheight;
1272l_uint32 maxval;
1273BOX *box;
1274NUMA *natot;
1275PIX *pixh, *pixw, *pix1, *pix2, *pix3;
1276PTA *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
1384PIX *
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{
1393l_int32 i, j, w, huedelta, satdelta, hue, sat, rval, gval, bval;
1394PIX *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 *---------------------------------------------------------------------------*/
1460PIX *
1462 PIX *pixs)
1463{
1464l_int32 w, h, d, wpl, i, j, rval, gval, bval, yval, uval, vval;
1465l_uint32 *line, *data;
1466PIXCMAP *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 */
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
1523PIX *
1525 PIX *pixs)
1526{
1527l_int32 w, h, d, wpl, i, j, rval, gval, bval, yval, uval, vval;
1528l_uint32 pixel;
1529l_uint32 *line, *data;
1530PIXCMAP *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 */
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
1588l_ok
1589convertRGBToYUV(l_int32 rval,
1590 l_int32 gval,
1591 l_int32 bval,
1592 l_int32 *pyval,
1593 l_int32 *puval,
1594 l_int32 *pvval)
1595{
1596l_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
1636l_ok
1637convertYUVToRGB(l_int32 yval,
1638 l_int32 uval,
1639 l_int32 vval,
1640 l_int32 *prval,
1641 l_int32 *pgval,
1642 l_int32 *pbval)
1643{
1644l_int32 rval, gval, bval;
1645l_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
1684l_ok
1686{
1687l_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
1717l_ok
1719{
1720l_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 *---------------------------------------------------------------------------*/
1768FPIXA *
1770{
1771l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
1772l_uint32 *lines, *datas;
1773l_float32 fxval, fyval, fzval;
1774l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
1775FPIX *fpix;
1776FPIXA *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
1827PIX *
1829{
1830l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
1831l_float32 fxval, fyval, fzval;
1832l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
1833l_uint32 *lined, *datad;
1834PIX *pixd;
1835FPIX *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
1885l_ok
1886convertRGBToXYZ(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
1927l_ok
1928convertXYZToRGB(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{
1936l_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 *---------------------------------------------------------------------------*/
1988FPIXA *
1990{
1991l_int32 w, h, wpl, i, j;
1992l_float32 fxval, fyval, fzval, flval, faval, fbval;
1993l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
1994l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
1995FPIX *fpix;
1996FPIXA *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
2054FPIXA *
2056{
2057l_int32 w, h, wpl, i, j;
2058l_float32 fxval, fyval, fzval, flval, faval, fbval;
2059l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
2060l_float32 *linex, *liney, *linez, *datax, *datay, *dataz;
2061FPIX *fpix;
2062FPIXA *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
2115l_ok
2116convertXYZToLAB(l_float32 xval,
2117 l_float32 yval,
2118 l_float32 zval,
2119 l_float32 *plval,
2120 l_float32 *paval,
2121 l_float32 *pbval)
2122{
2123l_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
2155l_ok
2156convertLABToXYZ(l_float32 lval,
2157 l_float32 aval,
2158 l_float32 bval,
2159 l_float32 *pxval,
2160 l_float32 *pyval,
2161 l_float32 *pzval)
2162{
2163l_float32 fx, fy, fz;
2164l_float32 xw = 242.37; /* x component corresponding to rgb white */
2165l_float32 yw = 255.0; /* y component corresponding to rgb white */
2166l_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 */
2193static l_float32
2194lab_forward(l_float32 v)
2195{
2196const l_float32 f_thresh = 0.008856; /* (6/29)^3 */
2197const l_float32 f_factor = 7.787; /* (1/3) * (29/6)^2) */
2198const 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 */
2219static l_float32
2220lab_reverse(l_float32 v)
2221{
2222const l_float32 r_thresh = 0.20690; /* 6/29 */
2223const l_float32 r_factor = 0.12842; /* 3 * (6/29)^2 */
2224const 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 *---------------------------------------------------------------------------*/
2249FPIXA *
2251{
2252l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
2253l_uint32 *lines, *datas;
2254l_float32 flval, faval, fbval;
2255l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
2256FPIX *fpix;
2257FPIXA *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
2306PIX *
2308{
2309l_int32 w, h, wpls, wpld, i, j, rval, gval, bval;
2310l_float32 flval, faval, fbval;
2311l_float32 *linel, *linea, *lineb, *datal, *dataa, *datab;
2312l_uint32 *lined, *datad;
2313PIX *pixd;
2314FPIX *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
2364l_ok
2365convertRGBToLAB(l_int32 rval,
2366 l_int32 gval,
2367 l_int32 bval,
2368 l_float32 *pflval,
2369 l_float32 *pfaval,
2370 l_float32 *pfbval)
2371{
2372l_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
2401l_ok
2402convertLABToRGB(l_float32 flval,
2403 l_float32 faval,
2404 l_float32 fbval,
2405 l_int32 *prval,
2406 l_int32 *pgval,
2407 l_int32 *pbval)
2408{
2409l_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 *---------------------------------------------------------------------------*/
2447PIX *
2448pixMakeGamutRGB(l_int32 scale)
2449{
2450l_int32 i, j, k;
2451l_uint32 val32;
2452PIX *pix1, *pix2;
2453PIXA *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
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
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
FPIXA * pixConvertRGBToLAB(PIX *pixs)
pixConvertRGBToLAB()
Definition: colorspace.c:2250
PIX * pixConvertRGBToValue(PIX *pixs)
pixConvertRGBToValue()
Definition: colorspace.c:641
PIX * fpixaConvertLABToRGB(FPIXA *fpixa)
fpixaConvertLABToRGB()
Definition: colorspace.c:2307
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
PIX * pixMakeGamutRGB(l_int32 scale)
pixMakeGamutRGB()
Definition: colorspace.c:2448
PIX * fpixaConvertXYZToRGB(FPIXA *fpixa)
fpixaConvertXYZToRGB()
Definition: colorspace.c:1828
FPIXA * fpixaConvertLABToXYZ(FPIXA *fpixas)
fpixaConvertLABToXYZ()
Definition: colorspace.c:2055
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 * pixConvertYUVToRGB(PIX *pixd, PIX *pixs)
pixConvertYUVToRGB()
Definition: colorspace.c:1524
PIX * pixMakeRangeMaskHV(PIX *pixs, l_int32 huecenter, l_int32 huehw, l_int32 valcenter, l_int32 valhw, l_int32 regionflag)
pixMakeRangeMaskHV()
Definition: colorspace.c:809
PIX * pixConvertRGBToSaturation(PIX *pixs)
pixConvertRGBToSaturation()
Definition: colorspace.c:576
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 * pixMakeRangeMaskHS(PIX *pixs, l_int32 huecenter, l_int32 huehw, l_int32 satcenter, l_int32 sathw, l_int32 regionflag)
pixMakeRangeMaskHS()
Definition: colorspace.c:710
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
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 * fpixaConvertXYZToLAB(FPIXA *fpixas)
fpixaConvertXYZToLAB()
Definition: colorspace.c:1989
PIX * pixConvertRGBToYUV(PIX *pixd, PIX *pixs)
pixConvertRGBToYUV()
Definition: colorspace.c:1461
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 * pixMakeHistoSV(PIX *pixs, l_int32 factor, NUMA **pnasat, NUMA **pnaval)
pixMakeHistoSV()
Definition: colorspace.c:1170
PIX * pixMakeRangeMaskSV(PIX *pixs, l_int32 satcenter, l_int32 sathw, l_int32 valcenter, l_int32 valhw, l_int32 regionflag)
pixMakeRangeMaskSV()
Definition: colorspace.c:907
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
PIX * pixConvertHSVToRGB(PIX *pixd, PIX *pixs)
pixConvertHSVToRGB()
Definition: colorspace.c:206
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
FPIXA * pixConvertRGBToXYZ(PIX *pixs)
pixConvertRGBToXYZ()
Definition: colorspace.c:1769
PIX * pixConvertRGBToHSV(PIX *pixd, PIX *pixs)
pixConvertRGBToHSV()
Definition: colorspace.c:142
PIX * pixMakeHistoHS(PIX *pixs, l_int32 factor, NUMA **pnahue, NUMA **pnasat)
pixMakeHistoHS()
Definition: colorspace.c:996
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
PIX * pixWindowedMean(PIX *pixs, l_int32 wc, l_int32 hc, l_int32 hasborder, l_int32 normflag)
pixWindowedMean()
Definition: convolve.c:1073
l_float32 * fpixaGetData(FPIXA *fpixa, l_int32 index)
fpixaGetData()
Definition: fpix1.c:970
FPIX * fpixCreate(l_int32 width, l_int32 height)
fpixCreate()
Definition: fpix1.c:156
l_ok fpixaAddFPix(FPIXA *fpixa, FPIX *fpix, l_int32 copyflag)
fpixaAddFPix()
Definition: fpix1.c:751
FPIX * fpixaGetFPix(FPIXA *fpixa, l_int32 index, l_int32 accesstype)
fpixaGetFPix()
Definition: fpix1.c:907
FPIXA * fpixaCreate(l_int32 n)
fpixaCreate()
Definition: fpix1.c:631
l_int32 fpixGetWpl(FPIX *fpix)
fpixGetWpl()
Definition: fpix1.c:376
void fpixDestroy(FPIX **pfpix)
fpixDestroy()
Definition: fpix1.c:292
l_int32 fpixaGetCount(FPIXA *fpixa)
fpixaGetCount()
Definition: fpix1.c:866
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
l_ok numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
Definition: numabasic.c:685
NUMA * numaCreate(l_int32 n)
numaCreate()
Definition: numabasic.c:194
l_ok numaShiftValue(NUMA *na, l_int32 index, l_float32 diff)
numaShiftValue()
Definition: numabasic.c:811
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1949
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok 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
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition: pix2.c:2210
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:817
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition: pix2.c:2101
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
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 * pixConvertGrayToFalseColor(PIX *pixs, l_float32 gamma)
pixConvertGrayToFalseColor()
Definition: pixconv.c:1858
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:328
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3332
PTA * ptaCreate(l_int32 n)
ptaCreate()
Definition: ptabasic.c:120
l_ok ptaAddPt(PTA *pta, l_float32 x, l_float32 y)
ptaAddPt()
Definition: ptabasic.c:343
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