1402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/******************************************************************************* 2402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Copyright (c) 2000, 2009 IBM Corporation and others. 3402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * All rights reserved. This program and the accompanying materials 4402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * are made available under the terms of the Eclipse Public License v1.0 5402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * which accompanies this distribution, and is available at 6402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * http://www.eclipse.org/legal/epl-v10.html 7402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 8402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Contributors: 9402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * IBM Corporation - initial API and implementation 10402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll *******************************************************************************/ 11402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpackage org.eclipse.test.performance.ui; 12402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 13402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.BufferedOutputStream; 14402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.File; 15402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileNotFoundException; 16402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.FileOutputStream; 17402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.IOException; 18402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.io.OutputStream; 19402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.net.URL; 20402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.text.DecimalFormat; 21402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.text.NumberFormat; 22402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.Arrays; 23402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.Calendar; 24402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.Enumeration; 25402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport java.util.HashMap; 26402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 27402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.swt.SWT; 28402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.swt.graphics.Image; 29402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.swt.graphics.ImageData; 30402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.swt.graphics.ImageLoader; 31402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.swt.graphics.PaletteData; 32402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.swt.graphics.RGB; 33402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.test.internal.performance.PerformanceTestPlugin; 34402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.test.internal.performance.db.Variations; 35402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.eclipse.test.internal.performance.results.utils.Util; 36402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollimport org.osgi.framework.Bundle; 37402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 38402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 39402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic class Utils { 40402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 41402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static double STANDARD_ERROR_THRESHOLD = 0.03; // 3% 42402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static final NumberFormat PERCENT_FORMAT = NumberFormat.getPercentInstance(); 43402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static { 44402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll PERCENT_FORMAT.setMaximumFractionDigits(1); 45402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 46402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static final DecimalFormat DEVIATION_FORMAT = (DecimalFormat) NumberFormat.getPercentInstance(); 47402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static { 48402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll DEVIATION_FORMAT.setMaximumFractionDigits(1); 49402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll DEVIATION_FORMAT.setMinimumFractionDigits(1); 50402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll DEVIATION_FORMAT.setPositivePrefix("+"); 51402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll DEVIATION_FORMAT.setNegativePrefix("- "); 52402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 53402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static final DecimalFormat STDERR_FORMAT = (DecimalFormat) NumberFormat.getNumberInstance(); 54402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static { 55402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll STDERR_FORMAT.setMaximumFractionDigits(1); 56402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll STDERR_FORMAT.setMinimumFractionDigits(1); 57402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll STDERR_FORMAT.setMultiplier(100); 58402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 59402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String STANDARD_ERROR_THRESHOLD_STRING = PERCENT_FORMAT.format(STANDARD_ERROR_THRESHOLD); 60402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 61402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // Image files 62402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String UNKNOWN_IMAGE="images/Unknown.gif"; 63402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String OK_IMAGE="images/OK.gif"; 64402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String OK_IMAGE_WARN="images/OK_caution.gif"; 65402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String FAIL_IMAGE="images/FAIL.gif"; 66402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String FAIL_IMAGE_WARN="images/FAIL_caution.gif"; 67402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String FAIL_IMAGE_EXPLAINED="images/FAIL_greyed.gif"; 68402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String LIGHT="images/light.gif"; 69402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String WARNING_OBJ="images/warning_obj.gif"; 70402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 71402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // Java script files 72402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String TOOLTIP_SCRIPT = "scripts/ToolTip.js"; 73402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String TOOLTIP_STYLE = "scripts/ToolTip.css"; 74402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String FINGERPRINT_SCRIPT = "scripts/Fingerprints.js"; 75402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 76402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // Doc files 77402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String HELP = "doc/help.html"; 78402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 79402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // Status 80402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static int OK = 0; 81402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static int NAN = 0x1; 82402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static int ERR = 0x2; 83402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 84402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 85402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return <html><head><meta http-equiv="Content-Type" 86402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * content="text/html; charset=iso-8859-1"> 87402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 88402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String HTML_OPEN = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n"; 89402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 90402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 91402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Return "</html>". 92402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 93402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String HTML_CLOSE = "</html>\n"; 94402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 95402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 96402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Default style-sheet used on eclipse.org 97402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 98402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public final static String HTML_DEFAULT_CSS = "<style type=\"text/css\">" + "p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}\n" 99402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + "pre { font-family: \"Courier New\", Courier, mono; font-size: 10pt}\n" + "h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}\n" 100402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + "code { font-family: \"Courier New\", Courier, mono; font-size: 10pt}\n" + "sup { font-family: arial,helvetica,geneva; font-size: 10px}\n" 101402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + "h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}\n" + "li { font-family: arial, helvetica, geneva; font-size: 10pt}\n" 102402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + "h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}\n" 103402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + "body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}\n" 104402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + ".indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}\n" 105402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll + ".indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}\n" + "</style>\n\n"; 106402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 107402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 108402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Creates a Variations object using build id pattern, config and jvm. 109402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 110402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param buildIdPattern 111402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param config 112402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param jvm 113402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 114402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static Variations getVariations(String buildIdPattern, String config, String jvm) { 115402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll String buildIdPatterns = buildIdPattern.replace(',', '%'); 116402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll Variations variations = new Variations(); 117402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll variations.put(PerformanceTestPlugin.CONFIG, config); 118402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll variations.put(PerformanceTestPlugin.BUILD, buildIdPatterns); 119402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll variations.put("jvm", jvm); 120402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return variations; 121402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 122402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 123402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 124402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Copy all bundle files contained in the given path 125402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 126402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static void copyBundleFiles(Bundle bundle, String path, String pattern, File output) { 127402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll Enumeration imageFiles = bundle.findEntries(path, pattern, false); 128402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll while (imageFiles.hasMoreElements()) { 129402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll URL url = (URL) imageFiles.nextElement(); 130402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll try { 131402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll File outputFile = new File(output, url.getFile()); 132402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (!outputFile.getParentFile().exists()) { 133402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll outputFile.getParentFile().mkdirs(); 134402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 135402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll Util.copyStream(url.openStream(), outputFile); 136402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } catch (IOException e) { 137402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // TODO Auto-generated catch block 138402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll e.printStackTrace(); 139402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 140402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 141402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 142402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 143402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 144402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Downsample Image to 8 bit depth format so that the resulting image data 145402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * can be saved to GIF. Note. If the source image contains photo quality 146402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * content with more than 256 colours, resulting data will look very poor. 147402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 148402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static int closest(RGB[] rgbs, int n, RGB rgb) { 149402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int minDist = 256 * 256 * 3; 150402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int minIndex = 0; 151402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (int i = 0; i < n; ++i) { 152402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll RGB rgb2 = rgbs[i]; 153402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int da = rgb2.red - rgb.red; 154402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int dg = rgb2.green - rgb.green; 155402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int db = rgb2.blue - rgb.blue; 156402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int dist = da * da + dg * dg + db * db; 157402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (dist < minDist) { 158402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll minDist = dist; 159402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll minIndex = i; 160402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 161402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 162402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return minIndex; 163402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 164402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 165402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll static class ColorCounter implements Comparable { 166402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll RGB rgb; 167402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 168402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int count; 169402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 170402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public int compareTo(Object o) { 171402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return ((ColorCounter) o).count - this.count; 172402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 173402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 174402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 175402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static ImageData downSample(Image image) { 176402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ImageData data = image.getImageData(); 177402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (!data.palette.isDirect && data.depth <= 8) 178402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return data; 179402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 180402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // compute a histogram of color frequencies 181402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll HashMap freq = new HashMap(); 182402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int width = data.width; 183402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int[] pixels = new int[width]; 184402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int[] maskPixels = new int[width]; 185402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (int y = 0, height = data.height; y < height; ++y) { 186402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll data.getPixels(0, y, width, pixels, 0); 187402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (int x = 0; x < width; ++x) { 188402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll RGB rgb = data.palette.getRGB(pixels[x]); 189402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ColorCounter counter = (ColorCounter) freq.get(rgb); 190402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (counter == null) { 191402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll counter = new ColorCounter(); 192402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll counter.rgb = rgb; 193402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll freq.put(rgb, counter); 194402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 195402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll counter.count++; 196402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 197402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 198402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 199402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // sort colors by most frequently used 200402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ColorCounter[] counters = new ColorCounter[freq.size()]; 201402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll freq.values().toArray(counters); 202402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll Arrays.sort(counters); 203402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 204402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // pick the most frequently used 256 (or fewer), and make a palette 205402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ImageData mask = null; 206402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (data.transparentPixel != -1 || data.maskData != null) { 207402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll mask = data.getTransparencyMask(); 208402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 209402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int n = Math.min(256, freq.size()); 210402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll RGB[] rgbs = new RGB[n + (mask != null ? 1 : 0)]; 211402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (int i = 0; i < n; ++i) 212402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll rgbs[i] = counters[i].rgb; 213402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (mask != null) { 214402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll rgbs[rgbs.length - 1] = data.transparentPixel != -1 ? data.palette.getRGB(data.transparentPixel) : new RGB(255, 255, 255); 215402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 216402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll PaletteData palette = new PaletteData(rgbs); 217402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 218402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // create a new image using the new palette: 219402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // for each pixel in the old image, look up the best matching 220402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // index in the new palette 221402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ImageData newData = new ImageData(width, data.height, 8, palette); 222402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (mask != null) 223402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll newData.transparentPixel = rgbs.length - 1; 224402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (int y = 0, height = data.height; y < height; ++y) { 225402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll data.getPixels(0, y, width, pixels, 0); 226402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (mask != null) 227402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll mask.getPixels(0, y, width, maskPixels, 0); 228402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll for (int x = 0; x < width; ++x) { 229402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (mask != null && maskPixels[x] == 0) { 230402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll pixels[x] = rgbs.length - 1; 231402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 232402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll RGB rgb = data.palette.getRGB(pixels[x]); 233402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll pixels[x] = closest(rgbs, n, rgb); 234402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 235402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 236402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll newData.setPixels(0, y, width, pixels, 0); 237402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 238402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return newData; 239402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 240402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 241402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 242402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Returns the date/time from the build id in format yyyymmddhm 243402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 244402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param buildId 245402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return date/time in format YYYYMMDDHHMM, ie. 200504060010 246402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 247402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static long getDateFromBuildID(String buildId) { 248402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return getDateFromBuildID(buildId, false); 249402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 250402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 251402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static long getDateFromBuildID(String buildId, boolean matchLast) { 252402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll Calendar calendar = Calendar.getInstance(); 253402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 254402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (buildId.indexOf('_') != -1) { 255402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll String[] buildIdParts = buildId.split("_"); 256402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 257402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int buildIdSegment = 1; 258402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (matchLast) 259402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buildIdSegment = buildIdParts.length - 1; 260402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // if release build, expect <release>_<release date and 261402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // timestamp>_<date and timestamp test ran> 262402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // use test date and time for plotting 263402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int year = Integer.parseInt(buildIdParts[buildIdSegment].substring(0, 4)); 264402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int month = Integer.parseInt(buildIdParts[buildIdSegment].substring(4, 6)) - 1; 265402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int date = Integer.parseInt(buildIdParts[buildIdSegment].substring(6, 8)); 266402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int hours = Integer.parseInt(buildIdParts[buildIdSegment].substring(8, 10)); 267402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int min = Integer.parseInt(buildIdParts[buildIdSegment].substring(10, 12)); 268402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 269402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll calendar.set(year, month, date, hours, min); 270402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return calendar.getTimeInMillis(); 271402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 272402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else if (buildId.indexOf('-') != -1) { 273402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // if regular build, expect <buildType><date>-<time> format 274402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll String[] buildIdParts = buildId.split("-"); 275402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int year = Integer.parseInt(buildIdParts[0].substring(1, 5)); 276402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int month = Integer.parseInt(buildIdParts[0].substring(5, 7)) - 1; 277402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int date = Integer.parseInt(buildIdParts[0].substring(7, 9)); 278402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int hours = Integer.parseInt(buildIdParts[1].substring(0, 2)); 279402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int min = Integer.parseInt(buildIdParts[1].substring(2, 4)); 280402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll calendar.set(year, month, date, hours, min); 281402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 282402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return calendar.getTimeInMillis(); 283402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 284402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 285402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return -1; 286402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 287402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 288402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 289402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Returns a message corresponding to given statistics. 290402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 291402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param resultStats The value with its standard error 292402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param full 293402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return The failure message. May be empty if stats are good... 294402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 295402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static String failureMessage(double[] resultStats, boolean full) { 296402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll StringBuffer buffer = new StringBuffer(); 297402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int level = confidenceLevel(resultStats); 298402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// boolean isWarn = (level & WARN) != 0; 299402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll boolean isErr = (level & ERR) != 0; 300402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (full) { 301402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (isErr) { 302402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append("*** WARNING *** "); 303402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(Messages.bind(Messages.standardError, PERCENT_FORMAT.format(resultStats[1]), STANDARD_ERROR_THRESHOLD_STRING)); 304402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 305402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return buffer.toString(); 306402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 307402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (resultStats != null) { 308402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll double deviation = resultStats[0]; 309402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append("<font color=\"#0000FF\" size=\"1\">"); 310402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (Double.isNaN(deviation) || Double.isInfinite(deviation)) { 311402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(" [n/a]"); 312402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 313402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll double stderr = resultStats[1]; 314402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll deviation = Math.abs(deviation)<0.001 ? 0 : -deviation; 315402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (Double.isNaN(stderr) || Double.isInfinite(stderr)) { 316402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(DEVIATION_FORMAT.format(deviation)); 317402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append("</font><font color=\"#DDDD00\" size=\"1\"> "); 318402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(" [n/a]"); 319402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 320402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(DEVIATION_FORMAT.format(deviation)); 321402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(" [±"); 322402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(STDERR_FORMAT.format(Math.abs(stderr))); 323402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append(']'); 324402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 325402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 326402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll buffer.append("</font>"); 327402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 328402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return buffer.toString(); 329402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 330402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 331402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 332402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Returns the confidence level for given statistics: 333402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * <ul> 334402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * <li>{@link #NAN}: if the value is infinite or not a number</li> 335402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * <li>{@link #ERR}: if the standard error is over the expected threshold ({@link #STANDARD_ERROR_THRESHOLD})</li> 336402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * <li>{@link #OK}: in all other cases</li> 337402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * </ul> 338402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 339402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param resultStats array of 2 doubles, the former is the average value and 340402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * the latter is the standard error made while computing the average. 341402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return a value telling caller the level of confidence of the provided value 342402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 343402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static int confidenceLevel(double[] resultStats) { 344402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll int level = OK; 345402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (resultStats != null){ 346402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (Double.isNaN(resultStats[0]) || Double.isInfinite(resultStats[0])) { 347402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll level = NAN; 348402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 349402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// if (resultStats[1] >= (STANDARD_ERROR_THRESHOLD/2)) { // warns standard error higher than the half of authorized threshold 350402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// level |= WARN; 351402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll// } 352402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (resultStats[1] >= STANDARD_ERROR_THRESHOLD) { // standard error higher than the authorized threshold 353402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll level = ERR; 354402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 355402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 356402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 357402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return level; 358402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 359402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 360402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll /** 361402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * Get an icon image corresponding to a given level of confidence and explanation. 362402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * 363402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param confidence the confiden level 364402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param hasExplanation flags indicates whether the confidence may be tempered by an explanation 365402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @return Corresponding image 366402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 367402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll public static String getImage(int confidence, boolean scenarioFailed, boolean hasExplanation) { 368402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll String image = null; 369402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 370402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (scenarioFailed) { 371402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (hasExplanation) { 372402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image = FAIL_IMAGE_EXPLAINED; 373402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else if ((confidence & ERR) != 0) { 374402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image = FAIL_IMAGE_WARN; 375402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 376402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image = FAIL_IMAGE; 377402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 378402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else if ((confidence & NAN) != 0) { 379402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image = UNKNOWN_IMAGE; 380402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else if ((confidence & ERR) != 0) { 381402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image = OK_IMAGE_WARN; 382402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } else { 383402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image = OK_IMAGE; 384402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 385402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll return image; 386402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 387402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 388402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll/** 389402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param outputFile 390402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll * @param image 391402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll */ 392402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Mollpublic static void saveImage(File outputFile, Image image) { 393402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // Save image 394402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ImageData data = downSample(image); 395402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll ImageLoader imageLoader = new ImageLoader(); 396402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll imageLoader.data = new ImageData[] { data }; 397402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 398402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll OutputStream out = null; 399402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll try { 400402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll out = new BufferedOutputStream(new FileOutputStream(outputFile)); 401402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll imageLoader.save(out, SWT.IMAGE_GIF); 402402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } catch (FileNotFoundException e) { 403402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll e.printStackTrace(); 404402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } finally { 405402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll image.dispose(); 406402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll if (out != null) { 407402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll try { 408402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll out.close(); 409402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } catch (IOException e1) { 410402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll // silently ignored 411402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 412402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 413402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll } 414402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll} 415402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll 416402794e73aed8611d62eb4b01cd155e2d76fcb87Raphael Moll}