// // Software Flicker filter code // #define TIMINGINFO 1 #ifdef TIMINGINFO // Wow! It's taking almost 2 seconds to draw each frame on the // Co-Lite system in the dmedia lab. LARGE_INTEGER __freq; int timingready = 0; int __tcnt = 0; char __tstr[256]; LARGE_INTEGER __ss1, __ss2, __ss3, __ss4, __ss5; double __d1, __d2, __d3, __d4, __d5; #endif // Filter input image to output to reduce screen flicker // // Images must have same dimensions and rowbytes, which // is ignored now. void filt(void *in, void *out, int w, int h) { int iy, ix; #ifdef TIMINGINFO if (!timingready) { if (!QueryPerformanceFrequency(&__freq)) { sprintf(__tstr, "No frequency counter\n"); OutputDebugString(__tstr); } if (!QueryPerformanceCounter(&__ss1)) { sprintf (__tstr, "QueryPerformanceCounter\n"); OutputDebugString(__tstr); } timingready = 1; } #endif #ifdef TIMINGINFO QueryPerformanceCounter(&__ss1); #endif if (in == out) return; if (h < 0) h = -h; // 16 bit is RBGA5551, 32 bit is ABGR // If 16 bit, skip the filter for now if (getpixelsize() == 16) { memcpy (out, in, w * h * 2); return; } #ifdef EASYFILT if (getpixelsize() == 32) { memcpy (out, in, w * h * 2); return; } #endif // Each output line(i) is 1/4(i-1)+1/2i+1/4(i+1), // except first and last, which are 3/4i+1/4(i+1) and // 1/4(i-1)+3/4i // #define BPP 4 for (iy = 0; iy < h; iy++) { void *prev, *cur, *next, *dst; unsigned char *srcprev, *srccur, *srcnext, *dstpix; prev = (char *)in + ((iy - 1) * w * BPP); cur = (char *)in + (iy * w * BPP); next = (char *)in + ((iy + 1) * w * BPP); dst = (char *)out + (iy * w * BPP); dstpix = dst; srcprev = prev; srccur = cur; srcnext = next; if (iy == 0) { for (ix = 0; ix < w; ix++) { // Do A...B...G...R one at a time // *dstpix++ = // .75 * *srccur++ + .25 * *srcnext++; dstpix++; // skip A srcprev++; srccur++; srcnext++; #ifdef DOFP *dstpix++ = .75 * *srccur++ + .25 * *srcnext++; *dstpix++ = .75 * *srccur++ + .25 * *srcnext++; *dstpix++ = .75 * *srccur++ + .25 * *srcnext++; #else *dstpix++ = (*srccur>>2) + (*srccur>>1) + (*srcnext>>2); srcprev++; srccur++; srcnext++; *dstpix++ = (*srccur>>2) + (*srccur>>1) + (*srcnext>>2); srcprev++; srccur++; srcnext++; *dstpix++ = (*srccur>>2) + (*srccur>>1) + (*srcnext>>2); srcprev++; srccur++; srcnext++; #endif } } else if (iy == h - 1) { for (ix = 0; ix < w; ix++) { // Do A...B...G...R one at a time // *dstpix++ = // .25 * *srcprev++ + .75 * *srccur++; dstpix++; // skip A srcprev++; srccur++; srcnext++; #ifdef DOFP *dstpix++ = .25 * *srcprev++ + .75 * *srccur++; *dstpix++ = .25 * *srcprev++ + .75 * *srccur++; *dstpix++ = .25 * *srcprev++ + .75 * *srccur++; #else *dstpix++ = (*srcprev>>2) + (*srccur>>1) + (*srccur>>2); srcprev++; srccur++; srcnext++; *dstpix++ = (*srcprev>>2) + (*srccur>>1) + (*srccur>>2); srcprev++; srccur++; srcnext++; *dstpix++ = (*srcprev>>2) + (*srccur>>1) + (*srccur>>2); srcprev++; srccur++; srcnext++; #endif } } else { for (ix = 0; ix < w; ix++) { // Do A...B...G...R one at a time // *dstpix++ = // .25 * *srcprev++ + .5 * *srccur++ + .25 * *srcnext++; dstpix++; // skip A srcprev++; srccur++; srcnext++; #ifdef DOFP *dstpix++ = .25 * *srcprev++ + .5 * *srccur++ + .25 * *srcnext++; *dstpix++ = .25 * *srcprev++ + .5 * *srccur++ + .25 * *srcnext++; *dstpix++ = .25 * *srcprev++ + .5 * *srccur++ + .25 * *srcnext++; #else *dstpix++ = (*srcprev>>2) + (*srccur>>1) + (*srcnext>>2); srcprev++; srccur++; srcnext++; *dstpix++ = (*srcprev>>2) + (*srccur>>1) + (*srcnext>>2); srcprev++; srccur++; srcnext++; *dstpix++ = (*srcprev>>2) + (*srccur>>1) + (*srcnext>>2); srcprev++; srccur++; srcnext++; #endif } } } #ifdef TIMINGINFO QueryPerformanceCounter(&__ss2); __d1 = (double)(__ss2.QuadPart - __ss1.QuadPart)/__freq.QuadPart; if (!(__tcnt % 100)) { sprintf (__tstr, "%06d: filt=%3.3f sec\n", __tcnt, __d1); OutputDebugString(__tstr); } __tcnt++; #endif return; }