9 added files
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N CompareImages.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ CompareImages.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,93 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.contrib.Partridge.CDMS;
+
+import org.freehep.math.minuit.FCNBase;
+
+/**
+ *
+ * @author richp
+ */
+public class CompareImages implements FCNBase {
+
+ private Image _test;
+ private Image _ref;
+ private Image _dif;
+ private int _height;
+ private int _width;
+ private double _eps = 1.e-6;
+ private int _calls = 0;
+ private WriteBMP _writer = new WriteBMP();
+
+ public CompareImages(Image test, Image ref) {
+ _test = test;
+ _ref = ref;
+ _height = ref.getHeight();
+ _width = ref.getWidth();
+
+ // Check that the images are the same size
+ if (test.getHeight() != _height ||
+ test.getWidth() != _width) {
+ throw new RuntimeException("Images are different size");
+ }
+ }
+
+ public double valueOf(double[] args) {
+
+ // Get the variables we are minimizing
+ double hoffset = args[0];
+ double voffset = args[1];
+ double rotang = args[2];
+ int border = (int) Math.round(args[3]);
+
+ _calls++;
+
+ // Setup pixel arrays for the reference image and the test image
+ PixelArray refpix = new PixelArray(0., 0., 0., 1., _width, _height);
+ PixelArray testpix = new PixelArray(hoffset, voffset, rotang, 1., _width, _height);
+
+ // Setup the pixel interpolation
+ InterpolatePixelIntensity interpolate = new InterpolatePixelIntensity(_ref, refpix, testpix);
+
+ double chisq = 0.;
+// _dif = new Image(_height - 2 * _border, _width - 2 * _border);
+
+ // Loop over pixels in the test image, leaving off the border pixels that might not
+ // have corresponding reference pixels
+ for (int row = border; row < _height - border; row++) {
+ for (int col = border; col < _width - border; col++) {
+
+ // Find the interpolated reference intensity for this test pixel
+ int pixel = testpix.getPixel(row, col);
+ double ipred = interpolate.Interpolate(pixel);
+
+ // Compare with the intensity of the test pixel
+ double itest = _test.getIntensity(row, col);
+ chisq += (itest - ipred) * (itest - ipred);
+// int red = 0;
+// int blue = 0;
+// int green = 0;
+// if (itest > ipred) {
+// red = (int) (itest - ipred);
+// }
+// if (itest < ipred) {
+// green = (int) (ipred - itest);
+// }
+// _dif.setPixel(row - _border, col - _border, red, green, blue);
+ }
+ }
+
+// String filename = "c:/CDMS/difimage"+_calls+".bmp";
+// _writer.WriteImage(_dif, filename);
+
+ System.out.println("hoff: " + hoffset + " voff: " + voffset + " rotang: " + rotang + " chisq: " + chisq/1000.);
+ return chisq / 1000.;
+ }
+
+ public Image getImage() {
+ return _dif;
+ }
+
+}
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N Image.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Image.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,61 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.Partridge.CDMS;
+
+/**
+ *
+ * @author richp
+ */
+public class Image {
+
+ private int _width;
+ private int _height;
+ private int[][] _red;
+ private int[][] _green;
+ private int[][] _blue;
+
+ public Image(int width, int height) {
+
+ _width = width;
+ _height = height;
+ _red = new int[_height][_width];
+ _green = new int[_height][_width];
+ _blue = new int[_height][_width];
+ }
+
+ public void setPixel (int row, int col, int red, int green, int blue) {
+ _red[row][col] = red;
+ _green[row][col] = green;
+ _blue[row][col] = blue;
+ }
+
+ public int getWidth() {
+ return _width;
+ }
+
+ public int getHeight() {
+ return _height;
+ }
+
+ public int getRed(int row, int col) {
+ return _red[row][col];
+ }
+
+ public int getGreen(int row, int col) {
+ return _green[row][col];
+ }
+
+ public int getBlue(int row, int col) {
+ return _blue[row][col];
+ }
+
+ public double getIntensity(int row, int col) {
+ int red = _red[row][col];
+ int grn = _green[row][col];
+ int blu = _blue[row][col];
+ return Math.sqrt((red*red + grn*grn + blu*blu) / 3.);
+ }
+}
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N ImageAnalysis.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ImageAnalysis.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,96 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.io.IOException;
+import org.freehep.math.minuit.FunctionMinimum;
+import org.freehep.math.minuit.MnMigrad;
+import org.freehep.math.minuit.MnSimplex;
+import org.freehep.math.minuit.MnUserParameters;
+
+/**
+ *
+ * @author richp
+ */
+public class ImageAnalysis {
+
+ public static void main(String[] args) throws IOException {
+
+ // Set the file names of the test and reference images
+ String test_file = "c:/CDMS/ChargeDivisionUR_24-2_1.bmp";
+// String test_file = "c:/CDMS/MedLightSide.bmp";
+// String test_file = "c:/CDMS/Comparison.bmp";
+ String ref_file = "c:/CDMS/ChargeDivisionUR_23-2_1.bmp";
+
+ // Read in the image files
+ ReadBMP reader = new ReadBMP();
+ WriteBMP writer = new WriteBMP();
+ Image test = reader.ReadImage(test_file);
+ Image ref = reader.ReadImage(ref_file);
+ writer.WriteImage(ref, "c:/CDMS/testimage.bmp");
+
+ // Instantiate the image comparison class with these images
+ CompareImages comp = new CompareImages(test, ref);
+
+ MnUserParameters pars = new MnUserParameters();
+ pars.add("xoff", 0.234, 0.0, -10., 10.);
+ pars.add("yoff", 0.090, 0.0, -10., 10.);
+ pars.add("angle", 0.006, .0002, -0.05, 0.05);
+ pars.add("border", 20., 0.);
+ pars.fix(0);
+ pars.fix(1);
+ pars.fix(2);
+ pars.fix(3);
+
+ MnSimplex minimize = new MnSimplex(comp, pars);
+
+// MnMigrad minimize = new MnMigrad(comp, pars);
+
+ FunctionMinimum fcnmin = minimize.minimize();
+ MnUserParameters finalpars = fcnmin.userParameters();
+ double hoff = finalpars.value(0);
+ double voff = finalpars.value(1);
+ double rotang = finalpars.value(2);
+ int border = (int) Math.round(finalpars.value(3));
+
+ int width = test.getWidth();
+ int height = test.getHeight();
+ PixelArray testpix = new PixelArray(hoff, voff, rotang, 1., width, height);
+ PixelArray refpix = new PixelArray(0., 0., 0., 1., width, height);
+ InterpolatePixelIntensity interpolate = new InterpolatePixelIntensity(ref, refpix, testpix);
+ Image output = new Image(width - 2 * border, height - 2 * border);
+
+ for (int i=border; i<height-border; i++) {
+ for (int j=border; j<width-border; j++) {
+ double itest = test.getIntensity(i, j);
+ double iref = interpolate.Interpolate(testpix.getPixel(i, j));
+ int red = test.getRed(i, j);
+ int green = test.getGreen(i, j);
+ int blue = test.getBlue(i, j);
+ if (itest - iref > 50) {
+ red = 255;
+ green = 0;
+ blue = 0;
+ }
+ if (iref - itest > 50) {
+ red = 0;
+ green = 255;
+ blue = 0;
+ }
+ output.setPixel(i-border, j-border, red, green, blue);
+ }
+ }
+ String filename = "c:/CDMS/outputimage.bmp";
+ writer.WriteImage(output, filename);
+
+ ProcessImage process = new ProcessImage();
+ process.HistIntensity("Test Intensity", test);
+ process.HistIntensity("Reference Intensity", ref);
+ process.HistDeviations(border, testpix, test, refpix, ref);
+ process.CloseFile();
+
+ System.out.println("horiz offset: "+hoff+" vert offset: "+voff+" rot angle: "+rotang);
+ }
+}
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N InterpolatePixelIntensity.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ InterpolatePixelIntensity.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,184 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author richp
+ */
+public class InterpolatePixelIntensity {
+
+ private Image _ref;
+ private PixelArray _refpix;
+ private PixelArray _testpix;
+ private double _eps = 1.e-12;
+
+ public InterpolatePixelIntensity(Image ref, PixelArray refpix, PixelArray testpix) {
+ _ref = ref;
+ _refpix = refpix;
+ _testpix = testpix;
+ }
+
+ public double Interpolate(int pixel) {
+
+ // Find the center of the current test pixel
+ double[] testcenter = _testpix.getCenter(pixel);
+
+ // Find the reference pixel containing the center of the test pixel
+ int refcenter = _refpix.getPixel(testcenter[0], testcenter[1]);
+
+ // Get the list of reference pixels to check for overlaps
+ List<Integer> refnbrs = _refpix.getNeighbors(refcenter);
+
+ // Initialize the pixel area and weighted intensity sums
+ double totarea = 0.;
+ double intensity = 0.;
+
+ // Loop over the list of reference pixels
+ for (Integer nbr : refnbrs) {
+
+ // Create a list for vertices of the overlap region between this ref pixel and the test pixel
+ List<double[]> vertices = new ArrayList<double[]>();
+
+ // Loop over the reference pixel vertices and see if the reference vertex
+ // is inside the test pixel. If so add it to the list of vertices (don't
+ // worry about duplicate vertices - they contribute no additional polygon area
+ for (int i = 0; i < 4; i++) {
+ double[] vtx = _refpix.getVertex(i, nbr);
+ if (_testpix.Inside(pixel, vtx)) vertices.add(vtx);
+ }
+
+ // Now loop over the test pixel vertices
+ for (int i = 0; i < 4; i++) {
+ double[] vtx = _testpix.getVertex(i, pixel);
+ if (_refpix.Inside(nbr, vtx)) vertices.add(vtx);
+ }
+
+ // Finally, find any vertices produced by intersections of pixel edges
+ for (int i1=0; i1<4; i1++) {
+ int i2 = (i1 + 1) % 4;
+ double[] vt1 = _testpix.getVertex(i1, pixel);
+ double[] vt2 = _testpix.getVertex(i2, pixel);
+ for (int j1=0; j1<4; j1++) {
+ int j2 = (j1 + 1) % 4;
+ double[] vr1 = _refpix.getVertex(j1, nbr);
+ double[] vr2 = _refpix.getVertex(j2, nbr);
+ double[] vtx = findIntersection(vt1, vt2, vr1, vr2);
+ if (vtx != null) vertices.add(vtx);
+ }
+ }
+
+ // If there are no vertices, the test pixel and this reference pixel don't overlap
+ if (vertices.size() == 0) continue;
+
+ // Find the area of overlap between the test pixel and this reference neighbor pixel
+ double area = getArea(vertices);
+ totarea += area;
+
+ // Take the interpolated intensity to be the sum of the reference neighbor intensities
+ // weighted by the overlap area
+ int refrow = _refpix.getRow(nbr);
+ int refcol = _refpix.getCol(nbr);
+ intensity += area * _ref.getIntensity(refrow, refcol);
+ }
+
+ // Check to make sure the total pixel area is unity
+ if (Math.abs(totarea - 1.) > Math.sqrt(_eps)) {
+ System.out.println(" ***** Grand total area: "+totarea+" *****");
+ throw new RuntimeException("area sum error");
+ }
+
+ return intensity;
+ }
+
+ private double[] findIntersection(double[] vt1, double[] vt2, double[] vr1, double[] vr2) {
+
+ // Find the variables defining the line between vt1 and vt2
+ double a1 = vt2[1] - vt1[1];
+ double b1 = vt1[0] - vt2[0];
+ double c1 = a1 * vt1[0] + b1 * vt1[1];
+
+ // Find the variables defining the line between vr1 and vr2
+ double a2 = vr2[1] - vr1[1];
+ double b2 = vr1[0] - vr2[0];
+ double c2 = a2 * vr1[0] + b2 * vr1[1];
+
+ // Calculate the determinant, check for parallel lines
+ double det = a1 * b2 - a2 * b1;
+ if (Math.abs(det) < _eps) return null;
+
+ // Find the intersection using the determinant method
+ double x = (b2 * c1 - b1 * c2) / det;
+ double y = (a1 * c2 - a2 * c1) / det;
+
+ // Check that the x coordinate of the intersection is on the line segment
+ if (x < Math.min(vt1[0], vt2[0]) - _eps || x > Math.max(vt1[0], vt2[0]) + _eps) return null;
+ if (x < Math.min(vr1[0], vr2[0]) - _eps || x > Math.max(vr1[0], vr2[0]) + _eps) return null;
+
+ // Also check y in case the line is vertical
+ if (y < Math.min(vt1[1], vt2[1]) - _eps || y > Math.max(vt1[1], vt2[1]) + _eps) return null;
+ if (y < Math.min(vr1[1], vr2[1]) - _eps || y > Math.max(vr1[1], vr2[1]) + _eps) return null;
+
+ double[] cross = {x, y};
+ return cross;
+ }
+
+ private double getArea(List<double[]> polygon) {
+
+ // Check that we have at least 3 polygon vertices
+ int nv = polygon.size();
+ if (nv < 3) return 0.;
+
+ // Order the vertices so that adjacent vertices describe a line segment in the
+ // polygon
+ OrderVertices(polygon);
+
+ // Find the area of the polygon (see, for example, http://local.wasp.uwa.edu.au/~pbourke/geometry/polyarea/)
+ double area = 0.;
+ for (int i = 0; i < nv; i++) {
+ int j = (i + 1) % nv;
+ double[] p0 = polygon.get(i);
+ double[] p1 = polygon.get(j);
+ double darea = 0.5 * (p0[0] * p1[1] - p1[0] * p0[1]);
+ area += darea;
+ }
+ return Math.abs(area);
+ }
+
+ private double[] PseudoCentroid(List<double[]> polygon) {
+
+ // Find a point within the convex polygon by averaging the coordinates of all vertices
+ double[] pcent = {0., 0.};
+ int nv = polygon.size();
+ for (double[] point : polygon) {
+ pcent[0] += point[0] / nv;
+ pcent[1] += point[1] / nv;
+ }
+ return pcent;
+ }
+
+ private void OrderVertices(List<double[]> polygon) {
+
+ // Take as an origin a point within the polygon and order the polygon vertices according to their azimuthal angle
+ double[] pcent = PseudoCentroid(polygon);
+ int nv = polygon.size();
+ for (int i = 0; i < nv - 1; i++) {
+ for (int j = i + 1; j < nv; j++) {
+ // phi1 calcuation must stay inside loop because of possible re-ordering
+ double phi1 = Math.atan2(polygon.get(i)[1] - pcent[1], polygon.get(i)[0] - pcent[0]);
+ double phi2 = Math.atan2(polygon.get(j)[1] - pcent[1], polygon.get(j)[0] - pcent[0]);
+ if (phi1 > phi2) {
+ double[] temp = polygon.get(j);
+ polygon.set(j, polygon.get(i));
+ polygon.set(i, temp);
+ }
+ }
+ }
+ }
+}
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N PixelArray.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ PixelArray.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,146 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author richp
+ */
+public class PixelArray {
+
+ private double _x0;
+ private double _y0;
+ private double _rotang;
+ private double _size;
+ private int _nx;
+ private int _ny;
+ private double _xc;
+ private double _yc;
+ private double _u[] = new double[2];
+ private double _v[] = new double[2];
+ private double[] _xv = new double[4];
+ private double[] _yv = new double[4];
+
+ public PixelArray(double x0, double y0, double rotang, double size, int nx, int ny) {
+
+ // Save the parameters that define the pixel array
+ _x0 = x0;
+ _y0 = y0;
+ _rotang = rotang;
+ _size = size;
+ _nx = nx;
+ _ny = ny;
+
+ // Get unit vectors along the col (u) and row (v) directions
+ double cphi = Math.cos(rotang);
+ double sphi = Math.sin(rotang);
+ _u[0] = cphi;
+ _u[1] = sphi;
+ _v[0] = -sphi;
+ _v[1] = cphi;
+
+ // Find the coordinates of the LL pixel given offsets x0, y0 specified for
+ // the center pixel
+ double xll = _x0 + 0.5 * _size * (_nx * (1 - _u[0]) - _ny * _v[0]);
+ double yll = _y0 + 0.5 * _size * (_ny * (1 - _v[1]) - _nx * _u[1]);
+
+ // Find the vertices of pixel 0 whose LL corner is at the origin
+ // Vertices are stored in a clockwise direction
+ _xv[0] = xll;
+ _yv[0] = yll;
+ _xv[1] = xll + _size * _v[0];
+ _yv[1] = yll + _size * _v[1];
+ _xv[2] = xll + _size * (_u[0] + _v[0]);
+ _yv[2] = yll + _size * (_u[1] + _v[1]);
+ _xv[3] = xll + _size * _u[0];
+ _yv[3] = yll + _size * _u[1];
+
+ // Find the center
+ _xc = (_xv[0] + _xv[2]) / 2.;
+ _yc = (_yv[0] + _yv[2]) / 2.;
+ }
+
+ public double[] getCenter(int pixel) {
+ int row = getRow(pixel);
+ int col = getCol(pixel);
+ double[] center = new double[2];
+ center[0] = _xc + _size * (col * _u[0] + row * _v[0]);
+ center[1] = _yc + _size * (col * _u[1] + row * _v[1]);
+ return center;
+ }
+
+ public boolean Inside(int pixel, double[] vtx0) {
+ for (int i=0; i<4; i++) {
+ int j = (i+1) % 4;
+ double[] vtx1 = getVertex(i, pixel);
+ double[] vtx2 = getVertex(j, pixel);
+ if (twicearea(vtx1[0], vtx1[1], vtx2[0], vtx2[1], vtx0[0], vtx0[1]) < 0.) return false;
+ }
+ return true;
+ }
+
+ public double[] getVertex(int ivtx, int pixel) {
+ int row = getRow(pixel);
+ int col = getCol(pixel);
+ double[] vtx = new double[2];
+ vtx[0] = _xv[ivtx] + _size * (col * _u[0] + row * _v[0]);
+ vtx[1] = _yv[ivtx] + _size * (col * _u[1] + row * _v[1]);
+ return vtx;
+ }
+
+ public int getRow(int pixel) {
+ int row = pixel / _nx;
+ if (row < 0 || row >= _ny) throw new RuntimeException("Invalid pixel number");
+ return row;
+ }
+
+ public int getCol(int pixel) {
+ int col = pixel % _nx;
+ if (col < 0 || col >= _nx) throw new RuntimeException("Invalid pixel number");
+ return col;
+ }
+
+ public int getPixel(int row, int col) {
+ if (row < 0 || row >= _ny) throw new RuntimeException("Invalid row number");
+ if (col < 0 || col >= _nx) throw new RuntimeException("Invalid col number");
+ return row * _nx + col;
+ }
+
+ public int getPixel(double x, double y) {
+ int col = (int) Math.round(((x-_xc)*_u[0] + (y-_yc)*_u[1]) / _size);
+ int row = (int) Math.round(((x-_xc)*_v[0] + (y-_yc)*_v[1]) / _size);
+ return getPixel(row, col);
+ }
+
+ public int getNRow() {
+ return _ny;
+ }
+
+ public int getNCol() {
+ return _nx;
+ }
+
+ public List<Integer> getNeighbors(int pixel) {
+ List<Integer> nbrs = new ArrayList<Integer>();
+ int row = getRow(pixel);
+ int col = getCol(pixel);
+ for (int irow=row-1; irow<row+2; irow++) {
+ if (irow < 0 || irow >= _ny) continue;
+ for (int icol=col-1; icol<col+2; icol++) {
+ if (icol < 0 || icol > _nx) continue;
+ nbrs.add(getPixel(irow, icol));
+ }
+ }
+ return nbrs;
+ }
+
+ private double twicearea(double x1, double y1, double x2, double y2, double x3, double y3) {
+ return (x3*y2 - x2*y3) - (x3*y1 - x1*y3) + (x2*y1 - x1*y2);
+ }
+}
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N ProcessImage.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ProcessImage.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,48 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.io.IOException;
+import org.lcsim.util.aida.AIDA;
+
+/**
+ *
+ * @author richp
+ */
+public class ProcessImage {
+
+ private AIDA aida = AIDA.defaultInstance();
+
+ public ProcessImage() {
+ }
+
+ public void HistDeviations(int border, PixelArray testpix, Image test, PixelArray refpix, Image ref) {
+ InterpolatePixelIntensity interpolate = new InterpolatePixelIntensity(ref, refpix, testpix);
+ int height = test.getHeight();
+ int width = test.getWidth();
+ for (int i=border; i<height-border; i++) {
+ for (int j=border; j<width-border; j++) {
+ double itest = test.getIntensity(i, j);
+ double iref = interpolate.Interpolate(testpix.getPixel(i, j));
+ aida.histogram1D("Intensity Difference", 340, -170., 170.).fill(itest-iref);
+ aida.histogram2D("itest vs iref", 170, 0., 170., 170, 0., 170.).fill((itest), iref);
+ }
+ }
+ }
+
+ public void HistIntensity(String title, Image image) throws IOException {
+ for (int i=0; i<image.getHeight(); i++) {
+ for (int j=1; j<image.getWidth(); j++) {
+ double intensity = image.getIntensity(i, j);
+ aida.histogram1D(title, 170, 0., 170.).fill(intensity);
+ }
+ }
+ }
+
+ public void CloseFile() throws IOException {
+ aida.saveAs("c:/CDMS/intensity.aida");
+ }
+}
\ No newline at end of file
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N ReadBMP.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ReadBMP.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,82 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ *
+ * @author richp
+ */
+public class ReadBMP {
+
+ public ReadBMP() {
+ }
+
+ public Image ReadImage(String file) {
+
+ Image image;
+
+ try {
+ DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+
+ int magicnumber = getShort(in);
+ if (magicnumber != 19778)
+ throw new RuntimeException("This is not a BMP file - magic number = "+magicnumber);
+ int filesize = getInt(in);
+ int reserved1 = getShort(in);
+ int reserved2 = getShort(in);
+ int imageOffset = getInt(in);
+ int headerLength = getInt(in);
+ if (headerLength != 40) throw new RuntimeException("Unsupported header length: "+headerLength);
+ int imageWidth = getInt(in);
+ int imageHeight = getInt(in);
+ int nplane = getShort(in);
+ int pixelDepth = getShort(in);
+ int compressionType = getInt(in);
+ int imageSize = getInt(in);
+ int horres = getInt(in);
+ int vertres = getInt(in);
+ int npalate = getInt(in);
+ int nused = getInt(in);
+
+ System.out.println("Image width: " + imageWidth + " image height: " + imageHeight);
+ image = new Image(imageWidth, imageHeight);
+
+ for (int row = 0; row < imageHeight; row++) {
+ for (int col = 0; col < imageWidth; col++) {
+ int blue = in.readUnsignedByte();
+ int green = in.readUnsignedByte();
+ int red = in.readUnsignedByte();
+ int fill = in.readUnsignedByte();
+ image.setPixel(row, col, red, green, blue);
+ }
+ }
+
+ } catch(IOException e) {
+ System.out.println(e.toString());
+ return null;
+ }
+
+ return image;
+ }
+
+ private short getShort(DataInputStream in) throws IOException {
+ int low = in.readUnsignedByte();
+ int high = in.readUnsignedByte();
+ int value = low + 256 * high;
+ return (short) value;
+ }
+
+ private int getInt(DataInputStream in) throws IOException {
+ int low = getShort(in);
+ int high = getShort(in);
+ long value = low + 256*256 * high;
+ return (int) value;
+ }
+}
\ No newline at end of file
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N ReadTGA.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ReadTGA.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,87 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ *
+ * @author richp
+ */
+public class ReadTGA {
+
+ public ReadTGA() {
+ }
+
+ public Image ReadImage(String file) {
+
+ Image image;
+
+ try {
+ DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+
+ int imageIDLen = in.readUnsignedByte();
+ int colormapType = in.readUnsignedByte();
+ int imageType = in.readUnsignedByte();
+ if (imageType != 2) {
+ throw new RuntimeException("Unsupported image type: " + imageType);
+ }
+ int colormapStartingIndex = getShort(in);
+ int colormapLength = getShort(in);
+ int colormapEntrySize = in.readUnsignedByte();
+ int imageOrigin_x = getShort(in);
+ int imageOrigin_y = getShort(in);
+ int imageWidth = getShort(in);
+ int imageHeight = getShort(in);
+ int pixelDepth = in.readUnsignedByte();
+ int imageDescriptor = in.readUnsignedByte();
+
+ int[] imageID;
+ if (imageIDLen > 0) {
+ imageID = new int[imageIDLen];
+ for (int i = 0; i < imageIDLen; i++) {
+ imageID[i] = in.readUnsignedByte();
+ }
+ }
+
+ int colormapSize = colormapLength * colormapEntrySize / 8;
+ int[] colormap;
+ if (colormapSize > 0) {
+ colormap = new int[colormapSize];
+ for (int i = 0; i < colormapSize; i++) {
+ colormap[i] = in.readUnsignedByte();
+ }
+ }
+
+ System.out.println("Image width: " + imageWidth + " image height: " + imageHeight);
+ image = new Image(imageWidth, imageHeight);
+
+ for (int row = 0; row < imageHeight; row++) {
+ for (int col = 0; col < imageWidth; col++) {
+ int red = in.readUnsignedByte();
+ int green = in.readUnsignedByte();
+ int blue = in.readUnsignedByte();
+ image.setPixel(row, col, red, green, blue);
+ }
+ }
+
+ } catch(IOException e) {
+ System.out.println(e.toString());
+ return null;
+ }
+
+ return image;
+ }
+
+ private static short getShort(DataInputStream in) throws IOException {
+ int low = in.readUnsignedByte();
+ int high = in.readUnsignedByte();
+ int value = low + 256 * high;
+ return (short) value;
+ }
+}
\ No newline at end of file
lcsim-contrib/src/main/java/org/lcsim/contrib/Partridge/CDMS
diff -N WriteBMP.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ WriteBMP.java 8 Feb 2010 22:13:57 -0000 1.1
@@ -0,0 +1,91 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package org.lcsim.contrib.Partridge.CDMS;
+
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ *
+ * @author richp
+ */
+public class WriteBMP {
+
+ public WriteBMP() {
+ }
+
+ public void WriteImage(Image image, String file) {
+
+ try {
+ DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+
+ int imageWidth = image.getWidth();
+ int imageHeight = image.getHeight();
+ int headerLength = 40;
+ int imageOffset = headerLength + 14;
+ int imageSize = 4 * imageWidth * imageHeight;
+ int filesize = imageOffset + imageSize;
+ int magicnumber = 19778;
+ int reserved = 0;
+ int nplane = 1;
+ int pixelDepth = 32;
+ int compressionType = 0;
+ int horres = 3780;
+ int vertres = 3780;
+ int npalate = 0;
+ int nused = 0;
+
+ putShort(out, magicnumber);
+ putInt(out, filesize);
+ putShort(out, reserved);
+ putShort(out, reserved);
+ putInt(out, imageOffset);
+ putInt(out, headerLength);
+ putInt(out, imageWidth);
+ putInt(out, imageHeight);
+ putShort(out, nplane);
+ putShort(out, pixelDepth);
+ putInt(out, compressionType);
+ putInt(out, imageSize);
+ putInt(out, horres);
+ putInt(out, vertres);
+ putInt(out, npalate);
+ putInt(out, nused);
+
+ byte[] pixel = new byte[4];
+ for (int row = 0; row < imageHeight; row++) {
+ for (int col = 0; col < imageWidth; col++) {
+ pixel[0] = (byte) image.getBlue(row, col);
+ pixel[1] = (byte) image.getGreen(row, col);
+ pixel[2] = (byte) image.getRed(row, col);
+ pixel[3] = -1;
+ out.write(pixel);
+ }
+ }
+
+ out.close();
+
+ } catch (IOException e) {
+ System.out.println(e.toString());
+ return;
+ }
+ }
+
+ private void putShort(DataOutputStream out, int value) throws IOException {
+ byte[] data = new byte[2];
+ data[0] = (byte)((value % 256) & 255);
+ data[1] = (byte) ((value / 256) & 255);
+ out.write(data);
+ }
+
+ private void putInt(DataOutputStream out, int value) throws IOException {
+ int low = (value % 65536) & 65535 ;
+ int hi = (value / 65536) & 65535;
+ putShort(out, low);
+ putShort(out, hi);
+ }
+}
CVSspam 0.2.8