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

plbmpdec.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: plbmpdec.cpp,v 1.1 2004/05/21 21:02:52 maxx Exp $
00005 |      Windows Bitmap Decoder Class
00006 |
00007 |      Windows bitmap file decoder. Decodes 1, 4, 8, 24 and 32 bpp
00008 |      bitmap files (compressed and uncompressed) and returns a 32
00009 |      bpp DIB.
00010 |
00011 |      Copyright (c) 1996-1998 Ulrich von Zadow
00012 |
00013 \--------------------------------------------------------------------
00014 */
00015 
00016 #include "plstdpch.h"
00017 #include "plbmpdec.h"
00018 #include "plexcept.h"
00019 
00020 PLBmpDecoder::PLBmpDecoder
00021 () : PLPicDecoder()
00022     // Creates a decoder
00023 {
00024 }
00025 
00026 
00027 PLBmpDecoder::~PLBmpDecoder
00028     ()
00029 {
00030 }
00031 
00032 
00033 void PLBmpDecoder::DoDecode
00034     ( PLBmp * pBmp,
00035       PLDataSource * pDataSrc
00036     )
00037 {
00038   WINBITMAPINFOHEADER * pBMI = NULL;  // Pointer to bitmapinfoheader of the file.
00039 
00040   try
00041   {
00042     PLPixel32 Pal[256];
00043     pBMI = getInfoHeader (pDataSrc, &Pal[0]);
00044 
00045     int DestBPP = pBMI->biBitCount;
00046     bool bAlpha = false;
00047     if (DestBPP == 32)
00048       bAlpha = true;
00049     if (DestBPP > 8)
00050       DestBPP = 32;
00051     if (DestBPP < 8)
00052       DestBPP = 8;
00053         
00054     pBmp->Create (pBMI->biWidth, pBMI->biHeight, DestBPP, bAlpha);
00055     if (DestBPP == 8)
00056       pBmp->SetPalette (&Pal[0]);
00057     
00058     pBmp->Lock(false, true);
00059 
00060     try
00061     {
00062       switch (pBMI->biBitCount)
00063       {
00064         case 1:
00065           decode1bpp (pDataSrc, pBmp);
00066           break;
00067         case 4:
00068           if (pBMI->biCompression == BI_RGB)
00069             decode4bpp (pDataSrc, pBmp);
00070            else
00071             decodeRLE4 (pDataSrc, pBmp);
00072           break;
00073         case 8:
00074           if (pBMI->biCompression == BI_RGB)
00075             decode8bpp (pDataSrc, pBmp);
00076            else
00077             decodeRLE8 (pDataSrc, pBmp);
00078           break;
00079         case 16:
00080           decodeHiColor (pDataSrc, pBmp, pBMI);
00081           break;
00082         case 24:
00083         case 32:
00084           decodeTrueColor (pDataSrc, pBmp, pBMI->biBitCount);
00085           break;
00086         default:
00087           // This is not a standard bmp file.
00088           raiseError (PL_ERRFORMAT_UNKNOWN,
00089                       "Decoding bmp: Illegal bpp value.");
00090       }
00091             PLPoint DPI(0,0);
00092 
00093             if (pBMI->biXPelsPerMeter > 0)
00094                     DPI.x = (int)((float)pBMI->biXPelsPerMeter / 39.37f+0.5);
00095             if (DPI.x <= 1)
00096                     DPI.x = 150;
00097 
00098             if (pBMI->biYPelsPerMeter > 0)
00099                     DPI.y = (int)((float)pBMI->biYPelsPerMeter / 39.37f+0.5);
00100             if (DPI.y <= 1)
00101                     DPI.y = 150;
00102             pBmp->SetResolution(DPI);
00103 
00104       pBmp->Unlock();
00105 
00106       delete pBMI;
00107       pBMI = NULL;
00108       Trace (3, "Decoding finished.\n");
00109     }
00110     catch (...)
00111     {
00112       pBmp->Unlock();
00113       throw;
00114     }
00115   }
00116   catch (PLTextException)
00117   {
00118     if (pBMI)
00119       delete pBMI;
00120     throw;
00121   }
00122   catch(...)
00123   {
00124     delete pBMI;
00125     throw;
00126   }
00127 }
00128 
00129 WINBITMAPINFOHEADER * PLBmpDecoder::getInfoHeader
00130     ( PLDataSource * pDataSrc,
00131       PLPixel32* pPal
00132     )
00133     // Decodes the bitmap file & info headers
00134 {
00135   WINBITMAPFILEHEADER BFH;
00136   WINBITMAPINFOHEADER * pBMI;
00137   int offset = 0;
00138 
00139   BFH.bfType = ReadIWord (pDataSrc);
00140 
00141   while (BFH.bfType == 0x4142)
00142   {
00143     BFH.bfSize = ReadILong (pDataSrc);
00144     BFH.bfReserved1 = ReadIWord (pDataSrc);
00145     BFH.bfReserved2 = ReadIWord (pDataSrc);
00146     BFH.bfOffBits = ReadILong (pDataSrc);
00147     BFH.bfType = ReadIWord (pDataSrc);
00148     offset += 14;
00149   }
00150 
00151   BFH.bfSize = ReadILong (pDataSrc);
00152   BFH.bfReserved1 = ReadIWord (pDataSrc);
00153   BFH.bfReserved2 = ReadIWord (pDataSrc);
00154   BFH.bfOffBits = ReadILong (pDataSrc);
00155 
00156   // Check for bitmap file signature: First 2 bytes are 'BA', 'BM',
00157   // 'IC', 'PI', 'CI' or 'CP'
00158   if (!((BFH.bfType == 0x4142) || (BFH.bfType == 0x4d42) ||
00159         (BFH.bfType == 0x4349) || (BFH.bfType == 0x5043) ||
00160         (BFH.bfType == 0x4943) || (BFH.bfType == 0x5043)))
00161     raiseError (PL_ERRWRONG_SIGNATURE,
00162                 "Bitmap decoder: This isn't a bitmap.");
00163 
00164   Trace (2, "Bitmap file signature found\n");
00165 
00166   pBMI = new WINBITMAPINFOHEADER;
00167 
00168   try
00169   {
00170     int Colors = 0;
00171 
00172     pBMI->biSize = ReadILong (pDataSrc);
00173 
00174     if (pBMI->biSize == 12)
00175     {
00176       // read as BITMAPCOREHEADER struct (OS2 1.x Format)
00177       pBMI->biWidth    = ReadIWord(pDataSrc);
00178       pBMI->biHeight   = ReadIWord(pDataSrc);
00179       pBMI->biPlanes   = ReadIWord(pDataSrc);
00180       pBMI->biBitCount = ReadIWord(pDataSrc);
00181 
00182       pBMI->biCompression = 0;
00183       pBMI->biSizeImage = 0;
00184       pBMI->biXPelsPerMeter = 0;
00185       pBMI->biYPelsPerMeter = 0;
00186       pBMI->biClrUsed = 0;
00187       pBMI->biClrImportant = 0;
00188 
00189       // Read palette if 8 bpp or less.
00190       if (pBMI->biBitCount <= 8)
00191       {
00192         Colors = readPalette (pBMI, pDataSrc, pPal, 3);
00193         pDataSrc->Skip(BFH.bfOffBits - 26 - 3 * Colors - offset);
00194       }
00195     }
00196     else if (pBMI->biSize == 40)
00197     {
00198       // read as BITMAPINFOHEADER struct
00199       pBMI->biWidth = ReadILong (pDataSrc);
00200       pBMI->biHeight = ReadILong (pDataSrc);
00201       pBMI->biPlanes = ReadIWord (pDataSrc);
00202       pBMI->biBitCount = ReadIWord (pDataSrc);
00203       pBMI->biCompression = ReadILong (pDataSrc);
00204       pBMI->biSizeImage = ReadILong (pDataSrc);
00205       pBMI->biXPelsPerMeter = ReadILong (pDataSrc);
00206       pBMI->biYPelsPerMeter = ReadILong (pDataSrc);
00207       pBMI->biClrUsed = ReadILong (pDataSrc);
00208       pBMI->biClrImportant = ReadILong (pDataSrc);
00209 
00210       // Read palette if 8 bpp or less.
00211       if (pBMI->biBitCount <= 8)
00212         Colors = readPalette (pBMI, pDataSrc, pPal, 4);
00213     }
00214     else
00215     {
00216       // read as BITMAPINFOHEADER struct (OS2 2.x Format)
00217       pBMI->biWidth = ReadILong (pDataSrc);
00218       pBMI->biHeight = ReadILong (pDataSrc);
00219       pBMI->biPlanes = ReadIWord (pDataSrc);
00220       pBMI->biBitCount = ReadIWord (pDataSrc);
00221       pBMI->biCompression = ReadILong (pDataSrc);
00222       pBMI->biSizeImage = ReadILong (pDataSrc);
00223       pBMI->biXPelsPerMeter = ReadILong (pDataSrc);
00224       pBMI->biYPelsPerMeter = ReadILong (pDataSrc);
00225       pBMI->biClrUsed = ReadILong (pDataSrc);
00226       pBMI->biClrImportant = ReadILong (pDataSrc);
00227       pDataSrc->Skip(pBMI->biSize - sizeof (WINBITMAPINFOHEADER));
00228 
00229       // Read palette if 8 bpp or less.
00230       if (pBMI->biBitCount <= 8)
00231         Colors = readPalette (pBMI, pDataSrc, pPal, 3);
00232     }
00233 
00234     Trace (2, "Bitmap header is ok.\n");
00235 
00236   }
00237   catch (PLTextException)
00238   {
00239     if (pBMI)
00240       delete pBMI;
00241     throw;
00242   }
00243   catch(...)
00244   {
00245     delete pBMI;
00246     throw;
00247   }
00248   return pBMI;
00249 }
00250 
00251 void PLBmpDecoder::decode1bpp
00252     ( PLDataSource * pDataSrc,
00253       PLBmp * pBmp
00254     )
00255     // Decodes a 2-color bitmap. Ignores the palette & just uses
00256     // black & white as 'colors' if decoding to 32 bit
00257 {
00258   int i;
00259   int y;                           // Current row
00260   int x;                           // Current column
00261 
00262   PLBYTE * pDest;                    // Current destination.
00263   PLBYTE * pSrc;                     // Current position in file.
00264   PLBYTE   BTable[8];                // Table of bit masks.
00265   PLBYTE   SrcByte;                  // Source byte cache.
00266   int    XSize = pBmp->GetWidth(); // Width of bitmap in pixels.
00267   int    LineLen = ((XSize+7)/8 + 3) & ~3;
00268                                    // Width of source in bytes
00269                                    //   (DWORD-aligned).
00270   int    LinePadding = LineLen-((XSize+7)/8);
00271   PLBYTE ** pLineArray = pBmp->GetLineArray();
00272                                    // Pointers to dest. lines.
00273 
00274   int    OpaqueBlack = 0x00000000;
00275   *(((PLBYTE*)&OpaqueBlack)+PL_RGBA_ALPHA) = 0xFF;
00276 
00277   Trace (2, "Decoding 1 bit per pixel bitmap.\n");
00278 
00279   // Initialize bit masks.
00280   for (i=0; i<8; i++)
00281   {
00282     BTable[i] = 1<<i;
00283   }
00284 
00285   for (y=0; y<pBmp->GetHeight(); y++)
00286   { // For each line...
00287     pDest = pLineArray[pBmp->GetHeight()-y-1];
00288     for (x=0; x<XSize/8; x++)
00289     { // For each source byte...
00290       pSrc = pDataSrc->Read1Byte();
00291       SrcByte = *(pSrc);
00292       for (i=7; i>=0; i--)
00293       { // For each bit...
00294         if (SrcByte & BTable[i]) // Test if bit i is set
00295           *pDest = 0x01;
00296          else
00297           *pDest = 0x00;
00298         pDest++;
00299       }
00300     }
00301 
00302     // Last few bits in line...
00303     if (XSize & 7)
00304     {
00305       pSrc = pDataSrc->Read1Byte();
00306       SrcByte = *(pSrc);
00307       for (i=7; i>7-(XSize & 7); i--)
00308       { // For each bit...
00309         if (SrcByte & BTable[i]) // Test if bit i is set
00310           *pDest = 0x01;
00311          else
00312           *pDest = 0x00;
00313         pDest++;
00314       }
00315     }
00316     pDataSrc->Skip (LinePadding);
00317   }
00318 }
00319 
00320 
00321 void PLBmpDecoder::decode4bpp
00322     ( PLDataSource * pDataSrc,
00323       PLBmp * pBmp
00324     )
00325     // Decodes an uncompressed 16-color-bitmap.
00326 {
00327   int y;                            // Current row
00328   int x;                            // Current column
00329 
00330   PLBYTE * pDest;                     // Current destination.
00331   PLBYTE * pSrc;                      // Current position in file.
00332   PLBYTE   SrcByte;                   // Source byte cache.
00333   int    XSize = pBmp->GetWidth();  // Width of bitmap in pixels.
00334   int    LineLen = ((XSize+1)/2 + 3) & ~3;
00335                                     // Width of source in bytes
00336                                     //   (DWORD-aligned).
00337   int    LinePadding = LineLen-((XSize+1)/2);
00338   PLBYTE ** pLineArray = pBmp->GetLineArray();
00339                                    // Pointers to dest. lines.
00340 
00341   Trace (2, "Decoding uncompressed 4 bit per pixel bitmap.\n");
00342 
00343   for (y=0; y<pBmp->GetHeight(); y++)
00344   { // For each line...
00345     pDest = pLineArray[pBmp->GetHeight()-y-1];
00346     for (x=0; x<XSize/2; x++)
00347     { // For each source byte...
00348       pSrc = pDataSrc->Read1Byte();
00349       SrcByte = *(pSrc);
00350 
00351       *pDest = SrcByte>>4;
00352       pDest++;
00353       *pDest = SrcByte & 15;
00354       pDest++;
00355    }
00356 
00357     // Last nibble in line if line length is odd.
00358     if (XSize & 1)
00359     {
00360       pSrc = pDataSrc->Read1Byte();
00361       *pDest = (*(pSrc))>>4;
00362       pDest++;
00363     }
00364     pDataSrc->Skip (LinePadding);
00365   }
00366 }
00367 
00368 
00369 void PLBmpDecoder::decode8bpp
00370     ( PLDataSource * pDataSrc,
00371       PLBmp * pBmp
00372     )
00373     // Decodes an uncompressed 256-color-bitmap.
00374 {
00375   int y;                            // Current row
00376   int x;                            // Current column
00377 
00378   PLBYTE * pDest;                     // Current destination.
00379   PLBYTE * pSrc;                      // Current position in file.
00380   int    XSize = pBmp->GetWidth();// Width of bitmap in pixels.
00381   int    LineLen = (XSize + 3) & ~3;
00382                                     // Width of source in bytes
00383                                     //   (DWORD-aligned).
00384   int    LinePadding = LineLen-XSize;
00385   PLBYTE ** pLineArray = pBmp->GetLineArray();
00386                                    // Pointers to dest. lines.
00387 
00388   Trace (2, "Decoding uncompressed 8 bit per pixel bitmap.\n");
00389 
00390   for (y=0; y<pBmp->GetHeight(); y++)
00391   { // For each line...
00392     pDest = pLineArray[pBmp->GetHeight()-y-1];
00393     for (x=0; x<XSize; x++)
00394     { // For each source byte...
00395       pSrc = pDataSrc->Read1Byte();
00396       *pDest = *pSrc;
00397       pDest++;
00398     }
00399     pDataSrc->Skip (LinePadding);
00400   }
00401 }
00402 
00403 
00404 void PLBmpDecoder::decodeRLE4
00405     ( PLDataSource * pDataSrc,
00406       PLBmp * pBmp
00407     )
00408     // Decodes a compressed 16-color-bitmap.
00409 {
00410   int y;                              // Current row
00411 
00412   PLBYTE * pSrc;
00413   PLBYTE * pDest;                       // Current destination.
00414   int    XSize = pBmp->GetWidth();  // Width of bitmap in pixels.
00415   PLBYTE   SrcByte;                     // Source byte cache.
00416 
00417   PLBYTE   RunLength;    // Length of current run.
00418   bool   bOdd;         // true if current run has odd length.
00419 
00420   bool   bEOL;         // true if end of line reached.
00421   bool   bEOF=false;   // true if end of file reached.
00422 
00423   PLBYTE * pLineBuf;     // Current line as uncompressed nibbles.
00424   PLBYTE * pBuf;         // Current position in pLineBuf.
00425   PLBYTE ** pLineArray = pBmp->GetLineArray();
00426                                    // Pointers to dest. lines.
00427 
00428   Trace (2, "Decoding RLE4-compressed bitmap.\n");
00429 
00430   // Allocate enough memory for DWORD alignment in original 4 bpp
00431   // bitmap.
00432   pLineBuf = new PLBYTE [XSize*4+28];
00433 
00434   for (y=0; y<pBmp->GetHeight() && !bEOF; y++)
00435   { // For each line...
00436     pBuf = pLineBuf;
00437     bEOL=false;
00438     while (!bEOL)
00439     { // For each packet do
00440       pSrc = pDataSrc->Read1Byte();
00441       RunLength = *pSrc;
00442       if (RunLength==0)
00443       { // Literal or escape.
00444         pSrc = pDataSrc->Read1Byte();
00445         RunLength = *pSrc;
00446         switch (RunLength)
00447         {
00448           case 0: // End of line escape
00449             bEOL = true;
00450             break;
00451           case 1: // End of file escape
00452             bEOF = true;
00453             bEOL = true;
00454             break;
00455           case 2: // Delta escape.
00456             // I have never seen a file using this.
00457             delete [] pLineBuf;
00458             raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00459                         "Encountered delta escape.");
00460             break;
00461           default:
00462             // Literal packet
00463             bOdd = (RunLength & 1);
00464             RunLength /= 2; // Convert pixels to bytes.
00465             for (int i=0; i<RunLength; i++)
00466             { // For each source byte...
00467               pSrc = pDataSrc->Read1Byte();
00468               decode2Nibbles (pBuf, *pSrc);
00469               pBuf += 2;
00470             }
00471             if (bOdd)
00472             { // Odd length packet -> one nibble left over
00473               pSrc = pDataSrc->Read1Byte();
00474               *pBuf = (*(pSrc))>>4;
00475               pBuf++;
00476             }
00477             // Word alignment at end of literal packet.
00478             if ((RunLength + bOdd) & 1) pDataSrc->Skip(1);
00479         }
00480       }
00481       else
00482       { // Encoded packet:
00483         // RunLength 4 bpp pixels with 2 alternating
00484         // values.
00485         pSrc = pDataSrc->Read1Byte();
00486         SrcByte = *pSrc;
00487         for (int i=0; i<RunLength/2; i++)
00488         {
00489           decode2Nibbles (pBuf, SrcByte);
00490           pBuf += 2;
00491         }
00492         if (RunLength & 1)
00493         {
00494           *pBuf = (*(pSrc))>>4;
00495           pBuf++;
00496         }
00497       }
00498     }
00499     pDest = pLineArray[pBmp->GetHeight()-y-1];
00500     memcpy (pDest, pLineBuf, XSize);
00501   }
00502   delete [] pLineBuf;
00503 }
00504 
00505 
00506 void PLBmpDecoder::decodeRLE8
00507     ( PLDataSource * pDataSrc,
00508       PLBmp * pBmp
00509     )
00510     // Decodes a compressed 256-color-bitmap.
00511 {
00512   int y;                              // Current row
00513 
00514   PLBYTE * pDest;                       // Current destination.
00515   PLBYTE * pSrc;                        // Current position in file.
00516   PLBYTE   RunLength;                   // Length of current run.
00517   bool   bEOL;                        // true if end of line reached.
00518   bool   bEOF=false;                  // true if end of file reached.
00519   PLBYTE ** pLineArray = pBmp->GetLineArray();
00520                                       // Pointers to dest. lines.
00521 
00522   Trace (2, "Decoding RLE8-compressed bitmap.\n");
00523 
00524   for (y=0; y<pBmp->GetHeight() && !bEOF; y++)
00525   { // For each line...
00526     pDest = pLineArray[pBmp->GetHeight()-y-1];
00527     bEOL=false;
00528     while (!bEOL)
00529     { // For each packet do
00530       pSrc = pDataSrc->Read1Byte();
00531       RunLength = *pSrc;
00532       if (RunLength==0)
00533       { // Literal or escape.
00534         pSrc = pDataSrc->Read1Byte();
00535         RunLength = *pSrc;
00536         switch (RunLength)
00537         {
00538           case 0: // End of line escape
00539             bEOL = true;
00540             break;
00541           case 1: // End of file escape
00542             bEOF = true;
00543             bEOL = true;
00544             break;
00545           case 2: // Delta escape.
00546             // I have never seen a file using this...
00547             raiseError (PL_ERRFORMAT_NOT_SUPPORTED,
00548                         "Encountered delta escape.");
00549             bEOL = true;
00550             bEOF = true;
00551             break;
00552           default:
00553             // Literal packet
00554             pSrc = pDataSrc->ReadNBytes(RunLength);
00555             memcpy (pDest, pSrc, RunLength);
00556             pDest += RunLength;
00557             // Word alignment at end of literal packet.
00558             if (RunLength & 1) pDataSrc->Skip(1);
00559         }
00560       }
00561       else
00562       { // Encoded packet:
00563         // RunLength pixels, all with the same value
00564         pSrc = pDataSrc->Read1Byte();
00565         memset (pDest, *pSrc, RunLength);
00566         pDest += RunLength;
00567       }
00568     }
00569   }
00570 }
00571 
00572 void PLBmpDecoder::decodeHiColor
00573     ( PLDataSource * pDataSrc,
00574       PLBmp * pBmp,
00575       WINBITMAPINFOHEADER * pBMI
00576     )
00577 {
00578   if (pBMI->biCompression == BI_RGB)
00579     decodeTrueColor (pDataSrc, pBmp, 15);
00580   else
00581   {
00582     PLASSERT (pBMI->biCompression == BI_BITFIELDS);
00583     // Colors are really bit masks.
00584     PLULONG * pColMask;
00585     pDataSrc->Read4Bytes();  // Skip blue bitmask
00586     pColMask = (PLULONG *) pDataSrc->ReadNBytes(4);
00587     pDataSrc->Read4Bytes();  // Skip red bitmask
00588     if (*pColMask == 0x03E0)
00589       decodeTrueColor (pDataSrc, pBmp, 15);
00590     else
00591       decodeTrueColor (pDataSrc, pBmp, 16);
00592   }
00593 }
00594 
00595 
00596 void PLBmpDecoder::decodeTrueColor
00597     ( PLDataSource * pDataSrc,
00598       PLBmp * pBmp,
00599       int SrcBPP
00600     )
00601     // Decodes true-color bitmap
00602 {
00603   int y;                            // Current row
00604   PLBYTE * pDest;                     // Current destination.
00605   PLBYTE ** pLineArray = pBmp->GetLineArray();
00606                                    // Pointers to dest. lines.
00607 
00608   Trace (2, "Decoding true-color bitmap.\n");
00609 
00610   for (y=0; y<pBmp->GetHeight(); y++)
00611   { // For each line...
00612     pDest = pLineArray[pBmp->GetHeight()-y-1];
00613     switch (SrcBPP)
00614     {
00615       case 15:
00616         decode15bppLine (pDataSrc, pBmp, pDest);
00617         break;
00618       case 16:
00619         decode16bppLine (pDataSrc, pBmp, pDest);
00620         break;
00621       case 24:
00622         decode24bppLine (pDataSrc, pBmp, pDest);
00623         break;
00624       case 32:
00625         decode32bppLine (pDataSrc, pBmp, pDest);
00626         break;
00627       default:
00628         // This routine should never have been called if we get here.
00629         PLASSERT (false);
00630     }
00631   }
00632 }
00633 
00634 void PLBmpDecoder::decode15bppLine
00635     ( PLDataSource * pDataSrc,
00636       PLBmp * pBmp,
00637       PLBYTE * pDest
00638     )
00639 {
00640   int LineLen = (pBmp->GetWidth()*2 + 3) & ~3; // Width of source in bytes
00641                                                // (DWORD-aligned).
00642   int LinePadding = LineLen - pBmp->GetWidth()*2;
00643 
00644   int x;                            // Current column
00645   for (x=0; x<pBmp->GetWidth(); x++)
00646   { // For each pixel...
00647     PLBYTE * pSrc = pDataSrc->ReadNBytes(2);     // Current position in file.
00648     PLWORD Pixel = *(PLWORD*)pSrc;
00649     *(pDest+PL_RGBA_RED) = PLBYTE (( Pixel >> 7 ) & 0x0F8);
00650     *(pDest+PL_RGBA_GREEN) = PLBYTE (( Pixel >> 2 ) & 0x0F8);
00651     *(pDest+PL_RGBA_BLUE) = PLBYTE (( Pixel & 0x1F ) * 8);
00652     *(pDest+PL_RGBA_ALPHA) = 0xFF;
00653     pDest += 4;
00654   }
00655   pDataSrc->Skip (LinePadding);
00656 }
00657 
00658 void PLBmpDecoder::decode16bppLine
00659     ( PLDataSource * pDataSrc,
00660       PLBmp * pBmp,
00661       PLBYTE * pDest
00662     )
00663 {
00664   int LineLen = (pBmp->GetWidth()*2 + 3) & ~3; // Width of source in bytes
00665                                                // (DWORD-aligned).
00666   int LinePadding = LineLen - pBmp->GetWidth()*2;
00667 
00668   int x;                            // Current column
00669   for (x=0; x<pBmp->GetWidth(); x++)
00670   { // For each pixel...
00671     PLBYTE * pSrc = pDataSrc->ReadNBytes(2);     // Current position in file.
00672     PLWORD Pixel = *(PLWORD*)pSrc;
00673     *(pDest+PL_RGBA_RED) = PLBYTE (( Pixel >> 8 ) & 0x0F8);
00674     *(pDest+PL_RGBA_GREEN) = PLBYTE (( Pixel >> 3 ) & 0x0F8);
00675     *(pDest+PL_RGBA_BLUE) = PLBYTE (( Pixel & 0x1F ) * 8);
00676     *(pDest+PL_RGBA_ALPHA) = 0xFF;
00677     pDest += 4;
00678   }
00679   pDataSrc->Skip (LinePadding);
00680 }
00681 
00682 
00683 void PLBmpDecoder::decode24bppLine
00684     ( PLDataSource * pDataSrc,
00685       PLBmp * pBmp,
00686       PLBYTE * pDest
00687     )
00688 {
00689   int LineLen = (pBmp->GetWidth()*3 + 3) & ~3; // Width of source in bytes
00690                                                // (DWORD-aligned).
00691   int LinePadding = LineLen - pBmp->GetWidth()*3;
00692 
00693   int x;                            // Current column
00694   for (x=0; x<pBmp->GetWidth(); x++)
00695   { // For each pixel...
00696     PLBYTE * pSrc;                    // Current position in file.
00697     pSrc = pDataSrc->ReadNBytes(3);
00698     *(pDest+PL_RGBA_BLUE) = ((WINRGBQUAD *)pSrc)->rgbBlue;
00699     *(pDest+PL_RGBA_GREEN) = ((WINRGBQUAD *)pSrc)->rgbGreen;
00700     *(pDest+PL_RGBA_RED) = ((WINRGBQUAD *)pSrc)->rgbRed;
00701     *(pDest+PL_RGBA_ALPHA) = 0xFF;
00702     pDest += 4;
00703   }
00704   pDataSrc->Skip (LinePadding);
00705 }
00706 
00707 void PLBmpDecoder::decode32bppLine
00708     ( PLDataSource * pDataSrc,
00709       PLBmp * pBmp,
00710       PLBYTE * pDest
00711     )
00712 {
00713   PLBYTE * pSrc = pDataSrc->ReadNBytes (pBmp->GetWidth()*4);
00714   memcpy (pDest, pSrc, pBmp->GetWidth()*4);
00715 }
00716 
00717 
00718 void PLBmpDecoder::decode2Nibbles
00719     ( PLBYTE * pDest,
00720       PLBYTE SrcByte
00721     )
00722     // Decodes two 4-bit pixels.
00723 {
00724   *pDest = SrcByte>>4;
00725   *(pDest+1) = SrcByte & 15;
00726 }
00727 
00728 int PLBmpDecoder::readPalette
00729     ( WINBITMAPINFOHEADER * pBMI,     // Pointer to bitmapinfoheader in file.
00730       PLDataSource * pDataSrc,
00731       PLPixel32 * pPal,
00732       int RGBSize
00733     )
00734     // Assumes 8 bpp or less.
00735 {
00736   Trace (3, "Reading palette.\n");
00737   int i;
00738 
00739   int NumColors;
00740   if (pBMI->biClrUsed == 0)
00741     NumColors = 1<<(pBMI->biBitCount);
00742    else
00743     NumColors = pBMI->biClrUsed;
00744 
00745   PLBYTE * pFilePal = (PLBYTE *) pDataSrc->ReadNBytes (NumColors*RGBSize);
00746   WINRGBQUAD * pCurEntry;
00747 
00748   // Correct the byte ordering & copy the data.
00749   for (i=0; i<NumColors; i++)
00750   {
00751     pCurEntry = (WINRGBQUAD *)(pFilePal+(RGBSize)*i);
00752     pPal[i].Set (pCurEntry->rgbRed, pCurEntry->rgbGreen,
00753                  pCurEntry->rgbBlue, 0xFF);
00754   }
00755 
00756   return NumColors;
00757 }
00758 /*
00759 /--------------------------------------------------------------------
00760 |
00761 |      $Log: plbmpdec.cpp,v $
00762 |      Revision 1.1  2004/05/21 21:02:52  maxx
00763 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00764 |
00765 |      Revision 1.1  2002/11/13 01:58:20  mspindle
00766 |      *** empty log message ***
00767 |
00768 |      Revision 1.7  2001/10/21 17:12:39  uzadow
00769 |      Added PSD decoder beta, removed BPPWanted from all decoders, added PLFilterPixel.
00770 |
00771 |      Revision 1.6  2001/10/16 17:12:26  uzadow
00772 |      Added support for resolution information (Luca Piergentili)
00773 |
00774 |      Revision 1.5  2001/10/06 22:03:26  uzadow
00775 |      Added PL prefix to basic data types.
00776 |
00777 |      Revision 1.4  2001/10/06 20:44:45  uzadow
00778 |      Linux compatibility
00779 |
00780 |      Revision 1.3  2001/10/06 15:32:22  uzadow
00781 |      Removed types LPBYTE, DWORD, UCHAR, VOID and INT from the code.
00782 |
00783 |      Revision 1.2  2001/10/05 21:15:09  uzadow
00784 |      Improved support for OS/2 bitmap decoding.
00785 |
00786 |      Revision 1.1  2001/09/16 19:03:22  uzadow
00787 |      Added global name prefix PL, changed most filenames.
00788 |
00789 |      Revision 1.20  2001/02/04 14:31:52  uzadow
00790 |      Member initialization list cleanup (Erik Hoffmann).
00791 |
00792 |      Revision 1.19  2001/01/21 14:28:21  uzadow
00793 |      Changed array cleanup from delete to delete[].
00794 |
00795 |      Revision 1.18  2001/01/14 15:32:21  uzadow
00796 |      Unix compatibility changes.
00797 |
00798 |      Revision 1.17  2001/01/14 15:09:33  uzadow
00799 |      Added support for decoding OS/2 bitmaps.
00800 |
00801 |      Revision 1.16  2000/12/18 22:42:52  uzadow
00802 |      Replaced RGBAPIXEL with PLPixel32.
00803 |
00804 |      Revision 1.15  2000/12/09 13:45:55  uzadow
00805 |      Added support for 16 bpp bitmaps.
00806 |
00807 |      Revision 1.14  2000/12/04 13:20:28  uzadow
00808 |      Minor refactorings.
00809 |
00810 |      Revision 1.13  2000/10/24 22:57:42  uzadow
00811 |      Fixed exception handling
00812 |
00813 |      Revision 1.12  2000/08/13 12:11:43  Administrator
00814 |      Added experimental DirectDraw-Support
00815 |
00816 |      Revision 1.11  2000/07/07 13:20:47  Ulrich von Zadow
00817 |      Bugfix: Added #pragma pack to WINBITMAPFILEHEADER.
00818 |
00819 |      Revision 1.10  2000/05/23 10:19:11  Ulrich von Zadow
00820 |      Minor unix compatibility changes.
00821 |
00822 |      Revision 1.9  2000/01/16 20:43:12  anonymous
00823 |      Removed MFC dependencies
00824 |
00825 |      Revision 1.8  2000/01/04 18:36:02  Ulrich von Zadow
00826 |      Corrected handling of bitmap files with extended headers.
00827 |
00828 |      Revision 1.7  1999/12/30 15:54:02  Ulrich von Zadow
00829 |      no message
00830 |
00831 |      Revision 1.6  1999/12/08 15:39:45  Ulrich von Zadow
00832 |      Unix compatibility changes
00833 |
00834 |      Revision 1.5  1999/11/27 18:45:48  Ulrich von Zadow
00835 |      Added/Updated doc comments.
00836 |
00837 |      Revision 1.4  1999/10/03 18:50:51  Ulrich von Zadow
00838 |      Added automatic logging of changes.
00839 |
00840 |
00841 --------------------------------------------------------------------
00842 */

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