org.esa.s2tbx.dataio.openjpeg.OpenJpegUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.esa.s2tbx.dataio.openjpeg.OpenJpegUtils.java

Source

/*
 * Copyright (C) 2014-2015 CS-SI (foss-contact@thor.si.c-s.fr)
 *
 * 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.s2tbx.dataio.openjpeg;

import org.apache.commons.lang.SystemUtils;
import org.esa.s2tbx.dataio.Utils;
import org.esa.s2tbx.dataio.jp2.TileLayout;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Utility class to work with openjpeg:
 * - retrieve TileLayout information from a granule
 * - execute openjpeg
 *
 * @author Oscar Picas-Puig
 */
public class OpenJpegUtils {

    /**
     * Get the tile layout with opj_dump
     *
     * @param opjdumpPath path to opj_dump
     * @param jp2FilePath the path to the jpeg file
     * @return the tile layout for the openjpeg file
     * @throws IOException
     * @throws InterruptedException
     */
    public static TileLayout getTileLayoutWithOpenJPEG(String opjdumpPath, Path jp2FilePath)
            throws IOException, InterruptedException {

        if (opjdumpPath == null) {
            throw new IllegalStateException("Cannot retrieve tile layout, opj_dump cannot be found");
        }

        TileLayout tileLayout;

        String pathToImageFile = jp2FilePath.toAbsolutePath().toString();
        if (SystemUtils.IS_OS_WINDOWS) {
            pathToImageFile = Utils.GetIterativeShortPathName(pathToImageFile);
        }

        ProcessBuilder builder = new ProcessBuilder(opjdumpPath, "-i", pathToImageFile);
        builder.redirectErrorStream(true);

        CommandOutput exit = OpenJpegUtils.runProcess(builder);

        if (exit.getErrorCode() != 0) {
            StringBuilder sbu = new StringBuilder();
            for (String fragment : builder.command()) {
                sbu.append(fragment);
                sbu.append(' ');
            }

            throw new IOException(
                    String.format("Command [%s] failed with error code [%d], stdoutput [%s] and stderror [%s]",
                            sbu.toString(), exit.getErrorCode(), exit.getTextOutput(), exit.getErrorOutput()));
        }
        tileLayout = OpenJpegUtils.parseOpjDump(exit.getTextOutput());

        return tileLayout;
    }

    public static String convertStreamToString(java.io.InputStream is) {
        java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
        return s.hasNext() ? s.next() : "";
    }

    public static CommandOutput runProcess(ProcessBuilder builder) throws InterruptedException, IOException {
        builder.environment().putAll(System.getenv());
        StringBuilder output = new StringBuilder();
        boolean isStopped = false;
        final Process process = builder.start();
        try (BufferedReader outReader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
            while (!isStopped) {
                while (outReader.ready()) {
                    String line = outReader.readLine();
                    if (line != null && !line.isEmpty()) {
                        output.append(line);
                    }
                }
                if (!process.isAlive()) {
                    isStopped = true;
                } else {
                    Thread.yield();
                }
            }
            outReader.close();
        }
        int exitCode = process.exitValue();
        //String output = convertStreamToString(process.getInputStream());
        String errorOutput = convertStreamToString(process.getErrorStream());
        return new CommandOutput(exitCode, output.toString(), errorOutput);
    }

    /**
     * Parse the {@code String} returned by opj_dump command
     *
     * @param content the tring returned by opj_dump
     * @return the TileLayout extracted from this string
     */
    public static TileLayout parseOpjDump(String content) {
        List<String> splittedContent = new ArrayList<>();
        Collections.addAll(splittedContent, content.split(content.contains("\n") ? "\n" : "\t"));
        return parseOpjDump(splittedContent);
    }

    /**
     * Parse opj_dump result lines
     *
     * @param content the lines of text returned from opj_dump command
     * @return the TileLayout extracted from the lines
     */
    public static TileLayout parseOpjDump(List<String> content) {
        int Width = 0;
        int Height = 0;
        int tileWidth = 0;
        int tileHeight = 0;
        int xTiles = 0;
        int yTiles = 0;
        int resolutions = 0;

        for (String line : content) {
            if (line.contains("x1") && line.contains("y1")) {
                String[] segments = line.trim().split(",");
                Width = Integer.parseInt(segments[0].split("\\=")[1]);
                Height = Integer.parseInt(segments[1].split("\\=")[1]);
            }
            if (line.contains("tdx") && line.contains("tdy")) {
                String[] segments = line.trim().split(",");
                tileWidth = Integer.parseInt(segments[0].split("\\=")[1]);
                tileHeight = Integer.parseInt(segments[1].split("\\=")[1]);
            }
            if (line.contains("tw") && line.contains("th")) {
                String[] segments = line.trim().split(",");
                xTiles = Integer.parseInt(segments[0].split("\\=")[1]);
                yTiles = Integer.parseInt(segments[1].split("\\=")[1]);
            }
            if (line.contains("numresolutions")) {
                resolutions = Integer.parseInt(line.trim().split("\\=")[1]);
            }
        }

        return new TileLayout(Width, Height, tileWidth, tileHeight, xTiles, yTiles, resolutions);

    }
}