Main Page | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Namespace Members | Data Fields | Globals

pnmfile.h

Go to the documentation of this file.
00001 /* basic image I/O */
00002 
00003 #ifndef PNM_FILE_H
00004 #define PNM_FILE_H
00005 
00006 #include <cstdlib>
00007 #include <climits>
00008 #include <cstring>
00009 #include <fstream>
00010 #include "image.h"
00011 #include "misc.h"
00012 
00013 #define BUF_SIZE 256
00014 
00015 class pnm_error { };
00016 
00017 static void read_packed(unsigned char *data, int size, std::ifstream &f) {
00018   unsigned char c = 0;
00019   
00020   int bitshift = -1;
00021   for (int pos = 0; pos < size; pos++) {
00022     if (bitshift == -1) {
00023       c = f.get();
00024       bitshift = 7;
00025     }
00026     data[pos] = (c >> bitshift) & 1;
00027     bitshift--;
00028     }
00029 }
00030 
00031 static void write_packed(unsigned char *data, int size, std::ofstream &f) {
00032   unsigned char c = 0;
00033   
00034   int bitshift = 7;
00035   for (int pos = 0; pos < size; pos++) {
00036       c = c | (data[pos] << bitshift);
00037       bitshift--;
00038       if ((bitshift == -1) || (pos == size-1)) {
00039         f.put(c);
00040         bitshift = 7;
00041         c = 0;
00042       }
00043   }
00044 }
00045 
00046 /* read PNM field, skipping comments */ 
00047 static void pnm_read(std::ifstream &file, char *buf) {
00048   char doc[BUF_SIZE];
00049   char c;
00050   
00051   file >> c;
00052   while (c == '#') {
00053     file.getline(doc, BUF_SIZE);
00054     file >> c;
00055   }
00056   file.putback(c);
00057   
00058   file.width(BUF_SIZE);
00059   file >> buf;
00060   file.ignore();
00061 }
00062 
00063 static image<uchar> *loadPBM(const char *name) {
00064   char buf[BUF_SIZE];
00065   
00066   /* read header */
00067   std::ifstream file(name, std::ios::in | std::ios::binary);
00068   pnm_read(file, buf);
00069   if (strncmp(buf, "P4", 2))
00070     throw pnm_error();
00071     
00072   pnm_read(file, buf);
00073   int width = atoi(buf);
00074   pnm_read(file, buf);
00075   int height = atoi(buf);
00076   
00077   /* read data */
00078   image<uchar> *im = new image<uchar>(width, height);
00079   for (int i = 0; i < height; i++)
00080     read_packed(imPtr(im, 0, i), width, file);
00081   
00082   return im;
00083 }
00084 
00085 static void savePBM(image<uchar> *im, const char *name) {
00086   int width = im->width();
00087   int height = im->height();
00088   std::ofstream file(name, std::ios::out | std::ios::binary);
00089 
00090   file << "P4\n" << width << " " << height << "\n";
00091   for (int i = 0; i < height; i++)
00092     write_packed(imPtr(im, 0, i), width, file);
00093 }
00094 
00095 static image<uchar> *loadPGM(const char *name) {
00096   char buf[BUF_SIZE];
00097   
00098   /* read header */
00099   std::ifstream file(name, std::ios::in | std::ios::binary);
00100   pnm_read(file, buf);
00101   if (strncmp(buf, "P5", 2))
00102     throw pnm_error();
00103 
00104   pnm_read(file, buf);
00105   int width = atoi(buf);
00106   pnm_read(file, buf);
00107   int height = atoi(buf);
00108 
00109   pnm_read(file, buf);
00110   if (atoi(buf) > UCHAR_MAX)
00111     throw pnm_error();
00112 
00113   /* read data */
00114   image<uchar> *im = new image<uchar>(width, height);
00115   file.read((char *)imPtr(im, 0, 0), width * height * sizeof(uchar));
00116 
00117   return im;
00118 }
00119 
00120 static void savePGM(image<uchar> *im, const char *name) {
00121   int width = im->width();
00122   int height = im->height();
00123   std::ofstream file(name, std::ios::out | std::ios::binary);
00124 
00125   file << "P5\n" << width << " " << height << "\n" << UCHAR_MAX << "\n";
00126   file.write((char *)imPtr(im, 0, 0), width * height * sizeof(uchar));
00127 }
00128 
00129 static image<rgb> *loadPPM(const char *name) {
00130   char buf[BUF_SIZE], doc[BUF_SIZE];
00131   
00132   /* read header */
00133   std::ifstream file(name, std::ios::in | std::ios::binary);
00134   pnm_read(file, buf);
00135   if (strncmp(buf, "P6", 2))
00136     throw pnm_error();
00137 
00138   pnm_read(file, buf);
00139   int width = atoi(buf);
00140   pnm_read(file, buf);
00141   int height = atoi(buf);
00142 
00143   pnm_read(file, buf);
00144   if (atoi(buf) > UCHAR_MAX)
00145     throw pnm_error();
00146 
00147   /* read data */
00148   image<rgb> *im = new image<rgb>(width, height);
00149   file.read((char *)imPtr(im, 0, 0), width * height * sizeof(rgb));
00150 
00151   return im;
00152 }
00153 
00154 static void savePPM(image<rgb> *im, const char *name) {
00155   int width = im->width();
00156   int height = im->height();
00157   std::ofstream file(name, std::ios::out | std::ios::binary);
00158 
00159   file << "P6\n" << width << " " << height << "\n" << UCHAR_MAX << "\n";
00160   file.write((char *)imPtr(im, 0, 0), width * height * sizeof(rgb));
00161 }
00162 
00163 template <class T>
00164 void load_image(image<T> **im, const char *name) {
00165   char buf[BUF_SIZE];
00166   
00167   /* read header */
00168   std::ifstream file(name, std::ios::in | std::ios::binary);
00169   pnm_read(file, buf);
00170   if (strncmp(buf, "VLIB", 9))
00171     throw pnm_error();
00172 
00173   pnm_read(file, buf);
00174   int width = atoi(buf);
00175   pnm_read(file, buf);
00176   int height = atoi(buf);
00177 
00178   /* read data */
00179   *im = new image<T>(width, height);
00180   file.read((char *)imPtr((*im), 0, 0), width * height * sizeof(T));
00181 }
00182 
00183 template <class T>
00184 void save_image(image<T> *im, const char *name) {
00185   int width = im->width();
00186   int height = im->height();
00187   std::ofstream file(name, std::ios::out | std::ios::binary);
00188 
00189   file << "VLIB\n" << width << " " << height << "\n";
00190   file.write((char *)imPtr(im, 0, 0), width * height * sizeof(T));
00191 }
00192 
00193 #endif

Generated on Wed Oct 5 14:36:12 2005 for RobotFlow by  doxygen 1.4.4