Main Page   Data Structures   File List   Data Fields   Globals  

pnm2img.c

Go to the documentation of this file.
00001 #include "sadie.h"
00002 
00003 #define BUFFER_SIZE 1000
00004 
00005 #define UCHAR(c) ((unsigned char) (c))
00006 
00007 /*
00008  * The maximum amount of memory to allocate for data read from the
00009  * file.  If we need more than this, we do it in pieces.
00010  */
00011 
00012 #define MAX_MEMORY      10000   /* don't allocate > 10KB */
00013 
00014 /*
00015  * Define PGM and PNM, i.e. gray images and color images.
00016  */
00017 
00018 #define PGM 1
00019 #define PPM 2
00020 
00021 /*
00022  * Prototypes for local procedures defined in this file:
00023  */
00024 
00025 static int ReadPNMFileHeader (FILE * fp,
00026                               int *widthPtr, int *heightPtr,
00027                               int *maxIntensityPtr);
00028 
00029 /*-Copyright Information------------------------------------------------------*/
00030 /* Copyright (c) 1998 by the University of Arizona Digital Image Analysis Lab */
00031 /*-General Information--------------------------------------------------------*/
00032 /*                                                                            */
00033 /*   This function reads a PNM image from disk into main memory.            */
00034 /*                                                                            */
00035 /*----------------------------------------------------------------------------*/
00036 /*-Interface Information------------------------------------------------------*/
00037 void
00038 PNM2IMG (name, out)
00039      char *name;                /*  I   String, containing the name of the disk file.         */
00040      IMAGE **out;               /*  O   Address of a pointer to the image.                    */
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   /* open image file */
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       /* create image of appropriate size */
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       /* create image of appropriate size */
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;                  /* Image file to read the header from */
00165      int *widthPtr, *heightPtr; /* The dimensions of the image are
00166                                  * returned here. */
00167      int *maxIntensityPtr;      /* The maximum intensity value for
00168                                  * the image is stored here. */
00169 {
00170   char buffer[BUFFER_SIZE];
00171   int i, numFields, firstInLine;
00172   int type = 0;
00173   char c;
00174 
00175   /*
00176    * Read 4 space-separated fields from the file, ignoring
00177    * comments (any line that starts with "#").
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        * Skip comments and white space.
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        * Read a field (everything up to the next white space).
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    * Parse the fields, which are: id, width, height, maxIntensity.
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 }

Generated on Sun May 18 15:36:12 2003 for tclSadie by doxygen1.3