mql-for-begginers/Include/Files/FileBMP.mqh
2025-07-22 18:30:17 +03:00

183 lines
6.7 KiB
MQL5

//+------------------------------------------------------------------+
//| FileBMP.mqh |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#include <Object.mqh>
//+------------------------------------------------------------------+
//| Bitmap headers |
//+------------------------------------------------------------------+
struct BITMAPFILEHEADER
{
ushort bfType;
uint bfSize;
ushort bfReserved1;
ushort bfReserved2;
uint bfOffBits;
};
struct BITMAPINFOHEADER
{
uint biSize;
int biWidth;
int biHeight;
ushort biPlanes;
ushort biBitCount;
uint biCompression;
uint biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
uint biClrUsed;
uint biClrImportant;
};
#define BM 0x4D42
//+------------------------------------------------------------------+
//| Class CFileBMP |
//| Purpose: Special class to read and write bmp file |
//| Derives from class CObject. |
//+------------------------------------------------------------------+
class CFileBMP : public CObject
{
protected:
int m_handle;
BITMAPFILEHEADER m_file_header;
BITMAPINFOHEADER m_info_header;
public:
CFileBMP(void);
~CFileBMP(void);
int OpenWrite(const string file_name,bool common_flag=false);
int OpenRead(const string file_name,bool common_flag=false);
int Write32BitsArray(uint& uint_array[],const int width,const int height);
int Read32BitsArray(uint& uint_array[],int& width,int& height);
void Close(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CFileBMP::CFileBMP(void) : m_handle(INVALID_HANDLE)
{
ZeroMemory(m_file_header);
ZeroMemory(m_info_header);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CFileBMP::~CFileBMP(void)
{
Close();
}
//+------------------------------------------------------------------+
//| Open the file |
//+------------------------------------------------------------------+
int CFileBMP::OpenWrite(const string file_name,bool common_flag)
{
Close();
//--- action
int open_flags=FILE_BIN|FILE_WRITE|FILE_SHARE_READ|FILE_SHARE_WRITE;
if(common_flag)
open_flags|=FILE_COMMON;
//--- open
m_handle=FileOpen(file_name,open_flags);
//--- result
return(m_handle);
}
//+------------------------------------------------------------------+
//| Open the file |
//+------------------------------------------------------------------+
int CFileBMP::OpenRead(const string file_name,bool common_flag)
{
Close();
//--- action
int open_flags=FILE_BIN|FILE_READ|FILE_SHARE_READ|FILE_SHARE_WRITE;
if(common_flag)
open_flags|=FILE_COMMON;
//--- open
m_handle=FileOpen(file_name,open_flags);
//--- check bmp headers
if(m_handle!=INVALID_HANDLE)
{
uint fileheader_size=FileReadStruct(m_handle,m_file_header);
uint infoheader_size=FileReadStruct(m_handle,m_info_header);
//--- it should be a simple 32-bit bmp
if(fileheader_size!=sizeof(m_file_header) ||
infoheader_size!=sizeof(m_info_header) ||
m_file_header.bfType!=BM ||
m_file_header.bfOffBits!=sizeof(m_file_header)+sizeof(m_info_header) ||
m_info_header.biBitCount!=32 ||
m_info_header.biClrUsed!=0)
Close();
}
//--- result
return(m_handle);
}
//+------------------------------------------------------------------+
//| Write the file |
//+------------------------------------------------------------------+
int CFileBMP::Write32BitsArray(uint& uint_array[],const int width,const int height)
{
if(m_handle==INVALID_HANDLE)
return(-1);
//--- check size
int size=width*height;
if(size==0)
return(0);
if(size<0)
size=-size;
if(ArraySize(uint_array)<size)
return(-2);
//--- prepare headers
ZeroMemory(m_file_header);
ZeroMemory(m_info_header);
m_file_header.bfType=BM;
m_file_header.bfSize=sizeof(m_file_header)+sizeof(m_info_header)+size*sizeof(uint);
m_file_header.bfOffBits=sizeof(m_file_header)+sizeof(m_info_header);
m_info_header.biSize=sizeof(m_info_header);
m_info_header.biWidth=width;
m_info_header.biHeight=height;
m_info_header.biPlanes=1;
m_info_header.biBitCount=32;
m_info_header.biSizeImage=size*32;
//--- write bmp-file
FileSeek(m_handle,0,SEEK_SET);
FileWriteStruct(m_handle,m_file_header);
FileWriteStruct(m_handle,m_info_header);
uint written=FileWriteArray(m_handle,uint_array,0,size);
//--- bytes written
return((int)written*sizeof(uint));
}
//+------------------------------------------------------------------+
//| Read the file |
//+------------------------------------------------------------------+
int CFileBMP::Read32BitsArray(uint& uint_array[],int& width,int& height)
{
if(m_handle==INVALID_HANDLE)
return(-1);
//--- store dimensions from header
width=m_info_header.biWidth;
height=m_info_header.biHeight;
//--- check size
int size=width*height;
if(size==0)
return(0);
if(size<0)
size=-size;
//--- read bmp-file
FileSeek(m_handle,sizeof(m_file_header)+sizeof(m_info_header),SEEK_SET);
uint read=FileReadArray(m_handle,uint_array,0,size);
//--- bytes read
return((int)read*sizeof(uint));
}
//+------------------------------------------------------------------+
//| Close the file |
//+------------------------------------------------------------------+
void CFileBMP::Close(void)
{
//--- check handle
if(m_handle!=INVALID_HANDLE)
{
FileClose(m_handle);
m_handle=INVALID_HANDLE;
}
}
//+------------------------------------------------------------------+