private static boolean isGlobal(Product product, TiffFileInfo info) { boolean isGlobal = false; final TIFFField pixelScaleField = info.getField(GeoTIFFTagSet.TAG_MODEL_PIXEL_SCALE); if (pixelScaleField != null) { double[] pixelScales = pixelScaleField.getAsDoubles(); if (isPixelScaleValid(pixelScales)) { final double widthInDegree = pixelScales[0] * product.getSceneRasterWidth(); isGlobal = Math.ceil(widthInDegree) >= 360; } } return isGlobal; }
Product readGeoTIFFProduct(final ImageInputStream stream, final File inputFile) throws IOException { Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(stream); while (imageReaders.hasNext()) { final ImageReader reader = imageReaders.next(); if (reader instanceof TIFFImageReader) { imageReader = (TIFFImageReader) reader; break; } } if (imageReader == null) { throw new IOException("GeoTiff imageReader not found"); } imageReader.setInput(stream); Product product = null; final TIFFImageMetadata imageMetadata = (TIFFImageMetadata) imageReader.getImageMetadata(FIRST_IMAGE); final TiffFileInfo tiffInfo = new TiffFileInfo(imageMetadata.getRootIFD()); final TIFFField field = tiffInfo.getField(Utils.PRIVATE_BEAM_TIFF_TAG_NUMBER); if (field != null && field.getType() == TIFFTag.TIFF_ASCII) { final String s = field.getAsString(0).trim(); if (s.contains("<Dimap_Document")) { // with DIMAP header InputStream is = null; try { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); final DocumentBuilder builder = factory.newDocumentBuilder(); is = new ByteArrayInputStream(s.getBytes()); final Document document = new DOMBuilder().build(builder.parse(is)); product = DimapProductHelpers.createProduct(document); removeGeoCodingAndTiePointGrids(product); initBandsMap(product); } catch (ParserConfigurationException | SAXException ignore) { // ignore if it can not be read } finally { if (is != null) { is.close(); } } } } if (product == null) { // without DIMAP header final String productName; if (tiffInfo.containsField(BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION)) { final TIFFField field1 = tiffInfo.getField(BaselineTIFFTagSet.TAG_IMAGE_DESCRIPTION); productName = field1.getAsString(0); } else if (inputFile != null) { productName = FileUtils.getFilenameWithoutExtension(inputFile); } else { productName = "geotiff"; } final String productType = getReaderPlugIn().getFormatNames()[0]; final int width = imageReader.getWidth(FIRST_IMAGE); final int height = imageReader.getHeight(FIRST_IMAGE); product = new Product(productName, productType, width, height, this); addBandsToProduct(tiffInfo, product); } if (tiffInfo.isGeotiff()) { applyGeoCoding(tiffInfo, imageMetadata, product); } TiffTagToMetadataConverter.addTiffTagsToMetadata( imageMetadata, tiffInfo, product.getMetadataRoot()); if (inputFile != null) { product.setFileLocation(inputFile); } setPreferredTiling(product); return product; }
public void writeToStream(ImageOutputStream stream, final boolean isBTIFF) throws IOException { long nextSpace; if (!isBTIFF) { int numFields = getNumTIFFFields(); stream.writeShort(numFields); nextSpace = stream.getStreamPosition() + 12 * numFields + 4; } else { long numFields = getNumTIFFFields(); stream.writeLong(numFields); nextSpace = stream.getStreamPosition() + 20 * numFields + 8; } Iterator iter = iterator(); while (iter.hasNext()) { TIFFField f = (TIFFField) iter.next(); TIFFTag tag = f.getTag(); int type = f.getType(); int count = f.getCount(); // Hack to deal with unknown tags if (type == 0) { type = TIFFTag.TIFF_UNDEFINED; } int size = count * TIFFTag.getSizeOfType(type); if (type == TIFFTag.TIFF_ASCII) { int chars = 0; for (int i = 0; i < count; i++) { chars += f.getAsString(i).length() + 1; } count = chars; size = count; } int tagNumber = f.getTagNumber(); stream.writeShort(tagNumber); stream.writeShort(type); if (isBTIFF) { stream.writeLong(count); stream.writeLong(0); stream.mark(); // Mark beginning of next field stream.skipBytes(-8); } else { stream.writeInt(count); stream.writeInt(0); stream.mark(); // Mark beginning of next field stream.skipBytes(-4); } long pos; if (!isBTIFF) { if (size > 4 || tag.isIFDPointer()) { // Ensure IFD or value is written on a word boundary nextSpace = (nextSpace + 3) & ~0x3; stream.writeInt((int) nextSpace); stream.seek(nextSpace); pos = nextSpace; if (tag.isIFDPointer()) { TIFFIFD subIFD = (TIFFIFD) f.getData(); subIFD.writeToStream(stream, isBTIFF); nextSpace = subIFD.lastPosition; } else { writeTIFFFieldToStream(f, stream); nextSpace = stream.getStreamPosition(); } } else { pos = stream.getStreamPosition(); writeTIFFFieldToStream(f, stream); } } else { if (size > 8 || tag.isIFDPointer()) { // Ensure IFD or value is written on a Long boundary nextSpace = (nextSpace + 7) & ~0x7; stream.writeLong(nextSpace); stream.seek(nextSpace); pos = nextSpace; if (tag.isIFDPointer()) { TIFFIFD subIFD = (TIFFIFD) f.getData(); subIFD.writeToStream(stream, isBTIFF); nextSpace = subIFD.lastPosition; } else { writeTIFFFieldToStream(f, stream); nextSpace = stream.getStreamPosition(); } } else { pos = stream.getStreamPosition(); writeTIFFFieldToStream(f, stream); } } // If we are writing the data for the // StripByteCounts, TileByteCounts, StripOffsets, // TileOffsets, JPEGInterchangeFormat, or // JPEGInterchangeFormatLength fields, record the current stream // position for backpatching if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS || tagNumber == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) { this.stripOrTileByteCountsPosition = pos; } else if (tagNumber == BaselineTIFFTagSet.TAG_STRIP_OFFSETS || tagNumber == BaselineTIFFTagSet.TAG_TILE_OFFSETS || tagNumber == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) { this.stripOrTileOffsetsPosition = pos; } stream.reset(); // Go to marked position of next field } this.lastPosition = nextSpace; }
/** * Returns a <code>TIFFIFD</code> wherein all fields from the <code>BaselineTIFFTagSet</code> are * copied by value and all other fields copied by reference. */ public TIFFIFD getShallowClone() { // Get the baseline TagSet. TIFFTagSet baselineTagSet = BaselineTIFFTagSet.getInstance(); // If the baseline TagSet is not included just return. List tagSetList = getTagSetList(); if (!tagSetList.contains(baselineTagSet)) { return this; } // Create a new object. TIFFIFD shallowClone = new TIFFIFD(tagSetList, getParentTag()); // Get the tag numbers in the baseline set. Set baselineTagNumbers = baselineTagSet.getTagNumbers(); // Iterate over the fields in this IFD. Iterator fields = iterator(); while (fields.hasNext()) { // Get the next field. TIFFField field = (TIFFField) fields.next(); // Get its tag number. Integer tagNumber = new Integer(field.getTagNumber()); // Branch based on membership in baseline set. TIFFField fieldClone; if (baselineTagNumbers.contains(tagNumber)) { // Copy by value. Object fieldData = field.getData(); int fieldType = field.getType(); try { switch (fieldType) { case TIFFTag.TIFF_BYTE: case TIFFTag.TIFF_SBYTE: case TIFFTag.TIFF_UNDEFINED: fieldData = ((byte[]) fieldData).clone(); break; case TIFFTag.TIFF_ASCII: fieldData = ((String[]) fieldData).clone(); break; case TIFFTag.TIFF_SHORT: fieldData = ((char[]) fieldData).clone(); break; case TIFFTag.TIFF_LONG: case TIFFTag.TIFF_IFD_POINTER: fieldData = ((long[]) fieldData).clone(); break; case TIFFTag.TIFF_RATIONAL: fieldData = ((long[][]) fieldData).clone(); break; case TIFFTag.TIFF_SSHORT: fieldData = ((short[]) fieldData).clone(); break; case TIFFTag.TIFF_SLONG: fieldData = ((int[]) fieldData).clone(); break; case TIFFTag.TIFF_SRATIONAL: fieldData = ((int[][]) fieldData).clone(); break; case TIFFTag.TIFF_FLOAT: fieldData = ((float[]) fieldData).clone(); break; case TIFFTag.TIFF_DOUBLE: fieldData = ((double[]) fieldData).clone(); break; default: // Shouldn't happen but do nothing ... } } catch (Exception e) { // Ignore it and copy by reference ... } fieldClone = new TIFFField( field.getTag(), fieldType, field.getCount(), fieldData); } else { // Copy by reference. fieldClone = field; } // Add the field to the clone. shallowClone.addTIFFField(fieldClone); } // Set positions. shallowClone.setPositions( stripOrTileOffsetsPosition, stripOrTileByteCountsPosition, lastPosition); return shallowClone; }
private static void writeTIFFFieldToStream(TIFFField field, ImageOutputStream stream) throws IOException { int count = field.getCount(); Object data = field.getData(); switch (field.getType()) { case TIFFTag.TIFF_ASCII: for (int i = 0; i < count; i++) { String s = ((String[]) data)[i]; int length = s.length(); for (int j = 0; j < length; j++) { stream.writeByte(s.charAt(j) & 0xff); } stream.writeByte(0); } break; case TIFFTag.TIFF_UNDEFINED: case TIFFTag.TIFF_BYTE: case TIFFTag.TIFF_SBYTE: stream.write((byte[]) data); break; case TIFFTag.TIFF_SHORT: stream.writeChars((char[]) data, 0, ((char[]) data).length); break; case TIFFTag.TIFF_SSHORT: stream.writeShorts((short[]) data, 0, ((short[]) data).length); break; case TIFFTag.TIFF_SLONG: stream.writeInts((int[]) data, 0, ((int[]) data).length); break; case TIFFTag.TIFF_LONG: for (int i = 0; i < count; i++) { stream.writeInt((int) (((long[]) data)[i])); } break; case TIFFTag.TIFF_LONG8: stream.writeLongs((long[]) data, 0, ((long[]) data).length); break; case TIFFTag.TIFF_IFD_POINTER: stream.writeInt(0); // will need to be backpatched break; case TIFFTag.TIFF_FLOAT: stream.writeFloats((float[]) data, 0, ((float[]) data).length); break; case TIFFTag.TIFF_DOUBLE: stream.writeDoubles((double[]) data, 0, ((double[]) data).length); break; case TIFFTag.TIFF_SRATIONAL: for (int i = 0; i < count; i++) { stream.writeInt(((int[][]) data)[i][0]); stream.writeInt(((int[][]) data)[i][1]); } break; case TIFFTag.TIFF_RATIONAL: for (int i = 0; i < count; i++) { long num = ((long[][]) data)[i][0]; long den = ((long[][]) data)[i][1]; stream.writeInt((int) num); stream.writeInt((int) den); } break; default: // error } }