pnmfile.h
Go to the documentation of this file.
00001 /*
00002 Copyright (C) 2006 Pedro Felzenszwalb
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU General Public License as published by
00006 the Free Software Foundation; either version 2 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU General Public License for more details.
00013 
00014 You should have received a copy of the GNU General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00017 */
00018 
00019 /* basic image I/O */
00020 
00021 #ifndef PNM_FILE_H
00022 #define PNM_FILE_H
00023 
00024 #include <cstdlib>
00025 #include <climits>
00026 #include <cstring>
00027 #include <fstream>
00028 #include "image.h"
00029 #include "misc.h"
00030 
00031 #define BUF_SIZE 256
00032 
00033 class pnm_error { };
00034 
00035 static void read_packed(unsigned char *data, int size, std::ifstream &f) {
00036   unsigned char c = 0;
00037   
00038   int bitshift = -1;
00039   for (int pos = 0; pos < size; pos++) {
00040     if (bitshift == -1) {
00041       c = f.get();
00042       bitshift = 7;
00043     }
00044     data[pos] = (c >> bitshift) & 1;
00045     bitshift--;
00046     }
00047 }
00048 
00049 static void write_packed(unsigned char *data, int size, std::ofstream &f) {
00050   unsigned char c = 0;
00051   
00052   int bitshift = 7;
00053   for (int pos = 0; pos < size; pos++) {
00054       c = c | (data[pos] << bitshift);
00055       bitshift--;
00056       if ((bitshift == -1) || (pos == size-1)) {
00057         f.put(c);
00058         bitshift = 7;
00059         c = 0;
00060       }
00061   }
00062 }
00063 
00064 /* read PNM field, skipping comments */ 
00065 static void pnm_read(std::ifstream &file, char *buf) {
00066   char doc[BUF_SIZE];
00067   char c;
00068   
00069   file >> c;
00070   while (c == '#') {
00071     file.getline(doc, BUF_SIZE);
00072     file >> c;
00073   }
00074   file.putback(c);
00075   
00076   file.width(BUF_SIZE);
00077   file >> buf;
00078   file.ignore();
00079 }
00080 
00081 static image<uchar> *loadPBM(const char *name) {
00082   char buf[BUF_SIZE];
00083   
00084   /* read header */
00085   std::ifstream file(name, std::ios::in | std::ios::binary);
00086   pnm_read(file, buf);
00087   if (strncmp(buf, "P4", 2))
00088     throw pnm_error();
00089     
00090   pnm_read(file, buf);
00091   int width = atoi(buf);
00092   pnm_read(file, buf);
00093   int height = atoi(buf);
00094   
00095   /* read data */
00096   image<uchar> *im = new image<uchar>(width, height);
00097   for (int i = 0; i < height; i++)
00098     read_packed(imPtr(im, 0, i), width, file);
00099   
00100   return im;
00101 }
00102 
00103 static void savePBM(image<uchar> *im, const char *name) {
00104   int width = im->width();
00105   int height = im->height();
00106   std::ofstream file(name, std::ios::out | std::ios::binary);
00107 
00108   file << "P4\n" << width << " " << height << "\n";
00109   for (int i = 0; i < height; i++)
00110     write_packed(imPtr(im, 0, i), width, file);
00111 }
00112 
00113 static image<uchar> *loadPGM(const char *name) {
00114   char buf[BUF_SIZE];
00115   
00116   /* read header */
00117   std::ifstream file(name, std::ios::in | std::ios::binary);
00118   pnm_read(file, buf);
00119   if (strncmp(buf, "P5", 2))
00120     throw pnm_error();
00121 
00122   pnm_read(file, buf);
00123   int width = atoi(buf);
00124   pnm_read(file, buf);
00125   int height = atoi(buf);
00126 
00127   pnm_read(file, buf);
00128   if (atoi(buf) > UCHAR_MAX)
00129     throw pnm_error();
00130 
00131   /* read data */
00132   image<uchar> *im = new image<uchar>(width, height);
00133   file.read((char *)imPtr(im, 0, 0), width * height * sizeof(uchar));
00134 
00135   return im;
00136 }
00137 
00138 static void savePGM(image<uchar> *im, const char *name) {
00139   int width = im->width();
00140   int height = im->height();
00141   std::ofstream file(name, std::ios::out | std::ios::binary);
00142 
00143   file << "P5\n" << width << " " << height << "\n" << UCHAR_MAX << "\n";
00144   file.write((char *)imPtr(im, 0, 0), width * height * sizeof(uchar));
00145 }
00146 
00147 static image<rgb> *loadPPM(const char *name) {
00148   char buf[BUF_SIZE], doc[BUF_SIZE];
00149   
00150   /* read header */
00151   std::ifstream file(name, std::ios::in | std::ios::binary);
00152   pnm_read(file, buf);
00153   if (strncmp(buf, "P6", 2))
00154     throw pnm_error();
00155 
00156   pnm_read(file, buf);
00157   int width = atoi(buf);
00158   pnm_read(file, buf);
00159   int height = atoi(buf);
00160 
00161   pnm_read(file, buf);
00162   if (atoi(buf) > UCHAR_MAX)
00163     throw pnm_error();
00164 
00165   /* read data */
00166   image<rgb> *im = new image<rgb>(width, height);
00167   file.read((char *)imPtr(im, 0, 0), width * height * sizeof(rgb));
00168 
00169   return im;
00170 }
00171 
00172 static void savePPM(image<rgb> *im, const char *name) {
00173   int width = im->width();
00174   int height = im->height();
00175   std::ofstream file(name, std::ios::out | std::ios::binary);
00176 
00177   file << "P6\n" << width << " " << height << "\n" << UCHAR_MAX << "\n";
00178   file.write((char *)imPtr(im, 0, 0), width * height * sizeof(rgb));
00179 }
00180 
00181 template <class T>
00182 void load_image(image<T> **im, const char *name) {
00183   char buf[BUF_SIZE];
00184   
00185   /* read header */
00186   std::ifstream file(name, std::ios::in | std::ios::binary);
00187   pnm_read(file, buf);
00188   if (strncmp(buf, "VLIB", 9))
00189     throw pnm_error();
00190 
00191   pnm_read(file, buf);
00192   int width = atoi(buf);
00193   pnm_read(file, buf);
00194   int height = atoi(buf);
00195 
00196   /* read data */
00197   *im = new image<T>(width, height);
00198   file.read((char *)imPtr((*im), 0, 0), width * height * sizeof(T));
00199 }
00200 
00201 template <class T>
00202 void save_image(image<T> *im, const char *name) {
00203   int width = im->width();
00204   int height = im->height();
00205   std::ofstream file(name, std::ios::out | std::ios::binary);
00206 
00207   file << "VLIB\n" << width << " " << height << "\n";
00208   file.write((char *)imPtr(im, 0, 0), width * height * sizeof(T));
00209 }
00210 
00211 #endif


iri_leaf_fitting
Author(s): Sergi Foix
autogenerated on Fri Dec 6 2013 20:28:17