GetBBox.c 10 KB

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