615: Add i/o read for pbm and pgm formats.

2006-10-10 Thierry GERAUD <theo@tegucigalpa.lrde.epita.fr> Add i/o read for pbm and pgm formats. * tests/io_pnm.cc: New. * tests/Makefile.am (check_PROGRAMS): Update. * oln/io: New directory. * oln/io/pnm.hh: New. * oln/core/image_entry.hh (coord_type): New single_vtype. * oln/core/abstract/image.hh (decl): New comment. * oln/core/2d/image2d.hh (adr_at): New. * oln/basics2d.hh (include): Add fwd_piter.hh. * oln/Makefile.am (nobase_oln_HEADERS): Update. * img: New directory. * img/chien.pbm: New. * img/lena32.pgm: New. Index: tests/io_pnm.cc =================================================================== --- tests/io_pnm.cc (revision 0) +++ tests/io_pnm.cc (revision 0) @@ -0,0 +1,40 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/// Test oln::io_pnm.cc. + +#include <cassert> +#include <oln/basics2d.hh> +#include <oln/io/pnm.hh> + +int +main() +{ + // Fill a 2-d image using its iterator. + oln::image2d<bool> ima = oln::io::load_pbm("../img/chien.pbm"); + oln::image2d<unsigned char> ima2 = oln::io::load_pgm("../img/lena32.pgm"); +} Index: tests/Makefile.am =================================================================== --- tests/Makefile.am (revision 614) +++ tests/Makefile.am (working copy) @@ -25,6 +25,7 @@ image1d \ image2d \ image3d \ + io_pnm \ npoints \ \ identity_morpher \ Index: oln/io/pnm.hh =================================================================== --- oln/io/pnm.hh (revision 0) +++ oln/io/pnm.hh (revision 0) @@ -0,0 +1,224 @@ +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 EPITA Research and +// Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef OLN_IO_PNM_HH +# define OLN_IO_PNM_HH + +# include <iostream> +# include <fstream> +# include <string> + +# include <oln/core/2d/image2d.hh> + + +namespace oln { + + namespace io { + + namespace internal { + + void abort() + { + std::cerr << " aborting." << std::endl; + exit(0); + } + + bool read_pnm_header(std::istream& istr, + char& type, + int& nrows, int& ncols, + bool test = false) + { + // check magic + if (istr.get() != 'P' ) + goto err; + type = istr.get(); + if (type < '1' or type > '6') + goto err; + if (istr.get() != '\n') + goto err; + + // skip comments + while (istr.peek() == '#') + { + std::string line; + std::getline(istr, line); + } + + // get size + istr >> ncols >> nrows; + if (nrows <= 0 or ncols <= 0) + goto err; + + // skip maxvalue + if (istr.get() != '\n') + goto err; + if (type != '1' and type != '4') + { + std::string line; + std::getline(istr, line); + } + return true; + + err: + if (not test) + { + std::cerr << "error: badly formed header!"; + abort(); + } + return false; + } + + void read_pnm_header(char ascii, char raw, + std::istream& istr, + char& type, + int& nrows, int& ncols) + { + read_pnm_header(istr, type, nrows, ncols); + if (not (type == ascii or type == raw)) + { + std::cerr << "error: bad pnm type; " + << "expected P" << ascii + << " or P" << raw + << ", get P" << type << "!"; + abort(); + } + } + + + /// load_pbm_raw. + template <typename I> + void load_pbm_raw(std::ifstream& file, I& ima) + { + oln_type_of(I, coord) cols = 0; + unsigned bits = 0; + unsigned char c = 0; + oln_type_of(I, fwd_piter) p(ima.topo()); + for_all(p) + { + if (bits == 0) + { + c = file.get(); + bits = 8; + } + ima(p) = (c & (1 << --bits)) ? false : true; + if (++cols >= int(ima.bbox().ncols())) + cols = bits = 0; + } + } + + + /// load_pbm_ascii. + template <typename I> + void load_pbm_ascii(std::ifstream& file, I& ima) + { + oln_type_of(I, fwd_piter) p(ima.topo()); + for_all(p) + ima(p) = (file.get() == '0'); + } + + + /// load_ascii. + template <typename I> + void load_pnm_ascii(std::ifstream& file, I& ima) + { + oln_type_of(I, fwd_piter) p(ima.topo()); + for_all(p) + { + oln_type_of(I, value) value; + file >> value; + ima(p) = value; + // FIXME: Test alt code below. + // file >> ima(p); + } + } + + + /// load_raw_2d. + template <typename I> + void load_pnm_raw_2d(std::ifstream& file, I& ima) + { + int col = ima.pmin().col(); + size_t len = ima.bbox().ncols(); + for (int row = ima.pmin().row(); row <= ima.pmax().row(); ++row) + file.read((char*)(ima.adr_at(row, col)), + len * sizeof(oln_type_of(I, value))); + } + + + } // end of namespace oln::io::internal + + + image2d<bool> load_pbm(const std::string& filename) + { + std::ifstream file(filename.c_str()); + if (not file) + { + std::cerr << "error: file '" << filename + << "' not found!"; + abort(); + } + char type; + int nrows, ncols; + internal::read_pnm_header('1', '4', file, type, nrows, ncols); + image2d<bool> ima(nrows, ncols); + if (type == '4') + internal::load_pbm_raw(file, ima); + else + // type == '1' + internal::load_pbm_ascii(file, ima); + return ima; + } + + + image2d<unsigned char> load_pgm(const std::string& filename) + { + std::ifstream file(filename.c_str()); + if (not file) + { + std::cerr << "error: file '" << filename + << "' not found!"; + abort(); + } + char type; + int nrows, ncols; + internal::read_pnm_header('2', '5', file, type, nrows, ncols); + image2d<unsigned char> ima(nrows, ncols); + if (type == '4') + internal::load_pnm_raw_2d(file, ima); + else + // type == '1' + internal::load_pnm_ascii(file, ima); + return ima; + } + + } // end of namespace oln::io + +} // end of namespace oln + + +#endif // ! OLN_IO_PNM_HH Index: oln/core/image_entry.hh =================================================================== --- oln/core/image_entry.hh (revision 614) +++ oln/core/image_entry.hh (working copy) @@ -67,6 +67,8 @@ typedef mlc::undefined topo_type; typedef mlc::undefined grid_type; + // coord_type: see below. + // psite_type: see below. typedef mlc::undefined point_type; @@ -82,13 +84,23 @@ }; + // Coord. template <typename E> + struct single_vtype< image_entry<E>, typedef_::coord_type > + { + typedef oln_deduce_type_of(E, point, coord) ret; + }; + + + // Psite. + template <typename E> struct single_vtype< image_entry<E>, typedef_::psite_type > { typedef oln_type_of(E, point) ret; }; + // Piter. template <typename E> struct single_vtype< image_entry<E>, typedef_::piter_type > { @@ -96,6 +108,7 @@ }; + // Rvalue. template <typename E> struct single_vtype< image_entry<E>, typedef_::rvalue_type > { Index: oln/core/abstract/image.hh =================================================================== --- oln/core/abstract/image.hh (revision 614) +++ oln/core/abstract/image.hh (working copy) @@ -66,6 +66,8 @@ // oln_virtual_typedef(topo); // oln_virtual_typedef(grid); +// oln_virtual_typedef(coord); + // oln_virtual_typedef(psite); // oln_virtual_typedef(point); Index: oln/core/2d/image2d.hh =================================================================== --- oln/core/2d/image2d.hh (revision 614) +++ oln/core/2d/image2d.hh (working copy) @@ -89,6 +89,9 @@ T& impl_op_readwrite(const point2d& p); + T* adr_at(int row, int col); + const T* adr_at(int row, int col) const; + private: topo2d topo_; @@ -143,6 +146,22 @@ return data_->operator()(p.row(), p.col()); } + template <typename T> + T* image2d<T>::adr_at(int row, int col) + { + precondition(data_ != 0); + precondition(data_->has(row, col)); + return &(data_->operator()(row, col)); + } + + template <typename T> + const T* image2d<T>::adr_at(int row, int col) const + { + precondition(data_ != 0); + precondition(data_->has(row, col)); + return &(data_->operator()(row, col)); + } + # endif } // end of namespace oln Index: oln/basics2d.hh =================================================================== --- oln/basics2d.hh (revision 614) +++ oln/basics2d.hh (working copy) @@ -50,5 +50,7 @@ # include <oln/core/2d/image2d.hh> +# include <oln/core/fwd_piter.hh> + #endif // ! OLN_BASICS2D_HH Index: oln/Makefile.am =================================================================== --- oln/Makefile.am (revision 614) +++ oln/Makefile.am (working copy) @@ -132,6 +132,8 @@ \ debug/print.hh \ \ + io/pnm.hh \ + \ level/fill.hh \ \ morpher/internal/image_extension.hh \ Index: img/chien.pbm =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: img/chien.pbm ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: img/lena32.pgm =================================================================== --- img/lena32.pgm (revision 0) +++ img/lena32.pgm (revision 0) @@ -0,0 +1,4 @@ +P5 +32 32 +255 +€chmzt¹Šsy{{`£bgly~~~~vv Áw{Y3 ¡ `fkx}~ ~~}wt³³uV40¡]dlw|ªysrÆp02.r Xbhsy{w} «ºÀ°io@02<hk Ybhsxrs{ŠºÇÏÁqhdB/1FyYkYbhtvov«ÀÇËзo>yZ129uZkV`g{ynz¢Ž»ÁÇÉÑ SŠÁK12aao Ycf xlx§¯±·ŸŸÅÁ¥ ¶ÎÉO-F`p£Zac l|§ª«±µ²µŸÆÊÀ©<4v_r€Zaav±œÃÉ¿r.Scu¥Ya`¢z~r[fU[¢¿ÀŸ¥|B4wfs€X_a|ª|zbF>H]޶Ž| F/H£fn£X`ep |vX@C;P°¬»¿mlF32e¡ dl£[cit xT:6?Sª¥ÃÐRE6= ck£[ci}naD:6C§y»²pJO4T_d£\`pUKI73j¯qVo«mEFU4n\]€blnZJOU/C®THX< ±NS¡brZSD>V;swv«±cFXM ÀÅHMfhV\D9UVuGu¡§V@^gºÉÍIX¡b]NYYAVrIIw£@>d ÇÎÐA^€f[DR_iQ5Jt d7@fªÏÑÓ7_ŠhSDdcp56Aa~?8Dj³ÕÓÒ1a£^HAdotB548Cbf2>Lmº×Ï·;Ra>A]jqM935>d ^AOo}~ÀÍOwY€Z8GKWse>59Go¡»ÁGqs}ÅTXsp€O1A:KkoI5<UqÃÎirªÇsac_t¢I1A4>foN:KewŠœÒ }Í®gc`Sz£M295@XY<7_hŽËÄ~ Ÿ\^Z[¢M075<^I,BakªÄÐWP«\W]Oi E39B>UA.Od~¡¹Ïa[iOU_FQ<9ANKJBFl|°È°esr`T_X? \ No newline at end of file
participants (1)
-
Thierry GERAUD