https://git.reactos.org/?p=reactos.git;a=commitdiff;h=70e05170cf8a260326f9bc...
commit 70e05170cf8a260326f9bcbd2909fba711df2500 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Wed Aug 9 08:17:07 2023 +0900 Commit: GitHub noreply@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;