Point.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * point (pixel) translation
  6. *
  7. * history:
  8. * 1995-11-27 fl Created
  9. * 1996-03-31 fl Fixed colour support
  10. * 1996-08-13 fl Support 8-bit to "1" thresholding
  11. * 1997-05-31 fl Added floating point transform
  12. * 1998-07-02 fl Added integer point transform
  13. * 1998-07-17 fl Support L to anything lookup
  14. * 2004-12-18 fl Refactored; added I to L lookup
  15. *
  16. * Copyright (c) 1997-2004 by Secret Labs AB.
  17. * Copyright (c) 1995-2004 by Fredrik Lundh.
  18. *
  19. * See the README file for information on usage and redistribution.
  20. */
  21. #include "Imaging.h"
  22. typedef struct {
  23. const void *table;
  24. } im_point_context;
  25. static void
  26. im_point_8_8(Imaging imOut, Imaging imIn, im_point_context *context) {
  27. int x, y;
  28. /* 8-bit source, 8-bit destination */
  29. UINT8 *table = (UINT8 *)context->table;
  30. for (y = 0; y < imIn->ysize; y++) {
  31. UINT8 *in = imIn->image8[y];
  32. UINT8 *out = imOut->image8[y];
  33. for (x = 0; x < imIn->xsize; x++) {
  34. out[x] = table[in[x]];
  35. }
  36. }
  37. }
  38. static void
  39. im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context *context) {
  40. int x, y;
  41. /* 2x8-bit source, 2x8-bit destination */
  42. UINT8 *table = (UINT8 *)context->table;
  43. for (y = 0; y < imIn->ysize; y++) {
  44. UINT8 *in = (UINT8 *)imIn->image[y];
  45. UINT8 *out = (UINT8 *)imOut->image[y];
  46. for (x = 0; x < imIn->xsize; x++) {
  47. out[0] = table[in[0]];
  48. out[3] = table[in[3] + 256];
  49. in += 4;
  50. out += 4;
  51. }
  52. }
  53. }
  54. static void
  55. im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context *context) {
  56. int x, y;
  57. /* 3x8-bit source, 3x8-bit destination */
  58. UINT8 *table = (UINT8 *)context->table;
  59. for (y = 0; y < imIn->ysize; y++) {
  60. UINT8 *in = (UINT8 *)imIn->image[y];
  61. UINT8 *out = (UINT8 *)imOut->image[y];
  62. for (x = 0; x < imIn->xsize; x++) {
  63. out[0] = table[in[0]];
  64. out[1] = table[in[1] + 256];
  65. out[2] = table[in[2] + 512];
  66. in += 4;
  67. out += 4;
  68. }
  69. }
  70. }
  71. static void
  72. im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context *context) {
  73. int x, y;
  74. /* 4x8-bit source, 4x8-bit destination */
  75. UINT8 *table = (UINT8 *)context->table;
  76. for (y = 0; y < imIn->ysize; y++) {
  77. UINT8 *in = (UINT8 *)imIn->image[y];
  78. UINT8 *out = (UINT8 *)imOut->image[y];
  79. for (x = 0; x < imIn->xsize; x++) {
  80. out[0] = table[in[0]];
  81. out[1] = table[in[1] + 256];
  82. out[2] = table[in[2] + 512];
  83. out[3] = table[in[3] + 768];
  84. in += 4;
  85. out += 4;
  86. }
  87. }
  88. }
  89. static void
  90. im_point_8_32(Imaging imOut, Imaging imIn, im_point_context *context) {
  91. int x, y;
  92. /* 8-bit source, 32-bit destination */
  93. char *table = (char *)context->table;
  94. for (y = 0; y < imIn->ysize; y++) {
  95. UINT8 *in = imIn->image8[y];
  96. INT32 *out = imOut->image32[y];
  97. for (x = 0; x < imIn->xsize; x++) {
  98. memcpy(out + x, table + in[x] * sizeof(INT32), sizeof(INT32));
  99. }
  100. }
  101. }
  102. static void
  103. im_point_32_8(Imaging imOut, Imaging imIn, im_point_context *context) {
  104. int x, y;
  105. /* 32-bit source, 8-bit destination */
  106. UINT8 *table = (UINT8 *)context->table;
  107. for (y = 0; y < imIn->ysize; y++) {
  108. INT32 *in = imIn->image32[y];
  109. UINT8 *out = imOut->image8[y];
  110. for (x = 0; x < imIn->xsize; x++) {
  111. int v = in[x];
  112. if (v < 0) {
  113. v = 0;
  114. } else if (v > 65535) {
  115. v = 65535;
  116. }
  117. out[x] = table[v];
  118. }
  119. }
  120. }
  121. Imaging
  122. ImagingPoint(Imaging imIn, const char *mode, const void *table) {
  123. /* lookup table transform */
  124. ImagingSectionCookie cookie;
  125. Imaging imOut;
  126. im_point_context context;
  127. void (*point)(Imaging imIn, Imaging imOut, im_point_context * context);
  128. if (!imIn) {
  129. return (Imaging)ImagingError_ModeError();
  130. }
  131. if (!mode) {
  132. mode = imIn->mode;
  133. }
  134. if (imIn->type != IMAGING_TYPE_UINT8) {
  135. if (imIn->type != IMAGING_TYPE_INT32 || strcmp(mode, "L") != 0) {
  136. goto mode_mismatch;
  137. }
  138. } else if (!imIn->image8 && strcmp(imIn->mode, mode) != 0) {
  139. goto mode_mismatch;
  140. }
  141. imOut = ImagingNew(mode, imIn->xsize, imIn->ysize);
  142. if (!imOut) {
  143. return NULL;
  144. }
  145. /* find appropriate handler */
  146. if (imIn->type == IMAGING_TYPE_UINT8) {
  147. if (imIn->bands == imOut->bands && imIn->type == imOut->type) {
  148. switch (imIn->bands) {
  149. case 1:
  150. point = im_point_8_8;
  151. break;
  152. case 2:
  153. point = im_point_2x8_2x8;
  154. break;
  155. case 3:
  156. point = im_point_3x8_3x8;
  157. break;
  158. case 4:
  159. point = im_point_4x8_4x8;
  160. break;
  161. default:
  162. /* this cannot really happen */
  163. point = im_point_8_8;
  164. break;
  165. }
  166. } else {
  167. point = im_point_8_32;
  168. }
  169. } else {
  170. point = im_point_32_8;
  171. }
  172. ImagingCopyPalette(imOut, imIn);
  173. ImagingSectionEnter(&cookie);
  174. context.table = table;
  175. point(imOut, imIn, &context);
  176. ImagingSectionLeave(&cookie);
  177. return imOut;
  178. mode_mismatch:
  179. return (Imaging)ImagingError_ValueError(
  180. "point operation not supported for this mode");
  181. }
  182. Imaging
  183. ImagingPointTransform(Imaging imIn, double scale, double offset) {
  184. /* scale/offset transform */
  185. ImagingSectionCookie cookie;
  186. Imaging imOut;
  187. int x, y;
  188. if (!imIn || (strcmp(imIn->mode, "I") != 0 && strcmp(imIn->mode, "I;16") != 0 &&
  189. strcmp(imIn->mode, "F") != 0)) {
  190. return (Imaging)ImagingError_ModeError();
  191. }
  192. imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
  193. if (!imOut) {
  194. return NULL;
  195. }
  196. switch (imIn->type) {
  197. case IMAGING_TYPE_INT32:
  198. ImagingSectionEnter(&cookie);
  199. for (y = 0; y < imIn->ysize; y++) {
  200. INT32 *in = imIn->image32[y];
  201. INT32 *out = imOut->image32[y];
  202. /* FIXME: add clipping? */
  203. for (x = 0; x < imIn->xsize; x++) {
  204. out[x] = in[x] * scale + offset;
  205. }
  206. }
  207. ImagingSectionLeave(&cookie);
  208. break;
  209. case IMAGING_TYPE_FLOAT32:
  210. ImagingSectionEnter(&cookie);
  211. for (y = 0; y < imIn->ysize; y++) {
  212. FLOAT32 *in = (FLOAT32 *)imIn->image32[y];
  213. FLOAT32 *out = (FLOAT32 *)imOut->image32[y];
  214. for (x = 0; x < imIn->xsize; x++) {
  215. out[x] = in[x] * scale + offset;
  216. }
  217. }
  218. ImagingSectionLeave(&cookie);
  219. break;
  220. case IMAGING_TYPE_SPECIAL:
  221. if (strcmp(imIn->mode, "I;16") == 0) {
  222. ImagingSectionEnter(&cookie);
  223. for (y = 0; y < imIn->ysize; y++) {
  224. char *in = (char *)imIn->image[y];
  225. char *out = (char *)imOut->image[y];
  226. /* FIXME: add clipping? */
  227. for (x = 0; x < imIn->xsize; x++) {
  228. UINT16 v;
  229. memcpy(&v, in + x * sizeof(v), sizeof(v));
  230. v = v * scale + offset;
  231. memcpy(out + x * sizeof(UINT16), &v, sizeof(v));
  232. }
  233. }
  234. ImagingSectionLeave(&cookie);
  235. break;
  236. }
  237. /* FALL THROUGH */
  238. default:
  239. ImagingDelete(imOut);
  240. return (Imaging)ImagingError_ValueError("internal error");
  241. }
  242. return imOut;
  243. }