/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.beam.smos.dgg; import com.bc.ceres.glevel.MultiLevelModel; import com.bc.ceres.glevel.MultiLevelSource; import com.bc.ceres.glevel.support.DefaultMultiLevelModel; import com.bc.ceres.glevel.support.DefaultMultiLevelSource; import org.esa.beam.jai.TiledFileOpImage; import javax.imageio.stream.ImageOutputStream; import javax.imageio.stream.MemoryCacheImageOutputStream; import javax.media.jai.PlanarImage; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.image.DataBufferInt; import java.awt.image.Raster; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class SmosDggTilizer { public static void main(String[] args) throws IOException { new SmosDggTilizer().doIt(new File(args[0]), new File(args[1])); } private void doIt(File inputLevel0Dir, File outputDir) throws IOException { if (!outputDir.exists() && !outputDir.mkdir()) { throw new IOException("Failed to create directory: "+outputDir.getAbsolutePath()); } final TiledFileOpImage opImage = TiledFileOpImage.create(inputLevel0Dir, null); final int dataType = opImage.getSampleModel().getDataType(); int tileWidth = 512; int tileHeight = 512; final int levelCount = 7; final MultiLevelModel model = new DefaultMultiLevelModel(levelCount, new AffineTransform(), opImage.getWidth(), opImage.getHeight()); final MultiLevelSource multiLevelSource = new DefaultMultiLevelSource(opImage, model); for (int level = 5; level < levelCount; level++) { final PlanarImage image = PlanarImage.wrapRenderedImage(multiLevelSource.getImage(level)); final int width = image.getWidth(); final int height = image.getHeight(); int numXTiles; int numYTiles; while (true) { numXTiles = width / tileWidth; numYTiles = height / tileHeight; if (numXTiles * tileWidth == width && numYTiles * tileHeight == image.getHeight()) { break; } if (numXTiles * tileWidth < width) { tileWidth /= 2; } if (numYTiles * tileHeight < height) { tileHeight /= 2; } } if (numXTiles == 0 || numYTiles == 0) { throw new IllegalStateException("numXTiles == 0 || numYTiles == 0"); } if (tileWidth < 512 && tileHeight < 512) { tileWidth = width; tileHeight = height; numXTiles = numYTiles = 1; } final File outputLevelDir = new File(outputDir, "" + level); if (!outputLevelDir.exists() && !outputLevelDir.mkdir()) { throw new IOException("Failed to create directory: "+outputLevelDir.getAbsolutePath()); } final File imagePropertiesFile = new File(outputLevelDir, "image.properties"); System.out.println("Writing " + imagePropertiesFile + "..."); final PrintWriter printWriter = new PrintWriter(new FileWriter(imagePropertiesFile)); writeImageProperties(level, dataType, width, height, tileWidth, tileHeight, numXTiles, numYTiles, new PrintWriter(System.out)); writeImageProperties(level, dataType, width, height, tileWidth, tileHeight, numXTiles, numYTiles, printWriter); System.out.flush(); printWriter.close(); writeTiles(outputLevelDir, image, tileWidth, tileHeight, numXTiles, numYTiles); } } private void writeTiles(File levelDir, PlanarImage image, int tileWidth, int tileHeight, int numXTiles, int numYTiles) throws IOException { for (int tileY = 0; tileY < numYTiles; tileY++) { for (int tileX = 0; tileX < numXTiles; tileX++) { final int x = tileX * tileWidth; final int y = tileY * tileHeight; final Raster raster = image.getData(new Rectangle(x, y, tileWidth, tileHeight)); int[] data = ((DataBufferInt) raster.getDataBuffer()).getData(); if (data.length != tileWidth * tileHeight) { data = new int[tileWidth * tileHeight]; raster.getDataElements(x, y, tileWidth, tileHeight, data); } writeData(levelDir, tileX, tileY, data); } } } private void writeImageProperties(int level, int dataType, int width, int height, int tileWidth, int tileHeight, int numXTiles, int numYTiles, PrintWriter printWriter) { printWriter.println("level = " + level); printWriter.println("dataType = " + dataType); printWriter.println("width = " + width); printWriter.println("height = " + height); printWriter.println("tileWidth = " + tileWidth); printWriter.println("tileHeight = " + tileHeight); printWriter.println("numXTiles = " + numXTiles); printWriter.println("numYTiles = " + numYTiles); } private void writeData(File levelDir, int tileX, int tileY, int[] data) throws IOException { final String baseName = tileX + "-" + tileY + ".raw"; final File file = new File(levelDir, baseName + ".zip"); final ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(file)); zipOutputStream.putNextEntry(new ZipEntry(baseName)); final ImageOutputStream imageOutputStream = new MemoryCacheImageOutputStream(zipOutputStream); imageOutputStream.writeInts(data, 0, data.length); imageOutputStream.flush(); zipOutputStream.closeEntry(); zipOutputStream.close(); } }