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

planydec.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: planydec.cpp,v 1.1 2004/05/21 21:02:52 maxx Exp $
00005 |      Picture Decoder Class
00006 |
00007 |      Class which decodes pictures with any known format. It auto-
00008 |      detects the format to use and delegates the work to one of the
00009 |      other decoder classes.
00010 |
00011 |      Copyright (c) 1996-2002 Ulrich von Zadow
00012 |
00013 \--------------------------------------------------------------------
00014 */
00015 
00016 #include "plstdpch.h"
00017 #include "planydec.h"
00018 
00019 #include "config.h" // Buenaposada, for PL_MSB_FIRST & PL_LSB_FIRST
00020 #include "plbitmap.h"
00021 #include "plexcept.h"
00022 
00023 // needed for BMP recognition even when this format is not decoded
00024 #include "plwindefs.h"
00025 
00026 #ifdef PL_SUPPORT_BMP
00027 #include "plbmpdec.h"
00028 #endif
00029 
00030 #ifdef PL_SUPPORT_PICT
00031 #include "plpictdec.h"
00032 #endif
00033 
00034 #ifdef PL_SUPPORT_TGA
00035 #include "pltgadec.h"
00036 #endif
00037 
00038 #ifdef PL_SUPPORT_TIFF
00039 #include "pltiffdec.h"
00040 #endif
00041 
00042 #ifdef PL_SUPPORT_JPEG
00043 #include "pljpegdec.h"
00044 #endif
00045 
00046 #ifdef PL_SUPPORT_PNG
00047 #include "plpngdec.h"
00048 #endif
00049 
00050 #ifdef PL_SUPPORT_WEMF
00051 #include "plwemfdec.h"
00052 #endif
00053 
00054 #ifdef PL_SUPPORT_PCX
00055 #include "plpcxdec.h"
00056 #endif
00057 
00058 #ifdef PL_SUPPORT_PGM
00059 #include "plpgmdec.h"
00060 #endif
00061 
00062 #ifdef PL_SUPPORT_GIF
00063 #include "plgifdec.h"
00064 #endif
00065 
00066 #ifdef PL_SUPPORT_PPM
00067 #include "plppmdec.h"
00068 #endif
00069 
00070 #ifdef PL_SUPPORT_PSD
00071 #include "plpsddec.h"
00072 #endif
00073 
00074 PLAnyPicDecoder::PLAnyPicDecoder () 
00075   : PLPicDecoder(),
00076     m_Type(PL_FT_UNKNOWN)
00077 // Creates a decoder
00078 {
00079   // Create sub-decoders...
00080 #ifdef PL_SUPPORT_BMP
00081   m_pBmpDec = new PLBmpDecoder ();
00082 #endif
00083 #ifdef PL_SUPPORT_TGA
00084   m_pTGADec = new PLTGADecoder ();
00085 #endif
00086 #ifdef PL_SUPPORT_TIFF
00087   m_pTIFFDec = new PLTIFFDecoder ();
00088 #endif
00089 #ifdef PL_SUPPORT_JPEG
00090   m_pJPEGDec = new PLJPEGDecoder ();
00091 #endif
00092 #ifdef PL_SUPPORT_PICT
00093 #ifdef PL_SUPPORT_JPEG
00094   m_pPictDec = new PLPictDecoder (m_pJPEGDec);
00095 #else
00096   m_pPictDec = new PLPictDecoder (NULL);
00097 #endif
00098 #endif
00099 #ifdef PL_SUPPORT_PNG
00100   m_pPNGDec = new PLPNGDecoder ();
00101 #endif
00102 #ifdef PL_SUPPORT_WEMF
00103   m_pWEMFDec = new PLWEMFDecoder();
00104 #endif
00105 #ifdef PL_SUPPORT_PCX
00106   m_pPCXDec = new PLPCXDecoder();
00107 #endif
00108 #ifdef PL_SUPPORT_PGM
00109   m_pPGMDec = new PLPGMDecoder();
00110 #endif
00111 #ifdef PL_SUPPORT_GIF
00112   m_pGIFDec = new PLGIFDecoder();
00113 #endif
00114 #ifdef PL_SUPPORT_PPM
00115   m_pPPMDec = new PLPPMDecoder();
00116 #endif
00117 #ifdef PL_SUPPORT_PSD
00118   m_pPSDDec = new PLPSDDecoder();
00119 #endif
00120 }
00121 
00122 
00123 PLAnyPicDecoder::~PLAnyPicDecoder ()
00124 {
00125 #ifdef PL_SUPPORT_BMP
00126   delete m_pBmpDec;
00127 #endif
00128 #ifdef PL_SUPPORT_PICT
00129   delete m_pPictDec;
00130 #endif
00131 #ifdef PL_SUPPORT_TGA
00132   delete m_pTGADec;
00133 #endif
00134 #ifdef PL_SUPPORT_TIFF
00135   delete m_pTIFFDec;
00136 #endif
00137 #ifdef PL_SUPPORT_JPEG
00138   delete m_pJPEGDec;
00139 #endif
00140 #ifdef PL_SUPPORT_PNG
00141   delete m_pPNGDec;
00142 #endif
00143 #ifdef PL_SUPPORT_WEMF
00144   delete m_pWEMFDec;
00145 #endif
00146 #ifdef PL_SUPPORT_PCX
00147   delete m_pPCXDec;
00148 #endif
00149 #ifdef PL_SUPPORT_PGM
00150   delete m_pPGMDec;
00151 #endif
00152 #ifdef PL_SUPPORT_GIF
00153   delete m_pGIFDec;
00154 #endif
00155 #ifdef PL_SUPPORT_PPM
00156   delete m_pPPMDec;
00157 #endif
00158 #ifdef PL_SUPPORT_PSD
00159   delete m_pPSDDec;
00160 #endif
00161 }
00162 
00163 
00164 void PLAnyPicDecoder::MakeBmp (PLDataSource * pDataSrc, PLBmp * pBmp, int BPPWanted)
00165 {
00166   m_Type = PL_FT_UNKNOWN;
00167 #ifdef PL_SUPPORT_WEMF
00168   // If we have support for WMF and EMF, we check only the
00169   // file extension and let Windows do the rest
00170   char* strname = strupr(strdup(pDataSrc->GetName()));
00171   if (strname == NULL)
00172   {
00173     raiseError (PL_ERRNO_MEMORY,"Out of memory during strdup.");
00174   }
00175   strupr(strname);
00176   if (strstr(strname,".WMF") != NULL)
00177   {
00178     m_Type = PL_FT_WMF;
00179   }
00180   else if (strstr(strname,".EMF") != NULL)
00181   {
00182     m_Type = PL_FT_EMF;
00183   }
00184   ::free(strname);
00185 #endif
00186 
00187   if (m_Type == PL_FT_UNKNOWN)
00188   {
00189     m_Type = getFileType (pDataSrc->GetBufferPtr (512),
00190                           pDataSrc->GetFileSize());
00191   }
00192 
00193   switch (m_Type)
00194   {
00195     case PL_FT_UNKNOWN:
00196       raiseError (PL_ERRUNKNOWN_FILE_TYPE, "Unknown file type.");
00197 #ifdef PL_SUPPORT_BMP
00198     case PL_FT_WINBMP:
00199       Trace (2, "Windows bitmap recognized.\n");
00200       m_pBmpDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00201       break;
00202 #endif
00203 #ifdef PL_SUPPORT_PICT
00204     case PL_FT_MACPICT:
00205       Trace (2, "Mac PICT recognized.\n");
00206       m_pPictDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00207       break;
00208 #endif
00209 #ifdef PL_SUPPORT_TGA
00210     case PL_FT_TARGA:
00211       Trace (2, "TGA file recognized.\n");
00212       m_pTGADec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00213       break;
00214 #endif
00215 #ifdef PL_SUPPORT_TIFF
00216     case PL_FT_EPSTIFF:
00217       Trace (2, "TIFF preview in EPS file recognized.\n");
00218       // skip eps information
00219       pDataSrc->ReadNBytes (epsLongVal(20+pDataSrc->GetBufferPtr(30)));
00220       m_pTIFFDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00221       break;
00222     case PL_FT_TIFF:
00223       Trace (2, "TIFF file recognized.\n");
00224       m_pTIFFDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00225       break;
00226 #endif
00227 #ifdef PL_SUPPORT_JPEG
00228     case PL_FT_JPEG:
00229       Trace (2, "JPEG file recognized.\n");
00230       m_pJPEGDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00231       break;
00232 #endif
00233 #ifdef PL_SUPPORT_PNG
00234     case PL_FT_PNG:
00235       Trace (2, "PNG file recognized.\n");
00236       m_pPNGDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00237       break;
00238 #endif
00239 #ifdef PL_SUPPORT_WEMF
00240     case PL_FT_WMF:
00241       Trace (2, "WMF file recognized.\n");
00242       m_pWEMFDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00243       break;
00244     case PL_FT_EMF:
00245       Trace (2, "EMF file recognized.\n");
00246       m_pWEMFDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00247       break;
00248 #endif
00249 #ifdef PL_SUPPORT_PCX
00250     case PL_FT_PCX:
00251       Trace (2, "PCX file recognized.\n");
00252       m_pPCXDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00253       break;
00254 #endif
00255 #ifdef PL_SUPPORT_GIF
00256     case PL_FT_GIF:
00257       Trace (2, "GIF file recognized.\n");
00258       m_pGIFDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00259       break;
00260 #endif
00261 #ifdef PL_SUPPORT_PGM
00262     case PL_FT_PGM:
00263       Trace (2, "PGM file recognized.\n");
00264       m_pPGMDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00265       break;
00266 #endif
00267 #ifdef PL_SUPPORT_PPM
00268     case PL_FT_PPM:
00269       Trace (2, "PPM file recognized.\n");
00270       m_pPPMDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00271       break;
00272 #endif
00273 #ifdef PL_SUPPORT_PSD
00274     case PL_FT_PSD:
00275       Trace (2, "PSD file recognized.\n");
00276       m_pPSDDec->MakeBmp (pDataSrc, pBmp, BPPWanted);
00277       break;
00278 #endif
00279     default:
00280       raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00281                   "Library not compiled for this file type.");
00282       break;
00283   }
00284 }
00285 
00286 int PLAnyPicDecoder::GetFileFormat ()
00287 {
00288   return m_Type;
00289 }
00290 
00292 // Local functions
00293 
00294 int PLAnyPicDecoder::getFileType (PLBYTE * pData, int DataLen)
00295 // Check for file-format-specific data & return the file type if
00296 // something fits.
00297 {
00298   // Check for bitmap file signature: First 2 bytes are 'BM'.
00299   WINBITMAPFILEHEADER * pBFH;
00300   pBFH = (WINBITMAPFILEHEADER *) pData;
00301 #ifdef PL_LSB_FIRST 
00302   if ((pBFH->bfType == 0x4142) || (pBFH->bfType == 0x4d42) || 
00303       (pBFH->bfType == 0x4349) || (pBFH->bfType == 0x5043) || 
00304       (pBFH->bfType == 0x4943) || (pBFH->bfType == 0x5043))
00305 #else // PL_MSB_FIRST, For Motorola et Al.
00306   if ((pBFH->bfType == 0x4241) || (pBFH->bfType == 0x424d) ||
00307       (pBFH->bfType == 0x4943) || (pBFH->bfType == 0x4350) || 
00308       (pBFH->bfType == 0x4349) || (pBFH->bfType == 0x4350))
00309 #endif
00310     return PL_FT_WINBMP;
00311 
00312   // Check for TGA file. The TGA format doesn't have a signature,
00313   // so the program checks for a meaningful TGA header.
00314   bool bCouldBeTGA = true;
00315   if (*(pData+1) > 1)
00316     bCouldBeTGA = false;
00317   PLBYTE TGAImgType = *(pData+2);
00318   if ((TGAImgType > 11) || (TGAImgType > 3 && TGAImgType < 9))
00319     bCouldBeTGA = false;
00320   PLBYTE TGAColMapDepth = *(pData+7);
00321   if (TGAColMapDepth != 8 && TGAColMapDepth != 15 &&
00322       TGAColMapDepth != 16 && TGAColMapDepth != 24 &&
00323       TGAColMapDepth != 32 && TGAColMapDepth != 0)
00324     bCouldBeTGA = false;
00325   PLBYTE TGAPixDepth = *(pData+16);
00326   if (TGAPixDepth != 8 && TGAPixDepth != 15 &&
00327       TGAPixDepth != 16 && TGAPixDepth != 24 &&
00328       TGAPixDepth != 32)
00329     bCouldBeTGA = false;
00330   if (bCouldBeTGA)
00331     return PL_FT_TARGA;
00332 
00333   // Check for GIF
00334   PLULONG GIFSig = *((PLULONG *)pData);
00335   if (GIFSig == 0x38464947)
00336     return PL_FT_GIF;
00337 
00338   // Check for TIFF
00339   PLULONG TIFFSig = *((PLULONG *)pData);
00340   if (TIFFSig == 0x002A4949 || TIFFSig == 0x2A004D4D)
00341     return PL_FT_TIFF;
00342 
00343   // Check for Mac PICT signature and Version.
00344   if (DataLen > 540)
00345   {
00346     PLBYTE * pPictSig = (PLBYTE *)(pData+0x20a);
00347     if ((pPictSig[0] == 0x00 && pPictSig[1] == 0x11 &&
00348          pPictSig[2] == 0x02 && pPictSig[3] == 0xFF) ||
00349         (pPictSig[0] == 0x00 && pPictSig[1] == 0x11 &&
00350          pPictSig[2] == 0x01) ||
00351         (pPictSig[0] == 0x11 && pPictSig[1] == 0x01 &&
00352          pPictSig[2] == 0x01 && pPictSig[3] == 0x00))
00353       return PL_FT_MACPICT;
00354   }
00355 
00356   // Check for JPEG/JFIF.
00357   if ((*pData == 0xFF) && (*(pData+1) == 0xD8) &&
00358       (*(pData+2) == 0xFF))
00359     return PL_FT_JPEG;
00360 
00361   // Check for PNG.
00362   if ((*pData == 0x89) && (*(pData+1) == 0x50) &&
00363       (*(pData+2) == 0x4E) && (*(pData+3) == 0x47))
00364     return PL_FT_PNG;
00365 
00366   // Check for TIFF wrapped in EPS
00367   PLULONG EPSSig = *((PLULONG *)pData);
00368   if ((EPSSig == 0xc6d3d0c5 || EPSSig == 0xc5d0d3c6) &&
00369       *(PLULONG *)(pData+20) && *(PLULONG *)(pData+24))
00370     return PL_FT_EPSTIFF;
00371 
00372   // Check for PCX
00373   // This check isn't really safe... should find other criteria.
00374   if (pData[0] == 0x0A && pData[2] == 0x01)
00375     return PL_FT_PCX;
00376 
00377   // Check for PGM
00378   if (pData[0] == 0x50 && ((pData[1] == 0x32)||(pData[1] == 0x35)))
00379     return PL_FT_PGM;
00380 
00381   // Check for PPM
00382   if (pData[0] == 0x50 && ((pData[1] == 0x33)||(pData[1] == 0x36)))
00383     return PL_FT_PPM;
00384 
00385   // Check for PSD
00386   if (!strncmp ((char *)pData, "8BPS", 4))
00387     return PL_FT_PSD;
00388 
00389   return PL_FT_UNKNOWN;
00390 }
00391 
00392 
00393 long PLAnyPicDecoder::epsLongVal (unsigned char *p)
00394 {
00395   unsigned long retval = 0;
00396   int i;
00397   // this may look like an endian dependency but its not - EPS headers
00398   // are always this way round
00399   for (i = 0; i < 4; i++)
00400     retval = ((retval >> 8) & 0xffffffL) + (((long)*p++) << 24);
00401   return (long) retval;
00402 }
00403 
00404 /*
00405 /--------------------------------------------------------------------
00406 |
00407 |      $Log: planydec.cpp,v $
00408 |      Revision 1.1  2004/05/21 21:02:52  maxx
00409 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00410 |
00411 |      Revision 1.1  2002/11/13 01:58:20  mspindle
00412 |      *** empty log message ***
00413 |
00414 |      Revision 1.6  2002/03/06 22:46:54  uzadow
00415 |      Fixed major PLAnyDec bug
00416 |
00417 |      Revision 1.5  2001/10/21 17:12:39  uzadow
00418 |      Added PSD decoder beta, removed BPPWanted from all decoders, added PLFilterPixel.
00419 |
00420 |      Revision 1.4  2001/10/16 17:51:32  uzadow
00421 |      Added ppm support (Todd Harris)
00422 |
00423 |      Revision 1.3  2001/10/06 22:03:26  uzadow
00424 |      Added PL prefix to basic data types.
00425 |
00426 |      Revision 1.2  2001/10/05 21:15:09  uzadow
00427 |      Improved support for OS/2 bitmap decoding.
00428 |
00429 |      Revision 1.1  2001/09/16 19:03:22  uzadow
00430 |      Added global name prefix PL, changed most filenames.
00431 |
00432 |      Revision 1.15  2001/02/04 14:31:52  uzadow
00433 |      Member initialization list cleanup (Erik Hoffmann).
00434 |
00435 |      Revision 1.14  2001/01/15 12:09:02  uzadow
00436 |      Fixed autodetection bug introduced yesterday.
00437 |
00438 |      Revision 1.13  2001/01/14 13:36:15  uzadow
00439 |      Added PLAnyPicDecoder::GetFileFormat()
00440 |
00441 |      Revision 1.12  2000/12/08 12:32:00  uzadow
00442 |      Added gif decoder by Michael Salzlechner.
00443 |
00444 |      Revision 1.11  2000/07/11 17:11:00  Ulrich von Zadow
00445 |      Added support for RGBA pixel ordering (Jose Miguel Buenaposada Biencinto).
00446 |
00447 |      Revision 1.10  2000/03/31 11:53:29  Ulrich von Zadow
00448 |      Added quantization support.
00449 |
00450 |      Revision 1.9  2000/03/16 13:56:37  Ulrich von Zadow
00451 |      Added pgm decoder by Jose Miguel Buenaposada Biencinto
00452 |
00453 |      Revision 1.8  2000/01/16 20:43:12  anonymous
00454 |      Removed MFC dependencies
00455 |
00456 |      Revision 1.7  2000/01/10 23:52:59  Ulrich von Zadow
00457 |      Changed formatting & removed tabs.
00458 |
00459 |      Revision 1.6  1999/12/08 15:39:45  Ulrich von Zadow
00460 |      Unix compatibility changes
00461 |
00462 |      Revision 1.5  1999/10/21 17:43:08  Ulrich von Zadow
00463 |      Added pcx support by Meng Bo.
00464 |
00465 |      Revision 1.4  1999/10/03 18:50:51  Ulrich von Zadow
00466 |      Added automatic logging of changes.
00467 |
00468 |
00469 --------------------------------------------------------------------
00470 */

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