Revision: 20099
          http://sourceforge.net/p/jmol/code/20099
Author:   hansonr
Date:     2014-11-10 12:26:03 +0000 (Mon, 10 Nov 2014)
Log Message:
-----------
Jmol.___JmolVersion="14.2.8_2014.11.10"

bug fix: slightly better GIF processing

Modified Paths:
--------------
    branches/v14_2/Jmol/src/javajs/img/GifEncoder.java
    branches/v14_2/Jmol/src/org/jmol/viewer/Jmol.properties

Modified: branches/v14_2/Jmol/src/javajs/img/GifEncoder.java
===================================================================
--- branches/v14_2/Jmol/src/javajs/img/GifEncoder.java  2014-11-10 12:23:38 UTC 
(rev 20098)
+++ branches/v14_2/Jmol/src/javajs/img/GifEncoder.java  2014-11-10 12:26:03 UTC 
(rev 20099)
@@ -78,7 +78,7 @@
  * GifEncoder extensively adapted for Jmol by Bob Hanson
  * 
  * Color quantization roughly follows the GIMP method
- * "dither Floyd-Steinberg standard" but with some twists.
+ * "dither Floyd-Steinberg (normal)" but with some twists.
  * (For example, we exclude the background color.)
  * 
  * Note that although GIMP code annotation refers to "median-cut", 
@@ -482,21 +482,23 @@
 
   /**
    * 
-   * Assign all colors to their closest approximation and
-   * change pixels[] array to index values.
+   * Assign all colors to their closest approximation and change pixels[] array
+   * to index values.
    * 
    * Floyd-Steinberg dithering, with error limiting to 75%. Finds the closest
    * known color and then spreads out the error over four leading pixels.
    * 
-   * @param colorMap 
-   * @param boxes 
+   * @param colorMap
+   * @param boxes
    * 
    */
-  private void quantizePixels(Map<Integer, ColorCell> colorMap, Lst<ColorCell> 
boxes) {
+  private void quantizePixels(Map<Integer, ColorCell> colorMap,
+                              Lst<ColorCell> boxes) {
     P3[] pixelErr = new P3[pixels.length];
     P3 err = new P3();
     P3 lab;
     int rgb;
+    Map<Integer, ColorCell> nearestCell = new Hashtable<Integer, ColorCell>();
     for (int i = 0, p = 0; i < height; ++i) {
       boolean notLastRow = (i != height - 1);
       for (int j = 0; j < width; ++j, p++) {
@@ -506,32 +508,37 @@
         } else {
           lab = toLAB(pixels[p]);
           err = pixelErr[p]; // it does not matter that we repurpose errors[p] 
here.
+          // important not to round the clamp here -- full floating precision
           err.x = clamp(err.x, -75, 75);
           err.y = clamp(err.y, -75, 75);
           err.z = clamp(err.z, -75, 75);
           lab.add(err);
           rgb = CU.colorPtToFFRGB(toRGB(lab));
         }
-        ColorCell app = colorMap.get(Integer.valueOf(rgb));
-        if (app == null) {
-          if (lab == null)
-            lab = toLAB(pixels[p]);
-          // find nearest cell
-          float maxerr = Float.MAX_VALUE;
-          // skip 0 0 0
-          for (int ib = boxes.size(); --ib >= 1;) {
-            ColorCell b = boxes.get(ib);
-            err.sub2(lab, b.lab);
-            float d = err.lengthSquared();
-            if (d < maxerr) {
-              maxerr = d;
-              app = b;
+        Integer key = Integer.valueOf(rgb);
+        ColorCell cell = colorMap.get(key);
+        if (cell == null) {
+          // critical to generate lab from rgb here for nearestCell mapping.
+          lab = toLAB(rgb);
+          cell = nearestCell.get(key);
+          if (cell == null) {
+            // find nearest cell
+            float maxerr = Float.MAX_VALUE;
+            // skip 0 0 0
+            for (int ib = boxes.size(); --ib >= 1;) {
+              ColorCell b = boxes.get(ib);
+              err.sub2(lab, b.lab);
+              float d = err.lengthSquared();
+              if (d < maxerr) {
+                maxerr = d;
+                cell = b;
+              }
             }
+            nearestCell.put(key, cell);
           }
-          err.sub2(lab, app.lab);
-
           if (floydSteinberg) {
             // dither
+            err.sub2(lab, cell.lab);
             boolean notLastCol = (j < width - 1);
             if (notLastCol)
               addError(err, 7, pixelErr, p + 1);
@@ -544,7 +551,7 @@
             }
           }
         }
-        pixels[p] = app.index;
+        pixels[p] = cell.index;
       }
     }
   }
@@ -683,7 +690,8 @@
   }
 
   private float clamp(float c, float min, float max) {
-    return Math.round(c < min ? min : c > max ? max : c);
+    c = (c < min ? min : c > max ? max : c);
+    return (min == 0 ? Math.round(c) : c);
   }
 
   //static {

Modified: branches/v14_2/Jmol/src/org/jmol/viewer/Jmol.properties
===================================================================
--- branches/v14_2/Jmol/src/org/jmol/viewer/Jmol.properties     2014-11-10 
12:23:38 UTC (rev 20098)
+++ branches/v14_2/Jmol/src/org/jmol/viewer/Jmol.properties     2014-11-10 
12:26:03 UTC (rev 20099)
@@ -4,8 +4,12 @@
 # THIS IS THE RELEASE BRANCH 
 # BUG FIXES ONLY, PLEASE
 
-Jmol.___JmolVersion="14.2.7_2014.11.09"
+Jmol.___JmolVersion="14.2.8_2014.11.10"
 
+bug fix: slightly better GIF processing
+
+JmolVersion="14.2.8_2014.11.09"
+
 bug fix: GIF writer not properly handling large numbers of colors
   -- use of CIE L*a*b for color quantification
   -- nearly identical to GIMP
@@ -13,7 +17,7 @@
   -- uses Floyd-Steinberg dithering
   -- will not discolor background (as GIMP will do)
 
-JmolVersion="14.2.7_2014.10.27"
+JmolVersion="14.2.8_2014.10.27"
 
 bug fix: up-arrow in console may not return command if contains unicode
 bug fix: antialiasing can subtly change background color

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
_______________________________________________
Jmol-commits mailing list
Jmol-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jmol-commits

Reply via email to