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

plpicdec.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: plpicdec.cpp,v 1.1 2004/05/21 21:02:53 maxx Exp $
00005 |      Generic Picture Decoder Class
00006 |
00007 |      Abstract base class to construct PLBmps from picture data in
00008 |      memory or in a file. Classes derived from this class implement
00009 |      concrete decoders for specific file formats. The data is
00010 |      returned in 8- or 32-bit DIBs with a valid alpha channel.
00011 |
00012 |      Copyright (c) 1996-2002 Ulrich von Zadow
00013 |
00014 \--------------------------------------------------------------------
00015 */
00016 
00017 #include "plstdpch.h"
00018 #include "plpicdec.h"
00019 #include "plfilesrc.h"
00020 #ifdef _WINDOWS
00021 #include "plressrc.h"
00022 #endif
00023 #include "plmemsrc.h"
00024 #include "plexcept.h"
00025 #include "planybmp.h"
00026 
00027 #include <stdio.h>
00028 
00029 // Set default Trace configuration here. The defined levels are
00030 // explained in picdec.h.
00031 int PLPicDecoder::m_TraceLevel = 0;
00032 char * PLPicDecoder::m_pszTraceFName = NULL;
00033 
00034 
00035 PLPicDecoder::PLPicDecoder
00036   () : PLObject(),
00037        m_pDataSrc (0)
00038     // Creates a decoder
00039 {
00040 }
00041 
00042 
00043 PLPicDecoder::~PLPicDecoder
00044     ()
00045 {
00046   if (m_pszTraceFName)
00047     delete [] m_pszTraceFName;
00048   m_pszTraceFName = NULL;
00049 }
00050 
00051 
00052 void PLPicDecoder::MakeBmpFromFile
00053     ( const char * pszFName,
00054       PLBmp * pBmp,
00055       int BPPWanted,
00056       PLIProgressNotification * pProgNot
00057     )
00058     // Decodes a picture in a file by creating a file data source and
00059     // calling MakeBmp with this data source.
00060 {
00061   try 
00062   {
00063     OpenFile (pszFName, pProgNot);
00064     MakeBmp (m_pDataSrc, pBmp, BPPWanted);
00065     Close();
00066   }
00067   catch (PLTextException)
00068   {
00069     // Clean up on error
00070     if (m_pDataSrc) delete m_pDataSrc;
00071     throw;
00072   }
00073 }
00074 
00075 #ifdef _WINDOWS
00076 void PLPicDecoder::MakeBmpFromResource
00077     ( HINSTANCE hInstResource, int ResourceID,
00078       PLBmp * pBmp,
00079       int BPPWanted,
00080             const char * ResType,
00081       HMODULE hResModule
00082     )
00083     // Decodes a picture in a resource by creating a resource data
00084     // source and calling MakeBmp with this data source.
00085 {
00086   PLResourceSource * pResSrc = NULL;
00087   int err;
00088 
00089   char sz[256];
00090   sprintf (sz, "--- Decoding resource ID %i. ---\n", ResourceID);
00091   Trace (1, sz);
00092 
00093   try
00094   {
00095     pResSrc = new PLResourceSource ();
00096     err = pResSrc->Open (hInstResource, ResourceID, ResType);
00097     if (err)
00098     {
00099       sprintf (sz, "Opening resource %i failed", ResourceID);
00100       raiseError (err, sz);
00101     }
00102 
00103     MakeBmp (pResSrc, pBmp, BPPWanted);
00104     pResSrc->Close ();
00105   }
00106   catch (PLTextException)
00107   {
00108     // Clean up on error
00109     if (pResSrc) delete pResSrc;
00110     throw;
00111   }
00112 
00113   // Clean up
00114   delete pResSrc;
00115 }
00116 #endif
00117 
00118 
00119 void PLPicDecoder::MakeBmpFromMemory
00120     ( unsigned char * ucMemSrc,
00121       int MemSrcSize,
00122       PLBmp * pBmp,
00123       int BPPWanted,
00124       PLIProgressNotification * pProgNot
00125     )
00126     // Decodes a picture from memory directly resembling the image file by
00127     // creating a memory data source and calling MakeBmp with this data source.
00128 {
00129   PLMemSource * pMemSrc = NULL;
00130   int err;
00131 
00132   char sz[256];
00133   sprintf (sz, "--- Decoding from memory at %p. ---\n", ucMemSrc);
00134   Trace (1, sz);
00135 
00136   try
00137   {
00138     pMemSrc = new PLMemSource ();
00139     err = pMemSrc->Open (ucMemSrc, MemSrcSize);
00140     if (err)
00141     {
00142       sprintf (sz, "Reading from memory at %p failed", ucMemSrc);
00143       raiseError (err, sz);
00144     }
00145 
00146     MakeBmp (pMemSrc, pBmp, BPPWanted);
00147     pMemSrc->Close ();
00148   }
00149   catch (PLTextException)
00150   {
00151     // Clean up on error
00152     if (pMemSrc) delete pMemSrc;
00153     throw;
00154   }
00155 
00156   // Clean up
00157   delete pMemSrc;
00158 }
00159 
00160 
00161 void PLPicDecoder::MakeBmp
00162     ( PLDataSource * pDataSrc,
00163       PLBmp * pBmp,
00164       int BPPWanted
00165     )
00166     // Decodes a picture by getting the encoded data from pDataSrc.
00167     // Stores the results in pBmp.
00168 {
00169   DoDecode (pBmp, pDataSrc);
00170   if (BPPWanted != 0) {
00171     if (BPPWanted > pBmp->GetBitsPerPixel()) {
00172       PLAnyBmp TempBmp;
00173       TempBmp.CreateCopy (*pBmp, BPPWanted);
00174       *pBmp = TempBmp;
00175     } else if (BPPWanted < pBmp->GetBitsPerPixel()) {
00176       throw (PLTextException (PL_ERRFORMAT_NOT_SUPPORTED, "Image bit depth doesn't match request."));
00177     }
00178   }
00179 }
00180 
00181 void PLPicDecoder::SetTraceConfig
00182     ( int Level,
00183       char * pszFName
00184     )
00185 {
00186   // Level has to be between 0 and 3.
00187   PLASSERT (Level < 4);
00188 
00189   m_TraceLevel = Level;
00190 
00191   if (m_pszTraceFName)
00192     delete [] m_pszTraceFName;
00193 
00194   if (pszFName)
00195   {
00196     m_pszTraceFName = new char[strlen (pszFName)+1];
00197     strcpy (m_pszTraceFName, pszFName);
00198 
00199     // Delete any old Trace file with the same name.
00200     remove (m_pszTraceFName);
00201   }
00202   else
00203     m_pszTraceFName = NULL;
00204 }
00205 
00206 void PLPicDecoder::OpenFile
00207     ( const char * pszFName, 
00208       PLIProgressNotification * pProgNot
00209     )
00210 {
00211   int err;
00212 
00213   char sz[1024];
00214   sprintf (sz, "--- Decoding file %s. ---\n", pszFName);
00215   Trace (1, sz);
00216 
00217   try
00218   {
00219     PLFileSource * pFileSrc = new PLFileSource (pProgNot);
00220     m_pDataSrc = pFileSrc;
00221     err = pFileSrc->Open (pszFName);
00222     if (err)
00223     {
00224       sprintf (sz, "Opening %s failed", pszFName);
00225       raiseError (err, sz);
00226     }
00227 
00228   }
00229   catch (PLTextException)
00230   {
00231     if (m_pDataSrc) 
00232       delete m_pDataSrc;
00233     m_pDataSrc = 0;
00234     throw;
00235   }
00236 }
00237 
00238 void PLPicDecoder::Close
00239     ()
00240 {
00241   m_pDataSrc->Close ();
00242   delete m_pDataSrc;
00243   m_pDataSrc = 0;
00244 }
00245 
00246 void PLPicDecoder::raiseError
00247     ( int Code,
00248       char * pszErr
00249     )
00250     // This function is needed by callbacks outside of any object,
00251     // so it's public and static. It should not be called from
00252     // outside of the library.
00253 {
00254   char sz[256];
00255   sprintf (sz, "Decoder error: %s\n", pszErr);
00256   Trace (0, sz);
00257   throw (PLTextException (Code, sz));
00258 }
00259 
00260 void PLPicDecoder::Trace
00261     ( int TraceLevel,
00262       const char * pszMessage
00263     )
00264     // Outputs debugging data to a file or to the MSVC debug console.
00265 {
00266   if (TraceLevel <= m_TraceLevel)
00267   {
00268     if (m_pszTraceFName)
00269     {
00270       // The file is closed after every call so no data is lost
00271       // if the program crashes.
00272       FILE * pFile = fopen (m_pszTraceFName, "a+t");
00273       if (pFile != (FILE *)0)
00274       {
00275         fprintf (pFile, pszMessage);
00276         fclose (pFile);
00277       }
00278       else
00279       { // No permission? File locked? Filename nonsense?
00280         PLTRACE ("Error opening Trace file!\n");
00281       }
00282     }
00283     else
00284       PLTRACE (pszMessage);
00285   }
00286 }
00287 
00288 void PLPicDecoder::DoDecode
00289     ( PLBmp * pBmp,
00290       PLDataSource * pDataSrc
00291     )
00292     // Implements the actual decoding process. Uses variables local to
00293     // the object to retrieve and store the data. Implemented in
00294     // derived classes.
00295 {
00296   // This routine should never be called. It's here so derived classes
00297   // can override MakeDIB directly if they want to. (CAnyDecoder does
00298   // this).
00299   PLASSERT (false);
00300 }
00301 
00302 PLBYTE * PLPicDecoder::unpackPictRow
00303     ( PLBYTE * pLineBuf,
00304       PLDataSource * pDataSrc,
00305       int Width,
00306       int rowBytes,
00307       int SrcBytes
00308     )
00309 {
00310   PLBYTE * pRawLine = pLineBuf;
00311 
00312   if (rowBytes < 8)
00313   { // Ah-ha!  The bits aren't actually packed.  This will be easy.
00314     pRawLine = pDataSrc->ReadNBytes (rowBytes);
00315   }
00316   else
00317   {
00318     PLBYTE * pSrcLine = pDataSrc->ReadNBytes(SrcBytes);
00319     PLBYTE * pCurPixel = pRawLine;
00320 
00321     // Unpack RLE. The data is packed bytewise.
00322     for (int j = 0; j < SrcBytes; )
00323     {
00324       PLBYTE FlagCounter = pSrcLine[j];
00325       if (FlagCounter & 0x80)
00326       {
00327         if (FlagCounter == 0x80)
00328           // Special case: repeat value of 0.
00329           // Apple sais ignore.
00330           j++;
00331         else
00332         { // Packed data.
00333           int len = ((FlagCounter ^ 255) & 255) + 2;
00334 
00335           memset (pCurPixel, *(pSrcLine+j+1), len);
00336           pCurPixel += len;
00337           j += 2;
00338         }
00339       }
00340       else
00341       { // Unpacked data
00342         int len = (FlagCounter & 255) + 1;
00343         memcpy (pCurPixel, pSrcLine+j+1, len);
00344         pCurPixel += len;
00345         j += len + 1;
00346       }
00347     }
00348   }
00349   return pRawLine;
00350 }
00351 
00352 
00353 /*
00354 /--------------------------------------------------------------------
00355 |
00356 |      $Log: plpicdec.cpp,v $
00357 |      Revision 1.1  2004/05/21 21:02:53  maxx
00358 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00359 |
00360 |      Revision 1.1  2002/11/13 01:58:21  mspindle
00361 |      *** empty log message ***
00362 |
00363 |      Revision 1.5  2002/03/03 16:29:55  uzadow
00364 |      Re-added BPPWanted.
00365 |
00366 |      Revision 1.4  2001/10/21 17:12:40  uzadow
00367 |      Added PSD decoder beta, removed BPPWanted from all decoders, added PLFilterPixel.
00368 |
00369 |      Revision 1.3  2001/10/16 17:12:26  uzadow
00370 |      Added support for resolution information (Luca Piergentili)
00371 |
00372 |      Revision 1.2  2001/10/06 22:37:08  uzadow
00373 |      Linux compatibility.
00374 |
00375 |      Revision 1.1  2001/09/16 19:03:22  uzadow
00376 |      Added global name prefix PL, changed most filenames.
00377 |
00378 |      Revision 1.13  2001/09/15 21:02:44  uzadow
00379 |      Cleaned up stdpch.h and config.h to make them internal headers.
00380 |
00381 |      Revision 1.12  2001/02/04 14:31:52  uzadow
00382 |      Member initialization list cleanup (Erik Hoffmann).
00383 |
00384 |      Revision 1.11  2001/02/04 14:07:24  uzadow
00385 |      Changed max. filename length.
00386 |
00387 |      Revision 1.10  2001/01/21 14:28:21  uzadow
00388 |      Changed array cleanup from delete to delete[].
00389 |
00390 |      Revision 1.9  2000/12/18 22:42:52  uzadow
00391 |      Replaced RGBAPIXEL with PLPixel32.
00392 |
00393 |      Revision 1.8  2000/03/30 21:24:15  Ulrich von Zadow
00394 |      Added MakeBmpFromMemory() function by Markus Ewald
00395 |
00396 |      Revision 1.7  2000/01/16 20:43:14  anonymous
00397 |      Removed MFC dependencies
00398 |
00399 |      Revision 1.6  2000/01/11 21:40:30  Ulrich von Zadow
00400 |      Added instance handle parameter to LoadFromResource()
00401 |
00402 |      Revision 1.5  2000/01/08 15:51:30  Ulrich von Zadow
00403 |      Misc. modifications to png encoder.
00404 |
00405 |      Revision 1.4  1999/11/08 22:12:51  Ulrich von Zadow
00406 |      Andreas Koepf: Added resource type as parameter to
00407 |      MakeBmpFromResource
00408 |
00409 |      Revision 1.3  1999/10/03 18:50:51  Ulrich von Zadow
00410 |      Added automatic logging of changes.
00411 |
00412 |
00413 \--------------------------------------------------------------------
00414 */

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