BVB Source Codes

CRYENGINE Show BMPHelper.cpp Source code

Return Download CRYENGINE: download BMPHelper.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   BMPHelper.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/11/2006 by AlexL
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: BMPHelper
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include <CryCore/Platform/platform.h>
  16. #include "BMPHelper.h"
  17. #include "RichSaveGameTypes.h"
  18.  
  19. #if defined(NEED_ENDIAN_SWAP)
  20. // big endian
  21. static const unsigned short BF_TYPE = 0x424D;            /* 0x42 == 'B', 0x4D == 'M' */
  22. #else
  23. // little endian
  24. static const unsigned short BF_TYPE = 0x4D42;            /* 0x42 == 'B', 0x4D == 'M' */
  25. #endif
  26.  
  27. #define COMPRESSION_BI_RGB 0
  28.  
  29. namespace BMPHelper
  30. {
  31. size_t CalcBMPSize(int width, int height, int depth)
  32. {
  33.         int bytesPerLine = width * depth;
  34.         if (bytesPerLine & 0x0003)
  35.         {
  36.                 bytesPerLine |= 0x0003;
  37.                 ++bytesPerLine;
  38.         }
  39.         size_t totalSize = bytesPerLine * height + sizeof(CryBitmapFileHeader) + sizeof(CryBitmapInfoHeader);
  40.         return totalSize;
  41. }
  42.  
  43. // pByteData: B G R A
  44. // if pFile != 0 writes into file. otherwise opens a new file with filename 'filename'
  45. // returns size of written bytes in outFileSize
  46. // can be optimized quite a bit
  47. bool InternalSaveBMP(const char* filename, FILE* pFile, uint8* pByteData, int width, int height, int depth, bool inverseY)
  48. {
  49.         CryBitmapFileHeader bitmapfileheader;
  50.         CryBitmapInfoHeader bitmapinfoheader;
  51.  
  52.         ICryPak* pCryPak = gEnv->pCryPak;
  53.         const bool bFileGiven = pFile != 0;
  54.         if (bFileGiven == false)
  55.                 pFile = pCryPak->FOpen(filename, "wb");
  56.         if (pFile == 0)
  57.                 return false;
  58.  
  59.         int origBytesPerLine = width * depth;
  60.         int bytesPerLine = origBytesPerLine;
  61.         if (bytesPerLine & 0x0003)
  62.         {
  63.                 bytesPerLine |= 0x0003;
  64.                 ++bytesPerLine;
  65.         }
  66.         int padBytes = bytesPerLine - origBytesPerLine;   // how many pad-bytes
  67.  
  68.         uint8* pTempImage = new uint8[bytesPerLine * height]; // optimize and write one line only
  69.  
  70.         for (int y = 0; y < height; y++)
  71.         {
  72.                 int src_y = y;
  73.                 if (inverseY)
  74.                         src_y = (height - 1) - y;
  75.  
  76.                 uint8* pDstLine = pTempImage + y * bytesPerLine;
  77.                 uint8* pSrcLine = pByteData + src_y * origBytesPerLine;
  78.                 if (depth == 3)
  79.                 {
  80.                         uint8 r, g, b;
  81.                         for (int x = 0; x < width; x++)
  82.                         {
  83.                                 b = *pSrcLine++;
  84.                                 g = *pSrcLine++;
  85.                                 r = *pSrcLine++;
  86.                                 *pDstLine++ = b;
  87.                                 *pDstLine++ = g;
  88.                                 *pDstLine++ = r;
  89.                         }
  90.                 }
  91.                 else
  92.                 {
  93.                         uint8 r, g, b, a;
  94.                         for (int x = 0; x < width; x++)
  95.                         {
  96.                                 b = *pSrcLine++;
  97.                                 g = *pSrcLine++;
  98.                                 r = *pSrcLine++;
  99.                                 a = *pSrcLine++;
  100.                                 *pDstLine++ = b;
  101.                                 *pDstLine++ = g;
  102.                                 *pDstLine++ = r;
  103.                                 *pDstLine++ = a;
  104.                         }
  105.                 }
  106.                 for (int n = 0; n < padBytes; ++n)
  107.                 {
  108.                         *pDstLine++ = 0;
  109.                 }
  110.         }
  111.  
  112.         // Fill in bitmap structures
  113.         bitmapfileheader.bfType = BF_TYPE;
  114.         bitmapfileheader.bfSize = bytesPerLine * height + sizeof(CryBitmapFileHeader) + sizeof(CryBitmapInfoHeader);
  115.         bitmapfileheader.bfReserved1 = 0;
  116.         bitmapfileheader.bfReserved2 = 0;
  117.         bitmapfileheader.bfOffBits = sizeof(CryBitmapFileHeader) + sizeof(CryBitmapInfoHeader);
  118.         bitmapinfoheader.biSize = sizeof(CryBitmapInfoHeader);
  119.         bitmapinfoheader.biWidth = width;
  120.         bitmapinfoheader.biHeight = height;
  121.         bitmapinfoheader.biPlanes = 1;
  122.         bitmapinfoheader.biBitCount = depth * 8;
  123.         bitmapinfoheader.biCompression = COMPRESSION_BI_RGB;
  124.         bitmapinfoheader.biSizeImage = 0;
  125.         bitmapinfoheader.biXPelsPerMeter = 0;
  126.         bitmapinfoheader.biYPelsPerMeter = 0;
  127.         bitmapinfoheader.biClrUsed = 0;
  128.         bitmapinfoheader.biClrImportant = 0;
  129.  
  130.         pCryPak->FWrite(&bitmapfileheader, 1, pFile);
  131.         pCryPak->FWrite(&bitmapinfoheader, 1, pFile);
  132.         pCryPak->FWrite(pTempImage, bytesPerLine * height, 1, pFile);
  133.  
  134.         if (bFileGiven == false)
  135.                 pCryPak->FClose(pFile);
  136.  
  137.         delete[] pTempImage;
  138.  
  139.         // Success
  140.         return true;
  141.  
  142. }
  143.  
  144. // fills data with BGR or BGRA
  145. // always top->bottom
  146. bool InternalLoadBMP(const char* filename, FILE* pFile, uint8* pByteData, int& width, int& height, int& depth, bool bForceInverseY)
  147. {
  148.         // todo: cleanup for pFile
  149.         struct Cleanup
  150.         {
  151.                 Cleanup() : m_pFile(0), m_bCloseFile(false), m_bRestoreCur(false), m_offset(0) {}
  152.                 ~Cleanup()
  153.                 {
  154.                         if (m_pFile)
  155.                         {
  156.                                 if (m_bRestoreCur)
  157.                                         gEnv->pCryPak->FSeek(m_pFile, m_offset, SEEK_SET);
  158.                                 if (m_bCloseFile)
  159.                                         gEnv->pCryPak->FClose(m_pFile);
  160.                         }
  161.                 }
  162.                 void SetFile(FILE* pFile, bool bClose, bool bRestoreCur)
  163.                 {
  164.                         m_pFile = pFile;
  165.                         m_bCloseFile = bClose;
  166.                         m_bRestoreCur = bRestoreCur;
  167.                         if (m_pFile && m_bRestoreCur)
  168.                                 m_offset = gEnv->pCryPak->FTell(m_pFile);
  169.                 }
  170.         protected:
  171.                 FILE* m_pFile;
  172.                 bool  m_bCloseFile;
  173.                 bool  m_bRestoreCur;
  174.                 long  m_offset;
  175.         };
  176.  
  177.         Cleanup cleanup;   // potentially close the file on return (if pFile was given, do nothing)
  178.         CryBitmapFileHeader bitmapfileheader;
  179.         CryBitmapInfoHeader bitmapinfoheader;
  180.  
  181.         memset(&bitmapfileheader, 0, sizeof(CryBitmapFileHeader));
  182.         memset(&bitmapinfoheader, 0, sizeof(CryBitmapInfoHeader));
  183.  
  184.         ICryPak* pCryPak = gEnv->pCryPak;
  185.         const bool bFileGiven = pFile != 0;
  186.         if (bFileGiven == false)
  187.                 pFile = pCryPak->FOpen(filename, "rb");
  188.         if (pFile == 0)
  189.                 return false;
  190.  
  191.         cleanup.SetFile(pFile, !bFileGiven, bFileGiven);
  192.  
  193.         size_t els = pCryPak->FRead(&bitmapfileheader, 1, pFile);
  194.         if (els != 1)
  195.                 return false;
  196.  
  197.         els = pCryPak->FRead(&bitmapinfoheader, 1, pFile);
  198.         if (els != 1)
  199.                 return false;
  200.  
  201.         if (bitmapfileheader.bfType != BF_TYPE)
  202.                 return false;
  203.  
  204.         if (bitmapinfoheader.biCompression != COMPRESSION_BI_RGB)
  205.                 return false;
  206.  
  207.         if (bitmapinfoheader.biBitCount != 24 && bitmapinfoheader.biBitCount != 32)
  208.                 return false;
  209.  
  210.         if (bitmapinfoheader.biPlanes != 1)
  211.                 return false;
  212.  
  213.         int imgWidth = bitmapinfoheader.biWidth;
  214.         int imgHeight = bitmapinfoheader.biHeight;
  215.         int imgDepth = bitmapinfoheader.biBitCount == 24 ? 3 : 4;
  216.  
  217.         int imgBytesPerLine = imgWidth * imgDepth;
  218.         int fileBytesPerLine = imgBytesPerLine;
  219.         if (fileBytesPerLine & 0x0003)
  220.         {
  221.                 fileBytesPerLine |= 0x0003;
  222.                 ++fileBytesPerLine;
  223.         }
  224.         size_t prologSize = sizeof(CryBitmapFileHeader) + sizeof(CryBitmapInfoHeader);
  225.         size_t bufSize = bitmapfileheader.bfSize - prologSize;
  226.  
  227.         // some BMPs from Adobe PhotoShop seem 2 bytes longer
  228.         if (bufSize != fileBytesPerLine * imgHeight && bufSize != (fileBytesPerLine * imgHeight) + 2)
  229.                 return false;
  230.  
  231.         bool bFlipY = true;
  232.         width = imgWidth;
  233.         height = imgHeight;
  234.         if (height < 0)     // height > 0: bottom->top, height < 0: top->bottom, no flip necessary
  235.         {
  236.                 height = -height;
  237.                 bFlipY = false;
  238.         }
  239.         depth = imgDepth;
  240.  
  241.         if (pByteData == 0)   // only requested dimensions
  242.                 return true;
  243.  
  244.         uint8* pTempImage = new uint8[bufSize];
  245.         if (pTempImage == 0)
  246.                 return false;
  247.  
  248.         els = pCryPak->FReadRaw(pTempImage, 1, bufSize, pFile);
  249.         if (els != bufSize)
  250.         {
  251.                 delete[] pTempImage;
  252.                 return false;
  253.         }
  254.  
  255.         if (bForceInverseY)
  256.                 bFlipY = !bFlipY;
  257.  
  258.         // read all rows
  259.         uint8* pSrcLine = pTempImage;
  260.         for (int y = 0; y < imgHeight; ++y)
  261.         {
  262.                 int dstY = y;
  263.                 if (bFlipY)
  264.                         dstY = imgHeight - y - 1;
  265.  
  266.                 uint8* pDstLine = pByteData + dstY * imgBytesPerLine;
  267.                 memcpy(pDstLine, pSrcLine, imgBytesPerLine);
  268.                 pSrcLine += fileBytesPerLine;
  269.         }
  270.  
  271.         delete[] pTempImage;
  272.  
  273.         // Success
  274.         return true;
  275. }
  276.  
  277. bool LoadBMP(const char* filename, uint8* pByteData, int& width, int& height, int& depth, bool bForceInverseY)
  278. {
  279.         return InternalLoadBMP(filename, 0, pByteData, width, height, depth, bForceInverseY);
  280. }
  281.  
  282. bool LoadBMP(FILE* pFile, uint8* pByteData, int& width, int& height, int& depth, bool bForceInverseY)
  283. {
  284.         return InternalLoadBMP("", pFile, pByteData, width, height, depth, bForceInverseY);
  285. }
  286.  
  287. bool SaveBMP(const char* filename, uint8* pByteData, int width, int height, int depth, bool flipY)
  288. {
  289.         return InternalSaveBMP(filename, 0, pByteData, width, height, depth, flipY);
  290. }
  291.  
  292. bool SaveBMP(FILE* pFile, uint8* pByteData, int width, int height, int depth, bool flipY)
  293. {
  294.         return InternalSaveBMP("", pFile, pByteData, width, height, depth, flipY);
  295. }
  296. };
  297.  
downloadBMPHelper.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top