From 4ff0acc120ea0334dc36c2f11adab478c92803a0 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Tue, 29 Oct 2024 13:32:33 +0300 Subject: fixes #4610 (NewStory: WebP pictures aren't shown) --- plugins/NewStory/src/history_control.h | 4 +- plugins/NewStory/src/stdafx.h | 2 +- plugins/NewStory/src/templates.cpp | 4 +- plugins/NewStory/src/utils.cpp | 25 +++------ plugins/NewStory/src/utils.h | 2 +- plugins/NewStory/src/webpage.cpp | 92 +++++++++++++++------------------- 6 files changed, 52 insertions(+), 77 deletions(-) (limited to 'plugins') diff --git a/plugins/NewStory/src/history_control.h b/plugins/NewStory/src/history_control.h index f7fcb8b570..a313a85091 100644 --- a/plugins/NewStory/src/history_control.h +++ b/plugins/NewStory/src/history_control.h @@ -82,8 +82,8 @@ public: COLORREF clText = -1, clBack = -1; - Bitmap* find_image(const wchar_t *pwszUrl); - Bitmap* load_image(const wchar_t *pwszUrl, ItemData *pItem); + FIBITMAP* find_image(const wchar_t *pwszUrl); + FIBITMAP* load_image(const wchar_t *pwszUrl, ItemData *pItem); void draw(); }; diff --git a/plugins/NewStory/src/stdafx.h b/plugins/NewStory/src/stdafx.h index a0edec01c5..6f3d1440b1 100644 --- a/plugins/NewStory/src/stdafx.h +++ b/plugins/NewStory/src/stdafx.h @@ -107,7 +107,7 @@ struct CMPlugin : public PLUGIN HANDLE m_log; HBRUSH hBackBrush; - Bitmap *m_pNoImage; + FIBITMAP *m_pNoImage; ULONG_PTR m_gdiplusToken; CMOption bOptVScroll, bSortAscending; diff --git a/plugins/NewStory/src/templates.cpp b/plugins/NewStory/src/templates.cpp index e915e468ae..800d73b749 100644 --- a/plugins/NewStory/src/templates.cpp +++ b/plugins/NewStory/src/templates.cpp @@ -52,8 +52,8 @@ static void AppendImage(CMStringW &buf, const CMStringW &wszUrl, const CMStringW int iHeight = uMaxHeight; if (auto *pImage = pItem->pOwner->webPage.find_image(wszUrl)) { - if (pImage->GetHeight() < uMaxHeight) - iHeight = pImage->GetHeight(); + if (FreeImage_GetHeight(pImage) < uMaxHeight) + iHeight = FreeImage_GetHeight(pImage); buf.AppendFormat(L"
", iHeight, wszUrl.c_str()); } diff --git a/plugins/NewStory/src/utils.cpp b/plugins/NewStory/src/utils.cpp index f6aca92604..811eac0e0d 100644 --- a/plugins/NewStory/src/utils.cpp +++ b/plugins/NewStory/src/utils.cpp @@ -20,27 +20,14 @@ along with this program. If not, see . #include -Bitmap* LoadImageFromResource(HINSTANCE hInst, int resourceId, const wchar_t *pwszType) +FIBITMAP* LoadImageFromResource(HINSTANCE hInst, int resourceId, const wchar_t *pwszType) { if (HRSRC hrsrc = FindResourceW(hInst, MAKEINTRESOURCE(resourceId), pwszType)) { - if (DWORD dwSize = SizeofResource(hInst, hrsrc)) { - if (HGLOBAL hRes = LoadResource(hInst, hrsrc)) { - void *pImage = LockResource(hRes); - - if (HGLOBAL hGlobal = ::GlobalAlloc(GHND, dwSize)) { - void *pBuffer = ::GlobalLock(hGlobal); - if (pBuffer) { - memcpy(pBuffer, pImage, dwSize); - - CComPtr pStream; - HRESULT hr = CreateStreamOnHGlobal(hGlobal, TRUE, &pStream); - if (SUCCEEDED(hr)) - return new Gdiplus::Bitmap(pStream); - } - - GlobalFree(hGlobal); // free memory only if the function fails - } - } + if (HGLOBAL hRes = LoadResource(hInst, hrsrc)) { + auto *pMemory = FreeImage_OpenMemory((uint8_t*)LockResource(hRes), SizeofResource(hInst, hrsrc)); + auto *pDib = FreeImage_LoadFromMemory(FIF_PNG, pMemory); + FreeImage_CloseMemory(pMemory); + return pDib; } } diff --git a/plugins/NewStory/src/utils.h b/plugins/NewStory/src/utils.h index 1858c34d9c..f18a5944d9 100644 --- a/plugins/NewStory/src/utils.h +++ b/plugins/NewStory/src/utils.h @@ -12,6 +12,6 @@ int GetFontHeight(const LOGFONTA &lf); void UrlAutodetect(CMStringW &str); void RemoveBbcodes(CMStringW &pwszText); -Bitmap* LoadImageFromResource(HINSTANCE, int, const wchar_t *); +FIBITMAP* LoadImageFromResource(HINSTANCE, int, const wchar_t *); int SmartSendEvent(int iEvent, MCONTACT hContact, LPARAM lParam); diff --git a/plugins/NewStory/src/webpage.cpp b/plugins/NewStory/src/webpage.cpp index 7ce346a17c..3e098fbd37 100644 --- a/plugins/NewStory/src/webpage.cpp +++ b/plugins/NewStory/src/webpage.cpp @@ -325,16 +325,16 @@ void NSWebPage::draw_list_marker(uint_ptr hdc, const list_marker &marker) release_clip((HDC)hdc); } -Bitmap* NSWebPage::load_image(const wchar_t *pwszUrl, ItemData *pItem) +FIBITMAP* NSWebPage::load_image(const wchar_t *pwszUrl, ItemData *pItem) { mir_cslockfull lck(m_csImages); auto img = m_images.find(pwszUrl); if (img != m_images.end() && img->second) - return (Bitmap *)img->second; + return (FIBITMAP *)img->second; if (uint_ptr newImg = get_image(pwszUrl, false)) { add_image(pwszUrl, newImg); - return (Bitmap *)newImg; + return (FIBITMAP *)newImg; } NSWebCache tmp(this, pwszUrl, pItem); @@ -364,12 +364,12 @@ void NSWebPage::add_image(LPCWSTR url, uint_ptr img) m_images[url] = img; } -Bitmap* NSWebPage::find_image(const wchar_t *pwszUrl) +FIBITMAP* NSWebPage::find_image(const wchar_t *pwszUrl) { mir_cslock lck(m_csImages); auto img = m_images.find(pwszUrl); if (img != m_images.end() && img->second) - return (Bitmap *)img->second; + return (FIBITMAP *)img->second; return nullptr; } @@ -391,7 +391,7 @@ void NSWebPage::clear_images() mir_cslock lck(m_csImages); for (auto &img : m_images) if (img.second) - delete (Bitmap *)img.second; + delete (FIBITMAP *)img.second; m_images.clear(); } @@ -487,6 +487,13 @@ void NSWebPage::link(const document::ptr &, const element::ptr &) ///////////////////////////////////////////////////////////////////////////////////////// // GDI+ part (former gdiplus_container) +static void FreeImage_Draw(HDC hdc, FIBITMAP *pdib, int x, int y, int w, int h) +{ + BITMAPINFO *pbmpi = FreeImage_GetInfo(pdib); + BYTE *pDibBits = FreeImage_GetBits(pdib); + ::SetDIBitsToDevice(hdc, x, y, w, h, 0, 0, 0, h, pDibBits, pbmpi, DIB_RGB_COLORS); +} + static Color gdiplus_color(web_color color) { return Color(color.alpha, color.red, color.green, color.blue); @@ -524,10 +531,10 @@ void NSWebPage::fill_rect(HDC hdc, int x, int y, int width, int height, web_colo void NSWebPage::get_img_size(uint_ptr img, size &sz) { - Bitmap *bmp = (Bitmap *)img; + FIBITMAP *bmp = (FIBITMAP *)img; if (bmp) { - sz.width = bmp->GetWidth(); - sz.height = bmp->GetHeight(); + sz.width = FreeImage_GetWidth(bmp); + sz.height = FreeImage_GetHeight(bmp); } } @@ -538,7 +545,7 @@ void NSWebPage::draw_image(uint_ptr _hdc, const background_layer &bg, const std: std::wstring url = Utf2T(src.c_str()); - Bitmap *bgbmp = find_image(url.c_str()); + FIBITMAP *bgbmp = find_image(url.c_str()); if (!bgbmp) bgbmp = g_plugin.m_pNoImage; @@ -546,62 +553,54 @@ void NSWebPage::draw_image(uint_ptr _hdc, const background_layer &bg, const std: graphics.SetInterpolationMode(Gdiplus::InterpolationModeNearestNeighbor); graphics.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHalf); - Region reg(Rect(bg.border_box.left(), bg.border_box.top(), bg.border_box.width, bg.border_box.height)); + Gdiplus::Region reg(Rect(bg.border_box.left(), bg.border_box.top(), bg.border_box.width, bg.border_box.height)); graphics.SetClip(®); - Bitmap *scaled_img = nullptr; - if (bg.origin_box.width != (int)bgbmp->GetWidth() || bg.origin_box.height != (int)bgbmp->GetHeight()) { - scaled_img = new Bitmap(bg.origin_box.width, bg.origin_box.height); - Graphics gr(scaled_img); - gr.SetPixelOffsetMode(Gdiplus::PixelOffsetModeHighQuality); - gr.DrawImage(bgbmp, 0, 0, bg.origin_box.width, bg.origin_box.height); - bgbmp = scaled_img; + FIBITMAP *scaled_img = nullptr; + int iWidth = FreeImage_GetHeight(bgbmp), iHeight = FreeImage_GetWidth(bgbmp); + if (bg.origin_box.width != iWidth || bg.origin_box.height != iHeight) { + bgbmp = scaled_img = FreeImage_Rescale(bgbmp, bg.origin_box.width, bg.origin_box.height); + iWidth = bg.origin_box.width; iHeight = bg.origin_box.height; } switch (bg.repeat) { case background_repeat_no_repeat: - { - graphics.DrawImage(bgbmp, bg.origin_box.x, bg.origin_box.y, bgbmp->GetWidth(), bgbmp->GetHeight()); - } + FreeImage_Draw((HDC)_hdc, bgbmp, bg.origin_box.x, bg.origin_box.y, iWidth, iHeight); break; + case background_repeat_repeat_x: { - CachedBitmap bmp(bgbmp, &graphics); int x = bg.origin_box.x; - while (x > bg.clip_box.left()) x -= bgbmp->GetWidth(); - for (; x < bg.clip_box.right(); x += bgbmp->GetWidth()) { - graphics.DrawCachedBitmap(&bmp, x, bg.origin_box.y); - } + while (x > bg.clip_box.left()) + x -= iWidth; + for (; x < bg.clip_box.right(); x += iWidth) + FreeImage_Draw((HDC)_hdc, bgbmp, x, bg.origin_box.y, iWidth, iHeight); } break; case background_repeat_repeat_y: { - CachedBitmap bmp(bgbmp, &graphics); int y = bg.origin_box.y; - while (y > bg.clip_box.top()) y -= bgbmp->GetHeight(); - for (; y < bg.clip_box.bottom(); y += bgbmp->GetHeight()) { - graphics.DrawCachedBitmap(&bmp, bg.origin_box.x, y); - } + while (y > bg.clip_box.top()) y -= iHeight; + for (; y < bg.clip_box.bottom(); y += iHeight) + FreeImage_Draw((HDC)_hdc, bgbmp, bg.origin_box.x, y, iWidth, iHeight); } break; case background_repeat_repeat: { - CachedBitmap bmp(bgbmp, &graphics); int x = bg.origin_box.x; - while (x > bg.clip_box.left()) x -= bgbmp->GetWidth(); + while (x > bg.clip_box.left()) x -= iWidth; int y0 = bg.origin_box.y; - while (y0 > bg.clip_box.top()) y0 -= bgbmp->GetHeight(); + while (y0 > bg.clip_box.top()) y0 -= iHeight; - for (; x < bg.clip_box.right(); x += bgbmp->GetWidth()) { - for (int y = y0; y < bg.clip_box.bottom(); y += bgbmp->GetHeight()) { - graphics.DrawCachedBitmap(&bmp, x, y); - } - } + for (; x < bg.clip_box.right(); x += iWidth) + for (int y = y0; y < bg.clip_box.bottom(); y += iHeight) + FreeImage_Draw((HDC)_hdc, bgbmp, x, y, iWidth, iHeight); } break; } - delete scaled_img; + if (scaled_img) + FreeImage_Unload(scaled_img); } // length of dash and space for "dashed" style, in multiples of pen width @@ -697,18 +696,7 @@ uint_ptr NSWebPage::get_image(LPCWSTR url_or_path, bool) if (!mir_wstrncmp(url_or_path, L"file://", 7)) url_or_path += 7; - IStream *pStream = 0; - HRESULT hr = SHCreateStreamOnFileEx(url_or_path, STGM_READ | STGM_SHARE_DENY_NONE, 0, FALSE, 0, &pStream); - if (!SUCCEEDED(hr)) - return 0; - - auto *pImage = new Gdiplus::Bitmap(pStream); - pStream->Release(); - if (pImage->GetLastStatus() != Ok) { - delete pImage; - return 0; - } - return (uint_ptr)pImage; + return (uint_ptr)FreeImage_LoadU(FreeImage_GetFIFFromFilenameU(url_or_path), url_or_path); } void NSWebPage::get_client_rect(position &pos) const -- cgit v1.2.3