Package info.freelibrary.djatoka.io

Source Code of info.freelibrary.djatoka.io.PNMImage

/*
* This file is part of Mapyrus, software for plotting maps.
* Copyright (C) 2003 - 2011 Simon Chenery.
*
* Mapyrus is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Mapyrus 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Mapyrus; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* ===========================================================================
*
* Reusing this in freelibrary-djatoka to get rid of current JAI dependency; I
* also made a few minor changes (changed exceptions, parameters passed, etc.)
*
* Kevin S. Clarke <ksclarke@gmail.com>
*/

package info.freelibrary.djatoka.io;

import gov.lanl.adore.djatoka.io.FormatIOException;

import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/*
* Holds an image read from a Netpbm PPM and PGM format image files.
*/
public class PNMImage {

    private BufferedImage m_image;

    /**
     * Read Netpbm PNM image from file.
     *
     * @param filename name of file.
     */
    public PNMImage(String filename) throws FormatIOException, IOException {
        this(new FileInputStream(filename));
    }

    /**
     * Read Netpbm PNM image from open stream.
     *
     * @param aInputStream A Netpbm PNM image's input stream
     */
    public PNMImage(InputStream aInputStream) throws FormatIOException, IOException {
        DataInputStream stream = new DataInputStream(new BufferedInputStream(aInputStream));

        try {
            /*
             * Check for 'P5' or 'P6' magic number in file.
             */
            int magic1 = stream.read();
            int magic2 = stream.read();
            boolean isGreyscale;
            boolean isBitmap;

            if (magic1 == 'P' && magic2 == '6') {
                isGreyscale = isBitmap = false;
            } else if (magic1 == 'P' && magic2 == '5') {
                isGreyscale = true;
                isBitmap = false;
            } else if (magic1 == 'P' && magic2 == '4') {
                isBitmap = true;
                isGreyscale = false;
            } else {
                throw new FormatIOException("Bad PPM magic number: " + magic1 + magic2);
            }

            /*
             * Read image header.
             */
            int width = readNumber(stream);
            int height = readNumber(stream);
            int maxValue = 1;
            if (!isBitmap) {
                maxValue = readNumber(stream);
            }

            int nBytes = (maxValue < 256) ? 1 : 2;

            /*
             * Read pixel values into image.
             */
            m_image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

            int nextByte = 0;
            for (int y = 0; y < height; y++) {
                int bitMask = 0;
                for (int x = 0; x < width; x++) {
                    int r, g, b, pixel;
                    if (nBytes == 1) {
                        if (isBitmap) {
                            /*
                             * Extract pixel from next bit.
                             */
                            if (bitMask == 0) {
                                nextByte = stream.read();
                                bitMask = 128;
                            }
                            r = g = b = (((nextByte & bitMask) != 0) ? 0 : 255);
                            bitMask >>= 1;
                        } else if (isGreyscale) {
                            r = g = b = stream.read();
                        } else {
                            r = stream.read();
                            g = stream.read();
                            b = stream.read();
                        }
                    } else {
                        if (isGreyscale) {
                            r = g = b = stream.readShort();
                        } else {
                            r = stream.readShort();
                            g = stream.readShort();
                            b = stream.readShort();
                        }
                    }
                    pixel = (r << 16) | (g << 8) | b;
                    m_image.setRGB(x, y, pixel);
                }
            }
        } finally {
            try {
                stream.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * Read decimal number from stream.
     *
     * @param stream stream to read from.
     * @return number read from stream.
     */
    private int readNumber(InputStream stream) throws IOException {
        int retval = 0;
        int c = stream.read();
        boolean inComment = (c == '#');
        while (c != -1 && (inComment || Character.isWhitespace((char) c))) {
            c = stream.read();
            if (c == '#') {
                inComment = true;
            } else if (inComment && (c == '\r' || c == '\n')) {
                inComment = false;
            }
        }

        while (c >= '0' && c <= '9') {
            retval = retval * 10 + (c - '0');
            c = stream.read();
        }
        return (retval);
    }

    /**
     * Get Netpbm PNM image as buffered image.
     *
     * @return image.
     */
    public BufferedImage getBufferedImage() {
        return (m_image);
    }

    /**
     * Write an image to a Netpbm PPM format file.
     *
     * @param image image to write
     * @param stream output stream to write image to.
     */
    public static void write(BufferedImage image, OutputStream stream) throws IOException {
        /*
         * Write file header.
         */
        int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();
        stream.write('P');
        stream.write('6');
        stream.write('\n');
        stream.write(Integer.toString(imageWidth).getBytes());
        stream.write(' ');
        stream.write(Integer.toString(imageHeight).getBytes());
        stream.write('\n');
        stream.write(Integer.toString(255).getBytes());
        stream.write('\n');

        /*
         * Write each row of pixels.
         */
        for (int y = 0; y < imageHeight; y++) {
            for (int x = 0; x < imageWidth; x++) {
                int pixel = image.getRGB(x, y);
                int b = (pixel & 0xff);
                int g = ((pixel >> 8) & 0xff);
                int r = ((pixel >> 16) & 0xff);
                stream.write(r);
                stream.write(g);
                stream.write(b);
            }
        }
        stream.flush();
    }
}
TOP

Related Classes of info.freelibrary.djatoka.io.PNMImage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.