コード例 #1
0
void unit_tests() {
  int a[4] = {1, 2, 3, 4};
  insertion_sort(a, 4);
  test_sorted(a, 4);

  int b[4] = {10, 20, 40, 30};
  insertion_sort(b, 4);
  test_sorted(b, 4);

  int c[4] = {10, 4000, 20, 300};
  insertion_sort(c, 4);
  test_sorted(c, 4);

  int d[4] = {3000, 40000, 20000, 10000};
  insertion_sort(d, 4);
  test_sorted(d, 4);
}
コード例 #2
0
ファイル: Quant.c プロジェクト: Nexuapex/Pillow
static int
split(BoxNode *node)
{
   unsigned char rl,rh,gl,gh,bl,bh;
   int f[3];
   int best,axis;
   int i;
   PixelList *heads[2][3];
   PixelList *tails[2][3];
   uint32_t newCounts[2];
   BoxNode *left,*right;

   rh=node->head[0]->p.c.r;
   rl=node->tail[0]->p.c.r;
   gh=node->head[1]->p.c.g;
   gl=node->tail[1]->p.c.g;
   bh=node->head[2]->p.c.b;
   bl=node->tail[2]->p.c.b;
#ifdef TEST_SPLIT
   printf ("splitting node [%d %d %d] [%d %d %d] ",rl,gl,bl,rh,gh,bh);
#endif
   f[0]=(rh-rl)*77;
   f[1]=(gh-gl)*150;
   f[2]=(bh-bl)*29;

   best=f[0];
   axis=0;
   for (i=1;i<3;i++) {
      if (best<f[i]) { best=f[i]; axis=i; }
   }
#ifdef TEST_SPLIT
   printf ("along axis %d\n",axis+1);
#endif

#ifdef TEST_SPLIT
   {
      PixelList *_prevTest,*_nextTest;
      int _i,_nextCount[3],_prevCount[3];
      for (_i=0;_i<3;_i++) {
         if (node->tail[_i]->next[_i]) {
            printf ("tail is not tail\n");
            printf ("node->tail[%d]->next[%d]=%p\n",_i,_i,node->tail[_i]->next[_i]);
         }
         if (node->head[_i]->prev[_i]) {
            printf ("head is not head\n");
            printf ("node->head[%d]->prev[%d]=%p\n",_i,_i,node->head[_i]->prev[_i]);
         }
      }

      for (_i=0;_i<3;_i++) {
         for (_nextCount[_i]=0,_nextTest=node->head[_i];_nextTest&&_nextTest->next[_i];_nextTest=_nextTest->next[_i],_nextCount[_i]++);
         for (_prevCount[_i]=0,_prevTest=node->tail[_i];_prevTest&&_prevTest->prev[_i];_prevTest=_prevTest->prev[_i],_prevCount[_i]++);
         if (_nextTest!=node->tail[_i]) {
            printf ("next-list of axis %d does not end at tail\n",_i);
         }
         if (_prevTest!=node->head[_i]) {
            printf ("prev-list of axis %d does not end at head\n",_i);
         }
         for (;_nextTest&&_nextTest->prev[_i];_nextTest=_nextTest->prev[_i]);
         for (;_prevTest&&_prevTest->next[_i];_prevTest=_prevTest->next[_i]);
         if (_nextTest!=node->head[_i]) {
            printf ("next-list of axis %d does not loop back to head\n",_i);
         }
         if (_prevTest!=node->tail[_i]) {
            printf ("prev-list of axis %d does not loop back to tail\n",_i);
         }
      }
      for (_i=1;_i<3;_i++) {
         if (_prevCount[_i]!=_prevCount[_i-1] ||
             _nextCount[_i]!=_nextCount[_i-1] ||
             _prevCount[_i]!=_nextCount[_i]) {
            printf ("{%d %d %d} {%d %d %d}\n",
                    _prevCount[0],
                    _prevCount[1],
                    _prevCount[2],
                    _nextCount[0],
                    _nextCount[1],
                    _nextCount[2]);
         }
      }
    }
#endif
   node->axis=axis;
   if (!splitlists(node->head,
                   node->tail,
                   heads,
                   tails,
                   newCounts,
                   axis,
                   node->pixelCount)) {
#ifndef NO_OUTPUT
      printf ("list split failed.\n");
#endif
      return 0;
   }
#ifdef TEST_SPLIT
   if (!test_sorted(heads[0])) {
      printf ("bug in split");
      exit(1);
   }
   if (!test_sorted(heads[1])) {
      printf ("bug in split");
      exit(1);
   }
#endif
   /* malloc check ok, small constant allocation */
   left=malloc(sizeof(BoxNode));
   right=malloc(sizeof(BoxNode));
   if (!left||!right) {
      return 0;
   }
   for(i=0;i<3;i++) {
      left->head[i]=heads[0][i];
      left->tail[i]=tails[0][i];
      right->head[i]=heads[1][i];
      right->tail[i]=tails[1][i];
      node->head[i]=NULL;
      node->tail[i]=NULL;
   }
#ifdef TEST_SPLIT
   if (left->head[0]) {
      rh=left->head[0]->p.c.r;
      rl=left->tail[0]->p.c.r;
      gh=left->head[1]->p.c.g;
      gl=left->tail[1]->p.c.g;
      bh=left->head[2]->p.c.b;
      bl=left->tail[2]->p.c.b;
      printf ("   left node  [%3d %3d %3d] [%3d %3d %3d]\n",rl,gl,bl,rh,gh,bh);
   }
   if (right->head[0]) {
      rh=right->head[0]->p.c.r;
      rl=right->tail[0]->p.c.r;
      gh=right->head[1]->p.c.g;
      gl=right->tail[1]->p.c.g;
      bh=right->head[2]->p.c.b;
      bl=right->tail[2]->p.c.b;
      printf ("   right node [%3d %3d %3d] [%3d %3d %3d]\n",rl,gl,bl,rh,gh,bh);
   }
#endif
   left->l=left->r=NULL;
   right->l=right->r=NULL;
   left->axis=right->axis=-1;
   left->volume=right->volume=-1;
   left->pixelCount=newCounts[0];
   right->pixelCount=newCounts[1];
   node->l=left;
   node->r=right;
   return 1;
}
コード例 #3
0
ファイル: Quant.c プロジェクト: Nexuapex/Pillow
int
quantize(Pixel *pixelData,
         uint32_t nPixels,
         uint32_t nQuantPixels,
         Pixel **palette,
         uint32_t *paletteLength,
         uint32_t **quantizedPixels,
         int kmeans)
{
   PixelList *hl[3];
   HashTable *h;
   BoxNode *root;
   uint32_t i;
   uint32_t *qp;
   uint32_t nPaletteEntries;

   uint32_t *avgDist;
   uint32_t **avgDistSortKey;
   Pixel *p;

#ifndef NO_OUTPUT
   uint32_t timer,timer2;
#endif

#ifndef NO_OUTPUT
   timer2=clock();
   printf ("create hash table..."); fflush(stdout); timer=clock();
#endif
   h=create_pixel_hash(pixelData,nPixels);
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif
   if (!h) {
      goto error_0;
   }

#ifndef NO_OUTPUT
   printf ("create lists from hash table..."); fflush(stdout); timer=clock();
#endif
   hl[0]=hl[1]=hl[2]=NULL;
   hashtable_foreach(h,hash_to_list,hl);
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif

   if (!hl[0]) {
      goto error_1;
   }

#ifndef NO_OUTPUT
   printf ("mergesort lists..."); fflush(stdout); timer=clock();
#endif
   for(i=0;i<3;i++) {
      hl[i]=mergesort_pixels(hl[i],i);
   }
#ifdef TEST_MERGESORT
   if (!test_sorted(hl)) {
      printf ("bug in mergesort\n");
      goto error_1;
   }
#endif
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif

#ifndef NO_OUTPUT
   printf ("median cut..."); fflush(stdout); timer=clock();
#endif
   root=median_cut(hl,nPixels,nQuantPixels);
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif
   if (!root) {
      goto error_1;
   }
   nPaletteEntries=0;
#ifndef NO_OUTPUT
   printf ("median cut tree to hash table..."); fflush(stdout); timer=clock();
#endif
   annotate_hash_table(root,h,&nPaletteEntries);
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif
#ifndef NO_OUTPUT
   printf ("compute palette...\n"); fflush(stdout); timer=clock();
#endif
   if (!compute_palette_from_median_cut(pixelData,nPixels,h,&p,nPaletteEntries)) {
      goto error_3;
   }
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif

   free_box_tree(root);
   root=NULL;

   /* malloc check ok, using calloc for overflow */
   qp=calloc(nPixels, sizeof(uint32_t));
   if (!qp) { goto error_4; }

   if (nPaletteEntries > UINT32_MAX / nPaletteEntries )  {
       goto error_5;
   }
   /* malloc check ok, using calloc for overflow, check of n*n above */
   avgDist=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t));
   if (!avgDist) { goto error_5; }

   /* malloc check ok, using calloc for overflow, check of n*n above */
   avgDistSortKey=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t *));
   if (!avgDistSortKey) { goto error_6; }

   if (!build_distance_tables(avgDist,avgDistSortKey,p,nPaletteEntries)) {
      goto error_7;
   }

   if (!map_image_pixels_from_median_box(pixelData,nPixels,p,nPaletteEntries,h,avgDist,avgDistSortKey,qp)) {
      goto error_7;
   }

#ifdef TEST_NEAREST_NEIGHBOUR
#include <math.h>
   {
      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,pixelData[i],&paletteEntry)) {
            bestmatch=paletteEntry;
         } else {
            bestmatch=0;
            bestdist=
               _SQR(pixelData[i].c.r-p[0].c.r)+
               _SQR(pixelData[i].c.g-p[0].c.g)+
               _SQR(pixelData[i].c.b-p[0].c.b);
            for (j=1;j<nPaletteEntries;j++) {
               dist=
                  _SQR(pixelData[i].c.r-p[j].c.r)+
                  _SQR(pixelData[i].c.g-p[j].c.g)+
                  _SQR(pixelData[i].c.b-p[j].c.b);
               if (dist==bestdist && j==qp[i]) {
                  bestmatch=j;
               }
               if (dist<bestdist) {
                  bestdist=dist;
                  bestmatch=j;
               }
            }
            hashtable_insert(h2,pixelData[i],bestmatch);
         }
         if (qp[i]!=bestmatch ) {
            printf ("discrepancy in matching algorithms pixel %d [%d %d] %f %f\n",
                    i,qp[i],bestmatch,
                    sqrt((double)(_SQR(pixelData[i].c.r-p[qp[i]].c.r)+
                                  _SQR(pixelData[i].c.g-p[qp[i]].c.g)+
                                  _SQR(pixelData[i].c.b-p[qp[i]].c.b))),
                    sqrt((double)(_SQR(pixelData[i].c.r-p[bestmatch].c.r)+
                                  _SQR(pixelData[i].c.g-p[bestmatch].c.g)+
                                  _SQR(pixelData[i].c.b-p[bestmatch].c.b)))
                   );
         }
      }
      hashtable_free(h2);
   }
#endif
#ifndef NO_OUTPUT
   printf ("k means...\n"); fflush(stdout); timer=clock();
#endif
   if (kmeans) k_means(pixelData,nPixels,p,nPaletteEntries,qp,kmeans-1);
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
#endif

   *quantizedPixels=qp;
   *palette=p;
   *paletteLength=nPaletteEntries;

#ifndef NO_OUTPUT
   printf ("cleanup..."); fflush(stdout); timer=clock();
#endif
   if (avgDist) free(avgDist);
   if (avgDistSortKey) free(avgDistSortKey);
   destroy_pixel_hash(h);
#ifndef NO_OUTPUT
   printf ("done (%f)\n",(clock()-timer)/(double)CLOCKS_PER_SEC);
   printf ("-----\ntotal time %f\n",(clock()-timer2)/(double)CLOCKS_PER_SEC);
#endif
   return 1;

error_7:
   if (avgDistSortKey) free(avgDistSortKey);
error_6:
   if (avgDist) free(avgDist);
error_5:
   if (qp) free(qp);
error_4:
   if (p) free(p);
error_3:
   if (root) free_box_tree(root);
error_1:
   destroy_pixel_hash(h);
error_0:
   *quantizedPixels=NULL;
   *paletteLength=0;
   *palette=NULL;
   return 0;
}