001/***************************************************************************** 002 * Copyright by The HDF Group. * 003 * Copyright by the Board of Trustees of the University of Illinois. * 004 * All rights reserved. * 005 * * 006 * This file is part of the HDF Java Products distribution. * 007 * The full copyright notice, including terms governing use, modification, * 008 * and redistribution, is contained in the files COPYING and Copyright.html. * 009 * COPYING can be found at the root of the source code distribution tree. * 010 * Or, see http://hdfgroup.org/products/hdf-java/doc/Copyright.html. * 011 * If you do not have access to either file, you may request a copy from * 012 * help@hdfgroup.org. * 013 ****************************************************************************/ 014 015package hdf.view; 016 017import java.io.BufferedInputStream; 018import java.io.BufferedOutputStream; 019import java.io.File; 020import java.io.FileInputStream; 021import java.io.FileOutputStream; 022import java.io.RandomAccessFile; 023import java.util.Enumeration; 024import java.util.Hashtable; 025import java.util.StringTokenizer; 026 027import javax.swing.filechooser.FileFilter; 028 029/** 030 * A convenience implementation of FileFilter that filters out all files except 031 * for those type extensions that it knows about. 032 * 033 * @author Peter X. Cao 034 * @version 2.4 9/6/2007 035 */ 036public class DefaultFileFilter extends FileFilter { 037 private static FileFilter FILE_FILTER_HDF = null; 038 private static FileFilter FILE_FILTER_HDF4 = null; 039 private static FileFilter FILE_FILTER_HDF5 = null; 040 private static FileFilter FILE_FILTER_JPEG = null; 041 private static FileFilter FILE_FILTER_TIFF = null; 042 private static FileFilter FILE_FILTER_PNG = null; 043 private static FileFilter FILE_FILTER_GIF = null; 044 private static FileFilter FILE_FILTER_BMP = null; 045 private static FileFilter FILE_FILTER_IMG = null; 046 private static FileFilter FILE_FILTER_TEXT = null; 047 private static FileFilter FILE_FILTER_BINARY = null; 048 049 private static String fileExtension = ViewProperties.getFileExtension(); 050 051 private Hashtable<String, DefaultFileFilter> filters = null; 052 private String description = null; 053 private String fullDescription = null; 054 private boolean useExtensionsInDescription = true; 055 056 /** 057 * Creates a file filter. If no filters are added, then all files are 058 * accepted. 059 * 060 * @see #addExtension 061 */ 062 public DefaultFileFilter() { 063 this.filters = new Hashtable<String, DefaultFileFilter>(); 064 } 065 066 /** 067 * Creates a file filter that accepts files with the given extension. 068 * Example: new DefaultFileFilter("jpg"); 069 * 070 * @see #addExtension 071 */ 072 public DefaultFileFilter(String extension) { 073 this(extension, null); 074 } 075 076 /** 077 * Creates a file filter that accepts the given file type. Example: new 078 * DefaultFileFilter("jpg", "JPEG Image Images"); 079 * 080 * Note that the "." before the extension is not needed. If provided, it 081 * will be ignored. 082 * 083 * @see #addExtension 084 */ 085 public DefaultFileFilter(String extension, String description) { 086 this(); 087 if (extension != null) { 088 addExtension(extension); 089 } 090 if (description != null) { 091 setDescription(description); 092 } 093 } 094 095 /** 096 * Creates a file filter from the given string array. Example: new 097 * DefaultFileFilter(String {"gif", "jpg"}); 098 * 099 * Note that the "." before the extension is not needed adn will be ignored. 100 * 101 * @see #addExtension 102 */ 103 public DefaultFileFilter(String[] filters) { 104 this(filters, null); 105 } 106 107 /** 108 * Creates a file filter from the given string array and description. 109 * Example: new DefaultFileFilter(String {"gif", "jpg"}, 110 * "Gif and JPG Images"); 111 * 112 * Note that the "." before the extension is not needed and will be ignored. 113 * 114 * @see #addExtension 115 */ 116 public DefaultFileFilter(String[] filters, String description) { 117 this(); 118 for (int i = 0; i < filters.length; i++) { 119 // add filters one by one 120 addExtension(filters[i]); 121 } 122 if (description != null) { 123 setDescription(description); 124 } 125 } 126 127 /** 128 * Return true if this file should be shown in the directory pane, false if 129 * it shouldn't. 130 * 131 * Files that begin with "." are ignored. 132 * 133 * @see #getExtension 134 */ 135 @Override 136 public boolean accept(File f) { 137 if (f != null) { 138 if (f.isDirectory()) { 139 return true; 140 } 141 String extension = getExtension(f); 142 if ((extension != null) && (filters.get(getExtension(f)) != null)) { 143 return true; 144 } 145 } 146 147 return false; 148 } 149 150 /** 151 * Return the extension portion of the file's name . 152 * 153 * @see #getExtension 154 * @see FileFilter#accept 155 */ 156 public String getExtension(File f) { 157 if (f != null) { 158 String filename = f.getName(); 159 int i = filename.lastIndexOf('.'); 160 if ((i > 0) && (i < filename.length() - 1)) { 161 return filename.substring(i + 1).toLowerCase(); 162 } 163 } 164 return null; 165 } 166 167 /** 168 * Adds a filetype "dot" extension to filter against. 169 * 170 * For example: the following code will create a filter that filters out all 171 * files except those that end in ".jpg" and ".tif": 172 * 173 * DefaultFileFilter filter = new DefaultFileFilter(); 174 * filter.addExtension("jpg"); filter.addExtension("tif"); or 175 * filter.addExtension("jpg, tif"); 176 * 177 * Note that the "." before the extension is not needed and will be ignored. 178 */ 179 public void addExtension(String extension) { 180 if (filters == null) { 181 filters = new Hashtable<String, DefaultFileFilter>(5); 182 } 183 184 String ext = null; 185 StringTokenizer st = new StringTokenizer(extension, ","); 186 while (st.hasMoreElements()) { 187 ext = st.nextToken().trim(); 188 filters.put(ext.toLowerCase(), this); 189 } 190 fullDescription = null; 191 } 192 193 /** 194 * Returns the human readable description of this filter. For example: 195 * "JPEG and GIF Image Files (*.jpg, *.gif)" 196 */ 197 @Override 198 public String getDescription() { 199 if (fullDescription == null) { 200 if ((description == null) || isExtensionListInDescription()) { 201 fullDescription = description == null ? "(" : description 202 + " ("; 203 // build the description from the extension list 204 Enumeration<String> extensions = filters.keys(); 205 if (extensions != null) { 206 207 if (!extensions.hasMoreElements()) { 208 fullDescription = null; 209 return null; 210 } 211 212 fullDescription += "." + extensions.nextElement(); 213 while (extensions.hasMoreElements()) { 214 fullDescription += ", " 215 + extensions.nextElement(); 216 } 217 } 218 fullDescription += ")"; 219 } 220 else { 221 fullDescription = description; 222 } 223 } 224 return fullDescription; 225 } 226 227 /** 228 * Sets the human readable description of this filter. For example: 229 * filter.setDescription("Gif and JPG Images"); 230 */ 231 public void setDescription(String description) { 232 this.description = description; 233 fullDescription = null; 234 } 235 236 /** 237 * Determines whether the extension list (.jpg, .gif, etc) should show up in 238 * the human readable description. 239 * 240 * Only relevent if a description was provided in the constructor or using 241 * setDescription(); 242 * 243 */ 244 public void setExtensionListInDescription(boolean b) { 245 useExtensionsInDescription = b; 246 fullDescription = null; 247 } 248 249 /** 250 * Returns whether the extension list (.jpg, .gif, etc) should show up in 251 * the human readable description. 252 * 253 * Only relevent if a description was provided in the constructor or using 254 * setDescription(); 255 */ 256 public boolean isExtensionListInDescription() { 257 return useExtensionsInDescription; 258 } 259 260 /** Return a file filter for HDF4/5 file. */ 261 public static FileFilter getFileFilter() { 262 boolean extensionNotChanged = (fileExtension 263 .equalsIgnoreCase(ViewProperties.getFileExtension())); 264 265 if ((FILE_FILTER_HDF != null) && extensionNotChanged) { 266 return FILE_FILTER_HDF; 267 } 268 269 // update extensions 270 fileExtension = ViewProperties.getFileExtension(); 271 272 DefaultFileFilter filter = new DefaultFileFilter(); 273 filter.setDescription("HDF & more"); 274 275 filter.addExtension(fileExtension); 276 277 return (FILE_FILTER_HDF = filter); 278 } 279 280 /** Return a file filter for HDF4 file. */ 281 public static FileFilter getFileFilterHDF4() { 282 if (FILE_FILTER_HDF4 != null) { 283 return FILE_FILTER_HDF4; 284 } 285 286 DefaultFileFilter filter = new DefaultFileFilter(); 287 filter.addExtension("hdf"); 288 filter.addExtension("h4"); 289 filter.addExtension("hdf4"); 290 filter.setDescription("HDF4 files"); 291 FILE_FILTER_HDF4 = filter; 292 293 return FILE_FILTER_HDF4; 294 } 295 296 /** Return a file filter for HDF5 file. */ 297 public static FileFilter getFileFilterHDF5() { 298 if (FILE_FILTER_HDF5 != null) { 299 return FILE_FILTER_HDF5; 300 } 301 302 DefaultFileFilter filter = new DefaultFileFilter(); 303 filter.addExtension("h5"); 304 filter.addExtension("hdf5"); 305 filter.setDescription("HDF5 files"); 306 FILE_FILTER_HDF5 = filter; 307 308 return FILE_FILTER_HDF5; 309 } 310 311 /** Return a file filter for JPEG image files. */ 312 public static FileFilter getFileFilterJPEG() { 313 if (FILE_FILTER_JPEG != null) { 314 return FILE_FILTER_JPEG; 315 } 316 317 DefaultFileFilter filter = new DefaultFileFilter(); 318 filter.addExtension("jpg"); 319 filter.addExtension("jpeg"); 320 filter.addExtension("jpe"); 321 filter.addExtension("jif"); 322 filter.addExtension("jfif"); 323 filter.addExtension("jfi"); 324 filter.setDescription("JPEG images"); 325 FILE_FILTER_JPEG = filter; 326 327 return FILE_FILTER_JPEG; 328 } 329 330 /** Return a file filter for TIFF image files. */ 331 public static FileFilter getFileFilterTIFF() { 332 if (FILE_FILTER_TIFF != null) { 333 return FILE_FILTER_TIFF; 334 } 335 336 DefaultFileFilter filter = new DefaultFileFilter(); 337 filter.addExtension("tif"); 338 filter.addExtension("tiff"); 339 filter.setDescription("TIFF images"); 340 FILE_FILTER_TIFF = filter; 341 342 return FILE_FILTER_TIFF; 343 } 344 345 /** Return a file filter for PNG image files. */ 346 public static FileFilter getFileFilterPNG() { 347 if (FILE_FILTER_PNG != null) { 348 return FILE_FILTER_PNG; 349 } 350 351 DefaultFileFilter filter = new DefaultFileFilter(); 352 filter.addExtension("png"); 353 filter.setDescription("PNG images"); 354 FILE_FILTER_PNG = filter; 355 356 return FILE_FILTER_PNG; 357 } 358 359 /** Return a file filter for BMP image files. */ 360 public static FileFilter getFileFilterBMP() { 361 if (FILE_FILTER_BMP != null) { 362 return FILE_FILTER_BMP; 363 } 364 365 DefaultFileFilter filter = new DefaultFileFilter(); 366 filter.addExtension("bmp"); 367 filter.addExtension("dib"); 368 filter.setDescription("BMP images"); 369 FILE_FILTER_BMP = filter; 370 371 return FILE_FILTER_BMP; 372 } 373 374 /** Return a file filter for GIF image files. */ 375 public static FileFilter getFileFilterGIF() { 376 if (FILE_FILTER_GIF != null) { 377 return FILE_FILTER_GIF; 378 } 379 380 DefaultFileFilter filter = new DefaultFileFilter(); 381 filter.addExtension("gif"); 382 filter.setDescription("GIF images"); 383 FILE_FILTER_GIF = filter; 384 385 return FILE_FILTER_GIF; 386 } 387 388 /** Return a file filter for GIF, JPEG, BMP, or PNG image files. */ 389 public static FileFilter getImageFileFilter() { 390 if (FILE_FILTER_IMG != null) { 391 return FILE_FILTER_IMG; 392 } 393 394 DefaultFileFilter filter = new DefaultFileFilter(); 395 filter.addExtension("jpg"); 396 filter.addExtension("jpeg"); 397 filter.addExtension("jpe"); 398 filter.addExtension("jif"); 399 filter.addExtension("jfif"); 400 filter.addExtension("jfi"); 401 filter.addExtension("png"); 402 filter.addExtension("gif"); 403 filter.addExtension("bmp"); 404 filter.addExtension("dib"); 405 filter.setDescription("GIF, JPEG, BMP, or PNG images"); 406 FILE_FILTER_IMG = filter; 407 408 return FILE_FILTER_IMG; 409 } 410 411 /** Return a file filter for text file. */ 412 public static FileFilter getFileFilterText() { 413 if (FILE_FILTER_TEXT != null) { 414 return FILE_FILTER_TEXT; 415 } 416 417 DefaultFileFilter filter = new DefaultFileFilter(); 418 filter.addExtension("txt"); 419 filter.addExtension("text"); 420 filter.setDescription("Text"); 421 FILE_FILTER_TEXT = filter; 422 423 return FILE_FILTER_TEXT; 424 } 425 426 /** Return a file filter for binary file. */ 427 public static FileFilter getFileFilterBinary() { 428 if (FILE_FILTER_BINARY != null) { 429 return FILE_FILTER_BINARY; 430 } 431 432 DefaultFileFilter filter = new DefaultFileFilter(); 433 filter.addExtension("bin"); 434 filter.setDescription("Binary"); 435 FILE_FILTER_BINARY = filter; 436 437 return FILE_FILTER_BINARY; 438 } 439 440 /** 441 * look at the first 4 bytes of the file to see if it is an HDF4 file. 442 * byte[0]=14, byte[1]=3, byte[2]=19, byte[3]=1 or if it is a netCDF file 443 * byte[0]=67, byte[1]=68, byte[2]=70, byte[3]=1 or 444 */ 445 public static boolean isHDF4(String filename) { 446 boolean ish4 = false; 447 RandomAccessFile raf = null; 448 449 try { 450 raf = new RandomAccessFile(filename, "r"); 451 } 452 catch (Exception ex) { 453 raf = null; 454 } 455 456 if (raf == null) { 457 return false; 458 } 459 460 byte[] header = new byte[4]; 461 try { 462 raf.read(header); 463 } 464 catch (Exception ex) { 465 header = null; 466 } 467 468 if (header != null) { 469 if ( 470 // HDF4 471 ((header[0] == 14) && (header[1] == 3) && (header[2] == 19) && (header[3] == 1)) 472 /* 473 * // netCDF || (header[0]==67 && header[1]==68 && header[2]==70 && 474 * header[3]==1) 475 */ 476 ) { 477 ish4 = true; 478 } 479 else { 480 ish4 = false; 481 } 482 } 483 484 try { 485 raf.close(); 486 } 487 catch (Exception ex) { 488 } 489 490 return ish4; 491 } 492 493 /** 494 * look at the first 8 bytes of the file to see if it is an HDF5 file. 495 * byte[0]=-199 which is 137 in unsigned byte, byte[1]=72, byte[2]=68, 496 * byte[3]=70, byte[4]=13, byte[5]=10, byte[6]=26, byte[7]=10 497 */ 498 public static boolean isHDF5(String filename) { 499 boolean ish5 = false; 500 RandomAccessFile raf = null; 501 502 try { 503 raf = new RandomAccessFile(filename, "r"); 504 } 505 catch (Exception ex) { 506 raf = null; 507 } 508 509 if (raf == null) { 510 return false; 511 } 512 513 byte[] header = new byte[8]; 514 long fileSize = 0; 515 try { 516 fileSize = raf.length(); 517 } 518 catch (Exception ex) { 519 } 520 521 // The super block is located by searching for the HDF5 file signature 522 // at byte offset 0, byte offset 512 and at successive locations in the 523 // file, each a multiple of two of the previous location, i.e. 0, 512, 524 // 1024, 2048, etc 525 long offset = 0; 526 while (!ish5 && (offset < fileSize)) { 527 try { 528 raf.seek(offset); 529 raf.read(header); 530 } 531 catch (Exception ex) { 532 header = null; 533 } 534 535 if ((header[0] == -119) && (header[1] == 72) && (header[2] == 68) 536 && (header[3] == 70) && (header[4] == 13) 537 && (header[5] == 10) && (header[6] == 26) 538 && (header[7] == 10)) { 539 ish5 = true; 540 } 541 else { 542 ish5 = false; 543 if (offset == 0) { 544 offset = 512; 545 } 546 else { 547 offset *= 2; 548 } 549 } 550 } 551 552 try { 553 raf.close(); 554 } 555 catch (Exception ex) { 556 } 557 558 return ish5; 559 } 560 561 /** 562 * look at the first 4 bytes of the file to see if it is a netCDF file 563 * byte[0]=67, byte[1]=68, byte[2]=70, byte[3]=1 or 564 */ 565 public static boolean isNetcdf(String filename) { 566 boolean isnc = false; 567 RandomAccessFile raf = null; 568 569 try { 570 raf = new RandomAccessFile(filename, "r"); 571 } 572 catch (Exception ex) { 573 raf = null; 574 } 575 576 if (raf == null) { 577 return false; 578 } 579 580 byte[] header = new byte[4]; 581 try { 582 raf.read(header); 583 } 584 catch (Exception ex) { 585 header = null; 586 } 587 588 if (header != null) { 589 if ( 590 // netCDF 591 (header[0] == 67) && (header[1] == 68) && (header[2] == 70) 592 && (header[3] == 1)) { 593 isnc = true; 594 } 595 else { 596 isnc = false; 597 } 598 } 599 600 try { 601 raf.close(); 602 } 603 catch (Exception ex) { 604 } 605 606 return isnc; 607 } 608 609 /** 610 * Read HDF5 user block data into byte array. 611 * 612 * @return a byte array of user block, or null if there is user data. 613 */ 614 public static byte[] getHDF5UserBlock(String filename) { 615 byte[] userBlock = null; 616 RandomAccessFile raf = null; 617 618 try { 619 raf = new RandomAccessFile(filename, "r"); 620 } 621 catch (Exception ex) { 622 try { 623 raf.close(); 624 } 625 catch (Throwable err) { 626 ; 627 } 628 raf = null; 629 } 630 631 if (raf == null) { 632 return null; 633 } 634 635 byte[] header = new byte[8]; 636 long fileSize = 0; 637 try { 638 fileSize = raf.length(); 639 } 640 catch (Exception ex) { 641 fileSize = 0; 642 } 643 if (fileSize <= 0) { 644 try { 645 raf.close(); 646 } 647 catch (Throwable err) { 648 ; 649 } 650 return null; 651 } 652 653 // The super block is located by searching for the HDF5 file signature 654 // at byte offset 0, byte offset 512 and at successive locations in the 655 // file, each a multiple of two of the previous location, i.e. 0, 512, 656 // 1024, 2048, etc 657 long offset = 0; 658 boolean ish5 = false; 659 while (offset < fileSize) { 660 try { 661 raf.seek(offset); 662 raf.read(header); 663 } 664 catch (Exception ex) { 665 header = null; 666 } 667 668 if ((header[0] == -119) && (header[1] == 72) && (header[2] == 68) 669 && (header[3] == 70) && (header[4] == 13) 670 && (header[5] == 10) && (header[6] == 26) 671 && (header[7] == 10)) { 672 ish5 = true; 673 break; // find the end of user block 674 } 675 else { 676 ish5 = false; 677 if (offset == 0) { 678 offset = 512; 679 } 680 else { 681 offset *= 2; 682 } 683 } 684 } 685 686 if (!ish5 || (offset == 0)) { 687 try { 688 raf.close(); 689 } 690 catch (Throwable err) { 691 ; 692 } 693 return null; 694 } 695 696 int blockSize = (int) offset; 697 userBlock = new byte[blockSize]; 698 try { 699 raf.seek(0); 700 raf.read(userBlock, 0, blockSize); 701 } 702 catch (Exception ex) { 703 userBlock = null; 704 } 705 706 try { 707 raf.close(); 708 } 709 catch (Exception ex) { 710 } 711 712 return userBlock; 713 } 714 715 /** 716 * Write HDF5 user block data into byte array. 717 * 718 * @return a byte array of user block, or null if there is user data. 719 */ 720 public static boolean setHDF5UserBlock(String fin, String fout, byte[] buf) { 721 boolean ish5 = false; 722 723 if ((buf == null) || (buf.length <= 0)) { 724 return false; 725 } 726 727 File tmpFile = new File(fin); 728 if (!tmpFile.exists()) { 729 return false; 730 } 731 732 // find the end of user block for the input file; 733 RandomAccessFile raf = null; 734 try { 735 raf = new RandomAccessFile(fin, "r"); 736 } 737 catch (Exception ex) { 738 raf = null; 739 } 740 741 if (raf == null) { 742 return false; 743 } 744 745 byte[] header = new byte[8]; 746 long fileSize = 0; 747 try { 748 fileSize = raf.length(); 749 } 750 catch (Exception ex) { 751 fileSize = 0; 752 } 753 try { 754 fileSize = raf.length(); 755 } 756 catch (Exception ex) { 757 fileSize = 0; 758 } 759 if (fileSize <= 0) { 760 try { 761 raf.close(); 762 } 763 catch (Throwable err) { 764 ; 765 } 766 return false; 767 } 768 769 // The super block is located by searching for the HDF5 file signature 770 // at byte offset 0, byte offset 512 and at successive locations in the 771 // file, each a multiple of two of the previous location, i.e. 0, 512, 772 // 1024, 2048, etc 773 long offset = 0; 774 while (offset < fileSize) { 775 try { 776 raf.seek(offset); 777 raf.read(header); 778 } 779 catch (Exception ex) { 780 header = null; 781 } 782 783 if ((header[0] == -119) && (header[1] == 72) && (header[2] == 68) 784 && (header[3] == 70) && (header[4] == 13) 785 && (header[5] == 10) && (header[6] == 26) 786 && (header[7] == 10)) { 787 ish5 = true; 788 break; 789 } 790 else { 791 ish5 = false; 792 if (offset == 0) { 793 offset = 512; 794 } 795 else { 796 offset *= 2; 797 } 798 } 799 } 800 try { 801 raf.close(); 802 } 803 catch (Throwable err) { 804 ; 805 } 806 807 if (!ish5) { 808 return false; 809 } 810 811 int length = 0; 812 int bsize = 1024; 813 byte[] buffer; 814 BufferedInputStream bi = null; 815 BufferedOutputStream bo = null; 816 817 try { 818 bi = new BufferedInputStream(new FileInputStream(fin)); 819 } 820 catch (Exception ex) { 821 try { 822 bi.close(); 823 } 824 catch (Exception ex2) { 825 } 826 return false; 827 } 828 829 try { 830 bo = new BufferedOutputStream(new FileOutputStream(fout)); 831 } 832 catch (Exception ex) { 833 try { 834 bo.close(); 835 } 836 catch (Exception ex2) { 837 } 838 try { 839 bi.close(); 840 } 841 catch (Exception ex2) { 842 } 843 return false; 844 } 845 846 // skip the header of original file 847 try { 848 bi.skip(offset); 849 } 850 catch (Exception ex) { 851 } 852 853 // write the header into the new file 854 try { 855 bo.write(buf, 0, buf.length); 856 } 857 catch (Exception ex) { 858 } 859 860 // The super block space is allocated by offset 0, 512, 1024, 2048, etc 861 offset = 512; 862 while (offset < buf.length) { 863 offset *= 2; 864 } 865 int padSize = (int) (offset - buf.length); 866 if (padSize > 0) { 867 byte[] padBuf = new byte[padSize]; 868 try { 869 bo.write(padBuf, 0, padSize); 870 } 871 catch (Exception ex) { 872 } 873 } 874 875 // copy the hdf5 file content from input file to the output file 876 buffer = new byte[bsize]; 877 try { 878 length = bi.read(buffer, 0, bsize); 879 } 880 catch (Exception ex) { 881 length = 0; 882 } 883 while (length > 0) { 884 try { 885 bo.write(buffer, 0, length); 886 length = bi.read(buffer, 0, bsize); 887 } 888 catch (Exception ex) { 889 length = 0; 890 } 891 } 892 893 try { 894 bo.flush(); 895 } 896 catch (Exception ex) { 897 } 898 try { 899 bi.close(); 900 } 901 catch (Exception ex) { 902 } 903 try { 904 bo.close(); 905 } 906 catch (Exception ex) { 907 } 908 return true; 909 } 910}