/* * libpipi Pathetic image processing interface library * Copyright (c) 2004-2008 Sam Hocevar * All Rights Reserved * * $Id$ * * This library is free software. It comes without any warranty, to * the extent permitted by applicable law. You can redistribute it * and/or modify it under the terms of the Do What The Fuck You Want * To Public License, Version 2, as published by Sam Hocevar. See * http://sam.zoy.org/wtfpl/COPYING for more details. */ /* * gdi.c: Windows GDI I/O functions (BMP only) */ #include "config.h" #include #include #include #include #include extern "C" { #include "pipi.h" #include "pipi_internals.h" } extern "C" pipi_image_t *pipi_load_gdiplus(const char *name) { size_t len; len = mbstowcs(NULL, name, 0); wchar_t *wname = new wchar_t[len + 1]; if(mbstowcs(wname, name, len + 1) == (size_t)-1) { delete[] wname; return NULL; } ULONG_PTR token; Gdiplus::GdiplusStartupInput input; Gdiplus::GdiplusStartup(&token, &input, NULL); Gdiplus::Bitmap *b = Gdiplus::Bitmap::FromFile(wname, 0); if(!b) { delete[] wname; return NULL; } delete[] wname; Gdiplus::BitmapData bdata; Gdiplus::Rect rect(0, 0, b->GetWidth(), b->GetHeight()); if(b->LockBits(&rect, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, &bdata) != Gdiplus::Ok) { delete b; return NULL; } pipi_image_t *img = pipi_new(b->GetWidth(), b->GetHeight()); pipi_pixels_t *p = pipi_get_pixels(img, PIPI_PIXELS_RGBA_U8); memcpy(p->pixels, bdata.Scan0, bdata.Width * bdata.Height * 4); b->UnlockBits(&bdata); delete b; img->codec_priv = NULL; img->wrap = 0; img->u8 = 1; return img; } extern "C" int pipi_save_gdiplus(pipi_image_t *img, const char *name) { ULONG_PTR token; Gdiplus::GdiplusStartupInput input; Gdiplus::GdiplusStartup(&token, &input, NULL); wchar_t const *fmt; if(strstr(name, ".gif")) fmt = L"image/gif"; else if(strstr(name, ".jpeg") || strstr(name, ".jpeg")) fmt = L"image/jpeg"; else if(strstr(name, ".png")) fmt = L"image/png"; else if(strstr(name, ".tiff")) fmt = L"image/tiff"; else /* if(strstr(name, ".bmp")) */ fmt = L"image/bmp"; unsigned int num = 0, size = 0; Gdiplus::GetImageEncodersSize(&num, &size); if(size == 0) return -1; Gdiplus::ImageCodecInfo *codecs = (Gdiplus::ImageCodecInfo *)(malloc(size)); if(!codecs) return -1; Gdiplus::GetImageEncoders(num, size, codecs); CLSID clsid; for(unsigned int i = 0; i < num; i++) { if(wcscmp(codecs[i].MimeType, fmt) == 0) { clsid = codecs[i].Clsid; break; } } size_t len; len = mbstowcs(NULL, name, 0); wchar_t *wname = new wchar_t[len + 1]; if(mbstowcs(wname, name, len + 1) == (size_t)-1) { delete[] wname; return -1; } Gdiplus::Bitmap *b = new Gdiplus::Bitmap(img->w, img->h, PixelFormat32bppARGB); Gdiplus::BitmapData bdata; Gdiplus::Rect rect(0, 0, img->w, img->h); if(b->LockBits(&rect, (unsigned int)Gdiplus::ImageLockModeWrite, PixelFormat32bppARGB, &bdata) != Gdiplus::Ok) { delete b; return -1; } pipi_pixels_t *p = pipi_get_pixels(img, PIPI_PIXELS_RGBA_U8); memcpy(bdata.Scan0, p->pixels, bdata.Width * bdata.Height * 4); b->UnlockBits(&bdata); if(b->Save(wname, &clsid, NULL) != Gdiplus::Ok) { delete[] wname; delete b; return -1; } delete[] wname; delete b; return 0; } /* * XXX: The following functions are local. */