001: package org.cougaar.demo.mandelbrot.util;
002:
003: import java.awt.Color;
004: import java.io.BufferedReader;
005: import java.io.FileReader;
006: import java.io.InputStream;
007: import java.io.InputStreamReader;
008: import java.io.Reader;
009: import java.util.AbstractList;
010: import java.util.ArrayList;
011: import java.util.LinkedHashMap;
012: import java.util.List;
013: import java.util.Map;
014: import java.util.regex.Matcher;
015: import java.util.regex.Pattern;
016:
017: /**
018: * A color palette parser.
019: * <p>
020: * @see default_palette.map See "default_palette.map" for the default content
021: */
022: public class Palette extends AbstractList {
023:
024: private static final String DEFAULT_FILENAME = "resource:/org/cougaar/demo/mandelbrot/util/default_palette.map";
025:
026: private static final int CACHE_SIZE = 5;
027: private static final Map cache = (CACHE_SIZE <= 0 ? null
028: : (new LinkedHashMap(CACHE_SIZE) {
029: protected boolean removeEldestEntry(Map.Entry eldest) {
030: return (size() > CACHE_SIZE);
031: }
032: }));
033:
034: private final Color[] colors;
035:
036: public Palette() {
037: this (-1);
038: }
039:
040: public Palette(int max) {
041: this (null, max);
042: }
043:
044: public Palette(String filename) {
045: this (filename, -1);
046: }
047:
048: public Palette(String filename, int max) {
049: colors = cachedReadPalette(filename, max);
050: }
051:
052: public int size() {
053: return colors.length;
054: }
055:
056: public Object get(int index) {
057: return colors[index];
058: }
059:
060: private static Color[] cachedReadPalette(String filename, int max) {
061: if (cache == null) {
062: return readPalette(filename, max);
063: }
064: synchronized (cache) {
065: String key = filename + ":" + max;
066: Color[] ret = (Color[]) cache.get(key);
067: if (ret == null) {
068: ret = readPalette(filename, max);
069: cache.put(key, ret);
070: }
071: return ret;
072: }
073: }
074:
075: private static Color[] readPalette(String filename, int max) {
076: // check for default filename
077: String s = filename;
078: if (s == null) {
079: s = DEFAULT_FILENAME;
080: }
081:
082: List l = new ArrayList();
083: try {
084: // open stream
085: Reader reader;
086: if (s.startsWith("resource:")) {
087: s = s.substring("resource:".length());
088: InputStream in = Palette.class.getResourceAsStream(s);
089: if (in == null) {
090: throw new RuntimeException(
091: "Unable to find resource");
092: }
093: reader = new InputStreamReader(in);
094: } else {
095: reader = new FileReader(s);
096: }
097:
098: // read (RED GREEN BLUE) lines
099: BufferedReader br = new BufferedReader(reader);
100: Pattern p = Pattern
101: .compile("^(\\d+)\\s+(\\d+)\\s+(\\d+)(\\s.*)?$");
102: while (true) {
103: String line = br.readLine();
104: if (line == null) {
105: break;
106: }
107: int sep = line.indexOf('#');
108: if (sep >= 0) {
109: line = line.substring(0, sep);
110: }
111: line = line.trim();
112: if (line.length() == 0) {
113: continue;
114: }
115: Matcher m = p.matcher(line);
116: if (!m.matches()) {
117: continue;
118: }
119: int r = Integer.parseInt(m.group(1));
120: int g = Integer.parseInt(m.group(2));
121: int b = Integer.parseInt(m.group(3));
122: l.add(new Color(r, g, b));
123: }
124: } catch (Exception e) {
125: System.err.println("Unable to read " + s + ": " + e);
126: }
127:
128: // handle empty case
129: int n = l.size();
130: if (n < 2) {
131: System.err.println("Pallete " + s + " contains " + n
132: + " colors");
133: l.clear();
134: l.add(Color.BLACK);
135: l.add(Color.WHITE);
136: n = l.size();
137: }
138:
139: // resize to match max-length, convert to array
140: int m = (max < 0 ? l.size() - 1 : max);
141: Color[] ret = new Color[m + 1];
142: if ((m + 1) == n) {
143: ret = (Color[]) l.toArray(ret);
144: } else {
145: double d = ((double) n / (m + 1));
146: for (int j = 0; j <= m; j++) {
147: int k = (int) ((double) j * d);
148: ret[j] = (Color) l.get(k);
149: }
150: }
151:
152: return ret;
153: }
154: }
|