148#include <config_auto.h>
151#include "allheaders.h"
153static l_int32 blendComponents(l_int32 a, l_int32 b, l_float32 fract);
154static l_int32 blendHardLightComponents(l_int32 a, l_int32 b, l_float32 fract);
182l_int32 w1, h1, d1, d2;
184PIX *pixc, *pixt, *pixd;
187 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, NULL);
189 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, NULL);
192 d1 = pixGetDepth(pixs1);
193 d2 = pixGetDepth(pixs2);
194 if (d1 == 1 && d2 > 1)
195 return (
PIX *)ERROR_PTR(
"mixing gray or color with 1 bpp",
200 d2 = pixGetDepth(pixt);
208 pixGetDimensions(pixs1, &w1, &h1, NULL);
209 box = boxCreate(-x, -y, w1, h1);
210 pixc = pixClipRectangle(pixt, box, NULL);
213 L_WARNING(
"box doesn't overlap pix\n", __func__);
223 }
else if (d2 == 8) {
271l_int32 i, j, d, wc, hc, w, h, wplc;
272l_int32 val, rval, gval, bval;
274l_uint32 *linec, *datac;
275PIX *pixc, *pix1, *pix2;
278 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, NULL);
280 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, NULL);
281 if (pixGetDepth(pixs1) == 1)
282 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, NULL);
283 if (pixGetDepth(pixs2) != 1)
284 return (
PIX *)ERROR_PTR(
"pixs2 not 1 bpp", __func__, NULL);
285 if (pixd == pixs1 && pixGetColormap(pixs1))
286 return (
PIX *)ERROR_PTR(
"inplace; pixs1 has colormap", __func__, NULL);
287 if (pixd && (pixd != pixs1))
288 return (
PIX *)ERROR_PTR(
"pixd must be NULL or pixs1", __func__, NULL);
289 if (fract < 0.0 || fract > 1.0) {
290 L_WARNING(
"fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
295 L_WARNING(
"invalid blend type; setting to L_BLEND_WITH_INVERSE\n",
307 if (pixGetDepth(pix1) < 8)
308 pix2 = pixConvertTo8(pix1, FALSE);
310 pix2 = pixClone(pix1);
311 pixd = pixCopy(NULL, pix2);
316 pixGetDimensions(pixd, &w, &h, &d);
317 pixc = pixClone(pixs2);
318 wc = pixGetWidth(pixc);
319 hc = pixGetHeight(pixc);
320 datac = pixGetData(pixc);
321 wplc = pixGetWpl(pixc);
334 for (i = 0; i < hc; i++) {
335 if (i + y < 0 || i + y >= h)
continue;
336 linec = datac + i * wplc;
337 for (j = 0; j < wc; j++) {
338 if (j + x < 0 || j + x >= w)
continue;
344 pixGetPixel(pixd, x + j, y + i, &pixval);
345 val = (l_int32)(pixval + fract * (255 - 2 * pixval));
346 pixSetPixel(pixd, x + j, y + i, val);
349 pixGetPixel(pixd, x + j, y + i, &pixval);
350 extractRGBValues(pixval, &rval, &gval, &bval);
351 rval = (l_int32)(rval + fract * (255 - 2 * rval));
352 gval = (l_int32)(gval + fract * (255 - 2 * gval));
353 bval = (l_int32)(bval + fract * (255 - 2 * bval));
354 composeRGBPixel(rval, gval, bval, &pixval);
355 pixSetPixel(pixd, x + j, y + i, pixval);
358 L_WARNING(
"d neither 8 nor 32 bpp; no blend\n",
370 for (i = 0; i < hc; i++) {
371 if (i + y < 0 || i + y >= h)
continue;
372 linec = datac + i * wplc;
373 for (j = 0; j < wc; j++) {
374 if (j + x < 0 || j + x >= w)
continue;
380 pixGetPixel(pixd, x + j, y + i, &pixval);
381 val = (l_int32)(pixval + fract * (255 - pixval));
382 pixSetPixel(pixd, x + j, y + i, val);
385 pixGetPixel(pixd, x + j, y + i, &pixval);
386 extractRGBValues(pixval, &rval, &gval, &bval);
387 rval = (l_int32)(rval + fract * (255 - rval));
388 gval = (l_int32)(gval + fract * (255 - gval));
389 bval = (l_int32)(bval + fract * (255 - bval));
390 composeRGBPixel(rval, gval, bval, &pixval);
391 pixSetPixel(pixd, x + j, y + i, pixval);
394 L_WARNING(
"d neither 8 nor 32 bpp; no blend\n",
406 for (i = 0; i < hc; i++) {
407 if (i + y < 0 || i + y >= h)
continue;
408 linec = datac + i * wplc;
409 for (j = 0; j < wc; j++) {
410 if (j + x < 0 || j + x >= w)
continue;
416 pixGetPixel(pixd, x + j, y + i, &pixval);
417 val = (l_int32)((1. - fract) * pixval);
418 pixSetPixel(pixd, x + j, y + i, val);
421 pixGetPixel(pixd, x + j, y + i, &pixval);
422 extractRGBValues(pixval, &rval, &gval, &bval);
423 rval = (l_int32)((1. - fract) * rval);
424 gval = (l_int32)((1. - fract) * gval);
425 bval = (l_int32)((1. - fract) * bval);
426 composeRGBPixel(rval, gval, bval, &pixval);
427 pixSetPixel(pixd, x + j, y + i, pixval);
430 L_WARNING(
"d neither 8 nor 32 bpp; no blend\n",
438 L_WARNING(
"invalid binary mask blend type\n", __func__);
500l_int32 i, j, d, wc, hc, w, h, wplc, wpld, delta;
501l_int32 ival, irval, igval, ibval, cval, dval;
503l_uint32 *linec, *lined, *datac, *datad;
504PIX *pixc, *pix1, *pix2;
507 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, pixd);
509 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, pixd);
510 if (pixGetDepth(pixs1) == 1)
511 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, pixd);
512 if (pixd == pixs1 && pixGetColormap(pixs1))
513 return (
PIX *)ERROR_PTR(
"can't do in-place with cmap", __func__, pixd);
514 if (pixd && (pixd != pixs1))
515 return (
PIX *)ERROR_PTR(
"pixd must be NULL or pixs1", __func__, pixd);
516 if (fract < 0.0 || fract > 1.0) {
517 L_WARNING(
"fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
521 L_WARNING(
"invalid blend type; setting to L_BLEND_GRAY\n", __func__);
532 if (pixGetDepth(pix1) < 8)
533 pix2 = pixConvertTo8(pix1, FALSE);
535 pix2 = pixClone(pix1);
536 pixd = pixCopy(NULL, pix2);
541 pixGetDimensions(pixd, &w, &h, &d);
542 wpld = pixGetWpl(pixd);
543 datad = pixGetData(pixd);
544 pixc = pixConvertTo8(pixs2, 0);
545 pixGetDimensions(pixc, &wc, &hc, NULL);
546 datac = pixGetData(pixc);
547 wplc = pixGetWpl(pixc);
556 for (i = 0; i < hc; i++) {
557 if (i + y < 0 || i + y >= h)
continue;
558 linec = datac + i * wplc;
559 lined = datad + (i + y) * wpld;
563 for (j = 0; j < wc; j++) {
564 if (j + x < 0 || j + x >= w)
continue;
566 if (transparent == 0 || cval != transpix) {
568 ival = (l_int32)((1. - fract) * dval + fract * cval);
574 for (j = 0; j < wc; j++) {
575 if (j + x < 0 || j + x >= w)
continue;
577 if (transparent == 0 || cval != transpix) {
578 val32 = *(lined + j + x);
579 extractRGBValues(val32, &irval, &igval, &ibval);
580 irval = (l_int32)((1. - fract) * irval + fract * cval);
581 igval = (l_int32)((1. - fract) * igval + fract * cval);
582 ibval = (l_int32)((1. - fract) * ibval + fract * cval);
583 composeRGBPixel(irval, igval, ibval, &val32);
584 *(lined + j + x) = val32;
593 for (i = 0; i < hc; i++) {
594 if (i + y < 0 || i + y >= h)
continue;
595 linec = datac + i * wplc;
596 lined = datad + (i + y) * wpld;
610 for (j = 0; j < wc; j++) {
611 if (j + x < 0 || j + x >= w)
continue;
613 if (transparent == 0 || cval != transpix) {
615 delta = (128 - ival) * (255 - cval) / 256;
616 ival += (l_int32)(fract * delta + 0.5);
623 for (j = 0; j < wc; j++) {
624 if (j + x < 0 || j + x >= w)
continue;
626 if (transparent == 0 || cval != transpix) {
627 val32 = *(lined + j + x);
628 extractRGBValues(val32, &irval, &igval, &ibval);
629 delta = (128 - irval) * (255 - cval) / 256;
630 irval += (l_int32)(fract * delta + 0.5);
631 delta = (128 - igval) * (255 - cval) / 256;
632 igval += (l_int32)(fract * delta + 0.5);
633 delta = (128 - ibval) * (255 - cval) / 256;
634 ibval += (l_int32)(fract * delta + 0.5);
635 composeRGBPixel(irval, igval, ibval, &val32);
636 *(lined + j + x) = val32;
695l_int32 i, j, d, wc, hc, w, h, wplc, wpld;
696l_int32 irval, igval, ibval, cval, dval;
699l_uint32 *linec, *lined, *datac, *datad;
700PIX *pixc, *pix1, *pix2;
703 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, pixd);
705 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, pixd);
706 if (pixGetDepth(pixs1) == 1)
707 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, pixd);
708 if (pixd == pixs1 && pixGetColormap(pixs1))
709 return (
PIX *)ERROR_PTR(
"can't do in-place with cmap", __func__, pixd);
710 if (pixd && (pixd != pixs1))
711 return (
PIX *)ERROR_PTR(
"pixd must be NULL or pixs1", __func__, pixd);
712 if (fract < 0.0 || fract > 1.0) {
713 L_WARNING(
"fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
724 if (pixGetDepth(pix1) < 8)
725 pix2 = pixConvertTo8(pix1, FALSE);
727 pix2 = pixClone(pix1);
728 pixd = pixCopy(NULL, pix2);
733 pixGetDimensions(pixd, &w, &h, &d);
734 wpld = pixGetWpl(pixd);
735 datad = pixGetData(pixd);
736 pixc = pixConvertTo8(pixs2, 0);
737 pixGetDimensions(pixc, &wc, &hc, NULL);
738 datac = pixGetData(pixc);
739 wplc = pixGetWpl(pixc);
742 for (i = 0; i < hc; i++) {
743 if (i + y < 0 || i + y >= h)
continue;
744 linec = datac + i * wplc;
745 lined = datad + (i + y) * wpld;
749 for (j = 0; j < wc; j++) {
750 if (j + x < 0 || j + x >= w)
continue;
753 a = (1.0 - fract) * dval + fract * (255.0 - dval);
754 dval = (l_int32)(cval * dval / 255.0 +
755 a * (255.0 - cval) / 255.0);
760 for (j = 0; j < wc; j++) {
761 if (j + x < 0 || j + x >= w)
continue;
763 val32 = *(lined + j + x);
764 extractRGBValues(val32, &irval, &igval, &ibval);
765 a = (1.0 - fract) * irval + fract * (255.0 - irval);
766 irval = (l_int32)(cval * irval / 255.0 +
767 a * (255.0 - cval) / 255.0);
768 a = (1.0 - fract) * igval + fract * (255.0 - igval);
769 igval = (l_int32)(cval * igval / 255.0 +
770 a * (255.0 - cval) / 255.0);
771 a = (1.0 - fract) * ibval + fract * (255.0 - ibval);
772 ibval = (l_int32)(cval * ibval / 255.0 +
773 a * (255.0 - cval) / 255.0);
774 composeRGBPixel(irval, igval, ibval, &val32);
775 *(lined + j + x) = val32;
829l_int32 i, j, wc, hc, w, h, wplc, wpld;
830l_int32 rval, gval, bval, rcval, gcval, bcval;
831l_uint32 cval32, val32;
832l_uint32 *linec, *lined, *datac, *datad;
836 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, NULL);
838 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, NULL);
839 if (pixGetDepth(pixs1) == 1)
840 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, NULL);
841 if (pixd == pixs1 && pixGetDepth(pixs1) != 32)
842 return (
PIX *)ERROR_PTR(
"inplace; pixs1 not 32 bpp", __func__, NULL);
843 if (pixd && (pixd != pixs1))
844 return (
PIX *)ERROR_PTR(
"pixd must be NULL or pixs1", __func__, NULL);
845 if (fract < 0.0 || fract > 1.0) {
846 L_WARNING(
"fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
856 pixd = pixConvertTo32(pixs1);
857 pixGetDimensions(pixd, &w, &h, NULL);
858 wpld = pixGetWpl(pixd);
859 datad = pixGetData(pixd);
860 pixc = pixConvertTo32(pixs2);
861 pixGetDimensions(pixc, &wc, &hc, NULL);
862 datac = pixGetData(pixc);
863 wplc = pixGetWpl(pixc);
866 for (i = 0; i < hc; i++) {
873 if (i + y < 0 || i + y >= h)
continue;
874 linec = datac + i * wplc;
875 lined = datad + (i + y) * wpld;
876 for (j = 0; j < wc; j++) {
877 if (j + x < 0 || j + x >= w)
continue;
878 cval32 = *(linec + j);
879 if (transparent == 0 ||
880 ((cval32 & 0xffffff00) != (transpix & 0xffffff00))) {
881 val32 = *(lined + j + x);
882 extractRGBValues(cval32, &rcval, &gcval, &bcval);
883 extractRGBValues(val32, &rval, &gval, &bval);
884 rval = (l_int32)((1. - fract) * rval + fract * rcval);
885 gval = (l_int32)((1. - fract) * gval + fract * gcval);
886 bval = (l_int32)((1. - fract) * bval + fract * bcval);
887 composeRGBPixel(rval, gval, bval, &val32);
888 *(lined + j + x) = val32;
936pixBlendColorByChannel(
PIX *pixd,
947l_int32 i, j, wc, hc, w, h, wplc, wpld;
948l_int32 rval, gval, bval, rcval, gcval, bcval;
949l_uint32 cval32, val32;
950l_uint32 *linec, *lined, *datac, *datad;
954 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, pixd);
956 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, pixd);
957 if (pixGetDepth(pixs1) == 1)
958 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, pixd);
959 if (pixd == pixs1 && pixGetDepth(pixs1) != 32)
960 return (
PIX *)ERROR_PTR(
"inplace; pixs1 not 32 bpp", __func__, pixd);
961 if (pixd && (pixd != pixs1))
962 return (
PIX *)ERROR_PTR(
"pixd must be NULL or pixs1", __func__, pixd);
970 pixd = pixConvertTo32(pixs1);
971 pixGetDimensions(pixd, &w, &h, NULL);
972 wpld = pixGetWpl(pixd);
973 datad = pixGetData(pixd);
974 pixc = pixConvertTo32(pixs2);
975 pixGetDimensions(pixc, &wc, &hc, NULL);
976 datac = pixGetData(pixc);
977 wplc = pixGetWpl(pixc);
980 for (i = 0; i < hc; i++) {
981 if (i + y < 0 || i + y >= h)
continue;
982 linec = datac + i * wplc;
983 lined = datad + (i + y) * wpld;
984 for (j = 0; j < wc; j++) {
985 if (j + x < 0 || j + x >= w)
continue;
986 cval32 = *(linec + j);
987 if (transparent == 0 ||
988 ((cval32 & 0xffffff00) != (transpix & 0xffffff00))) {
989 val32 = *(lined + j + x);
990 extractRGBValues(cval32, &rcval, &gcval, &bcval);
991 extractRGBValues(val32, &rval, &gval, &bval);
992 rval = blendComponents(rval, rcval, rfract);
993 gval = blendComponents(gval, gcval, gfract);
994 bval = blendComponents(bval, bcval, bfract);
995 composeRGBPixel(rval, gval, bval, &val32);
996 *(lined + j + x) = val32;
1007blendComponents(l_int32 a,
1012 return ((a < b) ? a : b);
1014 return ((a > b) ? a : b);
1015 return (l_int32)((1. - fract) * a + fract * b);
1072l_int32 i, j, d, wc, hc, w, h, wplc, wpld, delta, overlap;
1073l_int32 rval, gval, bval, cval, dval, mval, median, pivot;
1075l_uint32 *linec, *lined, *datac, *datad;
1076l_float32 fmedian, factor;
1078PIX *pixc, *pix1, *pix2;
1081 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, pixd);
1083 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, pixd);
1084 if (pixGetDepth(pixs1) == 1)
1085 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, pixd);
1086 if (pixd == pixs1 && pixGetColormap(pixs1))
1087 return (
PIX *)ERROR_PTR(
"can't do in-place with cmap", __func__, pixd);
1088 if (pixd && (pixd != pixs1))
1089 return (
PIX *)ERROR_PTR(
"pixd must be NULL or pixs1", __func__, pixd);
1090 if (fract < 0.0 || fract > 1.0) {
1091 L_WARNING(
"fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
1094 if (shift == -1) shift = 64;
1095 if (shift < 0 || shift > 127) {
1096 L_WARNING(
"invalid shift; setting to 64\n", __func__);
1101 pixGetDimensions(pixs1, &w, &h, NULL);
1102 pixGetDimensions(pixs2, &wc, &hc, NULL);
1103 box = boxCreate(x, y, wc, hc);
1104 boxt = boxCreate(0, 0, w, h);
1105 boxIntersects(box, boxt, &overlap);
1109 return (
PIX *)ERROR_PTR(
"no image overlap", __func__, pixd);
1119 if (pixGetDepth(pix1) < 8)
1120 pix2 = pixConvertTo8(pix1, FALSE);
1122 pix2 = pixClone(pix1);
1123 pixd = pixCopy(NULL, pix2);
1129 pix1 = pixClipRectangle(pixd, box, NULL);
1130 pix2 = pixConvertTo8(pix1, 0);
1131 pixGetRankValueMasked(pix2, NULL, 0, 0, 1, 0.5, &fmedian, NULL);
1132 median = (l_int32)(fmedian + 0.5);
1134 pivot = median + shift;
1136 pivot = median - shift;
1142 d = pixGetDepth(pixd);
1143 wpld = pixGetWpl(pixd);
1144 datad = pixGetData(pixd);
1145 pixc = pixConvertTo8(pixs2, 0);
1146 datac = pixGetData(pixc);
1147 wplc = pixGetWpl(pixc);
1148 for (i = 0; i < hc; i++) {
1149 if (i + y < 0 || i + y >= h)
continue;
1150 linec = datac + i * wplc;
1151 lined = datad + (i + y) * wpld;
1166 for (j = 0; j < wc; j++) {
1167 if (j + x < 0 || j + x >= w)
continue;
1170 delta = (pivot - dval) * (255 - cval) / 256;
1171 dval += (l_int32)(fract * delta + 0.5);
1189 for (j = 0; j < wc; j++) {
1190 if (j + x < 0 || j + x >= w)
continue;
1192 val32 = *(lined + j + x);
1193 extractRGBValues(val32, &rval, &gval, &bval);
1194 mval = L_MAX(rval, gval);
1195 mval = L_MAX(mval, bval);
1196 mval = L_MAX(mval, 1);
1197 delta = (pivot - mval) * (255 - cval) / 256;
1198 factor = fract * delta / mval;
1199 rval += (l_int32)(factor * rval + 0.5);
1200 gval += (l_int32)(factor * gval + 0.5);
1201 bval += (l_int32)(factor * bval + 0.5);
1202 composeRGBPixel(rval, gval, bval, &val32);
1203 *(lined + j + x) = val32;
1241l_int32 i, j, w, h, d, wb, hb, db, wd, hd, wplb, wpld;
1242l_int32 valb, vald, nvald, rval, gval, bval, nrval, ngval, nbval;
1243l_float32 nfactor, fract;
1244l_uint32 val32, nval32;
1245l_uint32 *lined, *datad, *lineb, *datab;
1249 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1251 return (
PIX *)ERROR_PTR(
"pixb not defined", __func__, NULL);
1252 if (pixGetDepth(pixs) == 1)
1253 return (
PIX *)ERROR_PTR(
"pixs is 1 bpp", __func__, NULL);
1254 pixGetDimensions(pixb, &wb, &hb, &db);
1256 return (
PIX *)ERROR_PTR(
"pixb not 8 bpp", __func__, NULL);
1257 if (factor < 0.0 || factor > 255.0)
1258 return (
PIX *)ERROR_PTR(
"factor not in [0.0...255.0]", __func__, NULL);
1260 return (
PIX *)ERROR_PTR(
"invalid fade type", __func__, NULL);
1264 pixGetDimensions(pixd, &wd, &hd, &d);
1267 datad = pixGetData(pixd);
1268 wpld = pixGetWpl(pixd);
1269 datab = pixGetData(pixb);
1270 wplb = pixGetWpl(pixb);
1277 nfactor = factor / 255.;
1278 for (i = 0; i < h; i++) {
1279 lineb = datab + i * wplb;
1280 lined = datad + i * wpld;
1281 for (j = 0; j < w; j++) {
1283 fract = nfactor * (l_float32)valb;
1284 fract = L_MIN(fract, 1.0);
1288 nvald = vald + (l_int32)(fract * (255. - (l_float32)vald));
1290 nvald = vald - (l_int32)(fract * (l_float32)vald);
1294 extractRGBValues(val32, &rval, &gval, &bval);
1296 nrval = rval + (l_int32)(fract * (255. - (l_float32)rval));
1297 ngval = gval + (l_int32)(fract * (255. - (l_float32)gval));
1298 nbval = bval + (l_int32)(fract * (255. - (l_float32)bval));
1300 nrval = rval - (l_int32)(fract * (l_float32)rval);
1301 ngval = gval - (l_int32)(fract * (l_float32)gval);
1302 nbval = bval - (l_int32)(fract * (l_float32)bval);
1304 composeRGBPixel(nrval, ngval, nbval, &nval32);
1350pixBlendHardLight(
PIX *pixd,
1357l_int32 i, j, w, h, d, wc, hc, dc, wplc, wpld;
1358l_int32 cval, dval, rcval, gcval, bcval, rdval, gdval, bdval;
1359l_uint32 cval32, dval32;
1360l_uint32 *linec, *lined, *datac, *datad;
1364 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, pixd);
1366 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, pixd);
1367 pixGetDimensions(pixs1, &w, &h, &d);
1368 pixGetDimensions(pixs2, &wc, &hc, &dc);
1370 return (
PIX *)ERROR_PTR(
"pixs1 is 1 bpp", __func__, pixd);
1371 if (dc != 8 && dc != 32)
1372 return (
PIX *)ERROR_PTR(
"pixs2 not 8 or 32 bpp", __func__, pixd);
1373 if (pixd && (pixd != pixs1))
1374 return (
PIX *)ERROR_PTR(
"inplace and pixd != pixs1", __func__, pixd);
1375 if (pixd == pixs1 && pixGetColormap(pixs1))
1376 return (
PIX *)ERROR_PTR(
"inplace and pixs1 cmapped", __func__, pixd);
1377 if (pixd && d != 8 && d != 32)
1378 return (
PIX *)ERROR_PTR(
"inplace and not 8 or 32 bpp", __func__, pixd);
1380 if (fract < 0.0 || fract > 1.0) {
1381 L_WARNING(
"fract must be in [0.0, 1.0]; setting to 0.5\n", __func__);
1387 dc = pixGetDepth(pixc);
1395 if (pixGetColormap(pixs1)) {
1399 pixd = pixConvertTo32(pixs1);
1401 pixt = pixConvertTo32(pixs1);
1402 pixCopy(pixd, pixt);
1408 if (pixGetColormap(pixs1))
1411 pixd = pixCopy(pixd, pixs1);
1412 d = pixGetDepth(pixd);
1415 if (!(d == 8 && dc == 8) &&
1416 !(d == 32 && dc == 8) &&
1417 !(d == 32 && dc == 32)) {
1419 return (
PIX *)ERROR_PTR(
"bad! -- invalid depth combo!", __func__, pixd);
1422 wpld = pixGetWpl(pixd);
1423 datad = pixGetData(pixd);
1424 datac = pixGetData(pixc);
1425 wplc = pixGetWpl(pixc);
1426 for (i = 0; i < hc; i++) {
1427 if (i + y < 0 || i + y >= h)
continue;
1428 linec = datac + i * wplc;
1429 lined = datad + (i + y) * wpld;
1430 for (j = 0; j < wc; j++) {
1431 if (j + x < 0 || j + x >= w)
continue;
1432 if (d == 8 && dc == 8) {
1435 dval = blendHardLightComponents(dval, cval, fract);
1437 }
else if (d == 32 && dc == 8) {
1438 dval32 = *(lined + x + j);
1439 extractRGBValues(dval32, &rdval, &gdval, &bdval);
1441 rdval = blendHardLightComponents(rdval, cval, fract);
1442 gdval = blendHardLightComponents(gdval, cval, fract);
1443 bdval = blendHardLightComponents(bdval, cval, fract);
1444 composeRGBPixel(rdval, gdval, bdval, &dval32);
1445 *(lined + x + j) = dval32;
1446 }
else if (d == 32 && dc == 32) {
1447 dval32 = *(lined + x + j);
1448 extractRGBValues(dval32, &rdval, &gdval, &bdval);
1449 cval32 = *(linec + j);
1450 extractRGBValues(cval32, &rcval, &gcval, &bcval);
1451 rdval = blendHardLightComponents(rdval, rcval, fract);
1452 gdval = blendHardLightComponents(gdval, gcval, fract);
1453 bdval = blendHardLightComponents(bdval, bcval, fract);
1454 composeRGBPixel(rdval, gdval, bdval, &dval32);
1455 *(lined + x + j) = dval32;
1512static l_int32 blendHardLightComponents(l_int32 a,
1517 b = 0x80 - (l_int32)(fract * (0x80 - b));
1518 return (a * b) >> 7;
1520 b = 0x80 + (l_int32)(fract * (b - 0x80));
1521 return 0xff - (((0xff - b) * (0xff - a)) >> 7);
1563l_int32 rval, gval, bval;
1564l_int32 i, j, w, h, d, ncb, wb, hb, wpls;
1565l_int32 index, val, nadded;
1568l_uint32 *lines, *datas;
1569PIXCMAP *cmaps, *cmapb, *cmapsc;
1572 return ERROR_INT(
"pixs not defined", __func__, 1);
1574 return ERROR_INT(
"pixb not defined", __func__, 1);
1575 if ((cmaps = pixGetColormap(pixs)) == NULL)
1576 return ERROR_INT(
"no colormap in pixs", __func__, 1);
1577 if ((cmapb = pixGetColormap(pixb)) == NULL)
1578 return ERROR_INT(
"no colormap in pixb", __func__, 1);
1579 ncb = pixcmapGetCount(cmapb);
1581 pixGetDimensions(pixs, &w, &h, &d);
1582 if (d != 2 && d != 4 && d != 8)
1583 return ERROR_INT(
"depth not in {2,4,8}", __func__, 1);
1588 cmapsc = pixcmapCopy(cmaps);
1592 for (i = 0, nadded = 0; i < ncb; i++) {
1593 pixcmapGetColor(cmapb, i, &rval, &gval, &bval);
1594 if (pixcmapGetIndex(cmapsc, rval, gval, bval, &index)) {
1595 if (pixcmapAddColor(cmapsc, rval, gval, bval)) {
1596 pixcmapDestroy(&cmapsc);
1597 return ERROR_INT(
"not enough room in cmaps", __func__, 1);
1599 lut[i] = pixcmapGetCount(cmapsc) - 1;
1608 pixcmapDestroy(&cmapsc);
1610 pixSetColormap(pixs, cmapsc);
1614 datas = pixGetData(pixs);
1615 wpls = pixGetWpl(pixs);
1616 pixGetDimensions(pixb, &wb, &hb, NULL);
1617 for (i = 0; i < hb; i++) {
1618 if (i + y < 0 || i + y >= h)
continue;
1619 lines = datas + (y + i) * wpls;
1620 for (j = 0; j < wb; j++) {
1621 if (j + x < 0 || j + x >= w)
continue;
1625 if (val == sindex) {
1626 pixGetPixel(pixb, j, i, &pval);
1632 if (val == sindex) {
1633 pixGetPixel(pixb, j, i, &pval);
1639 if (val == sindex) {
1640 pixGetPixel(pixb, j, i, &pval);
1645 return ERROR_INT(
"depth not in {2,4,8}", __func__, 1);
1698l_int32 w1, h1, d1, w2, h2, d2, spp, wg, hg, wmin, hmin, wpld, wpls, wplg;
1699l_int32 i, j, val, dval, sval;
1700l_int32 drval, dgval, dbval, srval, sgval, sbval;
1701l_uint32 dval32, sval32;
1702l_uint32 *datad, *datas, *datag, *lined, *lines, *lineg;
1704PIX *pixr1, *pixr2, *pix1, *pix2, *pixg2, *pixd;
1707 return (
PIX *)ERROR_PTR(
"pixs1 not defined", __func__, NULL);
1709 return (
PIX *)ERROR_PTR(
"pixs2 not defined", __func__, NULL);
1710 pixGetDimensions(pixs1, &w1, &h1, &d1);
1711 pixGetDimensions(pixs2, &w2, &h2, &d2);
1712 if (d1 == 1 || d2 == 1)
1713 return (
PIX *)ERROR_PTR(
"pixs1 or pixs2 is 1 bpp", __func__, NULL);
1715 if (pixGetDepth(pixg) != 8)
1716 return (
PIX *)ERROR_PTR(
"pixg not 8 bpp", __func__, NULL);
1717 pixGetDimensions(pixg, &wg, &hg, NULL);
1718 wmin = L_MIN(w2, wg);
1719 hmin = L_MIN(h2, hg);
1720 pixg2 = pixClone(pixg);
1722 spp = pixGetSpp(pixs2);
1723 if (d2 != 32 || spp != 4)
1724 return (
PIX *)ERROR_PTR(
"no alpha; pixs2 not rgba", __func__, NULL);
1735 d1 = pixGetDepth(pixr1);
1736 d2 = pixGetDepth(pixr2);
1738 pix1 = pixClone(pixr1);
1740 pix2 = pixConvertTo32(pixr2);
1742 pix2 = pixClone(pixr2);
1743 }
else if (d2 == 32) {
1744 pix2 = pixClone(pixr2);
1745 pix1 = pixConvertTo32(pixr1);
1747 pix1 = pixConvertTo8(pixr1, FALSE);
1748 pix2 = pixConvertTo8(pixr2, FALSE);
1754 pixd = pixCopy(NULL, pix1);
1758 d1 = pixGetDepth(pixd);
1759 d2 = pixGetDepth(pix2);
1760 if (!pixd || d1 != d2 || (d1 != 8 && d1 != 32)) {
1764 return (
PIX *)ERROR_PTR(
"depths not regularized! bad!", __func__, NULL);
1774 datad = pixGetData(pixd);
1775 datas = pixGetData(pix2);
1776 datag = pixGetData(pixg2);
1777 wpld = pixGetWpl(pixd);
1778 wpls = pixGetWpl(pix2);
1779 wplg = pixGetWpl(pixg2);
1780 for (i = 0; i < hmin; i++) {
1781 if (i + y < 0 || i + y >= h1)
continue;
1782 lined = datad + (i + y) * wpld;
1783 lines = datas + i * wpls;
1784 lineg = datag + i * wplg;
1785 for (j = 0; j < wmin; j++) {
1786 if (j + x < 0 || j + x >= w1)
continue;
1788 if (val == 0)
continue;
1789 fract = (l_float32)val / 255.;
1793 dval = (l_int32)((1.0 - fract) * dval + fract * sval);
1796 dval32 = *(lined + j + x);
1797 sval32 = *(lines + j);
1798 extractRGBValues(dval32, &drval, &dgval, &dbval);
1799 extractRGBValues(sval32, &srval, &sgval, &sbval);
1800 drval = (l_int32)((1.0 - fract) * drval + fract * srval);
1801 dgval = (l_int32)((1.0 - fract) * dgval + fract * sgval);
1802 dbval = (l_int32)((1.0 - fract) * dbval + fract * sbval);
1803 composeRGBPixel(drval, dgval, dbval, &dval32);
1804 *(lined + j + x) = dval32;
1854PIX *pixt, *pixc, *pixr, *pixg;
1857 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, pixd);
1858 if (pixGetDepth(pixs) != 32)
1859 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", __func__, pixd);
1860 if (pixd && (pixd != pixs))
1861 return (
PIX *)ERROR_PTR(
"pixd neither null nor pixs", __func__, pixd);
1866 pixd = pixCopy(NULL, pixs);
1868 pixr = pixClipRectangle(pixd, box, &boxt);
1869 boxGetGeometry(boxt, &x, &y, &w, &h);
1870 pixc = pixCreate(w, h, 32);
1873 pixc = pixCreateTemplate(pixs);
1874 pixr = pixClone(pixd);
1876 pixSetAllArbitrary(pixc, color);
1879 pixg = pixConvertTo8(pixr, 0);
1880 pixGammaTRC(pixg, pixg, gamma, minval, maxval);
1886 pixRasterop(pixd, x, y, w, h,
PIX_SRC, pixt, 0, 0);
1889 pixTransferAllData(pixd, &pixt, 0, 0);
1927l_int32 i, j, bx, by, w, h, wpl;
1928l_int32 red, green, blue, rval, gval, bval, nrval, ngval, nbval;
1929l_float32 frval, fgval, fbval;
1930l_uint32 *data, *line;
1934 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, pixd);
1935 if (pixGetDepth(pixs) != 32)
1936 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", __func__, pixd);
1937 if (pixd && (pixd != pixs))
1938 return (
PIX *)ERROR_PTR(
"pixd neither null nor pixs", __func__, pixd);
1941 pixd = pixCopy(NULL, pixs);
1943 boxGetGeometry(box, &bx, &by, NULL, NULL);
1944 pixt = pixClipRectangle(pixd, box, NULL);
1946 pixt = pixClone(pixd);
1950 extractRGBValues(color, &red, &green, &blue);
1951 frval = (1. / 255.) * red;
1952 fgval = (1. / 255.) * green;
1953 fbval = (1. / 255.) * blue;
1954 data = pixGetData(pixt);
1955 wpl = pixGetWpl(pixt);
1956 pixGetDimensions(pixt, &w, &h, NULL);
1957 for (i = 0; i < h; i++) {
1958 line = data + i * wpl;
1959 for (j = 0; j < w; j++) {
1960 extractRGBValues(line[j], &rval, &gval, &bval);
1961 nrval = (l_int32)(frval * rval + 0.5);
1962 ngval = (l_int32)(fgval * gval + 0.5);
1963 nbval = (l_int32)(fbval * bval + 0.5);
1964 composeRGBPixel(nrval, ngval, nbval, line + j);
1970 pixRasterop(pixd, bx, by, w, h,
PIX_SRC, pixt, 0, 0);
2004 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2005 if (pixGetDepth(pixs) != 32)
2006 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", __func__, NULL);
2007 if (pixGetSpp(pixs) != 4) {
2008 L_WARNING(
"no alpha channel; returning clone\n", __func__);
2009 return pixClone(pixs);
2012 pixt = pixCreateTemplate(pixs);
2013 pixSetAllArbitrary(pixt, color);
2053PIX *pixd, *pix1, *pix2;
2056 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2057 if (fract < 0.0 || fract > 1.0)
2058 return (
PIX *)ERROR_PTR(
"invalid fract", __func__, NULL);
2061 if (pixGetColormap(pixs))
2064 pix1 = pixClone(pixs);
2065 pixd = pixConvertTo32(pix1);
2068 if (invert) pixInvert(pixd, pixd);
2071 pix2 = pixConvertTo8(pix1, 0);
2072 pixInvert(pix2, pix2);
2073 pixMultConstantGray(pix2, fract);
2108PIX *pixd, *pix1, *pix2, *pix3, *pix4;
2111 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2112 if (!(pixGetDepth(pixs) == 32 || pixGetColormap(pixs)))
2113 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp or cmapped", __func__, NULL);
2121 pix1 = pixInvert(NULL, pixd);
2122 pix2 = pixConvertRGBToGrayMinMax(pix1, L_CHOOSE_MAX);
2123 pix3 = pixThresholdToBinary(pix2, 1);
2124 pixInvert(pix3, pix3);
2131 pix4 = pixDistanceFunction(pix3, 8, 8, L_BOUNDARY_FG);
2132 pixMultConstantGray(pix4, 128.0);
2169 l_float32 distfract,
2172l_int32 i, j, w, h, d, wpl, xmin, ymin, range, val, rval, gval, bval;
2173l_float32 slope, limit, del;
2174l_uint32 *data, *line;
2177 return ERROR_INT(
"pixs not defined", __func__, 1);
2178 if (pixGetColormap(pixs) != NULL)
2179 return ERROR_INT(
"pixs has a colormap", __func__, 1);
2180 pixGetDimensions(pixs, &w, &h, &d);
2181 if (d != 8 && d != 32)
2182 return ERROR_INT(
"pixs not 8 or 32 bpp", __func__, 1);
2185 return ERROR_INT(
"invalid fade direction from edge", __func__, 1);
2187 return ERROR_INT(
"invalid fadeto photometry", __func__, 1);
2188 if (maxfade <= 0)
return 0;
2190 return ERROR_INT(
"invalid maxfade", __func__, 1);
2191 if (distfract <= 0 || distfract * L_MIN(w, h) < 1.0) {
2192 L_INFO(
"distfract is too small\n", __func__);
2195 if (distfract > 1.0)
2196 return ERROR_INT(
"invalid distfract", __func__, 1);
2200 range = (l_int32)(distfract * w);
2202 slope = maxfade / (l_float32)range;
2204 range = (l_int32)(distfract * w);
2206 slope = maxfade / (l_float32)range;
2208 range = (l_int32)(distfract * h);
2210 slope = maxfade / (l_float32)range;
2212 range = (l_int32)(distfract * h);
2214 slope = maxfade / (l_float32)range;
2218 data = pixGetData(pixs);
2219 wpl = pixGetWpl(pixs);
2221 for (j = 0; j < range; j++) {
2223 : maxfade - slope * (range - j);
2224 for (i = 0; i < h; i++) {
2225 line = data + i * wpl;
2228 val += (limit - val) * del + 0.5;
2231 extractRGBValues(*(line + xmin + j), &rval, &gval, &bval);
2232 rval += (limit - rval) * del + 0.5;
2233 gval += (limit - gval) * del + 0.5;
2234 bval += (limit - bval) * del + 0.5;
2235 composeRGBPixel(rval, gval, bval, line + xmin + j);
2240 for (i = 0; i < range; i++) {
2241 del = (dir ==
L_FROM_TOP) ? maxfade - slope * i
2242 : maxfade - slope * (range - i);
2243 line = data + (ymin + i) * wpl;
2244 for (j = 0; j < w; j++) {
2247 val += (limit - val) * del + 0.5;
2250 extractRGBValues(*(line + j), &rval, &gval, &bval);
2251 rval += (limit - rval) * del + 0.5;
2252 gval += (limit - gval) * del + 0.5;
2253 bval += (limit - bval) * del + 0.5;
2254 composeRGBPixel(rval, gval, bval, line + j);
#define GET_DATA_QBIT(pdata, n)
#define SET_DATA_DIBIT(pdata, n, val)
#define GET_DATA_BYTE(pdata, n)
#define GET_DATA_DIBIT(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
#define GET_DATA_BIT(pdata, n)
#define SET_DATA_QBIT(pdata, n, val)
PIX * pixBlend(PIX *pixs1, PIX *pixs2, l_int32 x, l_int32 y, l_float32 fract)
pixBlend()
PIX * pixBlendWithGrayMask(PIX *pixs1, PIX *pixs2, PIX *pixg, l_int32 x, l_int32 y)
pixBlendWithGrayMask()
PIX * pixMultiplyByColor(PIX *pixd, PIX *pixs, BOX *box, l_uint32 color)
pixMultiplyByColor()
PIX * pixAddAlphaToBlend(PIX *pixs, l_float32 fract, l_int32 invert)
pixAddAlphaToBlend()
PIX * pixBlendGrayAdapt(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 x, l_int32 y, l_float32 fract, l_int32 shift)
pixBlendGrayAdapt()
PIX * pixAlphaBlendUniform(PIX *pixs, l_uint32 color)
pixAlphaBlendUniform()
PIX * pixBlendColor(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 x, l_int32 y, l_float32 fract, l_int32 transparent, l_uint32 transpix)
pixBlendColor()
PIX * pixSetAlphaOverWhite(PIX *pixs)
pixSetAlphaOverWhite()
PIX * pixBlendGray(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 x, l_int32 y, l_float32 fract, l_int32 type, l_int32 transparent, l_uint32 transpix)
pixBlendGray()
l_ok pixLinearEdgeFade(PIX *pixs, l_int32 dir, l_int32 fadeto, l_float32 distfract, l_float32 maxfade)
pixLinearEdgeFade()
PIX * pixBlendBackgroundToColor(PIX *pixd, PIX *pixs, BOX *box, l_uint32 color, l_float32 gamma, l_int32 minval, l_int32 maxval)
pixBlendBackgroundToColor()
PIX * pixBlendGrayInverse(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 x, l_int32 y, l_float32 fract)
pixBlendGrayInverse()
PIX * pixBlendMask(PIX *pixd, PIX *pixs1, PIX *pixs2, l_int32 x, l_int32 y, l_float32 fract, l_int32 type)
pixBlendMask()
l_ok pixBlendCmap(PIX *pixs, PIX *pixb, l_int32 x, l_int32 y, l_int32 sindex)
pixBlendCmap()
PIX * pixFadeWithGray(PIX *pixs, PIX *pixb, l_float32 factor, l_int32 type)
pixFadeWithGray()
@ L_BLEND_GRAY_WITH_INVERSE
@ REMOVE_CMAP_TO_FULL_COLOR
@ REMOVE_CMAP_BASED_ON_SRC