import java.io.*; import java.util.*; /** * This class generates a Mandelbrot fractal and outputs to an XPM. * The fractal is an escape map. Each pixel in the map array corresponds * with a coordinate (on the complex plane). * *
 * Copyright (c) 1997 Jon Lin 
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in
 * supporting documentation.
 *
 * This file is provided AS IS with no warranties of any kind.  The author
 * shall have no liability with respect to the infringement of copyrights,
 * trade secrets or any patents by this file or any part thereof.  In no
 * event will the author be liable for any lost revenue or profits or
 * other special, indirect and consequential damages.
 * 
* * @author jonlin@tesuji.org */ public class MandelbrotGenerator { // Cache for the mapping of colors to letters private static String[] letters; // constants for sweeping variations public static final int LINEAR_SWEEP = 0; public static final int LOG_SWEEP = 1; public static final int EXP_SWEEP = 2; // constants for bailout test variations public static final int ZMAG_TEST = 0; public static final int REAL_TEST = 1; public static final int IMAG_TEST = 2; public static final int ABS_TEST = 3; // flags for various sweeping boolean sweep_X_coef = false; boolean sweep_Y_coef = false; boolean sweep_X_shift = false; boolean sweep_Y_shift = false; boolean sweep_X_perturb = false; boolean sweep_Y_perturb = false; boolean zoom = false; boolean random_zoom = false; // vars used for coef sweeping. int coef_sweep = 0; double x_coef_sweep_value = 0; double y_coef_sweep_value = 0; int x_coef_sweep_period = 1; int y_coef_sweep_period = 1; // vars used for shift sweeping. int shift_sweep = 0; double x_shift_sweep_value = 0; double y_shift_sweep_value = 0; int x_shift_sweep_period = 1; int y_shift_sweep_period = 1; // vars used for perturn sweeping. int perturb_sweep = 0; double x_perturb_sweep_value = 0; double y_perturb_sweep_value = 0; int x_perturb_sweep_period = 1; int y_perturb_sweep_period = 1; // vars used for zooming. int start_x_zoom_value = 0; int start_y_zoom_value = 0; int start_x_zoom_period = 1; int start_y_zoom_period = 1; int end_x_zoom_value = 0; int end_y_zoom_value = 0; int end_x_zoom_period = 1; int end_y_zoom_period = 1; int x_zoom_shift = 0; int y_zoom_shift = 0; int x_zoom_shift_period = 1; int y_zoom_shift_period = 1; int x_zoom_limit = -1; int y_zoom_limit = -1; double x_zoom_limit_point = -1; double y_zoom_limit_point = -1; double x_zoom_limit_error = -1; double y_zoom_limit_error = -1; // vars used for generating. double start_x = -2; double end_x = 2; double start_y = -2; double end_y = 2; double x_coef = 0; double y_coef = 0; double x_perturb = 0; double y_perturb = 0; double x_shift = 30; double y_shift = 0; double bailout = 16; static int bailout_test = 0; int max_iter = 150; int width = 640; int height = 480; int num_frames = 1; int frame_offset = 0; int frame_count = 0; int num_colors; String[] colorMap = null; String colorMapFile = null; String outputPrefix = "mandel"; // random number generator for Random zooming. Random rand; public MandelbrotGenerator(String[] args) { // First thing, parse the arguments. parseArgs(args); rand = new Random(); // Make the color map to use. colorMap = makeColorMap(colorMapFile,num_colors); // This is the array which stores all the escape values. int[][] map = new int[width][height]; // This loop continually generates and changes the parameters for(int x=0;x-1) && (y_zoom_limit>-1)) { zoomRandom(); zoomLimit(); } else { zoomRandom(); } } else if(zoom) { if((x_zoom_limit>-1) && (y_zoom_limit>-1)) { zoomLinear(); zoomLimit(); } else { zoomLinear(); zoomShift(); } } // Change parameters for coef sweep if(coef_sweep == LINEAR_SWEEP) { sweepCoefLinear(); } else if(coef_sweep == LOG_SWEEP) { sweepCoefLogrithmic(); } else if(coef_sweep == EXP_SWEEP) { sweepCoefExponential(); } // Change parameters for shift sweep if(shift_sweep == LINEAR_SWEEP) { sweepShiftLinear(); } else if(shift_sweep == LOG_SWEEP) { sweepShiftLogrithmic(); } else if(shift_sweep == EXP_SWEEP) { sweepShiftExponential(); } // Change parameters for perturb sweep if(perturb_sweep == LINEAR_SWEEP) { sweepPerturbLinear(); } else if(perturb_sweep == LOG_SWEEP) { sweepPerturbLogrithmic(); } else if(perturb_sweep == EXP_SWEEP) { sweepPerturbExponential(); } } System.exit(1); } /** * shrinks the bounding box (start_x, start_y),(end_x, end_y) * according to the zooming parameters. */ public void zoomLinear() { double x_unit = (end_x - start_x)/width; double y_unit = (end_y - start_y)/height; if((frame_count % start_x_zoom_period)==0) { start_x = start_x + (x_unit * start_x_zoom_value); } if((frame_count % end_x_zoom_period)==0) { end_x = end_x - (x_unit * end_x_zoom_value); } if((frame_count % start_y_zoom_period)==0) { start_y = start_y + (y_unit * start_y_zoom_value); } if((frame_count % end_y_zoom_period)==0) { end_y = end_y - (y_unit * end_y_zoom_value); } } /** * shifts the bounding box (start_x, start_y),(end_x, end_y) * accoring to the shifting parameters. */ public void zoomShift() { double x_unit = (end_x - start_x)/width; double y_unit = (end_y - start_y)/height; if((frame_count % x_zoom_shift_period)==0) { start_x = start_x + (x_unit * x_zoom_shift); end_x = end_x + (x_unit * x_zoom_shift); } if((frame_count % y_zoom_shift_period)==0) { start_y = start_y + (y_unit * y_zoom_shift); end_y = end_y + (y_unit * y_zoom_shift); } } /** * shifts the bounding box (start_x, start_y),(end_x, end_y) * according to the zoom limit. The center of the bounding box * approaches the zoom limit parameters. */ public void zoomLimit() { // First find the units per pixel double x_unit = (end_x - start_x)/width; double y_unit = (end_y - start_y)/height; // Then the center coordinates of the current map double x_center = (x_unit*width)/2 + start_x; double y_center = (y_unit*height)/2 + start_y; // Then the lengths from the center to the zoom limit double x_length = Math.abs(x_zoom_limit_point - x_center); double y_length = Math.abs(y_zoom_limit_point - y_center); // If the length is smaller than the limit error, bail. if((x_length < x_zoom_limit_error) && (y_length < y_zoom_limit_error)) { print("Reached zoom limit! Exiting."); System.exit(0); } // These are the x,y lengths to shift. double x_shift = 20*x_unit; double y_shift = 20*y_unit; // If the zoom shift parameters are used, reset the lengths to the parameters if(x_zoom_shift>0) { x_shift = Math.abs(x_zoom_shift)*x_unit; } if(y_zoom_shift>0) { y_shift = Math.abs(y_zoom_shift)*y_unit; } // If the shift exceeds the distance to the limit point, just shift by the distance if(x_shift > x_length) { x_shift = x_length; } if(y_shift > y_length) { y_shift = y_length; } // scale the shift according to the incident angle of the limit point if(x_length>=y_length) { y_shift = (y_length*x_shift)/x_length; } else { x_shift = (x_length*y_shift)/y_length; } // Shift the bounding box if(x_center > x_zoom_limit_point) { start_x = start_x - (x_shift); end_x = end_x - (x_shift); } else { start_x = start_x + (x_shift); end_x = end_x + (x_shift); } if(y_center > y_zoom_limit_point) { start_y = start_y - (y_shift); end_y = end_y - (y_shift); } else { start_y = start_y + (y_shift); end_y = end_y + (y_shift); } } /** * shrinks and shifts the bounding box (start_x, start_y),(end_x, end_y) * according to the bounds set by the zoom parameters. */ public void zoomRandom() { double x_unit = (end_x - start_x)/width; double y_unit = (end_y - start_y)/height; int tmp_start_x_zoom = Math.abs(rand.nextInt()%start_x_zoom_value); int tmp_end_x_zoom = Math.abs(rand.nextInt()%end_x_zoom_value); int tmp_start_y_zoom = Math.abs(rand.nextInt()%start_y_zoom_value); int tmp_end_y_zoom = Math.abs(rand.nextInt()%end_y_zoom_value); if((frame_count % start_x_zoom_period)==0) { start_x = start_x + (x_unit * tmp_start_x_zoom); } if((frame_count % end_x_zoom_period)==0) { end_x = end_x - (x_unit * tmp_end_x_zoom); } if((frame_count % start_y_zoom_period)==0) { start_y = start_y + (y_unit * tmp_start_y_zoom); } if((frame_count % end_y_zoom_period)==0) { end_y = end_y - (y_unit * tmp_end_y_zoom); } if((x_zoom_limit==-1) && (y_zoom_limit==-1)) { x_unit = (end_x - start_x)/width; y_unit = (end_y - start_y)/height; int tmp_x_shift = Math.abs(rand.nextInt()%x_zoom_shift); int tmp_y_shift = Math.abs(rand.nextInt()%y_zoom_shift); if((frame_count % x_zoom_shift_period)==0) { start_x = start_x + (x_unit * tmp_x_shift); end_x = end_x + (x_unit * tmp_x_shift); } if((frame_count % y_zoom_shift_period)==0) { start_y = start_y + (y_unit * tmp_y_shift); end_y = end_y + (y_unit * tmp_y_shift); } } } /** * Sweeps the coef vector linearly according to the coef sweep parameters. */ public void sweepCoefLinear() { if(sweep_X_coef && ((frame_count % x_coef_sweep_period)==0)) { x_coef = x_coef + x_coef_sweep_value; } if(sweep_Y_coef && ((frame_count % y_coef_sweep_period)==0)) { y_coef = y_coef + y_coef_sweep_value; } } /** * Sweeps the coef vector logrithmicly according to the coef sweep parameters. */ public void sweepCoefLogrithmic() { if(sweep_X_coef && ((frame_count % x_coef_sweep_period)==0)) { x_coef = (x_coef + x_coef_sweep_value) / 2; } if(sweep_Y_coef && ((frame_count % y_coef_sweep_period)==0)) { y_coef = (y_coef + y_coef_sweep_value) / 2; } } /** * Sweeps the coef vector exponentially according to the coef sweep parameters. */ public void sweepCoefExponential() { if(sweep_X_coef && ((frame_count % x_coef_sweep_period)==0)) { x_coef = (2 * x_coef) - x_coef_sweep_value; } if(sweep_Y_coef && ((frame_count % y_coef_sweep_period)==0)) { y_coef = (2 * y_coef) - y_coef_sweep_value; } } /** * Sweeps the shift vector linearly according to the shift sweep parameters. */ public void sweepShiftLinear() { if(sweep_X_shift && ((frame_count % x_shift_sweep_period)==0)) { x_shift = x_shift + x_shift_sweep_value; } if(sweep_Y_shift && ((frame_count % y_shift_sweep_period)==0)) { y_shift = y_shift + y_shift_sweep_value; } } /** * Sweeps the shift vector logrithmicly according to the shift sweep parameters. */ public void sweepShiftLogrithmic() { if(sweep_X_shift && ((frame_count % x_shift_sweep_period)==0)) { x_shift = (x_shift + x_shift_sweep_value) / 2; } if(sweep_Y_shift && ((frame_count % y_shift_sweep_period)==0)) { y_shift = (y_shift + y_shift_sweep_value) / 2; } } /** * Sweeps the shift vector exponentially according to the shift sweep parameters. */ public void sweepShiftExponential() { if(sweep_X_shift && ((frame_count % x_shift_sweep_period)==0)) { x_shift = (2 * x_shift) - x_shift_sweep_value; } if(sweep_Y_shift && ((frame_count % y_shift_sweep_period)==0)) { y_shift = (2 * y_shift) - y_shift_sweep_value; } } /** * Sweeps the perturb vector linearly according to the perturb sweep parameters. */ public void sweepPerturbLinear() { if(sweep_X_perturb && ((frame_count % x_perturb_sweep_period)==0)) { x_perturb = x_perturb + x_perturb_sweep_value; } if(sweep_Y_perturb && ((frame_count % y_perturb_sweep_period)==0)) { y_perturb = y_perturb + y_perturb_sweep_value; } } /** * Sweeps the perturb vector logrithmically according to the perturb sweep parameters. */ public void sweepPerturbLogrithmic() { if(sweep_X_perturb && ((frame_count % x_perturb_sweep_period)==0)) { x_perturb = (x_perturb + x_perturb_sweep_value) / 2; } if(sweep_Y_perturb && ((frame_count % y_perturb_sweep_period)==0)) { y_perturb = (y_perturb + y_perturb_sweep_value) / 2; } } /** * Sweeps the perturb vector exponentially according to the perturb sweep parameters. */ public void sweepPerturbExponential() { if(sweep_X_perturb && ((frame_count % x_perturb_sweep_period)==0)) { x_perturb = (2 * x_perturb) - x_perturb_sweep_value; } if(sweep_Y_perturb && ((frame_count % y_perturb_sweep_period)==0)) { y_perturb = (2 * y_perturb) - y_perturb_sweep_value; } } /** * This method parses the arguments passed to the MandelbrotGenerator. * These arguments determine what this class will do. */ public void parseArgs(String[] args) { try { // First, read in the required parameters width = Integer.parseInt(args[0]); height = Integer.parseInt(args[1]); colorMapFile = args[2]; num_colors = Integer.parseInt(args[3]); // if there are more arguments (the options), parse them if(args.length>4) { for(int x=4;x#####.xpm'."); print(" "); print(" -num_frames The number of frames to generate. Each frame will undergo "); print(" the specified zoom, shift, and sweeps."); print(" -outputPrefix The filename prefix of the output file(s)."); print(" -frame_offset The offset to start the output file numbering."); print(" "); } else { print("Valid help options are: "); print(" bounding_box, fractal_params, iter_params, zooming, sweeping, output_params"); } System.exit(2); } } } } } catch(Exception e) { print("Error: "+e); e.printStackTrace(); print("Usage: MandelbrotGenerator [x_size] [y_size] [colorMapFile] [num_colors] "); print(" -start_x [double]"); print(" -start_y [double]"); print(" -end_x [double]"); print(" -end_y [double]"); print(" -x_coef [double]"); print(" -y_coef [double]"); print(" -x_shift [double]"); print(" -y_shift [double]"); print(" -x_perturb [double]"); print(" -y_perturb [double]"); print(" -bailout [double]"); print(" -bailout_test [0|1|2|3] (zmag,real,imag,abs)"); print(" -max_iter [integer]"); print(" -num_frames [integer]"); print(" -outputPrefix [filename]"); print(" -frame_offset [integer]"); print(" -coef_sweep_type [0|1|2] (linear,log,exp)"); print(" -sweep_x_coef "); print(" -sweep_y_coef "); print(" -x_coef_sweep_value [double]"); print(" -y_coef_sweep_value [double]"); print(" -x_coef_sweep_period [integer]"); print(" -y_coef_sweep_period [integer]"); print(" -shift_sweep_type [0|1|2] (linear,log,exp)"); print(" -sweep_x_shift "); print(" -sweep_y_shift "); print(" -x_shift_sweep_value [double]"); print(" -y_shift_sweep_value [double]"); print(" -x_shift_sweep_period [integer]"); print(" -y_shift_sweep_period [integer]"); print(" -perturb_sweep_type [0|1|2] (linear,log,exp)"); print(" -sweep_x_perturb "); print(" -sweep_y_perturb "); print(" -x_perturb_sweep_value [double]"); print(" -y_perturb_sweep_value [double]"); print(" -x_perturb_sweep_period [integer]"); print(" -y_perturb_sweep_period [integer]"); print(" -zoom "); print(" -random_zoom"); print(" -start_x_zoom_value [integer] (pixels)"); print(" -start_y_zoom_value [integer] (pixels)"); print(" -end_x_zoom_value [integer] (pixels)"); print(" -end_y_zoom_value [integer] (pixels)"); print(" -x_zoom_shift [integer] (pixels)"); print(" -y_zoom_shift [integer] (pixels)"); print(" -start_x_zoom_period [integer]"); print(" -start_y_zoom_period [integer]"); print(" -end_x_zoom_period [integer]"); print(" -end_y_zoom_period [integer]"); print(" -x_zoom_shift_period [integer]"); print(" -y_zoom_shift_period [integer]"); print(" -zoom_limit [integer] [integer] (x y) (pixels)"); print(" -help "); System.exit(-1); } // If zooming to a limit, calculate the initial zoom limit parameters if((x_zoom_limit>-1) && (y_zoom_limit>-1)) { x_zoom_limit_error = (end_x - start_x)/width; y_zoom_limit_error = (end_y - start_y)/height; x_zoom_limit_point = ((x_zoom_limit_error)*x_zoom_limit) + start_x; y_zoom_limit_point = ((y_zoom_limit_error)*y_zoom_limit) + start_y; } System.out.println(printStatus()); } /** * This method returns a status String. */ public String printStatus() { StringBuffer rval = new StringBuffer(); rval.append(" Image size: "+width+" x "+height+", color map: "+colorMapFile+" ("+num_colors+")\n"); if(bailout_test==REAL_TEST) { rval.append(" Maximum number of iterations: "+max_iter+", Bailout value: "+bailout+" (x*x)\n"); } else if(bailout_test==IMAG_TEST) { rval.append(" Maximum number of iterations: "+max_iter+", Bailout value: "+bailout+" (y*y)\n"); } else if(bailout_test==ABS_TEST) { rval.append(" Maximum number of iterations: "+max_iter+", Bailout value: "+bailout+" (|x|+|y|)\n"); } else { rval.append(" Maximum number of iterations: "+max_iter+", Bailout value: "+bailout+" ((x*x)+(y*y))\n"); } rval.append(" Bounding box: ("+start_x+","+start_y+") , ("+end_x+","+end_y+")\n"); rval.append(" Coeficient vector: ["+x_coef+","+y_coef+"]\n"); rval.append(" Shift vector: ["+x_shift+","+y_shift+"]\n"); rval.append(" Perturb vector: ["+x_perturb+","+y_perturb+"]\n"); if(random_zoom) { rval.append(" Random zooming and shifting (bounded by given values)\n"); } else if(zoom) { rval.append(" Zooming and shifting\n"); } if(random_zoom||zoom) { rval.append(" Bounding box shrink (pixels): +("+start_x_zoom_value+","+start_y_zoom_value+") , -("+end_x_zoom_value+","+end_y_zoom_value+") \n"); rval.append(" Bounding box shift (pixels): ("+x_zoom_shift+","+y_zoom_shift+")\n"); if((x_zoom_limit>-1) && (y_zoom_limit>-1)) { rval.append(" Zoom approaches the point ("+x_zoom_limit_point+","+y_zoom_limit_point+") +/- ("+x_zoom_limit_error+","+y_zoom_limit_error+")\n"); } } if(sweep_X_coef || sweep_Y_coef) { rval.append(" Sweeping coeficient vector "); if(coef_sweep==LINEAR_SWEEP) { rval.append("linearly "); } else if(coef_sweep==LOG_SWEEP) { rval.append("logrithmically "); } else if(coef_sweep==EXP_SWEEP) { rval.append("exponentially "); } rval.append("by ("+x_coef_sweep_value+","+y_coef_sweep_value+")\n"); } if(sweep_X_shift || sweep_Y_shift) { rval.append(" Sweeping shift vector "); if(shift_sweep==LINEAR_SWEEP) { rval.append("linearly "); } else if(shift_sweep==LOG_SWEEP) { rval.append("logrithmically "); } else if(shift_sweep==EXP_SWEEP) { rval.append("exponentially "); } rval.append("by ("+x_shift_sweep_value+","+y_shift_sweep_value+")\n"); } if(sweep_X_perturb || sweep_Y_perturb) { rval.append(" Sweeping perturb vector "); if(perturb_sweep==LINEAR_SWEEP) { rval.append("linearly "); } else if(perturb_sweep==LOG_SWEEP) { rval.append("logrithmically "); } else if(perturb_sweep==EXP_SWEEP) { rval.append("exponentially "); } rval.append("by ("+x_perturb_sweep_value+","+y_perturb_sweep_value+")\n"); } return(rval.toString()); } /** * This method prints the XPM file. */ public void printXPM(int[][] map, int frame, String status) { String filename = outputPrefix; String number = ""+frame; while(number.length()<5) { number = "0"+number; } filename = filename+number+".xpm"; String XPM = generateXPM(filename,map,width,height,colorMap,status); print("Writing XPM: "+filename); try { File xpmFile = new File(filename); BufferedWriter writer = new BufferedWriter(new FileWriter(xpmFile)); writer.write(XPM); writer.flush(); writer.close(); } catch(Exception e) { print("Error writing XPM: "+e); e.printStackTrace(); } } /** * Generates an escape map using the mandelbrot attractor. * The escape values are stored the map array. * @param map This is where the results are stored. * @param width The number of pixels on the X axis. * @param height The number of pixels on the Y axis. * @param start_x The starting X coordinate. * @param end_x The ending X coordinate. * @param start_y The starting Y coordinate. * @param end_y The ending Y coordinate. * @param x_coef The coeficient added to the X value. * @param y_coef The coeficient added to the Y value. * @param x_perturb The initial X value. * @param y_perturb The initial Y value. * @param bailout_value This is the square of the magnitude of the complex number denoting infinity. * @param max_iter This is the maximum number of iterations. */ public static void generate(int[][] map, int width, int height, double start_x, double end_x, double start_y, double end_y, double x_coef, double y_coef, double x_shift, double y_shift, double x_perturb, double y_perturb, double bailout_value, int max_iter) { double k=0; double l=0; double x=0; double y=0; double tx=0; double ty=0; double tmp_k = ((end_x-start_x) + x_coef) / width; double tmp_l = ((end_y-start_y) + y_coef) / height; double last_x_sqr = 0; double last_y_sqr = 0; // f(z) = z*z : f(x+(i)y) = ((x*x)-(y*y)-k) + (i)((2*x*y)-l) for(int q=0;q bailout_value) { map[p][q] = 1; } else { x = tx; y = ty; boolean bailed = false; for(int iteration=2; iteration <= max_iter; iteration++) { // calculate f(x+(i)y) tx = last_x_sqr - last_y_sqr - k; ty = (2 * x * y) - l; // calculate the new squares for x and y, these are cached for the next iteration last_x_sqr = tx*tx; last_y_sqr = ty*ty; if(((bailout_test==ZMAG_TEST) && ((last_x_sqr + last_y_sqr) > bailout_value)) || ((bailout_test==REAL_TEST) && (last_x_sqr > bailout_value)) || ((bailout_test==IMAG_TEST) && (last_y_sqr > bailout_value)) || ((bailout_test==ABS_TEST) && ((Math.abs(tx) + Math.abs(ty)) > bailout_value))) { map[p][q] = iteration; iteration = max_iter; bailed = true; } else { x = tx; y = ty; } } if(!bailed) { map[p][q] = 0; } } } } } public static void main(String[] args) { new MandelbrotGenerator(args); } public static void print(String s) { System.out.println("Mandelbrot: "+s); } /** * This method generates a XPM from a 2 dimensional array. The XPM is returned as a String. * @param xpmName The name of this XPM. * @param image The array of pixels representing the image. The orientation of the image is assumed to be image[x][y]. * @param width The number of columns in the image map (x size). * @param height The number of rows in the image map (y size). * @param colorMap An array of Hex color values. (i.e. #FF00AA). * @param comment The comment to include in the XPM. If null, no comment is included. * @return Returns the XPM of this image as a String. */ public static String generateXPM(String xpmName, int[][] image, int width, int height, String[] colorMap, String comment) { StringBuffer rval = new StringBuffer(); rval.append(generateHeader(xpmName, comment)); String[] colorMapping = makeColorMapping(colorMap); rval.append(generateColorMapping(width, height, colorMap, colorMapping)); rval.append("/* pixels */\n"); for(int y=0;y * 0 0 0 * 0 4 0 * 0 16 0 * * And so on. * @param filename The full pathname of the file which contains the RGB values. * @param num_colors The number of colors expected in this file. * @return Returns a String array of colors suitable for the 'generateXPM()' method. */ public static String[] makeColorMap(String filename, int num_colors) { String[] colors = new String[num_colors]; File mapFile = new File(filename); BufferedReader reader = null; try { int cIndex = 0; reader = new BufferedReader(new FileReader(mapFile)); String line = reader.readLine(); while(line!=null) { String thiscolor = "#"; for(int x=0;x<3;x++) { line = line.trim(); int end = 0; try { while(line.charAt(end++)!=' ') { ; } } catch(StringIndexOutOfBoundsException esadas) { end=line.length(); } thiscolor = thiscolor+getHexValue(Integer.parseInt(line.substring(0,end).trim())); line = line.substring(end); } colors[cIndex++] = thiscolor; line = reader.readLine(); } if(cIndex9) { if(rem==10) { rval = "A"; } else if(rem==11) { rval = "B"; } else if(rem==12) { rval = "C"; } else if(rem==13) { rval = "D"; } else if(rem==14) { rval = "E"; } else if(rem==15) { rval = "F"; } } else { rval = rem+""; } rem = decimalValue%16; decimalValue = (int)(decimalValue/16); if(decimalValue>0) { rval = "FF"; } else { if(rem>9) { if(rem==10) { rval = "A"+rval; } else if(rem==11) { rval = "B"+rval; } else if(rem==12) { rval = "C"+rval; } else if(rem==13) { rval = "D"+rval; } else if(rem==14) { rval = "E"+rval; } else if(rem==15) { rval = "F"+rval; } } else { rval = rem+rval; } } return(rval); } private static String[] makeColorMapping(String[] colorMap) { String[] mapping = new String[colorMap.length]; if(letters == null) { makeLetters(); } try { int x=0; while(true) { mapping[x]=letters[x%64]; x++; } } catch(ArrayIndexOutOfBoundsException e) {;} try { if(mapping.length>64) { try { int x=0; int z=0; while(true) { for(int y=0;y<64;y++) { mapping[x+y]=letters[z]+mapping[x+y]; } z++; x=x+64; } } catch(ArrayIndexOutOfBoundsException e) {;} } if(mapping.length>(64*64)) { try { int x=0; int z=0; while(true) { for(int y=0;y<(64*64);y++) { mapping[x+y]=letters[z]+mapping[x+y]; } z++; x=x+(64*64); } } catch(ArrayIndexOutOfBoundsException e) {;} } if(mapping.length>(64*64*64)) { try { int x=0; int z=0; while(true) { for(int y=0;y<(64*64*64);y++) { mapping[x+y]=letters[z]+mapping[x+y]; } z++; x=x+(64*64*64); } } catch(ArrayIndexOutOfBoundsException e) {;} } } catch(Exception e) {;} return(mapping); } private static String generateColorMapping(int width, int height, String[] colorMap, String[] colorMapping) { StringBuffer rval = new StringBuffer(); rval.append("/* width height num_colors chars_per_pixel */\n"); rval.append("\" "+width+" "+height+" "+colorMap.length+" "+colorMapping[0].length()+"\",\n"); rval.append("/* colors */\n"); for(int x=0;x