commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s...@apache.org
Subject svn commit: r995859 [28/30] - in /commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan: ./ color/ common/ common/byteSources/ common/mylzw/ formats/bmp/ formats/bmp/pixelparsers/ formats/bmp/writers/ formats/gif/ formats/ico/ formats/jpeg/ f...
Date Fri, 10 Sep 2010 16:33:42 GMT
Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/ColorSpaceSubset.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/ColorSpaceSubset.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/ColorSpaceSubset.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/ColorSpaceSubset.java Fri Sep 10 16:33:35 2010
@@ -18,161 +18,161 @@ package org.apache.sanselan.palette;
 
 class ColorSpaceSubset implements Comparable
 {
-	public final int mins[], maxs[];
-	public final int precision;
-	public final int precision_mask;
-	public final int total;
-	public int rgb; // median
-
-	public ColorSpaceSubset(int total, int precision)
-	{
-		this.total = total;
-		this.precision = precision;
-		precision_mask = (1 << precision) - 1;
-
-		mins = new int[PaletteFactory.components];
-		maxs = new int[PaletteFactory.components];
-		for (int i = 0; i < PaletteFactory.components; i++)
-		{
-			mins[i] = 0;
-			//			maxs[i] = 255;
-			maxs[i] = precision_mask;
-		}
-
-		rgb = -1;
-	}
-
-	public ColorSpaceSubset(int total, int precision, int mins[], int maxs[],
-			int table[])
-	{
-		this.total = total;
-		this.precision = precision;
-		this.mins = mins;
-		this.maxs = maxs;
-		precision_mask = (1 << precision) - 1;
-
-		rgb = -1;
-	}
-
-	public static long compares = 0;
-
-	public final boolean contains(int red, int green, int blue)
-	{
-		compares++;
-
-		red >>= (8 - precision);
-		if (mins[0] > red)
-			return false;
-		if (maxs[0] < red)
-			return false;
-
-		green >>= (8 - precision);
-		if (mins[1] > green)
-			return false;
-		if (maxs[1] < green)
-			return false;
-
-		blue >>= (8 - precision);
-		if (mins[2] > blue)
-			return false;
-		if (maxs[2] < blue)
-			return false;
-
-		return true;
-	}
-
-	public void dump(String prefix)
-	{
-		int rdiff = maxs[0] - mins[0] + 1;
-		int gdiff = maxs[1] - mins[1] + 1;
-		int bdiff = maxs[2] - mins[2] + 1;
-		int color_area = rdiff * gdiff * bdiff;
-
-		System.out.println(prefix + ": [" + Integer.toHexString(rgb)
-				+ "] total : " + total
-		//						+ " ("
-				//						+ (100.0 * (double) total / (double) total_area)
-				//						+ " %)"
-				);
-		System.out.println("\t" + "rgb: " + Integer.toHexString(rgb) + ", "
-				+ "red: " + Integer.toHexString(mins[0] << (8 - precision))
-				+ ", " + Integer.toHexString(maxs[0] << (8 - precision)) + ", "
-				+ "green: " + Integer.toHexString(mins[1] << (8 - precision))
-				+ ", " + Integer.toHexString(maxs[1] << (8 - precision)) + ", "
-				+ "blue: " + Integer.toHexString(mins[2] << (8 - precision))
-				+ ", " + Integer.toHexString(maxs[2] << (8 - precision)));
-		System.out.println("\t" + "red: " + mins[0] + ", " + maxs[0] + ", "
-				+ "green: " + mins[1] + ", " + maxs[1] + ", " + "blue: "
-				+ mins[2] + ", " + maxs[2]);
-		System.out
-				.println("\t" + "rdiff: " + rdiff + ", " + "gdiff: " + gdiff
-						+ ", " + "bdiff: " + bdiff + ", " + "color_area: "
-						+ color_area);
-	}
-
-	public void dumpJustRGB(String prefix)
-	{
-		System.out.println("\t" + "rgb: " + Integer.toHexString(rgb) + ", "
-				+ "red: " + Integer.toHexString(mins[0] << (8 - precision))
-				+ ", " + Integer.toHexString(maxs[0] << (8 - precision)) + ", "
-				+ "green: " + Integer.toHexString(mins[1] << (8 - precision))
-				+ ", " + Integer.toHexString(maxs[1] << (8 - precision)) + ", "
-				+ "blue: " + Integer.toHexString(mins[2] << (8 - precision))
-				+ ", " + Integer.toHexString(maxs[2] << (8 - precision)));
-	}
-
-	public int getArea()
-	{
-		int rdiff = maxs[0] - mins[0] + 1;
-		int gdiff = maxs[1] - mins[1] + 1;
-		int bdiff = maxs[2] - mins[2] + 1;
-		int color_area = rdiff * gdiff * bdiff;
-
-		return color_area;
-
-	}
-
-	public void setAverageRGB(int table[])
-	{
-
-		{
-			long redsum = 0, greensum = 0, bluesum = 0;
-
-			for (int red = mins[0]; red <= maxs[0]; red++)
-				for (int green = mins[1]; green <= maxs[1]; green++)
-					for (int blue = mins[2]; blue <= maxs[2]; blue++)
-					//					for (int red = 0; red <= precision_mask; red++)
-					//						for (int green = 0; green <= precision_mask; green++)
-					//							for (int blue = 0; blue <= precision_mask; blue++)
-					{
-						int index = (blue << (2 * precision)) // note: order reversed
-								| (green << (1 * precision))
-								| (red << (0 * precision));
-						int count = table[index];
-						redsum += count * (red << (8 - precision));
-						greensum += count * (green << (8 - precision));
-						bluesum += count * (blue << (8 - precision));
-
-					}
-
-			redsum /= total;
-			greensum /= total;
-			bluesum /= total;
-			rgb = (int) (((redsum & 0xff) << 16) | ((greensum & 0xff) << 8) | ((bluesum & 0xff) << 0));
-		}
-	}
-
-	public int compareTo(Object o)
-	{
-		ColorSpaceSubset other = (ColorSpaceSubset) o;
-		return rgb - other.rgb;
-	}
-
-	public int index;
-
-	public final void setIndex(int i)
-	{
-		index = i;
-	}
+    public final int mins[], maxs[];
+    public final int precision;
+    public final int precision_mask;
+    public final int total;
+    public int rgb; // median
+
+    public ColorSpaceSubset(int total, int precision)
+    {
+        this.total = total;
+        this.precision = precision;
+        precision_mask = (1 << precision) - 1;
+
+        mins = new int[PaletteFactory.components];
+        maxs = new int[PaletteFactory.components];
+        for (int i = 0; i < PaletteFactory.components; i++)
+        {
+            mins[i] = 0;
+            //            maxs[i] = 255;
+            maxs[i] = precision_mask;
+        }
+
+        rgb = -1;
+    }
+
+    public ColorSpaceSubset(int total, int precision, int mins[], int maxs[],
+            int table[])
+    {
+        this.total = total;
+        this.precision = precision;
+        this.mins = mins;
+        this.maxs = maxs;
+        precision_mask = (1 << precision) - 1;
+
+        rgb = -1;
+    }
+
+    public static long compares = 0;
+
+    public final boolean contains(int red, int green, int blue)
+    {
+        compares++;
+
+        red >>= (8 - precision);
+        if (mins[0] > red)
+            return false;
+        if (maxs[0] < red)
+            return false;
+
+        green >>= (8 - precision);
+        if (mins[1] > green)
+            return false;
+        if (maxs[1] < green)
+            return false;
+
+        blue >>= (8 - precision);
+        if (mins[2] > blue)
+            return false;
+        if (maxs[2] < blue)
+            return false;
+
+        return true;
+    }
+
+    public void dump(String prefix)
+    {
+        int rdiff = maxs[0] - mins[0] + 1;
+        int gdiff = maxs[1] - mins[1] + 1;
+        int bdiff = maxs[2] - mins[2] + 1;
+        int color_area = rdiff * gdiff * bdiff;
+
+        System.out.println(prefix + ": [" + Integer.toHexString(rgb)
+                + "] total : " + total
+        //                        + " ("
+                //                        + (100.0 * (double) total / (double) total_area)
+                //                        + " %)"
+                );
+        System.out.println("\t" + "rgb: " + Integer.toHexString(rgb) + ", "
+                + "red: " + Integer.toHexString(mins[0] << (8 - precision))
+                + ", " + Integer.toHexString(maxs[0] << (8 - precision)) + ", "
+                + "green: " + Integer.toHexString(mins[1] << (8 - precision))
+                + ", " + Integer.toHexString(maxs[1] << (8 - precision)) + ", "
+                + "blue: " + Integer.toHexString(mins[2] << (8 - precision))
+                + ", " + Integer.toHexString(maxs[2] << (8 - precision)));
+        System.out.println("\t" + "red: " + mins[0] + ", " + maxs[0] + ", "
+                + "green: " + mins[1] + ", " + maxs[1] + ", " + "blue: "
+                + mins[2] + ", " + maxs[2]);
+        System.out
+                .println("\t" + "rdiff: " + rdiff + ", " + "gdiff: " + gdiff
+                        + ", " + "bdiff: " + bdiff + ", " + "color_area: "
+                        + color_area);
+    }
+
+    public void dumpJustRGB(String prefix)
+    {
+        System.out.println("\t" + "rgb: " + Integer.toHexString(rgb) + ", "
+                + "red: " + Integer.toHexString(mins[0] << (8 - precision))
+                + ", " + Integer.toHexString(maxs[0] << (8 - precision)) + ", "
+                + "green: " + Integer.toHexString(mins[1] << (8 - precision))
+                + ", " + Integer.toHexString(maxs[1] << (8 - precision)) + ", "
+                + "blue: " + Integer.toHexString(mins[2] << (8 - precision))
+                + ", " + Integer.toHexString(maxs[2] << (8 - precision)));
+    }
+
+    public int getArea()
+    {
+        int rdiff = maxs[0] - mins[0] + 1;
+        int gdiff = maxs[1] - mins[1] + 1;
+        int bdiff = maxs[2] - mins[2] + 1;
+        int color_area = rdiff * gdiff * bdiff;
+
+        return color_area;
+
+    }
+
+    public void setAverageRGB(int table[])
+    {
+
+        {
+            long redsum = 0, greensum = 0, bluesum = 0;
+
+            for (int red = mins[0]; red <= maxs[0]; red++)
+                for (int green = mins[1]; green <= maxs[1]; green++)
+                    for (int blue = mins[2]; blue <= maxs[2]; blue++)
+                    //                    for (int red = 0; red <= precision_mask; red++)
+                    //                        for (int green = 0; green <= precision_mask; green++)
+                    //                            for (int blue = 0; blue <= precision_mask; blue++)
+                    {
+                        int index = (blue << (2 * precision)) // note: order reversed
+                                | (green << (1 * precision))
+                                | (red << (0 * precision));
+                        int count = table[index];
+                        redsum += count * (red << (8 - precision));
+                        greensum += count * (green << (8 - precision));
+                        bluesum += count * (blue << (8 - precision));
+
+                    }
+
+            redsum /= total;
+            greensum /= total;
+            bluesum /= total;
+            rgb = (int) (((redsum & 0xff) << 16) | ((greensum & 0xff) << 8) | ((bluesum & 0xff) << 0));
+        }
+    }
+
+    public int compareTo(Object o)
+    {
+        ColorSpaceSubset other = (ColorSpaceSubset) o;
+        return rgb - other.rgb;
+    }
+
+    public int index;
+
+    public final void setIndex(int i)
+    {
+        index = i;
+    }
 
 }
\ No newline at end of file

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/MedianCutQuantizer.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/MedianCutQuantizer.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/MedianCutQuantizer.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/MedianCutQuantizer.java Fri Sep 10 16:33:35 2010
@@ -28,499 +28,499 @@ import org.apache.sanselan.util.Debug;
 
 public class MedianCutQuantizer
 {
-	private final boolean ignoreAlpha;
+    private final boolean ignoreAlpha;
 
-	public MedianCutQuantizer(boolean ignore_alpha)
-	{
-		this.ignoreAlpha = ignore_alpha;
-	}
-
-	private static class ColorCount
-	{
-		public final int argb;
-		public int count = 0;
-		public final int alpha, red, green, blue;
-
-		public ColorCount(int argb)
-		{
-			this.argb = argb;
-
-			alpha = 0xff & (argb >> 24);
-			red = 0xff & (argb >> 16);
-			green = 0xff & (argb >> 8);
-			blue = 0xff & (argb >> 0);
-
-			//			super.hashCode();
-		}
-
-		public int hashCode()
-		{
-			return argb;
-		}
-
-		public boolean equals(Object o)
-		{
-			ColorCount other = (ColorCount) o;
-			return other.argb == this.argb;
-		}
-
-	}
-
-	private class ColorGroup
-	{
-		//		public final ColorGroup parent;
-		public ColorGroupCut cut = null;
-		//		public final ArrayList children = new ArrayList();
-		public int palette_index = -1;
-
-		public final ArrayList color_counts;
-		public int min_red = Integer.MAX_VALUE;
-		public int max_red = Integer.MIN_VALUE;
-		public int min_green = Integer.MAX_VALUE;
-		public int max_green = Integer.MIN_VALUE;
-		public int min_blue = Integer.MAX_VALUE;
-		public int max_blue = Integer.MIN_VALUE;
-		public int min_alpha = Integer.MAX_VALUE;
-		public int max_alpha = Integer.MIN_VALUE;
-
-		public final int alpha_diff;
-		public final int red_diff;
-		public final int green_diff;
-		public final int blue_diff;
-
-		public final int max_diff;
-		public final int diff_total;
-
-		public ColorGroup(final ArrayList color_counts)
-				throws ImageWriteException
-		{
-			this.color_counts = color_counts;
-
-			if (color_counts.size() < 1)
-				throw new ImageWriteException("empty color_group");
-
-			for (int i = 0; i < color_counts.size(); i++)
-			{
-				ColorCount color = (ColorCount) color_counts.get(i);
-
-				min_alpha = Math.min(min_alpha, color.alpha);
-				max_alpha = Math.max(max_alpha, color.alpha);
-				min_red = Math.min(min_red, color.red);
-				max_red = Math.max(max_red, color.red);
-				min_green = Math.min(min_green, color.green);
-				max_green = Math.max(max_green, color.green);
-				min_blue = Math.min(min_blue, color.blue);
-				max_blue = Math.max(max_blue, color.blue);
-			}
-
-			alpha_diff = max_alpha - min_alpha;
-			red_diff = max_red - min_red;
-			green_diff = max_green - min_green;
-			blue_diff = max_blue - min_blue;
-			max_diff = Math.max(ignoreAlpha ? red_diff : Math.max(alpha_diff,
-					red_diff), Math.max(green_diff, blue_diff));
-			diff_total = (ignoreAlpha ? 0 : alpha_diff) + red_diff + green_diff
-					+ blue_diff;
-
-		}
-
-		public boolean contains(int argb)
-		{
-			int alpha = 0xff & (argb >> 24);
-			int red = 0xff & (argb >> 16);
-			int green = 0xff & (argb >> 8);
-			int blue = 0xff & (argb >> 0);
-
-			if (!ignoreAlpha && (alpha < min_alpha || alpha > max_alpha))
-				return false;
-			if (red < min_red || red > max_red)
-				return false;
-			if (green < min_green || green > max_green)
-				return false;
-			if (blue < min_blue || blue > max_blue)
-				return false;
-			return true;
-		}
-
-		public int getMedianValue()
-		{
-			long count_total = 0;
-			long alpha_total = 0, red_total = 0, green_total = 0, blue_total = 0;
-
-			for (int i = 0; i < color_counts.size(); i++)
-			{
-				ColorCount color = (ColorCount) color_counts.get(i);
-
-				count_total += color.count;
-				alpha_total += color.count * color.alpha;
-				red_total += color.count * color.red;
-				green_total += color.count * color.green;
-				blue_total += color.count * color.blue;
-			}
-
-			int alpha = ignoreAlpha ? 0xff : (int) Math
-					.round((double) alpha_total / count_total);
-			int red = (int) Math.round((double) red_total / count_total);
-			int green = (int) Math.round((double) green_total / count_total);
-			int blue = (int) Math.round((double) blue_total / count_total);
-
-			return (alpha << 24) | (red << 16) | (green << 8) | blue;
-		}
-
-		public String toString()
-		{
-			return "{ColorGroup. min_red: " + Integer.toHexString(min_red)
-					+ ", max_red: " + Integer.toHexString(max_red)
-					+ ", min_green: " + Integer.toHexString(min_green)
-					+ ", max_green: " + Integer.toHexString(max_green)
-					+ ", min_blue: " + Integer.toHexString(min_blue)
-					+ ", max_blue: " + Integer.toHexString(max_blue)
-					+ ", min_alpha: " + Integer.toHexString(min_alpha)
-					+ ", max_alpha: " + Integer.toHexString(max_alpha)
-					+ ", max_diff: " + Integer.toHexString(max_diff)
-					+ ", diff_total: " + diff_total + "}";
-		}
-
-	}
-
-	public Map groupColors1(BufferedImage image, int max, int mask)
-			throws ImageWriteException
-	{
-		Map color_map = new HashMap();
-
-		int width = image.getWidth();
-		int height = image.getHeight();
-
-		int row[] = new int[width];
-		for (int y = 0; y < height; y++)
-		{
-			image.getRGB(0, y, width, 1, row, 0, width);
-			for (int x = 0; x < width; x++)
-			{
-				int argb = row[x];
-
-				if (ignoreAlpha)
-					argb &= 0xffffff;
-				argb &= mask;
-
-				ColorCount color = (ColorCount) color_map
-						.get(new Integer(argb));
-				if (color == null)
-				{
-					color = new ColorCount(argb);
-					color_map.put(new Integer(argb), color);
-					if (color_map.keySet().size() > max)
-						return null;
-				}
-				color.count++;
-			}
-		}
-
-		return color_map;
-	}
-
-	public Map groupColors(BufferedImage image, int max_colors)
-			throws ImageWriteException
-	{
-		int max = Integer.MAX_VALUE;
-
-		for (int i = 0; i < 8; i++)
-		{
-			int mask = 0xff & (0xff << i);
-			mask = mask | (mask << 8) | (mask << 16) | (mask << 24);
-
-			Debug.debug("mask(" + i + ")", mask + " ("
-					+ Integer.toHexString(mask) + ")");
-
-			Map result = groupColors1(image, max, mask);
-			if (result != null)
-				return result;
-		}
-		throw new Error("");
-	}
-
-	public Palette process(BufferedImage image, int max_colors, boolean verbose)
-			throws ImageWriteException
-	{
-		Map color_map = groupColors(image, max_colors);
-
-		int discrete_colors = color_map.keySet().size();
-		if (discrete_colors <= max_colors)
-		{
-			if (verbose)
-				Debug.debug("lossless palette: " + discrete_colors);
-
-			int palette[] = new int[discrete_colors];
-			ArrayList color_counts = new ArrayList(color_map.values());
-
-			for (int i = 0; i < color_counts.size(); i++)
-			{
-				ColorCount color_count = (ColorCount) color_counts.get(i);
-				palette[i] = color_count.argb;
-				if (ignoreAlpha)
-					palette[i] |= 0xff000000;
-			}
-
-			return new SimplePalette(palette);
-		}
-
-		if (verbose)
-			Debug.debug("discrete colors: " + discrete_colors);
-
-		ArrayList color_groups = new ArrayList();
-		ColorGroup root = new ColorGroup(new ArrayList(color_map.values()));
-		{
-			color_groups.add(root);
-
-			final Comparator comparator = new Comparator()
-			{
-				public int compare(Object o1, Object o2)
-				{
-					ColorGroup cg1 = (ColorGroup) o1;
-					ColorGroup cg2 = (ColorGroup) o2;
-
-					if (cg1.max_diff == cg2.max_diff)
-						return cg2.diff_total - cg1.diff_total;
-					return cg2.max_diff - cg1.max_diff;
-				}
-			};
-
-			while (color_groups.size() < max_colors)
-			{
-				Collections.sort(color_groups, comparator);
-
-				ColorGroup color_group = (ColorGroup) color_groups.get(0);
-
-				if (color_group.max_diff == 0)
-					break;
-				if (!ignoreAlpha
-						&& color_group.alpha_diff > color_group.red_diff
-						&& color_group.alpha_diff > color_group.green_diff
-						&& color_group.alpha_diff > color_group.blue_diff)
-				{
-					doCut(color_group, ALPHA, color_groups);
-				}
-				else if (color_group.red_diff > color_group.green_diff
-						&& color_group.red_diff > color_group.blue_diff)
-				{
-					doCut(color_group, RED, color_groups);
-				}
-				else if (color_group.green_diff > color_group.blue_diff)
-				{
-					doCut(color_group, GREEN, color_groups);
-				}
-				else
-				{
-					doCut(color_group, BLUE, color_groups);
-				}
-			}
-		}
-
-		{
-			int palette_size = color_groups.size();
-			if (verbose)
-				Debug.debug("palette size: " + palette_size);
-
-			int palette[] = new int[palette_size];
-
-			for (int i = 0; i < color_groups.size(); i++)
-			{
-				ColorGroup color_group = (ColorGroup) color_groups.get(i);
-
-				palette[i] = color_group.getMedianValue();
-
-				color_group.palette_index = i;
-
-				if (color_group.color_counts.size() < 1)
-					throw new ImageWriteException("empty color_group: "
-							+ color_group);
-
-				//				if(color_group.)
-				//				Debug.debug("color_group", color_group);
-				//				Debug.debug("palette[" + i + "]", palette[i] + " ("
-				//						+ Integer.toHexString(palette[i]) + ")");
-			}
-
-			if (palette_size > discrete_colors)
-				throw new ImageWriteException("palette_size>discrete_colors");
-
-			return new MedianCutPalette(root, palette);
-		}
-	}
-
-	private static final int ALPHA = 0;
-	private static final int RED = 1;
-	private static final int GREEN = 2;
-	private static final int BLUE = 3;
-
-	private void doCut(ColorGroup color_group, final int mode,
-			final ArrayList color_groups) throws ImageWriteException
-	{
-		int count_total = 0;
-		for (int i = 0; i < color_group.color_counts.size(); i++)
-		{
-			ColorCount color_count = (ColorCount) color_group.color_counts
-					.get(i);
-			count_total += color_count.count;
-		}
-
-		Comparator comparator = new Comparator()
-		{
-			public int compare(Object o1, Object o2)
-			{
-				ColorCount c1 = (ColorCount) o1;
-				ColorCount c2 = (ColorCount) o2;
-
-				switch (mode)
-				{
-					case ALPHA :
-						return c1.alpha - c2.alpha;
-					case RED :
-						return c1.red - c2.red;
-					case GREEN :
-						return c1.green - c2.green;
-					case BLUE :
-						return c1.blue - c2.blue;
-					default :
-						return 0;
-				}
-			}
-		};
-
-		Collections.sort(color_group.color_counts, comparator);
-		int count_half = (int) Math.round((double) count_total / 2);
-		int old_count = 0, new_count = 0;
-		int median_index;
-		for (median_index = 0; median_index < color_group.color_counts.size(); median_index++)
-		{
-			ColorCount color_count = (ColorCount) color_group.color_counts
-					.get(median_index);
-
-			new_count += color_count.count;
-
-			if (new_count < count_half)
-			{
-				old_count = new_count;
-				continue;
-			}
-			break;
-		}
-
-		if (median_index == color_group.color_counts.size() - 1)
-			median_index--;
-		else if (median_index > 0)
-		{
-			int new_diff = Math.abs(new_count - count_half);
-			int old_diff = Math.abs(count_half - old_count);
-			if (old_diff < new_diff)
-				median_index--;
-		}
-
-		color_groups.remove(color_group);
-		{
-			ArrayList color_counts1 = new ArrayList(color_group.color_counts
-					.subList(0, median_index + 1));
-			ArrayList color_counts2 = new ArrayList(color_group.color_counts
-					.subList(median_index + 1, color_group.color_counts.size()));
-
-			ColorGroup less, more;
-			{
-				less = new ColorGroup(new ArrayList(color_counts1));
-				color_groups.add(less);
-			}
-			{
-				more = new ColorGroup(new ArrayList(color_counts2));
-				color_groups.add(more);
-			}
-
-			ColorCount median_value = (ColorCount) color_group.color_counts
-					.get(median_index);
-			int limit;
-			switch (mode)
-			{
-				case ALPHA :
-					limit = median_value.alpha;
-					break;
-				case RED :
-					limit = median_value.red;
-					break;
-				case GREEN :
-					limit = median_value.green;
-					break;
-				case BLUE :
-					limit = median_value.blue;
-					break;
-				default :
-					throw new Error("Bad mode.");
-			}
-			color_group.cut = new ColorGroupCut(less, more, mode, limit);
-
-		}
-	}
-	private class ColorGroupCut
-	{
-		public final ColorGroup less, more;
-		public final int mode, limit;
-
-		public ColorGroupCut(ColorGroup less, ColorGroup more, int mode,
-				int limit)
-		{
-			this.less = less;
-			this.more = more;
-			this.mode = mode;
-			this.limit = limit;
-		}
-
-		public ColorGroup getColorGroup(int argb)
-		{
-			int value;
-			switch (mode)
-			{
-				case ALPHA :
-					value = 0xff & (argb >> 24);
-					break;
-				case RED :
-					value = 0xff & (argb >> 16);
-					break;
-				case GREEN :
-					value = 0xff & (argb >> 8);
-					break;
-				case BLUE :
-					value = 0xff & (argb >> 0);
-					break;
-				default :
-					throw new Error("bad mode.");
-			}
-			if (value <= limit)
-				return less;
-			return more;
-		}
-
-	}
-
-	public class MedianCutPalette extends SimplePalette
-	{
-		private final ColorGroup root;
-
-		public MedianCutPalette(ColorGroup root, int palette[])
-		{
-			super(palette);
-			this.root = root;
-		}
-
-		public int getPaletteIndex(int rgb)
-		{
-			ColorGroup cg = root;
-
-			while (cg.cut != null)
-			{
-				ColorGroup next = cg.cut.getColorGroup(rgb);
-
-				cg = next;
-			}
-
-			return cg.palette_index;
-		}
-	}
+    public MedianCutQuantizer(boolean ignore_alpha)
+    {
+        this.ignoreAlpha = ignore_alpha;
+    }
+
+    private static class ColorCount
+    {
+        public final int argb;
+        public int count = 0;
+        public final int alpha, red, green, blue;
+
+        public ColorCount(int argb)
+        {
+            this.argb = argb;
+
+            alpha = 0xff & (argb >> 24);
+            red = 0xff & (argb >> 16);
+            green = 0xff & (argb >> 8);
+            blue = 0xff & (argb >> 0);
+
+            //            super.hashCode();
+        }
+
+        public int hashCode()
+        {
+            return argb;
+        }
+
+        public boolean equals(Object o)
+        {
+            ColorCount other = (ColorCount) o;
+            return other.argb == this.argb;
+        }
+
+    }
+
+    private class ColorGroup
+    {
+        //        public final ColorGroup parent;
+        public ColorGroupCut cut = null;
+        //        public final ArrayList children = new ArrayList();
+        public int palette_index = -1;
+
+        public final ArrayList color_counts;
+        public int min_red = Integer.MAX_VALUE;
+        public int max_red = Integer.MIN_VALUE;
+        public int min_green = Integer.MAX_VALUE;
+        public int max_green = Integer.MIN_VALUE;
+        public int min_blue = Integer.MAX_VALUE;
+        public int max_blue = Integer.MIN_VALUE;
+        public int min_alpha = Integer.MAX_VALUE;
+        public int max_alpha = Integer.MIN_VALUE;
+
+        public final int alpha_diff;
+        public final int red_diff;
+        public final int green_diff;
+        public final int blue_diff;
+
+        public final int max_diff;
+        public final int diff_total;
+
+        public ColorGroup(final ArrayList color_counts)
+                throws ImageWriteException
+        {
+            this.color_counts = color_counts;
+
+            if (color_counts.size() < 1)
+                throw new ImageWriteException("empty color_group");
+
+            for (int i = 0; i < color_counts.size(); i++)
+            {
+                ColorCount color = (ColorCount) color_counts.get(i);
+
+                min_alpha = Math.min(min_alpha, color.alpha);
+                max_alpha = Math.max(max_alpha, color.alpha);
+                min_red = Math.min(min_red, color.red);
+                max_red = Math.max(max_red, color.red);
+                min_green = Math.min(min_green, color.green);
+                max_green = Math.max(max_green, color.green);
+                min_blue = Math.min(min_blue, color.blue);
+                max_blue = Math.max(max_blue, color.blue);
+            }
+
+            alpha_diff = max_alpha - min_alpha;
+            red_diff = max_red - min_red;
+            green_diff = max_green - min_green;
+            blue_diff = max_blue - min_blue;
+            max_diff = Math.max(ignoreAlpha ? red_diff : Math.max(alpha_diff,
+                    red_diff), Math.max(green_diff, blue_diff));
+            diff_total = (ignoreAlpha ? 0 : alpha_diff) + red_diff + green_diff
+                    + blue_diff;
+
+        }
+
+        public boolean contains(int argb)
+        {
+            int alpha = 0xff & (argb >> 24);
+            int red = 0xff & (argb >> 16);
+            int green = 0xff & (argb >> 8);
+            int blue = 0xff & (argb >> 0);
+
+            if (!ignoreAlpha && (alpha < min_alpha || alpha > max_alpha))
+                return false;
+            if (red < min_red || red > max_red)
+                return false;
+            if (green < min_green || green > max_green)
+                return false;
+            if (blue < min_blue || blue > max_blue)
+                return false;
+            return true;
+        }
+
+        public int getMedianValue()
+        {
+            long count_total = 0;
+            long alpha_total = 0, red_total = 0, green_total = 0, blue_total = 0;
+
+            for (int i = 0; i < color_counts.size(); i++)
+            {
+                ColorCount color = (ColorCount) color_counts.get(i);
+
+                count_total += color.count;
+                alpha_total += color.count * color.alpha;
+                red_total += color.count * color.red;
+                green_total += color.count * color.green;
+                blue_total += color.count * color.blue;
+            }
+
+            int alpha = ignoreAlpha ? 0xff : (int) Math
+                    .round((double) alpha_total / count_total);
+            int red = (int) Math.round((double) red_total / count_total);
+            int green = (int) Math.round((double) green_total / count_total);
+            int blue = (int) Math.round((double) blue_total / count_total);
+
+            return (alpha << 24) | (red << 16) | (green << 8) | blue;
+        }
+
+        public String toString()
+        {
+            return "{ColorGroup. min_red: " + Integer.toHexString(min_red)
+                    + ", max_red: " + Integer.toHexString(max_red)
+                    + ", min_green: " + Integer.toHexString(min_green)
+                    + ", max_green: " + Integer.toHexString(max_green)
+                    + ", min_blue: " + Integer.toHexString(min_blue)
+                    + ", max_blue: " + Integer.toHexString(max_blue)
+                    + ", min_alpha: " + Integer.toHexString(min_alpha)
+                    + ", max_alpha: " + Integer.toHexString(max_alpha)
+                    + ", max_diff: " + Integer.toHexString(max_diff)
+                    + ", diff_total: " + diff_total + "}";
+        }
+
+    }
+
+    public Map groupColors1(BufferedImage image, int max, int mask)
+            throws ImageWriteException
+    {
+        Map color_map = new HashMap();
+
+        int width = image.getWidth();
+        int height = image.getHeight();
+
+        int row[] = new int[width];
+        for (int y = 0; y < height; y++)
+        {
+            image.getRGB(0, y, width, 1, row, 0, width);
+            for (int x = 0; x < width; x++)
+            {
+                int argb = row[x];
+
+                if (ignoreAlpha)
+                    argb &= 0xffffff;
+                argb &= mask;
+
+                ColorCount color = (ColorCount) color_map
+                        .get(new Integer(argb));
+                if (color == null)
+                {
+                    color = new ColorCount(argb);
+                    color_map.put(new Integer(argb), color);
+                    if (color_map.keySet().size() > max)
+                        return null;
+                }
+                color.count++;
+            }
+        }
+
+        return color_map;
+    }
+
+    public Map groupColors(BufferedImage image, int max_colors)
+            throws ImageWriteException
+    {
+        int max = Integer.MAX_VALUE;
+
+        for (int i = 0; i < 8; i++)
+        {
+            int mask = 0xff & (0xff << i);
+            mask = mask | (mask << 8) | (mask << 16) | (mask << 24);
+
+            Debug.debug("mask(" + i + ")", mask + " ("
+                    + Integer.toHexString(mask) + ")");
+
+            Map result = groupColors1(image, max, mask);
+            if (result != null)
+                return result;
+        }
+        throw new Error("");
+    }
+
+    public Palette process(BufferedImage image, int max_colors, boolean verbose)
+            throws ImageWriteException
+    {
+        Map color_map = groupColors(image, max_colors);
+
+        int discrete_colors = color_map.keySet().size();
+        if (discrete_colors <= max_colors)
+        {
+            if (verbose)
+                Debug.debug("lossless palette: " + discrete_colors);
+
+            int palette[] = new int[discrete_colors];
+            ArrayList color_counts = new ArrayList(color_map.values());
+
+            for (int i = 0; i < color_counts.size(); i++)
+            {
+                ColorCount color_count = (ColorCount) color_counts.get(i);
+                palette[i] = color_count.argb;
+                if (ignoreAlpha)
+                    palette[i] |= 0xff000000;
+            }
+
+            return new SimplePalette(palette);
+        }
+
+        if (verbose)
+            Debug.debug("discrete colors: " + discrete_colors);
+
+        ArrayList color_groups = new ArrayList();
+        ColorGroup root = new ColorGroup(new ArrayList(color_map.values()));
+        {
+            color_groups.add(root);
+
+            final Comparator comparator = new Comparator()
+            {
+                public int compare(Object o1, Object o2)
+                {
+                    ColorGroup cg1 = (ColorGroup) o1;
+                    ColorGroup cg2 = (ColorGroup) o2;
+
+                    if (cg1.max_diff == cg2.max_diff)
+                        return cg2.diff_total - cg1.diff_total;
+                    return cg2.max_diff - cg1.max_diff;
+                }
+            };
+
+            while (color_groups.size() < max_colors)
+            {
+                Collections.sort(color_groups, comparator);
+
+                ColorGroup color_group = (ColorGroup) color_groups.get(0);
+
+                if (color_group.max_diff == 0)
+                    break;
+                if (!ignoreAlpha
+                        && color_group.alpha_diff > color_group.red_diff
+                        && color_group.alpha_diff > color_group.green_diff
+                        && color_group.alpha_diff > color_group.blue_diff)
+                {
+                    doCut(color_group, ALPHA, color_groups);
+                }
+                else if (color_group.red_diff > color_group.green_diff
+                        && color_group.red_diff > color_group.blue_diff)
+                {
+                    doCut(color_group, RED, color_groups);
+                }
+                else if (color_group.green_diff > color_group.blue_diff)
+                {
+                    doCut(color_group, GREEN, color_groups);
+                }
+                else
+                {
+                    doCut(color_group, BLUE, color_groups);
+                }
+            }
+        }
+
+        {
+            int palette_size = color_groups.size();
+            if (verbose)
+                Debug.debug("palette size: " + palette_size);
+
+            int palette[] = new int[palette_size];
+
+            for (int i = 0; i < color_groups.size(); i++)
+            {
+                ColorGroup color_group = (ColorGroup) color_groups.get(i);
+
+                palette[i] = color_group.getMedianValue();
+
+                color_group.palette_index = i;
+
+                if (color_group.color_counts.size() < 1)
+                    throw new ImageWriteException("empty color_group: "
+                            + color_group);
+
+                //                if(color_group.)
+                //                Debug.debug("color_group", color_group);
+                //                Debug.debug("palette[" + i + "]", palette[i] + " ("
+                //                        + Integer.toHexString(palette[i]) + ")");
+            }
+
+            if (palette_size > discrete_colors)
+                throw new ImageWriteException("palette_size>discrete_colors");
+
+            return new MedianCutPalette(root, palette);
+        }
+    }
+
+    private static final int ALPHA = 0;
+    private static final int RED = 1;
+    private static final int GREEN = 2;
+    private static final int BLUE = 3;
+
+    private void doCut(ColorGroup color_group, final int mode,
+            final ArrayList color_groups) throws ImageWriteException
+    {
+        int count_total = 0;
+        for (int i = 0; i < color_group.color_counts.size(); i++)
+        {
+            ColorCount color_count = (ColorCount) color_group.color_counts
+                    .get(i);
+            count_total += color_count.count;
+        }
+
+        Comparator comparator = new Comparator()
+        {
+            public int compare(Object o1, Object o2)
+            {
+                ColorCount c1 = (ColorCount) o1;
+                ColorCount c2 = (ColorCount) o2;
+
+                switch (mode)
+                {
+                    case ALPHA :
+                        return c1.alpha - c2.alpha;
+                    case RED :
+                        return c1.red - c2.red;
+                    case GREEN :
+                        return c1.green - c2.green;
+                    case BLUE :
+                        return c1.blue - c2.blue;
+                    default :
+                        return 0;
+                }
+            }
+        };
+
+        Collections.sort(color_group.color_counts, comparator);
+        int count_half = (int) Math.round((double) count_total / 2);
+        int old_count = 0, new_count = 0;
+        int median_index;
+        for (median_index = 0; median_index < color_group.color_counts.size(); median_index++)
+        {
+            ColorCount color_count = (ColorCount) color_group.color_counts
+                    .get(median_index);
+
+            new_count += color_count.count;
+
+            if (new_count < count_half)
+            {
+                old_count = new_count;
+                continue;
+            }
+            break;
+        }
+
+        if (median_index == color_group.color_counts.size() - 1)
+            median_index--;
+        else if (median_index > 0)
+        {
+            int new_diff = Math.abs(new_count - count_half);
+            int old_diff = Math.abs(count_half - old_count);
+            if (old_diff < new_diff)
+                median_index--;
+        }
+
+        color_groups.remove(color_group);
+        {
+            ArrayList color_counts1 = new ArrayList(color_group.color_counts
+                    .subList(0, median_index + 1));
+            ArrayList color_counts2 = new ArrayList(color_group.color_counts
+                    .subList(median_index + 1, color_group.color_counts.size()));
+
+            ColorGroup less, more;
+            {
+                less = new ColorGroup(new ArrayList(color_counts1));
+                color_groups.add(less);
+            }
+            {
+                more = new ColorGroup(new ArrayList(color_counts2));
+                color_groups.add(more);
+            }
+
+            ColorCount median_value = (ColorCount) color_group.color_counts
+                    .get(median_index);
+            int limit;
+            switch (mode)
+            {
+                case ALPHA :
+                    limit = median_value.alpha;
+                    break;
+                case RED :
+                    limit = median_value.red;
+                    break;
+                case GREEN :
+                    limit = median_value.green;
+                    break;
+                case BLUE :
+                    limit = median_value.blue;
+                    break;
+                default :
+                    throw new Error("Bad mode.");
+            }
+            color_group.cut = new ColorGroupCut(less, more, mode, limit);
+
+        }
+    }
+    private class ColorGroupCut
+    {
+        public final ColorGroup less, more;
+        public final int mode, limit;
+
+        public ColorGroupCut(ColorGroup less, ColorGroup more, int mode,
+                int limit)
+        {
+            this.less = less;
+            this.more = more;
+            this.mode = mode;
+            this.limit = limit;
+        }
+
+        public ColorGroup getColorGroup(int argb)
+        {
+            int value;
+            switch (mode)
+            {
+                case ALPHA :
+                    value = 0xff & (argb >> 24);
+                    break;
+                case RED :
+                    value = 0xff & (argb >> 16);
+                    break;
+                case GREEN :
+                    value = 0xff & (argb >> 8);
+                    break;
+                case BLUE :
+                    value = 0xff & (argb >> 0);
+                    break;
+                default :
+                    throw new Error("bad mode.");
+            }
+            if (value <= limit)
+                return less;
+            return more;
+        }
+
+    }
+
+    public class MedianCutPalette extends SimplePalette
+    {
+        private final ColorGroup root;
+
+        public MedianCutPalette(ColorGroup root, int palette[])
+        {
+            super(palette);
+            this.root = root;
+        }
+
+        public int getPaletteIndex(int rgb)
+        {
+            ColorGroup cg = root;
+
+            while (cg.cut != null)
+            {
+                ColorGroup next = cg.cut.getColorGroup(rgb);
+
+                cg = next;
+            }
+
+            return cg.palette_index;
+        }
+    }
 
 }

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/Palette.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/Palette.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/Palette.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/Palette.java Fri Sep 10 16:33:35 2010
@@ -21,14 +21,14 @@ import org.apache.sanselan.ImageWriteExc
 public abstract class Palette
 {
 
-	public abstract int getPaletteIndex(int rgb) throws ImageWriteException;
+    public abstract int getPaletteIndex(int rgb) throws ImageWriteException;
 
-	public abstract int getEntry(int index);
+    public abstract int getEntry(int index);
 
-	public abstract int length();
+    public abstract int length();
 
-	public void dump()
-	{
-	}
+    public void dump()
+    {
+    }
 
 }
\ No newline at end of file

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/PaletteFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/PaletteFactory.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/PaletteFactory.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/PaletteFactory.java Fri Sep 10 16:33:35 2010
@@ -27,557 +27,557 @@ import java.util.Map;
 
 public class PaletteFactory
 {
-	private static final boolean debug = false;
+    private static final boolean debug = false;
 
-	public void makePaletteFancy(BufferedImage src)
-	{
-		//		 map what rgb values have been used
-
-		byte rgbmap[] = new byte[256 * 256 * 32];
-		for (int i = 0; i < rgbmap.length; i++)
-			rgbmap[i] = 0;
-
-		int width = src.getWidth();
-		int height = src.getHeight();
-
-		for (int y = 0; y < height; y++)
-			for (int x = 0; x < width; x++)
-			{
-				int argb = src.getRGB(x, y);
-				int rggbb = 0x1fffff & argb;
-				int highred = 0x7 & (argb >> 21);
-				int mask = 1 << highred;
-				rgbmap[rggbb] |= mask;
-			}
-
-		int count = 0;
-		for (int i = 0; i < rgbmap.length; i++)
-		{
-			int eight = 0xff & rgbmap[i];
-			if ((i < 3) || ((i - rgbmap.length) > -3))
-			{
-			}
-			for (int j = 0; j < 8; j++)
-			{
-				int mask = 1 << (7 - j);
-				int bit = eight & mask;
-				if (bit > 0)
-					count++;
-
-			}
-		}
-
-		if (debug)
-			System.out.println("Used colors: " + count);
-
-		int colormap[] = new int[count];
-		int mapsize = 0;
-		for (int i = 0; i < rgbmap.length; i++)
-		{
-			int eight = 0xff & rgbmap[i];
-
-			for (int j = 0; j < 8; j++)
-			{
-				int mask = 1 << (7 - j);
-				int bit = eight & mask;
-
-				if (bit > 0)
-				{
-					int rgb = i | ((7 - j) << 21);
-
-					if (mapsize < colormap.length)
-						colormap[mapsize] = rgb;
-					mapsize++;
-				}
-			}
-		}
-
-		if (debug)
-			System.out.println("mapsize: " + mapsize);
-
-		//		for (int i = 0; i < colormap.length; i++)
-		//		{
-		//			int rgb = colormap[i];
-		//		}
-
-	}
-
-	private int pixelToQuantizationTableIndex(int argb, int precision)
-	{
-		int result = 0;
-		int precision_mask = (1 << precision) - 1;
-
-		for (int i = 0; i < components; i++)
-		{
-			int sample = argb & 0xff;
-			argb >>= 8;
-
-			sample >>= (8 - precision);
-			result = (result << precision) | (sample & precision_mask);
-		}
-
-		return result;
-	}
-
-	private int getFrequencyTotal(int table[], int mins[], int maxs[],
-			int precision)
-	{
-		int sum = 0;
-
-		for (int blue = mins[2]; blue <= maxs[2]; blue++)
-		{
-			int b = (blue << (2 * precision));
-			for (int green = mins[1]; green <= maxs[1]; green++)
-			{
-				int g = (green << (1 * precision));
-
-				for (int red = mins[0]; red <= maxs[0]; red++)
-				{
-					int index = b | g | red;
-
-					sum += table[index];
-				}
-			}
-		}
-
-		return sum;
-	}
-
-	private DivisionCandidate finishDivision(int table[],
-			ColorSpaceSubset subset, int component, int precision, int sum,
-			int slice)
-	{
-		if (debug)
-			subset.dump("trying (" + component + "): ");
-
-		int total = subset.total;
-
-		if ((slice < subset.mins[component])
-				|| (slice >= subset.maxs[component]))
-		{
-			return null;
-		}
-
-		if ((sum < 1) || (sum >= total))
-		{
-			return null;
-		}
-
-		int remainder = total - sum;
-		if ((remainder < 1) || (remainder >= total))
-		{
-			return null;
-		}
-
-		//		ArrayList result = new ArrayList();
-
-		int slice_mins[] = new int[subset.mins.length];
-		System.arraycopy(subset.mins, 0, slice_mins, 0, subset.mins.length);
-		int slice_maxs[] = new int[subset.maxs.length];
-		System.arraycopy(subset.maxs, 0, slice_maxs, 0, subset.maxs.length);
-
-		slice_maxs[component] = slice;
-		slice_mins[component] = slice + 1;
-
-		if (debug)
-		{
-			System.out.println("total: " + total);
-			System.out.println("first total: " + sum);
-			System.out.println("second total: " + (total - sum));
-			//			System.out.println("start: " + start);
-			//			System.out.println("end: " + end);
-			System.out.println("slice: " + slice);
-
-		}
-
-		ColorSpaceSubset first = new ColorSpaceSubset(sum, precision,
-				subset.mins, slice_maxs, table);
-		ColorSpaceSubset second = new ColorSpaceSubset(total - sum, precision,
-				slice_mins, subset.maxs, table);
-
-		return new DivisionCandidate(subset, first, second);
-
-	}
-
-	private ArrayList divideSubset2(int table[], ColorSpaceSubset subset,
-			int component, int precision)
-	{
-		if (debug)
-			subset.dump("trying (" + component + "): ");
-
-		int total = subset.total;
-
-		int slice_mins[] = new int[subset.mins.length];
-		System.arraycopy(subset.mins, 0, slice_mins, 0, subset.mins.length);
-		int slice_maxs[] = new int[subset.maxs.length];
-		System.arraycopy(subset.maxs, 0, slice_maxs, 0, subset.maxs.length);
-
-		int sum1 = 0, sum2;
-		int slice1, slice2;
-		int last = 0;
-
-		{
-			for (slice1 = subset.mins[component]; slice1 != subset.maxs[component] + 1; slice1++)
-			{
-
-				slice_mins[component] = slice1;
-				slice_maxs[component] = slice1;
-
-				last = getFrequencyTotal(table, slice_mins, slice_maxs,
-						precision);
-
-				sum1 += last;
-
-				if (sum1 >= (total / 2))
-					break;
-			}
-
-			sum2 = sum1 - last;
-			slice2 = slice1 - 1;
-
-		}
-
-		DivisionCandidate dc1 = finishDivision(table, subset, component,
-				precision, sum1, slice1);
-		DivisionCandidate dc2 = finishDivision(table, subset, component,
-				precision, sum2, slice2);
-
-		ArrayList result = new ArrayList();
-
-		if (dc1 != null)
-			result.add(dc1);
-		if (dc2 != null)
-			result.add(dc2);
-
-		return result;
-	}
-
-	private DivisionCandidate divideSubset2(int table[],
-			ColorSpaceSubset subset, int precision)
-	{
-		ArrayList dcs = new ArrayList();
-
-		dcs.addAll(divideSubset2(table, subset, 0, precision));
-		dcs.addAll(divideSubset2(table, subset, 1, precision));
-		dcs.addAll(divideSubset2(table, subset, 2, precision));
-
-		DivisionCandidate best_v = null;
-		//		int best_split 
-		double best_score = Double.MAX_VALUE;
-
-		for (int i = 0; i < dcs.size(); i++)
-		{
-			DivisionCandidate dc = (DivisionCandidate) dcs.get(i);
-
-			ColorSpaceSubset first = dc.dst_a;
-			ColorSpaceSubset second = dc.dst_b;
-			int area1 = first.total;
-			int area2 = second.total;
-
-			int diff = Math.abs(area1 - area2);
-			double split = ((double) diff) / ((double) Math.max(area1, area2));
-
-			double score = split;
-
-			if (best_v == null)
-			{
-				best_v = dc;
-				best_score = score;
-			}
-			else if (score < best_score)
-			{
-				best_v = dc;
-				best_score = score;
-			}
-
-		}
-
-		return best_v;
-	}
-
-	public static final int components = 3; // in bits
-
-	private static class DivisionCandidate
-	{
-		//		private final ColorSpaceSubset src;
-		private final ColorSpaceSubset dst_a, dst_b;
-
-		public DivisionCandidate(ColorSpaceSubset src, ColorSpaceSubset dst_a,
-				ColorSpaceSubset dst_b)
-		{
-			//			this.src = src;
-			this.dst_a = dst_a;
-			this.dst_b = dst_b;
-		}
-	}
-
-	private ArrayList divide(ArrayList v, int desired_count, int table[],
-			int precision)
-	{
-		ArrayList ignore = new ArrayList();
-
-		int count = 0;
-		while (true)
-		{
-			count++;
-
-			if (debug)
-				System.out.println("cycle(" + count + "): " + v.size()
-						+ " done");
-
-			int max_area = -1;
-			ColorSpaceSubset max_subset = null;
-
-			for (int i = 0; i < v.size(); i++)
-			{
-				ColorSpaceSubset subset = (ColorSpaceSubset) v.get(i);
-				if (ignore.contains(subset))
-					continue;
-				int area = subset.total;
-
-				if (max_subset == null)
-				{
-					max_subset = subset;
-					max_area = area;
-				}
-				else if (area > max_area)
-				{
-					max_subset = subset;
-					max_area = area;
-				}
-			}
-
-			if (max_subset == null)
-			{
-				return v;
-			}
-			if (debug)
-				System.out.println("\t" + "area: " + max_area);
-
-			{
-
-				DivisionCandidate dc = divideSubset2(table, max_subset,
-						precision);
-				if (dc != null)
-				{
-					v.remove(max_subset);
-					v.add(dc.dst_a);
-					v.add(dc.dst_b);
-				}
-				else
-					ignore.add(max_subset);
-			}
-
-			if (v.size() == desired_count)
-				return v;
-		}
-
-		//		return result;
-	}
-
-	public Palette makePaletteQuantized(BufferedImage src, int max)
-	{
-		int precision = 6; // in bits
-
-		int table_scale = precision * components;
-		int table_size = 1 << table_scale;
-		int table[] = new int[table_size];
-
-		int width = src.getWidth();
-		int height = src.getHeight();
-
-		ArrayList subsets = new ArrayList();
-		ColorSpaceSubset all = new ColorSpaceSubset(width * height, precision);
-		subsets.add(all);
-
-		int pre_total = getFrequencyTotal(table, all.mins, all.maxs, precision);
-		if (debug)
-			System.out.println("pre total: " + pre_total);
-
-		{ // step 1: count frequency of colors
-
-			for (int y = 0; y < height; y++)
-				for (int x = 0; x < width; x++)
-				{
-					int argb = src.getRGB(x, y);
-
-					int index = pixelToQuantizationTableIndex(argb, precision);
-
-					table[index]++;
-				}
-		}
-
-		int all_total = getFrequencyTotal(table, all.mins, all.maxs, precision);
-		if (debug)
-		{
-			System.out.println("all total: " + all_total);
-
-			System.out.println("width * height: " + (width * height));
-		}
-
-		subsets = divide(subsets, 256, table, precision);
-
-		if (debug)
-		{
-			System.out.println("subsets: " + subsets.size());
-			System.out.println("width*height: " + width * height);
-		}
-
-		for (int i = 0; i < subsets.size(); i++)
-		{
-			ColorSpaceSubset subset = (ColorSpaceSubset) subsets.get(i);
-
-			subset.setAverageRGB(table);
-
-			if (debug)
-				subset.dump(i + ": ");
-		}
-
-		Collections.sort(subsets);
-
-		return new QuantizedPalette(subsets, precision);
-	}
-
-	public SimplePalette makePaletteSimple(BufferedImage src, int max)
-	// This is not efficient for large values of max, say, max > 256;
-	{
-		Map map = new HashMap();
-		int rgbs[] = new int[max];
-		int rgb_count = 0;
-
-		int width = src.getWidth();
-		int height = src.getHeight();
-
-		for (int y = 0; y < height; y++)
-			for (int x = 0; x < width; x++)
-			{
-				int argb = src.getRGB(x, y);
-				int rgb = 0xffffff & argb;
-
-				String key = "" + rgb;
-				if (null == map.get(key))
-				{
-					if (rgb_count == max)
-						return null;
-
-					rgbs[rgb_count] = rgb;
-					map.put(key, key);
-					rgb_count++;
-				}
-			}
-
-		int result[] = new int[rgb_count];
-		System.arraycopy(rgbs, 0, result, 0, rgb_count);
-		Arrays.sort(result);
-
-		//		return result;
-		return new SimplePalette(result);
-	}
-
-	public boolean isGrayscale(BufferedImage src)
-	{
-		int width = src.getWidth();
-		int height = src.getHeight();
-
-		if (ColorSpace.TYPE_GRAY == src.getColorModel().getColorSpace()
-				.getType())
-			return true;
-
-		for (int y = 0; y < height; y++)
-			for (int x = 0; x < width; x++)
-			{
-				int argb = src.getRGB(x, y);
-
-				int red = 0xff & (argb >> 16);
-				int green = 0xff & (argb >> 8);
-				int blue = 0xff & (argb >> 0);
-
-				if (red != green || red != blue)
-					return false;
-			}
-
-		return true;
-	}
-
-	public boolean hasTransparency(BufferedImage src)
-	{
-		return hasTransparency(src, 255);
-	}
-
-	public boolean hasTransparency(BufferedImage src, int threshold)
-	{
-		int width = src.getWidth();
-		int height = src.getHeight();
-
-		if (!src.getColorModel().hasAlpha())
-			return false;
-
-		for (int y = 0; y < height; y++)
-			for (int x = 0; x < width; x++)
-			{
-				int argb = src.getRGB(x, y);
-				int alpha = 0xff & (argb >> 24);
-				if (alpha < threshold)
-					return true;
-			}
-
-		return false;
-	}
-
-	public int countTrasparentColors(int rgbs[])
-	{
-		int first = -1;
-
-		for (int i = 0; i < rgbs.length; i++)
-		{
-			int rgb = rgbs[i];
-			int alpha = 0xff & (rgb >> 24);
-			if (alpha < 0xff)
-			{
-				if (first < 0)
-				{
-					first = rgb;
-				}
-				else if (rgb != first)
-					return 2; // more than one transparent color;
-			}
-		}
-
-		if (first < 0)
-			return 0;
-		return 1;
-	}
-
-	public int countTransparentColors(BufferedImage src)
-	{
-		ColorModel cm = src.getColorModel();
-		if (!cm.hasAlpha())
-			return 0;
-
-		int width = src.getWidth();
-		int height = src.getHeight();
-
-		int first = -1;
-
-		for (int y = 0; y < height; y++)
-			for (int x = 0; x < width; x++)
-			{
-				int rgb = src.getRGB(x, y);
-				int alpha = 0xff & (rgb >> 24);
-				if (alpha < 0xff)
-				{
-					if (first < 0)
-					{
-						first = rgb;
-					}
-					else if (rgb != first)
-						return 2; // more than one transparent color;
-				}
-			}
-
-		if (first < 0)
-			return 0;
-		return 1;
-	}
+    public void makePaletteFancy(BufferedImage src)
+    {
+        //         map what rgb values have been used
+
+        byte rgbmap[] = new byte[256 * 256 * 32];
+        for (int i = 0; i < rgbmap.length; i++)
+            rgbmap[i] = 0;
+
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++)
+            {
+                int argb = src.getRGB(x, y);
+                int rggbb = 0x1fffff & argb;
+                int highred = 0x7 & (argb >> 21);
+                int mask = 1 << highred;
+                rgbmap[rggbb] |= mask;
+            }
+
+        int count = 0;
+        for (int i = 0; i < rgbmap.length; i++)
+        {
+            int eight = 0xff & rgbmap[i];
+            if ((i < 3) || ((i - rgbmap.length) > -3))
+            {
+            }
+            for (int j = 0; j < 8; j++)
+            {
+                int mask = 1 << (7 - j);
+                int bit = eight & mask;
+                if (bit > 0)
+                    count++;
+
+            }
+        }
+
+        if (debug)
+            System.out.println("Used colors: " + count);
+
+        int colormap[] = new int[count];
+        int mapsize = 0;
+        for (int i = 0; i < rgbmap.length; i++)
+        {
+            int eight = 0xff & rgbmap[i];
+
+            for (int j = 0; j < 8; j++)
+            {
+                int mask = 1 << (7 - j);
+                int bit = eight & mask;
+
+                if (bit > 0)
+                {
+                    int rgb = i | ((7 - j) << 21);
+
+                    if (mapsize < colormap.length)
+                        colormap[mapsize] = rgb;
+                    mapsize++;
+                }
+            }
+        }
+
+        if (debug)
+            System.out.println("mapsize: " + mapsize);
+
+        //        for (int i = 0; i < colormap.length; i++)
+        //        {
+        //            int rgb = colormap[i];
+        //        }
+
+    }
+
+    private int pixelToQuantizationTableIndex(int argb, int precision)
+    {
+        int result = 0;
+        int precision_mask = (1 << precision) - 1;
+
+        for (int i = 0; i < components; i++)
+        {
+            int sample = argb & 0xff;
+            argb >>= 8;
+
+            sample >>= (8 - precision);
+            result = (result << precision) | (sample & precision_mask);
+        }
+
+        return result;
+    }
+
+    private int getFrequencyTotal(int table[], int mins[], int maxs[],
+            int precision)
+    {
+        int sum = 0;
+
+        for (int blue = mins[2]; blue <= maxs[2]; blue++)
+        {
+            int b = (blue << (2 * precision));
+            for (int green = mins[1]; green <= maxs[1]; green++)
+            {
+                int g = (green << (1 * precision));
+
+                for (int red = mins[0]; red <= maxs[0]; red++)
+                {
+                    int index = b | g | red;
+
+                    sum += table[index];
+                }
+            }
+        }
+
+        return sum;
+    }
+
+    private DivisionCandidate finishDivision(int table[],
+            ColorSpaceSubset subset, int component, int precision, int sum,
+            int slice)
+    {
+        if (debug)
+            subset.dump("trying (" + component + "): ");
+
+        int total = subset.total;
+
+        if ((slice < subset.mins[component])
+                || (slice >= subset.maxs[component]))
+        {
+            return null;
+        }
+
+        if ((sum < 1) || (sum >= total))
+        {
+            return null;
+        }
+
+        int remainder = total - sum;
+        if ((remainder < 1) || (remainder >= total))
+        {
+            return null;
+        }
+
+        //        ArrayList result = new ArrayList();
+
+        int slice_mins[] = new int[subset.mins.length];
+        System.arraycopy(subset.mins, 0, slice_mins, 0, subset.mins.length);
+        int slice_maxs[] = new int[subset.maxs.length];
+        System.arraycopy(subset.maxs, 0, slice_maxs, 0, subset.maxs.length);
+
+        slice_maxs[component] = slice;
+        slice_mins[component] = slice + 1;
+
+        if (debug)
+        {
+            System.out.println("total: " + total);
+            System.out.println("first total: " + sum);
+            System.out.println("second total: " + (total - sum));
+            //            System.out.println("start: " + start);
+            //            System.out.println("end: " + end);
+            System.out.println("slice: " + slice);
+
+        }
+
+        ColorSpaceSubset first = new ColorSpaceSubset(sum, precision,
+                subset.mins, slice_maxs, table);
+        ColorSpaceSubset second = new ColorSpaceSubset(total - sum, precision,
+                slice_mins, subset.maxs, table);
+
+        return new DivisionCandidate(subset, first, second);
+
+    }
+
+    private ArrayList divideSubset2(int table[], ColorSpaceSubset subset,
+            int component, int precision)
+    {
+        if (debug)
+            subset.dump("trying (" + component + "): ");
+
+        int total = subset.total;
+
+        int slice_mins[] = new int[subset.mins.length];
+        System.arraycopy(subset.mins, 0, slice_mins, 0, subset.mins.length);
+        int slice_maxs[] = new int[subset.maxs.length];
+        System.arraycopy(subset.maxs, 0, slice_maxs, 0, subset.maxs.length);
+
+        int sum1 = 0, sum2;
+        int slice1, slice2;
+        int last = 0;
+
+        {
+            for (slice1 = subset.mins[component]; slice1 != subset.maxs[component] + 1; slice1++)
+            {
+
+                slice_mins[component] = slice1;
+                slice_maxs[component] = slice1;
+
+                last = getFrequencyTotal(table, slice_mins, slice_maxs,
+                        precision);
+
+                sum1 += last;
+
+                if (sum1 >= (total / 2))
+                    break;
+            }
+
+            sum2 = sum1 - last;
+            slice2 = slice1 - 1;
+
+        }
+
+        DivisionCandidate dc1 = finishDivision(table, subset, component,
+                precision, sum1, slice1);
+        DivisionCandidate dc2 = finishDivision(table, subset, component,
+                precision, sum2, slice2);
+
+        ArrayList result = new ArrayList();
+
+        if (dc1 != null)
+            result.add(dc1);
+        if (dc2 != null)
+            result.add(dc2);
+
+        return result;
+    }
+
+    private DivisionCandidate divideSubset2(int table[],
+            ColorSpaceSubset subset, int precision)
+    {
+        ArrayList dcs = new ArrayList();
+
+        dcs.addAll(divideSubset2(table, subset, 0, precision));
+        dcs.addAll(divideSubset2(table, subset, 1, precision));
+        dcs.addAll(divideSubset2(table, subset, 2, precision));
+
+        DivisionCandidate best_v = null;
+        //        int best_split
+        double best_score = Double.MAX_VALUE;
+
+        for (int i = 0; i < dcs.size(); i++)
+        {
+            DivisionCandidate dc = (DivisionCandidate) dcs.get(i);
+
+            ColorSpaceSubset first = dc.dst_a;
+            ColorSpaceSubset second = dc.dst_b;
+            int area1 = first.total;
+            int area2 = second.total;
+
+            int diff = Math.abs(area1 - area2);
+            double split = ((double) diff) / ((double) Math.max(area1, area2));
+
+            double score = split;
+
+            if (best_v == null)
+            {
+                best_v = dc;
+                best_score = score;
+            }
+            else if (score < best_score)
+            {
+                best_v = dc;
+                best_score = score;
+            }
+
+        }
+
+        return best_v;
+    }
+
+    public static final int components = 3; // in bits
+
+    private static class DivisionCandidate
+    {
+        //        private final ColorSpaceSubset src;
+        private final ColorSpaceSubset dst_a, dst_b;
+
+        public DivisionCandidate(ColorSpaceSubset src, ColorSpaceSubset dst_a,
+                ColorSpaceSubset dst_b)
+        {
+            //            this.src = src;
+            this.dst_a = dst_a;
+            this.dst_b = dst_b;
+        }
+    }
+
+    private ArrayList divide(ArrayList v, int desired_count, int table[],
+            int precision)
+    {
+        ArrayList ignore = new ArrayList();
+
+        int count = 0;
+        while (true)
+        {
+            count++;
+
+            if (debug)
+                System.out.println("cycle(" + count + "): " + v.size()
+                        + " done");
+
+            int max_area = -1;
+            ColorSpaceSubset max_subset = null;
+
+            for (int i = 0; i < v.size(); i++)
+            {
+                ColorSpaceSubset subset = (ColorSpaceSubset) v.get(i);
+                if (ignore.contains(subset))
+                    continue;
+                int area = subset.total;
+
+                if (max_subset == null)
+                {
+                    max_subset = subset;
+                    max_area = area;
+                }
+                else if (area > max_area)
+                {
+                    max_subset = subset;
+                    max_area = area;
+                }
+            }
+
+            if (max_subset == null)
+            {
+                return v;
+            }
+            if (debug)
+                System.out.println("\t" + "area: " + max_area);
+
+            {
+
+                DivisionCandidate dc = divideSubset2(table, max_subset,
+                        precision);
+                if (dc != null)
+                {
+                    v.remove(max_subset);
+                    v.add(dc.dst_a);
+                    v.add(dc.dst_b);
+                }
+                else
+                    ignore.add(max_subset);
+            }
+
+            if (v.size() == desired_count)
+                return v;
+        }
+
+        //        return result;
+    }
+
+    public Palette makePaletteQuantized(BufferedImage src, int max)
+    {
+        int precision = 6; // in bits
+
+        int table_scale = precision * components;
+        int table_size = 1 << table_scale;
+        int table[] = new int[table_size];
+
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        ArrayList subsets = new ArrayList();
+        ColorSpaceSubset all = new ColorSpaceSubset(width * height, precision);
+        subsets.add(all);
+
+        int pre_total = getFrequencyTotal(table, all.mins, all.maxs, precision);
+        if (debug)
+            System.out.println("pre total: " + pre_total);
+
+        { // step 1: count frequency of colors
+
+            for (int y = 0; y < height; y++)
+                for (int x = 0; x < width; x++)
+                {
+                    int argb = src.getRGB(x, y);
+
+                    int index = pixelToQuantizationTableIndex(argb, precision);
+
+                    table[index]++;
+                }
+        }
+
+        int all_total = getFrequencyTotal(table, all.mins, all.maxs, precision);
+        if (debug)
+        {
+            System.out.println("all total: " + all_total);
+
+            System.out.println("width * height: " + (width * height));
+        }
+
+        subsets = divide(subsets, 256, table, precision);
+
+        if (debug)
+        {
+            System.out.println("subsets: " + subsets.size());
+            System.out.println("width*height: " + width * height);
+        }
+
+        for (int i = 0; i < subsets.size(); i++)
+        {
+            ColorSpaceSubset subset = (ColorSpaceSubset) subsets.get(i);
+
+            subset.setAverageRGB(table);
+
+            if (debug)
+                subset.dump(i + ": ");
+        }
+
+        Collections.sort(subsets);
+
+        return new QuantizedPalette(subsets, precision);
+    }
+
+    public SimplePalette makePaletteSimple(BufferedImage src, int max)
+    // This is not efficient for large values of max, say, max > 256;
+    {
+        Map map = new HashMap();
+        int rgbs[] = new int[max];
+        int rgb_count = 0;
+
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++)
+            {
+                int argb = src.getRGB(x, y);
+                int rgb = 0xffffff & argb;
+
+                String key = "" + rgb;
+                if (null == map.get(key))
+                {
+                    if (rgb_count == max)
+                        return null;
+
+                    rgbs[rgb_count] = rgb;
+                    map.put(key, key);
+                    rgb_count++;
+                }
+            }
+
+        int result[] = new int[rgb_count];
+        System.arraycopy(rgbs, 0, result, 0, rgb_count);
+        Arrays.sort(result);
+
+        //        return result;
+        return new SimplePalette(result);
+    }
+
+    public boolean isGrayscale(BufferedImage src)
+    {
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        if (ColorSpace.TYPE_GRAY == src.getColorModel().getColorSpace()
+                .getType())
+            return true;
+
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++)
+            {
+                int argb = src.getRGB(x, y);
+
+                int red = 0xff & (argb >> 16);
+                int green = 0xff & (argb >> 8);
+                int blue = 0xff & (argb >> 0);
+
+                if (red != green || red != blue)
+                    return false;
+            }
+
+        return true;
+    }
+
+    public boolean hasTransparency(BufferedImage src)
+    {
+        return hasTransparency(src, 255);
+    }
+
+    public boolean hasTransparency(BufferedImage src, int threshold)
+    {
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        if (!src.getColorModel().hasAlpha())
+            return false;
+
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++)
+            {
+                int argb = src.getRGB(x, y);
+                int alpha = 0xff & (argb >> 24);
+                if (alpha < threshold)
+                    return true;
+            }
+
+        return false;
+    }
+
+    public int countTrasparentColors(int rgbs[])
+    {
+        int first = -1;
+
+        for (int i = 0; i < rgbs.length; i++)
+        {
+            int rgb = rgbs[i];
+            int alpha = 0xff & (rgb >> 24);
+            if (alpha < 0xff)
+            {
+                if (first < 0)
+                {
+                    first = rgb;
+                }
+                else if (rgb != first)
+                    return 2; // more than one transparent color;
+            }
+        }
+
+        if (first < 0)
+            return 0;
+        return 1;
+    }
+
+    public int countTransparentColors(BufferedImage src)
+    {
+        ColorModel cm = src.getColorModel();
+        if (!cm.hasAlpha())
+            return 0;
+
+        int width = src.getWidth();
+        int height = src.getHeight();
+
+        int first = -1;
+
+        for (int y = 0; y < height; y++)
+            for (int x = 0; x < width; x++)
+            {
+                int rgb = src.getRGB(x, y);
+                int alpha = 0xff & (rgb >> 24);
+                if (alpha < 0xff)
+                {
+                    if (first < 0)
+                    {
+                        first = rgb;
+                    }
+                    else if (rgb != first)
+                        return 2; // more than one transparent color;
+                }
+            }
+
+        if (first < 0)
+            return 0;
+        return 1;
+    }
 
 }
\ No newline at end of file

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/QuantizedPalette.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/QuantizedPalette.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/QuantizedPalette.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/QuantizedPalette.java Fri Sep 10 16:33:35 2010
@@ -22,65 +22,65 @@ import org.apache.sanselan.ImageWriteExc
 
 public class QuantizedPalette extends Palette
 {
-	private final int precision;
-	private final ArrayList subsets;
-	private final ColorSpaceSubset straight[];
-
-	public QuantizedPalette(ArrayList subsets, int precision)
-	{
-		this.subsets = subsets;
-		this.precision = precision;
-
-		{
-			straight = new ColorSpaceSubset[1 << (precision * 3)];
-
-			for (int i = 0; i < subsets.size(); i++)
-			{
-				ColorSpaceSubset subset = (ColorSpaceSubset) subsets.get(i);
-				subset.setIndex(i);
-
-				for (int u = subset.mins[0]; u <= subset.maxs[0]; u++)
-					for (int j = subset.mins[1]; j <= subset.maxs[1]; j++)
-						for (int k = subset.mins[2]; k <= subset.maxs[2]; k++)
-						{
-							int index = (u << (precision * 2))
-									| (j << (precision * 1))
-									| (k << (precision * 0));
-							straight[index] = subset;
-						}
-			}
-		}
-
-	}
-
-	public int getPaletteIndex(int rgb) throws ImageWriteException
-	{
-		int precisionMask = (1 << precision) - 1;
-
-		int index = ((rgb >> (24 - 3 * precision)) & (precisionMask << (precision << 1)))
-				| ((rgb >> (16 - 2 * precision)) & (precisionMask << precision))
-				| ((rgb >> (8 - precision)) & (precisionMask));
-
-		return straight[index].index;
-	}
-
-	public void dump()
-	{
-		//		System.out.println("ColorSpaceSubset.compares: "
-		//				+ ColorSpaceSubset.compares);
-		//		System.out.println("converted: " + converted);
-		//		System.out.println("avg. distance: " + (distance / converted));
-	}
-
-	public int getEntry(int index)
-	{
-		ColorSpaceSubset subset = (ColorSpaceSubset) subsets.get(index);
-		return subset.rgb;
-	}
-
-	public int length()
-	{
-		return subsets.size();
+    private final int precision;
+    private final ArrayList subsets;
+    private final ColorSpaceSubset straight[];
+
+    public QuantizedPalette(ArrayList subsets, int precision)
+    {
+        this.subsets = subsets;
+        this.precision = precision;
+
+        {
+            straight = new ColorSpaceSubset[1 << (precision * 3)];
+
+            for (int i = 0; i < subsets.size(); i++)
+            {
+                ColorSpaceSubset subset = (ColorSpaceSubset) subsets.get(i);
+                subset.setIndex(i);
+
+                for (int u = subset.mins[0]; u <= subset.maxs[0]; u++)
+                    for (int j = subset.mins[1]; j <= subset.maxs[1]; j++)
+                        for (int k = subset.mins[2]; k <= subset.maxs[2]; k++)
+                        {
+                            int index = (u << (precision * 2))
+                                    | (j << (precision * 1))
+                                    | (k << (precision * 0));
+                            straight[index] = subset;
+                        }
+            }
+        }
+
+    }
+
+    public int getPaletteIndex(int rgb) throws ImageWriteException
+    {
+        int precisionMask = (1 << precision) - 1;
+
+        int index = ((rgb >> (24 - 3 * precision)) & (precisionMask << (precision << 1)))
+                | ((rgb >> (16 - 2 * precision)) & (precisionMask << precision))
+                | ((rgb >> (8 - precision)) & (precisionMask));
+
+        return straight[index].index;
+    }
+
+    public void dump()
+    {
+        //        System.out.println("ColorSpaceSubset.compares: "
+        //                + ColorSpaceSubset.compares);
+        //        System.out.println("converted: " + converted);
+        //        System.out.println("avg. distance: " + (distance / converted));
+    }
+
+    public int getEntry(int index)
+    {
+        ColorSpaceSubset subset = (ColorSpaceSubset) subsets.get(index);
+        return subset.rgb;
+    }
+
+    public int length()
+    {
+        return subsets.size();
 
-	}
+    }
 }
\ No newline at end of file

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/SimplePalette.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/SimplePalette.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/SimplePalette.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/palette/SimplePalette.java Fri Sep 10 16:33:35 2010
@@ -20,53 +20,53 @@ import org.apache.sanselan.util.Debug;
 
 public class SimplePalette extends Palette
 {
-	private final int palette[];
+    private final int palette[];
 
-	public SimplePalette(int palette[])
-	{
-		this.palette = palette;
-	}
-
-	public int getPaletteIndex(int rgb)
-	{
-		return getPaletteIndex(palette, rgb);
-	}
-
-	public int getEntry(int index)
-	{
-		return palette[index];
-		//			return getPaletteIndex(palette, rgb);
-	}
-
-	private int getPaletteIndex(int palette[], int argb)
-	{
-
-		//		Debug.debug("getPaletteIndex argb", argb + " ("
-		//				+ Integer.toHexString(argb) + ")");
-
-		for (int i = 0; i < palette.length; i++)
-		{
-			//			Debug.debug("\t" + "palette[" + i + "]", palette[i] + " ("
-			//					+ Integer.toHexString(palette[i]) + ")");
-
-			if (palette[i] == argb)
-				return i;
-		}
-
-		return -1;
-	}
-
-	public void dump()
-	{
-		for (int i = 0; i < palette.length; i++)
-		{
-			Debug.debug("\t" + "palette[" + i + "]", palette[i] + " (0x"
-					+ Integer.toHexString(palette[i]) + ")");
-		}
-	}
-
-	public int length()
-	{
-		return palette.length;
-	}
+    public SimplePalette(int palette[])
+    {
+        this.palette = palette;
+    }
+
+    public int getPaletteIndex(int rgb)
+    {
+        return getPaletteIndex(palette, rgb);
+    }
+
+    public int getEntry(int index)
+    {
+        return palette[index];
+        //            return getPaletteIndex(palette, rgb);
+    }
+
+    private int getPaletteIndex(int palette[], int argb)
+    {
+
+        //        Debug.debug("getPaletteIndex argb", argb + " ("
+        //                + Integer.toHexString(argb) + ")");
+
+        for (int i = 0; i < palette.length; i++)
+        {
+            //            Debug.debug("\t" + "palette[" + i + "]", palette[i] + " ("
+            //                    + Integer.toHexString(palette[i]) + ")");
+
+            if (palette[i] == argb)
+                return i;
+        }
+
+        return -1;
+    }
+
+    public void dump()
+    {
+        for (int i = 0; i < palette.length; i++)
+        {
+            Debug.debug("\t" + "palette[" + i + "]", palette[i] + " (0x"
+                    + Integer.toHexString(palette[i]) + ")");
+        }
+    }
+
+    public int length()
+    {
+        return palette.length;
+    }
 }
\ No newline at end of file

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingInputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingInputStream.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingInputStream.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingInputStream.java Fri Sep 10 16:33:35 2010
@@ -23,34 +23,34 @@ import java.io.InputStream;
 
 public class CachingInputStream extends InputStream
 {
-	private final InputStream is;
-	private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    private final InputStream is;
+    private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
-	public CachingInputStream(InputStream is)
-	{
-		this.is = is;
-	}
-
-	public byte[] getCache()
-	{
-		return baos.toByteArray();
-	}
-
-	public int read() throws IOException
-	{
-		int result = is.read();
-		baos.write(result);
-		return result;
-	}
-
-	public int available() throws IOException
-	{
-		return is.available();
-	}
-
-	public void close() throws IOException
-	{
-		is.close();
-	}
+    public CachingInputStream(InputStream is)
+    {
+        this.is = is;
+    }
+
+    public byte[] getCache()
+    {
+        return baos.toByteArray();
+    }
+
+    public int read() throws IOException
+    {
+        int result = is.read();
+        baos.write(result);
+        return result;
+    }
+
+    public int available() throws IOException
+    {
+        return is.available();
+    }
+
+    public void close() throws IOException
+    {
+        is.close();
+    }
 
 }

Modified: commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingOutputStream.java
URL: http://svn.apache.org/viewvc/commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingOutputStream.java?rev=995859&r1=995858&r2=995859&view=diff
==============================================================================
--- commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingOutputStream.java (original)
+++ commons/proper/sanselan/trunk/src/main/java/org/apache/sanselan/util/CachingOutputStream.java Fri Sep 10 16:33:35 2010
@@ -23,33 +23,33 @@ import java.io.OutputStream;
 
 public class CachingOutputStream extends OutputStream
 {
-	private final OutputStream os;
-	private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    private final OutputStream os;
+    private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
 
-	public CachingOutputStream(OutputStream os)
-	{
-		this.os = os;
-	}
-
-	public void write(int b) throws IOException
-	{
-		os.write(b);
-		baos.write(b);
-	}
-
-	public byte[] getCache()
-	{
-		return baos.toByteArray();
-	}
-
-	public void close() throws IOException
-	{
-		os.close();
-	}
-
-	public void flush() throws IOException
-	{
-		os.flush();
-	}
+    public CachingOutputStream(OutputStream os)
+    {
+        this.os = os;
+    }
+
+    public void write(int b) throws IOException
+    {
+        os.write(b);
+        baos.write(b);
+    }
+
+    public byte[] getCache()
+    {
+        return baos.toByteArray();
+    }
+
+    public void close() throws IOException
+    {
+        os.close();
+    }
+
+    public void flush() throws IOException
+    {
+        os.flush();
+    }
 
 }



Mime
View raw message