about summary refs log tree commit diff
path: root/lib/fileio.c
diff options
context:
space:
mode:
authorgiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
committergiraffedata <giraffedata@9d0c8265-081b-0410-96cb-a4ca84ce46f8>2006-08-19 03:12:28 +0000
commit1fd361a1ea06e44286c213ca1f814f49306fdc43 (patch)
tree64c8c96cf54d8718847339a403e5e67b922e8c3f /lib/fileio.c
downloadnetpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.gz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.tar.xz
netpbm-mirror-1fd361a1ea06e44286c213ca1f814f49306fdc43.zip
Create Subversion repository
git-svn-id: http://svn.code.sf.net/p/netpbm/code/trunk@1 9d0c8265-081b-0410-96cb-a4ca84ce46f8
Diffstat (limited to 'lib/fileio.c')
-rw-r--r--lib/fileio.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/lib/fileio.c b/lib/fileio.c
new file mode 100644
index 00000000..01243f9d
--- /dev/null
+++ b/lib/fileio.c
@@ -0,0 +1,170 @@
+/* fileio.c - routines to read elements from Netpbm image files
+**
+** Copyright (C) 1988 by Jef Poskanzer.
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include <stdio.h>
+#include <limits.h>
+
+#include "pm.h"
+#include "fileio.h"
+
+char
+pm_getc(FILE * const file) {
+    int ich;
+    char ch;
+
+    ich = getc(file);
+    if (ich == EOF)
+        pm_error("EOF / read error reading a byte");
+    ch = (char) ich;
+    
+    if (ch == '#') {
+        do {
+	    ich = getc(file);
+	    if (ich == EOF)
+            pm_error("EOF / read error reading a byte");
+	    ch = (char) ich;
+	    } while (ch != '\n' && ch != '\r');
+	}
+    return ch;
+}
+
+
+
+/* This is useful for PBM files.  It used to be used for PGM and PPM files
+   too, since the sample size was always one byte.  Now, use pbm_getrawsample()
+   for PGM and PPM files.
+*/
+
+unsigned char
+pm_getrawbyte(FILE * const file) {
+    int iby;
+
+    iby = getc(file);
+    if (iby == EOF)
+        pm_error("EOF / read error reading a one-byte sample");
+    return (unsigned char) iby;
+}
+
+
+
+unsigned int
+pm_getuint(FILE * const ifP) {
+/*----------------------------------------------------------------------------
+   Read an unsigned integer in ASCII decimal from the file stream
+   represented by 'ifP' and return its value.
+
+   If there is nothing at the current position in the file stream that
+   can be interpreted as an unsigned integer, issue an error message
+   to stderr and abort the program.
+
+   If the number at the current position in the file stream is too
+   great to be represented by an 'int' (Yes, I said 'int', not
+   'unsigned int'), issue an error message to stderr and abort the
+   program.
+-----------------------------------------------------------------------------*/
+    char ch;
+    unsigned int i;
+
+    do {
+        ch = pm_getc(ifP);
+	} while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r');
+
+    if (ch < '0' || ch > '9')
+        pm_error("junk in file where an unsigned integer should be");
+
+    i = 0;
+    do {
+        unsigned int const digitVal = ch - '0';
+
+        if (i > INT_MAX/10 - digitVal)
+            pm_error("ASCII decimal integer in file is "
+                     "too large to be processed.  ");
+        i = i * 10 + digitVal;
+        ch = pm_getc(ifP);
+    } while (ch >= '0' && ch <= '9');
+
+    return i;
+}
+
+
+
+unsigned int
+pm_getraw(FILE *       const file, 
+          unsigned int const bytes) {
+
+    unsigned int value;  /* our return value */
+
+    if (bytes == 1) {
+        /* Here's a speedup for the common 1-byte sample case: */
+        value = getc(file);
+        if (value == EOF)
+            pm_error("EOF/error reading 1 byte sample from file.");
+    } else {
+        /* This code works for bytes == 1..4 */
+        /* We could speed this up by exploiting knowledge of the format of
+           an unsigned integer (i.e. endianness).  Then we could just cast
+           the value as an array of characters instead of shifting and
+           masking.
+           */
+        int shift;
+        unsigned char inval[4];
+        int cursor;
+        int n_read;
+
+        n_read = fread(inval, bytes, 1, file);
+        if (n_read < 1) 
+            pm_error("EOF/error reading %d byte sample from file.", bytes);
+        value = 0;  /* initial value */
+        cursor = 0;
+        for (shift = (bytes-1)*8; shift >= 0; shift-=8) 
+            value += inval[cursor++] << shift;
+    }
+    return(value);
+}
+
+
+
+void
+pm_putraw(FILE *       const file, 
+          unsigned int const value, 
+          unsigned int const bytes) {
+
+    if (bytes == 1) {
+        /* Here's a speedup for the common 1-byte sample case: */
+        int rc;
+        rc = fputc(value, file);
+        if (rc == EOF)
+            pm_error("Error writing 1 byte sample to file.");
+    } else {
+        /* This code works for bytes == 1..4 */
+        /* We could speed this up by exploiting knowledge of the format of
+           an unsigned integer (i.e. endianness).  Then we could just cast
+           the value as an array of characters instead of shifting and
+           masking.
+           */
+        int shift;
+        unsigned char outval[4];
+        int cursor;
+        int n_written;
+
+        cursor = 0;
+        for (shift = (bytes-1)*8; shift >= 0; shift-=8) {
+            outval[cursor++] = (value >> shift) & 0xFF;
+        }
+        n_written = fwrite(&outval, bytes, 1, file);
+        if (n_written == 0) 
+            pm_error("Error writing %d byte sample to file.", bytes);
+    }
+}
+
+
+