#include"BMP_in.h"

 

BOOL BMPfile_to_DIBSection(HWND hWnd,LPCTSTR file_name)

{

       LPBMPINFO lpBmpInfo;

 

       HANDLE fhBMP;

       int iFileSize;

       LPBYTE lpBMP;

       DWORD dwRead;

 

       LPBITMAPFILEHEADER lpbmpfh;

       LPBITMAPINFO lpbiBMPInfo;

       int BitCount,iOffset;

       LPBYTE lpBMPPixel;

       LPDWORD dwColors;

       int iWidth,iHeight;

      

       BITMAPINFO biInfo;

 

       HDC hdc;

       HBITMAP hBMP;

       LPDWORD lpPixel;

       HDC hdcBMP;

 

       int x,y;

 

       lpBmpInfo=(LPBMPINFO)GetWindowLong(hWnd,GWL_USERDATA);

       if(lpBmpInfo==NULL) return FALSE;

 

       fhBMP=CreateFile(file_name,GENERIC_READ,0,NULL,

              OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

       if(fhBMP==INVALID_HANDLE_VALUE){

              MessageBox(hWnd,"ファイルが開けません","エラー",MB_OK);

              return FALSE;

       }

       iFileSize=GetFileSize(fhBMP,NULL);

       lpBMP=(LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,iFileSize);

       ReadFile(fhBMP,lpBMP,iFileSize,&dwRead,NULL);

       CloseHandle(fhBMP);

 

       lpbmpfh=(LPBITMAPFILEHEADER)(lpBMP);

       lpbiBMPInfo=(LPBITMAPINFO)(lpBMP+sizeof(BITMAPFILEHEADER));

       BitCount=lpbiBMPInfo->bmiHeader.biBitCount;

       if(lpbmpfh->bfType!=('M'<<8)+'B' || (BitCount!=8 && BitCount!=24)){

              MessageBox(hWnd,"8ビット or 24ビットBMPファイルしか読み込めません","エラー",MB_OK);

              HeapFree(GetProcessHeap(),0,lpBMP);

              return FALSE;

       }

       iOffset=lpbmpfh->bfOffBits;

       lpBMPPixel=lpBMP+iOffset;

       dwColors=(LPDWORD)lpbiBMPInfo->bmiColors;

       iWidth=lpbiBMPInfo->bmiHeader.biWidth;

       iHeight=lpbiBMPInfo->bmiHeader.biHeight;

 

       biInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

       biInfo.bmiHeader.biWidth=iWidth;

       biInfo.bmiHeader.biHeight=iHeight;

       biInfo.bmiHeader.biPlanes=1;

       biInfo.bmiHeader.biBitCount=32;

       biInfo.bmiHeader.biCompression=BI_RGB;

 

       if(lpBmpInfo->lpPixel!=NULL)

              DeleteObject(lpBmpInfo->hdcBMP);

 

       hdc=GetDC(hWnd);

       hBMP=CreateDIBSection(hdc,&biInfo,DIB_RGB_COLORS,

              (LPVOID *)(&lpPixel),NULL,0);

       hdcBMP=CreateCompatibleDC(hdc);

       SelectObject(hdcBMP,hBMP);

 

       ReleaseDC(hWnd,hdc);

       DeleteObject(hBMP);

 

       switch(BitCount){

              case 8:

                     for(y=0;y<iHeight;y++)

                            for(x=0;x<iWidth;x++)

                                   lpPixel[x+y*iWidth]=dwColors[lpBMPPixel[x+y*iWidth]];

                     break;

              case 24:

                     for(y=0;y<iHeight;y++)

                            for(x=0;x<iWidth;x++)

                                   CopyMemory(lpPixel+x+y*iWidth,lpBMPPixel+x*3+y*iWidth*3,3);

                     break;

       }

 

       HeapFree(GetProcessHeap(),0,lpBMP);

 

       lpBmpInfo->biInfo=biInfo;

       lpBmpInfo->lpPixel=lpPixel;

       lpBmpInfo->hdcBMP=hdcBMP;

       lpBmpInfo->dw=1;

       lpBmpInfo->dh=1;

 

       return TRUE;

}

 

BOOL PasteDIBSection(HWND hWnd)

{

       LPBMPINFO lpBmpInfo;

 

       HGLOBAL hMem;

       LPBYTE lpBMP;

 

       LPBITMAPINFO lpbiBMPInfo;

       int BitCount;

       LPDWORD dwColors;

       LPBYTE lpBMPPixel;

       int iWidth,iHeight;

 

       BITMAPINFO biInfo;

 

       HDC hdc;

       HBITMAP hBMP;

       LPDWORD lpPixel;

       HDC hdcBMP;

 

       int x,y;

 

       lpBmpInfo=(LPBMPINFO)GetWindowLong(hWnd,GWL_USERDATA);

       if(lpBmpInfo==NULL) return FALSE;

 

       if(!IsClipboardFormatAvailable(CF_DIB)){

              MessageBox(hWnd,"利用できないデータ形式です","エラー",MB_OK);

              return FALSE;

       }

       OpenClipboard(hWnd);

       hMem=(HGLOBAL)GetClipboardData(CF_DIB);

       lpBMP=(LPBYTE)GlobalLock(hMem);

 

       lpbiBMPInfo=(LPBITMAPINFO)lpBMP;

       BitCount=lpbiBMPInfo->bmiHeader.biBitCount;

       switch(BitCount){

              case 8:

                     dwColors=(LPDWORD)lpbiBMPInfo->bmiColors;

                     lpBMPPixel=(LPBYTE)(lpBMP+sizeof(BITMAPINFO)+sizeof(RGBQUAD)*255);

                     break;

              case 24:

                     lpBMPPixel=(LPBYTE)(lpBMP+sizeof(BITMAPINFO));

                     break;

              default:

                     GlobalUnlock(hMem);

                     CloseClipboard();

                     MessageBox(hWnd,"8ビット or 24ビットBMPデータしか読み込めません","エラー",MB_OK);

                     return FALSE;

       }

       iWidth=lpbiBMPInfo->bmiHeader.biWidth;

       iHeight=lpbiBMPInfo->bmiHeader.biHeight;

 

       biInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);

       biInfo.bmiHeader.biWidth=iWidth;

       biInfo.bmiHeader.biHeight=iHeight;

       biInfo.bmiHeader.biPlanes=1;

       biInfo.bmiHeader.biBitCount=32;

       biInfo.bmiHeader.biCompression=BI_RGB;

      

       if(lpBmpInfo->lpPixel!=NULL)

              DeleteObject(lpBmpInfo->hdcBMP);

      

       hdc=GetDC(hWnd);

       hBMP=CreateDIBSection(hdc,&biInfo,DIB_RGB_COLORS,

              (LPVOID *)(&lpPixel),NULL,0);

       hdcBMP=CreateCompatibleDC(hdc);

       SelectObject(hdcBMP,hBMP);

 

       ReleaseDC(hWnd,hdc);

       DeleteObject(hBMP);

 

       switch(BitCount){

              case 8:

                     for(y=0;y<iHeight;y++)

                            for(x=0;x<iWidth;x++)

                                   lpPixel[x+y*iWidth]=dwColors[lpBMPPixel[x+y*iWidth]];

                     break;

              case 24:

                     for(y=0;y<iHeight;y++)

                            for(x=0;x<iWidth;x++)

                                   lpPixel[x+y*iWidth]=(lpBMPPixel[x*3+y*iWidth*3]<<8)            //G

                                                                  +(lpBMPPixel[x*3+y*iWidth*3+1]<<16)    //R

                                                                  + lpBMPPixel[x*3+y*iWidth*3+2];        //B

                     break;

       }

 

       GlobalUnlock(hMem);

       CloseClipboard();

 

       lpBmpInfo->biInfo=biInfo;

       lpBmpInfo->lpPixel=lpPixel;

       lpBmpInfo->hdcBMP=hdcBMP;

       lpBmpInfo->dw=1;

       lpBmpInfo->dh=1;

 

       return TRUE;

}

 

void DeleteDIBSection(HWND hWnd)

{

       LPBMPINFO lpBmpInfo;

 

       lpBmpInfo=(LPBMPINFO)GetWindowLong(hWnd,GWL_USERDATA);

       if(lpBmpInfo!=NULL){

              if(lpBmpInfo->lpPixel!=NULL){

            DeleteObject(lpBmpInfo->hdcBMP);

                     lpBmpInfo->lpPixel=NULL;

              }

              HeapFree(GetProcessHeap(),0,lpBmpInfo);

              SetWindowLong(hWnd,GWL_USERDATA,NULL);

       }

}