diff options
Diffstat (limited to 'image')
-rw-r--r-- | image/DrawResult.h | 1 | ||||
-rw-r--r-- | image/VectorImage.cpp | 22 | ||||
-rw-r--r-- | image/decoders/icon/win/nsIconChannel.cpp | 53 |
3 files changed, 35 insertions, 41 deletions
diff --git a/image/DrawResult.h b/image/DrawResult.h index 8240ede26..912f59dc3 100644 --- a/image/DrawResult.h +++ b/image/DrawResult.h @@ -6,6 +6,7 @@ #ifndef mozilla_image_DrawResult_h #define mozilla_image_DrawResult_h +#include <cstdint> // for uint8_t #include "mozilla/Attributes.h" #include "mozilla/Likely.h" diff --git a/image/VectorImage.cpp b/image/VectorImage.cpp index fd970e179..1e59b13fa 100644 --- a/image/VectorImage.cpp +++ b/image/VectorImage.cpp @@ -9,6 +9,7 @@ #include "gfxContext.h" #include "gfxDrawable.h" #include "gfxPlatform.h" +#include "gfxPrefs.h" // for surface cache size #include "gfxUtils.h" #include "imgFrame.h" #include "mozilla/AutoRestore.h" @@ -931,11 +932,14 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams, BackendTy RefPtr<gfxDrawable> svgDrawable = new gfxCallbackDrawable(cb, aParams.size); - // We take an early exit without using the surface cache if - // x or y > maxDimension, because for vector images this can cause bad perf - // issues if large sizes are scaled repeatedly (a rather common scenario) - // that can quickly exhaust the cache. - int32_t maxDimension = 3000; + // We take an early exit without using the surface cache if too large, + // because for vector images this can cause bad perf issues if large sizes + // are scaled repeatedly (a rather common scenario) that can quickly exhaust + // the cache. + // Similar to max image size calculations, this has a max cap and size check. + // max cap = 8000 (pixels); size check = 5% of cache + int32_t maxDimension = 8000; + int32_t maxCacheElemSize = (gfxPrefs::ImageMemSurfaceCacheMaxSizeKB() * 1024) / 20; bool bypassCache = bool(aParams.flags & FLAG_BYPASS_SURFACE_CACHE) || // Refuse to cache animated images: @@ -946,6 +950,14 @@ VectorImage::CreateSurfaceAndShow(const SVGDrawingParameters& aParams, BackendTy // Image x or y is larger than our cache cap: aParams.size.width > maxDimension || aParams.size.height > maxDimension; + if (!bypassCache) { + // This is separated out to make sure width and height are sane at this point + // and the result can't overflow. Note: keep maxDimension low enough so that + // (maxDimension)^2 x 4 < INT32_MAX. + // Assuming surface size for any rendered vector image is RGBA, so 4Bpp. + bypassCache = (aParams.size.width * aParams.size.height * 4) > maxCacheElemSize; + } + if (bypassCache) { return Show(svgDrawable, aParams); } diff --git a/image/decoders/icon/win/nsIconChannel.cpp b/image/decoders/icon/win/nsIconChannel.cpp index 9ddcbbc48..04680627a 100644 --- a/image/decoders/icon/win/nsIconChannel.cpp +++ b/image/decoders/icon/win/nsIconChannel.cpp @@ -29,11 +29,6 @@ #include "nsContentSecurityManager.h" #include "nsContentUtils.h" -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0600 - // we need windows.h to read out registry information... #include <windows.h> #include <shellapi.h> @@ -416,41 +411,27 @@ nsIconChannel::GetStockHIcon(nsIMozIconURI* aIconURI, { nsresult rv = NS_OK; - // We can only do this on Vista or above - HMODULE hShellDLL = ::LoadLibraryW(L"shell32.dll"); - decltype(SHGetStockIconInfo)* pSHGetStockIconInfo = - (decltype(SHGetStockIconInfo)*) ::GetProcAddress(hShellDLL, - "SHGetStockIconInfo"); - - if (pSHGetStockIconInfo) { - uint32_t desiredImageSize; - aIconURI->GetImageSize(&desiredImageSize); - nsAutoCString stockIcon; - aIconURI->GetStockIcon(stockIcon); - - SHSTOCKICONID stockIconID = GetStockIconIDForName(stockIcon); - if (stockIconID == SIID_INVALID) { - return NS_ERROR_NOT_AVAILABLE; - } + uint32_t desiredImageSize; + aIconURI->GetImageSize(&desiredImageSize); + nsAutoCString stockIcon; + aIconURI->GetStockIcon(stockIcon); - UINT infoFlags = SHGSI_ICON; - infoFlags |= GetSizeInfoFlag(desiredImageSize); + SHSTOCKICONID stockIconID = GetStockIconIDForName(stockIcon); + if (stockIconID == SIID_INVALID) { + return NS_ERROR_NOT_AVAILABLE; + } - SHSTOCKICONINFO sii = {0}; - sii.cbSize = sizeof(sii); - HRESULT hr = pSHGetStockIconInfo(stockIconID, infoFlags, &sii); + UINT infoFlags = SHGSI_ICON; + infoFlags |= GetSizeInfoFlag(desiredImageSize); - if (SUCCEEDED(hr)) { - *hIcon = sii.hIcon; - } else { - rv = NS_ERROR_FAILURE; - } - } else { - rv = NS_ERROR_NOT_AVAILABLE; - } + SHSTOCKICONINFO sii = {0}; + sii.cbSize = sizeof(sii); + HRESULT hr = SHGetStockIconInfo(stockIconID, infoFlags, &sii); - if (hShellDLL) { - ::FreeLibrary(hShellDLL); + if (SUCCEEDED(hr)) { + *hIcon = sii.hIcon; + } else { + rv = NS_ERROR_FAILURE; } return rv; |