]> git.imager.perl.org - imager.git/blobdiff - quant.c
correct an old bug link
[imager.git] / quant.c
diff --git a/quant.c b/quant.c
index 14b97fa7e1a2dbb4d6865085c6c10833e83751ff..419b81b76b52388f9e2b9f66cf13ab521393b2fb 100644 (file)
--- a/quant.c
+++ b/quant.c
@@ -93,7 +93,7 @@ i_quant_makemap(i_quantize *quant, i_img **imgs, int count) {
 }
 
 static void translate_closest(i_quantize *, i_img *, i_palidx *);
-static void translate_errdiff(i_quantize *, i_img *, i_palidx *);
+static int translate_errdiff(i_quantize *, i_img *, i_palidx *);
 static void translate_addi(i_quantize *, i_img *, i_palidx *);
 
 /*
@@ -143,7 +143,10 @@ i_quant_translate(i_quantize *quant, i_img *img) {
     break;
     
   case pt_errdiff:
-    translate_errdiff(quant, img, result);
+    if (!translate_errdiff(quant, img, result)) {
+      myfree(result);
+      return NULL;
+    }
     break;
     
   case pt_perturb:
@@ -464,7 +467,7 @@ makemap_addi(i_quantize *quant, i_img **imgs, int count) {
 
 typedef struct {
   i_sample_t rgb[3];
-  int count;
+  i_img_dim count;
 } quant_color_entry;
 
 #define MEDIAN_CUT_COLORS 32768
@@ -630,6 +633,7 @@ makemap_mediancut(i_quantize *quant, i_img **imgs, int count) {
       for (ch = 0; ch < 3; ++ch) {
         quant->mc_colors[i].channel[ch] = colors[i].rgb[ch];
       }
+      quant->mc_colors[i].rgba.a = 255;
     }
     quant->mc_count = out;
   }
@@ -647,8 +651,8 @@ makemap_mediancut(i_quantize *quant, i_img **imgs, int count) {
       int max_index = 0, max_ch = 0; /* index/channel with biggest spread */
       int max_size;
       medcut_partition *workpart;
-      int cum_total;
-      int half;
+      i_img_dim cum_total;
+      i_img_dim half;
       
       /* find the partition with the most biggest span with more than 
          one color */
@@ -702,7 +706,7 @@ makemap_mediancut(i_quantize *quant, i_img **imgs, int count) {
     /* fill in the color table - since we could still have partitions
        that have more than one color, we need to average the colors */
     for (part_num = 0; part_num < color_count; ++part_num) {
-      long sums[3];
+      double sums[3];
       medcut_partition *workpart;
       
       workpart = parts+part_num;
@@ -711,12 +715,13 @@ makemap_mediancut(i_quantize *quant, i_img **imgs, int count) {
       
       for (i = workpart->start; i < workpart->start + workpart->size; ++i) {
         for (ch = 0; ch < 3; ++ch) {
-          sums[ch] += colors[i].rgb[ch] * colors[i].count;
+          sums[ch] += (int)(colors[i].rgb[ch]) * colors[i].count;
         }
       }
       for (ch = 0; ch < 3; ++ch) {
         quant->mc_colors[part_num].channel[ch] = sums[ch] / workpart->pixels;
       }
+      quant->mc_colors[part_num].rgba.a = 255;
     }
     quant->mc_count = color_count;
   }
@@ -1354,8 +1359,7 @@ typedef struct errdiff_tag {
 } errdiff_t;
 
 /* perform an error diffusion dither */
-static
-void
+static int
 translate_errdiff(i_quantize *quant, i_img *img, i_palidx *out) {
   int *map;
   int mapw, maph, mapo;
@@ -1383,14 +1387,25 @@ translate_errdiff(i_quantize *quant, i_img *img, i_palidx *out) {
     mapo = maps[index].orig;
   }
   
+  difftotal = 0;
+  for (i = 0; i < maph * mapw; ++i) {
+    if (map[i] < 0) {
+      i_push_errorf(0, "errdiff_map values must be non-negative, errdiff[%d] is negative", i);
+      goto fail;
+    }
+    difftotal += map[i];
+  }
+
+  if (!difftotal) {
+    i_push_error(0, "error diffusion map must contain some non-zero values");
+    goto fail;
+  }
+
   errw = img->xsize+mapw;
   err = mymalloc(sizeof(*err) * maph * errw);
   /*errp = err+mapo;*/
   memset(err, 0, sizeof(*err) * maph * errw);
   
-  difftotal = 0;
-  for (i = 0; i < maph * mapw; ++i)
-    difftotal += map[i];
   /*printf("map:\n");
  for (dy = 0; dy < maph; ++dy) {
    for (dx = 0; dx < mapw; ++dx) {
@@ -1444,6 +1459,13 @@ translate_errdiff(i_quantize *quant, i_img *img, i_palidx *out) {
   }
   CF_CLEANUP;
   myfree(err);
+
+  return 1;
+
+ fail:
+  CF_CLEANUP;
+
+  return 0;
 }
 /* Prescan finds the boxes in the image that have the highest number of colors 
    and that result is used as the initial value for the vectores */
@@ -1514,7 +1536,7 @@ static void reorder(pbox prescan[512]) {
   c.cand++;
   c.pdc=c.pixcnt/(c.cand*c.cand); 
   /*  c.pdc=c.pixcnt/c.cand; */
-  while(c.pdc < prescan[nidx+1].pdc && nidx < 511) {
+  while(nidx < 511 && c.pdc < prescan[nidx+1].pdc) {
     prescan[nidx]=prescan[nidx+1];
     nidx++;
   }
@@ -1574,7 +1596,7 @@ static
 void
 cr_hashindex(cvec clr[256],int cnum,hashbox hb[512]) {
   
-  int bx,mind,cd,cumcnt,bst_idx,i;
+  int bx,mind,cd,cumcnt,i;
 /*  printf("indexing... \n");*/
   
   cumcnt=0;
@@ -1582,7 +1604,7 @@ cr_hashindex(cvec clr[256],int cnum,hashbox hb[512]) {
     mind=196608;
     for(i=0; i<cnum; i++) { 
       cd = maxdist(bx,&clr[i]);
-      if (cd < mind) { mind=cd; bst_idx=i; 
+      if (cd < mind) { mind=cd; } 
     }
     
     hb[bx].cnt=0;