//+------------------------------------------------------------------+ //| FileBMP.mqh | //| Copyright 2000-2025, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include //+------------------------------------------------------------------+ //| 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)