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

plpgmdec.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: plpgmdec.cpp,v 1.1 2004/05/21 21:02:53 maxx Exp $
00005 |      portable graymap Decoder Class
00006 |
00007 |      Original author: Jose Miguel Buenaposada Biencinto.
00008 |
00009 |      Copyright (c) 1996-1998 Ulrich von Zadow
00010 |
00011 \--------------------------------------------------------------------
00012 */
00013 
00014 #include "plstdpch.h"
00015 #include "plpgmdec.h"
00016 #include "plexcept.h"
00017 
00018 PLPGMDecoder::PLPGMDecoder
00019     ()
00020     : PLPicDecoder(),
00021       m_LastByte(0),
00022       m_UseLastByte(false)
00023     // Creates a decoder
00024 {
00025 }
00026 
00027 PLPGMDecoder::~PLPGMDecoder
00028     ()
00029 {
00030 }
00031 
00032 void PLPGMDecoder::DoDecode
00033     ( PLBmp * pBmp,
00034       PLDataSource * pDataSrc
00035     )
00036 {
00037   PGMHEADER PgmHead;
00038   Trace (2, "Decoding PGM.\n");
00039 
00040   readPgmHeader(&PgmHead, pDataSrc);
00041 
00042   // Image doesn't have alpha channel
00043   pBmp->Create (PgmHead.ImageWidth, PgmHead.ImageHeight,
00044                 8, false);
00045 
00046   readImage (&PgmHead, pBmp, pDataSrc);
00047 }
00048 
00049 
00050 void PLPGMDecoder::readPgmHeader
00051     ( PGMHEADER * pPgmHead,       // Pointer to PGM header structure
00052       PLDataSource * pDataSrc
00053     )
00054 {
00055   int current = 0;
00056   bool HeaderComplete = false;
00057 
00058   // Read type
00059   m_LastByte = ReadByte (pDataSrc);
00060   if (m_LastByte!=0x50) // ASCII P
00061       raiseError (PL_ERRFORMAT_UNKNOWN,
00062                   "PGM decoder: Is not the correct identifier P5 or P2.");
00063 
00064   m_LastByte = ReadByte (pDataSrc);
00065   if (m_LastByte==0x32) // ASCII 2
00066           pPgmHead->ImageType = PGM_P2;
00067   else if (m_LastByte==0x35) // ASCII 5
00068           pPgmHead->ImageType = PGM_P5;
00069   else
00070       raiseError (PL_ERRFORMAT_UNKNOWN,
00071                   "PGM decoder: Is not the correct identifier P5 or P2.");
00072 
00073   m_LastByte = ReadByte (pDataSrc);
00074 
00075   // Search for the with, height and Max gray value
00076   while (current<3)
00077   {
00078     if (m_LastByte==0x23) // # Starts a comment
00079                 skipComment(pDataSrc);
00080         else if ((m_LastByte>=0x30)&&(m_LastByte<=0x39)) // A digit
00081                 switch (current)
00082                 {
00083                 case 0: // looking for the width
00084                   {
00085                   pPgmHead->ImageWidth = readASCIIDecimal(pDataSrc);
00086                   current++;
00087                   }
00088                   break;
00089                 case 1: // looking for the height
00090                   {
00091                   pPgmHead->ImageHeight = readASCIIDecimal(pDataSrc);
00092                   current++;
00093                   }
00094                   break;
00095                 case 2: // looking for the max gray value
00096                   {
00097                   pPgmHead->MaxGrayValue  = readASCIIDecimal(pDataSrc);
00098           if ((pPgmHead->MaxGrayValue>255)||(pPgmHead->MaxGrayValue<=0))
00099                 pPgmHead->MaxGrayValue=255;
00100                   current++;
00101                   }
00102                   break;
00103                 default:
00104           continue;
00105                 }
00106         else
00107       skipPgmASCIISeparators(pDataSrc);
00108   }
00109 }
00110 
00111 PLBYTE *PLPGMDecoder::readASCIILine(PLDataSource *pDataSrc)
00112 {
00113   int i = 0;
00114   bool HaveLine = false;
00115   PLBYTE byte;
00116   PLBYTE* pLine   = new PLBYTE[PGM_MAXLINESIZE]; // Line should not be larger than 70 bytes
00117 
00118   do
00119   {
00120           if (i==80)
00121                   raiseError (PL_ERRFORMAT_UNKNOWN,
00122                          "PGM decoder: File Line to long.");
00123 
00124           byte    =ReadByte(pDataSrc);
00125           pLine[i]=byte;
00126           if ((byte==0x0D)|| // Carriege Return
00127               (byte==0x0A))  // Line Feed
00128           {
00129                   HaveLine=true;
00130                   pLine[i]=0x00;
00131           }
00132           i++;
00133   }
00134   while (!HaveLine);
00135 
00136   return pLine;
00137 }
00138 
00139 
00140 int PLPGMDecoder::readASCIIDecimal(PLDataSource * pDataSrc)
00141 {
00142   int Value    = 0;
00143   int digit;
00144 
00145   while ((m_LastByte>=0x30)&&(m_LastByte<=0x39)) // Is ASCII digit
00146   {
00147         digit      = m_LastByte - 0x30;
00148         Value      = Value*10+digit;
00149         m_LastByte = ReadByte(pDataSrc);
00150   }
00151 
00152   return Value;
00153 }
00154 
00155 void PLPGMDecoder::skipComment(PLDataSource * pDataSrc)
00156 {
00157         while ((m_LastByte!=0x0D)&& // Carriege Return
00158                (m_LastByte!=0x0A))  // New Line
00159         {
00160           m_LastByte     = ReadByte(pDataSrc);
00161         }
00162 }
00163 void PLPGMDecoder::skipPgmASCIISeparators(PLDataSource * pDataSrc)
00164 {
00165         while ((m_LastByte==0x20)|| // Space
00166              (m_LastByte==0x0D)|| // Carriege Return
00167 //           (m_LastByte<=0x10)|| // Tab
00168              (m_LastByte==0x0A))  // New Line
00169         {
00170           m_LastByte     = ReadByte(pDataSrc);
00171         }
00172 }
00173 
00174 void PLPGMDecoder::readImage
00175     ( PGMHEADER * pPgmHead,       // Pointer to PGM header structure
00176       PLBmp * pBmp,
00177       PLDataSource * pDataSrc
00178     )
00179 {
00180   switch (pPgmHead->ImageType)
00181   {
00182     case PGM_P5:
00183     case PGM_P2:
00184       readData(pPgmHead, pBmp, pDataSrc);
00185           break;
00186     default:
00187       raiseError (PL_ERRFORMAT_UNKNOWN, "Unknown PGM image type.");
00188   }
00189 }
00190 
00191 void PLPGMDecoder::readData
00192     ( PGMHEADER * pPgmHead,       // Pointer to PGM header structure
00193       PLBmp * pBmp,
00194       PLDataSource * pDataSrc
00195     )
00196 {
00197   int Width  = pPgmHead->ImageWidth;
00198   int Height = pPgmHead->ImageHeight;
00199 
00200   PLBYTE * pDest;
00201   PLBYTE ** pLineArray = pBmp->GetLineArray();
00202 
00203   int y;
00204 
00205   if (pPgmHead->ImageType == PGM_P2)
00206   {
00207     skipPgmASCIISeparators(pDataSrc);
00208     m_UseLastByte = true;
00209   }
00210 
00211   for (y=0; y < Height; y++)
00212   {
00213     pDest = pLineArray[y];
00214           if (pPgmHead->ImageType==PGM_P5) // P5
00215       expandByteLine (pDest, pPgmHead->MaxGrayValue,Width,  pDataSrc);
00216           else // P2
00217       expandASCIILine (pDest, pPgmHead->MaxGrayValue,Width, pDataSrc);
00218   }
00219 }
00220 
00221 void PLPGMDecoder::expandASCIILine
00222     ( PLBYTE * pDest,
00223       int MaxGrayValue,
00224       int Width,
00225       PLDataSource * pDataSrc
00226     )
00227 {
00228   int x;
00229 
00230   for (x=0; x<Width; x++)
00231   {
00232     *pDest = readASCIIPixel8 (MaxGrayValue, pDataSrc);
00233     pDest ++;
00234   }
00235 }
00236 
00237 void PLPGMDecoder::expandByteLine
00238     ( PLBYTE * pDest,
00239       int MaxGrayValue,
00240       int Width,
00241       PLDataSource * pDataSrc
00242     )
00243 {
00244   int x;
00245   PLBYTE *pLine;
00246 
00247   pLine = pDataSrc->ReadNBytes(Width);
00248   if (pLine==NULL)
00249           return;
00250 
00251   for (x=0; x<Width; x++)
00252   {
00253     *pDest = (PLBYTE)(((int)pLine[x]*255)/MaxGrayValue);
00254     pDest ++;
00255   }
00256 }
00257 
00258 PLBYTE PLPGMDecoder::readASCIIPixel8
00259     ( int MaxGrayValue,
00260       PLDataSource * pDataSrc
00261     )
00262 {
00263   PLBYTE Dest;
00264   int Value;
00265 
00266   skipPgmASCIISeparators(pDataSrc);
00267   m_UseLastByte = true;
00268   Value    = readASCIIDecimal(pDataSrc);
00269   Dest     = (PLBYTE)((Value*255)/MaxGrayValue);
00270 
00271   return Dest;
00272 }
00273 
00274 
00275 /*
00276 /--------------------------------------------------------------------
00277 |
00278 |      $Log: plpgmdec.cpp,v $
00279 |      Revision 1.1  2004/05/21 21:02:53  maxx
00280 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00281 |
00282 |      Revision 1.1  2002/11/13 01:58:21  mspindle
00283 |      *** empty log message ***
00284 |
00285 |      Revision 1.4  2001/10/21 17:12:40  uzadow
00286 |      Added PSD decoder beta, removed BPPWanted from all decoders, added PLFilterPixel.
00287 |
00288 |      Revision 1.3  2001/10/16 17:12:26  uzadow
00289 |      Added support for resolution information (Luca Piergentili)
00290 |
00291 |      Revision 1.2  2001/10/06 22:37:08  uzadow
00292 |      Linux compatibility.
00293 |
00294 |      Revision 1.1  2001/09/16 19:03:22  uzadow
00295 |      Added global name prefix PL, changed most filenames.
00296 |
00297 |      Revision 1.5  2001/02/04 14:31:52  uzadow
00298 |      Member initialization list cleanup (Erik Hoffmann).
00299 |
00300 |      Revision 1.4  2000/12/18 22:42:52  uzadow
00301 |      Replaced RGBAPIXEL with PLPixel32.
00302 |
00303 |      Revision 1.3  2000/05/27 16:34:05  Ulrich von Zadow
00304 |      Linux compatibility changes
00305 |
00306 |      Revision 1.2  2000/05/23 10:19:11  Ulrich von Zadow
00307 |      Minor unix compatibility changes.
00308 |
00309 |      Revision 1.1  2000/03/16 13:56:37  Ulrich von Zadow
00310 |      Added pgm decoder by Jose Miguel Buenaposada Biencinto
00311 |
00312 |
00313 \--------------------------------------------------------------------
00314 */

Generated on Wed Dec 15 21:20:30 2004 for vuVolume by  doxygen 1.3.9.1