|
|
/*
* StretchC.C * * StretchBlt for DIBs * * C version of stretch.asm: StretchDIB optimised for AVI. * * NOTES * - does not handle mirroring in x or y * - does not handle pixel translation * - will not work in place. * * AUTHOR * C version by Geraint Davies */
#include <windows.h>
#include "drawdibi.h"
#include "stretch.h"
/* Outline:
* * we select a y-stretching function depending on the ratio (eg 1:N or N:1). * it copies scanlines from source to destination, duplicating or omitting * scanlines as necessary to fit the destination. It copies each scanline * via the X_FUNC function we passed as an argument: this copies one scanline * duplicating or omitting pixels to fit the destination: we select an X_FUNC * depending on the bit-depth as well as the x-stretching ratio. * * both x and y stretching functions use the following basic model for deciding * when to insert/omit elements: * * delta = <larger extent> -1; * * for (number of destination elements) { * * copy one element * advance pointer to larger region * delta -= <smaller extent> * if (delta < 0) { * delta += <larger extent>; * advance pointer to smaller region * } * } */
/* stretch proportions */ #define STRETCH_1_1 1
#define STRETCH_1_2 2
#define STRETCH_1_4 3
#define STRETCH_1_N 4
#define STRETCH_N_1 5
#define STRETCH_4_1 6
#define STRETCH_2_1 7
/*
* an X_FUNC is a function that copies one scanline, stretching or shrinking it * to fit a destination scanline. Pick an X_FUNC depending on * bitdepth and stretch ratio (1:1, 1:2, 1:4, 1:N, N:1, 4:1, 2:1) * * the x_fract argument is the delta fraction: it is a representation * of the smaller extent (whichever that is) as a fraction of the larger, * and is used when stretching or shrinking to advance the pointer to the * smaller scanline every (fract) pixels of the larger. * Thus if we are expanding 1:8, x_fract will be 1/8, we will advance the * source pointer once every 8 pixels, and thus copy each source pixel to * 8 dest pixels. Note that if shrinking 8:1, x_fract will still be 1/8 * and we will use it to control advancement of the dest pointer. * the fraction is multiplied by 65536. */ typedef void (*X_FUNC) (LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract);
void X_Stretch_1_1_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_1_4_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_1_N_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_N_1_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract);
void X_Stretch_1_1_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_1_2_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_1_N_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_N_1_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract);
void X_Stretch_1_1_24Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_1_N_24Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract); void X_Stretch_N_1_24Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract);
/*
* Y_Stretch_* functions copy DstYE scanlines (using * an X_FUNC to copy each scanline) omitting or duplicating scanlines to * fit the destination extent. Pick a Y_ depending on the ratio * (1:N, N:1...) */
void Y_Stretch_1_N(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract, X_FUNC x_func);
void Y_Stretch_N_1(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract, X_FUNC x_func);
/*
* special case y-stretch functions for 1:2 in both dimensions for 8 and 16 bits * takes no X_FUNC arg. Will do entire stretch. */ void Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract);
void Stretch_1_2_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract);
/* straight copy of one scanline of count bytes */ void X_CopyScanline(LPBYTE lpSrc, LPBYTE lpDst, int count);
/* -------------------------------------------------------------------- */
/*
* StretchFactor * * calculate the stretch factor (proportion of source extent to destination * extent: 1:1, 1:2, 1:4, 1:N, N:1, 4:1,or 2:1) and also the * delta fraction (see above comment on X_FUNC). This is the ratio of * the smaller extent to the larger extent, represented as a fraction * multiplied by 65536. * * returns: the stretch factor (stores the delta fraction in *pfract) */
int StretchFactor(int SrcE, int DstE, int *pfract) {
if (SrcE == DstE) { if (pfract != NULL) { pfract = 0; }
return(STRETCH_1_1);
}
if (SrcE > DstE) { if (pfract != NULL) { *pfract = ( (DstE << 16) / SrcE) & 0xffff; }
if (SrcE == (DstE * 2)) { return(STRETCH_2_1); } else if (SrcE == (DstE * 4)) { return(STRETCH_4_1); } else { return(STRETCH_N_1); }
} else {
/* calculate delta fraction based on smallest / largest */ if (pfract != NULL) { *pfract = ( (SrcE << 16) / DstE) & 0xffff; } if (DstE == (SrcE * 2)) { return(STRETCH_1_2); } else if (DstE == (SrcE * 4)) { return(STRETCH_1_4); } else { return(STRETCH_1_N); } } }
/* -------------------------------------------------------------------- */
/*
* StretchDIB * */
void WINAPI StretchDIB( LPBITMAPINFOHEADER biDst, // --> BITMAPINFO of destination
LPVOID lpvDst, // --> to destination bits
int DstX, // Destination origin - x coordinate
int DstY, // Destination origin - y coordinate
int DstXE, // x extent of the BLT
int DstYE, // y extent of the BLT
LPBITMAPINFOHEADER biSrc, // --> BITMAPINFO of source
LPVOID lpvSrc, // --> to source bits
int SrcX, // Source origin - x coordinate
int SrcY, // Source origin - y coordinate
int SrcXE, // x extent of the BLT
int SrcYE // y extent of the BLT
) {
int nBits; int SrcWidth, DstWidth; LPBYTE lpDst = lpvDst, lpSrc = lpvSrc; int x_fract; int x_factor; int y_factor; X_FUNC xfunc;
/*
* check that bit depths are same and 8, 16 or 24 */
if ((nBits = biDst->biBitCount) != biSrc->biBitCount) { return; }
if ( (nBits != 8 ) && (nBits != 16) && (nBits != 24)) { return; }
/*
* check that extents are not bad */ if ( (SrcXE <= 0) || (SrcYE <= 0) || (DstXE <= 0) || (DstYE <= 0)) { return; }
/*
* calculate width of one scan line in bytes, rounded up to * DWORD boundary. */ SrcWidth = (((biSrc->biWidth * nBits) + 31) & ~31) / 8; DstWidth = (((biDst->biWidth * nBits) + 31) & ~31) / 8;
/*
* set initial source and dest pointers */ lpSrc += (SrcY * SrcWidth) + ((SrcX * nBits) / 8); lpDst += (DstY * DstWidth) + ((DstX * nBits) / 8);
/*
* calculate stretch proportions (1:1, 1:2, 1:N, N:1 etc) and * also the fractional stretch factor. (we are not interested in * the y stretch fraction - this is only used in x stretching. */
y_factor = StretchFactor(SrcYE, DstYE, NULL); x_factor = StretchFactor(SrcXE, DstXE, &x_fract);
/*
* we have special case routines for 1:2 in both dimensions * for 8 and 16 bits */ if ((y_factor == x_factor) && (y_factor == STRETCH_1_2)) {
if (nBits == 8) { //StartCounting();
Stretch_1_2_8Bits(lpSrc, lpDst, SrcXE, SrcYE, DstXE, DstYE, SrcWidth, DstWidth, x_fract); //EndCounting("8 bit");
return;
} else if (nBits == 16) { //StartCounting();
Stretch_1_2_16Bits(lpSrc, lpDst, SrcXE, SrcYE, DstXE, DstYE, SrcWidth, DstWidth, x_fract); //EndCounting("16 bit");
return; } }
/* pick an X stretch function */ switch(nBits) {
case 8: switch(x_factor) { case STRETCH_1_1: xfunc = X_Stretch_1_1_8Bits; break;
case STRETCH_1_2: xfunc = X_Stretch_1_2_8Bits; break;
case STRETCH_1_4: xfunc = X_Stretch_1_4_8Bits; break;
case STRETCH_1_N: xfunc = X_Stretch_1_N_8Bits; break;
case STRETCH_N_1: case STRETCH_4_1: case STRETCH_2_1: xfunc = X_Stretch_N_1_8Bits; break;
} break;
case 16: switch(x_factor) { case STRETCH_1_1: xfunc = X_Stretch_1_1_16Bits; break;
case STRETCH_1_2: xfunc = X_Stretch_1_2_16Bits; break;
case STRETCH_1_4: case STRETCH_1_N: xfunc = X_Stretch_1_N_16Bits; break;
case STRETCH_N_1: case STRETCH_4_1: case STRETCH_2_1: xfunc = X_Stretch_N_1_16Bits; break;
} break;
case 24: switch(x_factor) { case STRETCH_1_1: xfunc = X_Stretch_1_1_24Bits; break;
case STRETCH_1_2: case STRETCH_1_4: case STRETCH_1_N: xfunc = X_Stretch_1_N_24Bits; break;
case STRETCH_N_1: case STRETCH_4_1: case STRETCH_2_1: xfunc = X_Stretch_N_1_24Bits; break;
} break;
}
/*
* now call appropriate stretching function depending * on the y stretch factor */ switch (y_factor) { case STRETCH_1_1: case STRETCH_1_2: case STRETCH_1_4: case STRETCH_1_N: Y_Stretch_1_N(lpSrc, lpDst, SrcXE, SrcYE, DstXE, DstYE, SrcWidth, DstWidth, x_fract, xfunc); break;
case STRETCH_N_1: case STRETCH_4_1: case STRETCH_2_1: Y_Stretch_N_1(lpSrc, lpDst, SrcXE, SrcYE, DstXE, DstYE, SrcWidth, DstWidth, x_fract, xfunc); break;
} return; }
/* ---- y stretching -------------------------------------------- */
/*
* call an X_FUNC to copy scanlines from lpSrc to lpDst. Duplicate or * omit scanlines to stretch SrcYE to DstYE. */
/*
* Y_Stretch_1_N * * write DstYE scanlines based on SrcYE scanlines, DstYE > SrcYE * */
void Y_Stretch_1_N(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract, X_FUNC x_func) {
int ydelta; int i; LPBYTE lpPrev = NULL;
ydelta = DstYE -1;
for (i = 0; i < DstYE; i++) {
/* have we already stretched this scanline ? */ if (lpPrev == NULL) { /* no - copy one scanline */ (*x_func)(lpSrc, lpDst, SrcXE, DstXE, x_fract); lpPrev = lpDst; } else { /* yes - this is a duplicate scanline. do
* a straight copy of one that has already * been stretched/shrunk */ X_CopyScanline(lpPrev, lpDst, DstWidth); }
/* advance dest pointer */ lpDst += DstWidth;
/* should we advance source pointer this time ? */ if ( (ydelta -= SrcYE) < 0) { ydelta += DstYE; lpSrc += SrcWidth; lpPrev = NULL; } } }
/*
* Y_Stretch_N_1 * * write DstYE scanlines based on SrcYE scanlines, DstYE < SrcYE * */ void Y_Stretch_N_1(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract, X_FUNC x_func) {
int ydelta; int i;
ydelta = SrcYE -1;
for (i = 0; i < DstYE; i++) {
/* copy one scanline */ (*x_func)(lpSrc, lpDst, SrcXE, DstXE, x_fract);
/* advance dest pointer */ lpDst += DstWidth;
/* how many times do we advance source pointer this time ? */ do { lpSrc += SrcWidth; ydelta -= DstYE; } while (ydelta >= 0);
ydelta += SrcYE; } }
/* ---8-bit X stretching -------------------------------------------------- */
/*
* X_Stretch_1_N_8Bits * * copy one scan line, stretching 1:N (DstXE > SrcXE). For 8-bit depth. */ void X_Stretch_1_N_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { int xdelta; int i;
xdelta = DstXE -1;
for (i = 0; i < DstXE; i++) {
/* copy one byte and advance dest */ *lpDst++ = *lpSrc;
/* should we advance source pointer this time ? */ if ( (xdelta -= SrcXE) < 0) { xdelta += DstXE; lpSrc++; } } }
/*
* X_Stretch_N_1_8Bits * * copy one scan line, shrinking N:1 (DstXE < SrcXE). For 8-bit depth. */ void X_Stretch_N_1_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { int xdelta; int i;
xdelta = SrcXE -1;
for (i = 0; i < DstXE; i++) {
/* copy one byte and advance dest */ *lpDst++ = *lpSrc;
/* how many times do we advance source pointer this time ? */ do { lpSrc++; xdelta -= DstXE; } while (xdelta >= 0);
xdelta += SrcXE; } }
/*
* copy one scanline of count bytes from lpSrc to lpDst. used by 1:1 * scanline functions for all bit depths */ void X_CopyScanline(LPBYTE lpSrc, LPBYTE lpDst, int count) { int i;
/*
* if the alignment of lpSrc and lpDst is the same, then * we can get them aligned and do a faster copy */ if (((DWORD)(DWORD_PTR) lpSrc & 0x3) == ( (DWORD)(DWORD_PTR) lpDst & 0x3)) { /* align on WORD boundary */ if ( (DWORD)(DWORD_PTR) lpSrc & 0x1) { *lpDst++ = *lpSrc++; count--; }
/* align on DWORD boundary */ if ((DWORD)(DWORD_PTR) lpSrc & 0x2) { * ((LPWORD) lpDst) = *((LPWORD) lpSrc); lpDst += sizeof(WORD); lpSrc += sizeof(WORD); count -= sizeof(WORD); }
/* copy whole DWORDS */ for ( i = (count / 4); i > 0; i--) { *((LPDWORD) lpDst) = *((LPDWORD) lpSrc); lpSrc += sizeof(DWORD); lpDst += sizeof(DWORD); } } else { /* the lpSrc and lpDst pointers are different
* alignment, so leave them unaligned and * copy all the whole DWORDs */ for (i = (count / 4); i> 0; i--) { *( (DWORD UNALIGNED FAR *) lpDst) = *((DWORD UNALIGNED FAR *) lpSrc); lpSrc += sizeof(DWORD); lpDst += sizeof(DWORD); } }
/* in either case, copy last (up to 3) bytes. */ for ( i = count % 4; i > 0; i--) { *lpDst++ = *lpSrc++; } } /*
* X_Stretch_1_1_8Bits * * copy a scanline with no change (1:1) */ void X_Stretch_1_1_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) {
X_CopyScanline(lpSrc, lpDst, DstXE); }
/*
* X_Stretch_1_2_8Bits * * copy a scanline, doubling all the pixels (1:2) */ void X_Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { WORD wPix; int i;
for (i = 0; i < SrcXE; i++) { /* get a pixel and double it */ wPix = *lpSrc++; wPix |= (wPix << 8); * ((WORD UNALIGNED *) lpDst) = wPix; lpDst += sizeof(WORD); } }
/*
* X_Stretch_1_4_8Bits * * copy a scanline, quadrupling all the pixels (1:4) */ void X_Stretch_1_4_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { DWORD dwPix; int i;
for (i = 0; i < SrcXE; i++) {
/* get a pixel and make four copies of it */ dwPix = *lpSrc++; dwPix |= (dwPix <<8); dwPix |= (dwPix << 16); * ((DWORD UNALIGNED *) lpDst) = dwPix; lpDst += sizeof(DWORD); } }
/* -- 16-bit X functions -----------------------------------------------*/
/*
* copy one scan-line of 16 bits with no change (1:1) */ void X_Stretch_1_1_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) {
X_CopyScanline(lpSrc, lpDst, DstXE * sizeof(WORD));
}
/*
* copy one scanline of 16 bpp duplicating each pixel */ void X_Stretch_1_2_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) {
DWORD dwPix; int i;
for (i = 0; i < SrcXE; i++) { /* get a pixel and double it */ dwPix = * ((WORD *)lpSrc); dwPix |= (dwPix << 16); * ((DWORD UNALIGNED *) lpDst) = dwPix;
lpDst += sizeof(DWORD); lpSrc += sizeof(WORD); }
}
/*
* copy one scanline of 16 bits, stretching 1:n (dest > source) */ void X_Stretch_1_N_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { int xdelta; int i;
xdelta = DstXE -1;
for (i = 0; i < DstXE; i++) {
/* copy one pixel and advance dest */ *((WORD *) lpDst) = *((WORD *) lpSrc);
lpDst += sizeof(WORD);
/* should we advance source pointer this time ? */ if ( (xdelta -= SrcXE) < 0) { xdelta += DstXE; lpSrc += sizeof(WORD); } } }
/*
* copy one scanline of 16bits, shrinking n:1 (dest < source) */ void X_Stretch_N_1_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) {
int xdelta; int i;
xdelta = SrcXE -1;
for (i = 0; i < DstXE; i++) {
/* copy one pixel and advance dest */ *((WORD *) lpDst) = *((WORD *)lpSrc);
lpDst += sizeof(WORD);
/* how many times do we advance source pointer this time ? */ do { lpSrc += sizeof(WORD); xdelta -= DstXE; } while (xdelta >= 0);
xdelta += SrcXE; }
}
/* 24-bits ---------------------------------------------------------*/
/*
* copy one 24-bpp scanline as is (1:1) */ void X_Stretch_1_1_24Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { X_CopyScanline(lpSrc, lpDst, DstXE * 3); }
/*
* copy one 24-bpp scanline stretching 1:n (dest > source) */ void X_Stretch_1_N_24Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) {
int xdelta; int i;
xdelta = DstXE -1;
for (i = 0; i < DstXE; i++) { /* copy first word of pixel and advance dest */ *((WORD UNALIGNED *) lpDst) = *((WORD UNALIGNED *) lpSrc);
lpDst += sizeof(WORD);
/* copy third byte and advance dest */ *lpDst++ = lpSrc[sizeof(WORD)];
/* should we advance source pointer this time ? */ if ( (xdelta -= SrcXE) < 0) { xdelta += DstXE; lpSrc += 3; } } }
/*
* copy one scanline of 24 bits, shrinking n:1 (dest < source) */ void X_Stretch_N_1_24Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE, int DstXE, int x_fract) { int xdelta; int i;
xdelta = SrcXE -1;
for (i = 0; i < DstXE; i++) {
/* copy first word of pixel and advance dest */ *((WORD UNALIGNED *) lpDst) = *((WORD UNALIGNED *) lpSrc);
lpDst += sizeof(WORD);
/* copy third byte and advance dest */ *lpDst++ = lpSrc[sizeof(WORD)];
/* how many times do we advance source pointer this time ? */ do { lpSrc += 3; xdelta -= DstXE; } while (xdelta >= 0);
xdelta += SrcXE; } }
/* -- special-case 1:2 -------------------------------------------*/
/*
* stretch 1:2 in both directions, for 8 bits. * * An experiment was done on x86 to only write every other line during * the stretch and when the whole frame was done to use memcpy to fill * in the gaps. This is slower than doing the stretch in a single pass. */ void Stretch_1_2_8Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract) {
int SrcInc, DstInc; int i, j; WORD wPix; DWORD dwPix4;
/* amount to advance source by at the end of each scan */ SrcInc = SrcWidth - SrcXE;
/* amount to advance dest by at the end of each scan - note
* that we write two scans at once, so advance past the next * scan line */ DstInc = (DstWidth * 2) - DstXE;
/*
* we would like to copy the pixels DWORD at a time. this means * being aligned. if we are currently aligned on a WORD boundary, * then copy one pixel to get aligned. If we are on a byte * boundary, we can never get aligned, so use the slower loop. */ if ( ((DWORD)(DWORD_PTR)lpDst) & 1) {
/*
* dest is byte aligned - so we can never align it * by writing WORDs - use slow loop. */ for (i = 0; i < SrcYE; i++) { for (j = 0; j < SrcXE; j++) { /* get a pixel and double it */ wPix = *lpSrc++; wPix |= (wPix<<8); /* write doubled pixel to this scanline */ *( (WORD UNALIGNED *) lpDst) = wPix; /* write double pixel to next scanline */ *( (WORD UNALIGNED *) (lpDst + DstWidth)) = wPix; lpDst += sizeof(WORD); } lpSrc += SrcInc; lpDst += DstInc; } return; }
/*
* this will be the aligned version. align each scan line */ for ( i = 0; i < SrcYE; i++) {
/* count of pixels remaining */ j = SrcXE;
/* align this scan line */ if (((DWORD)(DWORD_PTR)lpDst) & 2) {
/* word aligned - copy one doubled pixel and we are ok */ wPix = *lpSrc++; wPix |= (wPix << 8); *( (WORD *) lpDst) = wPix; *( (WORD *) (lpDst + DstWidth)) = wPix; lpDst += sizeof(WORD);
j -= 1; }
/* now dest is aligned - so loop eating two pixels at a time
* until there is at most one left */ for ( ; j > 1; j -= 2) {
/* read two pixels and double them */ wPix = * ((WORD UNALIGNED *) lpSrc); lpSrc += sizeof(WORD);
dwPix4 = (wPix & 0xff) | ((wPix & 0xff) << 8); dwPix4 |= ((wPix & 0xff00) << 8) | ((wPix & 0xff00) << 16); *((DWORD *) lpDst) = dwPix4; *((DWORD *) (lpDst + DstWidth)) = dwPix4;
lpDst += sizeof(DWORD); }
/* odd byte remaining ? */ if (j > 0) { /* word aligned - copy one doubled pixel and we are ok */ wPix = *lpSrc++; wPix |= (wPix << 8); *( (WORD *) lpDst) = wPix; *( (WORD *) (lpDst + DstWidth)) = wPix; lpDst += sizeof(WORD);
j -= 1; } lpSrc += SrcInc; lpDst += DstInc; } }
/* ----------------------------------------------------------------*/
/*
* stretch 1:2 in both directions, for 16-bits */
void Stretch_1_2_16Bits(LPBYTE lpSrc, LPBYTE lpDst, int SrcXE,int SrcYE, int DstXE, int DstYE, int SrcWidth, int DstWidth, int x_fract)
{ int SrcInc, DstInc; int i, j; DWORD dwPix;
/* amount to advance source by at the end of each scan */ SrcInc = SrcWidth - (SrcXE * sizeof(WORD));
/* amount to advance dest by at the end of each scan - note
* that we write two scans at once, so advance past the next * scan line */ DstInc = (DstWidth * 2) - (DstXE * sizeof(WORD));
for (i = 0; i < SrcYE; i++) {
for (j = 0; j < SrcXE; j++) {
/* get a pixel and double it */
dwPix = *((WORD *)lpSrc); dwPix |= (dwPix<<16);
lpSrc += sizeof(WORD);
/* write doubled pixel to this scanline */
*( (DWORD UNALIGNED *) lpDst) = dwPix;
/* write double pixel to next scanline */ *( (DWORD UNALIGNED *) (lpDst + DstWidth)) = dwPix;
lpDst += sizeof(DWORD); } lpSrc += SrcInc; lpDst += DstInc;
} }
|