/* Miranda IM: the free IM client for Microsoft* Windows* Copyright 2000-2009 Miranda ICQ/IM project, all portions of this codebase are copyrighted to the people listed in contributors.txt. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "..\..\core\commonheaders.h" #include #include "m_png.h" #include "m_imgsrvc.h" static INT_PTR sttBitmapLoader(const TCHAR* ptszFileName) { IPicture *pic; HBITMAP hBmp, hBmpCopy; HBITMAP hOldBitmap, hOldBitmap2; BITMAP bmpInfo; HDC hdc, hdcMem1, hdcMem2; short picType; TCHAR szFilename[MAX_PATH]; if ( !PathToAbsoluteT(ptszFileName, szFilename, NULL)) mir_sntprintf(szFilename, SIZEOF(szFilename), _T("%s"), ptszFileName); int filenameLen = lstrlen(szFilename); if (filenameLen > 4) { TCHAR* pszExt = szFilename + filenameLen - 4; if (ServiceExists(MS_IMG_LOAD)) return CallService(MS_IMG_LOAD, (WPARAM)szFilename, IMGL_TCHAR); if ( !lstrcmpi(pszExt, _T(".bmp")) || !lstrcmpi(pszExt, _T(".rle"))) { //LoadImage can do this much faster return (INT_PTR)LoadImage(hInst, szFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); } if ( !lstrcmpi(pszExt, _T(".png"))) { HANDLE hFile, hMap = NULL; BYTE* ppMap = NULL; INT_PTR cbFileSize = 0; BITMAPINFOHEADER* pDib; BYTE* pDibBits; if ( !ServiceExists(MS_PNG2DIB)) { MessageBox(NULL, TranslateT("You need an image services plugin to process PNG images."), TranslateT("Error"), MB_OK); return 0; } if ((hFile = CreateFile(szFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) if ((hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL) if ((ppMap = (BYTE*)MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL) cbFileSize = GetFileSize(hFile, NULL); if (cbFileSize != 0) { PNG2DIB param; param.pSource = ppMap; param.cbSourceSize = cbFileSize; param.pResult = &pDib; if (CallService(MS_PNG2DIB, 0, (LPARAM)¶m)) { pDibBits = (BYTE*)(pDib+1); HDC sDC = GetDC(NULL); HBITMAP hBitmap = CreateDIBitmap(sDC, pDib, CBM_INIT, pDibBits, (BITMAPINFO*)pDib, DIB_PAL_COLORS); SelectObject(sDC, hBitmap); ReleaseDC(NULL, sDC); GlobalFree(pDib); cbFileSize = (INT_PTR)hBitmap; } else cbFileSize = 0; } if (ppMap != NULL) UnmapViewOfFile(ppMap); if (hMap != NULL) CloseHandle(hMap); if (hFile != NULL) CloseHandle(hFile); return (INT_PTR)cbFileSize; } } if (S_OK != OleLoadPicturePath(LPOLESTR((const wchar_t*)StrConvU(szFilename)), NULL, 0, 0, IID_IPicture, (PVOID*)&pic)) return 0; pic->get_Type(&picType); if (picType != PICTYPE_BITMAP) { pic->Release(); return 0; } OLE_HANDLE hOleBmp; pic->get_Handle(&hOleBmp); hBmp = (HBITMAP)hOleBmp; GetObject(hBmp, sizeof(bmpInfo), &bmpInfo); //need to copy bitmap so we can free the IPicture hdc = GetDC(NULL); hdcMem1 = CreateCompatibleDC(hdc); hdcMem2 = CreateCompatibleDC(hdc); hOldBitmap = (HBITMAP)SelectObject(hdcMem1, hBmp); hBmpCopy = CreateCompatibleBitmap(hdcMem1, bmpInfo.bmWidth, bmpInfo.bmHeight); hOldBitmap2 = (HBITMAP)SelectObject(hdcMem2, hBmpCopy); BitBlt(hdcMem2, 0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, hdcMem1, 0, 0, SRCCOPY); SelectObject(hdcMem1, hOldBitmap); SelectObject(hdcMem2, hOldBitmap2); DeleteDC(hdcMem2); DeleteDC(hdcMem1); ReleaseDC(NULL, hdc); DeleteObject(hBmp); pic->Release(); return (INT_PTR)hBmpCopy; } static INT_PTR BmpFilterLoadBitmap(WPARAM, LPARAM lParam) { return sttBitmapLoader(StrConvT((const char*)lParam)); } static INT_PTR BmpFilterLoadBitmapW(WPARAM, LPARAM lParam) { return sttBitmapLoader((const wchar_t*)lParam); } /////////////////////////////////////////////////////////////////////////////////////////////////// static INT_PTR BmpFilterGetStrings(WPARAM wParam, LPARAM lParam) { int bytesLeft = wParam; char *filter = (char*)lParam, *pfilter; lstrcpynA(filter, Translate("All Bitmaps"), bytesLeft); bytesLeft-=lstrlenA(filter); strncat(filter, " (*.bmp;*.jpg;*.gif;*.png)", bytesLeft); pfilter = filter+lstrlenA(filter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, "*.BMP;*.RLE;*.JPG;*.JPEG;*.GIF;*.PNG", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, Translate("Windows Bitmaps"), bytesLeft); bytesLeft-=lstrlenA(pfilter); strncat(pfilter, " (*.bmp;*.rle)", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, "*.BMP;*.RLE", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, Translate("JPEG Bitmaps"), bytesLeft); bytesLeft-=lstrlenA(pfilter); strncat(pfilter, " (*.jpg;*.jpeg)", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, "*.JPG;*.JPEG", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, Translate("GIF Bitmaps"), bytesLeft); bytesLeft-=lstrlenA(pfilter); strncat(pfilter, " (*.gif)", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, "*.GIF", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, Translate("PNG Bitmaps"), bytesLeft); bytesLeft-=lstrlenA(pfilter); strncat(pfilter, " (*.png)", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, "*.PNG", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, Translate("All Files"), bytesLeft); bytesLeft-=lstrlenA(pfilter); strncat(pfilter, " (*)", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpynA(pfilter, "*", bytesLeft); pfilter+=lstrlenA(pfilter)+1; bytesLeft = wParam-(pfilter-filter); if (bytesLeft) *pfilter = '\0'; return 0; } static INT_PTR BmpFilterGetStringsW(WPARAM wParam, LPARAM lParam) { int bytesLeft = wParam; TCHAR *filter = (TCHAR*)lParam, *pfilter; lstrcpyn(filter, TranslateT("All Bitmaps"), bytesLeft); bytesLeft-=lstrlen(filter); _tcsncat(filter, _T(" (*.bmp;*.jpg;*.gif;*.png)"), bytesLeft); pfilter = filter+lstrlen(filter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, _T("*.BMP;*.RLE;*.JPG;*.JPEG;*.GIF;*.PNG"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, TranslateT("Windows Bitmaps"), bytesLeft); bytesLeft-=lstrlen(pfilter); _tcsncat(pfilter, _T(" (*.bmp;*.rle)"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, _T("*.BMP;*.RLE"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, TranslateT("JPEG Bitmaps"), bytesLeft); bytesLeft-=lstrlen(pfilter); _tcsncat(pfilter, _T(" (*.jpg;*.jpeg)"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, _T("*.JPG;*.JPEG"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, TranslateT("GIF Bitmaps"), bytesLeft); bytesLeft-=lstrlen(pfilter); _tcsncat(pfilter, _T(" (*.gif)"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, _T("*.GIF"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, TranslateT("PNG Bitmaps"), bytesLeft); bytesLeft-=lstrlen(pfilter); _tcsncat(pfilter, _T(" (*.png)"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, _T("*.PNG"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, TranslateT("All Files"), bytesLeft); bytesLeft-=lstrlen(pfilter); _tcsncat(pfilter, _T(" (*)"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); lstrcpyn(pfilter, _T("*"), bytesLeft); pfilter+=lstrlen(pfilter)+1; bytesLeft = wParam-(pfilter-filter); if (bytesLeft) *pfilter = '\0'; return 0; } int InitBitmapFilter(void) { CreateServiceFunction(MS_UTILS_LOADBITMAP, BmpFilterLoadBitmap); CreateServiceFunction(MS_UTILS_GETBITMAPFILTERSTRINGS, BmpFilterGetStrings); CreateServiceFunction(MS_UTILS_GETBITMAPFILTERSTRINGSW, BmpFilterGetStringsW); CreateServiceFunction(MS_UTILS_LOADBITMAPW, BmpFilterLoadBitmapW); return 0; }