Reduced resource usage.

This commit is contained in:
spx 2011-02-07 09:38:27 +00:00
parent f505c30828
commit 1228e243cc
10 changed files with 165 additions and 133 deletions

View File

@ -31,6 +31,11 @@
#define Li2Double(x) ((double)((x).QuadPart)) #define Li2Double(x) ((double)((x).QuadPart))
#define Ft2Double(x) ((double)((x).dwHighDateTime) * 4.294967296E9 + (double)((x).dwLowDateTime)) #define Ft2Double(x) ((double)((x).dwHighDateTime) * 4.294967296E9 + (double)((x).dwLowDateTime))
PROCNTQSI CMeasureCPU::c_NtQuerySystemInformation = NULL;
PROCGST CMeasureCPU::c_GetSystemTimes = NULL;
int CMeasureCPU::c_NumOfProcessors = 0;
ULONG CMeasureCPU::c_BufferSize = 0;
// ntdll!NtQuerySystemInformation (NT specific!) // ntdll!NtQuerySystemInformation (NT specific!)
// //
// The function copies the system information of the // The function copies the system information of the
@ -57,15 +62,24 @@
*/ */
CMeasureCPU::CMeasureCPU(CMeterWindow* meterWindow) : CMeasure(meterWindow), CMeasureCPU::CMeasureCPU(CMeterWindow* meterWindow) : CMeasure(meterWindow),
m_FirstTime(true), m_FirstTime(true),
m_Processor(), m_Processor()
m_NtQuerySystemInformation((PROCNTQSI)GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation")),
m_GetSystemTimes((PROCGST)GetProcAddress(GetModuleHandle(L"kernel32"), "GetSystemTimes"))
{ {
m_MaxValue = 100.0; m_MaxValue = 100.0;
if (c_NtQuerySystemInformation == NULL)
{
c_NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation");
}
if (c_GetSystemTimes == NULL)
{
c_GetSystemTimes = (PROCGST)GetProcAddress(GetModuleHandle(L"kernel32"), "GetSystemTimes");
}
if (c_NumOfProcessors == 0)
{
SYSTEM_INFO systemInfo = {0}; SYSTEM_INFO systemInfo = {0};
GetSystemInfo(&systemInfo); GetSystemInfo(&systemInfo);
m_NumOfProcessors = (int)systemInfo.dwNumberOfProcessors; c_NumOfProcessors = (int)systemInfo.dwNumberOfProcessors;
}
} }
/* /*
@ -90,7 +104,7 @@ void CMeasureCPU::ReadConfig(CConfigParser& parser, const WCHAR* section)
int processor = parser.ReadInt(section, L"Processor", 0); int processor = parser.ReadInt(section, L"Processor", 0);
if (processor < 0 || processor > m_NumOfProcessors) if (processor < 0 || processor > c_NumOfProcessors)
{ {
LogWithArgs(LOG_WARNING, L"[%s] Invalid Processor: %i", section, processor); LogWithArgs(LOG_WARNING, L"[%s] Invalid Processor: %i", section, processor);
@ -105,9 +119,9 @@ void CMeasureCPU::ReadConfig(CConfigParser& parser, const WCHAR* section)
if (m_FirstTime) if (m_FirstTime)
{ {
if (m_Processor == 0 && m_GetSystemTimes == NULL) if (m_Processor == 0 && c_GetSystemTimes == NULL)
{ {
m_OldTime.assign(m_NumOfProcessors * 2, 0.0); m_OldTime.assign(c_NumOfProcessors * 2, 0.0);
} }
else else
{ {
@ -126,23 +140,23 @@ bool CMeasureCPU::Update()
{ {
if (!CMeasure::PreUpdate()) return false; if (!CMeasure::PreUpdate()) return false;
if (m_Processor == 0 && m_GetSystemTimes) if (m_Processor == 0 && c_GetSystemTimes)
{ {
BOOL status; BOOL status;
FILETIME ftIdleTime, ftKernelTime, ftUserTime; FILETIME ftIdleTime, ftKernelTime, ftUserTime;
// get new CPU's idle/kernel/user time // get new CPU's idle/kernel/user time
status = m_GetSystemTimes(&ftIdleTime, &ftKernelTime, &ftUserTime); status = c_GetSystemTimes(&ftIdleTime, &ftKernelTime, &ftUserTime);
if (status == 0) return false; if (status == 0) return false;
CalcUsage(Ft2Double(ftIdleTime), CalcUsage(Ft2Double(ftIdleTime),
Ft2Double(ftKernelTime) + Ft2Double(ftUserTime)); Ft2Double(ftKernelTime) + Ft2Double(ftUserTime));
} }
else if (m_NtQuerySystemInformation) else if (c_NtQuerySystemInformation)
{ {
LONG status; LONG status;
BYTE* buf = NULL; ULONG bufSize = c_BufferSize;
ULONG bufSize = 0; BYTE* buf = (bufSize > 0) ? new BYTE[bufSize] : NULL;
int loop = 0; int loop = 0;
@ -150,16 +164,16 @@ bool CMeasureCPU::Update()
{ {
ULONG size = 0; ULONG size = 0;
status = m_NtQuerySystemInformation(SystemProcessorPerformanceInformation, buf, bufSize, &size); status = c_NtQuerySystemInformation(SystemProcessorPerformanceInformation, buf, bufSize, &size);
if (status == STATUS_SUCCESS) break; if (status == STATUS_SUCCESS || status != STATUS_INFO_LENGTH_MISMATCH) break;
if (status == STATUS_INFO_LENGTH_MISMATCH) else // status == STATUS_INFO_LENGTH_MISMATCH
{ {
if (size == 0) // Returned required buffer size is always 0 on Windows 2000/XP. if (size == 0) // Returned required buffer size is always 0 on Windows 2000/XP.
{ {
if (bufSize == 0) if (bufSize == 0)
{ {
bufSize = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * m_NumOfProcessors; bufSize = sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * c_NumOfProcessors;
} }
else else
{ {
@ -178,24 +192,24 @@ bool CMeasureCPU::Update()
} }
} }
if (buf) delete [] buf; delete [] buf;
buf = new BYTE[bufSize]; buf = new BYTE[bufSize];
} }
else // failed
{
if (buf) delete [] buf;
return false;
}
++loop; ++loop;
} while (loop < 10); } while (loop < 5);
if (status != STATUS_SUCCESS) // failed if (status != STATUS_SUCCESS) // failed
{ {
if (buf) delete [] buf; delete [] buf;
return false; return false;
} }
if (bufSize != c_BufferSize)
{
// Store the new buffer size
c_BufferSize = bufSize;
}
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* systemPerfInfo = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)buf; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* systemPerfInfo = (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION*)buf;
if (m_Processor == 0) if (m_Processor == 0)
@ -257,12 +271,12 @@ void CMeasureCPU::CalcUsage(double idleTime, double systemTime)
*/ */
void CMeasureCPU::CalcAverageUsage(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* systemPerfInfo) void CMeasureCPU::CalcAverageUsage(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* systemPerfInfo)
{ {
if(!m_FirstTime) if (!m_FirstTime)
{ {
double dbIdleTimeDiff = 0, dbSystemTimeDiff = 0; double dbIdleTimeDiff = 0, dbSystemTimeDiff = 0;
double dbCpuUsage; double dbCpuUsage;
for (int i = 0; i < m_NumOfProcessors; ++i) for (int i = 0; i < c_NumOfProcessors; ++i)
{ {
double dbIdleTime, dbSystemTime; double dbIdleTime, dbSystemTime;
@ -286,7 +300,7 @@ void CMeasureCPU::CalcAverageUsage(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sys
else else
{ {
// store new CPU's idle and system time // store new CPU's idle and system time
for (int i = 0; i < m_NumOfProcessors; ++i) for (int i = 0; i < c_NumOfProcessors; ++i)
{ {
m_OldTime[i * 2 + 0] = Li2Double(systemPerfInfo[i].IdleTime); m_OldTime[i * 2 + 0] = Li2Double(systemPerfInfo[i].IdleTime);
m_OldTime[i * 2 + 1] = Li2Double(systemPerfInfo[i].KernelTime) + Li2Double(systemPerfInfo[i].UserTime); m_OldTime[i * 2 + 1] = Li2Double(systemPerfInfo[i].KernelTime) + Li2Double(systemPerfInfo[i].UserTime);

View File

@ -48,12 +48,14 @@ protected:
bool m_FirstTime; bool m_FirstTime;
int m_Processor; int m_Processor;
int m_NumOfProcessors;
PROCNTQSI m_NtQuerySystemInformation;
PROCGST m_GetSystemTimes;
std::vector<double> m_OldTime; std::vector<double> m_OldTime;
static PROCNTQSI c_NtQuerySystemInformation;
static PROCGST c_GetSystemTimes;
static int c_NumOfProcessors;
static ULONG c_BufferSize;
}; };
#endif #endif

View File

@ -34,6 +34,7 @@ extern CRainmeter* Rainmeter;
** **
*/ */
CMeterBar::CMeterBar(CMeterWindow* meterWindow) : CMeter(meterWindow), CMeterBar::CMeterBar(CMeterWindow* meterWindow) : CMeter(meterWindow),
m_Image(L"BarImage"),
m_NeedsReload(false), m_NeedsReload(false),
m_Color(Color::Green), m_Color(Color::Green),
m_Orientation(VERTICAL), m_Orientation(VERTICAL),
@ -41,7 +42,6 @@ CMeterBar::CMeterBar(CMeterWindow* meterWindow) : CMeter(meterWindow),
m_Border(), m_Border(),
m_Flip(false) m_Flip(false)
{ {
m_Image.SetConfigAttributes(L"BarImage", NULL);
} }
/* /*

View File

@ -33,7 +33,7 @@ extern CRainmeter* Rainmeter;
** **
*/ */
CMeterBitmap::CMeterBitmap(CMeterWindow* meterWindow) : CMeter(meterWindow), CMeterBitmap::CMeterBitmap(CMeterWindow* meterWindow) : CMeter(meterWindow),
m_Image(true), m_Image(L"BitmapImage", NULL, true),
m_NeedsReload(false), m_NeedsReload(false),
m_ZeroFrame(false), m_ZeroFrame(false),
m_FrameCount(1), m_FrameCount(1),
@ -46,7 +46,6 @@ CMeterBitmap::CMeterBitmap(CMeterWindow* meterWindow) : CMeter(meterWindow),
m_TransitionStartTicks(), m_TransitionStartTicks(),
m_TransitionStartValue() m_TransitionStartValue()
{ {
m_Image.SetConfigAttributes(L"BitmapImage", NULL);
} }
/* /*

View File

@ -40,14 +40,13 @@ enum BUTTON_STATE
** **
*/ */
CMeterButton::CMeterButton(CMeterWindow* meterWindow) : CMeter(meterWindow), CMeterButton::CMeterButton(CMeterWindow* meterWindow) : CMeter(meterWindow),
m_Image(true), m_Image(L"ButtonImage", NULL, true),
m_NeedsReload(false), m_NeedsReload(false),
m_Bitmaps(), m_Bitmaps(),
m_State(BUTTON_STATE_NORMAL), m_State(BUTTON_STATE_NORMAL),
m_Clicked(false), m_Clicked(false),
m_Executable(false) m_Executable(false)
{ {
m_Image.SetConfigAttributes(L"ButtonImage", NULL);
} }
/* /*

View File

@ -26,6 +26,10 @@ using namespace Gdiplus;
extern CRainmeter* Rainmeter; extern CRainmeter* Rainmeter;
CTintedImageHelper_DefineConfigArray(CMeterHistogram::c_PrimaryConfigArray, L"Primary");
CTintedImageHelper_DefineConfigArray(CMeterHistogram::c_SecondaryConfigArray, L"Secondary");
CTintedImageHelper_DefineConfigArray(CMeterHistogram::c_BothConfigArray, L"Both");
/* /*
** CMeterHistogram ** CMeterHistogram
** **
@ -40,6 +44,9 @@ CMeterHistogram::CMeterHistogram(CMeterWindow* meterWindow) : CMeter(meterWindow
m_MeterPos(), m_MeterPos(),
m_Autoscale(false), m_Autoscale(false),
m_Flip(false), m_Flip(false),
m_PrimaryImage(L"PrimaryImage", c_PrimaryConfigArray),
m_SecondaryImage(L"SecondaryImage", c_SecondaryConfigArray),
m_BothImage(L"BothImage", c_BothConfigArray),
m_PrimaryNeedsReload(false), m_PrimaryNeedsReload(false),
m_SecondaryNeedsReload(false), m_SecondaryNeedsReload(false),
m_BothNeedsReload(false), m_BothNeedsReload(false),
@ -51,9 +58,6 @@ CMeterHistogram::CMeterHistogram(CMeterWindow* meterWindow) : CMeter(meterWindow
m_MinSecondaryValue(), m_MinSecondaryValue(),
m_WidthChanged(true) m_WidthChanged(true)
{ {
m_PrimaryImage.SetConfigAttributes(L"PrimaryImage", L"Primary");
m_SecondaryImage.SetConfigAttributes(L"SecondaryImage", L"Secondary");
m_BothImage.SetConfigAttributes(L"BothImage", L"Both");
} }
/* /*

View File

@ -68,6 +68,10 @@ private:
double m_MinSecondaryValue; double m_MinSecondaryValue;
bool m_WidthChanged; bool m_WidthChanged;
static const WCHAR* c_PrimaryConfigArray[CTintedImage::ConfigCount];
static const WCHAR* c_SecondaryConfigArray[CTintedImage::ConfigCount];
static const WCHAR* c_BothConfigArray[CTintedImage::ConfigCount];
}; };
#endif #endif

View File

@ -2169,12 +2169,11 @@ bool CMeterWindow::ResizeWindow(bool reset)
if ((m_BackgroundMode == BGMODE_IMAGE || m_BackgroundMode == BGMODE_SCALED_IMAGE || m_BackgroundMode == BGMODE_TILED_IMAGE) && !m_BackgroundName.empty()) if ((m_BackgroundMode == BGMODE_IMAGE || m_BackgroundMode == BGMODE_SCALED_IMAGE || m_BackgroundMode == BGMODE_TILED_IMAGE) && !m_BackgroundName.empty())
{ {
// Load the background // Load the background
CTintedImage tintedBackground; CTintedImage* tintedBackground = new CTintedImage(L"Background");
tintedBackground.SetConfigAttributes(L"Background", NULL); tintedBackground->ReadConfig(m_Parser, L"Rainmeter");
tintedBackground.ReadConfig(m_Parser, L"Rainmeter"); tintedBackground->LoadImage(m_BackgroundName, true);
tintedBackground.LoadImage(m_BackgroundName, true);
if (!tintedBackground.IsLoaded()) if (!tintedBackground->IsLoaded())
{ {
m_BackgroundSize.cx = 0; m_BackgroundSize.cx = 0;
m_BackgroundSize.cy = 0; m_BackgroundSize.cy = 0;
@ -2184,7 +2183,7 @@ bool CMeterWindow::ResizeWindow(bool reset)
} }
else else
{ {
Bitmap* tempBackground = tintedBackground.GetImage(); Bitmap* tempBackground = tintedBackground->GetImage();
// Calculate the window dimensions // Calculate the window dimensions
m_BackgroundSize.cx = tempBackground->GetWidth(); m_BackgroundSize.cx = tempBackground->GetWidth();
@ -2301,6 +2300,8 @@ bool CMeterWindow::ResizeWindow(bool reset)
m_Background = desktop; m_Background = desktop;
} }
} }
delete tintedBackground;
} }
else else
{ {

View File

@ -44,6 +44,8 @@ const Gdiplus::ColorMatrix CTintedImage::c_IdentifyMatrix = {
0.0f, 0.0f, 0.0f, 0.0f, 1.0f 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
}; };
CTintedImageHelper_DefineConfigArray(CTintedImage::c_DefaultConfigArray, L"");
/* /*
** CTintedImage ** CTintedImage
** **
@ -54,7 +56,10 @@ const Gdiplus::ColorMatrix CTintedImage::c_IdentifyMatrix = {
** - ImageRotate ** - ImageRotate
** **
*/ */
CTintedImage::CTintedImage(bool disableTransform) : m_DisableTransform(disableTransform), CTintedImage::CTintedImage(const WCHAR* name, const WCHAR** configArray, bool disableTransform) : m_DisableTransform(disableTransform),
m_ConfigName(name ? name : L"Image"),
m_ConfigArray(configArray ? configArray : c_DefaultConfigArray),
m_Bitmap(), m_Bitmap(),
m_BitmapTint(), m_BitmapTint(),
m_hBuffer(), m_hBuffer(),
@ -65,11 +70,11 @@ CTintedImage::CTintedImage(bool disableTransform) : m_DisableTransform(disableTr
m_Crop(-1, -1, -1, -1), m_Crop(-1, -1, -1, -1),
m_CropMode(CROPMODE_TL), m_CropMode(CROPMODE_TL),
m_GreyScale(false), m_GreyScale(false),
m_ColorMatrix(c_IdentifyMatrix), m_ColorMatrix(new ColorMatrix),
m_Flip(RotateNoneFlipNone), m_Flip(RotateNoneFlipNone),
m_Rotate() m_Rotate()
{ {
SetConfigAttributes(L"Image", L""); *m_ColorMatrix = c_IdentifyMatrix;
} }
/* /*
@ -81,6 +86,8 @@ CTintedImage::CTintedImage(bool disableTransform) : m_DisableTransform(disableTr
CTintedImage::~CTintedImage() CTintedImage::~CTintedImage()
{ {
DisposeImage(); DisposeImage();
delete m_ColorMatrix;
} }
/* /*
@ -201,7 +208,7 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
} }
if (!m_NeedsTinting) if (!m_NeedsTinting)
{ {
if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix)) if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, &c_IdentifyMatrix))
{ {
m_NeedsTinting = true; m_NeedsTinting = true;
} }
@ -328,12 +335,12 @@ void CTintedImage::ApplyCrop()
*/ */
void CTintedImage::ApplyTint() void CTintedImage::ApplyTint()
{ {
if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, c_IdentifyMatrix)) if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, &c_IdentifyMatrix))
{ {
Bitmap* original = GetImage(); Bitmap* original = GetImage();
ImageAttributes ImgAttr; ImageAttributes ImgAttr;
ImgAttr.SetColorMatrix(&m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap); ImgAttr.SetColorMatrix(m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
Rect r(0, 0, original->GetWidth(), original->GetHeight()); Rect r(0, 0, original->GetWidth(), original->GetHeight());
@ -448,35 +455,6 @@ void CTintedImage::ApplyTransform()
} }
} }
/*
** SetConfigAttributes
**
** Sets own attributes.
**
*/
void CTintedImage::SetConfigAttributes(const WCHAR* name, const WCHAR* prefix)
{
if (name)
{
m_ConfigName = name;
}
if (prefix)
{
(m_ConfigImageCrop = prefix) += L"ImageCrop";
(m_ConfigGreyscale = prefix) += L"Greyscale";
(m_ConfigImageTint = prefix) += L"ImageTint";
(m_ConfigImageAlpha = prefix) += L"ImageAlpha";
(m_ConfigColorMatrix1 = prefix) += L"ColorMatrix1";
(m_ConfigColorMatrix2 = prefix) += L"ColorMatrix2";
(m_ConfigColorMatrix3 = prefix) += L"ColorMatrix3";
(m_ConfigColorMatrix4 = prefix) += L"ColorMatrix4";
(m_ConfigColorMatrix5 = prefix) += L"ColorMatrix5";
(m_ConfigImageFlip = prefix) += L"ImageFlip";
(m_ConfigImageRotate = prefix) += L"ImageRotate";
}
}
/* /*
** ReadConfig ** ReadConfig
** **
@ -489,7 +467,7 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
Rect oldCrop = m_Crop; Rect oldCrop = m_Crop;
CROPMODE oldCropMode = m_CropMode; CROPMODE oldCropMode = m_CropMode;
bool oldGreyScale = m_GreyScale; bool oldGreyScale = m_GreyScale;
ColorMatrix oldColorMatrix = m_ColorMatrix; ColorMatrix oldColorMatrix = *m_ColorMatrix;
RotateFlipType oldFlip = m_Flip; RotateFlipType oldFlip = m_Flip;
REAL oldRotate = m_Rotate; REAL oldRotate = m_Rotate;
@ -498,7 +476,7 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
m_Crop.X = m_Crop.Y = m_Crop.Width = m_Crop.Height = -1; m_Crop.X = m_Crop.Y = m_Crop.Width = m_Crop.Height = -1;
m_CropMode = CROPMODE_TL; m_CropMode = CROPMODE_TL;
std::wstring crop = parser.ReadString(section, m_ConfigImageCrop.c_str(), L""); std::wstring crop = parser.ReadString(section, m_ConfigArray[ConfigIndexImageCrop], L"");
if (!crop.empty()) if (!crop.empty())
{ {
if (wcschr(crop.c_str(), L',')) if (wcschr(crop.c_str(), L','))
@ -536,7 +514,8 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
if (m_CropMode < CROPMODE_TL || m_CropMode > CROPMODE_C) if (m_CropMode < CROPMODE_TL || m_CropMode > CROPMODE_C)
{ {
std::wstring error = m_ConfigImageCrop + L"="; std::wstring error = m_ConfigArray[ConfigIndexImageCrop];
error += L"=";
error += crop; error += crop;
error += L" (origin) is not valid in meter ["; error += L" (origin) is not valid in meter [";
error += section; error += section;
@ -548,83 +527,83 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
m_NeedsCrop = (oldCrop.X != m_Crop.X || oldCrop.Y != m_Crop.Y || oldCrop.Width != m_Crop.Width || oldCrop.Height != m_Crop.Height || oldCropMode != m_CropMode); m_NeedsCrop = (oldCrop.X != m_Crop.X || oldCrop.Y != m_Crop.Y || oldCrop.Width != m_Crop.Width || oldCrop.Height != m_Crop.Height || oldCropMode != m_CropMode);
m_GreyScale = 0!=parser.ReadInt(section, m_ConfigGreyscale.c_str(), 0); m_GreyScale = 0!=parser.ReadInt(section, m_ConfigArray[ConfigIndexGreyscale], 0);
Color tint = parser.ReadColor(section, m_ConfigImageTint.c_str(), Color::White); Color tint = parser.ReadColor(section, m_ConfigArray[ConfigIndexImageTint], Color::White);
int alpha = parser.ReadInt(section, m_ConfigImageAlpha.c_str(), tint.GetAlpha()); // for backwards compatibility int alpha = parser.ReadInt(section, m_ConfigArray[ConfigIndexImageAlpha], tint.GetAlpha()); // for backwards compatibility
alpha = min(255, alpha); alpha = min(255, alpha);
alpha = max(0, alpha); alpha = max(0, alpha);
m_ColorMatrix = c_IdentifyMatrix; *m_ColorMatrix = c_IdentifyMatrix;
// Read in the Color Matrix // Read in the Color Matrix
// It has to be read in like this because it crashes when reading over 17 floats // It has to be read in like this because it crashes when reading over 17 floats
// at one time. The parser does it fine, but after putting the returned values // at one time. The parser does it fine, but after putting the returned values
// into the Color Matrix the next time the parser is used it crashes. // into the Color Matrix the next time the parser is used it crashes.
std::vector<Gdiplus::REAL> matrix = parser.ReadFloats(section, m_ConfigColorMatrix1.c_str()); std::vector<Gdiplus::REAL> matrix1 = parser.ReadFloats(section, m_ConfigArray[ConfigIndexColorMatrix1]);
if (matrix.size() == 5) if (matrix1.size() == 5)
{ {
for (int i = 0; i < 4; ++i) // The fifth column must be 0. for (int i = 0; i < 4; ++i) // The fifth column must be 0.
{ {
m_ColorMatrix.m[0][i] = matrix[i]; m_ColorMatrix->m[0][i] = matrix1[i];
} }
} }
else else
{ {
m_ColorMatrix.m[0][0] = (REAL)tint.GetRed() / 255.0f; m_ColorMatrix->m[0][0] = (REAL)tint.GetRed() / 255.0f;
} }
matrix = parser.ReadFloats(section, m_ConfigColorMatrix2.c_str()); std::vector<Gdiplus::REAL> matrix2 = parser.ReadFloats(section, m_ConfigArray[ConfigIndexColorMatrix2]);
if (matrix.size() == 5) if (matrix2.size() == 5)
{ {
for(int i = 0; i < 4; ++i) // The fifth column must be 0. for(int i = 0; i < 4; ++i) // The fifth column must be 0.
{ {
m_ColorMatrix.m[1][i] = matrix[i]; m_ColorMatrix->m[1][i] = matrix2[i];
} }
} }
else else
{ {
m_ColorMatrix.m[1][1] = (REAL)tint.GetGreen() / 255.0f; m_ColorMatrix->m[1][1] = (REAL)tint.GetGreen() / 255.0f;
} }
matrix = parser.ReadFloats(section, m_ConfigColorMatrix3.c_str()); std::vector<Gdiplus::REAL> matrix3 = parser.ReadFloats(section, m_ConfigArray[ConfigIndexColorMatrix3]);
if (matrix.size() == 5) if (matrix3.size() == 5)
{ {
for(int i = 0; i < 4; ++i) // The fifth column must be 0. for(int i = 0; i < 4; ++i) // The fifth column must be 0.
{ {
m_ColorMatrix.m[2][i] = matrix[i]; m_ColorMatrix->m[2][i] = matrix3[i];
} }
} }
else else
{ {
m_ColorMatrix.m[2][2] = (REAL)tint.GetBlue() / 255.0f; m_ColorMatrix->m[2][2] = (REAL)tint.GetBlue() / 255.0f;
} }
matrix = parser.ReadFloats(section, m_ConfigColorMatrix4.c_str()); std::vector<Gdiplus::REAL> matrix4 = parser.ReadFloats(section, m_ConfigArray[ConfigIndexColorMatrix4]);
if (matrix.size() == 5) if (matrix4.size() == 5)
{ {
for(int i = 0; i < 4; ++i) // The fifth column must be 0. for(int i = 0; i < 4; ++i) // The fifth column must be 0.
{ {
m_ColorMatrix.m[3][i] = matrix[i]; m_ColorMatrix->m[3][i] = matrix4[i];
} }
} }
else else
{ {
m_ColorMatrix.m[3][3] = (REAL)alpha / 255.0f; m_ColorMatrix->m[3][3] = (REAL)alpha / 255.0f;
} }
matrix = parser.ReadFloats(section, m_ConfigColorMatrix5.c_str()); std::vector<Gdiplus::REAL> matrix5 = parser.ReadFloats(section, m_ConfigArray[ConfigIndexColorMatrix5]);
if (matrix.size() == 5) if (matrix5.size() == 5)
{ {
for(int i = 0; i < 4; ++i) // The fifth column must be 1. for(int i = 0; i < 4; ++i) // The fifth column must be 1.
{ {
m_ColorMatrix.m[4][i] = matrix[i]; m_ColorMatrix->m[4][i] = matrix5[i];
} }
} }
m_NeedsTinting = (oldGreyScale != m_GreyScale || !CompareColorMatrix(oldColorMatrix, m_ColorMatrix)); m_NeedsTinting = (oldGreyScale != m_GreyScale || !CompareColorMatrix(&oldColorMatrix, m_ColorMatrix));
std::wstring flip = parser.ReadString(section, m_ConfigImageFlip.c_str(), L"NONE"); std::wstring flip = parser.ReadString(section, m_ConfigArray[ConfigIndexImageFlip], L"NONE");
if(_wcsicmp(flip.c_str(), L"NONE") == 0) if(_wcsicmp(flip.c_str(), L"NONE") == 0)
{ {
m_Flip = RotateNoneFlipNone; m_Flip = RotateNoneFlipNone;
@ -643,7 +622,8 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
} }
else else
{ {
std::wstring error = m_ConfigImageFlip + L"="; std::wstring error = m_ConfigArray[ConfigIndexImageFlip];
error += L"=";
error += flip; error += flip;
error += L" is not valid in meter ["; error += L" is not valid in meter [";
error += section; error += section;
@ -653,7 +633,7 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
if (!m_DisableTransform) if (!m_DisableTransform)
{ {
m_Rotate = (REAL)parser.ReadFloat(section, m_ConfigImageRotate.c_str(), 0.0); m_Rotate = (REAL)parser.ReadFloat(section, m_ConfigArray[ConfigIndexImageRotate], 0.0);
} }
m_NeedsTransform = (oldFlip != m_Flip || oldRotate != m_Rotate); m_NeedsTransform = (oldFlip != m_Flip || oldRotate != m_Rotate);
@ -665,13 +645,13 @@ void CTintedImage::ReadConfig(CConfigParser& parser, const WCHAR* section)
** Compares the two given color matrices. ** Compares the two given color matrices.
** **
*/ */
bool CTintedImage::CompareColorMatrix(const Gdiplus::ColorMatrix& a, const Gdiplus::ColorMatrix& b) bool CTintedImage::CompareColorMatrix(const Gdiplus::ColorMatrix* a, const Gdiplus::ColorMatrix* b)
{ {
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
for (int j = 0; j < 5; ++j) for (int j = 0; j < 4; ++j) // The fifth column is reserved.
{ {
if (a.m[i][j] != b.m[i][j]) if (a->m[i][j] != b->m[i][j])
{ {
return false; return false;
} }

View File

@ -23,15 +23,53 @@
#include <gdiplus.h> #include <gdiplus.h>
#include <string> #include <string>
/*
** CTintedImageHelper_DefineConfigArray macro
**
** This is a helper macro to define the array of the config item.
** It's necessary to give a string literal to the prefix parameter.
**
*/
#define CTintedImageHelper_DefineConfigArray(name, prefix) \
const WCHAR* (name)[CTintedImage::ConfigCount] = { \
prefix L"ImageCrop", \
prefix L"Greyscale", \
prefix L"ImageTint", \
prefix L"ImageAlpha", \
prefix L"ColorMatrix1", \
prefix L"ColorMatrix2", \
prefix L"ColorMatrix3", \
prefix L"ColorMatrix4", \
prefix L"ColorMatrix5", \
prefix L"ImageFlip", \
prefix L"ImageRotate" \
};
class CConfigParser; class CConfigParser;
class CTintedImage class CTintedImage
{ {
public: public:
CTintedImage(bool disableTransform = false); enum ConfigIndex
{
ConfigIndexImageCrop = 0,
ConfigIndexGreyscale,
ConfigIndexImageTint,
ConfigIndexImageAlpha,
ConfigIndexColorMatrix1,
ConfigIndexColorMatrix2,
ConfigIndexColorMatrix3,
ConfigIndexColorMatrix4,
ConfigIndexColorMatrix5,
ConfigIndexImageFlip,
ConfigIndexImageRotate,
ConfigCount
};
CTintedImage(const WCHAR* name = L"Image", const WCHAR** configArray = c_DefaultConfigArray, bool disableTransform = false);
virtual ~CTintedImage(); virtual ~CTintedImage();
void SetConfigAttributes(const WCHAR* name, const WCHAR* prefix);
void ReadConfig(CConfigParser& parser, const WCHAR* section); void ReadConfig(CConfigParser& parser, const WCHAR* section);
bool IsLoaded() { return (m_Bitmap != NULL); } bool IsLoaded() { return (m_Bitmap != NULL); }
@ -63,7 +101,7 @@ protected:
static bool LoadImageFromFileHandle(HANDLE fileHandle, Gdiplus::Bitmap** pBitmap, HGLOBAL* phBuffer); static bool LoadImageFromFileHandle(HANDLE fileHandle, Gdiplus::Bitmap** pBitmap, HGLOBAL* phBuffer);
static Gdiplus::Bitmap* TurnGreyscale(Gdiplus::Bitmap* source); static Gdiplus::Bitmap* TurnGreyscale(Gdiplus::Bitmap* source);
static bool CompareColorMatrix(const Gdiplus::ColorMatrix& a, const Gdiplus::ColorMatrix& b); static bool CompareColorMatrix(const Gdiplus::ColorMatrix* a, const Gdiplus::ColorMatrix* b);
Gdiplus::Bitmap* m_Bitmap; // The bitmap Gdiplus::Bitmap* m_Bitmap; // The bitmap
Gdiplus::Bitmap* m_BitmapTint; // The tinted bitmap Gdiplus::Bitmap* m_BitmapTint; // The tinted bitmap
@ -71,19 +109,8 @@ protected:
HGLOBAL m_hBuffer; HGLOBAL m_hBuffer;
FILETIME m_Modified; FILETIME m_Modified;
std::wstring m_ConfigName; const std::wstring m_ConfigName;
std::wstring m_ConfigImageCrop; const WCHAR** m_ConfigArray;
std::wstring m_ConfigGreyscale;
std::wstring m_ConfigImageTint;
std::wstring m_ConfigImageAlpha;
std::wstring m_ConfigColorMatrix1;
std::wstring m_ConfigColorMatrix2;
std::wstring m_ConfigColorMatrix3;
std::wstring m_ConfigColorMatrix4;
std::wstring m_ConfigColorMatrix5;
std::wstring m_ConfigImageFlip;
std::wstring m_ConfigImageRotate;
const bool m_DisableTransform; const bool m_DisableTransform;
bool m_NeedsCrop; bool m_NeedsCrop;
@ -93,12 +120,14 @@ protected:
Gdiplus::Rect m_Crop; Gdiplus::Rect m_Crop;
CROPMODE m_CropMode; CROPMODE m_CropMode;
bool m_GreyScale; bool m_GreyScale;
Gdiplus::ColorMatrix m_ColorMatrix; Gdiplus::ColorMatrix* m_ColorMatrix;
Gdiplus::RotateFlipType m_Flip; Gdiplus::RotateFlipType m_Flip;
Gdiplus::REAL m_Rotate; Gdiplus::REAL m_Rotate;
static const Gdiplus::ColorMatrix c_GreyScaleMatrix; static const Gdiplus::ColorMatrix c_GreyScaleMatrix;
static const Gdiplus::ColorMatrix c_IdentifyMatrix; static const Gdiplus::ColorMatrix c_IdentifyMatrix;
static const WCHAR* c_DefaultConfigArray[ConfigCount];
}; };
#endif #endif