00001 #include "sadie.h"
00002
00003 #define BUFFER_SIZE 1000
00004
00005 #define UCHAR(c) ((unsigned char) (c))
00006
00007
00008
00009
00010
00011
00012 #define MAX_MEMORY 10000
00013
00014
00015
00016
00017
00018 #define PGM 1
00019 #define PPM 2
00020
00021
00022
00023
00024
00025 static int ReadPNMFileHeader (FILE * fp,
00026 int *widthPtr, int *heightPtr,
00027 int *maxIntensityPtr);
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 void
00038 PNM2IMG (name, out)
00039 char *name;
00040 IMAGE **out;
00041
00042 {
00043 int i, j, k;
00044 char msg[SLEN];
00045 int fileWidth, fileHeight, maxIntensity;
00046 int nLines, nBytes, h, type, count;
00047 FILE *fp = NULL;
00048 unsigned char *pixelPtr = NULL, *data = NULL;
00049
00050
00051 if (!(fp = fopen (name, "r")))
00052 {
00053 sprintf (msg, " Can't open file %s.", name);
00054 MESSAGE ('E', msg);
00055 goto the_end;
00056 }
00057
00058 type = ReadPNMFileHeader (fp, &fileWidth, &fileHeight, &maxIntensity);
00059 if (type == 0)
00060 {
00061 sprintf (msg, "Couldn't read raw PNM header from file %s.", name);
00062 }
00063 if ((fileWidth <= 0) || (fileHeight <= 0))
00064 {
00065 sprintf (msg, "PNM image file %s has dimension(s) <= 0", name);
00066 MESSAGE ('E', msg);
00067 goto the_end;
00068 }
00069 if ((maxIntensity <= 0) || (maxIntensity >= 256))
00070 {
00071 sprintf (msg, "PNM image file %s has bad maximum intensity value %d",
00072 name, maxIntensity);
00073 MESSAGE ('E', msg);
00074 goto the_end;
00075 }
00076
00077 if (type == PGM)
00078 {
00079
00080 if (!CHECKIMG (*out))
00081 GETMEM (1, fileHeight, fileWidth, out);
00082 if (!CHECKIMG (*out))
00083 {
00084 sprintf (msg, "Can't allocate memory for image.");
00085 MESSAGE ('E', msg);
00086 goto the_end;
00087 }
00088 }
00089 else
00090 {
00091
00092 if (!CHECKIMG (*out))
00093 GETMEM (3, fileHeight, fileWidth, out);
00094 if (!CHECKIMG (*out))
00095 {
00096 sprintf (msg, "Can't allocate memory for image.");
00097 MESSAGE ('E', msg);
00098 goto the_end;
00099 }
00100 }
00101
00102 if (NAMES)
00103 {
00104 MESSAGE ('I', "");
00105 MESSAGE ('I', "PNM2IMG");
00106 MESSAGE ('I', "");
00107 sprintf (msg, " Input file: %s", name);
00108 MESSAGE ('I', msg);
00109 MESSAGE ('I', " Input format: PNM");
00110 sprintf (msg, " Number of bands, lines, pixels: %d, %d, %d",
00111 (*out)->nbnd, (*out)->nlin, (*out)->npix);
00112 MESSAGE ('I', msg);
00113 sprintf (msg, " Number of bits/pixel/band: %d", 8);
00114 MESSAGE ('I', msg);
00115 MESSAGE ('I', " ...............");
00116 }
00117
00118 nBytes = (*out)->npix * (*out)->nbnd;
00119 pixelPtr = (unsigned char *) malloc ((unsigned) nBytes);
00120 if (!pixelPtr)
00121 {
00122 MESSAGE ('E', "Could not allocate memory to read image.");
00123 goto the_end;
00124 }
00125
00126 for (j = 0; j < (*out)->nlin; j++)
00127 {
00128 data = pixelPtr;
00129 count = fread (data, 1, nBytes, fp);
00130
00131 if (count != nBytes)
00132 {
00133 sprintf (msg, "Error reading PNM image file %s: not enough data",
00134 name);
00135 MESSAGE ('E', msg);
00136 goto the_end;
00137 }
00138 for (k = 0; k < (*out)->npix; k++)
00139 {
00140 for (i = 0; i < (*out)->nbnd; i++)
00141 {
00142 (*out)->data[i][j][k] = (PIXEL) * data++;
00143 }
00144 }
00145 }
00146
00147 the_end:
00148
00149 if (pixelPtr)
00150 free (pixelPtr);
00151
00152 if (fp)
00153 {
00154 if (fclose (fp))
00155 {
00156 sprintf (msg, " Can't close file %s.", name);
00157 MESSAGE ('W', msg);
00158 }
00159 }
00160 }
00161
00162 static int
00163 ReadPNMFileHeader (fp, widthPtr, heightPtr, maxIntensityPtr)
00164 FILE *fp;
00165 int *widthPtr, *heightPtr;
00166
00167 int *maxIntensityPtr;
00168
00169 {
00170 char buffer[BUFFER_SIZE];
00171 int i, numFields, firstInLine;
00172 int type = 0;
00173 char c;
00174
00175
00176
00177
00178
00179
00180 if (fread (&c, 1, 1, fp) != 1)
00181 {
00182 return 0;
00183 }
00184 firstInLine = 1;
00185 i = 0;
00186 for (numFields = 0; numFields < 4; numFields++)
00187 {
00188
00189
00190
00191
00192 while (1)
00193 {
00194 while (isspace (UCHAR (c)))
00195 {
00196 firstInLine = (c == '\n');
00197 if (fread (&c, 1, 1, fp) != 1)
00198 {
00199 return 0;
00200 }
00201 }
00202 if (c != '#')
00203 {
00204 break;
00205 }
00206 do
00207 {
00208 if (fread (&c, 1, 1, fp) != 1)
00209 {
00210 return 0;
00211 }
00212 }
00213 while (c != '\n');
00214 firstInLine = 1;
00215 }
00216
00217
00218
00219
00220
00221 while (!isspace (UCHAR (c)))
00222 {
00223 if (i < (BUFFER_SIZE - 2))
00224 {
00225 buffer[i] = c;
00226 i++;
00227 }
00228 if (fread (&c, 1, 1, fp) != 1)
00229 {
00230 goto done;
00231 }
00232 }
00233 if (i < (BUFFER_SIZE - 1))
00234 {
00235 buffer[i] = ' ';
00236 i++;
00237 }
00238 firstInLine = 0;
00239 }
00240 done:
00241 buffer[i] = 0;
00242
00243
00244
00245
00246
00247 if (strncmp (buffer, "P6 ", 3) == 0)
00248 {
00249 type = PPM;
00250 }
00251 else if (strncmp (buffer, "P5 ", 3) == 0)
00252 {
00253 type = PGM;
00254 }
00255 else
00256 {
00257 return 0;
00258 }
00259 if (sscanf (buffer + 3, "%d %d %d", widthPtr, heightPtr, maxIntensityPtr)
00260 != 3)
00261 {
00262 return 0;
00263 }
00264 return type;
00265 }