Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

159 lignes
3.8 KiB

  1. /*
  2. * libpipi Pathetic image processing interface library
  3. * Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This library is free software. It comes without any warranty, to
  9. * the extent permitted by applicable law. You can redistribute it
  10. * and/or modify it under the terms of the Do What The Fuck You Want
  11. * To Public License, Version 2, as published by Sam Hocevar. See
  12. * http://sam.zoy.org/wtfpl/COPYING for more details.
  13. */
  14. /*
  15. * gdi.c: Windows GDI I/O functions (BMP only)
  16. */
  17. #include "config.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <windows.h>
  22. #include <gdiplus.h>
  23. #include "pipi.h"
  24. #include "pipi_internals.h"
  25. extern "C" pipi_image_t *pipi_load_gdiplus(const char *name)
  26. {
  27. size_t len;
  28. if(mbstowcs_s(&len, NULL, 0, name, _TRUNCATE) != 0)
  29. return NULL;
  30. wchar_t *wname = new wchar_t[len];
  31. if(mbstowcs_s(NULL, wname, len, name, _TRUNCATE) != 0)
  32. {
  33. delete[] wname;
  34. return NULL;
  35. }
  36. ULONG_PTR token;
  37. Gdiplus::GdiplusStartupInput input;
  38. Gdiplus::GdiplusStartup(&token, &input, NULL);
  39. Gdiplus::Bitmap *b = Gdiplus::Bitmap::FromFile(wname, 0);
  40. if(!b)
  41. {
  42. delete[] wname;
  43. return NULL;
  44. }
  45. delete[] wname;
  46. Gdiplus::BitmapData bdata;
  47. Gdiplus::Rect rect(0, 0, b->GetWidth(), b->GetHeight());
  48. if(b->LockBits(&rect, Gdiplus::ImageLockModeRead,
  49. PixelFormat32bppARGB, &bdata) != Gdiplus::Ok)
  50. {
  51. delete b;
  52. return NULL;
  53. }
  54. pipi_image_t *img = pipi_new(b->GetWidth(), b->GetHeight());
  55. pipi_pixels_t *p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
  56. memcpy(p->pixels, bdata.Scan0, bdata.Width * bdata.Height * 4);
  57. b->UnlockBits(&bdata);
  58. delete b;
  59. img->codec_priv = NULL;
  60. img->wrap = 0;
  61. img->u8 = 1;
  62. return img;
  63. }
  64. extern "C" int pipi_save_gdiplus(pipi_image_t *img, const char *name)
  65. {
  66. wchar_t const *fmt;
  67. if(strstr(name, ".gif"))
  68. fmt = L"image/gif";
  69. else if(strstr(name, ".jpeg") || strstr(name, ".jpeg"))
  70. fmt = L"image/jpeg";
  71. else if(strstr(name, ".png"))
  72. fmt = L"image/png";
  73. else if(strstr(name, ".tiff"))
  74. fmt = L"image/tiff";
  75. unsigned int num = 0, size = 0;
  76. Gdiplus::GetImageEncodersSize(&num, &size);
  77. if(size == 0)
  78. return -1;
  79. Gdiplus::ImageCodecInfo *codecs
  80. = (Gdiplus::ImageCodecInfo *)(malloc(size));
  81. if(!codecs)
  82. return -1;
  83. Gdiplus::GetImageEncoders(num, size, codecs);
  84. CLSID clsid;
  85. for(unsigned int i = 0; i < num; i++)
  86. {
  87. if(wcscmp(codecs[i].MimeType, fmt) == 0)
  88. {
  89. clsid = codecs[i].Clsid;
  90. break;
  91. }
  92. }
  93. size_t len;
  94. if(mbstowcs_s(&len, NULL, 0, name, _TRUNCATE) != 0)
  95. return NULL;
  96. wchar_t *wname = new wchar_t[len];
  97. if(mbstowcs_s(NULL, wname, len, name, _TRUNCATE) != 0)
  98. {
  99. delete[] wname;
  100. return -1;
  101. }
  102. ULONG_PTR token;
  103. Gdiplus::GdiplusStartupInput input;
  104. Gdiplus::GdiplusStartup(&token, &input, NULL);
  105. Gdiplus::Bitmap *b = new Gdiplus::Bitmap(img->w, img->h,
  106. PixelFormat32bppARGB);
  107. Gdiplus::BitmapData bdata;
  108. Gdiplus::Rect rect(0, 0, img->w, img->h);
  109. if(b->LockBits(&rect, Gdiplus::ImageLockModeWrite,
  110. PixelFormat32bppARGB, &bdata) != Gdiplus::Ok)
  111. {
  112. delete b;
  113. return -1;
  114. }
  115. pipi_pixels_t *p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
  116. memcpy(bdata.Scan0, p->pixels, bdata.Width * bdata.Height * 4);
  117. b->UnlockBits(&bdata);
  118. if(b->Save(wname, &clsid, NULL) != Gdiplus::Ok)
  119. {
  120. delete[] wname;
  121. delete b;
  122. return -1;
  123. }
  124. delete[] wname;
  125. delete b;
  126. return 0;
  127. }
  128. /*
  129. * XXX: The following functions are local.
  130. */