/** * Parse the IFD. * * @param byteOffsetIsValid If true, allow offsets on odd byte boundaries * @param suppressErrors If true, return IFD even with errors * @return The offset of the next IFD */ public long parse(boolean byteOffsetIsValid, boolean suppressErrors) throws TiffException { try { return parse(byteOffsetIsValid); } catch (TiffException e) { // If we got a TiffException and we're suppressing errors, // cover over the exception and issue an info message; // but we can't follow the IFD chain further. if (suppressErrors) { _info.setMessage(new InfoMessage(e.getMessage(), e.getOffset())); return 0; } else throw e; } }
/** * Parse the IFD. Errors are not suppressed. * * @param byteOffsetIsValid If true, allow offsets on odd byte boundaries * @return The offset of the next IFD */ public long parse(boolean byteOffsetIsValid) throws TiffException { /* Start at the IFD offset, read the number of entries, then * read the entire IFD. */ long offset = _offset; _next = 0L; byte[] buffer; int nFields = 0; try { _raf.seek(offset); nFields = ModuleBase.readUnsignedShort(_raf, _bigEndian); offset += 2; int len = 12 * nFields; buffer = new byte[len]; _raf.read(buffer, 0, len); /* Read the offset of the next IFD (or 0 if none). */ offset += len; _next = ModuleBase.readUnsignedInt(_raf, _bigEndian); } catch (Exception e) { throw new TiffException("Premature EOF", offset); } DataInputStream ifdStream = new DataInputStream(new ByteArrayInputStream(buffer)); try { int prevTag = 0; for (int i = 0; i < nFields; i++) { int tag = ModuleBase.readUnsignedShort(ifdStream, _bigEndian, null); /* Tags must be in ascending numerical order. */ if (!debug_allowoutofsequence && tag < prevTag) { _info.setMessage( new ErrorMessage("Tag " + tag + " out of sequence", _offset + 2 + 12 * i)); _info.setWellFormed(false); } prevTag = tag; int type = ModuleBase.readUnsignedShort(ifdStream, _bigEndian, null); /* Skip over tags with unknown type. */ if (type < BYTE || type > IFD) { _info.setMessage( new ErrorMessage( "Unknown data type", "Type = " + type + ", Tag = " + tag, _offset + 4 + 12 * i)); } else { /* Type gives indication of the TIFF version. */ if (SBYTE <= type && type <= IFD) { _version = 6; } long count = ModuleBase.readUnsignedInt(ifdStream, _bigEndian, null); long value = ModuleBase.readUnsignedInt(ifdStream, _bigEndian, null); if (calcValueSize(type, count) > 4) { /* Value is the word-aligned offset of the actual * value. */ if ((value & 1) != 0) { if (byteOffsetIsValid) { _info.setMessage( new InfoMessage( "Value offset not word-aligned: " + value, _offset + 10 + 12 * i)); } else { throw new TiffException( "Value offset not " + "word-aligned: " + value, _offset + 10 + 12 * i); } } } else { /* Value is the actual value; pass the offset of * the value. */ value = _offset + 10 + 12 * i; } lookupTag(tag, type, count, value); } } } catch (IOException e) { throw new TiffException("Read error", _offset + 2); } postParseInitialization(); return _next; }