Revision: 6507
          http://sourceforge.net/p/jump-pilot/code/6507
Author:   ma15569
Date:     2020-09-22 09:26:19 +0000 (Tue, 22 Sep 2020)
Log Message:
-----------
Ported functionality from TiffUtils to TiffUtilsV2.
Make TiffUtils deprecated

Modified Paths:
--------------
    core/trunk/src/org/openjump/core/rasterimage/RasterImageIO.java
    core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java
    core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java

Modified: core/trunk/src/org/openjump/core/rasterimage/RasterImageIO.java
===================================================================
--- core/trunk/src/org/openjump/core/rasterimage/RasterImageIO.java     
2020-09-21 13:32:21 UTC (rev 6506)
+++ core/trunk/src/org/openjump/core/rasterimage/RasterImageIO.java     
2020-09-22 09:26:19 UTC (rev 6507)
@@ -26,7 +26,6 @@
 import org.apache.commons.imaging.ImageReadException;
 import org.apache.commons.imaging.formats.tiff.TiffField;
 import org.apache.commons.imaging.formats.tiff.fieldtypes.FieldType;
-import org.openjump.core.rasterimage.TiffTags.TiffMetadata;
 
 import com.sun.media.jai.codec.FileSeekableStream;
 import com.sun.media.jai.codec.TIFFDirectory;
@@ -38,8 +37,6 @@
 import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jump.I18N;
 import com.vividsolutions.jump.workbench.WorkbenchContext;
-import com.vividsolutions.jump.workbench.imagery.ReferencedImageException;
-import com.vividsolutions.jump.workbench.imagery.geoimg.GeoReferencedRaster;
 import com.vividsolutions.jump.workbench.ui.Viewport;
 
 /**
@@ -146,7 +143,7 @@
       Envelope imageEnvelope = TiffUtilsV2.getEnvelope(tiffFile);
       Overviews overviews = OverviewsUtils.getOverviews(new 
File(fileNameOrURL), imageEnvelope);
 
-      return TiffUtils.readImage(tiffFile, viewPortEnvelope, requestedRes, 
overviews, stats);
+      return TiffUtilsV2.readImage(tiffFile, viewPortEnvelope, requestedRes, 
overviews, stats);
 
     } else if (fileNameOrURL.toLowerCase().endsWith(".flt")) {
 

Modified: core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java
===================================================================
--- core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java 2020-09-21 
13:32:21 UTC (rev 6506)
+++ core/trunk/src/org/openjump/core/rasterimage/TiffUtils.java 2020-09-22 
09:26:19 UTC (rev 6507)
@@ -5,7 +5,6 @@
 import java.awt.geom.NoninvertibleTransformException;
 import java.awt.image.BufferedImage;
 import java.awt.image.Raster;
-import java.awt.image.renderable.ParameterBlock;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -16,9 +15,7 @@
 import javax.imageio.ImageReadParam;
 import javax.imageio.ImageReader;
 import javax.imageio.stream.ImageInputStream;
-import javax.media.jai.JAI;
 import javax.media.jai.RenderedOp;
-import javax.media.jai.util.ImagingListener;
 import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.TransformerConfigurationException;
 import javax.xml.transform.TransformerException;
@@ -36,7 +33,10 @@
 /**
  *
  * @author AdL
+ * @deprecated moved all methods to newer
+ * org.openjump.core.rasterimage.TiffUtilsV2 class
  */
+@Deprecated
 public class TiffUtils {
 
   public static ImageAndMetadata readImage(File tiffFile, Envelope 
viewportEnvelope, Resolution requestedRes,

Modified: core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java
===================================================================
--- core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java       
2020-09-21 13:32:21 UTC (rev 6506)
+++ core/trunk/src/org/openjump/core/rasterimage/TiffUtilsV2.java       
2020-09-22 09:26:19 UTC (rev 6507)
@@ -1,14 +1,37 @@
 package org.openjump.core.rasterimage;
 
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.NoninvertibleTransformException;
+import java.awt.image.BufferedImage;
+import java.awt.image.Raster;
 import java.awt.image.renderable.ParameterBlock;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
 import javax.media.jai.JAI;
 import javax.media.jai.RenderedOp;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
 
+import org.apache.commons.imaging.ImageReadException;
+import org.apache.commons.imaging.formats.tiff.TiffField;
+import org.apache.commons.imaging.formats.tiff.TiffImageMetadata;
+import org.apache.commons.imaging.formats.tiff.TiffImageParser;
+import org.xml.sax.SAXException;
+
+import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jump.workbench.Logger;
 import com.vividsolutions.jump.workbench.imagery.ReferencedImageException;
 import com.vividsolutions.jump.workbench.imagery.geoimg.GeoReferencedRaster;
 
@@ -66,4 +89,283 @@
     renderedOp = JAI.create("scale", parameterBlock);
     return JAI.create("scale", parameterBlock);
   }
+  public static ImageAndMetadata readImage(File tiffFile, Envelope 
viewportEnvelope, Resolution requestedRes,
+             Overviews overviews, Stats stats) throws 
NoninvertibleTransformException, IOException, FileNotFoundException,
+             TiffTags.TiffReadingException, Exception {
+
+           // Try to read geotiff tags
+           TiffTags.TiffMetadata tiffMetadata = 
TiffTags.readMetadata(tiffFile);
+           int originalImageWidth = tiffMetadata.getColsCount();
+           int originalImageHeight = tiffMetadata.getRowsCount();
+           Resolution cellSize = tiffMetadata.getResolution();
+           Double noData = tiffMetadata.getNoData();
+
+           // Now try with tfw
+           if (cellSize == null) {
+             WorldFileHandler worldFileHandler = new 
WorldFileHandler(tiffFile.getAbsolutePath(), true);
+             Envelope envelope = 
worldFileHandler.readWorldFile(originalImageWidth, originalImageHeight);
+             cellSize = new Resolution(envelope.getWidth() / 
originalImageWidth, envelope.getHeight() / originalImageHeight);
+           }
+
+           Envelope wholeImageEnvelope = 
RasterImageIO.getGeoReferencing(tiffFile.getAbsolutePath(), true,
+               new Point(originalImageWidth, originalImageHeight));
+
+           if (requestedRes == null) {
+             requestedRes = cellSize;
+           }
+
+           int overviewLevel = overviews.pickOverviewLevel(requestedRes);
+
+           if (stats == null) {
+             // Statistics on all pixels
+             stats = calculateStats(tiffFile, noData, tiffFile);
+           }
+
+           if (overviews.getOverviewsCount() == 1) {
+
+             // No overviews, decimation (subsampling)
+
+             float xScale = (float) (cellSize.getX() / requestedRes.getX());
+             float yScale = (float) (cellSize.getY() / requestedRes.getY());
+             xScale = Math.min(xScale, 1);
+             yScale = Math.min(yScale, 1);
+
+             RenderedOp renderedOp = readSubsampled(tiffFile, xScale, yScale);
+
+             // For better looking results, but slower:
+             // rop = JAI.create("SubsampleAverage", pb);
+
+             Resolution subsetResolution = new 
Resolution(wholeImageEnvelope.getWidth() / renderedOp.getWidth(),
+                 wholeImageEnvelope.getHeight() / renderedOp.getHeight());
+
+             Rectangle imageSubset = 
RasterImageIO.getDrawingRectangle(renderedOp.getWidth(), renderedOp.getHeight(),
+                 wholeImageEnvelope, viewportEnvelope, subsetResolution);
+
+             BufferedImage bufferedImage;
+             Envelope imagePartEnvelope;
+             int actualImageWidth;
+             int actualImageHeight;
+             if (imageSubset == null) {
+               bufferedImage = null;
+               imagePartEnvelope = null;
+               actualImageWidth = 0;
+               actualImageHeight = 0;
+             } else {
+               bufferedImage = renderedOp.getAsBufferedImage(imageSubset, 
null);
+               imagePartEnvelope =  getImageSubsetEnvelope(wholeImageEnvelope, 
imageSubset, subsetResolution);
+               actualImageWidth = bufferedImage.getWidth();
+               actualImageHeight = bufferedImage.getHeight();
+             }
+
+             Metadata metadata = new Metadata(wholeImageEnvelope, 
imagePartEnvelope,
+                 new Point(originalImageWidth, originalImageHeight), new 
Point(actualImageWidth, actualImageHeight),
+                 (cellSize.getX() + cellSize.getY()) / 2, 
(subsetResolution.getX() + subsetResolution.getY()) / 2, noData,
+                 stats);
+             return new ImageAndMetadata(bufferedImage, metadata);
+
+           } else {
+
+             // Read from internal overviews
+             ImageAndMetadata imageAndMetadata = readImage(tiffFile, 
overviewLevel, 0,
+                 new Point(originalImageWidth, originalImageHeight), cellSize, 
wholeImageEnvelope, viewportEnvelope, noData,
+                 stats);
+
+             // Read from external overviews
+             if (imageAndMetadata == null) {
+               File ovrFile = new File(tiffFile.getParent(), 
tiffFile.getName() + ".ovr");
+               imageAndMetadata = readImage(ovrFile, overviewLevel, 
overviews.getInternalOverviewsCount(),
+                   new Point(originalImageWidth, originalImageHeight), 
cellSize, wholeImageEnvelope, viewportEnvelope, noData,
+                   stats);
+             }
+             return imageAndMetadata;
+
+           }
+
+         }
+
+         private static ImageAndMetadata readImage(File tiffFile, int 
overviewIndex, int indexStart, Point originalSize,
+             Resolution originalCellSize, Envelope wholeImageEnvelope, 
Envelope viewportEnvelope, double noDataValue,
+             Stats stats) throws IOException, NoninvertibleTransformException {
+
+           ImageInputStream imageInputStream = 
ImageIO.createImageInputStream(tiffFile);
+           Iterator<ImageReader> iterator = 
ImageIO.getImageReaders(imageInputStream);
+
+           if (iterator != null && iterator.hasNext()) {
+
+             ImageReader imageReader = iterator.next();
+             imageReader.setInput(imageInputStream);
+             for (int i = 0; i < imageReader.getNumImages(true); i++) {
+               if (i + indexStart == overviewIndex) {
+
+                 Resolution subsetResolution = new 
Resolution(wholeImageEnvelope.getWidth() / imageReader.getWidth(i),
+                     wholeImageEnvelope.getHeight() / 
imageReader.getHeight(i));
+
+                 Rectangle imageSubset = 
RasterImageIO.getDrawingRectangle(imageReader.getWidth(i), 
imageReader.getHeight(i),
+                     wholeImageEnvelope, viewportEnvelope, subsetResolution);
+
+                 BufferedImage bufferedImage;
+                 Envelope imagePartEnvelope;
+                 int imageWidth;
+                 int imageHeight;
+                 if (imageSubset == null) {
+                   bufferedImage = null;
+                   imagePartEnvelope = null;
+                   imageWidth = 0;
+                   imageHeight = 0;
+                 } else {
+                   ImageReadParam imageReadParam = new ImageReadParam();
+                   imageReadParam.setSourceRegion(imageSubset);
+                   bufferedImage = imageReader.read(i, imageReadParam);
+                   imagePartEnvelope =  
getImageSubsetEnvelope(wholeImageEnvelope, imageSubset, subsetResolution);
+                   imageWidth = bufferedImage.getWidth();
+                   imageHeight = bufferedImage.getHeight();
+                 }
+
+//                         double originalCellSize = subsetResolution.getX();
+//                         int cellsCount = imageReader.getWidth(i) * 
imageReader.getHeight(i);
+//                         int sampleSize = 10000;
+//                         double lowResCellSize = Math.sqrt(Math.max(1, 
cellsCount/(double)sampleSize)) * originalCellSize;
+
+//                         if(stats == null) {
+//                             BufferedImage statsBufferedImage = 
imageReader.read(imageReader.getNumImages(true) - 1, null);
+//                             stats = calculateStats(statsBufferedImage, 
noDataValue);
+//                         }
+
+                 Metadata metadata = new Metadata(wholeImageEnvelope, 
imagePartEnvelope, originalSize,
+                     new Point(imageWidth, imageHeight), 
(originalCellSize.getX() + originalCellSize.getY()) / 2,
+                     (subsetResolution.getX() + subsetResolution.getY()) / 2, 
noDataValue, stats);
+
+                 return new ImageAndMetadata(bufferedImage, metadata);
+
+               }
+             }
+
+           }
+
+           return null;
+
+         }
+
+         private static Stats calculateStats(File tiffFile, double 
noDataValue, File imageFile)
+             throws ParserConfigurationException, TransformerException, 
ImageReadException, IOException, SAXException {
+
+           Stats stats = null;
+
+           // Look for internal stats tag
+           try {
+             TiffImageParser parser = new TiffImageParser();
+             TiffImageMetadata metadata = (TiffImageMetadata) 
parser.getMetadata(tiffFile);
+             List<TiffField> tiffFields = metadata.getAllFields();
+             for (TiffField tiffField : tiffFields) {
+               if (tiffField.getTag() == TiffTags.TIFFTAG_GDAL_METADATA) {
+                 GDALInternalMetadata gdalParser = new GDALInternalMetadata();
+                 stats = gdalParser.readStatistics(tiffField.getStringValue());
+                 break;
+               }
+             }
+           } catch (Exception ex) {
+             stats = null;
+           }
+
+           if (stats != null) {
+             return stats;
+           }
+
+           // Look for aux.xml file
+           File auxXmlFile = new File(imageFile.getParent(), 
imageFile.getName() + ".aux.xml");
+           if (auxXmlFile.exists()) {
+             GDALPamDataset gdalPamDataset = new GDALPamDataset();
+             try {
+               stats = gdalPamDataset.readStatistics(auxXmlFile);
+               return stats;
+             } catch (Exception ex) {
+               Logger.error("Failed to read statistics.", ex);
+               return createStatsXml(tiffFile, noDataValue, auxXmlFile);
+             }
+           }
+           return createStatsXml(tiffFile, noDataValue, auxXmlFile);
+
+         }
+
+         private static Stats createStatsXml(File tiffFile, double 
noDataValue, File auxXmlFile)
+             throws ParserConfigurationException, TransformerException, 
TransformerConfigurationException, SAXException,
+             IOException {
+
+           BufferedImage bufferedImage = readSubsampled(tiffFile, 1, 
1).getAsBufferedImage();
+           int bandCount = bufferedImage.getRaster().getNumBands();
+
+           double minValue[] = new double[bandCount];
+           double maxValue[] = new double[bandCount];
+           double sum[] = new double[bandCount];
+           double sumSquare[] = new double[bandCount];
+           long cellsCount[] = new long[bandCount];
+
+           for (int b = 0; b < bandCount; b++) {
+             minValue[b] = Double.MAX_VALUE;
+             maxValue[b] = -Double.MAX_VALUE;
+           }
+
+           for (int r = 0; r < bufferedImage.getHeight(); r++) {
+             Raster raster = bufferedImage.getData(new Rectangle(0, r, 
bufferedImage.getWidth(), 1));
+             for (int c = 0; c < bufferedImage.getWidth(); c++) {
+
+               for (int b = 0; b < bandCount; b++) {
+
+                 double value = raster.getSampleDouble(c, r, b);
+                 if (value != noDataValue && (float) value != (float) 
noDataValue && !Double.isNaN(value)
+                     && !Double.isInfinite(value)) {
+                   if (value < minValue[b])
+                     minValue[b] = value;
+                   if (value > maxValue[b])
+                     maxValue[b] = value;
+                   cellsCount[b]++;
+                   sum[b] += value;
+                   sumSquare[b] += value * value;
+                 }
+
+               }
+
+             }
+           }
+
+           Stats stats = new Stats(bandCount);
+           for (int b = 0; b < bandCount; b++) {
+             double meanValue = sum[b] / cellsCount[b];
+             double stdDevValue = Math.sqrt(sumSquare[b] / cellsCount[b] - 
meanValue * meanValue);
+             stats.setStatsForBand(b, minValue[b], maxValue[b], meanValue, 
stdDevValue);
+           }
+
+           // Write aux.xml
+           GDALPamDataset gdalPamDataset = new GDALPamDataset();
+           gdalPamDataset.writeStatistics(auxXmlFile, stats);
+
+           return stats;
+
+         }
+
+         private static Envelope getImageSubsetEnvelope(Envelope 
wholeImageEnvelope, Rectangle imageSubset,
+             Resolution subsetResolution) {
+
+           double ulX = Math.max(wholeImageEnvelope.getMinX(),
+               wholeImageEnvelope.getMinX() + imageSubset.getX() * 
subsetResolution.getX());
+           double ulY = Math.min(wholeImageEnvelope.getMaxY(),
+               wholeImageEnvelope.getMaxY() - imageSubset.getY() * 
subsetResolution.getY());
+           double lrX = Math.min(wholeImageEnvelope.getMaxX(), 
wholeImageEnvelope.getMinX()
+               + imageSubset.getX() * subsetResolution.getX() + 
imageSubset.getWidth() * subsetResolution.getX());
+           double lrY = Math.max(wholeImageEnvelope.getMinY(), 
wholeImageEnvelope.getMaxY()
+               - imageSubset.getY() * subsetResolution.getY() - 
imageSubset.getHeight() * subsetResolution.getY());
+           Coordinate ulCoord = new Coordinate(ulX, ulY);
+           Coordinate lrCoord = new Coordinate(lrX, lrY);
+
+           Envelope imagePartEnvelope = new Envelope(ulCoord, lrCoord);
+
+           return imagePartEnvelope;
+
+         }
+
+         public static Double readCellValue(File tiffFile, int col, int row, 
int band)  throws Exception {
+           Rectangle rectangle = new Rectangle(col, row, 1, 1);
+           return 
getRenderedOp(tiffFile).getData(rectangle).getSampleDouble(col, row, band);
+         }
+
 }



_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel

Reply via email to