You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

154 lines
4.1 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 "common.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <windows.h>
  23. #include "pipi.h"
  24. #include "pipi_internals.h"
  25. pipi_image_t *pipi_load_gdi(const char *name)
  26. {
  27. BITMAPINFO binfo;
  28. pipi_image_t *img;
  29. pipi_pixels_t *p;
  30. uint8_t *data;
  31. HBITMAP hbmap;
  32. HDC hdc;
  33. int x, y;
  34. hbmap = (HBITMAP)LoadImage(NULL, name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  35. if(!hbmap)
  36. return NULL;
  37. hdc = CreateCompatibleDC(NULL);
  38. SelectObject(hdc, hbmap);
  39. memset(&binfo, 0, sizeof(binfo));
  40. binfo.bmiHeader.biSize = sizeof(binfo.bmiHeader);
  41. if(!GetDIBits(hdc, hbmap, 0, 0, 0, &binfo, DIB_RGB_COLORS))
  42. {
  43. ReleaseDC(0, hdc);
  44. DeleteObject(hbmap);
  45. return NULL;
  46. }
  47. img = pipi_new(binfo.bmiHeader.biWidth, binfo.bmiHeader.biHeight);
  48. p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
  49. data = p->pixels;
  50. binfo.bmiHeader.biBitCount = 32;
  51. binfo.bmiHeader.biCompression = BI_RGB;
  52. binfo.bmiHeader.biHeight = - abs(binfo.bmiHeader.biHeight);
  53. if(!GetDIBits(hdc, hbmap, 0, binfo.bmiHeader.biHeight, data,
  54. &binfo, DIB_RGB_COLORS))
  55. {
  56. ReleaseDC(0, hdc);
  57. DeleteObject(hbmap);
  58. return NULL;
  59. }
  60. /* FIXME: get rid of this loop, maybe by using BITMAPV4HEADER above
  61. * so that GDI reorders the pixels for us. */
  62. for(y = 0; y < img->h; y++)
  63. for(x = 0; x < img->w; x++)
  64. {
  65. /* Swap B and R, don't touch G and A. */
  66. uint8_t tmp = data[0]; data[0] = data[2]; data[2] = tmp;
  67. data += 4;
  68. }
  69. img->codec_priv = NULL;
  70. img->wrap = 0;
  71. img->u8 = 1;
  72. ReleaseDC(0, hdc);
  73. DeleteObject(hbmap);
  74. return img;
  75. }
  76. int pipi_save_gdi(pipi_image_t *img, const char *name)
  77. {
  78. BITMAPINFOHEADER binfo;
  79. BITMAPFILEHEADER bfheader;
  80. uint8_t dummy[4] = { 0 };
  81. HANDLE hfile;
  82. pipi_pixels_t *p;
  83. DWORD ret = 0;
  84. uint8_t *data;
  85. int x, y, padding;
  86. p = pipi_getpixels(img, PIPI_PIXELS_RGBA_C);
  87. data = p->pixels;
  88. padding = ((img->w * 3) + 3) / 4 * 4 - img->w * 3;
  89. memset(&binfo, 0, sizeof(binfo));
  90. binfo.biSize = sizeof(binfo);
  91. binfo.biWidth = img->w;
  92. binfo.biHeight = img->h;
  93. binfo.biPlanes = 1;
  94. binfo.biBitCount = 24;
  95. binfo.biCompression = BI_RGB;
  96. binfo.biSizeImage = (img->w * 3 + padding) * img->h;
  97. memset(&bfheader, 0, sizeof(bfheader));
  98. bfheader.bfType = 0x4D42;
  99. bfheader.bfOffBits = sizeof(bfheader) + sizeof(binfo);
  100. bfheader.bfSize = bfheader.bfOffBits + binfo.biSizeImage;
  101. /* We don’t even create the bitmap object, since we know exactly
  102. * what kind of file we are saving. But later, when we support
  103. * different depths and BMP options, we'll need to care about it. */
  104. hfile = CreateFile(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  105. FILE_ATTRIBUTE_ARCHIVE, NULL);
  106. if(!hfile)
  107. return -1;
  108. WriteFile(hfile, &bfheader, sizeof(bfheader), &ret, NULL);
  109. WriteFile(hfile, &binfo, sizeof(binfo), &ret, NULL);
  110. for(y = 0; y < img->h; y++)
  111. {
  112. for(x = 0; x < img->w; x++)
  113. {
  114. uint8_t tmp[3];
  115. tmp[0] = data[4 * (img->w * (img->h - 1 - y) + x) + 2];
  116. tmp[1] = data[4 * (img->w * (img->h - 1 - y) + x) + 1];
  117. tmp[2] = data[4 * (img->w * (img->h - 1 - y) + x) + 0];
  118. WriteFile(hfile, tmp, 3, &ret, NULL);
  119. }
  120. if(padding)
  121. WriteFile(hfile, dummy, padding, &ret, NULL);
  122. }
  123. CloseHandle(hfile);
  124. return 0;
  125. }
  126. /*
  127. * XXX: The following functions are local.
  128. */