--- /dev/null
+package jp.sourceforge.dvibrowser.dvicore.image.pnm;
+/*
+ * Copyright (c) 2009, Takeyuki Nagao
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the
+ * following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import jp.sourceforge.dvibrowser.dvicore.util.DviUtils;
+
+
+
+public final class PnmHeader
+{
+ private static final Logger LOGGER = Logger.getLogger(PnmHeader.class
+ .getName());
+
+ public static final String PNM_COMMENT_NEWLINE = "\n";
+
+ public static final int PNM_TYPE_BITMAP_ASCII = 1;
+ public static final int PNM_TYPE_GRAYMAP_ASCII = 2;
+ public static final int PNM_TYPE_PIXMAP_ASCII = 3;
+ public static final int PNM_TYPE_BITMAP_BINARY = 4;
+ public static final int PNM_TYPE_GRAYMAP_BINARY = 5;
+ public static final int PNM_TYPE_PIXMAP_BINARY = 6;
+
+ private final int type;
+ private final int width;
+ private final int height;
+ private final int maxval;
+ private final String comment;
+
+ public PnmHeader(int type, String comment, int width, int height, int maxval)
+ {
+ this.type = type;
+ this.comment = comment;
+ this.width = width;
+ this.height = height;
+ this.maxval = maxval;
+ }
+
+ public boolean isBitmap()
+ {
+ return (PNM_TYPE_BITMAP_ASCII == type || PNM_TYPE_BITMAP_BINARY == type);
+ }
+
+ public boolean isGraymap()
+ {
+ return (PNM_TYPE_GRAYMAP_ASCII == type || PNM_TYPE_GRAYMAP_BINARY == type);
+ }
+
+ public boolean isPixmap()
+ {
+ return (PNM_TYPE_PIXMAP_ASCII == type || PNM_TYPE_PIXMAP_BINARY == type);
+ }
+
+ public boolean isASCII()
+ {
+ return (1 <= type && type <= 3);
+ }
+
+ public boolean isBinary()
+ {
+ return !isASCII();
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getMaxValue() {
+ return maxval;
+ }
+
+ public String toString() {
+ return getClass().getName() + "[type=" + type + ",width=" + width
+ + ",height=" + height + ",maxval=" + maxval + ",comment=" + comment + "]";
+ }
+
+ // P1: bitmap (ASCII)
+ // P2: graymap (ASCII)
+ // P3: pixmap (ASCII)
+ // P4: bitmap (binary)
+ // P5: graymap (binary)
+ // P6: pixmap (binary)
+
+// private static final Pattern patPnmMagicNumbers = Pattern.compile("P([1-6])");
+ private static final Pattern patPnmComment = Pattern.compile("#\\s?(.*)");
+ private static final Pattern patPnmSize = Pattern.compile("([0-9][0-9]*)\\s\\s*([0-9][0-9]*)");
+
+ public String readLine(InputStream is)
+ throws IOException
+ {
+ StringBuilder sb = new StringBuilder();
+
+ int c = -1;
+ do {
+ c = is.read();
+ } while (c != '\n');
+
+ return sb.toString();
+ }
+
+ public static String readLine(InputStream is, int c, int delim)
+ throws IOException
+ {
+ String line = "";
+ do {
+ if (c >= 0) {
+ line += (char) c;
+ }
+ c = is.read();
+ if (c < 0)
+ return null;
+ } while (c != delim);
+ return line;
+ }
+
+
+ public static PnmHeader parseHeader(InputStream is)
+ throws IOException
+ {
+ int type=-1, width=-1, height=-1, maxval=-1;
+ String comment = null;
+
+ {
+ int c1 = is.read();
+ int c2 = is.read();
+
+ if (!(c1 == 'P' && '1' <= c2 && c2 <= '6'))
+ throw new IOException("Invalid PNM magic number: c1=" + (char) c1 + " c2=" + (char) c2);
+ type = c2 - '0';
+ }
+
+ int c = -1;
+ int delim = -1;
+
+ c = is.read();
+
+ while (isNewLine(c)) {
+ delim = c;
+ c = is.read();
+ }
+
+ if (delim < 0) {
+ throw new IOException("Illegal data after PNM magic number: " + c);
+ }
+
+ // Parse Comments.
+ String line = readLine(is, c, delim);
+ while (null != line) {
+ Matcher mat = patPnmComment.matcher(line);
+ if (!mat.matches()) break;
+ String s = mat.group(1);
+ comment = (comment == null) ? s : comment + PNM_COMMENT_NEWLINE + s;
+ line = readLine(is, -1, delim);
+ }
+
+ // Parse size.
+ {
+ Matcher mat2 = patPnmSize.matcher(line);
+ if (mat2.matches()) {
+ try {
+ width = Integer.parseInt(mat2.group(1));
+ height = Integer.parseInt(mat2.group(2));
+ } catch (NumberFormatException e) {
+ DviUtils.logStackTrace(LOGGER, Level.WARNING, e);
+ }
+ }
+ }
+ if (width < 0 || height < 0) {
+ throw new IOException("Failed to decode PNM image size: " + line);
+ }
+
+ // Parse max value (which is required for graymap and pixmap).
+ if (PNM_TYPE_BITMAP_ASCII == type || PNM_TYPE_BITMAP_BINARY == type) {
+ maxval = 1;
+ } else {
+ line = readLine(is, -1, delim);
+ try {
+ maxval = Integer.parseInt(line);
+ } catch (NumberFormatException e) {
+ DviUtils.logStackTrace(LOGGER, Level.WARNING, e);
+ }
+ if (maxval < 0) {
+ throw new IOException("Failed to decode PNM max value: " + line);
+ }
+ }
+
+ return new PnmHeader(type, comment, width, height, maxval);
+ }
+
+ private static boolean isNewLine(int c) {
+ return (c == '\r' || c == '\n');
+ }
+
+ public String getComment() {
+ return comment;
+ }
+}
\ No newline at end of file