about summary refs log tree commit diff
path: root/converter/other/fitstopnm.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/other/fitstopnm.c')
-rw-r--r--converter/other/fitstopnm.c212
1 files changed, 127 insertions, 85 deletions
diff --git a/converter/other/fitstopnm.c b/converter/other/fitstopnm.c
index b41e0960..0d8753e5 100644
--- a/converter/other/fitstopnm.c
+++ b/converter/other/fitstopnm.c
@@ -39,11 +39,12 @@
 #include <string.h>
 #include <float.h>
 
+#include "pm_config.h"
 #include "pm_c_util.h"
 #include "mallocvar.h"
+#include "floatcode.h"
 #include "shhopt.h"
 #include "pnm.h"
-#include "pm_config.h"
 
 
 
@@ -156,109 +157,150 @@ struct FITS_Header {
 };
 
 
+/* This code deals properly with integers, no matter what the byte order
+   or integer size of the host machine.  We handle sign extension manually to
+   prevent problems with signed/unsigned characters.  We read floating point
+   values properly only when the host architecture conforms to IEEE-754.  If
+   you need to tweak this code for other machines, you might want to get a
+   copy of the FITS documentation from nssdca.gsfc.nasa.gov
+*/
+
 static void
-swapbytes(void *       const p,
-          unsigned int const nbytes) {
-#if BYTE_ORDER == LITTLE_ENDIAN
-    unsigned char * const c = p;
-    unsigned int i;
-    for (i = 0; i < nbytes/2; ++i) {
-        unsigned char const orig = c[i];
-        c[i] = c[nbytes-(i+1)];
-        c[nbytes-(i+1)] = orig;
-    }
-#endif
+readFitsChar(FILE *   const ifP,
+             double * const vP) {
+
+    /* 8 bit FITS integers are unsigned */
+
+    int const ich = getc(ifP);
+
+    if (ich == EOF)
+        pm_error("EOF / read error");
+    else
+        *vP = ich;
 }
 
 
-/*
- ** This code will deal properly with integers, no matter what the byte order
- ** or integer size of the host machine.  Sign extension is handled manually
- ** to prevent problems with signed/unsigned characters.  Floating point
- ** values will only be read properly when the host architecture is IEEE-754
- ** conformant.  If you need to tweak this code for other machines, you might
- ** want to snag a copy of the FITS documentation from nssdca.gsfc.nasa.gov
- */
 
 static void
-readVal(FILE *   const ifP,
-        int      const bitpix,
-        double * const vP) {
+readFitsShort(FILE *   const ifP,
+              double * const vP) {
 
-    switch (bitpix) {
-        /* 8 bit FITS integers are unsigned */
-    case 8: {
+    int ich;
+    int ival;
+    unsigned char c[8];
+
+    ich = getc(ifP);
+
+    if (ich == EOF)
+        pm_error("EOF / read error");
+
+    c[0] = ich;
+
+    ich = getc(ifP);
+
+    if (ich == EOF)
+        pm_error("EOF / read error");
+
+    c[1] = ich;
+
+    if (c[0] & 0x80)
+        ival = ~0xFFFF | c[0] << 8 | c[1];
+    else
+        ival = c[0] << 8 | c[1];
+
+    *vP = ival;
+}
+
+
+
+static void
+readFitsLong(FILE *   const ifP,
+             double * const vP) {
+
+    unsigned int i;
+    long int lval;
+    unsigned char c[4];
+
+    for (i = 0; i < 4; ++i) {
         int const ich = getc(ifP);
         if (ich == EOF)
             pm_error("EOF / read error");
-        *vP = ich;
-    } break;
+        c[i] = ich;
+    }
+
+    if (c[0] & 0x80)
+        lval = ~0xFFFFFFFF | c[0] << 24 | c[1] << 16 | c[2] << 8 | c[3];
+    else
+        lval = c[0] << 24 | c[1] << 16 | c[2] << 8 | c[3] << 0;
+
+    *vP = lval;
+}
+
+
+
+static void
+readFitsFloat(FILE *   const ifP,
+              double * const vP) {
 
-    case 16: {
-        int ich;
-        int ival;
-        unsigned char c[8];
+    unsigned int i;
+    pm_bigendFloat bigend;
 
-        ich = getc(ifP);
+    for (i = 0; i < 4; ++i) {
+        int const ich = getc(ifP);
         if (ich == EOF)
             pm_error("EOF / read error");
-        c[0] = ich;
-        ich = getc(ifP);
+        bigend.bytes[i] = ich;
+    }
+
+    *vP = pm_floatFromBigendFloat(bigend);
+}
+
+
+
+static void
+readFitsDouble(FILE *   const ifP,
+               double * const vP) {
+
+    unsigned int i;
+    pm_bigendDouble bigend;
+
+    for (i = 0; i < 8; ++i) {
+        int const ich = getc(ifP);
         if (ich == EOF)
             pm_error("EOF / read error");
-        c[1] = ich;
-        if (c[0] & 0x80)
-            ival = ~0xFFFF | c[0] << 8 | c[1];
-        else
-            ival = c[0] << 8 | c[1];
-        *vP = ival;
-    } break;
+        bigend.bytes[i] = ich;
+    }
+
+    *vP = pm_doubleFromBigendDouble(bigend);
+}
+
+
+
+static void
+readVal(FILE *   const ifP,
+        int      const bitpix,
+        double * const vP) {
+
+    switch (bitpix) {
+    case 8:
+        readFitsChar(ifP, vP);
+        break;
+
+    case 16:
+        readFitsShort(ifP, vP);
+        break;
       
-    case 32: {
-        unsigned int i;
-        long int lval;
-        unsigned char c[4];
-
-        for (i = 0; i < 4; ++i) {
-            int const ich = getc(ifP);
-            if (ich == EOF)
-                pm_error("EOF / read error");
-            c[i] = ich;
-        }
-        if (c[0] & 0x80)
-            lval = ~0xFFFFFFFF | c[0] << 24 | c[1] << 16 | c[2] << 8 | c[3];
-        else
-            lval = c[0] << 24 | c[1] << 16 | c[2] << 8 | c[3] << 0;
-        *vP = lval;
-    } break;
+    case 32:
+        readFitsLong(ifP, vP);
+        break;
       
-    case -32: {
-        unsigned int i;
-        unsigned char c[4];
-
-        for (i = 0; i < 4; ++i) {
-            int const ich = getc(ifP);
-            if (ich == EOF)
-                pm_error("EOF / read error");
-            c[i] = ich;
-        }
-        swapbytes(c, 4);
-        *vP = *((float *)c);
-    } break;
+    case -32:
+        readFitsFloat(ifP, vP);
+        break;
       
-    case -64: {
-        unsigned int i;
-        unsigned char c[8];
-
-        for (i = 0; i < 8; ++i) {
-            int const ich = getc(ifP);
-            if (ich == EOF)
-                pm_error("EOF / read error");
-            c[i] = ich;
-        }
-        swapbytes(c, 8);
-        *vP = *((double *)c);
-    } break;
+    case -64:
+        readFitsDouble(ifP, vP);
+        break;
       
     default:
         pm_error("Strange bitpix value %d in readVal()", bitpix);