Access.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * imaging access objects
  6. *
  7. * Copyright (c) Fredrik Lundh 2009.
  8. *
  9. * See the README file for information on usage and redistribution.
  10. */
  11. #include "Imaging.h"
  12. /* use Tests/make_hash.py to calculate these values */
  13. #define ACCESS_TABLE_SIZE 27
  14. #define ACCESS_TABLE_HASH 3078
  15. static struct ImagingAccessInstance access_table[ACCESS_TABLE_SIZE];
  16. static inline UINT32
  17. hash(const char* mode)
  18. {
  19. UINT32 i = ACCESS_TABLE_HASH;
  20. while (*mode)
  21. i = ((i<<5) + i) ^ (UINT8) *mode++;
  22. return i % ACCESS_TABLE_SIZE;
  23. }
  24. static ImagingAccess
  25. add_item(const char* mode)
  26. {
  27. UINT32 i = hash(mode);
  28. /* printf("hash %s => %d\n", mode, i); */
  29. if (access_table[i].mode && strcmp(access_table[i].mode, mode) != 0) {
  30. fprintf(stderr, "AccessInit: hash collision: %d for both %s and %s\n",
  31. i, mode, access_table[i].mode);
  32. exit(1);
  33. }
  34. access_table[i].mode = mode;
  35. return &access_table[i];
  36. }
  37. /* fetch pointer to pixel line */
  38. static void*
  39. line_8(Imaging im, int x, int y)
  40. {
  41. return &im->image8[y][x];
  42. }
  43. static void*
  44. line_16(Imaging im, int x, int y)
  45. {
  46. return &im->image8[y][x+x];
  47. }
  48. static void*
  49. line_32(Imaging im, int x, int y)
  50. {
  51. return &im->image32[y][x];
  52. }
  53. /* fetch individual pixel */
  54. static void
  55. get_pixel(Imaging im, int x, int y, void* color)
  56. {
  57. char* out = color;
  58. /* generic pixel access*/
  59. if (im->image8) {
  60. out[0] = im->image8[y][x];
  61. } else {
  62. UINT8* p = (UINT8*) &im->image32[y][x];
  63. if (im->type == IMAGING_TYPE_UINT8 && im->bands == 2) {
  64. out[0] = p[0];
  65. out[1] = p[3];
  66. return;
  67. }
  68. memcpy(out, p, im->pixelsize);
  69. }
  70. }
  71. static void
  72. get_pixel_8(Imaging im, int x, int y, void* color)
  73. {
  74. char* out = color;
  75. out[0] = im->image8[y][x];
  76. }
  77. static void
  78. get_pixel_16L(Imaging im, int x, int y, void* color)
  79. {
  80. UINT8* in = (UINT8*) &im->image[y][x+x];
  81. #ifdef WORDS_BIGENDIAN
  82. UINT16 out = in[0] + (in[1]<<8);
  83. memcpy(color, &out, sizeof(out));
  84. #else
  85. memcpy(color, in, sizeof(UINT16));
  86. #endif
  87. }
  88. static void
  89. get_pixel_16B(Imaging im, int x, int y, void* color)
  90. {
  91. UINT8* in = (UINT8*) &im->image[y][x+x];
  92. #ifdef WORDS_BIGENDIAN
  93. memcpy(color, in, sizeof(UINT16));
  94. #else
  95. UINT16 out = in[1] + (in[0]<<8);
  96. memcpy(color, &out, sizeof(out));
  97. #endif
  98. }
  99. static void
  100. get_pixel_32(Imaging im, int x, int y, void* color)
  101. {
  102. memcpy(color, &im->image32[y][x], sizeof(INT32));
  103. }
  104. static void
  105. get_pixel_32L(Imaging im, int x, int y, void* color)
  106. {
  107. UINT8* in = (UINT8*) &im->image[y][x*4];
  108. #ifdef WORDS_BIGENDIAN
  109. INT32 out = in[0] + (in[1]<<8) + (in[2]<<16) + (in[3]<<24);
  110. memcpy(color, &out, sizeof(out));
  111. #else
  112. memcpy(color, in, sizeof(INT32));
  113. #endif
  114. }
  115. static void
  116. get_pixel_32B(Imaging im, int x, int y, void* color)
  117. {
  118. UINT8* in = (UINT8*) &im->image[y][x*4];
  119. #ifdef WORDS_BIGENDIAN
  120. memcpy(color, in, sizeof(INT32));
  121. #else
  122. INT32 out = in[3] + (in[2]<<8) + (in[1]<<16) + (in[0]<<24);
  123. memcpy(color, &out, sizeof(out));
  124. #endif
  125. }
  126. /* store individual pixel */
  127. static void
  128. put_pixel(Imaging im, int x, int y, const void* color)
  129. {
  130. if (im->image8)
  131. im->image8[y][x] = *((UINT8*) color);
  132. else
  133. memcpy(&im->image32[y][x], color, sizeof(INT32));
  134. }
  135. static void
  136. put_pixel_8(Imaging im, int x, int y, const void* color)
  137. {
  138. im->image8[y][x] = *((UINT8*) color);
  139. }
  140. static void
  141. put_pixel_16L(Imaging im, int x, int y, const void* color)
  142. {
  143. memcpy(&im->image8[y][x+x], color, 2);
  144. }
  145. static void
  146. put_pixel_16B(Imaging im, int x, int y, const void* color)
  147. {
  148. const char* in = color;
  149. UINT8* out = (UINT8*) &im->image8[y][x+x];
  150. out[0] = in[1];
  151. out[1] = in[0];
  152. }
  153. static void
  154. put_pixel_32L(Imaging im, int x, int y, const void* color)
  155. {
  156. memcpy(&im->image8[y][x*4], color, 4);
  157. }
  158. static void
  159. put_pixel_32B(Imaging im, int x, int y, const void* color)
  160. {
  161. const char* in = color;
  162. UINT8* out = (UINT8*) &im->image8[y][x*4];
  163. out[0] = in[3];
  164. out[1] = in[2];
  165. out[2] = in[1];
  166. out[3] = in[0];
  167. }
  168. static void
  169. put_pixel_32(Imaging im, int x, int y, const void* color)
  170. {
  171. memcpy(&im->image32[y][x], color, sizeof(INT32));
  172. }
  173. void
  174. ImagingAccessInit()
  175. {
  176. #define ADD(mode_, line_, get_pixel_, put_pixel_) \
  177. { ImagingAccess access = add_item(mode_); \
  178. access->line = line_; \
  179. access->get_pixel = get_pixel_; \
  180. access->put_pixel = put_pixel_; \
  181. }
  182. /* populate access table */
  183. ADD("1", line_8, get_pixel_8, put_pixel_8);
  184. ADD("L", line_8, get_pixel_8, put_pixel_8);
  185. ADD("LA", line_32, get_pixel, put_pixel);
  186. ADD("La", line_32, get_pixel, put_pixel);
  187. ADD("I", line_32, get_pixel_32, put_pixel_32);
  188. ADD("I;16", line_16, get_pixel_16L, put_pixel_16L);
  189. ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L);
  190. ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B);
  191. ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L);
  192. ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B);
  193. ADD("F", line_32, get_pixel_32, put_pixel_32);
  194. ADD("P", line_8, get_pixel_8, put_pixel_8);
  195. ADD("PA", line_32, get_pixel, put_pixel);
  196. ADD("RGB", line_32, get_pixel_32, put_pixel_32);
  197. ADD("RGBA", line_32, get_pixel_32, put_pixel_32);
  198. ADD("RGBa", line_32, get_pixel_32, put_pixel_32);
  199. ADD("RGBX", line_32, get_pixel_32, put_pixel_32);
  200. ADD("CMYK", line_32, get_pixel_32, put_pixel_32);
  201. ADD("YCbCr", line_32, get_pixel_32, put_pixel_32);
  202. ADD("LAB", line_32, get_pixel_32, put_pixel_32);
  203. ADD("HSV", line_32, get_pixel_32, put_pixel_32);
  204. }
  205. ImagingAccess
  206. ImagingAccessNew(Imaging im)
  207. {
  208. ImagingAccess access = &access_table[hash(im->mode)];
  209. if (im->mode[0] != access->mode[0] || strcmp(im->mode, access->mode) != 0)
  210. return NULL;
  211. return access;
  212. }
  213. void
  214. _ImagingAccessDelete(Imaging im, ImagingAccess access)
  215. {
  216. }