#define WIN32_LEAN_AND_MEAN #include #include #include #include #include "bmpconv.hpp" #include "filestrm.hpp" #include "npstrm.hpp" #include "scrnview.hpp" #include "comp.hpp" static void convertTmp2Current(BITMAPINFO *bi, const void *tmpbits, void *currentbits) { static uint32 dstpal[256]; static int dstpal_initialized=0; if(!dstpal_initialized) { uint32 v[6]={0,64,128,192,240,255}; int i=0; for(int r=0; r<6; r++) for(int g=0; g<6; g++) for(int b=0; b<6; b++) dstpal[i++] = ((v[r]<<16)|v[g]<<8)|v[b]; for(; i<256; i++) dstpal[i] = 0; dstpal_initialized=1; } if(bi->bmiHeader.biBitCount==8) ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 8, (uint32)bi->bmiColors, currentbits, 8, (uint32)dstpal ); else if(bi->bmiHeader.biBitCount==16) { //555 or 565 ? if(bi->bmiHeader.biCompression==BI_BITFIELDS && *(DWORD*)(&bi->bmiColors[0]) == 0xf800 && *(DWORD*)(&bi->bmiColors[1]) == 0x07e0 && *(DWORD*)(&bi->bmiColors[2]) == 0x001f) ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 16, 0x0565, currentbits, 8, (uint32)dstpal ); else ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 16, 0x0555, currentbits, 8, (uint32)dstpal ); } else if(bi->bmiHeader.biBitCount==24) { ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 24, 0, currentbits, 8, (uint32)dstpal ); } else if(bi->bmiHeader.biBitCount==32) { ConvertBitmapBits((uint16)bi->bmiHeader.biWidth, (uint16)bi->bmiHeader.biHeight, tmpbits, 32, 0, currentbits, 8, (uint32)dstpal ); } } static void snapscreen0(unsigned *w, unsigned *h, char **cb) { unsigned width=*w,height=*h; char *cbitbuf=*cb; HDC hdcScreen=CreateDC("DISPLAY",NULL,NULL,NULL); if(!hdcScreen) { fprintf(stderr,"snap(0): CreateDC(screen) failed\n"); return; } HBITMAP hbmCurrent = (HBITMAP)GetCurrentObject(hdcScreen,OBJ_BITMAP); if(!hbmCurrent) { fprintf(stderr,"snap(0): hbmCurrent==NULL\n"); return; } char bihbuf[sizeof(BITMAPINFO)+256*sizeof(RGBQUAD)]; BITMAPINFO &bih=*(BITMAPINFO*)bihbuf; memset(bihbuf,0,sizeof(bihbuf)); bih.bmiHeader.biSize=sizeof(bih); if(GetDIBits(hdcScreen,hbmCurrent, 0,height, NULL, &bih, DIB_RGB_COLORS ) ==0) { fprintf(stderr,"snap(0): GetDIBits(...NULL...) failed\n"); return; } if(*cb==0 || *w!=bih.bmiHeader.biWidth || *h!=bih.bmiHeader.biHeight) { delete[] *cb; *w = bih.bmiHeader.biWidth; *h = bih.bmiHeader.biHeight; *cb = new char[*w * *h]; } char *tmpbitbuf = new char[*w * *h]; if(tmpbitbuf==0) { fprintf(stderr,"snap(0): could not allocate tmpbitbuf\n"); return; } if(GetDIBits(hdcScreen, hbmCurrent, 0,*h, tmpbitbuf, &bih, DIB_RGB_COLORS ) ==0) { fprintf(stderr,"snap(0): GetDIBits failed\n"); return; } DeleteDC(hdcScreen); //convert to 8-bit with fixed palette convertTmp2Current(&bih, tmpbitbuf, *cb); delete[] tmpbitbuf; } static void snapscreen1(unsigned *w, unsigned *h, char **cb) { unsigned width=*w,height=*h; char *cbitbuf=*cb; HDC hdcScreen=CreateDC("DISPLAY",NULL,NULL,NULL); if(!hdcScreen) { fprintf(stderr,"Glup! CreateDC() failed\n"); return; } HBITMAP hbmCurrent; int sw = GetDeviceCaps(hdcScreen,DESKTOPHORZRES), sh = GetDeviceCaps(hdcScreen,DESKTOPVERTRES); if(sw<640 || sh<480) { fprintf(stderr,"snap(1): GetDeviceCaps failed, using GetSystemMetrics() instead\n"); sw = GetSystemMetrics(SM_CXSCREEN); sh = GetSystemMetrics(SM_CYSCREEN); return; } HDC hdcMem = CreateCompatibleDC(hdcScreen); if(!hdcMem) { fprintf(stderr,"snap(1): CreateCompatibleDC() failed\n"); return; } char bibuf[sizeof(BITMAPINFO)+256*sizeof(RGBQUAD)]; BITMAPINFO &bi=*(BITMAPINFO*)bibuf; memset(bibuf,0,sizeof(bibuf)); bi.bmiHeader.biSize=sizeof(bi); bi.bmiHeader.biWidth = sw; bi.bmiHeader.biHeight = sh; bi.bmiHeader.biPlanes = 1; bi.bmiHeader.biBitCount = 8; bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = 0; bi.bmiHeader.biClrUsed = 6*6*6; bi.bmiHeader.biClrImportant = 6*6*6; { uint32 v[6]={0,64,128,192,240,255}; int i=0; for(int r=0; r<6; r++) for(int g=0; g<6; g++) for(int b=0; b<6; b++) { bi.bmiColors[i].rgbBlue = (BYTE)v[b]; bi.bmiColors[i].rgbGreen = (BYTE)v[g]; bi.bmiColors[i].rgbRed = (BYTE)v[r]; bi.bmiColors[i].rgbReserved = 0; i++; } for(; i<256; i++) { bi.bmiColors[i].rgbBlue = 0; bi.bmiColors[i].rgbGreen = 0; bi.bmiColors[i].rgbRed = 0; bi.bmiColors[i].rgbReserved = 0; } } void *pvBits; hbmCurrent = CreateDIBSection(hdcMem, &bi, DIB_RGB_COLORS, &pvBits, NULL, 0 ); if(!hbmCurrent) { fprintf(stderr,"snap(1): CreateDIBSection failed, error=%d\n",GetLastError()); return; } HGDIOBJ hbmOld=SelectObject(hdcMem,hbmCurrent); if(!hbmOld) { fprintf(stderr,"snap(1): SelectObject failed, error=%d\n",GetLastError()); return; } SetDIBColorTable(hdcMem,0,6*6*6,bi.bmiColors); if(!BitBlt(hdcMem,0,0,sw,sh, hdcScreen,0,0, SRCCOPY)) { fprintf(stderr,"snap(1): BitBlt failed, error=%d\n",GetLastError()); return; } DeleteDC(hdcScreen); SelectObject(hdcMem,hbmOld); DeleteDC(hdcMem); if(sw!=*w || sh!=*h || *cb==0) { delete[] (*cb); *w = sw; *h = sh; *cb = new char[sw*sh]; } memcpy(*cb, pvBits, sw*sh); DeleteObject(hbmCurrent); } void main(int argc, char **argv) { int snapmethod; OutStream *os; if(argc==4) { snapmethod=atoi(argv[1]); if(stricmp(argv[2],"np")==0) { os = new NPOutStream; os->open(argv[3]); } else if(stricmp(argv[2],"file")==0) { os = new FileOutStream; os->open(argv[3]); } else { fprintf(stderr,"Unknown commtype: '%s'\n",argv[2]); return; } } else { os = new FileOutStream; os->open("snap.out"); } InitializeCompressor(os); unsigned width=0,height=0; char *cbitbuf=0; DWORD starttime=GetTickCount(); for(int r=0;r<10;r++) { // while(!os->error()) { //printf("Snap! "); fflush(stdout); //get current screen image if(snapmethod==0) snapscreen0(&width,&height,&cbitbuf); else if(snapmethod==1) snapscreen1(&width,&height,&cbitbuf); //transmit it // compress(width,height,cbitbuf); //and give the user some time // Sleep(2000); } DWORD endtime=GetTickCount(); printf("Ticks: %d\n",endtime-starttime); os->close(); delete os; }