/* * Copyright (C) 2014 Jan Pokorsky * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package cz.cas.lib.proarc.common.imports; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.bind.DatatypeConverter; import org.apache.commons.io.IOUtils; /** * Helper class to check imported data. * * @author Jan Pokorsky */ public class InputUtils { public static final byte[] JP2000_MAGIC_NUMBER = DatatypeConverter.parseHexBinary("0000000C6A5020200D0A870A"); public static final byte[] JPEG_MAGIC_NUMBER = DatatypeConverter.parseHexBinary("FFD8FF"); public static final byte[] PDF_MAGIC_NUMBER = "%PDF".getBytes(); public static final byte[] TIFF_BE_MAGIC_NUMBER = DatatypeConverter.parseHexBinary("4D4D002A"); public static final byte[] TIFF_LE_MAGIC_NUMBER = DatatypeConverter.parseHexBinary("49492A00"); private static final Logger LOG = Logger.getLogger(InputUtils.class.getName()); public static boolean isJp2000(File f) throws IOException { return hasMagicNumber(f, JP2000_MAGIC_NUMBER); } public static boolean isJpeg(File f) throws IOException { return hasMagicNumber(f, JPEG_MAGIC_NUMBER); } public static boolean isPdf(File f) throws IOException { return hasMagicNumber(f, PDF_MAGIC_NUMBER); } public static boolean isTiff(File f) throws IOException { return hasMagicNumber(f, TIFF_LE_MAGIC_NUMBER, TIFF_BE_MAGIC_NUMBER); } /** * Checks a file for magic numbers. * @param f file to check * @param magics list of magic numbers * @return {@code true} if the file starts with some of magic numbers. * @throws IOException file access failure */ public static boolean hasMagicNumber(File f, byte[]... magics) throws IOException { int maxlength = 0; int minlength = 0; for (byte[] magic : magics) { maxlength = Math.max(maxlength, magic.length); minlength = Math.min(minlength, magic.length); } FileInputStream fis = new FileInputStream(f); try { byte[] buf = new byte[maxlength]; int length = fis.read(buf); if (length < minlength) { return false; } for (byte[] magic : magics) { if (startWith(buf, length, magic)) { return true; } } return false; } finally { IOUtils.closeQuietly(fis); } } private static boolean startWith(byte[] src, int srcLength, byte[] subarray) { if (subarray.length > srcLength ) { return false; } StringBuilder s1 = new StringBuilder(); StringBuilder s2 = new StringBuilder(); for (int i = 0; i < subarray.length; i++) { s1.append(src[i]); s2.append(subarray[i]); if (src[i] != subarray[i]) { if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "\nsrc: {0}\nsub: {1}", new Object[]{ DatatypeConverter.printHexBinary(src), DatatypeConverter.printHexBinary(subarray)}); } return false; } } return true; } }