Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

PbmFile.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library 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.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 /**
00029  * @file   PbmFile.C
00030  * @brief  Implementation of class qgar::PbmFile.
00031  *
00032  *         See file PbmFile.H for the interface.
00033  *
00034  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Karl Tombre">Karl Tombre</a>
00035  * @date   Jul 3, 2001  17:50
00036  * @since  qgar 1.0
00037  */
00038 
00039 
00040 // Most of the code documented here is an adaptation of code from the PBM
00041 // software package. Here is the copyright notice of this package:
00042 //
00043 // +------------------------------------------------------------------------+
00044 // | Copyright (C) 1988 by Jef Poskanzer                                    |
00045 // |                                                                        |
00046 // | Permission to use, copy, modify, and distribute this software and its  |
00047 // | documentation for any purpose and without fee is hereby granted,       |
00048 // | provided that the above copyright notice appear in all copies and that |
00049 // | both that copyright notice and this permission notice appear in        |
00050 // | supporting documentation.  This software is provided "as is" without   |
00051 // | express or implied warranty.                                           |
00052 // +------------------------------------------------------------------------+
00053 
00054 
00055 
00056 // STD
00057 #include <sstream>
00058 // QGAR
00059 #include <qgarlib/AbstractPbmPlusFile.H>
00060 #include <qgarlib/PbmFile.H>
00061 #include <qgarlib/QgarErrorIO.H>
00062 
00063 
00064 
00065 namespace qgar
00066 {
00067 
00068 // -------------------------------------------------------------------
00069 // I N I T I A L I Z A T I O N S   O F   S T A T I C   M E M B E R S 
00070 // -------------------------------------------------------------------
00071 
00072 
00073 const unsigned char  PbmFile::_s_pbm_magic1 = 'P';
00074 
00075 const unsigned char  PbmFile::_s_pbm_magic2 = '1';
00076 
00077 const unsigned short PbmFile::_s_pbm_format =
00078    (((unsigned short) PbmFile::_s_pbm_magic1) * 256)
00079  + (unsigned short) PbmFile::_s_pbm_magic2;
00080 
00081 const unsigned char  PbmFile::_s_rpbm_magic2 = '4';
00082 
00083 const unsigned short PbmFile::_s_rpbm_format =
00084   (((unsigned short) PbmFile::_s_pbm_magic1) * 256)
00085 + (unsigned short) PbmFile::_s_rpbm_magic2;
00086 
00087 
00088 // -------------------------------------------------------------------
00089 // C O N S T R U C T O R S 
00090 // -------------------------------------------------------------------
00091 
00092 
00093 // INITIALIZE FROM FILE NAME AND FORMAT.
00094 
00095 PbmFile::PbmFile(const char* aFileName, QGEpbmFormat aFormat)
00096 
00097   : AbstractPbmPlusFile(aFileName, 0, 0, aFormat)
00098 
00099 {
00100   // VOID
00101 }
00102 
00103 
00104 // INITIALIZE FROM FULL DATA
00105 
00106 PbmFile::PbmFile(const char* aFileName,
00107                  unsigned int aRowCnt,
00108                  unsigned int aColCnt,
00109                  QGEpbmFormat aFormat)
00110 
00111   : AbstractPbmPlusFile(aFileName, aRowCnt, aColCnt, aFormat)
00112 
00113 {
00114   // VOID
00115 }
00116 
00117 
00118 // -------------------------------------------------------------------
00119 // I N P U T 
00120 // -------------------------------------------------------------------
00121 
00122 
00123 // READ FILE HEADER
00124 
00125 void
00126 PbmFile::readHeader()
00127 
00128   throw(QgarErrorIO)
00129 
00130 {
00131   int ch1 = _fileStream.get();
00132   if (ch1 == EOF)
00133     {
00134       std::ostringstream os;
00135       os << "EOF while reading in file "
00136          << _fileName;
00137       throw QgarErrorIO(__FILE__, __LINE__,
00138                         "void qgar::PbmFile::readHeader()",
00139                         os.str());
00140     }
00141   
00142   int ch2 = _fileStream.get();
00143   if (ch2 == EOF)
00144     {
00145       std::ostringstream os;
00146       os << "EOF while reading in file "
00147          << _fileName;
00148       throw QgarErrorIO(__FILE__, __LINE__,
00149                         "void qgar::PbmFile::readHeader()",
00150                         os.str());
00151     }
00152 
00153   unsigned short magicNb = (ch1 * 256) + ch2;
00154 
00155   if (magicNb == _s_pbm_format)
00156     {
00157       _format = QGE_PBM_PLAIN;
00158     }
00159   else if (magicNb == _s_rpbm_format)
00160     {
00161       _format = QGE_PBM_RAW;
00162     }
00163   else
00164     {
00165       std::ostringstream os;
00166       os << "Bad magic number in file "
00167          << _fileName;
00168       throw QgarErrorIO(__FILE__, __LINE__,
00169                         "void qgar::PbmFile::readHeader()",
00170                         os.str());
00171     }
00172 
00173   _colCnt = getInt();
00174   _rowCnt = getInt();
00175   newRow();
00176 }
00177 
00178 
00179 // READ A ROW FROM THE FILE
00180 
00181 void
00182 PbmFile::readRow()
00183 {
00184   isOpenR();
00185 
00186   int col;
00187   int bitshift;
00188   unsigned char  item = 0;
00189   unsigned char* pRow;
00190 
00191   switch (_format)
00192     {
00193     case QGE_PBM_PLAIN:
00194       for (col = 0, pRow = _pRow; col < _colCnt; ++col, ++pRow)
00195         {
00196           *pRow = getBit();
00197         }
00198       break;
00199 
00200     case QGE_PBM_RAW:
00201       bitshift = -1;
00202       for (col = 0, pRow = _pRow; col < _colCnt; ++col, ++pRow)
00203         {
00204           if (bitshift == -1)
00205             {
00206               item = getRawByte();
00207               bitshift = 7;
00208             }
00209           *pRow = (item >> bitshift) & 1;
00210           --bitshift;
00211         }
00212     }
00213 }
00214 
00215 
00216 // GET A BIT FROM THE FILE
00217 
00218 unsigned char
00219 PbmFile::getBit()
00220 
00221   throw(QgarErrorIO)
00222 
00223 {
00224   char c;
00225 
00226   do
00227     {
00228       c = getChar();
00229     }
00230   while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
00231 
00232   if ((c != '0') && (c != '1'))
00233     {
00234       std::ostringstream os;
00235       os << "Junk in file "
00236          << _fileName;
00237       throw QgarErrorIO(__FILE__, __LINE__,
00238                         "unsigned char qgar::PbmFile::getBit()",
00239                         os.str());
00240     }
00241 
00242   return((c == '1') ? 1 : 0);
00243 }
00244 
00245 
00246 // -------------------------------------------------------------------
00247 // O U T P U T 
00248 // -------------------------------------------------------------------
00249 
00250 
00251 // WRITE FILE HEADER
00252 
00253 void
00254 PbmFile::writeHeader()
00255 {
00256   if (_format == QGE_PBM_RAW)
00257     {
00258       _fileStream << _s_pbm_magic1
00259                   << _s_rpbm_magic2
00260                   << std::endl;
00261     }
00262   else
00263     {
00264       _fileStream << _s_pbm_magic1
00265                   << _s_pbm_magic2
00266                   << std::endl;
00267     }
00268 
00269   _fileStream << _colCnt
00270               << ' '
00271               << _rowCnt
00272               << std::endl;
00273   newRow();
00274 }
00275 
00276 
00277 // WRITE A ROW INTO THE FILE
00278 
00279 void
00280 PbmFile::writeRow()
00281 {
00282   isOpenW();
00283 
00284   if (_format == QGE_PBM_RAW)
00285     {
00286       int       col;
00287       int       bitshift = 7;
00288       unsigned char  item     = 0;
00289       unsigned char* pRow;
00290 
00291       for (col = 0, pRow = _pRow; col < _colCnt; ++col, ++pRow)
00292         {
00293           if (*pRow != 0)
00294             {
00295               item += 1 << bitshift;
00296             }
00297           --bitshift;
00298           if (bitshift == -1 )
00299             {
00300               _fileStream.put(item);
00301               bitshift = 7;
00302               item = 0;
00303             }
00304         }
00305 
00306       if (bitshift != 7 )
00307         {
00308           _fileStream.put(item);
00309         }
00310     }
00311   else
00312     {
00313       int       col;
00314       int       charCnt = 0;
00315       unsigned char* pRow;
00316 
00317       for (col = 0, pRow = _pRow; col < _colCnt; ++col, ++pRow)
00318         {
00319           if (charCnt >= 70)
00320             {
00321             _fileStream << std::endl;
00322             charCnt = 0;
00323             }
00324         _fileStream << ((*pRow !=0) ? '1' : '0');
00325         ++charCnt;
00326         }
00327 
00328       _fileStream << std::endl;
00329     }
00330 }
00331 
00332 
00333 // WRITE FILE FOOTER
00334 
00335 void
00336 PbmFile::writeFooter()
00337 {
00338   // VOID
00339 }
00340 
00341 
00342 // -------------------------------------------------------------------
00343 
00344 
00345 } // namespace qgar