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.

common-image.c 6.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Imaging tools for cacaview and img2irc
  3. * Copyright (c) 2003-2006 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the Do What The Fuck You Want To
  10. * Public License, Version 2, as published by Sam Hocevar. See
  11. * http://sam.zoy.org/wtfpl/COPYING for more details.
  12. */
  13. #include "config.h"
  14. #include "common.h"
  15. #if !defined(__KERNEL__)
  16. # include <stdio.h>
  17. # include <string.h>
  18. # include <stdlib.h>
  19. #endif
  20. #if defined(USE_IMLIB2)
  21. # include <Imlib2.h>
  22. #else
  23. # if !defined(__KERNEL__)
  24. # include <stdio.h>
  25. # endif
  26. #endif
  27. #include "cucul.h"
  28. #include "common-image.h"
  29. #if !defined(USE_IMLIB2)
  30. static unsigned int u32fread(FILE *);
  31. static unsigned int u16fread(FILE *);
  32. static unsigned int u8fread(FILE *);
  33. #endif
  34. struct image * load_image(char const * name)
  35. {
  36. struct image * im = malloc(sizeof(struct image));
  37. unsigned int depth, bpp, rmask, gmask, bmask, amask;
  38. #if defined(USE_IMLIB2)
  39. Imlib_Image image;
  40. /* Load the new image */
  41. image = imlib_load_image(name);
  42. if(!image)
  43. {
  44. free(im);
  45. return NULL;
  46. }
  47. imlib_context_set_image(image);
  48. im->pixels = (char *)imlib_image_get_data_for_reading_only();
  49. im->w = imlib_image_get_width();
  50. im->h = imlib_image_get_height();
  51. rmask = 0x00ff0000;
  52. gmask = 0x0000ff00;
  53. bmask = 0x000000ff;
  54. amask = 0xff000000;
  55. bpp = 32;
  56. depth = 4;
  57. /* Create the libcucul dither */
  58. im->dither = cucul_create_dither(bpp, im->w, im->h, depth * im->w,
  59. rmask, gmask, bmask, amask);
  60. if(!im->dither)
  61. {
  62. imlib_free_image();
  63. free(im);
  64. return NULL;
  65. }
  66. im->priv = (void *)image;
  67. #else
  68. /* Try to load a BMP file */
  69. unsigned int red[256], green[256], blue[256], alpha[256];
  70. unsigned int i, colors, offset, tmp, planes;
  71. FILE *fp;
  72. fp = fopen(name, "rb");
  73. if(!fp)
  74. {
  75. free(im);
  76. return NULL;
  77. }
  78. if(u16fread(fp) != 0x4d42)
  79. {
  80. fclose(fp);
  81. free(im);
  82. return NULL;
  83. }
  84. u32fread(fp); /* size */
  85. u16fread(fp); /* reserved 1 */
  86. u16fread(fp); /* reserved 2 */
  87. offset = u32fread(fp);
  88. tmp = u32fread(fp); /* header size */
  89. if(tmp == 40)
  90. {
  91. im->w = u32fread(fp);
  92. im->h = u32fread(fp);
  93. planes = u16fread(fp);
  94. bpp = u16fread(fp);
  95. tmp = u32fread(fp); /* compression */
  96. if(tmp != 0)
  97. {
  98. fclose(fp);
  99. free(im);
  100. return NULL;
  101. }
  102. u32fread(fp); /* sizeimage */
  103. u32fread(fp); /* xpelspermeter */
  104. u32fread(fp); /* ypelspermeter */
  105. u32fread(fp); /* biclrused */
  106. u32fread(fp); /* biclrimportantn */
  107. colors = (offset - 54) / 4;
  108. for(i = 0; i < colors && i < 256; i++)
  109. {
  110. blue[i] = u8fread(fp) * 16;
  111. green[i] = u8fread(fp) * 16;
  112. red[i] = u8fread(fp) * 16;
  113. alpha[i] = 0;
  114. u8fread(fp);
  115. }
  116. }
  117. else if(tmp == 12)
  118. {
  119. im->w = u32fread(fp);
  120. im->h = u32fread(fp);
  121. planes = u16fread(fp);
  122. bpp = u16fread(fp);
  123. colors = (offset - 26) / 3;
  124. for(i = 0; i < colors && i < 256; i++)
  125. {
  126. blue[i] = u8fread(fp);
  127. green[i] = u8fread(fp);
  128. red[i] = u8fread(fp);
  129. alpha[i] = 0;
  130. }
  131. }
  132. else
  133. {
  134. fclose(fp);
  135. free(im);
  136. return NULL;
  137. }
  138. /* Fill the rest of the palette */
  139. for(i = colors; i < 256; i++)
  140. blue[i] = green[i] = red[i] = alpha[i] = 0;
  141. depth = (bpp + 7) / 8;
  142. /* Sanity check */
  143. if(!im->w || im->w > 0x10000 || !im->h || im->h > 0x10000 || planes != 1)
  144. {
  145. fclose(fp);
  146. free(im);
  147. return NULL;
  148. }
  149. /* Allocate the pixel buffer */
  150. im->pixels = malloc(im->w * im->h * depth);
  151. if(!im->pixels)
  152. {
  153. fclose(fp);
  154. free(im);
  155. return NULL;
  156. }
  157. memset(im->pixels, 0, im->w * im->h * depth);
  158. /* Read the bitmap data */
  159. for(i = im->h; i--; )
  160. {
  161. unsigned int j, k, bits = 0;
  162. switch(bpp)
  163. {
  164. case 1:
  165. for(j = 0; j < im->w; j++)
  166. {
  167. k = j % 32;
  168. if(k == 0)
  169. bits = u32fread(fp);
  170. im->pixels[im->w * i * depth + j] =
  171. (bits >> ((k & ~0xf) + 0xf - (k & 0xf))) & 0x1;
  172. }
  173. break;
  174. case 4:
  175. for(j = 0; j < im->w; j++)
  176. {
  177. k = j % 8;
  178. if(k == 0)
  179. bits = u32fread(fp);
  180. im->pixels[im->w * i * depth + j] =
  181. (bits >> (4 * ((k & ~0x1) + 0x1 - (k & 0x1)))) & 0xf;
  182. }
  183. break;
  184. default:
  185. /* Works for 8bpp, but also for 16, 24 etc. */
  186. fread(im->pixels + im->w * i * depth, im->w * depth, 1, fp);
  187. /* Pad reads to 4 bytes */
  188. tmp = (im->w * depth) % 4;
  189. tmp = (4 - tmp) % 4;
  190. while(tmp--)
  191. u8fread(fp);
  192. break;
  193. }
  194. }
  195. switch(depth)
  196. {
  197. case 3:
  198. rmask = 0xff0000;
  199. gmask = 0x00ff00;
  200. bmask = 0x0000ff;
  201. amask = 0x000000;
  202. break;
  203. case 2: /* XXX: those are the 16 bits values */
  204. rmask = 0x7c00;
  205. gmask = 0x03e0;
  206. bmask = 0x001f;
  207. amask = 0x0000;
  208. break;
  209. case 1:
  210. default:
  211. bpp = 8;
  212. rmask = gmask = bmask = amask = 0;
  213. break;
  214. }
  215. fclose(fp);
  216. /* Create the libcucul dither */
  217. im->dither = cucul_create_dither(bpp, im->w, im->h, depth * im->w,
  218. rmask, gmask, bmask, amask);
  219. if(!im->dither)
  220. {
  221. free(im->pixels);
  222. free(im);
  223. return NULL;
  224. }
  225. if(bpp == 8)
  226. cucul_set_dither_palette(im->dither, red, green, blue, alpha);
  227. #endif
  228. return im;
  229. }
  230. void unload_image(struct image * im)
  231. {
  232. #if defined(USE_IMLIB2)
  233. /* Imlib_Image image = (Imlib_Image)im->priv; */
  234. imlib_free_image();
  235. #else
  236. free(im->pixels);
  237. #endif
  238. cucul_free_dither(im->dither);
  239. }
  240. #if !defined(USE_IMLIB2)
  241. static unsigned int u32fread(FILE *fp)
  242. {
  243. unsigned char buffer[4];
  244. fread(buffer, 4, 1, fp);
  245. return ((unsigned int)buffer[3] << 24) | ((unsigned int)buffer[2] << 16)
  246. | ((unsigned int)buffer[1] << 8) | ((unsigned int)buffer[0]);
  247. }
  248. static unsigned int u16fread(FILE *fp)
  249. {
  250. unsigned char buffer[2];
  251. fread(buffer, 2, 1, fp);
  252. return ((unsigned int)buffer[1] << 8) | ((unsigned int)buffer[0]);
  253. }
  254. static unsigned int u8fread(FILE *fp)
  255. {
  256. unsigned char buffer;
  257. fread(&buffer, 1, 1, fp);
  258. return (unsigned int)buffer;
  259. }
  260. #endif