// B8G8R8 to B8G8R8A8 convsersion-code benchmark // copyright(C) 2000 XELF. All rights reserved. // http://www.cyborg.ne.jp/~xelf/ // You can use this source code for any purpose without permission. // Notes that this source code is not supported the processing of fraction pixels. #include #include #pragma comment(lib,"winmm.lib") #include #include #ifdef _DEBUG #define VERIFY // for verifying pointers #endif void CopyPixelImageBGRtoBGRA( BYTE* d, const BYTE* s, int width, int height ) { #ifdef VERIFY const BYTE* se=s+width*height*3; BYTE *de=d+width*height*4; #endif BYTE a=0xff; for(int y=height;--y>=0;) { for(int x=width;--x>=0;) { *d++=a; *d++=*s++; *d++=*s++; *d++=*s++; } } #ifdef VERIFY if (se!=s) { printf("program internal error.\r\n"); } if (de!=d) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRAword( BYTE* d, const BYTE* s, int width, int height ) { #ifdef VERIFY const BYTE* se=s+width*height*3; BYTE *de=d+width*height*4; #endif BYTE a=0xff; for(int y=height;--y>=0;) { for(int x=width;--x>=0;) { *d++=a; *d++=*s++; *(WORD*)d=*(WORD*)s; d+=2; s+=2; } } #ifdef VERIFY if (se!=s) { printf("program internal error.\r\n"); } if (de!=d) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRAword2( BYTE* d, const BYTE* s, int width, int height ) { #ifdef VERIFY const BYTE* se=s+width*height*3; BYTE *de=d+width*height*4; #endif BYTE a=0xff; for(int y=height;--y>=0;) { for(int x=width;--x>=0;) { *d=a; *(d+1)=*s; *(WORD*)(d+2)=*(WORD*)(s+1); d+=4; s+=3; } } #ifdef VERIFY if (se!=s) { printf("program internal error.\r\n"); } if (de!=d) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRA3( BYTE* d, const BYTE* s, int width, int height ) { #ifdef VERIFY const BYTE* se=s+width*height*3; BYTE *de=d+width*height*4; #endif BYTE a=0xff; int w=width/4; DWORD p0,p1,p2; for(int y=height;--y>=0;) { for(int x=w;--x>=0;) { p0=*(DWORD*)(s ); p1=*(DWORD*)(s+ 4); p2=*(DWORD*)(s+ 8); *(DWORD*)(d )=a|(p0<< 8); *(DWORD*)(d+ 4)=a|(p0>>16)|(p1<<16); *(DWORD*)(d+ 8)=a|(p1>> 8)|(p2<<24); *(DWORD*)(d+12)=a|(p2 ); s+=12; d+=16; } } #ifdef VERIFY if (se!=s) { printf("program internal error.\r\n"); } if (de!=d) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRAAsm3dwordor( BYTE* d, const BYTE* s, int width, int height ) { // (A=255) #ifdef VERIFY BYTE* de; const BYTE *se; #endif int w=width/4; __asm { // 3 pixels/lx mov esi,s; mov edi,d; mov ecx,height; ly: push ecx; mov ecx,w; lx: // h- -- -- -l mov eax,[esi]; // R1 B0 G0 R0 mov edx,eax; // shl eax,8; // B0 G0 R0 00 or eax,0xff; // B0 G0 R0 AA mov [edi],eax; // shr edx,16; // 00 00 R1 00 mov eax,[esi+4]; // G2 R2 B1 G1 mov ebx,eax; // shl eax,16; // B1 G1 00 00 add edx,eax; // B1 G1 R1 00 or edx,0xff; // B1 G1 R1 AA mov [edi+4],edx; // shr ebx,8; // 00 G2 R2 00 mov eax,[esi+8]; // B3 G3 R3 B2 mov edx,eax; // shl eax,24; // B2 00 00 00 add eax,ebx; // B2 G2 R2 00 or eax,0xff; // B2 G2 R2 AA mov [edi+8],eax; // or edx,0xff; // B3 G3 R3 AA add esi,12; mov [edi+12],edx; add edi,16; dec ecx; jnz lx; pop ecx; dec ecx; jnz ly; #ifdef VERIFY mov [se],esi; mov [de],edi; #endif } #ifdef VERIFY if (se!=s+width*height*3) { printf("program internal error.\r\n"); } if (de!=d+width*height*4) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRAAsm3( BYTE* d, const BYTE* s, int width, int height ) { // (A=255) #ifdef VERIFY BYTE* de; const BYTE *se; #endif int w=width/4; __asm { // 3 pixels/lx mov esi,s; mov edi,d; mov ecx,height; ly: push ecx; mov ecx,w; lx: // h- -- -- -l mov eax,[esi]; // R1 B0 G0 R0 mov edx,eax; // shl eax,8; // B0 G0 R0 00 or al,0xff; // B0 G0 R0 AA mov [edi],eax; // shr edx,16; // 00 00 R1 00 mov eax,[esi+4]; // G2 R2 B1 G1 mov ebx,eax; // shl eax,16; // B1 G1 00 00 add edx,eax; // B1 G1 R1 00 or dl,0xff; // B1 G1 R1 AA mov [edi+4],edx; // shr ebx,8; // 00 G2 R2 00 mov eax,[esi+8]; // B3 G3 R3 B2 mov edx,eax; // shl eax,24; // B2 00 00 00 add eax,ebx; // B2 G2 R2 00 or al,0xff; // B2 G2 R2 AA mov [edi+8],eax; // // or dl,0xff; // B3 G3 R3 AA mov dl,al; // B3 G3 R3 AA add esi,12; mov [edi+12],edx; add edi,16; dec ecx; jnz lx; pop ecx; dec ecx; jnz ly; #ifdef VERIFY mov [se],esi; mov [de],edi; #endif } #ifdef VERIFY if (se!=s+width*height*3) { printf("program internal error.\r\n"); } if (de!=d+width*height*4) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRAAsm1( BYTE* d, const BYTE* s, int width, int height ) { // (A=255) #ifdef VERIFY BYTE* de; const BYTE *se; #endif int w=width; __asm { mov esi,s; mov edi,d; mov ecx,height; ly: push ecx; mov ecx,w; mov ebx,0xff; lx: // h- -- -- -l mov ax,[esi+1]; // 00 00 B0 G0 shl eax,16; // B0 G0 00 00 mov ah,[esi]; // B0 G0 R0 00 or al,bl; // B0 G0 R0 AA add esi,3; mov [edi],eax; add edi,4; dec ecx; jnz lx; pop ecx; dec ecx; jnz ly; #ifdef VERIFY mov [se],esi; mov [de],edi; #endif } #ifdef VERIFY if (se!=s+width*height*3) { printf("program internal error.\r\n"); } if (de!=d+width*height*4) { printf("program internal error.\r\n"); } #endif } void CopyPixelImageBGRtoBGRAAsm1dwor( BYTE* d, const BYTE* s, int width, int height ) { // (A=255) #ifdef VERIFY BYTE* de; const BYTE *se; #endif int w=width; __asm { mov esi,s; mov edi,d; mov ecx,height; ly: push ecx; mov ecx,w; mov ebx,0xff; lx: // h- -- -- -l mov ax,[esi+1]; // 00 00 B0 G0 shl eax,16; // B0 G0 00 00 mov ah,[esi]; // B0 G0 R0 00 or eax,ebx; // B0 G0 R0 AA add esi,3; mov [edi],eax; add edi,4; dec ecx; jnz lx; pop ecx; dec ecx; jnz ly; #ifdef VERIFY mov [se],esi; mov [de],edi; #endif } #ifdef VERIFY if (se!=s+width*height*3) { printf("program internal error.\r\n"); } if (de!=d+width*height*4) { printf("program internal error.\r\n"); } #endif } enum { loop=100, }; class Benchmark { DWORD time; BYTE* d; public: Benchmark( LPCTSTR title, BYTE* _d ) { d=_d; printf("%s:",title); time=timeGetTime(); } ~Benchmark() { printf(" %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\r\n", d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7],d[8],d[9],d[10],d[11],d[12],d[13],d[14],d[15]); printf(" %6.2f [ms]\r\n",(timeGetTime()-time)/float(loop)); } }; int main() { timeBeginPeriod(1); int width=1024,height=1024; int ssize=width*height*3,dsize=width*height*4; BYTE* s=new BYTE[ssize]; BYTE* d=new BYTE[dsize]; printf("B8G8R8 to B8G8R8A8 convsersion-code benchmark VER.2000-11-20 by (C)2000 XELF.\r\n"); printf("width=%d height=%d\r\n(BGR source=%d [bytes], BGRA destination=%d [bytes])\r\n\r\n", width,height,ssize,dsize); for(int x=0,xe=min(16,width);x