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


grid_map_sdf
Author(s): Takahiro Miki , Péter Fankhauser
autogenerated on Mon Oct 9 2017 03:09:34