/* scale.c -------------- I think that I have to make an effort in math studies for future enhancement of this module :) see also: halfsize.c doublesz.c */ #include #include #include #include "../tthimage.h" /*::------------------------------------------------------------------::*/ /* * do not use in production !-) */ int Image_scale_simple(Image_Desc *src, Image_Desc *dst, int k) { float coefX, coefY, fx, fy; int xd, yd, xs, ys; int r, g, b; #if DEBUG_LEVEL fprintf(stderr, "scale simple: %p (%dx%d) -> %p (%dx%d) k:%d \n", src, src->width, src->height, dst, dst->width, dst->height, k); #endif if (k) { fprintf(stderr, "in %s, k must be zero, was %d\n", __func__, k); return BAD_PARAMETER; } coefX = (float)dst->width / (float)src->width; coefY = (float)dst->height / (float)src->height; #if DEBUG_LEVEL fprintf(stderr, "coefficients: X %f y %f\n", coefX, coefY); #endif /* * bon, pour les interpolations, il faut que je trouve * un peu de doc... mais ou ? */ for (yd=0; ydheight; yd++) { for (xd=0; xdwidth; xd++) { fx = (float)xd / coefX; fy = (float)yd / coefY; xs = (int)fx; ys = (int)fy; Image_getRGB(src, xs, ys, &r, &g, &b); (dst->Rpix[yd])[xd] = r; (dst->Gpix[yd])[xd] = g; (dst->Bpix[yd])[xd] = b; } } return FUNC_IS_ALPHA; } /*::------------------------------------------------------------------::*/ /* new 2 nov 2009 - ave StEx */ /* I've lost all my mathematical concepts so I'm going to make some approximations\dots this function is PRIVATE, see 'Image_getpix_bilin' for public interface 2022 September : update in progress. */ static int getpix_bilin(Image_Desc *src, double fx, double fy, int *pr, int *pg, int *pb) { double x11, y11, x22, y22; int xx, yy; int r11, g11, b11, r12, g12, b12, r21, g21, b21, r22, g22, b22; double drh, drw; double raa, gaa, baa; double rbb, gbb, bbb; double rcc, gcc, bcc; /* before real ops, set RGB to some know values */ *pr = *pg = *pb = 0; /* build all the nasty values */ x11 = floor(fx); y11 = floor(fy); x22 = ceil(fx); y22 = ceil(fy); drw = fx - x11; drh = fy - y11; xx = (int)x11; yy = (int)y11; #if DEBUG_LEVEL > 2 printf("X %10.3f %10.3f %10.3f %10.3f %4d\n", fx, x11, x22, drw, xx); printf("Y %10.3f %10.3f %10.3f %10.3f %4d\n", fy, y11, y22, drh, yy); #endif if ( ! Image_xy_inside(src, xx, yy) ) return -1; if ( ! Image_xy_inside(src, xx+1, yy+1) ) return -2; r11 = src->Rpix[yy][xx]; g11 = src->Gpix[yy][xx]; b11 = src->Bpix[yy][xx]; r12 = src->Rpix[yy][xx+1]; g12 = src->Gpix[yy][xx+1]; b12 = src->Bpix[yy][xx+1]; r22 = src->Rpix[yy+1][xx+1]; g22 = src->Gpix[yy+1][xx+1]; b22 = src->Bpix[yy+1][xx+1]; r21 = src->Rpix[yy+1][xx]; g21 = src->Gpix[yy+1][xx]; b21 = src->Bpix[yy+1][xx]; /* hum hum... */ raa = (double)r11 * (1.0-drw) + (double)r12 * drw; gaa = (double)g11 * (1.0-drw) + (double)g12 * drw; baa = (double)b11 * (1.0-drw) + (double)b12 * drw; if (raa < 0.0) abort(); if (gaa < 0.0) abort(); if (baa < 0.0) abort(); rbb = (double)r21 * (1.0-drw) + (double)r22 * drw; gbb = (double)g21 * (1.0-drw) + (double)g22 * drw; bbb = (double)b21 * (1.0-drw) + (double)b22 * drw; if (rbb < 0.0) abort(); if (gbb < 0.0) abort(); if (bbb < 0.0) abort(); /* hu ho ? */ rcc = (raa * (1.0-drh)) + (rbb * drh); gcc = (gaa * (1.0-drh)) + (gbb * drh); bcc = (baa * (1.0-drh)) + (bbb * drh); *pr = (int)rcc; *pg = (int)gcc; *pb = (int)bcc; return -105; } /*::------------------------------------------------------------------::*/ int Image_scale_bilinear(Image_Desc *src, Image_Desc *dst, int k) { int xd, yd, xs, ys, r, g, b; double coefX, coefY; double fxd, fyd, fxs, fys; #if DEBUG_LEVEL fprintf(stderr, "scale bilinear: %p (%dx%d) -> %p (%dx%d) k:%d \n", src, src->width, src->height, dst, dst->width, dst->height, k); #endif if (k) { fprintf(stderr, "in %s, k must be zero, was %d\n", __func__, k); return BAD_PARAMETER; } coefX = (double)dst->width / (double)src->width; coefY = (double)dst->height / (double)src->height; #if DEBUG_LEVEL fprintf(stderr, "%s : coefs %lf %lf\n", __func__, coefX, coefY); #endif for (yd=0; ydheight; yd++) { fyd = (double)yd; fys = fyd / coefY; for (xd=0; xdwidth; xd++) { fxd = (double)xd; fxs = fxd / coefX; getpix_bilin(src, fxs, fys, &r, &g, &b); (dst->Rpix[yd])[xd] = r; (dst->Gpix[yd])[xd] = g; (dst->Bpix[yd])[xd] = b; } } return FUNC_IS_BETA; } /*::------------------------------------------------------------------::*/ int Image_getpix_bilin(Image_Desc *src, double fx, double fy, int *pr, int *pg, int *pb) { int foo; foo = getpix_bilin(src, fx, fy, pr, pg, pb); return foo; } /*::------------------------------------------------------------------::*/ /* * for now, method must be 0 ! */ Image_Desc * Image_new_scale( Image_Desc *src, float scaleX, float scaleY, int methode ) { float fx, fy; int nw, nh, foo; Image_Desc *dst; #if DEBUG_LEVEL fprintf(stderr, "%s: image\t%d %d, scale %f %f\n", __func__, src->width, src->height, scaleX, scaleY); #endif if (methode) { fprintf(stderr, "in %s, methode must be zero, was %d\n", __func__, methode); return NULL; } fx = (float)src->width * scaleX; fy = (float)src->height * scaleY; nw = (int)(ceil((double)fx)); nh = (int)(ceil((double)fy)); #if DEBUG_LEVEL fprintf(stderr, "\t%f %f\n", fx, fy); fprintf(stderr, "\tnew dims: %d x %d\n", nw, nh); #endif if ( (dst = Image_alloc(nw, nh, 3)) == NULL ) { fprintf(stderr, "%s: no memory\n", __func__); return NULL; } #if DEBUG_LEVEL fprintf(stderr, "\tnew image @ %p\n", dst); #endif foo = Image_scale_simple(src, dst, 0); if (foo) { fprintf(stderr, "in %s scale_simple -> %d\n", __func__, foo); } return dst; } /*::------------------------------------------------------------------::*/