GetBBox.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * helpers to bounding boxes, min/max values, number of colors, etc.
  6. *
  7. * history:
  8. * 1996-07-22 fl Created
  9. * 1996-12-30 fl Added projection stuff
  10. * 1998-07-12 fl Added extrema stuff
  11. * 2004-09-17 fl Added colors stuff
  12. *
  13. * Copyright (c) 1997-2004 by Secret Labs AB.
  14. * Copyright (c) 1996-2004 by Fredrik Lundh.
  15. *
  16. * See the README file for details on usage and redistribution.
  17. */
  18. #include "Imaging.h"
  19. int
  20. ImagingGetBBox(Imaging im, int bbox[4])
  21. {
  22. /* Get the bounding box for any non-zero data in the image.*/
  23. int x, y;
  24. int has_data;
  25. /* Initialize bounding box to max values */
  26. bbox[0] = im->xsize;
  27. bbox[1] = -1;
  28. bbox[2] = bbox[3] = 0;
  29. #define GETBBOX(image, mask)\
  30. for (y = 0; y < im->ysize; y++) {\
  31. has_data = 0;\
  32. for (x = 0; x < im->xsize; x++)\
  33. if (im->image[y][x] & mask) {\
  34. has_data = 1;\
  35. if (x < bbox[0])\
  36. bbox[0] = x;\
  37. if (x >= bbox[2])\
  38. bbox[2] = x+1;\
  39. }\
  40. if (has_data) {\
  41. if (bbox[1] < 0)\
  42. bbox[1] = y;\
  43. bbox[3] = y+1;\
  44. }\
  45. }
  46. if (im->image8) {
  47. GETBBOX(image8, 0xff);
  48. } else {
  49. INT32 mask = 0xffffffff;
  50. if (im->bands == 3)
  51. ((UINT8*) &mask)[3] = 0;
  52. GETBBOX(image32, mask);
  53. }
  54. /* Check that we got a box */
  55. if (bbox[1] < 0)
  56. return 0; /* no data */
  57. return 1; /* ok */
  58. }
  59. int
  60. ImagingGetProjection(Imaging im, UINT8* xproj, UINT8* yproj)
  61. {
  62. /* Get projection arrays for non-zero data in the image.*/
  63. int x, y;
  64. int has_data;
  65. /* Initialize projection arrays */
  66. memset(xproj, 0, im->xsize);
  67. memset(yproj, 0, im->ysize);
  68. #define GETPROJ(image, mask)\
  69. for (y = 0; y < im->ysize; y++) {\
  70. has_data = 0;\
  71. for (x = 0; x < im->xsize; x++)\
  72. if (im->image[y][x] & mask) {\
  73. has_data = 1;\
  74. xproj[x] = 1;\
  75. }\
  76. if (has_data)\
  77. yproj[y] = 1;\
  78. }
  79. if (im->image8) {
  80. GETPROJ(image8, 0xff);
  81. } else {
  82. INT32 mask = 0xffffffff;
  83. if (im->bands == 3)
  84. ((UINT8*) &mask)[3] = 0;
  85. GETPROJ(image32, mask);
  86. }
  87. return 1; /* ok */
  88. }
  89. int
  90. ImagingGetExtrema(Imaging im, void *extrema)
  91. {
  92. int x, y;
  93. INT32 imin, imax;
  94. FLOAT32 fmin, fmax;
  95. if (im->bands != 1) {
  96. (void) ImagingError_ModeError();
  97. return -1; /* mismatch */
  98. }
  99. if (!im->xsize || !im->ysize)
  100. return 0; /* zero size */
  101. switch (im->type) {
  102. case IMAGING_TYPE_UINT8:
  103. imin = imax = im->image8[0][0];
  104. for (y = 0; y < im->ysize; y++) {
  105. UINT8* in = im->image8[y];
  106. for (x = 0; x < im->xsize; x++) {
  107. if (imin > in[x])
  108. imin = in[x];
  109. else if (imax < in[x])
  110. imax = in[x];
  111. }
  112. }
  113. ((UINT8*) extrema)[0] = (UINT8) imin;
  114. ((UINT8*) extrema)[1] = (UINT8) imax;
  115. break;
  116. case IMAGING_TYPE_INT32:
  117. imin = imax = im->image32[0][0];
  118. for (y = 0; y < im->ysize; y++) {
  119. INT32* in = im->image32[y];
  120. for (x = 0; x < im->xsize; x++) {
  121. if (imin > in[x])
  122. imin = in[x];
  123. else if (imax < in[x])
  124. imax = in[x];
  125. }
  126. }
  127. memcpy(extrema, &imin, sizeof(imin));
  128. memcpy(((char*)extrema) + sizeof(imin), &imax, sizeof(imax));
  129. break;
  130. case IMAGING_TYPE_FLOAT32:
  131. fmin = fmax = ((FLOAT32*) im->image32[0])[0];
  132. for (y = 0; y < im->ysize; y++) {
  133. FLOAT32* in = (FLOAT32*) im->image32[y];
  134. for (x = 0; x < im->xsize; x++) {
  135. if (fmin > in[x])
  136. fmin = in[x];
  137. else if (fmax < in[x])
  138. fmax = in[x];
  139. }
  140. }
  141. memcpy(extrema, &fmin, sizeof(fmin));
  142. memcpy(((char*)extrema) + sizeof(fmin), &fmax, sizeof(fmax));
  143. break;
  144. case IMAGING_TYPE_SPECIAL:
  145. if (strcmp(im->mode, "I;16") == 0) {
  146. UINT16 v;
  147. memcpy(&v, *im->image8, sizeof(v));
  148. imin = imax = v;
  149. for (y = 0; y < im->ysize; y++) {
  150. for (x = 0; x < im->xsize; x++) {
  151. memcpy(&v, im->image[y] + x * sizeof(v), sizeof(v));
  152. if (imin > v)
  153. imin = v;
  154. else if (imax < v)
  155. imax = v;
  156. }
  157. }
  158. v = (UINT16) imin;
  159. memcpy(extrema, &v, sizeof(v));
  160. v = (UINT16) imax;
  161. memcpy(((char*)extrema) + sizeof(v), &v, sizeof(v));
  162. break;
  163. }
  164. /* FALL THROUGH */
  165. default:
  166. (void) ImagingError_ModeError();
  167. return -1;
  168. }
  169. return 1; /* ok */
  170. }
  171. /* static ImagingColorItem* getcolors8(Imaging im, int maxcolors, int* size);*/
  172. static ImagingColorItem* getcolors32(Imaging im, int maxcolors, int* size);
  173. ImagingColorItem*
  174. ImagingGetColors(Imaging im, int maxcolors, int* size)
  175. {
  176. /* FIXME: add support for 8-bit images */
  177. return getcolors32(im, maxcolors, size);
  178. }
  179. static ImagingColorItem*
  180. getcolors32(Imaging im, int maxcolors, int* size)
  181. {
  182. unsigned int h;
  183. unsigned int i, incr;
  184. int colors;
  185. INT32 pixel_mask;
  186. int x, y;
  187. ImagingColorItem* table;
  188. ImagingColorItem* v;
  189. unsigned int code_size;
  190. unsigned int code_poly;
  191. unsigned int code_mask;
  192. /* note: the hash algorithm used here is based on the dictionary
  193. code in Python 2.1.3; the exact implementation is borrowed from
  194. Python's Unicode property database (written by yours truly) /F */
  195. static int SIZES[] = {
  196. 4,3, 8,3, 16,3, 32,5, 64,3, 128,3, 256,29, 512,17, 1024,9, 2048,5,
  197. 4096,83, 8192,27, 16384,43, 32768,3, 65536,45, 131072,9, 262144,39,
  198. 524288,39, 1048576,9, 2097152,5, 4194304,3, 8388608,33, 16777216,27,
  199. 33554432,9, 67108864,71, 134217728,39, 268435456,9, 536870912,5,
  200. 1073741824,83, 0
  201. };
  202. code_size = code_poly = code_mask = 0;
  203. for (i = 0; SIZES[i]; i += 2) {
  204. if (SIZES[i] > maxcolors) {
  205. code_size = SIZES[i];
  206. code_poly = SIZES[i+1];
  207. code_mask = code_size - 1;
  208. break;
  209. }
  210. }
  211. /* printf("code_size=%d\n", code_size); */
  212. /* printf("code_poly=%d\n", code_poly); */
  213. if (!code_size)
  214. return ImagingError_MemoryError(); /* just give up */
  215. if (!im->image32)
  216. return ImagingError_ModeError();
  217. table = calloc(code_size + 1, sizeof(ImagingColorItem));
  218. if (!table)
  219. return ImagingError_MemoryError();
  220. pixel_mask = 0xffffffff;
  221. if (im->bands == 3)
  222. ((UINT8*) &pixel_mask)[3] = 0;
  223. colors = 0;
  224. for (y = 0; y < im->ysize; y++) {
  225. INT32* p = im->image32[y];
  226. for (x = 0; x < im->xsize; x++) {
  227. INT32 pixel = p[x] & pixel_mask;
  228. h = (pixel); /* null hashing */
  229. i = (~h) & code_mask;
  230. v = &table[i];
  231. if (!v->count) {
  232. /* add to table */
  233. if (colors++ == maxcolors)
  234. goto overflow;
  235. v->x = x; v->y = y;
  236. v->pixel = pixel;
  237. v->count = 1;
  238. continue;
  239. } else if (v->pixel == pixel) {
  240. v->count++;
  241. continue;
  242. }
  243. incr = (h ^ (h >> 3)) & code_mask;
  244. if (!incr)
  245. incr = code_mask;
  246. for (;;) {
  247. i = (i + incr) & code_mask;
  248. v = &table[i];
  249. if (!v->count) {
  250. /* add to table */
  251. if (colors++ == maxcolors)
  252. goto overflow;
  253. v->x = x; v->y = y;
  254. v->pixel = pixel;
  255. v->count = 1;
  256. break;
  257. } else if (v->pixel == pixel) {
  258. v->count++;
  259. break;
  260. }
  261. incr = incr << 1;
  262. if (incr > code_mask)
  263. incr = incr ^ code_poly;
  264. }
  265. }
  266. }
  267. overflow:
  268. /* pack the table */
  269. for (x = y = 0; x < (int) code_size; x++)
  270. if (table[x].count) {
  271. if (x != y)
  272. table[y] = table[x];
  273. y++;
  274. }
  275. table[y].count = 0; /* mark end of table */
  276. *size = colors;
  277. return table;
  278. }