Beispiel #1
0
 private BufferedImage getImage(File file) {
   ImageInputStream iis = null;
   BufferedImage image = null;
   try {
     iis = ImageIO.createImageInputStream(file);
     Iterator<ImageReader> it = ImageIO.getImageReaders(iis);
     if (!it.hasNext()) throw new UnsupportedOperationException("No image reader fround.");
     ImageReader reader = it.next();
     reader.setInput(iis);
     int scaleFactor;
     if (reader.getWidth(0) >= reader.getHeight(0))
       scaleFactor = Math.round(((float) reader.getWidth(0)) / MAX_SIZE);
     else scaleFactor = Math.round(((float) reader.getHeight(0)) / MAX_SIZE);
     ImageReadParam param = reader.getDefaultReadParam();
     param.setSourceSubsampling(scaleFactor, scaleFactor, 0, 0);
     image = reader.read(0, param);
   } catch (IOException e) {
     e.printStackTrace();
   } finally {
     if (iis != null)
       try {
         iis.close();
       } catch (IOException e) {
         e.printStackTrace();
       }
   }
   return image;
 }
  /**
   * Gets resolution information about the coverage itself.
   *
   * @param reader an {@link ImageReader} to use for getting the resolution information.
   * @throws IOException
   * @throws TransformException
   * @throws DataSourceException
   */
  private void getResolutionInfo(ImageReader reader) throws IOException, TransformException {
    // //
    //
    // get the dimension of the high resolution image and compute the
    // resolution
    //
    // //
    final Rectangle originalDim = new Rectangle(0, 0, reader.getWidth(0), reader.getHeight(0));
    if (originalGridRange == null) {
      originalGridRange = new GridEnvelope2D(originalDim);
    }

    // ///
    //
    // setting the higher resolution available for this coverage
    //
    // ///
    highestRes = CoverageUtilities.getResolution((AffineTransform) raster2Model);

    if (LOGGER.isLoggable(Level.FINE))
      LOGGER.fine(
          new StringBuffer("Highest Resolution = [")
              .append(highestRes[0])
              .append(",")
              .append(highestRes[1])
              .toString());
  }
Beispiel #3
0
 public Dimension getImageDimensions(InputStream imageStream) {
   ImageInputStream in = null;
   Dimension dimension = null;
   try {
     in = ImageIO.createImageInputStream(imageStream);
     final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
     if (readers.hasNext()) {
       ImageReader reader = readers.next();
       try {
         reader.setInput(in);
         dimension = new Dimension(reader.getWidth(0), reader.getHeight(0));
       } finally {
         reader.dispose();
       }
     }
   } catch (IOException e) {
     e.printStackTrace();
   } finally {
     if (in != null)
       try {
         in.close();
       } catch (Exception e) {
         e.printStackTrace();
       }
   }
   return dimension;
 }
  private Dimension getSize(File file) {
    try {
      ImageInputStream input = ImageIO.createImageInputStream(file);
      if (input != null) {
        try {
          Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
          if (readers.hasNext()) {
            ImageReader reader = readers.next();
            try {
              reader.setInput(input);
              return new Dimension(reader.getWidth(0), reader.getHeight(0));
            } finally {
              reader.dispose();
            }
          }
        } finally {
          if (input != null) {
            input.close();
          }
        }
      }

      // Fallback: read the image using the normal means
      BufferedImage image = ImageIO.read(file);
      if (image != null) {
        return new Dimension(image.getWidth(), image.getHeight());
      } else {
        return null;
      }
    } catch (IOException e) {
      // Pass -- we can't handle all image types, warn about those we can
      return null;
    }
  }
Beispiel #5
0
  private static Dimension getSizeUsingImageIO(URL url) throws IOException {
    InputStream in = null;
    ImageInputStream iis = null;
    ImageReader reader = null;
    try {
      in = url.openStream();
      iis = new MemoryCacheImageInputStream(in);
      Iterator<ImageReader> it = ImageIO.getImageReaders(iis);
      if (!it.hasNext()) return null;

      reader = it.next();
      reader.setInput(iis, true, true);

      Dimension d = new Dimension(reader.getWidth(0), reader.getHeight(0));
      if (d.width <= 0 || d.height <= 0)
        throw new RuntimeException("invalid dimensions: " + d.width + "x" + d.height);
      return d;
    } finally {
      try {
        if (reader != null) reader.dispose();
      } catch (Exception e) {
        e.printStackTrace();
      }
      try {
        if (iis != null) iis.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
      try {
        if (in != null) in.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }
  /**
   * Write world image extensions : TFW, PRJ, TAB
   *
   * @param request
   * @param file
   * @param in
   * @throws IOException
   */
  private void writeWorldImageExt(WcsReaderRequest request, File file) throws IOException {

    String baseFilePath = file.getPath().substring(0, file.getPath().lastIndexOf('.'));

    // Compute image size and image transformed BBOX
    ReferencedEnvelope transformedBBox;
    AffineTransform transform;

    int width = -1;
    int height = -1;
    String ext = FileUtils.extension(file);

    try {
      final Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(ext.substring(1));

      while (readers.hasNext() && width < 0 && height < 0) {
        ImageInputStream stream = null;
        try {
          ImageReader reader = readers.next();
          stream = ImageIO.createImageInputStream(file.getAbsoluteFile());
          reader.setInput(stream, true, false);
          width = reader.getWidth(0);
          height = reader.getHeight(0);
          break;
        } catch (Exception e) {
          width = -1;
          height = -1;
          // try next reader;
        } finally {
          if (stream != null) {
            stream.close();
          }
        }
      }

      transformedBBox = request.requestBbox.transform(request.responseCRS, true, 10);
      if (width < 0) {
        width = (int) Math.round(transformedBBox.getWidth() / request.crsResolution());
      }

      if (height < 0) {
        height = (int) Math.round(transformedBBox.getHeight() / request.crsResolution());
      }

      Rectangle imageSize = new Rectangle(width, height);
      transform = RendererUtilities.worldToScreenTransform(transformedBBox, imageSize);
      transform.invert();

    } catch (Exception e) {
      throw new ExtractorException(e);
    }

    // Generate TFW TAB PRJ files
    createWorldFile(transform, ext, baseFilePath);
    createTABFile(transformedBBox, width, height, baseFilePath, ext);
    createPrjFile(request.responseCRS, baseFilePath);
  }
Beispiel #7
0
 /*
  * 图片裁剪二分之一
  */
 public static void cutHalfImage(String src, String dest) throws IOException {
   Iterator iterator = ImageIO.getImageReadersByFormatName("jpg");
   ImageReader reader = (ImageReader) iterator.next();
   InputStream in = new FileInputStream(src);
   ImageInputStream iis = ImageIO.createImageInputStream(in);
   reader.setInput(iis, true);
   ImageReadParam param = reader.getDefaultReadParam();
   int imageIndex = 0;
   int width = reader.getWidth(imageIndex) / 2;
   int height = reader.getHeight(imageIndex) / 2;
   Rectangle rect = new Rectangle(width / 2, height / 2, width, height);
   param.setSourceRegion(rect);
   BufferedImage bi = reader.read(0, param);
   ImageIO.write(bi, "jpg", new File(dest));
 }
  /**
   * Extract the ImageLayout from the provided reader for the first available image.
   *
   * @param reader an istance of {@link ImageReader}
   * @throws IOException in case an error occurs
   */
  protected void setLayout(ImageReader reader) throws IOException {

    Utilities.ensureNonNull("reader", reader);
    // save ImageLayout
    ImageLayout2 layout = new ImageLayout2();
    ImageTypeSpecifier its = reader.getImageTypes(0).next();
    layout.setColorModel(its.getColorModel()).setSampleModel(its.getSampleModel());
    layout.setMinX(0).setMinY(0).setWidth(reader.getWidth(0)).setHeight(reader.getHeight(0));
    layout
        .setTileGridXOffset(0)
        .setTileGridYOffset(0)
        .setTileWidth(reader.getTileWidth(0))
        .setTileHeight(reader.getTileHeight(0));
    setlayout(layout);
  }
Beispiel #9
0
 /**
  * Retrieve image dimensions. This method simply reads headers so it should perform relatively
  * fast.
  */
 protected static Dimension retrieveImageDimensions(File imageFile) throws IOException {
   long start = System.currentTimeMillis();
   if (!imageFile.exists()) {
     logger.info(
         "No file found while determining image dimensions: " + imageFile.getAbsolutePath());
     return null;
   }
   ImageInputStream iis = null;
   Dimension dimensions = null;
   ImageReader reader = null;
   // use a FileInputStream and make sure it gets closed to prevent unclosed file
   // errors on some operating systems
   FileInputStream fis = null;
   try {
     fis = new FileInputStream(imageFile);
     iis = ImageIO.createImageInputStream(fis);
     Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
     if (readers.hasNext()) {
       reader = readers.next();
       reader.setInput(iis, true);
       dimensions = new Dimension(reader.getWidth(0), reader.getHeight(0));
     }
   } finally {
     if (reader != null) {
       reader.dispose();
     }
     if (iis != null) {
       try {
         iis.close();
       } catch (IOException e) {
         // ignore
       }
     }
     IOUtils.closeQuietly(fis);
   }
   if (logger.isDebugEnabled()) {
     long execution = (System.currentTimeMillis() - start);
     logger.debug(
         "Image dimension lookup for "
             + imageFile.getAbsolutePath()
             + " took "
             + (execution / 1000.000)
             + " s");
   }
   return dimensions;
 }
  public static Dimension getDimesion(InputStream input) throws IOException {
    try (ImageInputStream in = ImageIO.createImageInputStream(input)) {
      final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
      if (readers.hasNext()) {
        ImageReader reader = readers.next();
        try {
          reader.setInput(in);
          return new Dimension(reader.getWidth(0), reader.getHeight(0));
        } finally {
          reader.dispose();
        }
      }
    } catch (IOException ex) {
    }

    BufferedImage image = read(input);
    return new Dimension(image.getWidth(), image.getHeight());
  }
  private List<Tile> toTiles(
      ImageReaderSpi provider, TileReaderPool readers, Set<ImageReaderSpi> providers, Path input)
      throws IOException {

    // Creates the tile for the first image, which usually have the maximal resolution.
    // The Tile constructor will read the TFW file and infer a provider if the given
    // 'provider' argument is null. If this is a new provider, then we need to declare
    // it to the pool of image readers before to use it.
    final List<Tile> tiles = new ArrayList<>();
    final Tile root = new Tile(provider, input, 0);
    if (providers.add(root.getImageReaderSpi())) {
      readers.setProviders(providers);
    }

    final AffineTransform scaledGridToCRS = new AffineTransform();
    final AffineTransform gridToCRS = root.getPendingGridToCRS(false);
    final ImageReader reader = root.getImageReader(readers, true, true);
    final int numImages = reader.getNumImages(false); // Result may be -1.
    for (int index = 0; index != numImages; index++) { // Intentional use of !=, not <.
      final int width, height;
      try {
        width = reader.getWidth(index);
        height = reader.getHeight(index);
      } catch (IndexOutOfBoundsException e) {
        // As explained in ImageReader javadoc, this approach is sometime
        // more efficient than invoking reader.getNumImages(true) first.
        break;
      }
      final Tile tile;
      if (index == 0) {
        tile = root;
      } else {
        final Rectangle region = root.getRegion();
        scaledGridToCRS.setTransform(new AffineTransform(gridToCRS));
        scaledGridToCRS.scale(region.width / (double) width, region.height / (double) height);
        tile = new Tile(root.getImageReaderSpi(), input, index, region, scaledGridToCRS);
      }
      tile.setSize(width, height);
      tiles.add(tile);
    }
    reader.dispose();
    return tiles;
  }
Beispiel #12
0
 public static String getImageDim(final String path, final String suffix) {
   int width = 0;
   int height = 0;
   // Dimension result = null;
   Iterator<ImageReader> iter = ImageIO.getImageReadersBySuffix(suffix);
   if (iter.hasNext()) {
     ImageReader reader = iter.next();
     try {
       ImageInputStream stream = new FileImageInputStream(new File(path));
       reader.setInput(stream);
       width = reader.getWidth(reader.getMinIndex());
       height = reader.getHeight(reader.getMinIndex());
       // result = new Dimension(width, height);
     } catch (IOException e) {
     } finally {
       reader.dispose();
     }
   } else {
   }
   return "" + width + "::" + height;
 }
Beispiel #13
0
  @Test
  public void imageReadParam() throws IOException {
    Iterator<ImageReader> itr = ImageIO.getImageReadersByFormatName("jpg");
    ImageReader imageReader = itr.next();

    ImageInputStream imageInputStream = ImageIO.createImageInputStream(new File(SRCIMG));

    imageReader.setInput(imageInputStream, true);

    ImageReadParam imageReadParam = imageReader.getDefaultReadParam();
    int halfWidth = imageReader.getWidth(0) / 2;
    int halfHeight = imageReader.getHeight(0) / 2;
    Rectangle rectangle = new Rectangle(0, 0, halfWidth, halfHeight);
    imageReadParam.setSourceRegion(rectangle);

    BufferedImage bufferedImage = imageReader.read(0, imageReadParam);
    System.out.println(bufferedImage.getWidth());

    boolean result = ImageIO.write(bufferedImage, "png", new File(CONTEXT + "999.png"));
    System.out.println(result);
  }
  /**
   * Standard constructor: needs a PictureFileDataPolicy.
   *
   * @param file The files which data are to be handled by this instance.
   * @param root The root directory, to calculate the relative dir (see {@link #getRelativeDir()}.
   * @param uploadPolicy The current upload policy
   * @throws JUploadIOException Encapsulation of the IOException, if any would occurs.
   */
  public PictureFileData(File file, File root, PictureUploadPolicy uploadPolicy)
      throws JUploadIOException {
    super(file, root, uploadPolicy);
    // EGR Should be useless
    // this.uploadPolicy = (PictureUploadPolicy) super.uploadPolicy;
    this.storeBufferedImage = uploadPolicy.hasToStoreBufferedImage();

    String fileExtension = getFileExtension();

    // Is it a picture?
    Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName(fileExtension);
    if (iter.hasNext()) {
      // It's a picture: we store its original width and height, for
      // further calculation (rescaling and rotation).
      this.isPicture = true;
      try {
        FileImageInputStream fiis = new FileImageInputStream(getFile());
        ImageReader ir = iter.next();
        ir.setInput(fiis);
        this.originalHeight = ir.getHeight(0);
        this.originalWidth = ir.getWidth(0);
        ir.dispose();
        fiis.close();
      } catch (IOException e) {
        throw new JUploadIOException("PictureFileData()", e);
      }
    } else {
      this.isPicture = false;
    }
    // Let's log the test result
    uploadPolicy.displayDebug(
        "isPicture=" + this.isPicture + " (" + file.getName() + "), extension=" + fileExtension,
        75);

    // If it's a picture, we override the default mime type:
    if (this.isPicture) {
      setMimeTypeByExtension(fileExtension);
    }
  }
    private static MalletTexture.Meta createMeta(final String _path, final InputStream _stream) {
      try (final ImageInputStream in = ImageIO.createImageInputStream(_stream)) {
        final Iterator<ImageReader> readers = ImageIO.getImageReaders(in);
        if (readers.hasNext()) {
          final ImageReader reader = readers.next();
          try {
            reader.setInput(in);
            // Add additional Meta information to MalletTexture as
            // and when it becomes needed. It shouldn't hold too much (RGB, RGBA, Mono, endinese,
            // 32, 24-bit, etc)
            // data as a game-developer shouldn't need detailed information.
            return new MalletTexture.Meta(_path, reader.getHeight(0), reader.getWidth(0));
          } finally {
            reader.dispose();
          }
        }
      } catch (IOException ex) {
        ex.printStackTrace();
      }

      return null;
    }
  private BufferedImage scaleDown(
      final ImageInputStream inputStream, final int maxWidth, final int maxHeight)
      throws IOException {
    final Iterator<ImageReader> readers = ImageIO.getImageReaders(inputStream);
    if (!readers.hasNext()) {
      throw new IOException("No ImageReader available for the given ImageInputStream");
    }
    // Use the first reader, next will instantiate ImageReader which needs to be disposed
    final ImageReader reader = readers.next();
    try {
      final ImageReadParam param = reader.getDefaultReadParam();
      reader.setInput(inputStream);

      final Dimension original = new Dimension(reader.getWidth(0), reader.getHeight(0));
      final Dimension target = new Dimension(maxWidth, maxHeight);
      final int ratio = maintainAspectRatio(original, target);
      param.setSourceSubsampling(ratio, ratio, 0, 0);

      return reader.read(0, param);
    } finally {
      reader.dispose();
    }
  }
  private static JSONObject getResultJson(File file, boolean extractLiveProject)
      throws IOException, JSONException, ScriptException {
    final JSONObject result = new JSONObject();
    result.put("formatChecked", true);
    final ImageInputStream iis = ImageIO.createImageInputStream(file);
    final Iterator<ImageReader> iterator = ImageIO.getImageReaders(iis);
    if (!iterator.hasNext()) {
      result.put("rejected", true);
      result.put("message", "Unknown image format: can't create an ImageInputStream");
      return result;
    }
    final ImageReader reader = iterator.next();
    final JSONObject imageType = SimagisLiveUtils.openObject(result, "imageType");
    try {
      reader.setInput(iis);
      JSONObject formatSpecific = new JSONObject();
      formatSpecific.put("javaFormatType", "DICOM");
      formatSpecific.put("javaFormatName", reader.getFormatName());
      result.put("formatSpecific", formatSpecific);

      final int dimX = reader.getWidth(0);
      final int dimY = reader.getHeight(0);
      if ((long) dimX * (long) dimY >= 512L * 1024L * 1024L) {
        result.put("rejected", true);
        result.put("message", "Too large image (more than 512 million pixels)");
        return result;
        // We are little reinsuring here: Java API can try to create a single byte[]
        // or short[] array with packed RGB triples (3 * dimX * dimY), and we would like
        // to be sure that its size will be far from the Java language limit 2 GB.
      }
      result.put("dimX", dimX);
      result.put("dimY", dimY);
      final Iterator<ImageTypeSpecifier> iioImageTypes = reader.getImageTypes(0);
      if (iioImageTypes != null && iioImageTypes.hasNext()) {
        // some 3rd party implementation can still return null here, though it is prohibited in
        // JavaDoc
        ImageTypeSpecifier imageTypeSpecifier = iioImageTypes.next();
        imageType.put("numComponents", imageTypeSpecifier.getNumComponents());
        imageType.put("numBands", imageTypeSpecifier.getNumBands());
        if (imageTypeSpecifier.getNumComponents() >= 4) {
          result.put("recommendedRenderingFormat", "png");
        }
      }
      final IIOMetadata streamMetadata = reader.getStreamMetadata();
      final IIOMetadataToJsonConverter converter = new IIOMetadataToJsonConverter();
      if (streamMetadata != null) {
        DICOMImageIOMetadata imageIOMetadata = DICOMImageIOMetadata.getInstance(streamMetadata, 0);
        if (imageIOMetadata != null) {
          result.put("DICOMMetadata", new JSONObject(imageIOMetadata));
        }
        result.put("streamMetadata", converter.toJson(streamMetadata));
      }
      final IIOMetadata imageMetadata = reader.getImageMetadata(0);
      if (imageMetadata != null) {
        result.put("imageMetadata", converter.toJson(imageMetadata));
      }
    } finally {
      reader.dispose();
      iis.close();
    }
    if (extractLiveProject) {
      JSONObject liveProject = extractLiveProject(result);
      result.put("liveProject", liveProject);
      result.remove("imageMetadata");
      result.remove("streamMetadata");
    }
    result.put("rejected", false);
    return result;
  }
Beispiel #18
0
  /**
   * Initializes these instance variables from the image metadata:
   *
   * <pre>
   * compression
   * width
   * height
   * samplesPerPixel
   * numBands
   * colorMap
   * photometricInterpretation
   * sampleFormat
   * bitsPerSample
   * extraSamples
   * tileOrStripWidth
   * tileOrStripHeight
   * </pre>
   */
  private void initializeFromMetadata() {
    TIFFField f;

    // Compression
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COMPRESSION);
    if (f == null) {
      processWarningOccurred("Compression field is missing; assuming no compression");
      compression = BaselineTIFFTagSet.COMPRESSION_NONE;
    } else {
      compression = f.getAsInt(0);
    }

    // Whether key dimensional information is absent.
    boolean isMissingDimension = false;

    // ImageWidth -> width
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH);
    if (f != null) {
      this.width = f.getAsInt(0);
    } else {
      processWarningOccurred("ImageWidth field is missing.");
      isMissingDimension = true;
    }

    // ImageLength -> height
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH);
    if (f != null) {
      this.height = f.getAsInt(0);
    } else {
      processWarningOccurred("ImageLength field is missing.");
      isMissingDimension = true;
    }

    // SamplesPerPixel
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL);
    if (f != null) {
      samplesPerPixel = f.getAsInt(0);
    } else {
      samplesPerPixel = 1;
      isMissingDimension = true;
    }

    // If any dimension is missing and there is a JPEG stream available
    // get the information from it.
    int defaultBitDepth = 1;
    if (isMissingDimension
        && (f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT))
            != null) {
      Iterator iter = ImageIO.getImageReadersByFormatName("JPEG");
      if (iter != null && iter.hasNext()) {
        ImageReader jreader = (ImageReader) iter.next();
        try {
          stream.mark();
          stream.seek(f.getAsLong(0));
          jreader.setInput(stream);
          if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_WIDTH) == null) {
            this.width = jreader.getWidth(0);
          }
          if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_IMAGE_LENGTH) == null) {
            this.height = jreader.getHeight(0);
          }
          ImageTypeSpecifier imageType = jreader.getRawImageType(0);
          if (imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLES_PER_PIXEL) == null) {
            this.samplesPerPixel = imageType.getSampleModel().getNumBands();
          }
          stream.reset();
          defaultBitDepth = imageType.getColorModel().getComponentSize(0);
        } catch (IOException e) {
          // Ignore it and proceed: an error will occur later.
        }
        jreader.dispose();
      }
    }

    if (samplesPerPixel < 1) {
      processWarningOccurred("Samples per pixel < 1!");
    }

    // SamplesPerPixel -> numBands
    numBands = samplesPerPixel;

    // ColorMap
    this.colorMap = null;
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_COLOR_MAP);
    if (f != null) {
      // Grab color map
      colorMap = f.getAsChars();
    }

    // PhotometricInterpretation
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_PHOTOMETRIC_INTERPRETATION);
    if (f == null) {
      if (compression == BaselineTIFFTagSet.COMPRESSION_CCITT_RLE
          || compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_4
          || compression == BaselineTIFFTagSet.COMPRESSION_CCITT_T_6) {
        processWarningOccurred(
            "PhotometricInterpretation field is missing; " + "assuming WhiteIsZero");
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO;
      } else if (this.colorMap != null) {
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR;
      } else if (samplesPerPixel == 3 || samplesPerPixel == 4) {
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_RGB;
      } else {
        processWarningOccurred(
            "PhotometricInterpretation field is missing; " + "assuming BlackIsZero");
        photometricInterpretation = BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO;
      }
    } else {
      photometricInterpretation = f.getAsInt(0);
    }

    // SampleFormat
    boolean replicateFirst = false;
    int first = -1;

    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_SAMPLE_FORMAT);
    sampleFormat = new int[samplesPerPixel];
    replicateFirst = false;
    if (f == null) {
      replicateFirst = true;
      first = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED;
    } else if (f.getCount() != samplesPerPixel) {
      replicateFirst = true;
      first = f.getAsInt(0);
    }

    for (int i = 0; i < samplesPerPixel; i++) {
      sampleFormat[i] = replicateFirst ? first : f.getAsInt(i);
      if (sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER
          && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER
          && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT
          && sampleFormat[i] != BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED) {
        processWarningOccurred("Illegal value for SAMPLE_FORMAT, assuming SAMPLE_FORMAT_UNDEFINED");
        sampleFormat[i] = BaselineTIFFTagSet.SAMPLE_FORMAT_UNDEFINED;
      }
    }

    // BitsPerSample
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_BITS_PER_SAMPLE);
    this.bitsPerSample = new int[samplesPerPixel];
    replicateFirst = false;
    if (f == null) {
      replicateFirst = true;
      first = defaultBitDepth;
    } else if (f.getCount() != samplesPerPixel) {
      replicateFirst = true;
      first = f.getAsInt(0);
    }

    for (int i = 0; i < samplesPerPixel; i++) {
      // Replicate initial value if not enough values provided
      bitsPerSample[i] = replicateFirst ? first : f.getAsInt(i);

      if (DEBUG) {
        System.out.println("bitsPerSample[" + i + "] = " + bitsPerSample[i]);
      }
    }

    // ExtraSamples
    this.extraSamples = null;
    f = imageMetadata.getTIFFField(BaselineTIFFTagSet.TAG_EXTRA_SAMPLES);
    if (f != null) {
      extraSamples = f.getAsInts();
    }

    //         System.out.println("colorMap = " + colorMap);
    //         if (colorMap != null) {
    //             for (int i = 0; i < colorMap.length; i++) {
    //              System.out.println("colorMap[" + i + "] = " + (int)(colorMap[i]));
    //             }
    //         }

  }
  /**
   * Collect georeferencing information about this geotiff.
   *
   * @param hints
   * @throws DataSourceException
   */
  private void getHRInfo(Hints hints) throws DataSourceException {
    ImageReader reader = null;
    ImageReader ovrReader = null;
    ImageInputStream ovrStream = null;
    try {
      // //
      //
      // Get a reader for this format
      //
      // //
      reader = READER_SPI.createReaderInstance();

      // //
      //
      // get the METADATA
      //
      // //
      inStream.mark();
      reader.setInput(inStream);
      final IIOMetadata iioMetadata = reader.getImageMetadata(0);
      final GeoTiffIIOMetadataDecoder metadata = new GeoTiffIIOMetadataDecoder(iioMetadata);
      gtcs = new GeoTiffMetadata2CRSAdapter(hints);

      // //
      //
      // get the CRS INFO
      //
      // //
      final Object tempCRS = this.hints.get(Hints.DEFAULT_COORDINATE_REFERENCE_SYSTEM);
      if (tempCRS != null) {
        this.crs = (CoordinateReferenceSystem) tempCRS;
        if (LOGGER.isLoggable(Level.FINE))
          LOGGER.log(Level.FINE, "Using forced coordinate reference system");
      } else {

        // check external prj first
        crs = getCRS(source);

        // now, if we did not want to override the inner CRS or we did not have any external PRJ at
        // hand
        // let's look inside the geotiff
        if (!OVERRIDE_INNER_CRS || crs == null) {
          if (metadata.hasGeoKey() && gtcs != null) {
            crs = gtcs.createCoordinateSystem(metadata);
          }
        }
      }

      //
      // No data
      //
      if (metadata.hasNoData()) {
        noData = metadata.getNoData();
      }

      //
      // parse and set layout
      //
      setLayout(reader);

      // //
      //
      // get the dimension of the hr image and build the model as well as
      // computing the resolution
      // //
      numOverviews = reader.getNumImages(true) - 1;
      int hrWidth = reader.getWidth(0);
      int hrHeight = reader.getHeight(0);
      final Rectangle actualDim = new Rectangle(0, 0, hrWidth, hrHeight);
      originalGridRange = new GridEnvelope2D(actualDim);

      if (gtcs != null
          && metadata != null
          && (metadata.hasModelTrasformation()
              || (metadata.hasPixelScales() && metadata.hasTiePoints()))) {
        this.raster2Model = GeoTiffMetadata2CRSAdapter.getRasterToModel(metadata);
      } else {
        // world file
        this.raster2Model = parseWorldFile(source);

        // now world file --> mapinfo?
        if (raster2Model == null) {
          MapInfoFileReader mifReader = parseMapInfoFile(source);
          if (mifReader != null) {
            raster2Model = mifReader.getTransform();
            crs = mifReader.getCRS();
          }
        }
      }

      if (crs == null) {
        if (LOGGER.isLoggable(Level.WARNING)) {
          LOGGER.warning("Coordinate Reference System is not available");
        }
        crs = AbstractGridFormat.getDefaultCRS();
      }

      if (this.raster2Model == null) {
        TiePoint[] modelTiePoints = metadata.getModelTiePoints();
        if (modelTiePoints != null && modelTiePoints.length > 1) {
          // use a unit transform and expose the GCPs
          gcps = new GroundControlPoints(Arrays.asList(modelTiePoints), crs);
          raster2Model = ProjectiveTransform.create(new AffineTransform());
          crs = AbstractGridFormat.getDefaultCRS();
        } else {
          throw new DataSourceException("Raster to Model Transformation is not available");
        }
      }

      // create envelope using corner transformation
      final AffineTransform tempTransform = new AffineTransform((AffineTransform) raster2Model);
      tempTransform.concatenate(CoverageUtilities.CENTER_TO_CORNER);
      originalEnvelope =
          CRS.transform(ProjectiveTransform.create(tempTransform), new GeneralEnvelope(actualDim));
      originalEnvelope.setCoordinateReferenceSystem(crs);

      // ///
      //
      // setting the higher resolution available for this coverage
      //
      // ///
      highestRes = new double[2];
      highestRes[0] = XAffineTransform.getScaleX0(tempTransform);
      highestRes[1] = XAffineTransform.getScaleY0(tempTransform);

      if (ovrInStreamSPI != null) {
        ovrReader = READER_SPI.createReaderInstance();
        ovrStream =
            ovrInStreamSPI.createInputStreamInstance(
                ovrSource, ImageIO.getUseCache(), ImageIO.getCacheDirectory());
        ovrReader.setInput(ovrStream);
        // this includes the real image as this is a image index, we need to add one.
        extOvrImgChoice = numOverviews + 1;
        numOverviews = numOverviews + ovrReader.getNumImages(true);
        if (numOverviews < extOvrImgChoice) extOvrImgChoice = -1;
      }

      // //
      //
      // get information for the successive images
      //
      // //
      if (numOverviews >= 1) {
        overViewResolutions = new double[numOverviews][2];
        // Internal overviews start at 1, so lastInternalOverview matches numOverviews if no
        // external.
        int firstExternalOverview = extOvrImgChoice == -1 ? numOverviews : extOvrImgChoice - 1;
        double spanRes0 = highestRes[0] * this.originalGridRange.getSpan(0);
        double spanRes1 = highestRes[1] * this.originalGridRange.getSpan(1);
        for (int i = 0; i < firstExternalOverview; i++) {
          overViewResolutions[i][0] = spanRes0 / reader.getWidth(i + 1);
          overViewResolutions[i][1] = spanRes1 / reader.getHeight(i + 1);
        }
        for (int i = firstExternalOverview; i < numOverviews; i++) {
          overViewResolutions[i][0] = spanRes0 / ovrReader.getWidth(i - firstExternalOverview);
          overViewResolutions[i][1] = spanRes1 / ovrReader.getHeight(i - firstExternalOverview);
        }

      } else overViewResolutions = null;
    } catch (Throwable e) {
      throw new DataSourceException(e);
    } finally {
      if (reader != null)
        try {
          reader.dispose();
        } catch (Throwable t) {
        }

      if (ovrReader != null)
        try {
          ovrReader.dispose();
        } catch (Throwable t) {
        }

      if (ovrStream != null)
        try {
          ovrStream.close();
        } catch (Throwable t) {
        }

      if (inStream != null)
        try {
          inStream.reset();
        } catch (Throwable t) {
        }
    }
  }