https://git.reactos.org/?p=reactos.git;a=commitdiff;h=70e05170cf8a260326f9b…
commit 70e05170cf8a260326f9bcbd2909fba711df2500
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Aug 9 08:17:07 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Wed Aug 9 08:17:07 2023 +0900
[MSPAINT][ATL] Delete deprecated functions (#5542)
- Rewrite CImageDx to reduce improper dependency with CImage.
- Check if the filename extension is supported before saving the files.
- Delete deprecated functions in CImage.
CORE-19094
---
base/applications/mspaint/atlimagedx.h | 331 ++++++++++++++++++++++++++-------
base/applications/mspaint/dib.cpp | 14 +-
base/applications/mspaint/precomp.h | 1 -
base/applications/mspaint/winproc.cpp | 10 +
sdk/lib/atl/atlimage.h | 55 ------
5 files changed, 287 insertions(+), 124 deletions(-)
diff --git a/base/applications/mspaint/atlimagedx.h
b/base/applications/mspaint/atlimagedx.h
index 735d4716dc7..6469e9d471b 100644
--- a/base/applications/mspaint/atlimagedx.h
+++ b/base/applications/mspaint/atlimagedx.h
@@ -7,135 +7,340 @@
#pragma once
-class CImageDx : public CImage
+#include <atlimage.h>
+
+namespace GPDE = Gdiplus::DllExports;
+
+class CImageDx
{
+protected:
+ HBITMAP m_hBitmap = NULL;
+
public:
- CImageDx() : CImage()
+ CImageDx()
{
- GetImageHorizontalResolution = NULL;
- GetImageVerticalResolution = NULL;
- BitmapSetResolution = NULL;
+ _shared()->AddRef();
}
- BOOL GetResolution(Gdiplus::GpImage *pImage, float *pxDpi, float *pyDpi)
+ ~CImageDx()
{
- *pxDpi = 96;
- *pyDpi = 96;
+ if (m_hBitmap)
+ ::DeleteObject(m_hBitmap);
+
+ _shared()->Release();
+ }
+
+ void Attach(HBITMAP hbm)
+ {
+ if (m_hBitmap)
+ ::DeleteObject(m_hBitmap);
+ m_hBitmap = hbm;
+ }
+
+ HBITMAP Detach()
+ {
+ HBITMAP hbmOld = m_hBitmap;
+ m_hBitmap = NULL;
+ return hbmOld;
+ }
- if (GetImageHorizontalResolution == NULL || GetImageVerticalResolution == NULL)
+ BOOL GetResolution(Gdiplus::GpImage *pImage, float *pxDpi, float *pyDpi)
+ {
+ if (!get_fn(_shared()->m_GetImageHorizontalResolution,
"GdipGetImageHorizontalResolution") ||
+ !get_fn(_shared()->m_GetImageVerticalResolution,
"GdipGetImageVerticalResolution"))
{
- GetImageHorizontalResolution =
-
AddrOf<GETIMAGEHORIZONTALRESOLUTION>("GdipGetImageHorizontalResolution");
- GetImageVerticalResolution =
-
AddrOf<GETIMAGEVERTICALRESOLUTION>("GdipGetImageVerticalResolution");
+ return FALSE;
}
- if (GetImageHorizontalResolution == NULL || GetImageVerticalResolution == NULL)
- return FALSE;
+ if (pxDpi)
+ _shared()->m_GetImageHorizontalResolution(pImage, pxDpi);
+ if (pyDpi)
+ _shared()->m_GetImageVerticalResolution(pImage, pyDpi);
- GetImageHorizontalResolution(pImage, pxDpi);
- GetImageVerticalResolution(pImage, pyDpi);
return TRUE;
}
- BOOL SetResolution(Gdiplus::GpBitmap *pBitmap, float xDpi, float yDpi) const
+ BOOL SetResolution(Gdiplus::GpBitmap *pBitmap, float xDpi, float yDpi)
{
- if (BitmapSetResolution == NULL)
- BitmapSetResolution =
AddrOf<BITMAPSETRESOLUTION>("GdipBitmapSetResolution");
-
- if (BitmapSetResolution == NULL)
+ if (!get_fn(_shared()->m_BitmapSetResolution,
"GdipBitmapSetResolution"))
return FALSE;
- BitmapSetResolution(pBitmap, xDpi, yDpi);
+ _shared()->m_BitmapSetResolution(pBitmap, xDpi, yDpi);
return TRUE;
}
HRESULT LoadDx(LPCTSTR pszFileName, float *pxDpi, float *pyDpi) throw()
{
- // convert the file name string into Unicode
- CStringW pszNameW(pszFileName);
+ using namespace Gdiplus;
+
+ _shared()->AddRef();
+
+ if (!get_fn(_shared()->m_CreateBitmapFromFile,
"GdipCreateBitmapFromFile") ||
+ !get_fn(_shared()->m_CreateHBITMAPFromBitmap,
"GdipCreateHBITMAPFromBitmap") ||
+ !get_fn(_shared()->m_DisposeImage, "GdipDisposeImage"))
+ {
+ _shared()->Release();
+ return E_FAIL;
+ }
// create a GpBitmap object from file
- using namespace Gdiplus;
GpBitmap *pBitmap = NULL;
- if (GetCommon().CreateBitmapFromFile(pszNameW, &pBitmap) != Ok)
+ if (_shared()->m_CreateBitmapFromFile(pszFileName, &pBitmap) != Ok)
{
+ _shared()->Release();
return E_FAIL;
}
- // get bitmap handle
+ // get an HBITMAP
HBITMAP hbm = NULL;
Color color(0xFF, 0xFF, 0xFF);
- Gdiplus::Status status;
- status = GetCommon().CreateHBITMAPFromBitmap(pBitmap, &hbm,
color.GetValue());
+ Status status = _shared()->m_CreateHBITMAPFromBitmap(pBitmap, &hbm,
color.GetValue());
// get the resolution
- GetResolution((Gdiplus::GpImage*)pBitmap, pxDpi, pyDpi);
+ if (pxDpi || pyDpi)
+ GetResolution((GpImage*)pBitmap, pxDpi, pyDpi);
// delete GpBitmap
- GetCommon().DisposeImage(pBitmap);
+ _shared()->m_DisposeImage(pBitmap);
// attach it
if (status == Ok)
Attach(hbm);
+
+ _shared()->Release();
return (status == Ok ? S_OK : E_FAIL);
}
HRESULT SaveDx(LPCTSTR pszFileName, REFGUID guidFileType = GUID_NULL,
- float xDpi = 0, float yDpi = 0) const throw()
+ float xDpi = 0, float yDpi = 0) throw()
{
using namespace Gdiplus;
- ATLASSERT(m_hbm);
-
- // TODO & FIXME: set parameters (m_rgbTransColor etc.)
- // convert the file name string into Unicode
- CStringW pszNameW(pszFileName);
+ _shared()->AddRef();
- // if the file type is null, get the file type from extension
- const GUID *FileType = &guidFileType;
- if (::IsEqualGUID(guidFileType, GUID_NULL))
+ if (!get_fn(_shared()->m_CreateBitmapFromHBITMAP,
"GdipCreateBitmapFromHBITMAP") ||
+ !get_fn(_shared()->m_SaveImageToFile, "GdipSaveImageToFile") ||
+ !get_fn(_shared()->m_DisposeImage, "GdipDisposeImage"))
{
- LPCWSTR pszExt = GetFileExtension(pszNameW);
- FileType = FileTypeFromExtension(pszExt);
- }
-
- // get CLSID from file type
- CLSID clsid;
- if (!GetClsidFromFileType(&clsid, FileType))
+ _shared()->Release();
return E_FAIL;
+ }
// create a GpBitmap from HBITMAP
GpBitmap *pBitmap = NULL;
- GetCommon().CreateBitmapFromHBITMAP(m_hbm, NULL, &pBitmap);
+ _shared()->m_CreateBitmapFromHBITMAP(m_hBitmap, NULL, &pBitmap);
// set the resolution
SetResolution(pBitmap, xDpi, yDpi);
+ // Get encoders
+ UINT cEncoders = 0;
+ ImageCodecInfo* pEncoders = GetAllEncoders(cEncoders);
+
+ // if the file type is null, get the file type from extension
+ CLSID clsid;
+ if (::IsEqualGUID(guidFileType, GUID_NULL))
+ {
+ CString strExt(PathFindExtension(pszFileName));
+ clsid = FindCodecForExtension(strExt, pEncoders, cEncoders);
+ }
+ else
+ {
+ clsid = FindCodecForFileType(guidFileType, pEncoders, cEncoders);
+ }
+
+ delete[] pEncoders;
+
// save to file
- Status status;
- status = GetCommon().SaveImageToFile(pBitmap, pszNameW, &clsid, NULL);
+ Status status = _shared()->m_SaveImageToFile(pBitmap, pszFileName, &clsid,
NULL);
// destroy GpBitmap
- GetCommon().DisposeImage(pBitmap);
+ _shared()->m_DisposeImage(pBitmap);
+
+ _shared()->Release();
return (status == Ok ? S_OK : E_FAIL);
}
+ static BOOL IsExtensionSupported(PWCHAR pchDotExt)
+ {
+ _shared()->AddRef();
+
+ UINT cEncoders;
+ Gdiplus::ImageCodecInfo* pEncoders = GetAllEncoders(cEncoders);
+
+ CLSID clsid = FindCodecForExtension(pchDotExt, pEncoders, cEncoders);
+ BOOL ret = !::IsEqualGUID(clsid, CLSID_NULL);
+ delete[] pEncoders;
+
+ _shared()->Release();
+ return ret;
+ }
+
protected:
- // get procedure address of the DLL
- template <typename TYPE>
- TYPE AddrOf(const char *name) const
+ using FN_Startup = decltype(&Gdiplus::GdiplusStartup);
+ using FN_Shutdown = decltype(&Gdiplus::GdiplusShutdown);
+ using FN_GetImageHorizontalResolution =
decltype(&GPDE::GdipGetImageHorizontalResolution);
+ using FN_GetImageVerticalResolution =
decltype(&GPDE::GdipGetImageVerticalResolution);
+ using FN_BitmapSetResolution = decltype(&GPDE::GdipBitmapSetResolution);
+ using FN_CreateBitmapFromHBITMAP = decltype(&GPDE::GdipCreateBitmapFromHBITMAP);
+ using FN_CreateBitmapFromFile = decltype(&GPDE::GdipCreateBitmapFromFile);
+ using FN_CreateHBITMAPFromBitmap = decltype(&GPDE::GdipCreateHBITMAPFromBitmap);
+ using FN_SaveImageToFile = decltype(&GPDE::GdipSaveImageToFile);
+ using FN_DisposeImage = decltype(&GPDE::GdipDisposeImage);
+ using FN_GetImageEncodersSize = decltype(&GPDE::GdipGetImageEncodersSize);
+ using FN_GetImageEncoders = decltype(&GPDE::GdipGetImageEncoders);
+
+ struct SHARED
+ {
+ HINSTANCE m_hGdiPlus = NULL;
+ LONG m_cRefs = 0;
+ ULONG_PTR m_dwToken = 0;
+ FN_Shutdown m_Shutdown = NULL;
+ FN_GetImageHorizontalResolution m_GetImageHorizontalResolution = NULL;
+ FN_GetImageVerticalResolution m_GetImageVerticalResolution = NULL;
+ FN_BitmapSetResolution m_BitmapSetResolution = NULL;
+ FN_CreateBitmapFromHBITMAP m_CreateBitmapFromHBITMAP = NULL;
+ FN_CreateBitmapFromFile m_CreateBitmapFromFile = NULL;
+ FN_CreateHBITMAPFromBitmap m_CreateHBITMAPFromBitmap = NULL;
+ FN_SaveImageToFile m_SaveImageToFile = NULL;
+ FN_DisposeImage m_DisposeImage = NULL;
+ FN_GetImageEncodersSize m_GetImageEncodersSize = NULL;
+ FN_GetImageEncoders m_GetImageEncoders = NULL;
+
+ HINSTANCE Init()
+ {
+ if (m_hGdiPlus)
+ return m_hGdiPlus;
+
+ m_hGdiPlus = ::LoadLibraryW(L"gdiplus.dll");
+ if (!m_hGdiPlus)
+ return NULL;
+
+ FN_Startup Startup = (FN_Startup)GetProcAddress(m_hGdiPlus,
"GdiplusStartup");
+ m_Shutdown = (FN_Shutdown)GetProcAddress(m_hGdiPlus,
"GdiplusShutdown");
+ if (!Startup || !m_Shutdown)
+ {
+ ::FreeLibrary(m_hGdiPlus);
+ m_hGdiPlus = NULL;
+ return NULL;
+ }
+
+ Gdiplus::GdiplusStartupInput gdiplusStartupInput;
+ Startup(&m_dwToken, &gdiplusStartupInput, NULL);
+
+ return m_hGdiPlus;
+ }
+
+ void Free()
+ {
+ ::FreeLibrary(m_hGdiPlus);
+ ZeroMemory(this, sizeof(*this));
+ }
+
+ LONG AddRef()
+ {
+ return ++m_cRefs;
+ }
+
+ LONG Release()
+ {
+ if (--m_cRefs == 0)
+ {
+ Free();
+ return 0;
+ }
+ return m_cRefs;
+ }
+ };
+
+ static SHARED* _shared()
+ {
+ static SHARED s_shared;
+ return &s_shared;
+ }
+
+ static Gdiplus::ImageCodecInfo* GetAllEncoders(UINT& cEncoders)
+ {
+ Gdiplus::ImageCodecInfo *ret = NULL;
+ UINT total_size;
+
+ if (!get_fn(_shared()->m_GetImageEncodersSize,
"GdipGetImageEncodersSize") ||
+ !get_fn(_shared()->m_GetImageEncoders, "GdipGetImageEncoders"))
+ {
+ cEncoders = 0;
+ return NULL;
+ }
+
+ _shared()->m_GetImageEncodersSize(&cEncoders, &total_size);
+ if (total_size == 0)
+ return NULL;
+
+ ret = new Gdiplus::ImageCodecInfo[total_size / sizeof(ret[0])];
+ if (ret == NULL)
+ {
+ cEncoders = 0;
+ return NULL;
+ }
+
+ _shared()->m_GetImageEncoders(cEncoders, total_size, ret);
+
+ return ret; // needs delete[]
+ }
+
+ template <typename FN_T>
+ static bool get_fn(FN_T& fn, const char *name)
{
- FARPROC proc = ::GetProcAddress(GetCommon().hinstGdiPlus, name);
- return reinterpret_cast<TYPE>(proc);
+ if (fn)
+ return true;
+ HINSTANCE hGdiPlus = _shared()->Init();
+ fn = reinterpret_cast<FN_T>(::GetProcAddress(hGdiPlus, name));
+ return fn != NULL;
}
- typedef St (WINGDIPAPI *GETIMAGEHORIZONTALRESOLUTION)(Im *, float*);
- typedef St (WINGDIPAPI *GETIMAGEVERTICALRESOLUTION)(Im *, float*);
- typedef St (WINGDIPAPI *BITMAPSETRESOLUTION)(Bm *, float, float);
+ // CImage::FindCodecForExtension is private. We have to duplicate it at here...
+ static CLSID
+ FindCodecForExtension(LPCTSTR dotext, const Gdiplus::ImageCodecInfo *pCodecs, UINT
nCodecs)
+ {
+ for (UINT i = 0; i < nCodecs; ++i)
+ {
+ CString strSpecs(pCodecs[i].FilenameExtension);
+ int ichOld = 0, ichSep;
+ for (;;)
+ {
+ ichSep = strSpecs.Find(TEXT(';'), ichOld);
+
+ CString strSpec;
+ if (ichSep < 0)
+ strSpec = strSpecs.Mid(ichOld);
+ else
+ strSpec = strSpecs.Mid(ichOld, ichSep - ichOld);
+
+ int ichDot = strSpec.ReverseFind(TEXT('.'));
+ if (ichDot >= 0)
+ strSpec = strSpec.Mid(ichDot);
+
+ if (!dotext || strSpec.CompareNoCase(dotext) == 0)
+ return pCodecs[i].Clsid;
+
+ if (ichSep < 0)
+ break;
+
+ ichOld = ichSep + 1;
+ }
+ }
+ return CLSID_NULL;
+ }
- GETIMAGEHORIZONTALRESOLUTION GetImageHorizontalResolution;
- GETIMAGEVERTICALRESOLUTION GetImageVerticalResolution;
- mutable BITMAPSETRESOLUTION BitmapSetResolution;
+ // CImage::FindCodecForFileType is private. We have to duplicate it at here...
+ static CLSID
+ FindCodecForFileType(REFGUID guidFileType, const Gdiplus::ImageCodecInfo *pCodecs,
UINT nCodecs)
+ {
+ for (UINT iInfo = 0; iInfo < nCodecs; ++iInfo)
+ {
+ if (::IsEqualGUID(pCodecs[iInfo].FormatID, guidFileType))
+ return pCodecs[iInfo].Clsid;
+ }
+ return CLSID_NULL;
+ }
};
diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp
index ea5ead7427a..a5b3f0b7896 100644
--- a/base/applications/mspaint/dib.cpp
+++ b/base/applications/mspaint/dib.cpp
@@ -262,7 +262,7 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCWSTR name, BOOL fIsMainFile)
// load the image
CImageDx img;
- float xDpi, yDpi;
+ float xDpi = 0, yDpi = 0;
HRESULT hr = img.LoadDx(name, &xDpi, &yDpi);
if (FAILED(hr))
{
@@ -274,12 +274,16 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCWSTR name, BOOL fIsMainFile)
if (!fIsMainFile)
return hBitmap;
+ if (xDpi <= 0 || yDpi <= 0)
+ {
+ HDC hDC = ::GetDC(NULL);
+ xDpi = ::GetDeviceCaps(hDC, LOGPIXELSX);
+ yDpi = ::GetDeviceCaps(hDC, LOGPIXELSY);
+ ::ReleaseDC(NULL, hDC);
+ }
+
g_xDpi = xDpi;
g_yDpi = yDpi;
- if (g_xDpi <= 0)
- g_xDpi = 96;
- if (g_yDpi <= 0)
- g_yDpi = 96;
SetBitmapAndInfo(hBitmap, name, &find, TRUE);
return hBitmap;
diff --git a/base/applications/mspaint/precomp.h b/base/applications/mspaint/precomp.h
index 368ce304461..385cc985a4f 100644
--- a/base/applications/mspaint/precomp.h
+++ b/base/applications/mspaint/precomp.h
@@ -13,7 +13,6 @@
#include <tchar.h>
#include <atlbase.h>
#include <atlcom.h>
-#include <atlimage.h>
#include <atlpath.h>
#include <atlstr.h>
#include <atlwin.h>
diff --git a/base/applications/mspaint/winproc.cpp
b/base/applications/mspaint/winproc.cpp
index a15e6dd3d6b..de22a406243 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -141,6 +141,16 @@ void CMainWindow::saveImage(BOOL overwrite)
{
canvasWindow.finishDrawing();
+ // Is the extension not supported?
+ PWCHAR pchDotExt = PathFindExtensionW(g_szFileName);
+ if (pchDotExt && *pchDotExt &&
!CImageDx::IsExtensionSupported(pchDotExt))
+ {
+ // Remove the extension
+ PathRemoveExtensionW(g_szFileName);
+ // No overwrite
+ overwrite = FALSE;
+ }
+
if (g_isAFile && overwrite)
{
imageModel.SaveImage(g_szFileName);
diff --git a/sdk/lib/atl/atlimage.h b/sdk/lib/atl/atlimage.h
index bbf7dc6a115..462b63b1e92 100644
--- a/sdk/lib/atl/atlimage.h
+++ b/sdk/lib/atl/atlimage.h
@@ -1056,50 +1056,6 @@ protected:
return CLSID_NULL;
}
- // Deprecated. Don't use this
- static const GUID *FileTypeFromExtension(LPCTSTR dotext)
- {
- CImage dummy; // HACK: Initialize common
- UINT cEncoders = 0;
- Gdiplus::ImageCodecInfo* pEncoders = _getAllEncoders(cEncoders);
-
- for (UINT i = 0; i < cEncoders; ++i)
- {
- CString strSpecs(pEncoders[i].FilenameExtension);
- int ichOld = 0, ichSep;
- for (;;)
- {
- ichSep = strSpecs.Find(TEXT(';'), ichOld);
-
- CString strSpec;
- if (ichSep < 0)
- strSpec = strSpecs.Mid(ichOld);
- else
- strSpec = strSpecs.Mid(ichOld, ichSep - ichOld);
-
- int ichDot = strSpec.ReverseFind(TEXT('.'));
- if (ichDot >= 0)
- strSpec = strSpec.Mid(ichDot);
-
- if (!dotext || strSpec.CompareNoCase(dotext) == 0)
- {
- static GUID s_guid;
- s_guid = pEncoders[i].FormatID;
- delete[] pEncoders;
- return &s_guid;
- }
-
- if (ichSep < 0)
- break;
-
- ichOld = ichSep + 1;
- }
- }
-
- delete[] pEncoders;
- return NULL;
- }
-
static CLSID
FindCodecForFileType(REFGUID guidFileType, const Gdiplus::ImageCodecInfo *pCodecs,
UINT nCodecs)
{
@@ -1111,17 +1067,6 @@ protected:
return CLSID_NULL;
}
- // Deprecated. Don't use this
- static bool GetClsidFromFileType(CLSID *clsid, const GUID *guid)
- {
- CImage dummy; // HACK: Initialize common
- UINT cEncoders = 0;
- Gdiplus::ImageCodecInfo* pEncoders = _getAllEncoders(cEncoders);
- *clsid = FindCodecForFileType(*guid, pEncoders, cEncoders);
- delete[] pEncoders;
- return true;
- }
-
static Gdiplus::ImageCodecInfo* _getAllEncoders(UINT& cEncoders)
{
UINT total_size = 0;