diff -urN old/xv-3.10a/xvsmooth.c xv-3.10a/xvsmooth.c --- old/xv-3.10a/xvsmooth.c Thu Dec 22 17:34:42 1994 +++ xv-3.10a/xvsmooth.c Sun Aug 17 14:07:58 1997 @@ -65,10 +65,13 @@ returns a dwide*dhigh 24bit image, or NULL on failure (malloc) */ /* rmap,gmap,bmap should be 'desired' colors */ + /* DANGER: This code assumes that a right-shift on signed integers is + performed arithmetically, i.e. the sign bit is copied to the right. */ + byte *pic24, *pp; - int *cxtab, *pxtab; - int y1Off, cyOff; - int ex, ey, cx, cy, px, py, apx, apy, x1, y1; + int *pxtab; + int ex, ey, px, py, x0, x1, y0, y1; + int y0off, y1off; int cA, cB, cC, cD; int pA, pB, pC, pD; int retval, bperpix; @@ -98,69 +101,61 @@ else { /* dwide >= swide && dhigh >= shigh */ - /* cx,cy = original pixel in pic824. px,py = relative position - of pixel ex,ey inside of cx,cy as percentages +-50%, +-50%. - 0,0 = middle of pixel */ - - /* we can save a lot of time by precomputing cxtab[] and pxtab[], both - dwide arrays of ints that contain values for the equations: - cx = (ex * swide) / dwide; - px = ((ex * swide * 100) / dwide) - (cx * 100) - 50; */ - - cxtab = (int *) malloc(dwide * sizeof(int)); - if (!cxtab) { free(pic24); return NULL; } + /* px, py = location on original image, in units of 1/256 pixel + We can save time by precomputing all values of px. */ pxtab = (int *) malloc(dwide * sizeof(int)); - if (!pxtab) { free(pic24); free(cxtab); return NULL; } - - for (ex=0; exshigh-1) y1=shigh-1; } + py = ((ey << 8) + 128) * shigh / dhigh - 128; + y0 = py >> 8; /* Put integer part in y0 */ + y1 = y0 + 1; + py &= 255; /* Keep fractional part in py */ + + if (y0 < 0) y0 = y1 = 0; + if (y1 >= shigh) y0 = y1 = shigh-1; - cyOff = cy * swide * bperpix; /* current line */ - y1Off = y1 * swide * bperpix; /* up or down one line, depending */ + y0off = y0 * swide * bperpix; /* current line */ + y1off = y1 * swide * bperpix; /* one line down */ if ((ey&15) == 0) WaitCursor(); - for (ex=0; ex> 8; /* Put integer part in x0 */ + x1 = x0 + 1; + px &= 255; /* Keep fractional part in px */ - if (px<0) { x1 = cx-1; if (x1<0) x1=0; } - else { x1 = cx+1; if (x1>swide-1) x1=swide-1; } + if (x0 < 0) x0 = x1 = 0; + if (x1 >= swide) x0 = x1 = swide-1; if (is24) { - pptr = pic824 + y1Off + x1*bperpix; /* corner pixel */ + pptr = pic824 + y0off + x0*bperpix; /* upper left pixel */ rA = *pptr++; gA = *pptr++; bA = *pptr++; - pptr = pic824 + y1Off + cx*bperpix; /* up/down center pixel */ + pptr = pic824 + y0off + x1*bperpix; /* upper right pixel */ rB = *pptr++; gB = *pptr++; bB = *pptr++; - pptr = pic824 + cyOff + x1*bperpix; /* left/right center pixel */ + pptr = pic824 + y1off + x0*bperpix; /* lower left pixel */ rC = *pptr++; gC = *pptr++; bC = *pptr++; - pptr = pic824 + cyOff + cx*bperpix; /* center pixel */ + pptr = pic824 + y1off + x1*bperpix; /* lower right pixel */ rD = *pptr++; gD = *pptr++; bD = *pptr++; } else { /* 8-bit picture */ - cA = pic824[y1Off + x1]; /* corner pixel */ - cB = pic824[y1Off + cx]; /* up/down center pixel */ - cC = pic824[cyOff + x1]; /* left/right center pixel */ - cD = pic824[cyOff + cx]; /* center pixel */ + cA = pic824[y0off + x0]; /* upper left pixel */ + cB = pic824[y0off + x1]; /* upper right pixel */ + cC = pic824[y1off + x0]; /* lower left pixel */ + cD = pic824[y1off + x1]; /* lower right pixel */ } /* quick check */ @@ -170,38 +165,30 @@ } else { - /* compute weighting factors */ - apx = abs(px); apy = abs(py); - pA = (apx * apy) / 100; - pB = (apy * (100 - apx)) / 100; - pC = (apx * (100 - apy)) / 100; - pD = 100 - (pA + pB + pC); + pA = (256-px)*(256-py); /* compute weighting factors */ + pB = px * (256-py); /* total weight is exactly 2^16 */ + pC = (256-px) * py; + pD = px * py; if (is24) { - *pp++ = ((int) (pA * rA))/100 + ((int) (pB * rB))/100 + - ((int) (pC * rC))/100 + ((int) (pD * rD))/100; - - *pp++ = ((int) (pA * gA))/100 + ((int) (pB * gB))/100 + - ((int) (pC * gC))/100 + ((int) (pD * gD))/100; - - *pp++ = ((int) (pA * bA))/100 + ((int) (pB * bB))/100 + - ((int) (pC * bC))/100 + ((int) (pD * bD))/100; + *pp++ = (pA * rA + pB * rB + pC * rC + pD * rD) + 32768 >> 16; + *pp++ = (pA * gA + pB * gB + pC * gC + pD * gD) + 32768 >> 16; + *pp++ = (pA * bA + pB * bB + pC * bC + pD * bD) + 32768 >> 16; } else { /* 8-bit pic */ - *pp++ = ((int) (pA * rmap[cA]))/100 + ((int)(pB * rmap[cB]))/100 + - ((int) (pC * rmap[cC]))/100 + ((int)(pD * rmap[cD]))/100; + *pp++ = (pA * rmap[cA] + pB * rmap[cB] + pC * rmap[cC] + + pD * rmap[cD]) + 32768 >> 16; - *pp++ = ((int) (pA * gmap[cA]))/100 + ((int)(pB * gmap[cB]))/100 + - ((int) (pC * gmap[cC]))/100 + ((int)(pD * gmap[cD]))/100; + *pp++ = (pA * gmap[cA] + pB * gmap[cB] + pC * gmap[cC] + + pD * gmap[cD]) + 32768 >> 16; - *pp++ = ((int)(pA * bmap[cA]))/100 + ((int)(pB * bmap[cB]))/100 + - ((int)(pC * bmap[cC]))/100 + ((int)(pD * bmap[cD]))/100; + *pp++ = (pA * bmap[cA] + pB * bmap[cB] + pC * bmap[cC] + + pD * bmap[cD]) + 32768 >> 16; } } } } - free(cxtab); free(pxtab); retval = 0; /* okay */ }