/* Plugin of Miranda IM for reading/writing PNG images. Copyright (c) 2004-06 George Hazan (ghazan@postman.ru) Portions of this code are gotten from the libpng codebase. Copyright 2000, Willem van Schaik. For conditions of distribution and use, see the copyright/license/disclaimer notice in png.h Miranda IM: the free icq client for MS Windows Copyright (C) 2000-2002 Richard Hughes, Roland Rabien & Tristan Van de Vreede 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 "stdafx.h" /* * freeimage helper functions */ // Correct alpha from bitmaps loaded without it (it cames with 0 and should be 255) // originally in loadavatars... EXTERN_C DLL_API void DLL_CALLCONV FreeImage_CorrectBitmap32Alpha(HBITMAP hBitmap, BOOL force) { BITMAP bmp; uint32_t dwLen; uint8_t *p; int x, y; BOOL fixIt; GetObject(hBitmap, sizeof(bmp), &bmp); if (bmp.bmBitsPixel != 32) return; dwLen = bmp.bmWidth * bmp.bmHeight * (bmp.bmBitsPixel / 8); p = (uint8_t *)malloc(dwLen); if (p == nullptr) return; memset(p, 0, dwLen); GetBitmapBits(hBitmap, dwLen, p); fixIt = TRUE; for (y = 0; fixIt && y < bmp.bmHeight; ++y) { uint8_t *px = p + bmp.bmWidth * 4 * y; for (x = 0; fixIt && x < bmp.bmWidth; ++x) { if (px[3] != 0 && !force) { fixIt = FALSE; } else { px[3] = 255; } px += 4; } } if (fixIt) SetBitmapBits(hBitmap, dwLen, p); free(p); } /* * needed for per pixel transparent images. Such images should then be rendered by * using AlphaBlend() with AC_SRC_ALPHA * dwFlags will be set to AVS_PREMULTIPLIED * return TRUE if the image has at least one pixel with transparency */ EXTERN_C DLL_API BOOL DLL_CALLCONV FreeImage_Premultiply(HBITMAP hBitmap) { BOOL transp = FALSE; BITMAP bmp; GetObject(hBitmap, sizeof(bmp), &bmp); if (bmp.bmBitsPixel == 32) { int width = bmp.bmWidth; int height = bmp.bmHeight; int dwLen = width * height * 4; uint8_t *p = (uint8_t *)malloc(dwLen); if (p != nullptr) { GetBitmapBits(hBitmap, dwLen, p); for (int y = 0; y < height; ++y) { uint8_t *px = p + width * 4 * y; for (int x = 0; x < width; ++x) { uint8_t alpha = px[3]; if (alpha < 255) { transp = TRUE; px[0] = px[0] * alpha/255; px[1] = px[1] * alpha/255; px[2] = px[2] * alpha/255; } px += 4; } } if (transp) dwLen = SetBitmapBits(hBitmap, dwLen, p); free(p); } } return transp; } EXTERN_C DLL_API HBITMAP DLL_CALLCONV FreeImage_CreateHBITMAPFromDIB(FIBITMAP *in) { FIBITMAP *dib = nullptr; int bpp = FreeImage_GetBPP(in); if (bpp == 48) dib = FreeImage_ConvertTo24Bits(in); else if (FreeImage_GetBPP(in) > 32) dib = FreeImage_ConvertTo32Bits(in); else dib = in; uint8_t *ptPixels; BITMAPINFO *info = FreeImage_GetInfo(dib); HBITMAP hBmp = CreateDIBSection(nullptr, info, DIB_RGB_COLORS, (void **)&ptPixels, nullptr, 0); if (ptPixels != nullptr) memmove(ptPixels, FreeImage_GetBits(dib), FreeImage_GetPitch(dib) * FreeImage_GetHeight(dib)); if (dib != in) FreeImage_Unload(dib); return hBmp; } EXTERN_C DLL_API FIBITMAP* DLL_CALLCONV FreeImage_CreateDIBFromHBITMAP(HBITMAP hBmp) { if (!hBmp) return nullptr; BITMAP bm; GetObject(hBmp, sizeof(BITMAP), (LPSTR) &bm); FIBITMAP *dib = FreeImage_Allocate(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel,0,0,0); // The GetDIBits function clears the biClrUsed and biClrImportant BITMAPINFO members (dont't know why) // So we save these infos below. This is needed for palettized images only. int nColors = FreeImage_GetColorsUsed(dib); HDC dc = GetDC(nullptr); GetDIBits(dc, hBmp, 0, FreeImage_GetHeight(dib), FreeImage_GetBits(dib), FreeImage_GetInfo(dib), DIB_RGB_COLORS); ReleaseDC(nullptr, dc); // restore BITMAPINFO members FreeImage_GetInfoHeader(dib)->biClrUsed = nColors; FreeImage_GetInfoHeader(dib)->biClrImportant = nColors; return dib; }