/*! * pixBilinearPtaGray() * * Input: pixs (8 bpp) * ptad (4 pts of final coordinate space) * ptas (4 pts of initial coordinate space) * grayval (0 to bring in BLACK, 255 for WHITE) * Return: pixd, or null on error */ PIX * pixBilinearPtaGray(PIX *pixs, PTA *ptad, PTA *ptas, l_uint8 grayval) { l_float32 *vc; PIX *pixd; PROCNAME("pixBilinearPtaGray"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!ptas) return (PIX *)ERROR_PTR("ptas not defined", procName, NULL); if (!ptad) return (PIX *)ERROR_PTR("ptad not defined", procName, NULL); if (pixGetDepth(pixs) != 8) return (PIX *)ERROR_PTR("pixs must be 8 bpp", procName, NULL); if (ptaGetCount(ptas) != 4) return (PIX *)ERROR_PTR("ptas count not 4", procName, NULL); if (ptaGetCount(ptad) != 4) return (PIX *)ERROR_PTR("ptad count not 4", procName, NULL); /* Get backwards transform from dest to src, and apply it */ getBilinearXformCoeffs(ptad, ptas, &vc); pixd = pixBilinearGray(pixs, vc, grayval); FREE(vc); return pixd; }
/*! * pixBilinearColor() * * Input: pixs (32 bpp) * vc (vector of 8 coefficients for bilinear transformation) * colorval (e.g., 0 to bring in BLACK, 0xffffff00 for WHITE) * Return: pixd, or null on error */ PIX * pixBilinearColor(PIX *pixs, l_float32 *vc, l_uint32 colorval) { l_int32 i, j, w, h, d, wpls, wpld; l_uint32 val; l_uint32 *datas, *datad, *lined; l_float32 x, y; PIX *pix1, *pix2, *pixd; PROCNAME("pixBilinearColor"); if (!pixs) return (PIX *) ERROR_PTR("pixs not defined", procName, NULL); pixGetDimensions(pixs, &w, &h, &d); if (d != 32) return (PIX *) ERROR_PTR("pixs must be 32 bpp", procName, NULL); if (!vc) return (PIX *) ERROR_PTR("vc not defined", procName, NULL); datas = pixGetData(pixs); wpls = pixGetWpl(pixs); pixd = pixCreateTemplate(pixs); pixSetAllArbitrary(pixd, colorval); datad = pixGetData(pixd); wpld = pixGetWpl(pixd); /* Iterate over destination pixels */ for (i = 0; i < h; i++) { lined = datad + i * wpld; for (j = 0; j < w; j++) { /* Compute float src pixel location corresponding to (i,j) */ bilinearXformPt(vc, j, i, &x, &y); linearInterpolatePixelColor(datas, wpls, w, h, x, y, colorval, &val); *(lined + j) = val; } } /* If rgba, transform the pixs alpha channel and insert in pixd */ if (pixGetSpp(pixs) == 4) { pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL); pix2 = pixBilinearGray(pix1, vc, 255); /* bring in opaque */ pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL); pixDestroy(&pix1); pixDestroy(&pix2); } return pixd; }
/*! * pixBilinear() * * Input: pixs (all depths; colormap ok) * vc (vector of 8 coefficients for bilinear transformation) * incolor (L_BRING_IN_WHITE, L_BRING_IN_BLACK) * Return: pixd, or null on error * * Notes: * (1) Brings in either black or white pixels from the boundary * (2) Removes any existing colormap, if necessary, before transforming */ PIX * pixBilinear(PIX *pixs, l_float32 *vc, l_int32 incolor) { l_int32 d; l_uint32 colorval; PIX *pixt1, *pixt2, *pixd; PROCNAME("pixBilinear"); if (!pixs) return (PIX *)ERROR_PTR("pixs not defined", procName, NULL); if (!vc) return (PIX *)ERROR_PTR("vc not defined", procName, NULL); if (pixGetDepth(pixs) == 1) return pixBilinearSampled(pixs, vc, incolor); /* Remove cmap if it exists, and unpack to 8 bpp if necessary */ pixt1 = pixRemoveColormap(pixs, REMOVE_CMAP_BASED_ON_SRC); d = pixGetDepth(pixt1); if (d < 8) pixt2 = pixConvertTo8(pixt1, FALSE); else pixt2 = pixClone(pixt1); d = pixGetDepth(pixt2); /* Compute actual color to bring in from edges */ colorval = 0; if (incolor == L_BRING_IN_WHITE) { if (d == 8) colorval = 255; else /* d == 32 */ colorval = 0xffffff00; } if (d == 8) pixd = pixBilinearGray(pixt2, vc, colorval); else /* d == 32 */ pixd = pixBilinearColor(pixt2, vc, colorval); pixDestroy(&pixt1); pixDestroy(&pixt2); return pixd; }