Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
Opener.java
1 package ij.io;
2 import java.awt.*;
3 import java.awt.image.*;
4 import java.io.*;
5 import java.net.URL;
6 import java.net.*;
7 import java.util.zip.*;
8 import java.util.Iterator;
9 import java.util.Locale;
10 import javax.swing.*;
11 import javax.swing.filechooser.*;
12 import ij.*;
13 import ij.gui.*;
14 import ij.process.*;
15 import ij.plugin.frame.*;
16 import ij.text.TextWindow;
17 import ij.util.Java2;
18 import java.util.LinkedList;
19 import java.util.ArrayList;
20 
24 public class Opener {
25 
26  private static final int UNKNOWN=0,TIFF=1,DICOM=2,FITS=3,PGM=4,JPEG=5,
27  GIF=6,LUT=7,BMP=8,ZIP=9,JAVA_OR_TEXT=10,ROI=11,TEXT=12,PNG=13,TIFF_AND_DICOM=14,CUSTOM=15;
28  private static final String[] types = {"unknown","tif","dcm","fits","pgm",
29  "jpg","gif","bmp","png"};
30  public static FileExtensionFilter[] FILE_FILTERS;
31  public static FileExtensionFilter ALL_FILES_FILTER;
32 
33  static {
34  ArrayList filters = new ArrayList();
35  LinkedList extensions = new LinkedList();
36  extensions.add("gif");
37  filters.add(new FileExtensionFilter("Graphics Interchange Format", extensions));
38  extensions.clear();
39  extensions.add("jpg");
40  extensions.add("jpeg");
41  filters.add(new FileExtensionFilter("Joint Photographic Experts Group", extensions));
42  extensions.clear();
43  extensions.add("png");
44  filters.add(new FileExtensionFilter("Portable Network Graphics", extensions));
45  extensions.clear();
46  extensions.add("bmp");
47  filters.add(new FileExtensionFilter("Windows Bitmap", extensions));
48  extensions.clear();
49  extensions.add("tif");
50  extensions.add("tiff");
51  filters.add(new FileExtensionFilter("Tagged Image File Format", extensions));
52  extensions.clear();
53  extensions.add("dcm");
54  extensions.add("dicom");
55  filters.add(new FileExtensionFilter("Digital Image and Communications in Medicine", extensions));
56  extensions.clear();
57  extensions.add("fits");
58  filters.add(new FileExtensionFilter("Flexible Image Transport System", extensions));
59  extensions.clear();
60  extensions.add("pgm");
61  filters.add(new FileExtensionFilter("Portable Gray Map", extensions));
62  LinkedList allExtensions = new LinkedList();
63  for (Iterator itr=filters.iterator(); itr.hasNext(); ) {
64  String[] e = ((FileExtensionFilter)(itr.next())).getExtensions();
65  for (int i=0; i < e.length; i++) {
66  allExtensions.add(e[i]);
67  }
68  }
69  ALL_FILES_FILTER = new FileExtensionFilter("All Supported Types", allExtensions);
70  ALL_FILES_FILTER.setShowExtensions(false);
71 
72  FILE_FILTERS = new FileExtensionFilter[filters.size()+1];
73  FILE_FILTERS[0] = ALL_FILES_FILTER;
74  for (int i=0; i < filters.size(); i++) {
75  FILE_FILTERS[i+1] = (FileExtensionFilter)filters.get(i);
76  }
77 
78  }
79 
80  public static File defaultDirectory = null;
81  private static int fileType;
82 
83 
84  public Opener() {
85  }
86 
93  public boolean open() {
94  JFileChooser fc = new JFileChooser();
95  if (defaultDirectory != null) {
96  fc.setCurrentDirectory(defaultDirectory);
97  }
98  for (int i=0; i < FILE_FILTERS.length; i++) {
99  fc.addChoosableFileFilter(FILE_FILTERS[i]);
100  }
101  fc.setFileFilter(ALL_FILES_FILTER);
102  fc.setAcceptAllFileFilterUsed(false);
103  int returnVal = fc.showOpenDialog(IJ.getInstance());
104  defaultDirectory = fc.getCurrentDirectory();
105 
106  if (returnVal!=JFileChooser.APPROVE_OPTION) {
107  return false;
108  }
109  String path = fc.getSelectedFile().toString();
110  return open(path);
111  }
112 
113 
120  public boolean open(String path) {
121  IJ.showStatus("Opening: " + path);
122 
123  ImagePlus imp = openImage(path);
124 
125  if (imp != null) {
126  imp.show();
127  IJ.getInstance().setFilename(path);
128  return true;
129  } else {
130  String msg = "File is not in a valid format, or it was not found.";
131  if (path!=null && path.length()<=64)
132  msg += " \n \n "+path;
133  IJ.showMessage("Opener", msg);
134  return false;
135  }
136  }
137 
138 
146  public ImagePlus openImage(String path) {
147  ImagePlus img = null;
148  if (path==null || path.equals(""))
149  img = null;
150  else if (path.indexOf("://")>0)
151  img = openURL(path);
152  else {
153  img = openImage(getDir(path), getName(path));
154  }
155  return img;
156  }
157 
158 
167  public ImagePlus openImage(String directory, String name) {
168  ImagePlus imp;
169  if (directory.length()>0 && !directory.endsWith(Prefs.separator))
170  directory += Prefs.separator;
171  String path = directory+name;
172  fileType = getFileType(path,name);
173  if (IJ.debugMode)
174  IJ.log("openImage: \""+types[fileType]+"\", "+path);
175  switch (fileType) {
176  case TIFF:
177  imp = openTiff(directory, name);
178  return imp;
179  case DICOM:
180  imp = (ImagePlus)IJ.runPlugIn("ij.plugin.DICOM", path);
181  if (imp.getWidth()!=0) return imp; else return null;
182  case TIFF_AND_DICOM:
183  // "hybrid" files created by GE-Senographe 2000 D */
184  imp = openTiff(directory,name);
185  ImagePlus imp2 = (ImagePlus)IJ.runPlugIn("ij.plugin.DICOM", path);
186  if (imp!=null)
187  imp.setProperty("Info",imp2.getProperty("Info"));
188  return imp;
189  case FITS:
190  imp = (ImagePlus)IJ.runPlugIn("ij.plugin.FITS", path);
191  if (imp.getWidth()!=0) return imp; else return null;
192  case PGM:
193  imp = (ImagePlus)IJ.runPlugIn("ij.plugin.PGM_Reader", path);
194  if (imp.getWidth()!=0) return imp; else return null;
195  case GIF:
196  IJ.getInstance().setCurrentType(".gif");
197  // and continuing...
198  case JPEG: case PNG:
199  imp = openJpegOrGif(directory, name);
200  if (imp!=null&&imp.getWidth()!=0) return imp; else return null;
201  case BMP:
202  imp = (ImagePlus)IJ.runPlugIn("ij.plugin.BMP_Reader", path);
203  if (imp.getWidth()!=0) return imp; else return null;
204  case ZIP:
205  imp = (ImagePlus)IJ.runPlugIn("ij.plugin.Zip_Reader", path);
206  if (imp.getWidth()!=0) return imp; else return null;
207  case UNKNOWN: case TEXT:
208  // Call HandleExtraFileTypes plugin to see if it can handle unknown format
209  imp = (ImagePlus)IJ.runPlugIn("HandleExtraFileTypes", path);
210  if (imp==null) return null;
211  if (imp.getWidth()>0 && imp.getHeight()>0) {
212  fileType = CUSTOM;
213  return imp;
214  } else {
215  if (imp.getWidth()==-1)
216  fileType = CUSTOM; // plugin opened image so don't display error
217  return null;
218  }
219  default:
220  return null;
221  }
222  }
223 
231  public ImagePlus openURL(String url) {
232  try {
233  String name = "";
234  int index = url.lastIndexOf('/');
235  if (index==-1)
236  index = url.lastIndexOf('\\');
237  if (index>0)
238  name = url.substring(index+1);
239  else
240  throw new MalformedURLException("Invalid URL: "+url);
241  URL u = new URL(url);
242  IJ.showStatus(""+url);
243  ImagePlus imp = null;
244  if (url.endsWith(".tif") || url.endsWith(".TIF"))
245  imp = openTiff(u.openStream(), name);
246  else if (url.endsWith(".zip"))
247  imp = openZip(u);
248  else if (url.endsWith(".dcm")) {
249  imp = (ImagePlus)IJ.runPlugIn("ij.plugin.DICOM", url);
250  if (imp!=null && imp.getWidth()==0) imp = null;
251  } else
252  imp = openJpegOrGifUsingURL(name, u);
253  IJ.showStatus("");
254  return imp;
255  } catch (Exception e) {
256  String msg = e.getMessage();
257  if (msg==null || msg.equals(""))
258  msg = "" + e;
259  IJ.showMessage("Open URL",msg + "\n \n" + url);
260  return null;
261  }
262  }
263 
265  ImagePlus openZip(URL url) throws IOException {
266  IJ.showProgress(0.01);
267  URLConnection uc = url.openConnection();
268  int fileSize = uc.getContentLength(); // compressed size
269  fileSize *=2; // estimate uncompressed size
270  InputStream in = uc.getInputStream();
271  ZipInputStream zin = new ZipInputStream(in);
272  ByteArrayOutputStream out = new ByteArrayOutputStream();
273  byte[] buf = new byte[4096];
274  ZipEntry entry = zin.getNextEntry();
275  if (entry==null)
276  return null;
277  String name = entry.getName();
278  //double fileSize = entry.getSize(); //returns -1
279  if (!name.endsWith(".tif"))
280  throw new IOException("This ZIP archive does not appear to contain a TIFF file");
281  int len;
282  int byteCount = 0;
283  int progress = 0;
284  while (true) {
285  len = zin.read(buf);
286  if (len<0) break;
287  out.write(buf, 0, len);
288  byteCount += len;
289  IJ.showProgress((double)(byteCount%fileSize)/fileSize);
290  }
291  zin.close();
292  byte[] bytes = out.toByteArray();
293  IJ.showProgress(1.0);
294  return openTiff(new ByteArrayInputStream(bytes), name);
295  }
296 
297  ImagePlus openJpegOrGifUsingURL(String title, URL url) {
298  if (url==null)
299  return null;
300  Image img = Toolkit.getDefaultToolkit().getImage(url);
301  if (img!=null) {
302  ImagePlus imp = new ImagePlus(title, img);
303  return imp;
304  } else
305  return null;
306  }
307 
308  ImagePlus openJpegOrGif(String dir, String name) {
309  ImagePlus imp = null;
310  Image img = Toolkit.getDefaultToolkit().getImage(dir+name);
311  if (img!=null) {
312  try {
313  imp = new ImagePlus(name, img);
314  } catch (IllegalStateException e) {
315  return null; // error loading image
316  }
317 
318  if (imp.getType()==ImagePlus.COLOR_RGB)
320  FileInfo fi = new FileInfo();
321  fi.fileFormat = fi.GIF_OR_JPG;
322  fi.fileName = name;
323  fi.directory = dir;
324  imp.setFileInfo(fi);
325 
326  }
327  return imp;
328 
329  }
330 
332  public static void convertGrayJpegTo8Bits(ImagePlus imp) {
333  ImageProcessor ip = imp.getProcessor();
334  int width = ip.getWidth();
335  int height = ip.getHeight();
336  int[] pixels = (int[])ip.getPixels();
337  int c,r,g,b,offset;
338  for (int y=0; y<(height-8); y++) {
339  offset = y*width;
340  for (int x=0; x<(width-8); x++) {
341  c = pixels[offset+x];
342  r = (c&0xff0000)>>16;
343  g = (c&0xff00)>>8;
344  b = c&0xff;
345  if (!((r==g)&&(g==b))) {
346  //IJ.write("count: "+count+" "+r+" "+g+" "+b);
347  return;
348  }
349  }
350  //count++;
351  }
352  IJ.showStatus("Converting to 8-bits");
353  new ImageConverter(imp).convertToGray8();
354  }
355 
358  public ImagePlus openTiff(String directory, String name) {
359  TiffDecoder td = new TiffDecoder(directory, name);
360  if (IJ.debugMode) td.enableDebugging();
361  FileInfo[] info=null;
362  try {info = td.getTiffInfo();}
363  catch (IOException e) {
364  String msg = e.getMessage();
365  if (msg==null||msg.equals("")) msg = ""+e;
366  IJ.showMessage("TiffDecoder", msg);
367  return null;
368  }
369  if (info==null)
370  return null;
371  return openTiff2(info);
372  }
373 
376  public ImagePlus openTiff(InputStream in, String name) {
377  FileInfo[] info = null;
378  try {
379  TiffDecoder td = new TiffDecoder(in, name);
380  if (IJ.debugMode) td.enableDebugging();
381  info = td.getTiffInfo();
382  } catch (FileNotFoundException e) {
383  IJ.showMessage("TiffDecoder", "File not found: "+e.getMessage());
384  return null;
385  } catch (Exception e) {
386  IJ.showMessage("TiffDecoder", ""+e);
387  return null;
388  }
389  return openTiff2(info);
390  }
391 
392  public String getName(String path) {
393  int i = path.lastIndexOf('/');
394  if (i==-1)
395  i = path.lastIndexOf('\\');
396  if (i>0)
397  return path.substring(i+1);
398  else
399  return path;
400  }
401 
402  public String getDir(String path) {
403  int i = path.lastIndexOf('/');
404  if (i==-1)
405  i = path.lastIndexOf('\\');
406  if (i>0)
407  return path.substring(0, i+1);
408  else
409  return "";
410  }
411 
415  ImagePlus openTiff2(FileInfo[] info) {
416  if (info==null)
417  return null;
418  ImagePlus imp = null;
419  if (IJ.debugMode) // dump tiff tags
420  IJ.log(info[0].info);
421  FileOpener fo = new FileOpener(info[0]);
422  imp = fo.open(false);
423  IJ.showStatus("");
424  return imp;
425  }
426 
427 
432  int getFileType(String path, String name) {
433  InputStream is;
434  byte[] buf = new byte[132];
435  try {
436  is = new FileInputStream(path);
437  is.read(buf, 0, 132);
438  is.close();
439  } catch (IOException e) {
440  IJ.error("Couldn't open path "+path);
441  return UNKNOWN;
442  }
443 
444  int b0=buf[0]&255, b1=buf[1]&255, b2=buf[2]&255, b3=buf[3]&255;
445  //IJ.log("getFileType: "+ name+" "+b0+" "+b1+" "+b2+" "+b3);
446 
447  // Combined TIFF and DICOM created by GE Senographe scanners
448  if (buf[128]==68 && buf[129]==73 && buf[130]==67 && buf[131]==77
449  && ((b0==73 && b1==73)||(b0==77 && b1==77)))
450  return TIFF_AND_DICOM;
451 
452  // Big-endian TIFF ("MM")
453  if (name.endsWith(".lsm"))
454  return UNKNOWN; // The LSM Reader plugin opens these files
455  if (b0==73 && b1==73 && b2==42 && b3==0)
456  return TIFF;
457 
458  // Little-endian TIFF ("II")
459  if (b0==77 && b1==77 && b2==0 && b3==42)
460  return TIFF;
461 
462  // JPEG
463  if (b0==255 && b1==216 && b2==255)
464  return JPEG;
465 
466  // GIF ("GIF8")
467  if (b0==71 && b1==73 && b2==70 && b3==56)
468  return GIF;
469 
470  // DICOM ("DICM" at offset 128)
471  if (buf[128]==68 && buf[129]==73 && buf[130]==67 && buf[131]==77) {
472  return DICOM;
473  }
474 
475  // ACR/NEMA with first tag = 00002,00xx or 00008,00xx
476  name = name.toLowerCase(Locale.US);
477  if ((b0==8||b0==2) && b1==0 && b3==0 && !name.endsWith(".spe"))
478  return DICOM;
479 
480  // FITS ("SIMP")
481  if (b0==83 && b1==73 && b2==77 && b3==80)
482  return FITS;
483 
484  // PGM ("P2" or "P5")
485  if (b0==80&&(b1==50||b1==53)&&(b2==10||b2==13||b2==32||b2==9))
486  return PGM;
487 
488  // Lookup table
489  if (name.endsWith(".lut"))
490  return LUT;
491 
492  // BMP ("BM")
493  if (b0==66 && b1==77 && name.endsWith(".bmp"))
494  return BMP;
495 
496  // PNG
497  if (b0==137 && b1==80 && b2==78 && b3==71 && IJ.isJava2())
498  return PNG;
499 
500  // ZIP containing a TIFF
501  if (name.endsWith(".zip"))
502  return ZIP;
503 
504  // Java source file or text file
505  if (name.endsWith(".java") || name.endsWith(".txt"))
506  return JAVA_OR_TEXT;
507 
508  // ImageJ, NIH Image, Scion Image for Windows ROI
509  if (b0==73 && b1==111) // "Iout"
510  return ROI;
511 
512  // Text file
513  boolean isText = true;
514  for (int i=0; i<10; i++) {
515  int c = buf[i];
516  if ((c<32&&c!=9&&c!=10&&c!=13) || c>126) {
517  isText = false;
518  break;
519  }
520  }
521  if (isText)
522  return TEXT;
523 
524  return UNKNOWN;
525  }
526 
528  ColorModel createColorModel(FileInfo fi) {
529  if (fi.fileType==FileInfo.COLOR8 && fi.lutSize>0)
530  return new IndexColorModel(8, fi.lutSize, fi.reds, fi.greens, fi.blues);
531  else
532  return LookUpTable.createGrayscaleColorModel(fi.whiteIsZero);
533  }
534 
536  InputStream createInputStream(FileInfo fi) throws IOException, MalformedURLException {
537  if (fi.inputStream!=null)
538  return fi.inputStream;
539  else if (fi.url!=null && !fi.url.equals(""))
540  return new URL(fi.url+fi.fileName).openStream();
541  else {
542  File f = new File(fi.directory + fi.fileName);
543  if (f==null || f.isDirectory())
544  return null;
545  else
546  return new FileInputStream(f);
547  }
548  }
549 
550 }