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;
  }
Exemple #3
0
  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;
  }
Exemple #4
0
  /**
   * 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;
  }
Exemple #5
0
  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
    }
  }