home *** CD-ROM | disk | FTP | other *** search
/ Windows Game Programming for Dummies (2nd Edition) / WinGamProgFD.iso / mac / Source / GPCHAP10 / PROG10_4.CPP < prev    next >
C/C++ Source or Header  |  2002-04-27  |  7KB  |  222 lines

  1. // PROG10_4.CPP - bitmap loading software
  2.  
  3. // INCLUDES ///////////////////////////////////////////////
  4.  
  5. #define WIN32_LEAN_AND_MEAN  
  6.  
  7. #include <windows.h>  
  8. #include <windowsx.h>  
  9. #include <iostream.h>
  10. #include <stdlib.h>
  11. #include <stdarg.h>
  12. #include <stdio.h>
  13. #include <math.h>
  14. #include <io.h>
  15. #include <fcntl.h>
  16. #include <signal.h>
  17. #include <float.h>
  18.  
  19. // this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
  20. #define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))
  21.  
  22. // this builds a 16 bit color value in 5.6.5 format (green dominate mode)
  23. #define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))
  24.  
  25. #define BITMAP_ID        0x4D42       // this is the universal id for a bitmap
  26.  
  27. // container structure for bitmaps .BMP file
  28. typedef struct BITMAP_FILE_TAG
  29.         {
  30.         BITMAPFILEHEADER bitmapfileheader;  // this contains the bitmapfile header
  31.         BITMAPINFOHEADER bitmapinfoheader;  // this is all the info including the palette
  32.         PALETTEENTRY     palette[256];      // we will store the palette here
  33.         UCHAR            *buffer;           // this is a pointer to the data
  34.  
  35.         } BITMAP_FILE, *BITMAP_FILE_PTR;
  36.  
  37. //////////////////////////////////////////////////////////////////////////////
  38.  
  39. int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
  40. {
  41. // this function opens a bitmap file and loads the data into bitmap
  42.  
  43. int file_handle,       // the file handle
  44.     index;             // looping index
  45.  
  46. UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
  47.     
  48. OFSTRUCT file_data;    // the file data information
  49.  
  50. // open the file if it exists
  51. if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
  52.    return(0);
  53.  
  54. // now load the bitmap file header
  55. _lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
  56.  
  57. // test if this is a bitmap file
  58. if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
  59.    {
  60.    // close the file
  61.    _lclose(file_handle);
  62.  
  63.    // return error
  64.    return(0);
  65.    } // end if
  66.  
  67. // now we know this is a bitmap, so read in all the sections
  68.  
  69. // first the bitmap infoheader
  70.  
  71. // now load the bitmap file header
  72. _lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
  73.  
  74. // now load the color palette if there is one
  75. if (bitmap->bitmapinfoheader.biBitCount == 8)
  76.    {
  77.    _lread(file_handle, &bitmap->palette,256*sizeof(PALETTEENTRY));
  78.  
  79.    // now set all the flags in the palette correctly and fix the reversed 
  80.    // BGR RGBQUAD data format
  81.    for (index=0; index<256; index++)
  82.        {
  83.        // reverse the red and green fields
  84.        int temp_color = bitmap->palette[index].peRed;
  85.        bitmap->palette[index].peRed  = bitmap->palette[index].peBlue;
  86.        bitmap->palette[index].peBlue = temp_color;
  87.        
  88.        // always set the flags word to this
  89.        bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
  90.        } // end for index
  91.  
  92.     } // end if
  93.  
  94. // finally the image data itself
  95. _lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
  96.  
  97. // now read in the image, if the image is 8 or 16 bit then simply read it
  98. // but if its 24 bit then read it into a temporary area and then convert
  99. // it to a 16 bit image
  100.  
  101. if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16)
  102.    {
  103.    // allocate the memory for the image
  104.    if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
  105.       {
  106.       // close the file
  107.       _lclose(file_handle);
  108.  
  109.       // return error
  110.       return(0);
  111.       } // end if
  112.  
  113.    // now read it in
  114.    _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
  115.  
  116.    } // end if
  117. else
  118.    {
  119.    // this must be a 24 bit image, load it in and convert it to 16 bit
  120.    printf("\nconverting 24 bit image...");
  121.  
  122.    // allocate temporary buffer
  123.    if (!(temp_buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
  124.       {
  125.       // close the file
  126.       _lclose(file_handle);
  127.  
  128.       // return error
  129.       return(0);
  130.       } // end if
  131.    
  132.    // allocate final 16 bit storage buffer
  133.    if (!(bitmap->buffer = (UCHAR *)malloc(2 * bitmap->bitmapinfoheader.biWidth * bitmap->bitmapinfoheader.biHeight)))
  134.       {
  135.       // close the file
  136.       _lclose(file_handle);
  137.  
  138.       // release working buffer
  139.       free(temp_buffer);
  140.  
  141.       // return error
  142.       return(0);
  143.       } // end if
  144.  
  145.    // now read it in
  146.    _lread(file_handle,temp_buffer,bitmap->bitmapinfoheader.biSizeImage);
  147.  
  148.    // now convert each 24 bit RGB value into a 16 bit value
  149.    for (index=0; index<bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight; index++)
  150.        {
  151.        // extract RGB components (note they are in memory BGR)
  152.        // also, assume 5.6.5 format, so scale appropriately
  153.        UCHAR red    = (temp_buffer[index*3 + 2] >> 3), // 5 bits
  154.              green  = (temp_buffer[index*3 + 1] >> 2), // 6 bits, change to 3 for 5 bits
  155.              blue   = (temp_buffer[index*3 + 0] >> 3); // 5 bits
  156.  
  157.        // build up 16 bit color word assume 5.6.5 format
  158.        USHORT color = _RGB16BIT565(red,green,blue);
  159.  
  160.        // write color to buffer
  161.        ((USHORT *)bitmap->buffer)[index] = color;
  162.  
  163.        } // end for index
  164.  
  165.    } // end if
  166.  
  167. // write the file info out 
  168. printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
  169.         filename,
  170.         bitmap->bitmapinfoheader.biSizeImage,
  171.         bitmap->bitmapinfoheader.biWidth,
  172.         bitmap->bitmapinfoheader.biHeight,
  173.         bitmap->bitmapinfoheader.biBitCount,
  174.         bitmap->bitmapinfoheader.biClrUsed,
  175.         bitmap->bitmapinfoheader.biClrImportant);
  176.  
  177. // close the file
  178. _lclose(file_handle);
  179.  
  180. // return success
  181. return(1);
  182.  
  183. } // end Load_Bitmap_File
  184.  
  185. ///////////////////////////////////////////////////////////////////////////////
  186.  
  187. int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
  188. {
  189. // this function releases all memory associated with "bitmap"
  190. if (bitmap->buffer)
  191.    {
  192.    // release memory
  193.    free(bitmap->buffer);
  194.  
  195.    // reset pointer
  196.    bitmap->buffer = NULL;
  197.  
  198.    } // end if
  199.  
  200. // return success
  201. return(1);
  202.  
  203. } // end Unload_Bitmap_File
  204.  
  205. ///////////////////////////////////////////////////////////////////////////////
  206.  
  207. void main(void)
  208. {
  209. char filename[80];
  210. BITMAP_FILE bitmap;
  211.  
  212. // load in .bmp files
  213. while(1)
  214.      {
  215.      printf("\nenter filename to load?");
  216.      scanf("%s", filename);
  217.      Load_Bitmap_File(&bitmap,filename);
  218.      Unload_Bitmap_File(&bitmap);
  219.      } // end while
  220.  
  221. } // end main
  222.