QuantHeap.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * heap data type used by the image quantizer
  6. *
  7. * history:
  8. * 98-09-10 tjs Contributed
  9. * 98-12-29 fl Added to PIL 1.0b1
  10. *
  11. * Written by Toby J Sargeant <tjs@longford.cs.monash.edu.au>.
  12. *
  13. * Copyright (c) 1998 by Toby J Sargeant
  14. * Copyright (c) 1998 by Secret Labs AB
  15. *
  16. * See the README file for information on usage and redistribution.
  17. */
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <math.h>
  22. #include <limits.h>
  23. #include "QuantHeap.h"
  24. struct _Heap {
  25. void **heap;
  26. int heapsize;
  27. int heapcount;
  28. HeapCmpFunc cf;
  29. };
  30. #define INITIAL_SIZE 256
  31. // #define DEBUG
  32. #ifdef DEBUG
  33. static int _heap_test(Heap *);
  34. #endif
  35. void ImagingQuantHeapFree(Heap *h) {
  36. free(h->heap);
  37. free(h);
  38. }
  39. static int _heap_grow(Heap *h,int newsize) {
  40. void *newheap;
  41. if (!newsize) newsize=h->heapsize<<1;
  42. if (newsize<h->heapsize) return 0;
  43. if (newsize > INT_MAX / sizeof(void *)){
  44. return 0;
  45. }
  46. /* malloc check ok, using calloc for overflow, also checking
  47. above due to memcpy below*/
  48. newheap=calloc(newsize, sizeof(void *));
  49. if (!newheap) return 0;
  50. memcpy(newheap,h->heap,sizeof(void *)*h->heapsize);
  51. free(h->heap);
  52. h->heap=newheap;
  53. h->heapsize=newsize;
  54. return 1;
  55. }
  56. #ifdef DEBUG
  57. static int _heap_test(Heap *h) {
  58. int k;
  59. for (k=1;k*2<=h->heapcount;k++) {
  60. if (h->cf(h,h->heap[k],h->heap[k*2])<0) {
  61. printf ("heap is bad\n");
  62. return 0;
  63. }
  64. if (k*2+1<=h->heapcount && h->cf(h,h->heap[k],h->heap[k*2+1])<0) {
  65. printf ("heap is bad\n");
  66. return 0;
  67. }
  68. }
  69. return 1;
  70. }
  71. #endif
  72. int ImagingQuantHeapRemove(Heap* h,void **r) {
  73. int k,l;
  74. void *v;
  75. if (!h->heapcount) {
  76. return 0;
  77. }
  78. *r=h->heap[1];
  79. v=h->heap[h->heapcount--];
  80. for (k=1;k*2<=h->heapcount;k=l) {
  81. l=k*2;
  82. if (l<h->heapcount) {
  83. if (h->cf(h,h->heap[l],h->heap[l+1])<0) {
  84. l++;
  85. }
  86. }
  87. if (h->cf(h,v,h->heap[l])>0) {
  88. break;
  89. }
  90. h->heap[k]=h->heap[l];
  91. }
  92. h->heap[k]=v;
  93. #ifdef DEBUG
  94. if (!_heap_test(h)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); }
  95. #endif
  96. return 1;
  97. }
  98. int ImagingQuantHeapAdd(Heap *h,void *val) {
  99. int k;
  100. if (h->heapcount==h->heapsize-1) {
  101. _heap_grow(h,0);
  102. }
  103. k=++h->heapcount;
  104. while (k!=1) {
  105. if (h->cf(h,val,h->heap[k/2])<=0) {
  106. break;
  107. }
  108. h->heap[k]=h->heap[k/2];
  109. k>>=1;
  110. }
  111. h->heap[k]=val;
  112. #ifdef DEBUG
  113. if (!_heap_test(h)) { printf ("oops - heap_add messed up the heap\n"); exit(1); }
  114. #endif
  115. return 1;
  116. }
  117. int ImagingQuantHeapTop(Heap *h,void **r) {
  118. if (!h->heapcount) {
  119. return 0;
  120. }
  121. *r=h->heap[1];
  122. return 1;
  123. }
  124. Heap *ImagingQuantHeapNew(HeapCmpFunc cf) {
  125. Heap *h;
  126. /* malloc check ok, small constant allocation */
  127. h=malloc(sizeof(Heap));
  128. if (!h) return NULL;
  129. h->heapsize=INITIAL_SIZE;
  130. /* malloc check ok, using calloc for overflow */
  131. h->heap=calloc(h->heapsize, sizeof(void *));
  132. if (!h->heap) {
  133. free(h);
  134. return NULL;
  135. }
  136. h->heapcount=0;
  137. h->cf=cf;
  138. return h;
  139. }