|
- /*
- * libpipi Pathetic image processing interface library
- * Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
- * 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 <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <windows.h>
-
- #include <Gdiplus.h>
-
- 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.
- */
|