extend some variable types to avoid overflows for mediancut
authorTony Cook <tony@develop-help.com>
Mon, 7 Jan 2019 12:13:10 +0000 (23:13 +1100)
committerTony Cook <tony@develop-help.com>
Mon, 7 Jan 2019 12:13:10 +0000 (23:13 +1100)
for very large images

Changes
quant.c

diff --git a/Changes b/Changes
index 7a77399..8df28b9 100644 (file)
--- a/Changes
+++ b/Changes
@@ -125,6 +125,10 @@ Lower severity (according to Coverity):
    (mymalloc) is negative.  Left from when that parameter was signed.
    CID 185305.
 
    (mymalloc) is negative.  Left from when that parameter was signed.
    CID 185305.
 
+ - make some types larger and add a cast to prevent integer overflows
+   when calculating a palette with median cut for extraordinarily
+   large images.  CID 185306.
+
 [1] The first two build submissions ended up at the end of a ~400
 build queue, and seemed to have been cancelled by Coverity.  A build
 submitted on NYE went through in minutes.
 [1] The first two build submissions ended up at the end of a ~400
 build queue, and seemed to have been cancelled by Coverity.  A build
 submitted on NYE went through in minutes.
diff --git a/quant.c b/quant.c
index 9b76968..01ec8fc 100644 (file)
--- a/quant.c
+++ b/quant.c
@@ -467,7 +467,7 @@ makemap_addi(i_quantize *quant, i_img **imgs, int count) {
 
 typedef struct {
   i_sample_t rgb[3];
 
 typedef struct {
   i_sample_t rgb[3];
-  int count;
+  i_img_dim count;
 } quant_color_entry;
 
 #define MEDIAN_CUT_COLORS 32768
 } quant_color_entry;
 
 #define MEDIAN_CUT_COLORS 32768
@@ -650,8 +650,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 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 */
       
       /* find the partition with the most biggest span with more than 
          one color */
@@ -705,7 +705,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) {
     /* 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;
       medcut_partition *workpart;
       
       workpart = parts+part_num;
@@ -714,7 +714,7 @@ 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) {
       
       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) {
         }
       }
       for (ch = 0; ch < 3; ++ch) {