You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
python-pillow/python-pillow_quantization....

1792 lines
54 KiB

diff --git a/_imaging.c b/_imaging.c
index c9d3c82..2ee7eef 100644
--- a/_imaging.c
+++ b/_imaging.c
@@ -1369,7 +1369,6 @@ _putdata(ImagingObject* self, PyObject* args)
#ifdef WITH_QUANTIZE
-#include "Quant.h"
static PyObject*
_quantize(ImagingObject* self, PyObject* args)
{
diff --git a/libImaging/Quant.c b/libImaging/Quant.c
index ff15ac0..7f328bd 100644
--- a/libImaging/Quant.c
+++ b/libImaging/Quant.c
@@ -25,17 +25,15 @@
#include <memory.h>
#include <time.h>
-#include "Quant.h"
+#include "QuantTypes.h"
#include "QuantOctree.h"
-
-#include "QuantDefines.h"
#include "QuantHash.h"
#include "QuantHeap.h"
#define NO_OUTPUT
typedef struct {
- unsigned long scale;
+ uint32_t scale;
} PixelHashData;
typedef struct _PixelList {
@@ -50,7 +48,7 @@ typedef struct _BoxNode {
PixelList *head[3],*tail[3];
int axis;
int volume;
- unsigned long pixelCount;
+ uint32_t pixelCount;
} BoxNode;
#define _SQR(x) ((x)*(x))
@@ -76,104 +74,92 @@ typedef struct _BoxNode {
((q)->c.g=(p)->c.g>>(s)), \
((q)->c.b=(p)->c.b>>(s))
-static unsigned long
-unshifted_pixel_hash(const HashTable h, const void *p)
+static uint32_t
+unshifted_pixel_hash(const HashTable *h, const Pixel pixel)
{
- Pixel *pixel=(Pixel *)&p;
- unsigned long hash=PIXEL_HASH(pixel->c.r,
- pixel->c.g,
- pixel->c.b);
- return hash;
+ return PIXEL_HASH(pixel.c.r, pixel.c.g, pixel.c.b);
}
static int
-unshifted_pixel_cmp(const HashTable h, const void *a, const void *b)
+unshifted_pixel_cmp(const HashTable *h, const Pixel pixel1, const Pixel pixel2)
{
- Pixel *pixel1=(Pixel *)&a;
- Pixel *pixel2=(Pixel *)&b;
- if (pixel1->c.r==pixel2->c.r) {
- if (pixel1->c.g==pixel2->c.g) {
- if (pixel1->c.b==pixel2->c.b) {
+ if (pixel1.c.r==pixel2.c.r) {
+ if (pixel1.c.g==pixel2.c.g) {
+ if (pixel1.c.b==pixel2.c.b) {
return 0;
} else {
- return (int)(pixel1->c.b)-(int)(pixel2->c.b);
+ return (int)(pixel1.c.b)-(int)(pixel2.c.b);
}
} else {
- return (int)(pixel1->c.g)-(int)(pixel2->c.g);
+ return (int)(pixel1.c.g)-(int)(pixel2.c.g);
}
} else {
- return (int)(pixel1->c.r)-(int)(pixel2->c.r);
+ return (int)(pixel1.c.r)-(int)(pixel2.c.r);
}
}
-static unsigned long
-pixel_hash(const HashTable h,const void *p)
+static uint32_t
+pixel_hash(const HashTable *h,const Pixel pixel)
{
PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h);
- Pixel *pixel=(Pixel *)&p;
- unsigned long hash=PIXEL_HASH(pixel->c.r>>d->scale,
- pixel->c.g>>d->scale,
- pixel->c.b>>d->scale);
- return hash;
+ return PIXEL_HASH(pixel.c.r>>d->scale, pixel.c.g>>d->scale, pixel.c.b>>d->scale);
}
static int
-pixel_cmp(const HashTable h,const void *a,const void *b)
+pixel_cmp(const HashTable *h,const Pixel pixel1, const Pixel pixel2)
{
PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h);
- Pixel *pixel1=(Pixel *)&a;
- Pixel *pixel2=(Pixel *)&b;
- unsigned long A,B;
- A=PIXEL_HASH(pixel1->c.r>>d->scale,
- pixel1->c.g>>d->scale,
- pixel1->c.b>>d->scale);
- B=PIXEL_HASH(pixel2->c.r>>d->scale,
- pixel2->c.g>>d->scale,
- pixel2->c.b>>d->scale);
+ uint32_t A,B;
+ A=PIXEL_HASH(pixel1.c.r>>d->scale, pixel1.c.g>>d->scale, pixel1.c.b>>d->scale);
+ B=PIXEL_HASH(pixel2.c.r>>d->scale, pixel2.c.g>>d->scale, pixel2.c.b>>d->scale);
return (A==B)?0:((A<B)?-1:1);
}
static void
-exists_count_func(const HashTable h, const void *key, void **val)
+exists_count_func(const HashTable *h, const Pixel key, uint32_t *val)
{
- *(unsigned long*)val+=1;
+ *val+=1;
}
static void
-new_count_func(const HashTable h, const void *key, void **val)
+new_count_func(const HashTable *h, const Pixel key, uint32_t *val)
{
- *(unsigned long*)val=1;
+ *val=1;
}
static void
-rehash_collide(HashTable h,
- void **keyp,
- void **valp,
- void *newkey,
- void *newval)
+rehash_collide(const HashTable *h,
+ Pixel *keyp,
+ uint32_t *valp,
+ Pixel newkey,
+ uint32_t newval)
{
- *valp = (void *)(((unsigned long) *valp) + ((unsigned long) newval));
+ *valp += newval;
}
/* %% */
-static HashTable
-create_pixel_hash(Pixel *pixelData,unsigned long nPixels)
+static HashTable *
+create_pixel_hash(Pixel *pixelData,uint32_t nPixels)
{
PixelHashData *d;
HashTable *hash;
- unsigned long i;
- unsigned long timer,timer2,timer3;
+ uint32_t i;
+#ifndef NO_OUTPUT
+ uint32_t timer,timer2,timer3;
+#endif
d=malloc(sizeof(PixelHashData));
if (!d) return NULL;
hash=hashtable_new(pixel_hash,pixel_cmp);
hashtable_set_user_data(hash,d);
d->scale=0;
+#ifndef NO_OUTPUT
timer=timer3=clock();
+#endif
for (i=0;i<nPixels;i++) {
if (!hashtable_insert_or_update_computed(hash,
- (void *)pixelData[i].v,
+ pixelData[i],
new_count_func,
exists_count_func)) {;
}
@@ -181,14 +167,14 @@ create_pixel_hash(Pixel *pixelData,unsigned long nPixels)
d->scale++;
#ifndef NO_OUTPUT
printf ("rehashing - new scale: %d\n",(int)d->scale);
-#endif
timer2=clock();
+#endif
hashtable_rehash_compute(hash,rehash_collide);
- timer2=clock()-timer2;
#ifndef NO_OUTPUT
+ timer2=clock()-timer2;
printf ("rehash took %f sec\n",timer2/(double)CLOCKS_PER_SEC);
-#endif
timer+=timer2;
+#endif
}
}
#ifndef NO_OUTPUT
@@ -201,7 +187,7 @@ create_pixel_hash(Pixel *pixelData,unsigned long nPixels)
}
static void
-destroy_pixel_hash(HashTable hash)
+destroy_pixel_hash(HashTable *hash)
{
PixelHashData *d=(PixelHashData *)hashtable_get_user_data(hash);
if (d) free(d);
@@ -237,17 +223,15 @@ compute_box_volume(BoxNode *b)
}
static void
-hash_to_list(HashTable h, const void *key, const void *val, void *u)
+hash_to_list(const HashTable *h, const Pixel pixel, const uint32_t count, void *u)
{
PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h);
PixelList **pl=(PixelList **)u;
PixelList *p;
- Pixel *pixel=(Pixel *)&key;
int i;
Pixel q;
- int count=(unsigned long) val;
- PIXEL_SCALE(pixel,&q,d->scale);
+ PIXEL_SCALE(&pixel,&q,d->scale);
p=malloc(sizeof(PixelList));
if (!p) return;
@@ -327,7 +311,7 @@ test_sorted(PixelList *pl[3])
#endif
static int
-box_heap_cmp(const Heap h, const void *A, const void *B)
+box_heap_cmp(const Heap *h, const void *A, const void *B)
{
BoxNode *a=(BoxNode *)A;
BoxNode *b=(BoxNode *)B;
@@ -341,11 +325,11 @@ splitlists(PixelList *h[3],
PixelList *t[3],
PixelList *nh[2][3],
PixelList *nt[2][3],
- unsigned long nCount[2],
+ uint32_t nCount[2],
int axis,
- unsigned long pixelCount)
+ uint32_t pixelCount)
{
- unsigned long left;
+ uint32_t left;
PixelList *l,*r,*c,*n;
int i;
@@ -476,7 +460,7 @@ split(BoxNode *node)
int i;
PixelList *heads[2][3];
PixelList *tails[2][3];
- unsigned long newCounts[2];
+ uint32_t newCounts[2];
BoxNode *left,*right;
rh=node->head[0]->p.c.r;
@@ -618,13 +602,13 @@ split(BoxNode *node)
static BoxNode *
median_cut(PixelList *hl[3],
- unsigned long imPixelCount,
+ uint32_t imPixelCount,
int nPixels)
{
PixelList *tl[3];
int i;
BoxNode *root;
- Heap h;
+ Heap* h;
BoxNode *thisNode;
h=ImagingQuantHeapNew(box_heap_cmp);
@@ -701,7 +685,7 @@ checkContained(BoxNode *n,Pixel *pp)
#endif
static int
-annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box)
+annotate_hash_table(BoxNode *n,HashTable *h,uint32_t *box)
{
PixelList *p;
PixelHashData *d=(PixelHashData *)hashtable_get_user_data(h);
@@ -717,7 +701,7 @@ annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box)
}
for (p=n->head[0];p;p=p->next[0]) {
PIXEL_UNSCALE(&(p->p),&q,d->scale);
- if (!hashtable_insert(h,(void *)q.v,(void *)*box)) {
+ if (!hashtable_insert(h,q,*box)) {
#ifndef NO_OUTPUT
printf ("hashtable insert failed\n");
#endif
@@ -731,20 +715,20 @@ annotate_hash_table(BoxNode *n,HashTable h,unsigned long *box)
static int
_sort_ulong_ptr_keys(const void *a, const void *b)
{
- unsigned long A=**(unsigned long **)a;
- unsigned long B=**(unsigned long **)b;
+ uint32_t A=**(uint32_t **)a;
+ uint32_t B=**(uint32_t **)b;
return (A==B)?0:((A<B)?-1:+1);
}
static int
-resort_distance_tables(unsigned long *avgDist,
- unsigned long **avgDistSortKey,
+resort_distance_tables(uint32_t *avgDist,
+ uint32_t **avgDistSortKey,
Pixel *p,
- unsigned long nEntries)
+ uint32_t nEntries)
{
- unsigned long i,j,k;
- unsigned long **skRow;
- unsigned long *skElt;
+ uint32_t i,j,k;
+ uint32_t **skRow;
+ uint32_t *skElt;
for (i=0;i<nEntries;i++) {
avgDist[i*nEntries+i]=0;
@@ -767,12 +751,12 @@ resort_distance_tables(unsigned long *avgDist,
}
static int
-build_distance_tables(unsigned long *avgDist,
- unsigned long **avgDistSortKey,
+build_distance_tables(uint32_t *avgDist,
+ uint32_t **avgDistSortKey,
Pixel *p,
- unsigned long nEntries)
+ uint32_t nEntries)
{
- unsigned long i,j;
+ uint32_t i,j;
for (i=0;i<nEntries;i++) {
avgDist[i*nEntries+i]=0;
@@ -787,7 +771,7 @@ build_distance_tables(unsigned long *avgDist,
for (i=0;i<nEntries;i++) {
qsort(avgDistSortKey+i*nEntries,
nEntries,
- sizeof(unsigned long *),
+ sizeof(uint32_t *),
_sort_ulong_ptr_keys);
}
return 1;
@@ -795,23 +779,23 @@ build_distance_tables(unsigned long *avgDist,
static int
map_image_pixels(Pixel *pixelData,
- unsigned long nPixels,
+ uint32_t nPixels,
Pixel *paletteData,
- unsigned long nPaletteEntries,
- unsigned long *avgDist,
- unsigned long **avgDistSortKey,
- unsigned long *pixelArray)
+ uint32_t nPaletteEntries,
+ uint32_t *avgDist,
+ uint32_t **avgDistSortKey,
+ uint32_t *pixelArray)
{
- unsigned long *aD,**aDSK;
- unsigned long idx;
- unsigned long i,j;
- unsigned long bestdist,bestmatch,dist;
- unsigned long initialdist;
- HashTable h2;
+ uint32_t *aD,**aDSK;
+ uint32_t idx;
+ uint32_t i,j;
+ uint32_t bestdist,bestmatch,dist;
+ uint32_t initialdist;
+ HashTable *h2;
h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
for (i=0;i<nPixels;i++) {
- if (!hashtable_lookup(h2,(void *)pixelData[i].v,(void **)&bestmatch)) {
+ if (!hashtable_lookup(h2,pixelData[i],&bestmatch)) {
bestmatch=0;
initialdist=_DISTSQR(paletteData+bestmatch,pixelData+i);
bestdist=initialdist;
@@ -830,7 +814,7 @@ map_image_pixels(Pixel *pixelData,
break;
}
}
- hashtable_insert(h2,(void *)pixelData[i].v,(void *)bestmatch);
+ hashtable_insert(h2,pixelData[i],bestmatch);
}
pixelArray[i]=bestmatch;
}
@@ -841,26 +825,26 @@ map_image_pixels(Pixel *pixelData,
static int
map_image_pixels_from_quantized_pixels(
Pixel *pixelData,
- unsigned long nPixels,
+ uint32_t nPixels,
Pixel *paletteData,
- unsigned long nPaletteEntries,
- unsigned long *avgDist,
- unsigned long **avgDistSortKey,
- unsigned long *pixelArray,
- unsigned long *avg[3],
- unsigned long *count)
+ uint32_t nPaletteEntries,
+ uint32_t *avgDist,
+ uint32_t **avgDistSortKey,
+ uint32_t *pixelArray,
+ uint32_t *avg[3],
+ uint32_t *count)
{
- unsigned long *aD,**aDSK;
- unsigned long idx;
- unsigned long i,j;
- unsigned long bestdist,bestmatch,dist;
- unsigned long initialdist;
- HashTable h2;
+ uint32_t *aD,**aDSK;
+ uint32_t idx;
+ uint32_t i,j;
+ uint32_t bestdist,bestmatch,dist;
+ uint32_t initialdist;
+ HashTable *h2;
int changes=0;
h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
for (i=0;i<nPixels;i++) {
- if (!hashtable_lookup(h2,(void *)pixelData[i].v,(void **)&bestmatch)) {
+ if (!hashtable_lookup(h2,pixelData[i],&bestmatch)) {
bestmatch=pixelArray[i];
initialdist=_DISTSQR(paletteData+bestmatch,pixelData+i);
bestdist=initialdist;
@@ -879,7 +863,7 @@ map_image_pixels_from_quantized_pixels(
break;
}
}
- hashtable_insert(h2,(void *)pixelData[i].v,(void *)bestmatch);
+ hashtable_insert(h2,pixelData[i],bestmatch);
}
if (pixelArray[i]!=bestmatch) {
changes++;
@@ -901,29 +885,29 @@ map_image_pixels_from_quantized_pixels(
static int
map_image_pixels_from_median_box(
Pixel *pixelData,
- unsigned long nPixels,
+ uint32_t nPixels,
Pixel *paletteData,
- unsigned long nPaletteEntries,
+ uint32_t nPaletteEntries,
HashTable *medianBoxHash,
- unsigned long *avgDist,
- unsigned long **avgDistSortKey,
- unsigned long *pixelArray)
+ uint32_t *avgDist,
+ uint32_t **avgDistSortKey,
+ uint32_t *pixelArray)
{
- unsigned long *aD,**aDSK;
- unsigned long idx;
- unsigned long i,j;
- unsigned long bestdist,bestmatch,dist;
- unsigned long initialdist;
- HashTable h2;
- unsigned long pixelVal;
+ uint32_t *aD,**aDSK;
+ uint32_t idx;
+ uint32_t i,j;
+ uint32_t bestdist,bestmatch,dist;
+ uint32_t initialdist;
+ HashTable *h2;
+ uint32_t pixelVal;
h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
for (i=0;i<nPixels;i++) {
- if (hashtable_lookup(h2,(void *)pixelData[i].v,(void **)&pixelVal)) {
+ if (hashtable_lookup(h2,pixelData[i],&pixelVal)) {
pixelArray[i]=pixelVal;
continue;
}
- if (!hashtable_lookup(medianBoxHash,(void *)pixelData[i].v,(void **)&pixelVal)) {
+ if (!hashtable_lookup(medianBoxHash,pixelData[i],&pixelVal)) {
#ifndef NO_OUTPUT
printf ("pixel lookup failed\n");
#endif
@@ -948,7 +932,7 @@ map_image_pixels_from_median_box(
}
}
pixelArray[i]=bestmatch;
- hashtable_insert(h2,(void *)pixelData[i].v,(void *)bestmatch);
+ hashtable_insert(h2,pixelData[i],bestmatch);
}
hashtable_free(h2);
return 1;
@@ -957,27 +941,27 @@ map_image_pixels_from_median_box(
static int
compute_palette_from_median_cut(
Pixel *pixelData,
- unsigned long nPixels,
- HashTable medianBoxHash,
+ uint32_t nPixels,
+ HashTable *medianBoxHash,
Pixel **palette,
- unsigned long nPaletteEntries)
+ uint32_t nPaletteEntries)
{
- unsigned long i;
- unsigned long paletteEntry;
+ uint32_t i;
+ uint32_t paletteEntry;
Pixel *p;
- unsigned long *avg[3];
- unsigned long *count;
+ uint32_t *avg[3];
+ uint32_t *count;
*palette=NULL;
- if (!(count=malloc(sizeof(unsigned long)*nPaletteEntries))) {
+ if (!(count=malloc(sizeof(uint32_t)*nPaletteEntries))) {
return 0;
}
- memset(count,0,sizeof(unsigned long)*nPaletteEntries);
+ memset(count,0,sizeof(uint32_t)*nPaletteEntries);
for(i=0;i<3;i++) {
avg[i]=NULL;
}
for(i=0;i<3;i++) {
- if (!(avg[i]=malloc(sizeof(unsigned long)*nPaletteEntries))) {
+ if (!(avg[i]=malloc(sizeof(uint32_t)*nPaletteEntries))) {
for(i=0;i<3;i++) {
if (avg[i]) free (avg[i]);
}
@@ -986,7 +970,7 @@ compute_palette_from_median_cut(
}
}
for(i=0;i<3;i++) {
- memset(avg[i],0,sizeof(unsigned long)*nPaletteEntries);
+ memset(avg[i],0,sizeof(uint32_t)*nPaletteEntries);
}
for (i=0;i<nPixels;i++) {
#ifdef TEST_SPLIT_INTEGRITY
@@ -998,7 +982,7 @@ compute_palette_from_median_cut(
return 0;
}
#endif
- if (!hashtable_lookup(medianBoxHash,(void *)pixelData[i].v,(void **)&paletteEntry)) {
+ if (!hashtable_lookup(medianBoxHash,pixelData[i],&paletteEntry)) {
#ifndef NO_OUTPUT
printf ("pixel lookup failed\n");
#endif
@@ -1039,11 +1023,11 @@ compute_palette_from_median_cut(
static int
recompute_palette_from_averages(
Pixel *palette,
- unsigned long nPaletteEntries,
- unsigned long *avg[3],
- unsigned long *count)
+ uint32_t nPaletteEntries,
+ uint32_t *avg[3],
+ uint32_t *count)
{
- unsigned long i;
+ uint32_t i;
for (i=0;i<nPaletteEntries;i++) {
palette[i].c.r=(int)(.5+(double)avg[0][i]/(double)count[i]);
@@ -1056,18 +1040,18 @@ recompute_palette_from_averages(
static int
compute_palette_from_quantized_pixels(
Pixel *pixelData,
- unsigned long nPixels,
+ uint32_t nPixels,
Pixel *palette,
- unsigned long nPaletteEntries,
- unsigned long *avg[3],
- unsigned long *count,
- unsigned long *qp)
+ uint32_t nPaletteEntries,
+ uint32_t *avg[3],
+ uint32_t *count,
+ uint32_t *qp)
{
- unsigned long i;
+ uint32_t i;
- memset(count,0,sizeof(unsigned long)*nPaletteEntries);
+ memset(count,0,sizeof(uint32_t)*nPaletteEntries);
for(i=0;i<3;i++) {
- memset(avg[i],0,sizeof(unsigned long)*nPaletteEntries);
+ memset(avg[i],0,sizeof(uint32_t)*nPaletteEntries);
}
for (i=0;i<nPixels;i++) {
if (qp[i]>=nPaletteEntries) {
@@ -1091,35 +1075,35 @@ compute_palette_from_quantized_pixels(
static int
k_means(Pixel *pixelData,
- unsigned long nPixels,
+ uint32_t nPixels,
Pixel *paletteData,
- unsigned long nPaletteEntries,
- unsigned long *qp,
+ uint32_t nPaletteEntries,
+ uint32_t *qp,
int threshold)
{
- unsigned long *avg[3];
- unsigned long *count;
- unsigned long i;
- unsigned long *avgDist;
- unsigned long **avgDistSortKey;
+ uint32_t *avg[3];
+ uint32_t *count;
+ uint32_t i;
+ uint32_t *avgDist;
+ uint32_t **avgDistSortKey;
int changes;
int built=0;
- if (!(count=malloc(sizeof(unsigned long)*nPaletteEntries))) {
+ if (!(count=malloc(sizeof(uint32_t)*nPaletteEntries))) {
return 0;
}
for(i=0;i<3;i++) {
avg[i]=NULL;
}
for(i=0;i<3;i++) {
- if (!(avg[i]=malloc(sizeof(unsigned long)*nPaletteEntries))) {
+ if (!(avg[i]=malloc(sizeof(uint32_t)*nPaletteEntries))) {
goto error_1;
}
}
- avgDist=malloc(sizeof(unsigned long)*nPaletteEntries*nPaletteEntries);
+ avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries);
if (!avgDist) { goto error_1; }
- avgDistSortKey=malloc(sizeof(unsigned long *)*nPaletteEntries*nPaletteEntries);
+ avgDistSortKey=malloc(sizeof(uint32_t *)*nPaletteEntries*nPaletteEntries);
if (!avgDistSortKey) { goto error_2; }
#ifndef NO_OUTPUT
@@ -1172,26 +1156,26 @@ error_1:
int
quantize(Pixel *pixelData,
- unsigned long nPixels,
- unsigned long nQuantPixels,
+ uint32_t nPixels,
+ uint32_t nQuantPixels,
Pixel **palette,
- unsigned long *paletteLength,
- unsigned long **quantizedPixels,
+ uint32_t *paletteLength,
+ uint32_t **quantizedPixels,
int kmeans)
{
PixelList *hl[3];
- HashTable h;
+ HashTable *h;
BoxNode *root;
- unsigned long i;
- unsigned long *qp;
- unsigned long nPaletteEntries;
+ uint32_t i;
+ uint32_t *qp;
+ uint32_t nPaletteEntries;
- unsigned long *avgDist;
- unsigned long **avgDistSortKey;
+ uint32_t *avgDist;
+ uint32_t **avgDistSortKey;
Pixel *p;
#ifndef NO_OUTPUT
- unsigned long timer,timer2;
+ uint32_t timer,timer2;
#endif
#ifndef NO_OUTPUT
@@ -1266,13 +1250,13 @@ quantize(Pixel *pixelData,
free_box_tree(root);
root=NULL;
- qp=malloc(sizeof(unsigned long)*nPixels);
+ qp=malloc(sizeof(uint32_t)*nPixels);
if (!qp) { goto error_4; }
- avgDist=malloc(sizeof(unsigned long)*nPaletteEntries*nPaletteEntries);
+ avgDist=malloc(sizeof(uint32_t)*nPaletteEntries*nPaletteEntries);
if (!avgDist) { goto error_5; }
- avgDistSortKey=malloc(sizeof(unsigned long *)*nPaletteEntries*nPaletteEntries);
+ avgDistSortKey=malloc(sizeof(uint32_t *)*nPaletteEntries*nPaletteEntries);
if (!avgDistSortKey) { goto error_6; }
if (!build_distance_tables(avgDist,avgDistSortKey,p,nPaletteEntries)) {
@@ -1286,12 +1270,12 @@ quantize(Pixel *pixelData,
#ifdef TEST_NEAREST_NEIGHBOUR
#include <math.h>
{
- unsigned long bestmatch,bestdist,dist;
- HashTable h2;
+ uint32_t bestmatch,bestdist,dist;
+ HashTable *h2;
printf ("nearest neighbour search (full search)..."); fflush(stdout); timer=clock();
h2=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
for (i=0;i<nPixels;i++) {
- if (hashtable_lookup(h2,(void *)pixelData[i].v,(void **)&paletteEntry)) {
+ if (hashtable_lookup(h2,pixelData[i],&paletteEntry)) {
bestmatch=paletteEntry;
} else {
bestmatch=0;
@@ -1312,7 +1296,7 @@ quantize(Pixel *pixelData,
bestmatch=j;
}
}
- hashtable_insert(h2,(void *)pixelData[i].v,(void *)bestmatch);
+ hashtable_insert(h2,pixelData[i],bestmatch);
}
if (qp[i]!=bestmatch ) {
printf ("discrepancy in matching algorithms pixel %d [%d %d] %f %f\n",
@@ -1375,53 +1359,52 @@ error_0:
typedef struct {
Pixel new;
Pixel furthest;
- unsigned long furthestDistance;
+ uint32_t furthestDistance;
int secondPixel;
} DistanceData;
static void
-compute_distances(const HashTable h, const void *key, void **val, void *u)
+compute_distances(const HashTable *h, const Pixel pixel, uint32_t *dist, void *u)
{
DistanceData *data=(DistanceData *)u;
- Pixel *pixel=(Pixel *)&key;
- unsigned long oldDist=*(unsigned long *)val;
- unsigned long newDist;
- newDist=_DISTSQR(&(data->new),pixel);
+ uint32_t oldDist=*dist;
+ uint32_t newDist;
+ newDist=_DISTSQR(&(data->new),&pixel);
if (data->secondPixel || newDist<oldDist) {
- *(unsigned long *)val=newDist;
+ *dist=newDist;
oldDist=newDist;
}
if (oldDist>data->furthestDistance) {
data->furthestDistance=oldDist;
- data->furthest.v=pixel->v;
+ data->furthest.v=pixel.v;
}
}
int
quantize2(Pixel *pixelData,
- unsigned long nPixels,
- unsigned long nQuantPixels,
+ uint32_t nPixels,
+ uint32_t nQuantPixels,
Pixel **palette,
- unsigned long *paletteLength,
- unsigned long **quantizedPixels,
+ uint32_t *paletteLength,
+ uint32_t **quantizedPixels,
int kmeans)
{
- HashTable h;
- unsigned long i;
- unsigned long mean[3];
+ HashTable *h;
+ uint32_t i;
+ uint32_t mean[3];
Pixel *p;
DistanceData data;
- unsigned long *qp;
- unsigned long *avgDist;
- unsigned long **avgDistSortKey;
+ uint32_t *qp;
+ uint32_t *avgDist;
+ uint32_t **avgDistSortKey;
p=malloc(sizeof(Pixel)*nQuantPixels);
if (!p) return 0;
mean[0]=mean[1]=mean[2]=0;
h=hashtable_new(unshifted_pixel_hash,unshifted_pixel_cmp);
for (i=0;i<nPixels;i++) {
- hashtable_insert(h,(void *)pixelData[i].v,(void *)0xffffffff);
+ hashtable_insert(h,pixelData[i],0xffffffff);
mean[0]+=pixelData[i].c.r;
mean[1]+=pixelData[i].c.g;
mean[2]+=pixelData[i].c.b;
@@ -1438,13 +1421,13 @@ quantize2(Pixel *pixelData,
}
hashtable_free(h);
- qp=malloc(sizeof(unsigned long)*nPixels);
+ qp=malloc(sizeof(uint32_t)*nPixels);
if (!qp) { goto error_1; }
- avgDist=malloc(sizeof(unsigned long)*nQuantPixels*nQuantPixels);
+ avgDist=malloc(sizeof(uint32_t)*nQuantPixels*nQuantPixels);
if (!avgDist) { goto error_2; }
- avgDistSortKey=malloc(sizeof(unsigned long *)*nQuantPixels*nQuantPixels);
+ avgDistSortKey=malloc(sizeof(uint32_t *)*nQuantPixels*nQuantPixels);
if (!avgDistSortKey) { goto error_3; }
if (!build_distance_tables(avgDist,avgDistSortKey,p,nQuantPixels)) {
@@ -1482,9 +1465,9 @@ ImagingQuantize(Imaging im, int colors, int mode, int kmeans)
UINT8* pp;
Pixel* p;
Pixel* palette;
- unsigned long paletteLength;
+ uint32_t paletteLength;
int result;
- unsigned long* newData;
+ uint32_t* newData;
Imaging imOut;
int withAlpha = 0;
ImagingSectionCookie cookie;
diff --git a/libImaging/Quant.h b/libImaging/Quant.h
deleted file mode 100644
index 0de485a..0000000
--- a/libImaging/Quant.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * The Python Imaging Library
- * $Id$
- *
- * image quantizer
- *
- * Written by Toby J Sargeant <tjs@longford.cs.monash.edu.au>.
- *
- * See the README file for information on usage and redistribution.
- */
-
-#ifndef __QUANT_H__
-#define __QUANT_H__
-
-typedef union {
- struct {
- unsigned char r,g,b,a;
- } c;
- struct {
- unsigned char v[4];
- } a;
- unsigned long v;
-} Pixel;
-
-int quantize(Pixel *,
- unsigned long,
- unsigned long,
- Pixel **,
- unsigned long *,
- unsigned long **,
- int);
-
-int quantize2(Pixel *,
- unsigned long,
- unsigned long,
- Pixel **,
- unsigned long *,
- unsigned long **,
- int);
-#endif
diff --git a/libImaging/QuantDefines.h b/libImaging/QuantDefines.h
deleted file mode 100644
index 5b08010..0000000
--- a/libImaging/QuantDefines.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * The Python Imaging Library
- * $Id$
- *
- * image quantizer
- *
- * Written by Toby J Sargeant <tjs@longford.cs.monash.edu.au>.
- *
- * See the README file for information on usage and redistribution.
- */
-
-#ifndef __DEFINES_H__
-#define __DEFINES_H__
-
-#if 0
-
-void *newMalloc(size_t,const char *,const char *,int);
-void newFree(void *,const char *,const char *,int);
-void print_malloc_stats();
-#define malloc(x) newMalloc(x,__FILE__,__FUNCTION__,__LINE__)
-#define free(x) newFree(x,__FILE__,__FUNCTION__,__LINE__)
-
-#endif
-
-#endif
diff --git a/libImaging/QuantHash.c b/libImaging/QuantHash.c
index e643840..58d8813 100644
--- a/libImaging/QuantHash.c
+++ b/libImaging/QuantHash.c
@@ -22,35 +22,35 @@
#include <math.h>
#include "QuantHash.h"
-#include "QuantDefines.h"
-typedef struct _IntHashNode {
- struct _IntHashNode *next;
- void *key,*value;
-} IntHashNode;
+typedef struct _HashNode {
+ struct _HashNode *next;
+ HashKey_t key;
+ HashVal_t value;
+} HashNode;
-typedef struct _IntHashTable {
- IntHashNode **table;
- unsigned long length;
- unsigned long count;
+typedef struct _HashTable {
+ HashNode **table;
+ uint32_t length;
+ uint32_t count;
HashFunc hashFunc;
HashCmpFunc cmpFunc;
- DestroyFunc keyDestroyFunc;
- DestroyFunc valDestroyFunc;
+ KeyDestroyFunc keyDestroyFunc;
+ ValDestroyFunc valDestroyFunc;
void *userData;
-} IntHashTable;
+} HashTable;
#define MIN_LENGTH 11
#define RESIZE_FACTOR 3
-static int _hashtable_insert_node(IntHashTable *,IntHashNode *,int,int,CollisionFunc);
+static int _hashtable_insert_node(HashTable *,HashNode *,int,int,CollisionFunc);
#if 0
-static int _hashtable_test(IntHashTable *);
+static int _hashtable_test(HashTable *);
#endif
-HashTable hashtable_new(HashFunc hf,HashCmpFunc cf) {
- IntHashTable *h;
- h=malloc(sizeof(IntHashTable));
+HashTable *hashtable_new(HashFunc hf,HashCmpFunc cf) {
+ HashTable *h;
+ h=malloc(sizeof(HashTable));
if (!h) { return NULL; }
h->hashFunc=hf;
h->cmpFunc=cf;
@@ -59,25 +59,24 @@ HashTable hashtable_new(HashFunc hf,HashCmpFunc cf) {
h->length=MIN_LENGTH;
h->count=0;
h->userData=NULL;
- h->table=malloc(sizeof(IntHashNode *)*h->length);
+ h->table=malloc(sizeof(HashNode *)*h->length);
if (!h->table) { free(h); return NULL; }
- memset (h->table,0,sizeof(IntHashNode *)*h->length);
- return (HashTable)h;
+ memset (h->table,0,sizeof(HashNode *)*h->length);
+ return h;
}
-static void _hashtable_destroy(HashTable H,const void *key,const void *val,void *u) {
- IntHashTable *h=(IntHashTable *)H;
- if (h->keyDestroyFunc&&key) {
- h->keyDestroyFunc((HashTable)h,(void *)key);
+static void _hashtable_destroy(const HashTable *h,const HashKey_t key,const HashVal_t val,void *u) {
+ if (h->keyDestroyFunc) {
+ h->keyDestroyFunc(h,key);
}
- if (h->valDestroyFunc&&val) {
- h->valDestroyFunc((HashTable)h,(void *)val);
+ if (h->valDestroyFunc) {
+ h->valDestroyFunc(h,val);
}
}
-static unsigned long _findPrime(unsigned long start,int dir) {
+static uint32_t _findPrime(uint32_t start,int dir) {
static int unit[]={0,1,0,1,0,0,0,1,0,1,0,1,0,1,0,0};
- unsigned long t;
+ uint32_t t;
while (start>1) {
if (!unit[start&0x0f]) {
start+=dir;
@@ -94,22 +93,20 @@ static unsigned long _findPrime(unsigned long start,int dir) {
return start;
}
-static void _hashtable_rehash(IntHashTable *h,
- CollisionFunc cf,
- unsigned long newSize) {
- IntHashNode **oldTable=h->table;
- unsigned long i;
- IntHashNode *n,*nn;
- unsigned long oldSize;
+static void _hashtable_rehash(HashTable *h,CollisionFunc cf,uint32_t newSize) {
+ HashNode **oldTable=h->table;
+ uint32_t i;
+ HashNode *n,*nn;
+ uint32_t oldSize;
oldSize=h->length;
- h->table=malloc(sizeof(IntHashNode *)*newSize);
+ h->table=malloc(sizeof(HashNode *)*newSize);
if (!h->table) {
h->table=oldTable;
return;
}
h->length=newSize;
h->count=0;
- memset (h->table,0,sizeof(IntHashNode *)*h->length);
+ memset (h->table,0,sizeof(HashNode *)*h->length);
for (i=0;i<oldSize;i++) {
for (n=oldTable[i];n;n=nn) {
nn=n->next;
@@ -119,9 +116,9 @@ static void _hashtable_rehash(IntHashTable *h,
free(oldTable);
}
-static void _hashtable_resize(IntHashTable *h) {
- unsigned long newSize;
- unsigned long oldSize;
+static void _hashtable_resize(HashTable *h) {
+ uint32_t newSize;
+ uint32_t oldSize;
oldSize=h->length;
newSize=oldSize;
if (h->count*RESIZE_FACTOR<h->length) {
@@ -136,13 +133,13 @@ static void _hashtable_resize(IntHashTable *h) {
}
#if 0
-static int _hashtable_test(IntHashTable *h) {
- unsigned long i;
+static int _hashtable_test(HashTable *h) {
+ uint32_t i;
int j;
- IntHashNode *n;
+ HashNode *n;
for (i=0;i<h->length;i++) {
for (n=h->table[i];n&&n->next;n=n->next) {
- j=h->cmpFunc((HashTable)h,n->key,n->next->key);
+ j=h->cmpFunc(h,n->key,n->next->key);
printf ("%c",j?(j<0?'-':'+'):'=');
}
printf ("\n");
@@ -151,26 +148,26 @@ static int _hashtable_test(IntHashTable *h) {
}
#endif
-static int _hashtable_insert_node(IntHashTable *h,IntHashNode *node,int resize,int update,CollisionFunc cf) {
- unsigned long hash=h->hashFunc((HashTable)h,node->key)%h->length;
- IntHashNode **n,*nv;
+static int _hashtable_insert_node(HashTable *h,HashNode *node,int resize,int update,CollisionFunc cf) {
+ uint32_t hash=h->hashFunc(h,node->key)%h->length;
+ HashNode **n,*nv;
int i;
for (n=&(h->table[hash]);*n;n=&((*n)->next)) {
nv=*n;
- i=h->cmpFunc((HashTable)h,nv->key,node->key);
+ i=h->cmpFunc(h,nv->key,node->key);
if (!i) {
if (cf) {
nv->key=node->key;
- cf((HashTable)h,&(nv->key),&(nv->value),node->key,node->value);
+ cf(h,&(nv->key),&(nv->value),node->key,node->value);
free(node);
return 1;
} else {
if (h->valDestroyFunc) {
- h->valDestroyFunc((HashTable)h,nv->value);
+ h->valDestroyFunc(h,nv->value);
}
if (h->keyDestroyFunc) {
- h->keyDestroyFunc((HashTable)h,nv->key);
+ h->keyDestroyFunc(h,nv->key);
}
nv->key=node->key;
nv->value=node->value;
@@ -192,17 +189,17 @@ static int _hashtable_insert_node(IntHashTable *h,IntHashNode *node,int resize,i
}
}
-static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int update) {
- IntHashNode **n,*nv;
- IntHashNode *t;
+static int _hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val,int resize,int update) {
+ HashNode **n,*nv;
+ HashNode *t;
int i;
- unsigned long hash=h->hashFunc((HashTable)h,key)%h->length;
+ uint32_t hash=h->hashFunc(h,key)%h->length;
for (n=&(h->table[hash]);*n;n=&((*n)->next)) {
nv=*n;
- i=h->cmpFunc((HashTable)h,nv->key,key);
+ i=h->cmpFunc(h,nv->key,key);
if (!i) {
- if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,nv->value); }
+ if (h->valDestroyFunc) { h->valDestroyFunc(h,nv->value); }
nv->value=val;
return 1;
} else if (i>0) {
@@ -210,7 +207,7 @@ static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int
}
}
if (!update) {
- t=malloc(sizeof(IntHashNode));
+ t=malloc(sizeof(HashNode));
if (!t) return 0;
t->next=*n;
*n=t;
@@ -224,15 +221,15 @@ static int _hashtable_insert(IntHashTable *h,void *key,void *val,int resize,int
}
}
-static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,void *newVal,int resize) {
- IntHashNode **n,*nv;
- IntHashNode *t;
+static int _hashtable_lookup_or_insert(HashTable *h,HashKey_t key,HashVal_t *retVal,HashVal_t newVal,int resize) {
+ HashNode **n,*nv;
+ HashNode *t;
int i;
- unsigned long hash=h->hashFunc((HashTable)h,key)%h->length;
+ uint32_t hash=h->hashFunc(h,key)%h->length;
for (n=&(h->table[hash]);*n;n=&((*n)->next)) {
nv=*n;
- i=h->cmpFunc((HashTable)h,nv->key,key);
+ i=h->cmpFunc(h,nv->key,key);
if (!i) {
*retVal=nv->value;
return 1;
@@ -240,7 +237,7 @@ static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,v
break;
}
}
- t=malloc(sizeof(IntHashNode));
+ t=malloc(sizeof(HashNode));
if (!t) return 0;
t->next=*n;
*n=t;
@@ -252,26 +249,25 @@ static int _hashtable_lookup_or_insert(IntHashTable *h,void *key,void **retVal,v
return 1;
}
-int hashtable_insert_or_update_computed(HashTable H,
- void *key,
+int hashtable_insert_or_update_computed(HashTable *h,
+ HashKey_t key,
ComputeFunc newFunc,
ComputeFunc existsFunc) {
- IntHashTable *h=(IntHashTable *)H;
- IntHashNode **n,*nv;
- IntHashNode *t;
+ HashNode **n,*nv;
+ HashNode *t;
int i;
- unsigned long hash=h->hashFunc((HashTable)h,key)%h->length;
+ uint32_t hash=h->hashFunc(h,key)%h->length;
for (n=&(h->table[hash]);*n;n=&((*n)->next)) {
nv=*n;
- i=h->cmpFunc((HashTable)h,nv->key,key);
+ i=h->cmpFunc(h,nv->key,key);
if (!i) {
- void *old=nv->value;
+ HashVal_t old=nv->value;
if (existsFunc) {
- existsFunc(H,nv->key,&(nv->value));
+ existsFunc(h,nv->key,&(nv->value));
if (nv->value!=old) {
if (h->valDestroyFunc) {
- h->valDestroyFunc((HashTable)h,old);
+ h->valDestroyFunc(h,old);
}
}
} else {
@@ -282,13 +278,13 @@ int hashtable_insert_or_update_computed(HashTable H,
break;
}
}
- t=malloc(sizeof(IntHashNode));
+ t=malloc(sizeof(HashNode));
if (!t) return 0;
t->key=key;
t->next=*n;
*n=t;
if (newFunc) {
- newFunc(H,t->key,&(t->value));
+ newFunc(h,t->key,&(t->value));
} else {
free(t);
return 0;
@@ -298,52 +294,47 @@ int hashtable_insert_or_update_computed(HashTable H,
return 1;
}
-int hashtable_update(HashTable H,void *key,void *val) {
- IntHashTable *h=(IntHashTable *)H;
+int hashtable_update(HashTable *h,HashKey_t key,HashVal_t val) {
return _hashtable_insert(h,key,val,1,0);
}
-int hashtable_insert(HashTable H,void *key,void *val) {
- IntHashTable *h=(IntHashTable *)H;
+int hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val) {
return _hashtable_insert(h,key,val,1,0);
}
-void hashtable_foreach_update(HashTable H,IteratorUpdateFunc i,void *u) {
- IntHashTable *h=(IntHashTable *)H;
- IntHashNode *n;
- unsigned long x;
+void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u) {
+ HashNode *n;
+ uint32_t x;
if (h->table) {
for (x=0;x<h->length;x++) {
for (n=h->table[x];n;n=n->next) {
- i((HashTable)h,n->key,(void **)&(n->value),u);
+ i(h,n->key,&(n->value),u);
}
}
}
}
-void hashtable_foreach(HashTable H,IteratorFunc i,void *u) {
- IntHashTable *h=(IntHashTable *)H;
- IntHashNode *n;
- unsigned long x;
+void hashtable_foreach(HashTable *h,IteratorFunc i,void *u) {
+ HashNode *n;
+ uint32_t x;
if (h->table) {
for (x=0;x<h->length;x++) {
for (n=h->table[x];n;n=n->next) {
- i((HashTable)h,n->key,n->value,u);
+ i(h,n->key,n->value,u);
}
}
}
}
-void hashtable_free(HashTable H) {
- IntHashTable *h=(IntHashTable *)H;
- IntHashNode *n,*nn;
- unsigned long i;
+void hashtable_free(HashTable *h) {
+ HashNode *n,*nn;
+ uint32_t i;
if (h->table) {
if (h->keyDestroyFunc || h->keyDestroyFunc) {
- hashtable_foreach(H,_hashtable_destroy,NULL);
+ hashtable_foreach(h,_hashtable_destroy,NULL);
}
for (i=0;i<h->length;i++) {
for (n=h->table[i];n;n=nn) {
@@ -356,31 +347,29 @@ void hashtable_free(HashTable H) {
free(h);
}
-DestroyFunc hashtable_set_value_destroy_func(HashTable H,DestroyFunc d) {
- IntHashTable *h=(IntHashTable *)H;
- DestroyFunc r=h->valDestroyFunc;
+ValDestroyFunc hashtable_set_value_destroy_func(HashTable *h,ValDestroyFunc d) {
+ ValDestroyFunc r=h->valDestroyFunc;
h->valDestroyFunc=d;
return r;
}
-DestroyFunc hashtable_set_key_destroy_func(HashTable H,DestroyFunc d) {
- IntHashTable *h=(IntHashTable *)H;
- DestroyFunc r=h->keyDestroyFunc;
+KeyDestroyFunc hashtable_set_key_destroy_func(HashTable *h,KeyDestroyFunc d) {
+ KeyDestroyFunc r=h->keyDestroyFunc;
h->keyDestroyFunc=d;
return r;
}
-static int _hashtable_remove(IntHashTable *h,
- const void *key,
- void **keyRet,
- void **valRet,
+static int _hashtable_remove(HashTable *h,
+ const HashKey_t key,
+ HashKey_t *keyRet,
+ HashVal_t *valRet,
int resize) {
- unsigned long hash=h->hashFunc((HashTable)h,key)%h->length;
- IntHashNode *n,*p;
+ uint32_t hash=h->hashFunc(h,key)%h->length;
+ HashNode *n,*p;
int i;
for (p=NULL,n=h->table[hash];n;p=n,n=n->next) {
- i=h->cmpFunc((HashTable)h,n->key,key);
+ i=h->cmpFunc(h,n->key,key);
if (!i) {
if (p) p=n->next; else h->table[hash]=n->next;
*keyRet=n->key;
@@ -395,17 +384,17 @@ static int _hashtable_remove(IntHashTable *h,
return 0;
}
-static int _hashtable_delete(IntHashTable *h,const void *key,int resize) {
- unsigned long hash=h->hashFunc((HashTable)h,key)%h->length;
- IntHashNode *n,*p;
+static int _hashtable_delete(HashTable *h,const HashKey_t key,int resize) {
+ uint32_t hash=h->hashFunc(h,key)%h->length;
+ HashNode *n,*p;
int i;
for (p=NULL,n=h->table[hash];n;p=n,n=n->next) {
- i=h->cmpFunc((HashTable)h,n->key,key);
+ i=h->cmpFunc(h,n->key,key);
if (!i) {
if (p) p=n->next; else h->table[hash]=n->next;
- if (h->valDestroyFunc) { h->valDestroyFunc((HashTable)h,n->value); }
- if (h->keyDestroyFunc) { h->keyDestroyFunc((HashTable)h,n->key); }
+ if (h->valDestroyFunc) { h->valDestroyFunc(h,n->value); }
+ if (h->keyDestroyFunc) { h->keyDestroyFunc(h,n->key); }
free(n);
h->count++;
return 1;
@@ -416,39 +405,33 @@ static int _hashtable_delete(IntHashTable *h,const void *key,int resize) {
return 0;
}
-int hashtable_remove(HashTable H,const void *key,void **keyRet,void **valRet) {
- IntHashTable *h=(IntHashTable *)H;
+int hashtable_remove(HashTable *h,const HashKey_t key,HashKey_t *keyRet,HashVal_t *valRet) {
return _hashtable_remove(h,key,keyRet,valRet,1);
}
-int hashtable_delete(HashTable H,const void *key) {
- IntHashTable *h=(IntHashTable *)H;
+int hashtable_delete(HashTable *h,const HashKey_t key) {
return _hashtable_delete(h,key,1);
}
-void hashtable_rehash_compute(HashTable H,CollisionFunc cf) {
- IntHashTable *h=(IntHashTable *)H;
+void hashtable_rehash_compute(HashTable *h,CollisionFunc cf) {
_hashtable_rehash(h,cf,h->length);
}
-void hashtable_rehash(HashTable H) {
- IntHashTable *h=(IntHashTable *)H;
+void hashtable_rehash(HashTable *h) {
_hashtable_rehash(h,NULL,h->length);
}
-int hashtable_lookup_or_insert(HashTable H,void *key,void **valp,void *val) {
- IntHashTable *h=(IntHashTable *)H;
+int hashtable_lookup_or_insert(HashTable *h,HashKey_t key,HashVal_t *valp,HashVal_t val) {
return _hashtable_lookup_or_insert(h,key,valp,val,1);
}
-int hashtable_lookup(const HashTable H,const void *key,void **valp) {
- IntHashTable *h=(IntHashTable *)H;
- unsigned long hash=h->hashFunc((HashTable)h,key)%h->length;
- IntHashNode *n;
+int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp) {
+ uint32_t hash=h->hashFunc(h,key)%h->length;
+ HashNode *n;
int i;
for (n=h->table[hash];n;n=n->next) {
- i=h->cmpFunc((HashTable)h,n->key,key);
+ i=h->cmpFunc(h,n->key,key);
if (!i) {
*valp=n->value;
return 1;
@@ -459,18 +442,15 @@ int hashtable_lookup(const HashTable H,const void *key,void **valp) {
return 0;
}
-unsigned long hashtable_get_count(const HashTable H) {
- IntHashTable *h=(IntHashTable *)H;
+uint32_t hashtable_get_count(const HashTable *h) {
return h->count;
}
-void *hashtable_get_user_data(const HashTable H) {
- IntHashTable *h=(IntHashTable *)H;
+void *hashtable_get_user_data(const HashTable *h) {
return h->userData;
}
-void *hashtable_set_user_data(HashTable H,void *data) {
- IntHashTable *h=(IntHashTable *)H;
+void *hashtable_set_user_data(HashTable *h,void *data) {
void *r=h->userData;
h->userData=data;
return r;
diff --git a/libImaging/QuantHash.h b/libImaging/QuantHash.h
index b98b56e..028b4af 100644
--- a/libImaging/QuantHash.h
+++ b/libImaging/QuantHash.h
@@ -9,28 +9,41 @@
* See the README file for information on usage and redistribution.
*/
-#ifndef __HASH_H__
-#define __HASH_H__
+#ifndef __QUANTHASH_H__
+#define __QUANTHASH_H__
#include "QuantTypes.h"
-HashTable hashtable_new(HashFunc,HashCmpFunc);
-void hashtable_free(HashTable);
-void hashtable_foreach(HashTable,IteratorFunc,void *);
-void hashtable_foreach_update(HashTable,IteratorUpdateFunc,void *);
-int hashtable_insert(HashTable,void *,void *);
-int hashtable_update(HashTable,void *,void *);
-int hashtable_lookup(const HashTable,const void *,void **);
-int hashtable_lookup_or_insert(HashTable,void *,void **,void *);
-int hashtable_insert_or_update_computed(HashTable,void *,ComputeFunc,ComputeFunc);
-int hashtable_delete(HashTable,const void *);
-int hashtable_remove(HashTable,const void *,void **,void **);
-void *hashtable_set_user_data(HashTable,void *);
-void *hashtable_get_user_data(const HashTable);
-DestroyFunc hashtable_set_key_destroy_func(HashTable,DestroyFunc);
-DestroyFunc hashtable_set_value_destroy_func(HashTable,DestroyFunc);
-unsigned long hashtable_get_count(const HashTable);
-void hashtable_rehash(HashTable);
-void hashtable_rehash_compute(HashTable,CollisionFunc);
+typedef struct _HashTable HashTable;
+typedef Pixel HashKey_t;
+typedef uint32_t HashVal_t;
-#endif
+typedef uint32_t (*HashFunc)(const HashTable *,const HashKey_t);
+typedef int (*HashCmpFunc)(const HashTable *,const HashKey_t,const HashKey_t);
+typedef void (*IteratorFunc)(const HashTable *,const HashKey_t,const HashVal_t,void *);
+typedef void (*IteratorUpdateFunc)(const HashTable *,const HashKey_t,HashVal_t *,void *);
+typedef void (*KeyDestroyFunc)(const HashTable *,HashKey_t);
+typedef void (*ValDestroyFunc)(const HashTable *,HashVal_t);
+typedef void (*ComputeFunc)(const HashTable *,const HashKey_t,HashVal_t *);
+typedef void (*CollisionFunc)(const HashTable *,HashKey_t *,HashVal_t *,HashKey_t,HashVal_t);
+
+HashTable * hashtable_new(HashFunc hf,HashCmpFunc cf);
+void hashtable_free(HashTable *h);
+void hashtable_foreach(HashTable *h,IteratorFunc i,void *u);
+void hashtable_foreach_update(HashTable *h,IteratorUpdateFunc i,void *u);
+int hashtable_insert(HashTable *h,HashKey_t key,HashVal_t val);
+int hashtable_update(HashTable *h,HashKey_t key,HashVal_t val);
+int hashtable_lookup(const HashTable *h,const HashKey_t key,HashVal_t *valp);
+int hashtable_lookup_or_insert(HashTable *h,HashKey_t key,HashVal_t *valp,HashVal_t val);
+int hashtable_insert_or_update_computed(HashTable *h,HashKey_t key,ComputeFunc newFunc,ComputeFunc existsFunc);
+int hashtable_delete(HashTable *h,const HashKey_t key);
+int hashtable_remove(HashTable *h,const HashKey_t key,HashKey_t *keyRet,HashVal_t *valRet);
+void *hashtable_set_user_data(HashTable *h,void *data);
+void *hashtable_get_user_data(const HashTable *h);
+KeyDestroyFunc hashtable_set_key_destroy_func(HashTable *,KeyDestroyFunc d);
+ValDestroyFunc hashtable_set_value_destroy_func(HashTable *,ValDestroyFunc d);
+uint32_t hashtable_get_count(const HashTable *h);
+void hashtable_rehash(HashTable *h);
+void hashtable_rehash_compute(HashTable *h,CollisionFunc cf);
+
+#endif // __QUANTHASH_H__
diff --git a/libImaging/QuantHeap.c b/libImaging/QuantHeap.c
index 9332a5c..bddcf14 100644
--- a/libImaging/QuantHeap.c
+++ b/libImaging/QuantHeap.c
@@ -21,31 +21,29 @@
#include <string.h>
#include <math.h>
-#include "QuantHash.h"
-#include "QuantDefines.h"
+#include "QuantHeap.h"
-typedef struct {
+typedef struct _Heap {
void **heap;
int heapsize;
int heapcount;
HeapCmpFunc cf;
-} IntHeap;
+} Heap;
#define INITIAL_SIZE 256
-#define DEBUG
+// #define DEBUG
#ifdef DEBUG
-static int _heap_test(Heap);
+static int _heap_test(Heap *);
#endif
-void ImagingQuantHeapFree(Heap H) {
- IntHeap *h=(IntHeap *)H;
+void ImagingQuantHeapFree(Heap *h) {
free(h->heap);
free(h);
}
-static int _heap_grow(IntHeap *h,int newsize) {
+static int _heap_grow(Heap *h,int newsize) {
void *newheap;
if (!newsize) newsize=h->heapsize<<1;
if (newsize<h->heapsize) return 0;
@@ -59,15 +57,14 @@ static int _heap_grow(IntHeap *h,int newsize) {
}
#ifdef DEBUG
-static int _heap_test(Heap H) {
- IntHeap *h=(IntHeap *)H;
+static int _heap_test(Heap *h) {
int k;
for (k=1;k*2<=h->heapcount;k++) {
- if (h->cf(H,h->heap[k],h->heap[k*2])<0) {
+ if (h->cf(h,h->heap[k],h->heap[k*2])<0) {
printf ("heap is bad\n");
return 0;
}
- if (k*2+1<=h->heapcount && h->cf(H,h->heap[k],h->heap[k*2+1])<0) {
+ if (k*2+1<=h->heapcount && h->cf(h,h->heap[k],h->heap[k*2+1])<0) {
printf ("heap is bad\n");
return 0;
}
@@ -76,8 +73,7 @@ static int _heap_test(Heap H) {
}
#endif
-int ImagingQuantHeapRemove(Heap H,void **r) {
- IntHeap *h=(IntHeap *)H;
+int ImagingQuantHeapRemove(Heap* h,void **r) {
int k,l;
void *v;
@@ -89,31 +85,30 @@ int ImagingQuantHeapRemove(Heap H,void **r) {
for (k=1;k*2<=h->heapcount;k=l) {
l=k*2;
if (l<h->heapcount) {
- if (h->cf(H,h->heap[l],h->heap[l+1])<0) {
+ if (h->cf(h,h->heap[l],h->heap[l+1])<0) {
l++;
}
}
- if (h->cf(H,v,h->heap[l])>0) {
+ if (h->cf(h,v,h->heap[l])>0) {
break;
}
h->heap[k]=h->heap[l];
}
h->heap[k]=v;
#ifdef DEBUG
- if (!_heap_test(H)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); }
+ if (!_heap_test(h)) { printf ("oops - heap_remove messed up the heap\n"); exit(1); }
#endif
return 1;
}
-int ImagingQuantHeapAdd(Heap H,void *val) {
- IntHeap *h=(IntHeap *)H;
+int ImagingQuantHeapAdd(Heap *h,void *val) {
int k;
if (h->heapcount==h->heapsize-1) {
_heap_grow(h,0);
}
k=++h->heapcount;
while (k!=1) {
- if (h->cf(H,val,h->heap[k/2])<=0) {
+ if (h->cf(h,val,h->heap[k/2])<=0) {
break;
}
h->heap[k]=h->heap[k/2];
@@ -121,13 +116,12 @@ int ImagingQuantHeapAdd(Heap H,void *val) {
}
h->heap[k]=val;
#ifdef DEBUG
- if (!_heap_test(H)) { printf ("oops - heap_add messed up the heap\n"); exit(1); }
+ if (!_heap_test(h)) { printf ("oops - heap_add messed up the heap\n"); exit(1); }
#endif
return 1;
}
-int ImagingQuantHeapTop(Heap H,void **r) {
- IntHeap *h=(IntHeap *)H;
+int ImagingQuantHeapTop(Heap *h,void **r) {
if (!h->heapcount) {
return 0;
}
@@ -136,15 +130,14 @@ int ImagingQuantHeapTop(Heap H,void **r) {
}
Heap *ImagingQuantHeapNew(HeapCmpFunc cf) {
- IntHeap *h;
+ Heap *h;
- h=malloc(sizeof(IntHeap));
+ h=malloc(sizeof(Heap));
if (!h) return NULL;
h->heapsize=INITIAL_SIZE;
h->heap=malloc(sizeof(void *)*h->heapsize);
if (!h->heap) { free(h); return NULL; }
h->heapcount=0;
h->cf=cf;
- return (Heap)h;
+ return h;
}
-
diff --git a/libImaging/QuantHeap.h b/libImaging/QuantHeap.h
index 5a213c4..77bf0d9 100644
--- a/libImaging/QuantHeap.h
+++ b/libImaging/QuantHeap.h
@@ -9,15 +9,19 @@
* See the README file for information on usage and redistribution.
*/
-#ifndef __HEAP_H__
-#define __HEAP_H__
+#ifndef __QUANTHEAP_H__
+#define __QUANTHEAP_H__
#include "QuantTypes.h"
-void ImagingQuantHeapFree(Heap);
-int ImagingQuantHeapRemove(Heap,void **);
-int ImagingQuantHeapAdd(Heap,void *);
-int ImagingQuantHeapTop(Heap,void **);
+typedef struct _Heap Heap;
+
+typedef int (*HeapCmpFunc)(const Heap *,const void *,const void *);
+
+void ImagingQuantHeapFree(Heap *);
+int ImagingQuantHeapRemove(Heap *,void **);
+int ImagingQuantHeapAdd(Heap *,void *);
+int ImagingQuantHeapTop(Heap *,void **);
Heap *ImagingQuantHeapNew(HeapCmpFunc);
-#endif
+#endif // __QUANTHEAP_H__
diff --git a/libImaging/QuantOctree.c b/libImaging/QuantOctree.c
index fcdf9e0..e841d6f 100644
--- a/libImaging/QuantOctree.c
+++ b/libImaging/QuantOctree.c
@@ -27,15 +27,15 @@
#include <stdlib.h>
#include <string.h>
-#include "Quant.h"
+#include "QuantOctree.h"
typedef struct _ColorBucket{
/* contains palette index when used for look up cube */
- unsigned long count;
- unsigned long r;
- unsigned long g;
- unsigned long b;
- unsigned long a;
+ uint32_t count;
+ uint32_t r;
+ uint32_t g;
+ uint32_t b;
+ uint32_t a;
} *ColorBucket;
typedef struct _ColorCube{
@@ -262,7 +262,7 @@ set_lookup_value(const ColorCube cube, const Pixel *p, long value) {
bucket->count = value;
}
-unsigned long
+uint32_t
lookup_color(const ColorCube cube, const Pixel *p) {
ColorBucket bucket = color_bucket_from_cube(cube, p);
return bucket->count;
@@ -302,9 +302,9 @@ create_palette_array(const ColorBucket palette, unsigned int paletteLength) {
static void
map_image_pixels(const Pixel *pixelData,
- unsigned long nPixels,
+ uint32_t nPixels,
const ColorCube lookupCube,
- unsigned long *pixelArray)
+ uint32_t *pixelArray)
{
long i;
for (i=0; i<nPixels; i++) {
@@ -316,11 +316,11 @@ const int CUBE_LEVELS[8] = {4, 4, 4, 0, 2, 2, 2, 0};
const int CUBE_LEVELS_ALPHA[8] = {3, 4, 3, 3, 2, 2, 2, 2};
int quantize_octree(Pixel *pixelData,
- unsigned long nPixels,
- unsigned long nQuantPixels,
+ uint32_t nPixels,
+ uint32_t nQuantPixels,
Pixel **palette,
- unsigned long *paletteLength,
- unsigned long **quantizedPixels,
+ uint32_t *paletteLength,
+ uint32_t **quantizedPixels,
int withAlpha)
{
ColorCube fineCube = NULL;
@@ -330,7 +330,7 @@ int quantize_octree(Pixel *pixelData,
ColorBucket paletteBucketsCoarse = NULL;
ColorBucket paletteBucketsFine = NULL;
ColorBucket paletteBuckets = NULL;
- unsigned long *qp = NULL;
+ uint32_t *qp = NULL;
long i;
long nCoarseColors, nFineColors, nAlreadySubtracted;
const int *cubeBits;
diff --git a/libImaging/QuantOctree.h b/libImaging/QuantOctree.h
index fd7b7db..968644e 100644
--- a/libImaging/QuantOctree.h
+++ b/libImaging/QuantOctree.h
@@ -1,12 +1,14 @@
#ifndef __QUANT_OCTREE_H__
#define __QUANT_OCTREE_H__
+#include "QuantTypes.h"
+
int quantize_octree(Pixel *,
- unsigned long,
- unsigned long,
+ uint32_t,
+ uint32_t,
Pixel **,
- unsigned long *,
- unsigned long **,
+ uint32_t *,
+ uint32_t **,
int);
-#endif
\ No newline at end of file
+#endif
diff --git a/libImaging/QuantTypes.h b/libImaging/QuantTypes.h
index 308b51c..8f113b0 100644
--- a/libImaging/QuantTypes.h
+++ b/libImaging/QuantTypes.h
@@ -12,17 +12,20 @@
#ifndef __TYPES_H__
#define __TYPES_H__
-typedef void *HashTable;
-typedef void *Heap;
-
-typedef unsigned long (*HashFunc)(const HashTable,const void *);
-typedef int (*HashCmpFunc)(const HashTable,const void *,const void *);
-typedef void (*IteratorFunc)(const HashTable,const void *,const void *,void *);
-typedef void (*IteratorUpdateFunc)(const HashTable,const void *,void **,void *);
-typedef void (*DestroyFunc)(const HashTable,void *);
-typedef void (*ComputeFunc)(const HashTable,const void *,void **);
-typedef void (*CollisionFunc)(const HashTable,void **,void **,void *,void *);
+#ifdef _MSC_VER
+typedef unsigned __int32 uint32_t;
+#else
+#include <stdint.h>
+#endif
-typedef int (*HeapCmpFunc)(const Heap,const void *,const void *);
+typedef union {
+ struct {
+ unsigned char r,g,b,a;
+ } c;
+ struct {
+ unsigned char v[4];
+ } a;
+ uint32_t v;
+} Pixel;
#endif