PageRenderTime 25ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/Imaging-1.1.7/Imaging-1.1.7/libImaging/Dib.c

https://bitbucket.org/peluchejs/ku-a-aty
C | 311 lines | 198 code | 64 blank | 49 comment | 47 complexity | 9e68a5fb517a9215e7877c6fcd02f40e MD5 | raw file
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * imaging display object for Windows
  6. *
  7. * history:
  8. * 1996-05-12 fl Created
  9. * 1996-05-17 fl Up and running
  10. * 1996-05-21 fl Added palette stuff
  11. * 1996-05-26 fl Added query palette and mode inquery
  12. * 1997-09-21 fl Added draw primitive
  13. * 1998-01-20 fl Use StretchDIBits instead of StretchBlt
  14. * 1998-12-30 fl Plugged a resource leak in DeleteDIB (from Roger Burnham)
  15. *
  16. * Copyright (c) Secret Labs AB 1997-2001.
  17. * Copyright (c) Fredrik Lundh 1996.
  18. *
  19. * See the README file for information on usage and redistribution.
  20. */
  21. #include "Imaging.h"
  22. #ifdef WIN32
  23. #include "ImDib.h"
  24. char*
  25. ImagingGetModeDIB(int size_out[2])
  26. {
  27. /* Get device characteristics */
  28. HDC dc;
  29. char* mode;
  30. dc = CreateCompatibleDC(NULL);
  31. mode = "P";
  32. if (!(GetDeviceCaps(dc, RASTERCAPS) & RC_PALETTE)) {
  33. mode = "RGB";
  34. if (GetDeviceCaps(dc, BITSPIXEL) == 1)
  35. mode = "1";
  36. }
  37. if (size_out) {
  38. size_out[0] = GetDeviceCaps(dc, HORZRES);
  39. size_out[1] = GetDeviceCaps(dc, VERTRES);
  40. }
  41. DeleteDC(dc);
  42. return mode;
  43. }
  44. ImagingDIB
  45. ImagingNewDIB(const char *mode, int xsize, int ysize)
  46. {
  47. /* Create a Windows bitmap */
  48. ImagingDIB dib;
  49. RGBQUAD *palette;
  50. int i;
  51. /* Check mode */
  52. if (strcmp(mode, "1") != 0 && strcmp(mode, "L") != 0 &&
  53. strcmp(mode, "RGB") != 0)
  54. return (ImagingDIB) ImagingError_ModeError();
  55. /* Create DIB context and info header */
  56. dib = (ImagingDIB) malloc(sizeof(*dib));
  57. if (!dib)
  58. return (ImagingDIB) ImagingError_MemoryError();
  59. dib->info = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) +
  60. 256 * sizeof(RGBQUAD));
  61. if (!dib->info) {
  62. free(dib);
  63. return (ImagingDIB) ImagingError_MemoryError();
  64. }
  65. memset(dib->info, 0, sizeof(BITMAPINFOHEADER));
  66. dib->info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  67. dib->info->bmiHeader.biWidth = xsize;
  68. dib->info->bmiHeader.biHeight = ysize;
  69. dib->info->bmiHeader.biPlanes = 1;
  70. dib->info->bmiHeader.biBitCount = strlen(mode)*8;
  71. dib->info->bmiHeader.biCompression = BI_RGB;
  72. /* Create DIB */
  73. dib->dc = CreateCompatibleDC(NULL);
  74. if (!dib->dc) {
  75. free(dib->info);
  76. free(dib);
  77. return (ImagingDIB) ImagingError_MemoryError();
  78. }
  79. dib->bitmap = CreateDIBSection(dib->dc, dib->info, DIB_RGB_COLORS,
  80. &dib->bits, NULL, 0);
  81. if (!dib->bitmap) {
  82. free(dib->info);
  83. free(dib);
  84. return (ImagingDIB) ImagingError_MemoryError();
  85. }
  86. strcpy(dib->mode, mode);
  87. dib->xsize = xsize;
  88. dib->ysize = ysize;
  89. dib->pixelsize = strlen(mode);
  90. dib->linesize = (xsize * dib->pixelsize + 3) & -4;
  91. if (dib->pixelsize == 1)
  92. dib->pack = dib->unpack = (ImagingShuffler) memcpy;
  93. else {
  94. dib->pack = ImagingPackBGR;
  95. dib->unpack = ImagingPackBGR;
  96. }
  97. /* Bind the DIB to the device context */
  98. dib->old_bitmap = SelectObject(dib->dc, dib->bitmap);
  99. palette = dib->info->bmiColors;
  100. /* Bind a palette to it as well (only required for 8-bit DIBs) */
  101. if (dib->pixelsize == 1) {
  102. for (i = 0; i < 256; i++) {
  103. palette[i].rgbRed =
  104. palette[i].rgbGreen =
  105. palette[i].rgbBlue = i;
  106. palette[i].rgbReserved = 0;
  107. }
  108. SetDIBColorTable(dib->dc, 0, 256, palette);
  109. }
  110. /* Create an associated palette (for 8-bit displays only) */
  111. if (strcmp(ImagingGetModeDIB(NULL), "P") == 0) {
  112. char palbuf[sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY)];
  113. LPLOGPALETTE pal = (LPLOGPALETTE) palbuf;
  114. int i, r, g, b;
  115. /* Load system palette */
  116. pal->palVersion = 0x300;
  117. pal->palNumEntries = 256;
  118. GetSystemPaletteEntries(dib->dc, 0, 256, pal->palPalEntry);
  119. if (strcmp(mode, "L") == 0) {
  120. /* Greyscale DIB. Fill all 236 slots with a greyscale ramp
  121. * (this is usually overkill on Windows since VGA only offers
  122. * 6 bits greyscale resolution). Ignore the slots already
  123. * allocated by Windows */
  124. i = 10;
  125. for (r = 0; r < 236; r++) {
  126. pal->palPalEntry[i].peRed =
  127. pal->palPalEntry[i].peGreen =
  128. pal->palPalEntry[i].peBlue = i;
  129. i++;
  130. }
  131. dib->palette = CreatePalette(pal);
  132. } else if (strcmp(mode, "RGB") == 0) {
  133. #ifdef CUBE216
  134. /* Colour DIB. Create a 6x6x6 colour cube (216 entries) and
  135. * add 20 extra greylevels for best result with greyscale
  136. * images. */
  137. i = 10;
  138. for (r = 0; r < 256; r += 51)
  139. for (g = 0; g < 256; g += 51)
  140. for (b = 0; b < 256; b += 51) {
  141. pal->palPalEntry[i].peRed = r;
  142. pal->palPalEntry[i].peGreen = g;
  143. pal->palPalEntry[i].peBlue = b;
  144. i++;
  145. }
  146. for (r = 1; r < 22-1; r++) {
  147. /* Black and white are already provided by the cube. */
  148. pal->palPalEntry[i].peRed =
  149. pal->palPalEntry[i].peGreen =
  150. pal->palPalEntry[i].peBlue = r * 255 / (22-1);
  151. i++;
  152. }
  153. #else
  154. /* Colour DIB. Alternate palette. */
  155. i = 10;
  156. for (r = 0; r < 256; r += 37)
  157. for (g = 0; g < 256; g += 32)
  158. for (b = 0; b < 256; b += 64) {
  159. pal->palPalEntry[i].peRed = r;
  160. pal->palPalEntry[i].peGreen = g;
  161. pal->palPalEntry[i].peBlue = b;
  162. i++;
  163. }
  164. #endif
  165. #if 0
  166. {
  167. /* DEBUG: dump palette to file */
  168. FILE *err = fopen("dib.pal", "w");
  169. for (i = 0; i < 256; i++)
  170. fprintf(err, "%d: %d/%d/%d\n", i,
  171. pal->palPalEntry[i].peRed,
  172. pal->palPalEntry[i].peGreen,
  173. pal->palPalEntry[i].peBlue);
  174. fclose(err);
  175. }
  176. #endif
  177. dib->palette = CreatePalette(pal);
  178. }
  179. }
  180. return dib;
  181. }
  182. void
  183. ImagingPasteDIB(ImagingDIB dib, Imaging im, int xy[4])
  184. {
  185. /* Paste image data into a bitmap */
  186. /* FIXME: check size! */
  187. int y;
  188. for (y = 0; y < im->ysize; y++)
  189. dib->pack(dib->bits + dib->linesize*(dib->ysize-(xy[1]+y)-1) +
  190. xy[0]*dib->pixelsize, im->image[y], im->xsize);
  191. }
  192. void
  193. ImagingExposeDIB(ImagingDIB dib, int dc)
  194. {
  195. /* Copy bitmap to display */
  196. if (dib->palette != 0)
  197. SelectPalette((HDC) dc, dib->palette, FALSE);
  198. BitBlt((HDC) dc, 0, 0, dib->xsize, dib->ysize, dib->dc, 0, 0, SRCCOPY);
  199. }
  200. void
  201. ImagingDrawDIB(ImagingDIB dib, int dc, int dst[4], int src[4])
  202. {
  203. /* Copy bitmap to printer/display */
  204. if (GetDeviceCaps((HDC) dc, RASTERCAPS) & RC_STRETCHDIB) {
  205. /* stretchdib (printers) */
  206. StretchDIBits((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1],
  207. src[0], src[1], src[2]-src[0], src[3]-src[1], dib->bits,
  208. dib->info, DIB_RGB_COLORS, SRCCOPY);
  209. } else {
  210. /* stretchblt (displays) */
  211. if (dib->palette != 0)
  212. SelectPalette((HDC) dc, dib->palette, FALSE);
  213. StretchBlt((HDC) dc, dst[0], dst[1], dst[2]-dst[0], dst[3]-dst[1],
  214. dib->dc, src[0], src[1], src[2]-src[0], src[3]-src[1],
  215. SRCCOPY);
  216. }
  217. }
  218. int
  219. ImagingQueryPaletteDIB(ImagingDIB dib, int dc)
  220. {
  221. /* Install bitmap palette */
  222. int n;
  223. if (dib->palette != 0) {
  224. /* Realize associated palette */
  225. HPALETTE now = SelectPalette((HDC) dc, dib->palette, FALSE);
  226. n = RealizePalette((HDC) dc);
  227. /* Restore palette */
  228. SelectPalette((HDC) dc, now, FALSE);
  229. } else
  230. n = 0;
  231. return n; /* number of colours that was changed */
  232. }
  233. void
  234. ImagingDeleteDIB(ImagingDIB dib)
  235. {
  236. /* Clean up */
  237. if (dib->palette)
  238. DeleteObject(dib->palette);
  239. if (dib->bitmap) {
  240. SelectObject(dib->dc, dib->old_bitmap);
  241. DeleteObject(dib->bitmap);
  242. }
  243. if (dib->dc)
  244. DeleteDC(dib->dc);
  245. free(dib->info);
  246. }
  247. #endif /* WIN32 */