Advertisement
Guest User

Untitled

a guest
Jan 18th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.65 KB | None | 0 0
  1. #include <windows.h>
  2. #include <stdio.h>      
  3.  
  4.  
  5.  
  6.  
  7. BYTE* ConvertRGBToBMPBuffer ( BYTE* Buffer, int width, int height, long* newsize )
  8. {
  9.  
  10.     // first make sure the parameters are valid
  11.     if ( ( NULL == Buffer ) || ( width == 0 ) || ( height == 0 ) )
  12.         return NULL;
  13.  
  14.     // now we have to find with how many bytes
  15.     // we have to pad for the next DWORD boundary  
  16.  
  17.     int padding = 0;
  18.     int scanlinebytes = width * 3;
  19.     while ( ( scanlinebytes + padding ) % 4 != 0 )     // DWORD = 4 bytes
  20.         padding++;
  21.     // get the padded scanline width
  22.     int psw = scanlinebytes + padding;
  23.    
  24.     // we can already store the size of the new padded buffer
  25.     *newsize = height * psw;
  26.  
  27.     // and create new buffer
  28.     BYTE* newbuf = new BYTE[*newsize];
  29.    
  30.     // fill the buffer with zero bytes then we dont have to add
  31.     // extra padding zero bytes later on
  32.     memset ( newbuf, 0, *newsize );
  33.  
  34.     // now we loop trough all bytes of the original buffer,
  35.     // swap the R and B bytes and the scanlines
  36.     long bufpos = 0;  
  37.     long newpos = 0;
  38.     for ( int y = 0; y < height; y++ )
  39.         for ( int x = 0; x < 3 * width; x+=3 )
  40.         {
  41.             bufpos = y * 3 * width + x;     // position in original buffer
  42.             newpos = ( height - y - 1 ) * psw + x;           // position in padded buffer
  43.  
  44.             newbuf[newpos] = Buffer[bufpos+2];       // swap r and b
  45.             newbuf[newpos + 1] = Buffer[bufpos + 1]; // g stays
  46.             newbuf[newpos + 2] = Buffer[bufpos];     // swap b and r
  47.         }
  48.  
  49.     return newbuf;
  50. }
  51.  
  52. /***************************************************************
  53. BYTE* ConvertBMPToRGBBuffer ( BYTE* Buffer,
  54.         int width, int height )
  55.  
  56. This function takes as input the data array
  57. from a bitmap and its width and height.
  58. It then converts the bmp data into an RGB array.
  59. The calling function must delete both the input
  60. and output arrays.
  61. The size of the returned array will be
  62. width * height * 3
  63. On error the returb value is NULL, else the
  64. RGB array.
  65.  
  66.  
  67. The Buffer is expected to be the exact data read out
  68. from a .bmp file.  
  69. The function will swap it around, since images
  70. are stored upside-down in bmps.
  71. The BGR triplets from the image data will
  72. be converted to RGB.
  73. And finally the function removes padding bytes.
  74. The returned arraay consits then of
  75. width * height RGB triplets.
  76.  
  77. *****************************************************************/
  78.  
  79. BYTE* ConvertBMPToRGBBuffer ( BYTE* Buffer, int width, int height )
  80. {
  81.     // first make sure the parameters are valid
  82.     if ( ( NULL == Buffer ) || ( width == 0 ) || ( height == 0 ) )
  83.         return NULL;
  84.  
  85.     // find the number of padding bytes
  86.        
  87.     int padding = 0;
  88.     int scanlinebytes = width * 3;
  89.     while ( ( scanlinebytes + padding ) % 4 != 0 )     // DWORD = 4 bytes
  90.         padding++;
  91.     // get the padded scanline width
  92.     int psw = scanlinebytes + padding;
  93.  
  94.     // create new buffer
  95.     BYTE* newbuf = new BYTE[width*height*3];
  96.    
  97.     // now we loop trough all bytes of the original buffer,
  98.     // swap the R and B bytes and the scanlines
  99.     long bufpos = 0;  
  100.     long newpos = 0;
  101.     for ( int y = 0; y < height; y++ )
  102.         for ( int x = 0; x < 3 * width; x+=3 )
  103.         {
  104.             newpos = y * 3 * width + x;    
  105.             bufpos = ( height - y - 1 ) * psw + x;
  106.  
  107.             newbuf[newpos] = Buffer[bufpos + 2];      
  108.             newbuf[newpos + 1] = Buffer[bufpos+1];
  109.             newbuf[newpos + 2] = Buffer[bufpos];    
  110.         }
  111.  
  112.     return newbuf;
  113. }
  114.  
  115.  
  116.  
  117.  
  118.  
  119. /***********************************************
  120. bool LoadBMPIntoDC ( HDC hDC, LPCTSTR bmpfile )
  121.  
  122. Takes in a device context and the name of a
  123. bitmap to load. If an error occurs the function
  124. returns false, else the contents of the bmp
  125. are blitted to the HDC
  126.  
  127. ************************************************/
  128.  
  129. bool LoadBMPIntoDC ( HDC hDC, LPCTSTR bmpfile )
  130. {
  131.     // check if params are valid
  132.     if ( ( NULL == hDC  ) || ( NULL == bmpfile ) )
  133.         return false;      
  134.  
  135.     // load bitmap into a bitmap handle
  136.     HANDLE hBmp = LoadImage ( NULL, bmpfile, IMAGE_BITMAP, 0, 0,
  137.         LR_LOADFROMFILE );
  138.    
  139.     if ( NULL == hBmp )
  140.         return false;        // failed to load image
  141.  
  142.     // bitmaps can only be selected into memory dcs:
  143.     HDC dcmem = CreateCompatibleDC ( NULL );
  144.  
  145.     // now select bitmap into the memory dc
  146.     if ( NULL == SelectObject ( dcmem, hBmp ) )
  147.     {   // failed to load bitmap into device context
  148.         DeleteDC ( dcmem );
  149.         return false;
  150.     }
  151.  
  152.    
  153.     // now get the bmp size
  154.     BITMAP bm;
  155.     GetObject ( hBmp, sizeof(bm), &bm );
  156.     // and blit it to the visible dc
  157.     if ( BitBlt ( hDC, 0, 0, bm.bmWidth, bm.bmHeight, dcmem,
  158.         0, 0, SRCCOPY ) == 0 )
  159.     {   // failed the blit
  160.         DeleteDC ( dcmem );
  161.         return false;
  162.     }
  163.            
  164.     DeleteDC ( dcmem );  // clear up the memory dc
  165.    
  166.     return true;
  167. }
  168.  
  169.  
  170.  
  171. /***************************************************************
  172. bool SaveBMP ( BYTE* Buffer, int width, int height,
  173.         long paddedsize, LPCTSTR bmpfile )
  174.  
  175. Function takes a buffer of size <paddedsize>
  176. and saves it as a <width> * <height> sized bitmap
  177. under the supplied filename.
  178. On error the return value is false.
  179.  
  180. ***************************************************************/
  181.  
  182. bool SaveBMP ( BYTE* Buffer, int width, int height, long paddedsize, LPCTSTR bmpfile )
  183. {
  184.     // declare bmp structures
  185.     BITMAPFILEHEADER bmfh;
  186.     BITMAPINFOHEADER info;
  187.    
  188.     // andinitialize them to zero
  189.     memset ( &bmfh, 0, sizeof (BITMAPFILEHEADER ) );
  190.     memset ( &info, 0, sizeof (BITMAPINFOHEADER ) );
  191.    
  192.     // fill the fileheader with data
  193.     bmfh.bfType = 0x4d42;       // 0x4d42 = 'BM'
  194.     bmfh.bfReserved1 = 0;
  195.     bmfh.bfReserved2 = 0;
  196.     bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
  197.     bmfh.bfOffBits = 0x36;      // number of bytes to start of bitmap bits
  198.    
  199.     // fill the infoheader
  200.  
  201.     info.biSize = sizeof(BITMAPINFOHEADER);
  202.     info.biWidth = width;
  203.     info.biHeight = height;
  204.     info.biPlanes = 1;          // we only have one bitplane
  205.     info.biBitCount = 24;       // RGB mode is 24 bits
  206.     info.biCompression = BI_RGB;   
  207.     info.biSizeImage = 0;       // can be 0 for 24 bit images
  208.     info.biXPelsPerMeter = 0x0ec4;     // paint and PSP use this values
  209.     info.biYPelsPerMeter = 0x0ec4;    
  210.     info.biClrUsed = 0;         // we are in RGB mode and have no palette
  211.     info.biClrImportant = 0;    // all colors are important
  212.  
  213.     // now we open the file to write to
  214.     HANDLE file = CreateFile ( bmpfile , GENERIC_WRITE, FILE_SHARE_READ,
  215.          NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  216.     if ( file == NULL )
  217.     {
  218.         CloseHandle ( file );
  219.         return false;
  220.     }
  221.    
  222.     // write file header
  223.     unsigned long bwritten;
  224.     if ( WriteFile ( file, &bmfh, sizeof ( BITMAPFILEHEADER ), &bwritten, NULL ) == false )
  225.     {  
  226.         CloseHandle ( file );
  227.         return false;
  228.     }
  229.     // write infoheader
  230.     if ( WriteFile ( file, &info, sizeof ( BITMAPINFOHEADER ), &bwritten, NULL ) == false )
  231.     {  
  232.         CloseHandle ( file );
  233.         return false;
  234.     }
  235.     // write image data
  236.     if ( WriteFile ( file, Buffer, paddedsize, &bwritten, NULL ) == false )
  237.     {  
  238.         CloseHandle ( file );
  239.         return false;
  240.     }
  241.    
  242.     // and close file
  243.     CloseHandle ( file );
  244.  
  245.     return true;
  246. }
  247.  
  248. /*******************************************************************
  249. BYTE* LoadBMP ( int* width, int* height, long* size
  250.         LPCTSTR bmpfile )
  251.  
  252. The function loads a 24 bit bitmap from bmpfile,
  253. stores it's width and height in the supplied variables
  254. and the whole size of the data (padded) in <size>
  255. and returns a buffer of the image data
  256.  
  257. On error the return value is NULL.
  258.  
  259.   NOTE: make sure you [] delete the returned array at end of
  260.         program!!!
  261. *******************************************************************/
  262.  
  263. BYTE* LoadBMP ( int* width, int* height, long* size, LPCTSTR bmpfile )
  264. {
  265.     // declare bitmap structures
  266.     BITMAPFILEHEADER bmpheader;
  267.     BITMAPINFOHEADER bmpinfo;
  268.     // value to be used in ReadFile funcs
  269.     DWORD bytesread;
  270.     // open file to read from
  271.     HANDLE file = CreateFile ( bmpfile , GENERIC_READ, FILE_SHARE_READ,
  272.          NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
  273.     if ( NULL == file )
  274.         return NULL; // coudn't open file
  275.    
  276.    
  277.     // read file header
  278.     if ( ReadFile ( file, &bmpheader, sizeof ( BITMAPFILEHEADER ), &bytesread, NULL ) == false )
  279.     {
  280.         CloseHandle ( file );
  281.         return NULL;
  282.     }
  283.  
  284.     //read bitmap info
  285.  
  286.     if ( ReadFile ( file, &bmpinfo, sizeof ( BITMAPINFOHEADER ), &bytesread, NULL ) == false )
  287.     {
  288.         CloseHandle ( file );
  289.         return NULL;
  290.     }
  291.    
  292.     // check if file is actually a bmp
  293.     if ( bmpheader.bfType != 'MB' )
  294.     {
  295.         CloseHandle ( file );
  296.         return NULL;
  297.     }
  298.  
  299.     // get image measurements
  300.     *width   = bmpinfo.biWidth;
  301.     *height  = abs ( bmpinfo.biHeight );
  302.  
  303.     // check if bmp is uncompressed
  304.     if ( bmpinfo.biCompression != BI_RGB )
  305.     {
  306.         CloseHandle ( file );
  307.         return NULL;
  308.     }
  309.  
  310.     // check if we have 24 bit bmp
  311.     if ( bmpinfo.biBitCount != 24 )
  312.     {
  313.         CloseHandle ( file );
  314.         return NULL;
  315.     }
  316.    
  317.  
  318.     // create buffer to hold the data
  319.     *size = bmpheader.bfSize - bmpheader.bfOffBits;
  320.     BYTE* Buffer = new BYTE[ *size ];
  321.     // move file pointer to start of bitmap data
  322.     SetFilePointer ( file, bmpheader.bfOffBits, NULL, FILE_BEGIN );
  323.     // read bmp data
  324.     if ( ReadFile ( file, Buffer, *size, &bytesread, NULL ) == false )
  325.     {
  326.         delete [] Buffer;
  327.         CloseHandle ( file );
  328.         return NULL;
  329.     }
  330.  
  331.     // everything successful here: close file and return buffer
  332.    
  333.     CloseHandle ( file );
  334.  
  335.     return Buffer;
  336. }
  337.  
  338. void TestBMPCopy (LPCTSTR input, LPCTSTR output)
  339. {
  340.     int x, y;
  341.     long s;
  342.     BYTE* b = LoadBMP ( &x, &y, &s, input );
  343.     SaveBMP ( b, x, y, s, output );
  344.     delete [] b;
  345. }
  346.  
  347. void TestBMPCopy2(LPCTSTR input, LPCTSTR output)
  348. {
  349.     int x, y;
  350.     long s, s2;
  351.     BYTE* a = LoadBMP ( &x, &y, &s, input );
  352.     BYTE* b = ConvertBMPToRGBBuffer ( a, x, y );
  353.     BYTE* c = ConvertRGBToBMPBuffer ( b, x, y, &s2 );  
  354.     SaveBMP ( c, x, y, s2, output );
  355.     delete [] a;
  356.     delete [] b;
  357.     delete [] c;
  358. }
  359.  
  360. void main ()
  361. {
  362.     // TestBMPCopy (L"test.bmp", L"copy.bmp");
  363.     TestBMPCopy2 (L"test.bmp", L"copy.bmp");
  364. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement