/* * TIFFWriter.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.util; /** * @author Marc A. Suchard * @author Liya Thomas -- most code taken from Liya's November 2001 free source code */ //import java.awt.*; import dr.geo.color.ChannelColorScheme; import dr.geo.color.ColorScheme; import java.awt.image.BufferedImage; import java.io.DataOutputStream; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; //import java.awt.image.IndexColorModel; public class TIFFWriter { public static final short MAXROWS = 6000; // maximum # of rows public static final short MAXCOLUMNS = 3000; // maximum # of columns public static void writeDoubleArray(String fileName, double[][] inputImageInt) { writeDoubleArray(fileName, inputImageInt, "png", ColorScheme.HEATMAP); } public static void writeDoubleArrayMultiChannel(String fileName, List<double[][]> inputImageIntList, String format, ChannelColorScheme scheme) { // Get size, assumes the same for all matrix in list int dim1 = inputImageIntList.get(0).length; int dim2 = (inputImageIntList.get(0))[0].length; BufferedImage image = new BufferedImage(dim1, dim2, BufferedImage.TYPE_INT_ARGB); List<Double> max = new ArrayList<Double>(); List<Double> min = new ArrayList<Double>(); final int channels = inputImageIntList.size(); for (int c = 0; c < channels; ++c) { double[][] inputImageInt = inputImageIntList.get(c); double tmax = Double.NEGATIVE_INFINITY; double tmin = Double.POSITIVE_INFINITY; for (int i = 0; i < dim1; ++i) { for (int j = 0; j < dim2; ++j) { double value = inputImageInt[i][j]; if (value > tmax) tmax = value; else if (value < tmin) tmin = value; } } max.add(tmax); min.add(tmin); } for (int i = 0; i < dim1; ++i) { for (int j = 0; j < dim2; ++j) { List<Double> input = new ArrayList<Double>(); for (int c = 0; c < channels; ++c) { double value = (inputImageIntList.get(c))[i][j]; input.add(value); } image.setRGB(i, j, scheme.getColor(input, min, max).getRGB()); } } try { javax.imageio.ImageIO.write(image, format, new File(fileName)); } catch (IOException e) { e.printStackTrace(); } } public static void writeDoubleArray(String fileName, double[][] inputImageInt, String format, ColorScheme scheme) { BufferedImage image = new BufferedImage(inputImageInt.length, inputImageInt[0].length, BufferedImage.TYPE_INT_ARGB); double max = Double.NEGATIVE_INFINITY; double min = Double.POSITIVE_INFINITY; for (int i = 0; i < inputImageInt.length; ++i) { for (int j = 0; j < inputImageInt[i].length; ++j) { double value = inputImageInt[i][j]; if (value > max) max = value; else if (value < min) min = value; } } for (int i = 0; i < inputImageInt.length; ++i) { for (int j = 0; j < inputImageInt[i].length; ++j) { double value = inputImageInt[i][j]; image.setRGB(i, j, scheme.getColor(value, min, max).getRGB()); } } try { javax.imageio.ImageIO.write(image, format, new File(fileName)); } catch (IOException e) { e.printStackTrace(); } } // public static double getRampValue(double input, double min, double max) { // double end = 1.0 / 6.0; // double start = 0.0; // return (input - min) / (max - min) * (end - start); // } // public static Color getColor(double input, double min, double max) { // float hue = (float) getRampValue(input, min, max); // float saturation = 0.85f; // float alpha = 1.0f; // return Color.getHSBColor(hue, saturation, alpha); // } // Create TIFF image of integer array public static void writeDoubleArray( DataOutputStream dataOut, double[][] inputImageInt) { final int rows = inputImageInt.length; final int columns = inputImageInt[0].length; if (rows < 0 || rows > MAXROWS || columns < 0 || columns > MAXCOLUMNS) throw new RuntimeException("Invalid # rows and # columns"); // offset to the end of data (gray values) in file int pos = 8 + rows * columns; try { /* * Write the header */ short i, j; i = (short) 'I'; j = (short) (i * 256 + i); fputword(dataOut, j); fputword(dataOut, (short) 42); fputlong(dataOut, pos); /* * Write the bitmap */ for (i = 0; i < rows; i++) for (j = 0; j < columns; j++) { int datum = (int) inputImageInt[i][j]; dataOut.writeByte((byte) datum); } /* * Write the tags */ fputword(dataOut, (short) 8); // # of tags writetiftag(dataOut, SubFileType, TIFFshort, 1, 1); writetiftag(dataOut, ImageWidth, TIFFshort, 1, columns); writetiftag(dataOut, ImageLength, TIFFshort, 1, rows); writetiftag(dataOut, BitsPerSample, TIFFshort, 1, 8); writetiftag(dataOut, Compression, TIFFshort, 1, 1); writetiftag(dataOut, PhotoMetricInterp, TIFFshort, 1, 1); // for gray values only writetiftag(dataOut, StripOffsets, TIFFlong, 1, 8); // beginning of image data writetiftag(dataOut, PlanarConfiguration, TIFFshort, 1, 1); fputlong(dataOut, 0); } catch (java.io.IOException read) { System.out.println("Error occured while writing output file."); } } /* * write one TIFF tag to the IFD */ static void writetiftag(DataOutputStream dataOut, short tag, short type, int length, int offset) { fputword(dataOut, tag); fputword(dataOut, type); fputlong(dataOut, length); fputlong(dataOut, offset); } /* writetiftag */ /* * function: fputword */ static void fputword(DataOutputStream dataOut, short n) { try { dataOut.writeByte((byte) n); dataOut.writeByte((byte) (n >> 8)); } catch (java.io.IOException read) { System.out.println("Error occured while writing output file."); } } /* fputword */ /* * function: fputlong */ static void fputlong(DataOutputStream dataOut, int n) { try { dataOut.writeByte((byte) n); dataOut.writeByte((byte) (n >> 8)); dataOut.writeByte((byte) (n >> 16)); dataOut.writeByte((byte) (n >> 24)); } catch (java.io.IOException read) { System.out.println("Error occured while writing output file."); } } /* fputlong */ public static final short GOOD_WRITE = 0; public static final short BAD_WRITE = 1; public static final short BAD_READ = 2; public static final short MEMORY_ERROR = 3; public static final short WRONG_BITS = 4; public static final short RGB_RED = 0; public static final short RGB_GREEN = 1; public static final short RGB_BLUE = 2; public static final short RGB_SIZE = 3; /* * TIFF object sizes */ public static final short TIFFbyte = 1; public static final short TIFFascii = 2; public static final short TIFFshort = 3; public static final short TIFFlong = 4; public static final short TIFFrational = 5; /* * TIFF tag names */ public static final short NewSubFile = 254; public static final short SubFileType = 255; public static final short ImageWidth = 256; public static final short ImageLength = 257; public static final short RowsPerStrip = 278; public static final short StripOffsets = 273; public static final short StripByteCounts = 279; public static final short SamplesPerPixel = 277; public static final short BitsPerSample = 258; public static final short Compression = 259; public static final short PlanarConfiguration = 284; public static final short Group3Options = 292; public static final short Group4Options = 293; public static final short FillOrder = 266; public static final short Threshholding = 263; public static final short CellWidth = 264; public static final short CellLength = 265; public static final short MinSampleValue = 280; public static final short MaxSampleValue = 281; public static final short PhotoMetricInterp = 262; public static final short GrayResponseUnit = 290; public static final short GrayResponseCurve = 291; public static final short ColorResponseUnit = 300; public static final short ColorResponseCurves = 301; public static final short XResolution = 282; public static final short YResolution = 283; public static final short ResolutionUnit = 296; public static final short Orientation = 274; public static final short DocumentName = 269; public static final short PageName = 285; public static final short XPosition = 286; public static final short YPosition = 287; public static final short PageNumber = 297; public static final short ImageDescription = 270; public static final short Make = 271; public static final short Model = 272; public static final short FreeOffsets = 288; public static final short FreeByteCounts = 289; public static final short ColorMap = 320; public static final short Artist = 315; public static final short DateTime = 306; public static final short HostComputer = 316; public static final short Software = 305; }