183 lines
6.7 KiB
MQL5
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;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|