Histo.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. {
  27. if (h->histogram)
  28. free(h->histogram);
  29. free(h);
  30. }
  31. ImagingHistogram
  32. ImagingHistogramNew(Imaging im)
  33. {
  34. ImagingHistogram h;
  35. /* Create histogram descriptor */
  36. h = calloc(1, sizeof(struct ImagingHistogramInstance));
  37. strncpy(h->mode, im->mode, IMAGING_MODE_LENGTH-1);
  38. h->mode[IMAGING_MODE_LENGTH-1] = 0;
  39. h->bands = im->bands;
  40. h->histogram = calloc(im->pixelsize, 256 * sizeof(long));
  41. return h;
  42. }
  43. ImagingHistogram
  44. ImagingGetHistogram(Imaging im, Imaging imMask, void* minmax)
  45. {
  46. ImagingSectionCookie cookie;
  47. int x, y, i;
  48. ImagingHistogram h;
  49. INT32 imin, imax;
  50. FLOAT32 fmin, fmax, scale;
  51. if (!im)
  52. return ImagingError_ModeError();
  53. if (imMask) {
  54. /* Validate mask */
  55. if (im->xsize != imMask->xsize || im->ysize != imMask->ysize)
  56. return ImagingError_Mismatch();
  57. if (strcmp(imMask->mode, "1") != 0 && strcmp(imMask->mode, "L") != 0)
  58. return ImagingError_ValueError("bad transparency mask");
  59. }
  60. h = ImagingHistogramNew(im);
  61. if (imMask) {
  62. /* mask */
  63. if (im->image8) {
  64. ImagingSectionEnter(&cookie);
  65. for (y = 0; y < im->ysize; y++)
  66. for (x = 0; x < im->xsize; x++)
  67. if (imMask->image8[y][x] != 0)
  68. h->histogram[im->image8[y][x]]++;
  69. ImagingSectionLeave(&cookie);
  70. } else { /* yes, we need the braces. C isn't Python! */
  71. if (im->type != IMAGING_TYPE_UINT8) {
  72. ImagingHistogramDelete(h);
  73. return ImagingError_ModeError();
  74. }
  75. ImagingSectionEnter(&cookie);
  76. for (y = 0; y < im->ysize; y++) {
  77. UINT8* in = (UINT8*) im->image32[y];
  78. for (x = 0; x < im->xsize; x++)
  79. if (imMask->image8[y][x] != 0) {
  80. h->histogram[(*in++)]++;
  81. h->histogram[(*in++)+256]++;
  82. h->histogram[(*in++)+512]++;
  83. h->histogram[(*in++)+768]++;
  84. } else
  85. in += 4;
  86. }
  87. ImagingSectionLeave(&cookie);
  88. }
  89. } else {
  90. /* mask not given; process pixels in image */
  91. if (im->image8) {
  92. ImagingSectionEnter(&cookie);
  93. for (y = 0; y < im->ysize; y++)
  94. for (x = 0; x < im->xsize; x++)
  95. h->histogram[im->image8[y][x]]++;
  96. ImagingSectionLeave(&cookie);
  97. } else {
  98. switch (im->type) {
  99. case IMAGING_TYPE_UINT8:
  100. ImagingSectionEnter(&cookie);
  101. for (y = 0; y < im->ysize; y++) {
  102. UINT8* in = (UINT8*) im->image[y];
  103. for (x = 0; x < im->xsize; x++) {
  104. h->histogram[(*in++)]++;
  105. h->histogram[(*in++)+256]++;
  106. h->histogram[(*in++)+512]++;
  107. h->histogram[(*in++)+768]++;
  108. }
  109. }
  110. ImagingSectionLeave(&cookie);
  111. break;
  112. case IMAGING_TYPE_INT32:
  113. if (!minmax) {
  114. ImagingHistogramDelete(h);
  115. return ImagingError_ValueError("min/max not given");
  116. }
  117. if (!im->xsize || !im->ysize)
  118. break;
  119. memcpy(&imin, minmax, sizeof(imin));
  120. memcpy(&imax, ((char*)minmax) + sizeof(imin), sizeof(imax));
  121. if (imin >= imax)
  122. break;
  123. ImagingSectionEnter(&cookie);
  124. scale = 255.0F / (imax - imin);
  125. for (y = 0; y < im->ysize; y++) {
  126. INT32* in = im->image32[y];
  127. for (x = 0; x < im->xsize; x++) {
  128. i = (int) (((*in++)-imin)*scale);
  129. if (i >= 0 && i < 256)
  130. h->histogram[i]++;
  131. }
  132. }
  133. ImagingSectionLeave(&cookie);
  134. break;
  135. case IMAGING_TYPE_FLOAT32:
  136. if (!minmax) {
  137. ImagingHistogramDelete(h);
  138. return ImagingError_ValueError("min/max not given");
  139. }
  140. if (!im->xsize || !im->ysize)
  141. break;
  142. memcpy(&fmin, minmax, sizeof(fmin));
  143. memcpy(&fmax, ((char*)minmax) + sizeof(fmin), sizeof(fmax));
  144. if (fmin >= fmax)
  145. break;
  146. ImagingSectionEnter(&cookie);
  147. scale = 255.0F / (fmax - fmin);
  148. for (y = 0; y < im->ysize; y++) {
  149. FLOAT32* in = (FLOAT32*) im->image32[y];
  150. for (x = 0; x < im->xsize; x++) {
  151. i = (int) (((*in++)-fmin)*scale);
  152. if (i >= 0 && i < 256)
  153. h->histogram[i]++;
  154. }
  155. }
  156. ImagingSectionLeave(&cookie);
  157. break;
  158. }
  159. }
  160. }
  161. return h;
  162. }