/* * #%L * OME library for reading the JPEG XR file format. * %% * Copyright (C) 2013 - 2015 Open Microscopy Environment: * - Board of Regents of the University of Wisconsin-Madison * - Glencoe Software, Inc. * - University of Dundee * %% * 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 2 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/gpl-2.0.html>. * #L% */ package ome.jxr.parser; import java.io.IOException; import loci.common.RandomAccessInputStream; import ome.jxr.JXRException; import ome.jxr.constants.File; /** * Parses the first bytes of the image file and validates the extracted values * for conformance with the file format specification. Throws exceptions early, * so that further and more expensive operation can be avoided. * * <dl> * * @author Blazej Pindelski bpindelski at dundee.ac.uk */ public final class FileParser extends Parser { private int encoderVersion; private boolean isLittleEndian; private int rootIFDOffset; private long fileSize; public int getEncoderVersion() { return encoderVersion; } public long getFileSize() { return fileSize; } public boolean isLittleEndian() { return isLittleEndian; } public int getRootIFDOffset() { return rootIFDOffset; } public FileParser(RandomAccessInputStream stream) { super(null, stream); } @Override public void parse(long parsingOffset) throws JXRException { super.parse(parsingOffset); try { checkFileSize(); checkHeaderLength(); checkFileStructureVersion(); checkHeaderBOM(); checkIfValidJpegXr(); calculateIFDOffset(); } catch (IOException ioe) { throw new JXRException(ioe); } } private void checkFileSize() throws IOException, JXRException { if (stream.length() > File.MAX_SIZE) { throw new JXRException("File size bigger than supported. Size: " + stream.length()); } fileSize = stream.length(); } private void checkHeaderLength() throws IOException, JXRException { if (stream.length() < 4) { throw new JXRException("File header too short."); } } private void checkFileStructureVersion() throws IOException, JXRException { stream.seek(0); stream.skipBytes(3); byte version = stream.readByte(); if (version != File.CODESTREAM_VERSION) { throw new JXRException("Wrong file format version. Found: " + version); } } private void checkHeaderBOM() throws IOException, JXRException { stream.seek(0); short littleEndian = stream.readShort(); if (littleEndian != File.LITTLE_ENDIAN) { throw new JXRException("File not using little-endian byte order. " + "BOM found: " + Integer.toHexString(littleEndian)); } isLittleEndian = true; } private void checkIfValidJpegXr() throws IOException, JXRException { stream.seek(0); stream.skipBytes(2); byte magic = stream.readByte(); if (magic != File.MAGIC_NUMBER) { throw new JXRException("Invalid magic byte. Found: " + Integer.toHexString(magic)); } encoderVersion = stream.readByte(); } private void calculateIFDOffset() throws IOException, JXRException { stream.seek(0); stream.skipBytes(4); int offset = stream.readInt(); if (offset == 0) { throw new JXRException("IFD offset invalid. Found: " + offset); } rootIFDOffset = offset; } public void close() throws IOException { super.close(); } }