您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

230 行
5.7 KiB

  1. /*
  2. * image.c: image I/O functions
  3. * $Id$
  4. *
  5. * Copyright: (c) 2004 Sam Hocevar <sam@zoy.org>
  6. * This program is free software. It comes without any warranty, to
  7. * the extent permitted by applicable law. You can redistribute it
  8. * and/or modify it under the terms of the Do What The Fuck You Want
  9. * To Public License, Version 2, as published by Sam Hocevar. See
  10. * http://sam.zoy.org/wtfpl/COPYING for more details.
  11. */
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "config.h"
  16. #include "common.h"
  17. #if defined(HAVE_SDL_IMAGE_H)
  18. # include <SDL_image.h>
  19. #elif defined(HAVE_IMLIB2_H)
  20. # include <Imlib2.h>
  21. #elif defined(HAVE_CV_H)
  22. # include <cv.h>
  23. # include <highgui.h>
  24. #else
  25. # error "No imaging library"
  26. #endif
  27. struct image *image_load(const char *name)
  28. {
  29. struct image *img;
  30. #if defined(HAVE_SDL_IMAGE_H)
  31. SDL_Surface *priv = IMG_Load(name);
  32. #elif defined(HAVE_IMLIB2_H)
  33. Imlib_Image priv = imlib_load_image(name);
  34. #elif defined(HAVE_CV_H)
  35. IplImage *priv = cvLoadImage(name, -1);
  36. #endif
  37. if(!priv)
  38. return NULL;
  39. #if defined(HAVE_SDL_IMAGE_H)
  40. if(priv->format->BytesPerPixel == 1)
  41. {
  42. img = image_new(priv->w, priv->h);
  43. SDL_BlitSurface(priv, NULL, img->priv, NULL);
  44. SDL_FreeSurface(priv);
  45. return img;
  46. }
  47. #endif
  48. img = (struct image *)malloc(sizeof(struct image));
  49. #if defined(HAVE_SDL_IMAGE_H)
  50. img->width = priv->w;
  51. img->height = priv->h;
  52. img->pitch = priv->pitch;
  53. img->channels = priv->format->BytesPerPixel;
  54. img->pixels = priv->pixels;
  55. #elif defined(HAVE_IMLIB2_H)
  56. imlib_context_set_image(priv);
  57. img->width = imlib_image_get_width();
  58. img->height = imlib_image_get_height();
  59. img->pitch = 4 * imlib_image_get_width();
  60. img->channels = 4;
  61. img->pixels = (char *)imlib_image_get_data();
  62. #elif defined(HAVE_CV_H)
  63. img->width = priv->width;
  64. img->height = priv->height;
  65. img->pitch = priv->widthStep;
  66. img->channels = priv->nChannels;
  67. img->pixels = priv->imageData;
  68. #endif
  69. img->priv = (void *)priv;
  70. return img;
  71. }
  72. struct image *image_new(int width, int height)
  73. {
  74. struct image *img;
  75. #if defined(HAVE_SDL_IMAGE_H)
  76. SDL_Surface *priv;
  77. Uint32 rmask, gmask, bmask, amask;
  78. # if SDL_BYTEORDER == SDL_BIG_ENDIAN
  79. rmask = 0xff000000;
  80. gmask = 0x00ff0000;
  81. bmask = 0x0000ff00;
  82. amask = 0x00000000;
  83. # else
  84. rmask = 0x000000ff;
  85. gmask = 0x0000ff00;
  86. bmask = 0x00ff0000;
  87. amask = 0x00000000;
  88. # endif
  89. priv = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
  90. rmask, gmask, bmask, amask);
  91. #elif defined(HAVE_IMLIB2_H)
  92. Imlib_Image priv = imlib_create_image(width, height);
  93. #elif defined(HAVE_CV_H)
  94. IplImage *priv = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3);
  95. #endif
  96. if(!priv)
  97. return NULL;
  98. img = (struct image *)malloc(sizeof(struct image));
  99. #if defined(HAVE_SDL_IMAGE_H)
  100. img->width = priv->w;
  101. img->height = priv->h;
  102. img->pitch = priv->pitch;
  103. img->channels = priv->format->BytesPerPixel;
  104. img->pixels = priv->pixels;
  105. #elif defined(HAVE_IMLIB2_H)
  106. imlib_context_set_image(priv);
  107. img->width = imlib_image_get_width();
  108. img->height = imlib_image_get_height();
  109. img->pitch = 4 * imlib_image_get_width();
  110. img->channels = 4;
  111. img->pixels = (char *)imlib_image_get_data();
  112. #elif defined(HAVE_CV_H)
  113. img->width = priv->width;
  114. img->height = priv->height;
  115. img->pitch = priv->widthStep;
  116. img->channels = priv->nChannels;
  117. img->pixels = priv->imageData;
  118. #endif
  119. img->priv = (void *)priv;
  120. return img;
  121. }
  122. struct image *image_dup(struct image *img)
  123. {
  124. struct image *dst;
  125. int x, y;
  126. dst = image_new(img->width, img->height);
  127. for(y = 0; y < img->height; y++)
  128. {
  129. for(x = 0; x < img->width; x++)
  130. {
  131. int r, g, b;
  132. getpixel(img, x, y, &r, &g, &b);
  133. setpixel(dst, x, y, r, g, b);
  134. }
  135. }
  136. return dst;
  137. }
  138. void image_free(struct image *img)
  139. {
  140. #if defined(HAVE_SDL_IMAGE_H)
  141. SDL_FreeSurface(img->priv);
  142. #elif defined(HAVE_IMLIB2_H)
  143. imlib_context_set_image(img->priv);
  144. imlib_free_image();
  145. #elif defined(HAVE_CV_H)
  146. IplImage *iplimg;
  147. iplimg = (IplImage *)img->priv;
  148. cvReleaseImage(&iplimg);
  149. #endif
  150. free(img);
  151. }
  152. void image_save(struct image *img, const char *name)
  153. {
  154. #if defined(HAVE_SDL_IMAGE_H)
  155. SDL_SaveBMP(img->priv, name);
  156. #elif defined(HAVE_IMLIB2_H)
  157. imlib_context_set_image(img->priv);
  158. imlib_save_image(name);
  159. #elif defined(HAVE_CV_H)
  160. cvSaveImage(name, img->priv);
  161. #endif
  162. }
  163. void image_swap(struct image *img1, struct image *img2)
  164. {
  165. struct image tmp;
  166. memcpy(&tmp, img1, sizeof(tmp));
  167. memcpy(img1, img2, sizeof(tmp));
  168. memcpy(img2, &tmp, sizeof(tmp));
  169. }
  170. int getgray(struct image *img, int x, int y, int *g)
  171. {
  172. if(x < 0 || y < 0 || x >= img->width || y >= img->height)
  173. {
  174. *g = 255;
  175. return -1;
  176. }
  177. *g = (unsigned char)img->pixels[y * img->pitch + x * img->channels + 1];
  178. return 0;
  179. }
  180. int getpixel(struct image *img, int x, int y, int *r, int *g, int *b)
  181. {
  182. if(x < 0 || y < 0 || x >= img->width || y >= img->height)
  183. {
  184. *r = 255;
  185. *g = 255;
  186. *b = 255;
  187. return -1;
  188. }
  189. *b = (unsigned char)img->pixels[y * img->pitch + x * img->channels];
  190. *g = (unsigned char)img->pixels[y * img->pitch + x * img->channels + 1];
  191. *r = (unsigned char)img->pixels[y * img->pitch + x * img->channels + 2];
  192. return 0;
  193. }
  194. int setpixel(struct image *img, int x, int y, int r, int g, int b)
  195. {
  196. if(x < 0 || y < 0 || x >= img->width || y >= img->height)
  197. return -1;
  198. img->pixels[y * img->pitch + x * img->channels] = b;
  199. img->pixels[y * img->pitch + x * img->channels + 1] = g;
  200. img->pixels[y * img->pitch + x * img->channels + 2] = r;
  201. return 0;
  202. }