Histo.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * histogram support
  6. *
  7. * history:
  8. * 1995-06-15 fl Created.
  9. * 1996-04-05 fl Fixed histogram for multiband images.
  10. * 1997-02-23 fl Added mask support
  11. * 1998-07-01 fl Added basic 32-bit float/integer support
  12. *
  13. * Copyright (c) 1997-2003 by Secret Labs AB.
  14. * Copyright (c) 1995-2003 by Fredrik Lundh.
  15. *
  16. * See the README file for information on usage and redistribution.
  17. */
  18. #include "Imaging.h"
  19. /* HISTOGRAM */
  20. /* --------------------------------------------------------------------
  21. * Take a histogram of an image. Returns a histogram object containing
  22. * 256 slots per band in the input image.
  23. */
  24. void
  25. ImagingHistogramDelete(ImagingHistogram h) {
  26. if (h) {
  27. if (h->histogram) {
  28. free(h->histogram);
  29. }
  30. free(h);
  31. }
  32. }
  33. ImagingHistogram
  34. ImagingHistogramNew(Imaging im) {
  35. ImagingHistogram h;
  36. /* Create histogram descriptor */
  37. h = calloc(1, sizeof(struct ImagingHistogramInstance));
  38. if (!h) {
  39. return (ImagingHistogram)ImagingError_MemoryError();
  40. }
  41. strncpy(h->mode, im->mode, IMAGING_MODE_LENGTH - 1);
  42. h->mode[IMAGING_MODE_LENGTH - 1] = 0;
  43. h->bands = im->bands;
  44. h->histogram = calloc(im->pixelsize, 256 * sizeof(long));
  45. if (!h->histogram) {
  46. free(h);
  47. return (ImagingHistogram)ImagingError_MemoryError();
  48. }
  49. return h;
  50. }
  51. ImagingHistogram
  52. ImagingGetHistogram(Imaging im, Imaging imMask, void *minmax) {
  53. ImagingSectionCookie cookie;
  54. int x, y, i;
  55. ImagingHistogram h;
  56. INT32 imin, imax;
  57. FLOAT32 fmin, fmax, scale;
  58. if (!im) {
  59. return ImagingError_ModeError();
  60. }
  61. if (imMask) {
  62. /* Validate mask */
  63. if (im->xsize != imMask->xsize || im->ysize != imMask->ysize) {
  64. return ImagingError_Mismatch();
  65. }
  66. if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0) {
  67. return ImagingError_ValueError("bad transparency mask");
  68. }
  69. }
  70. h = ImagingHistogramNew(im);
  71. if (!h) {
  72. return NULL;
  73. }
  74. if (imMask) {
  75. /* mask */
  76. if (im->image8) {
  77. ImagingSectionEnter(&cookie);
  78. for (y = 0; y < im->ysize; y++) {
  79. for (x = 0; x < im->xsize; x++) {
  80. if (imMask->image8[y][x] != 0) {
  81. h->histogram[im->image8[y][x]]++;
  82. }
  83. }
  84. }
  85. ImagingSectionLeave(&cookie);
  86. } else { /* yes, we need the braces. C isn't Python! */
  87. if (im->type != IMAGING_TYPE_UINT8) {
  88. ImagingHistogramDelete(h);
  89. return ImagingError_ModeError();
  90. }
  91. ImagingSectionEnter(&cookie);
  92. for (y = 0; y < im->ysize; y++) {
  93. UINT8 *in = (UINT8 *)im->image32[y];
  94. for (x = 0; x < im->xsize; x++) {
  95. if (imMask->image8[y][x] != 0) {
  96. h->histogram[(*in++)]++;
  97. h->histogram[(*in++) + 256]++;
  98. h->histogram[(*in++) + 512]++;
  99. h->histogram[(*in++) + 768]++;
  100. } else {
  101. in += 4;
  102. }
  103. }
  104. }
  105. ImagingSectionLeave(&cookie);
  106. }
  107. } else {
  108. /* mask not given; process pixels in image */
  109. if (im->image8) {
  110. ImagingSectionEnter(&cookie);
  111. for (y = 0; y < im->ysize; y++) {
  112. for (x = 0; x < im->xsize; x++) {
  113. h->histogram[im->image8[y][x]]++;
  114. }
  115. }
  116. ImagingSectionLeave(&cookie);
  117. } else {
  118. switch (im->type) {
  119. case IMAGING_TYPE_UINT8:
  120. ImagingSectionEnter(&cookie);
  121. for (y = 0; y < im->ysize; y++) {
  122. UINT8 *in = (UINT8 *)im->image[y];
  123. for (x = 0; x < im->xsize; x++) {
  124. h->histogram[(*in++)]++;
  125. h->histogram[(*in++) + 256]++;
  126. h->histogram[(*in++) + 512]++;
  127. h->histogram[(*in++) + 768]++;
  128. }
  129. }
  130. ImagingSectionLeave(&cookie);
  131. break;
  132. case IMAGING_TYPE_INT32:
  133. if (!minmax) {
  134. ImagingHistogramDelete(h);
  135. return ImagingError_ValueError("min/max not given");
  136. }
  137. if (!im->xsize || !im->ysize) {
  138. break;
  139. }
  140. memcpy(&imin, minmax, sizeof(imin));
  141. memcpy(&imax, ((char *)minmax) + sizeof(imin), sizeof(imax));
  142. if (imin >= imax) {
  143. break;
  144. }
  145. ImagingSectionEnter(&cookie);
  146. scale = 255.0F / (imax - imin);
  147. for (y = 0; y < im->ysize; y++) {
  148. INT32 *in = im->image32[y];
  149. for (x = 0; x < im->xsize; x++) {
  150. i = (int)(((*in++) - imin) * scale);
  151. if (i >= 0 && i < 256) {
  152. h->histogram[i]++;
  153. }
  154. }
  155. }
  156. ImagingSectionLeave(&cookie);
  157. break;
  158. case IMAGING_TYPE_FLOAT32:
  159. if (!minmax) {
  160. ImagingHistogramDelete(h);
  161. return ImagingError_ValueError("min/max not given");
  162. }
  163. if (!im->xsize || !im->ysize) {
  164. break;
  165. }
  166. memcpy(&fmin, minmax, sizeof(fmin));
  167. memcpy(&fmax, ((char *)minmax) + sizeof(fmin), sizeof(fmax));
  168. if (fmin >= fmax) {
  169. break;
  170. }
  171. ImagingSectionEnter(&cookie);
  172. scale = 255.0F / (fmax - fmin);
  173. for (y = 0; y < im->ysize; y++) {
  174. FLOAT32 *in = (FLOAT32 *)im->image32[y];
  175. for (x = 0; x < im->xsize; x++) {
  176. i = (int)(((*in++) - fmin) * scale);
  177. if (i >= 0 && i < 256) {
  178. h->histogram[i]++;
  179. }
  180. }
  181. }
  182. ImagingSectionLeave(&cookie);
  183. break;
  184. }
  185. }
  186. }
  187. return h;
  188. }