Beispiel #1
0
static int
k_means(Pixel *pixelData,
        uint32_t nPixels,
        Pixel *paletteData,
        uint32_t nPaletteEntries,
        uint32_t *qp,
        int threshold)
{
   uint32_t *avg[3];
   uint32_t *count;
   uint32_t i;
   uint32_t *avgDist;
   uint32_t **avgDistSortKey;
   int changes;
   int built=0;

   if (nPaletteEntries > UINT32_MAX / (sizeof(uint32_t))) {
       return 0;
   }
   /* malloc check ok, using calloc */
   if (!(count=calloc(nPaletteEntries, sizeof(uint32_t)))) {
      return 0;
   }
   for(i=0;i<3;i++) {
      avg[i]=NULL;
   }
   for(i=0;i<3;i++) {
      /* malloc check ok, using calloc */
      if (!(avg[i]=calloc(nPaletteEntries, sizeof(uint32_t)))) {
         goto error_1;
      }
   }

   /* this is enough of a check, since the multiplication n*size is done above */
   if (nPaletteEntries > UINT32_MAX / nPaletteEntries) {
       goto error_1;
   }
   /* malloc check ok, using calloc, checking n*n above */
   avgDist=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t));
   if (!avgDist) { goto error_1; }

   /* malloc check ok, using calloc, checking n*n above */
   avgDistSortKey=calloc(nPaletteEntries*nPaletteEntries, sizeof(uint32_t *));
   if (!avgDistSortKey) { goto error_2; }

#ifndef NO_OUTPUT
   printf("[");fflush(stdout);
#endif
   while (1) {
      if (!built) {
         compute_palette_from_quantized_pixels(pixelData,nPixels,paletteData,nPaletteEntries,avg,count,qp);
         build_distance_tables(avgDist,avgDistSortKey,paletteData,nPaletteEntries);
         built=1;
      } else {
         recompute_palette_from_averages(paletteData,nPaletteEntries,avg,count);
         resort_distance_tables(avgDist,avgDistSortKey,paletteData,nPaletteEntries);
      }
      changes=map_image_pixels_from_quantized_pixels(pixelData,
                                                     nPixels,
                                                     paletteData,
                                                     nPaletteEntries,
                                                     avgDist,
                                                     avgDistSortKey,
                                                     qp,
                                                     avg,
                                                     count);
      if (changes<0) {
         goto error_3;
      }
#ifndef NO_OUTPUT
      printf (".(%d)",changes);fflush(stdout);
#endif
      if (changes<=threshold) break;
   }
#ifndef NO_OUTPUT
   printf("]\n");
#endif
   if (avgDistSortKey) free(avgDistSortKey);
   if (avgDist) free(avgDist);
   for(i=0;i<3;i++) if (avg[i]) free (avg[i]);
   if (count) free(count);
   return 1;

error_3:
   if (avgDistSortKey) free(avgDistSortKey);
error_2:
   if (avgDist) free(avgDist);
error_1:
   for(i=0;i<3;i++) if (avg[i]) free (avg[i]);
   if (count) free(count);
   return 0;
}
Beispiel #2
0
static int
k_means(Pixel *pixelData,
        unsigned long nPixels,
        Pixel *paletteData,
        unsigned long nPaletteEntries,
        unsigned long *qp,
        int threshold)
{
   unsigned long *avg[3];
   unsigned long *count;
   unsigned long i;
   unsigned long *avgDist;
   unsigned long **avgDistSortKey;
   int changes;
   int built=0;
   
   if (!(count=malloc(sizeof(unsigned long)*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))) {
         goto error_1;
      }
   }
   avgDist=malloc(sizeof(unsigned long)*nPaletteEntries*nPaletteEntries);
   if (!avgDist) { goto error_1; }

   avgDistSortKey=malloc(sizeof(unsigned long *)*nPaletteEntries*nPaletteEntries);
   if (!avgDistSortKey) { goto error_2; }

#ifndef NO_OUTPUT
   printf("[");fflush(stdout);
#endif
   while (1) {
      if (!built) {
         compute_palette_from_quantized_pixels(pixelData,nPixels,paletteData,nPaletteEntries,avg,count,qp);
         build_distance_tables(avgDist,avgDistSortKey,paletteData,nPaletteEntries);
         built=1;
      } else {
         recompute_palette_from_averages(paletteData,nPaletteEntries,avg,count);
         resort_distance_tables(avgDist,avgDistSortKey,paletteData,nPaletteEntries);
      }
      changes=map_image_pixels_from_quantized_pixels(pixelData,
                                                     nPixels,
                                                     paletteData,
                                                     nPaletteEntries,
                                                     avgDist,
                                                     avgDistSortKey,
                                                     qp,
                                                     avg,
                                                     count);
      if (changes<0) {
         goto error_3;
      }
#ifndef NO_OUTPUT
      printf (".(%d)",changes);fflush(stdout);
#endif
      if (changes<=threshold) break;
   }
#ifndef NO_OUTPUT
   printf("]\n");
#endif
   if (avgDistSortKey) free(avgDistSortKey);
   if (avgDist) free(avgDist);
   for(i=0;i<3;i++) if (avg[i]) free (avg[i]);
   if (count) free(count);
   return 1;

error_3:
   if (avgDistSortKey) free(avgDistSortKey);
error_2:
   if (avgDist) free(avgDist);
error_1:
   for(i=0;i<3;i++) if (avg[i]) free (avg[i]);
   if (count) free(count);
   return 0;
}