OSDN Git Service

Change directory structure.
[dvibrowser/dvi2epub.git] / src / main / java / jp / sourceforge / dvibrowser / dvicore / image / pnm / PnmHeader.java
diff --git a/src/main/java/jp/sourceforge/dvibrowser/dvicore/image/pnm/PnmHeader.java b/src/main/java/jp/sourceforge/dvibrowser/dvicore/image/pnm/PnmHeader.java
new file mode 100644 (file)
index 0000000..226aae2
--- /dev/null
@@ -0,0 +1,241 @@
+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