pximage.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:75k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. // include
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "hxresult.h"
  39. #include "hxcom.h"
  40. #include "ihxpckts.h"
  41. #include "hxvsurf.h"
  42. // hxcont
  43. #include "hxbuffer.h"
  44. // hxmisc
  45. #include "unkimp.h"
  46. #include "baseobj.h"
  47. // pxcomlib
  48. #include "pxcolor.h"
  49. #include "pxrect.h"
  50. #include "pxeffect.h"
  51. #include "pximage.h"
  52. // hxdebug
  53. #include "hxheap.h"
  54. #ifdef _DEBUG
  55. #undef HX_THIS_FILE
  56. static char HX_THIS_FILE[] = __FILE__;
  57. #endif
  58. PXImage::PXImage()
  59. {
  60.     ResetMembers();
  61.     m_lRefCount   = 0;
  62.     m_pImageStore = NULL;
  63. }
  64. PXImage::~PXImage()
  65. {
  66.     Destroy();
  67. }
  68. HX_RESULT PXImage::CreateObject(PXImage** ppImg)
  69. {
  70.     HX_RESULT retVal = HXR_FAIL;
  71.     if (ppImg)
  72.     {
  73.         PXImage* pImg = new PXImage();
  74.         if (pImg)
  75.         {
  76.             *ppImg = pImg;
  77.             retVal = HXR_OK;
  78.         }
  79.     }
  80.     return retVal;
  81. }
  82. HX_RESULT PXImage::CreateInstance(PXImage** ppImg)
  83. {
  84.     HX_RESULT retVal = HXR_FAIL;
  85.     if (ppImg)
  86.     {
  87.         PXImage* pImg = new PXImage();
  88.         if (pImg)
  89.         {
  90.             // AddRef the object
  91.             pImg->AddRef();
  92.             // Assign the out parameter
  93.             *ppImg = pImg;
  94.             retVal = HXR_OK;
  95.         }
  96.     }
  97.     return retVal;
  98. }
  99. STDMETHODIMP PXImage::QueryInterface(REFIID riid, void** ppvObj)
  100. {
  101.     HX_RESULT retVal = HXR_OK;
  102.     if (IsEqualIID(riid, IID_IUnknown))
  103.     {
  104.         AddRef();
  105.         *ppvObj = (IUnknown *) this;
  106.     }
  107.     else
  108.     {
  109.         *ppvObj = NULL;
  110.         retVal  = HXR_NOINTERFACE;
  111.     }
  112.     return retVal;
  113. }
  114. STDMETHODIMP_(UINT32) PXImage::AddRef()
  115. {
  116.     return InterlockedIncrement(&m_lRefCount);
  117. }
  118. STDMETHODIMP_(UINT32) PXImage::Release()
  119. {
  120.     
  121.     if (InterlockedDecrement(&m_lRefCount) > 0)
  122.         return m_lRefCount;
  123.     delete this;
  124.     return 0;
  125. }
  126. HX_RESULT PXImage::Create(INT32 lW, INT32 lH, UINT32 ulBpp, UINT32 ulFormat,
  127.                           BOOL bRowsInverted, BOOL bAlloc)
  128. {
  129.     // Check for invalid input size
  130.     if (lW <= 0          ||
  131.         lW >  kMaxWidth  ||
  132.         lH <= 0          ||
  133.         lH >  kMaxHeight)
  134.     {
  135.         HX_ASSERT(FALSE);
  136.         return HXR_FAIL;
  137.     }
  138.     // Check to see if we're asked to NOT alloc, but
  139.     // don't have any image store
  140.     if (!bAlloc && !m_pImageStore)
  141.     {
  142.         HX_ASSERT(FALSE);
  143.         return HXR_FAIL;
  144.     }
  145.     // Filter out unsupported formats
  146.     switch (ulBpp)
  147.     {
  148.         case 32:
  149.             if (ulFormat != HX_RGB)
  150.             {
  151.                 HX_ASSERT(FALSE);
  152.                 return HXR_FAIL;
  153.             }
  154.             break;
  155.         default:
  156.             HX_ASSERT(FALSE);
  157.             return HXR_FAIL;
  158.     }
  159.     // Reset members (except image store)
  160.     ResetMembers();
  161.     // Assign member variables
  162.     m_cBitmapInfo.biWidth       = lW;
  163.     m_cBitmapInfo.biHeight      = lH;
  164.     m_cBitmapInfo.biBitCount    = (UINT16) ulBpp;
  165.     m_cBitmapInfo.biCompression = ulFormat;
  166.     m_cSubImageRect.left        = 0;
  167.     m_cSubImageRect.top         = 0;
  168.     m_cSubImageRect.right       = lW;
  169.     m_cSubImageRect.bottom      = lH;
  170.     m_lSubImageWidth            = lW;
  171.     m_lSubImageHeight           = lH;
  172.     m_bRowsInverted             = bRowsInverted;
  173.     m_ulBytesPerPixel           = (ulBpp + 7) >> 3;
  174.     m_lRowBytes                 = lW * m_ulBytesPerPixel;
  175.     m_lRowStride                = (m_lRowBytes + 3) & ~3;
  176.     // Determine the number of bytes we need
  177.     UINT32 ulNumBytes = m_lRowStride * m_cBitmapInfo.biHeight;
  178.     // Check to see if we need to alloc memory. We will allocate
  179.     // if the bAlloc parameter tells us to OR if bAlloc is FALSE
  180.     // AND we have don't already have enough to satisfy the request.
  181.     if (bAlloc || (!bAlloc && m_pImageStore->GetSize() < ulNumBytes))
  182.     {
  183.         // Now create the storage object
  184.         HX_RELEASE(m_pImageStore);
  185.         m_pImageStore = (IHXBuffer *) new CHXBuffer();
  186.         if (!m_pImageStore)
  187.         {
  188.             ResetMembers();
  189.             return HXR_OUTOFMEMORY;
  190.         }
  191.         m_pImageStore->AddRef();
  192.         // Set its size
  193.         HX_RESULT retVal = m_pImageStore->SetSize(ulNumBytes);
  194.         if (retVal != HXR_OK)
  195.         {
  196.             HX_RELEASE(m_pImageStore);
  197.             ResetMembers();
  198.             return retVal;
  199.         }
  200.     }
  201.     // Set the image buffer to beginning of storage
  202.     if (m_bRowsInverted)
  203.     {
  204.         m_pImageBuffer = m_pImageStore->GetBuffer() + (m_cBitmapInfo.biHeight - 1) * m_lRowStride;
  205.         m_lRowJump     = - m_lRowStride;
  206.     }
  207.     else
  208.     {
  209.         m_pImageBuffer = m_pImageStore->GetBuffer();
  210.         m_lRowJump     = m_lRowStride;
  211.     }
  212.     // Set the initialization flag
  213.     m_bInitialized = TRUE;
  214.     return HXR_OK;
  215. }
  216. HX_RESULT PXImage::CreateFromBuffer(INT32 lW, INT32 lH, UINT32 ulBpp, UINT32 ulFormat,
  217.                                     BOOL bRowsInverted, IHXBuffer* pBuffer)
  218. {
  219.     HX_RESULT retVal = HXR_OK;
  220.     if (lW > 0 && lW <= kMaxWidth && lH > 0 && lH <= kMaxHeight &&
  221.         ulBpp == 32 && ulFormat == HX_RGB && pBuffer)
  222.     {
  223.         // Reset members (except image store)
  224.         ResetMembers();
  225.         // Assign member variables
  226.         m_cBitmapInfo.biWidth       = lW;
  227.         m_cBitmapInfo.biHeight      = lH;
  228.         m_cBitmapInfo.biBitCount    = (UINT16) ulBpp;
  229.         m_cBitmapInfo.biCompression = ulFormat;
  230.         m_cSubImageRect.left        = 0;
  231.         m_cSubImageRect.top         = 0;
  232.         m_cSubImageRect.right       = lW;
  233.         m_cSubImageRect.bottom      = lH;
  234.         m_lSubImageWidth            = lW;
  235.         m_lSubImageHeight           = lH;
  236.         m_bRowsInverted             = bRowsInverted;
  237.         m_ulBytesPerPixel           = (ulBpp + 7) >> 3;
  238.         m_lRowBytes                 = lW * m_ulBytesPerPixel;
  239.         m_lRowStride                = (m_lRowBytes + 3) & ~3;
  240.         // Determine the number of bytes we need
  241.         UINT32 ulNumBytes = m_lRowStride * m_cBitmapInfo.biHeight;
  242.         //  Make sure the provided buffer is big enough
  243.         if (pBuffer->GetSize() >= ulNumBytes)
  244.         {
  245.             // Save the passed in buffer
  246.             HX_RELEASE(m_pImageStore);
  247.             m_pImageStore = pBuffer;
  248.             m_pImageStore->AddRef();
  249.             // Set the image buffer to beginning of storage
  250.             if (m_bRowsInverted)
  251.             {
  252.                 m_pImageBuffer = m_pImageStore->GetBuffer() + (m_cBitmapInfo.biHeight - 1) * m_lRowStride;
  253.                 m_lRowJump     = - m_lRowStride;
  254.             }
  255.             else
  256.             {
  257.                 m_pImageBuffer = m_pImageStore->GetBuffer();
  258.                 m_lRowJump     = m_lRowStride;
  259.             }
  260.             // Set the initialization flag
  261.             m_bInitialized = TRUE;
  262.         }
  263.         else
  264.         {
  265.             retVal = HXR_INVALID_PARAMETER;
  266.         }
  267.     }
  268.     else
  269.     {
  270.         retVal = HXR_INVALID_PARAMETER;
  271.     }
  272.     return retVal;
  273. }
  274. HX_RESULT PXImage::CreateSubImage(PXImage* pImg, INT32 lX, INT32 lY, INT32 lW, INT32 lH,
  275.                                   BOOL bCopy, BOOL bAlloc)
  276. {
  277.     // Check for input error
  278.     if (!pImg || lX < 0 || lY < 0 || lW < 0 || lH < 0)
  279.     {
  280.         HX_ASSERT(FALSE);
  281.         return HXR_FAIL;
  282.     }
  283.     // Adjust for default input
  284.     if (lW == 0)
  285.     {
  286.         lW = pImg->GetWidth();
  287.     }
  288.     if (lH == 0)
  289.     {
  290.         lH = pImg->GetHeight();
  291.     }
  292.     // Check for input error
  293.     if (lX + lW >  pImg->GetWidth())
  294.     {
  295.         lW = pImg->GetWidth() - lX;
  296.     }
  297.     if (lY + lH >  pImg->GetHeight())
  298.     {
  299.         lH = pImg->GetHeight() - lY;
  300.     }
  301.     // Check to see if we're asked NOT to copy but to alloc
  302.     if (!bCopy && bAlloc)
  303.     {
  304.         HX_ASSERT(FALSE);
  305.         return HXR_FAIL;
  306.     }
  307.     // Reset everything (except image store)
  308.     ResetMembers();
  309.     // Are we copying or not?
  310.     if (bCopy)
  311.     {
  312.         // Set member variables
  313.         m_cBitmapInfo.biWidth       = lW;
  314.         m_cBitmapInfo.biHeight      = lH;
  315.         m_cBitmapInfo.biBitCount    = pImg->m_cBitmapInfo.biBitCount;
  316.         m_cBitmapInfo.biCompression = pImg->m_cBitmapInfo.biCompression;
  317.         m_cSubImageRect.left        = 0;
  318.         m_cSubImageRect.top         = 0;
  319.         m_cSubImageRect.right       = lW;
  320.         m_cSubImageRect.bottom      = lH;
  321.         m_lSubImageWidth            = lW;
  322.         m_lSubImageHeight           = lH;
  323.         m_bRowsInverted             = pImg->m_bRowsInverted;
  324.         m_ulBytesPerPixel           = pImg->m_ulBytesPerPixel;
  325.         m_lRowBytes                 = lW * m_ulBytesPerPixel;
  326.         m_lRowStride                = (m_lRowBytes + 3) & ~3;
  327.         m_bHasAlpha                 = pImg->m_bHasAlpha;
  328.         // Determine the number of bytes we need
  329.         UINT32 ulNumBytes = m_lRowStride * m_cBitmapInfo.biHeight;
  330.         // Check to see if we need to alloc memory. We will allocate
  331.         // if the bAlloc parameter tells us to OR if bAlloc is FALSE
  332.         // AND we have don't already have enough to satisfy the request.
  333.         if (bAlloc || (!bAlloc && m_pImageStore->GetSize() < ulNumBytes))
  334.         {
  335.             // Create a new image store
  336.             HX_RELEASE(m_pImageStore);
  337.             m_pImageStore = (IHXBuffer *) new CHXBuffer();
  338.             if (!m_pImageStore)
  339.             {
  340.                 ResetMembers();
  341.                 return HXR_OUTOFMEMORY;
  342.             }
  343.             m_pImageStore->AddRef();
  344.             // Set its size
  345.             HX_RESULT retVal     = m_pImageStore->SetSize(ulNumBytes);
  346.             if (retVal != HXR_OK)
  347.             {
  348.                 Destroy();
  349.                 return retVal;
  350.             }
  351.         }
  352.         // Set the image buffer
  353.         if (m_bRowsInverted)
  354.         {
  355.             m_pImageBuffer = m_pImageStore->GetBuffer() + (m_cBitmapInfo.biHeight - 1) * m_lRowStride;
  356.             m_lRowJump     = - m_lRowStride;
  357.         }
  358.         else
  359.         {
  360.             m_pImageBuffer = m_pImageStore->GetBuffer();
  361.             m_lRowJump     = m_lRowStride;
  362.         }
  363.         // Copy the data
  364.         BYTE* pSrcRow = pImg->m_pImageBuffer + lY * pImg->m_lRowJump + lX * pImg->m_ulBytesPerPixel;
  365.         BYTE* pDstRow = m_pImageBuffer;
  366.         for (INT32 i = m_cBitmapInfo.biHeight; i; i--)
  367.         {
  368.             memcpy(pDstRow, pSrcRow, m_lRowBytes); /* Flawfinder: ignore */
  369.             pSrcRow += pImg->m_lRowJump;
  370.             pDstRow += m_lRowJump;
  371.         }
  372.     }
  373.     else
  374.     {
  375.         // Set member variables
  376.         m_cBitmapInfo          = pImg->m_cBitmapInfo;
  377.         m_cSubImageRect.left   = lX;
  378.         m_cSubImageRect.top    = lY;
  379.         m_cSubImageRect.right  = lX + lW;
  380.         m_cSubImageRect.bottom = lY + lH;
  381.         m_lSubImageWidth       = lW;
  382.         m_lSubImageHeight      = lH;
  383.         m_ulBytesPerPixel      = pImg->m_ulBytesPerPixel;
  384.         m_bRowsInverted        = pImg->m_bRowsInverted;
  385.         m_lRowBytes            = lW * m_ulBytesPerPixel;
  386.         m_bHasAlpha            = pImg->m_bHasAlpha;
  387.         // We ARE NOT copying, so our row stride and jump are the same
  388.         // as the source image
  389.         m_lRowStride = pImg->m_lRowStride;
  390.         m_lRowJump   = pImg->m_lRowJump;
  391.         // Ref the other image store
  392.         HX_RELEASE(m_pImageStore);
  393.         m_pImageStore = pImg->m_pImageStore;
  394.         m_pImageStore->AddRef();
  395.         // Set the image buffer properly (note that we must offset
  396.         // from the other object's m_pImageBuffer member and NOT the
  397.         // image store member - because we may be a subimage of a subimage)
  398.         m_pImageBuffer = pImg->m_pImageBuffer + (lY * m_lRowJump) + (lX * m_ulBytesPerPixel);
  399.     }
  400.     // Set the initialization flag
  401.     m_bInitialized = TRUE;
  402.     return HXR_OK;
  403. }
  404. HX_RESULT PXImage::CreateSubImage(PXImage* pImg, const PXRect& rSubRect,
  405.                                   BOOL bCopy, BOOL bAlloc)
  406. {
  407.     return CreateSubImage(pImg, (INT32) rSubRect.GetX(), (INT32) rSubRect.GetY(),
  408.                           (INT32) rSubRect.GetWidth(), (INT32) rSubRect.GetHeight(),
  409.                           bCopy, bAlloc);
  410. }
  411. HX_RESULT PXImage::CreateSubImage(PXImage* pImg, const HXxRect& rSubRect,
  412.                                   BOOL bCopy, BOOL bAlloc)
  413. {
  414.     return CreateSubImage(pImg, rSubRect.left, rSubRect.top, HXxRECT_WIDTH(rSubRect),
  415.                           HXxRECT_HEIGHT(rSubRect), bCopy, bAlloc);
  416. }
  417. HX_RESULT PXImage::CreateSubImageFromBuffer(PXImage* pImg, INT32 lX, INT32 lY,
  418.                                             INT32 lW, INT32 lH, IHXBuffer* pBuffer)
  419. {
  420.     HX_RESULT retVal = HXR_OK;
  421.     // Check for input error
  422.     if (pImg && lX >= 0 && lY >= 0 && lW >= 0 && lH >= 0)
  423.     {
  424.         // Adjust for default input
  425.         if (lW == 0)
  426.         {
  427.             lW = pImg->GetWidth();
  428.         }
  429.         if (lH == 0)
  430.         {
  431.             lH = pImg->GetHeight();
  432.         }
  433.         // Check for input error
  434.         if (lX + lW >  pImg->GetWidth())
  435.         {
  436.             lW = pImg->GetWidth() - lX;
  437.         }
  438.         if (lY + lH >  pImg->GetHeight())
  439.         {
  440.             lH = pImg->GetHeight() - lY;
  441.         }
  442.         // Reset everything (except image store)
  443.         ResetMembers();
  444.         // Set member variables
  445.         m_cBitmapInfo.biWidth       = lW;
  446.         m_cBitmapInfo.biHeight      = lH;
  447.         m_cBitmapInfo.biBitCount    = pImg->m_cBitmapInfo.biBitCount;
  448.         m_cBitmapInfo.biCompression = pImg->m_cBitmapInfo.biCompression;
  449.         m_cSubImageRect.left        = 0;
  450.         m_cSubImageRect.top         = 0;
  451.         m_cSubImageRect.right       = lW;
  452.         m_cSubImageRect.bottom      = lH;
  453.         m_lSubImageWidth            = lW;
  454.         m_lSubImageHeight           = lH;
  455.         m_bRowsInverted             = pImg->m_bRowsInverted;
  456.         m_ulBytesPerPixel           = pImg->m_ulBytesPerPixel;
  457.         m_lRowBytes                 = lW * m_ulBytesPerPixel;
  458.         m_lRowStride                = (m_lRowBytes + 3) & ~3;
  459.         m_bHasAlpha                 = pImg->m_bHasAlpha;
  460.         // Determine the number of bytes we need
  461.         UINT32 ulNumBytes = m_lRowStride * m_cBitmapInfo.biHeight;
  462.         // Make sure that the buffer we were provided is big enough
  463.         if (pBuffer->GetSize() >= ulNumBytes)
  464.         {
  465.             // Save the buffer
  466.             HX_RELEASE(m_pImageStore);
  467.             m_pImageStore = pBuffer;
  468.             m_pImageStore->AddRef();
  469.             // Set the image buffer
  470.             if (m_bRowsInverted)
  471.             {
  472.                 m_pImageBuffer = m_pImageStore->GetBuffer() + (m_cBitmapInfo.biHeight - 1) * m_lRowStride;
  473.                 m_lRowJump     = - m_lRowStride;
  474.             }
  475.             else
  476.             {
  477.                 m_pImageBuffer = m_pImageStore->GetBuffer();
  478.                 m_lRowJump     = m_lRowStride;
  479.             }
  480.             // Copy the data
  481.             BYTE* pSrcRow = pImg->m_pImageBuffer + lY * pImg->m_lRowJump + lX * pImg->m_ulBytesPerPixel;
  482.             BYTE* pDstRow = m_pImageBuffer;
  483.             for (INT32 i = m_cBitmapInfo.biHeight; i; i--)
  484.             {
  485.                 memcpy(pDstRow, pSrcRow, m_lRowBytes); /* Flawfinder: ignore */
  486.                 pSrcRow += pImg->m_lRowJump;
  487.                 pDstRow += m_lRowJump;
  488.             }
  489.         }
  490.         else
  491.         {
  492.             retVal = HXR_INVALID_PARAMETER;
  493.         }
  494.     }
  495.     else
  496.     {
  497.         retVal = HXR_INVALID_PARAMETER;
  498.     }
  499.     if (SUCCEEDED(retVal))
  500.     {
  501.         // Set the initialization flag
  502.         m_bInitialized = TRUE;
  503.     }
  504.     return retVal;
  505. }
  506. HX_RESULT PXImage::CreateSubImageFromBuffer(PXImage* pImg, const PXRect& rSubRect, IHXBuffer* pBuffer)
  507. {
  508.     return CreateSubImageFromBuffer(pImg, (INT32) rSubRect.GetX(), (INT32) rSubRect.GetY(),
  509.                                     (INT32) rSubRect.GetWidth(), (INT32) rSubRect.GetHeight(), pBuffer);
  510. }
  511. void PXImage::Destroy()
  512. {
  513.     HX_RELEASE(m_pImageStore);
  514.     ResetMembers();
  515. }
  516. HX_RESULT PXImage::Fill(const PXColor& rColor)
  517. {
  518.     UINT32 ulColor = MAKE_RGBA32(rColor.GetRed(),
  519.                                  rColor.GetGreen(),
  520.                                  rColor.GetBlue(),
  521.                                  rColor.GetAlpha());
  522.     return Fill32(ulColor);
  523. }
  524. HX_RESULT PXImage::Fill32(UINT32 ulColor)
  525. {
  526.     HX_RESULT retVal = HXR_OK;
  527.     if (m_bInitialized)
  528.     {
  529.         if (m_cBitmapInfo.biBitCount == 32 &&
  530.             CompressionSupported())
  531.         {
  532.             UINT32* pRow    = (UINT32*) m_pImageBuffer;
  533.             INT32   lJump   = m_lRowJump >> 2;
  534.             for (UINT32 ulY = (UINT32) m_lSubImageHeight; ulY; ulY--)
  535.             {
  536.                 UINT32* pPixel = pRow;
  537.                 for (UINT32 ulX = (UINT32) m_lSubImageWidth; ulX; ulX--)
  538.                 {
  539.                     *pPixel++ = ulColor;
  540.                 }
  541.                 pRow += lJump;
  542.             }
  543.         }
  544.         else
  545.         {
  546.             retVal = HXR_FAIL;
  547.         }
  548.     }
  549.     else
  550.     {
  551.         retVal = HXR_NOT_INITIALIZED;
  552.     }
  553.     return retVal;
  554. }
  555. HX_RESULT PXImage::Blend(PXImage* pImg1, PXImage* pImg2, BYTE* pLUT1, BYTE* pLUT2)
  556. {
  557.     if (!pImg1 || !pImg2 || !pLUT1 || !pLUT2 || !m_bInitialized)
  558.     {
  559.         HX_ASSERT(FALSE);
  560.         return HXR_FAIL;
  561.     }
  562.     FILTER_OUT_UNSUPPORTED_FORMATS;
  563.     if (!Compatible(pImg1) || !Compatible(pImg2) || !SameSize(pImg1) || !SameSize(pImg2))
  564.     {
  565.         HX_ASSERT(FALSE);
  566.         return HXR_FAIL;
  567.     }
  568.     UINT32* pSrcRow1  = (UINT32*) pImg1->m_pImageBuffer;
  569.     UINT32* pSrcRow2  = (UINT32*) pImg2->m_pImageBuffer;
  570.     UINT32* pDstRow   = (UINT32*) m_pImageBuffer;
  571.     INT32   lSrc1Jump = pImg1->m_lRowJump >> 2;
  572.     INT32   lSrc2Jump = pImg2->m_lRowJump >> 2;
  573.     INT32   lDstJump  = m_lRowJump       >> 2;
  574.     for (INT32 lY = m_lSubImageHeight; lY; lY--)
  575.     {
  576.         UINT32* pSrc1 = pSrcRow1;
  577.         UINT32* pSrc2 = pSrcRow2;
  578.         UINT32* pDst  = pDstRow;
  579.         if (pImg2->m_bHasAlpha)
  580.         {
  581.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  582.             {
  583.                 UINT32 ulR = pLUT1[GETRED32(*pSrc1)]   + pLUT2[GETRED32(*pSrc2)];
  584.                 UINT32 ulG = pLUT1[GETGREEN32(*pSrc1)] + pLUT2[GETGREEN32(*pSrc2)];
  585.                 UINT32 ulB = pLUT1[GETBLUE32(*pSrc1)]  + pLUT2[GETBLUE32(*pSrc2)];
  586.                 UINT32 ulA = GETALPHA32(*pSrc2);
  587.                 ulA        = (ulA < 128 ? ulA : ulA + 1); // scale to 256
  588.                 *pDst      = MAKE_RGB32(ALPHABLEND(GETRED32(*pDst),   ulR, ulA),
  589.                                         ALPHABLEND(GETGREEN32(*pDst), ulG, ulA),
  590.                                         ALPHABLEND(GETBLUE32(*pDst),  ulB, ulA));
  591.                 pSrc1++;
  592.                 pSrc2++;
  593.                 pDst++;
  594.             }
  595.         }
  596.         else
  597.         {
  598.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  599.             {
  600.                 *pDst = MAKE_RGB32(pLUT1[GETRED32(*pSrc1)]   + pLUT2[GETRED32(*pSrc2)],
  601.                                    pLUT1[GETGREEN32(*pSrc1)] + pLUT2[GETGREEN32(*pSrc2)],
  602.                                    pLUT1[GETBLUE32(*pSrc1)]  + pLUT2[GETBLUE32(*pSrc2)]);
  603.                 pSrc1++;
  604.                 pSrc2++;
  605.                 pDst++;
  606.             }
  607.         }
  608.         pSrcRow1 += lSrc1Jump;
  609.         pSrcRow2 += lSrc2Jump;
  610.         pDstRow  += lDstJump;
  611.     }
  612.     return HXR_OK;
  613. }
  614. HX_RESULT PXImage::RecursiveBlend(PXImage* pImg1, BYTE* pLUT1, BYTE* pSelfLUT)
  615. {
  616.     if (!pImg1 || !pLUT1 || !pSelfLUT || !m_bInitialized)
  617.     {
  618.         HX_ASSERT(FALSE);
  619.         return HXR_FAIL;
  620.     }
  621.     FILTER_OUT_UNSUPPORTED_FORMATS;
  622.     if (!Compatible(pImg1) || !SameSize(pImg1))
  623.     {
  624.         HX_ASSERT(FALSE);
  625.         return HXR_FAIL;
  626.     }
  627.     UINT32* pSrcRow1 = (UINT32*) pImg1->m_pImageBuffer;
  628.     UINT32* pDstRow  = (UINT32*) m_pImageBuffer;
  629.     INT32   lSrc1Jump = pImg1->m_lRowJump >> 2;
  630.     INT32   lDstJump  = m_lRowJump       >> 2;
  631.     for (INT32 lY = m_lSubImageHeight; lY; lY--)
  632.     {
  633.         UINT32* pSrc1 = pSrcRow1;
  634.         UINT32* pDst  = pDstRow;
  635.         for (INT32 lX = m_lSubImageWidth; lX; lX--)
  636.         {
  637.             *pDst = MAKE_RGB32(pLUT1[GETRED32(*pSrc1)]   + pSelfLUT[GETRED32(*pDst)],
  638.                                pLUT1[GETGREEN32(*pSrc1)] + pSelfLUT[GETGREEN32(*pDst)],
  639.                                pLUT1[GETBLUE32(*pSrc1)]  + pSelfLUT[GETBLUE32(*pDst)]);
  640.             pSrc1++;
  641.             pDst++;
  642.         }
  643.         pSrcRow1 += lSrc1Jump;
  644.         pDstRow  += lDstJump;
  645.     }
  646.     return HXR_OK;
  647. }
  648. HX_RESULT PXImage::BlendToColor(PXImage* pImg1, const PXColor& rColor, BYTE* pLUT1, BYTE* pLUT2)
  649. {
  650.     if (!pImg1 || !pLUT1 || !pLUT2 || !m_bInitialized)
  651.     {
  652.         HX_ASSERT(FALSE);
  653.         return HXR_FAIL;
  654.     }
  655.     FILTER_OUT_UNSUPPORTED_FORMATS;
  656.     if (!Compatible(pImg1) || !SameSize(pImg1))
  657.     {
  658.         HX_ASSERT(FALSE);
  659.         return HXR_FAIL;
  660.     }
  661.     BYTE ucFadedR = pLUT2[rColor.GetRed()];
  662.     BYTE ucFadedG = pLUT2[rColor.GetGreen()];
  663.     BYTE ucFadedB = pLUT2[rColor.GetBlue()];
  664.     UINT32* pSrcRow1 = (UINT32*) pImg1->m_pImageBuffer;
  665.     UINT32* pDstRow  = (UINT32*) m_pImageBuffer;
  666.     INT32   lSrc1Jump = pImg1->m_lRowJump >> 2;
  667.     INT32   lDstJump  = m_lRowJump       >> 2;
  668.     for (INT32 lY = m_lSubImageHeight; lY; lY--)
  669.     {
  670.         UINT32* pSrc1 = pSrcRow1;
  671.         UINT32* pDst  = pDstRow;
  672.         for (INT32 lX = m_lSubImageWidth; lX; lX--)
  673.         {
  674.             *pDst = MAKE_RGB32(pLUT1[GETRED32(*pSrc1)]   + ucFadedR,
  675.                                pLUT1[GETGREEN32(*pSrc1)] + ucFadedG,
  676.                                pLUT1[GETBLUE32(*pSrc1)]  + ucFadedB);
  677.             pSrc1++;
  678.             pDst++;
  679.         }
  680.         pSrcRow1 += lSrc1Jump;
  681.         pDstRow  += lDstJump;
  682.     }
  683.     return HXR_OK;
  684. }
  685. HX_RESULT PXImage::RecursiveBlendToColor(const PXColor& rColor, BYTE* pLUT1, BYTE* pLUT2)
  686. {
  687.     if (!pLUT1 || !pLUT2 || !m_bInitialized)
  688.     {
  689.         HX_ASSERT(FALSE);
  690.         return HXR_FAIL;
  691.     }
  692.     FILTER_OUT_UNSUPPORTED_FORMATS;
  693.     BYTE ucFadedR = pLUT2[rColor.GetRed()];
  694.     BYTE ucFadedG = pLUT2[rColor.GetGreen()];
  695.     BYTE ucFadedB = pLUT2[rColor.GetBlue()];
  696.     UINT32* pDstRow  = (UINT32*) m_pImageBuffer;
  697.     INT32   lDstJump = m_lRowJump       >> 2;
  698.     for (INT32 lY = m_lSubImageHeight; lY; lY--)
  699.     {
  700.         UINT32* pDst  = pDstRow;
  701.         for (INT32 lX = m_lSubImageWidth; lX; lX--)
  702.         {
  703.             *pDst = MAKE_RGB32(pLUT1[GETRED32(*pDst)]   + ucFadedR,
  704.                                pLUT1[GETGREEN32(*pDst)] + ucFadedG,
  705.                                pLUT1[GETBLUE32(*pDst)]  + ucFadedB);
  706.             pDst++;
  707.         }
  708.         pDstRow  += lDstJump;
  709.     }
  710.     return HXR_OK;
  711. }
  712. HX_RESULT PXImage::ChangeSizeFromNN(PXImage* pImg)
  713. {
  714.     if (!pImg || !m_bInitialized || !pImg->m_bInitialized)
  715.     {
  716.         HX_ASSERT(FALSE);
  717.         return HXR_FAIL;
  718.     }
  719.     FILTER_OUT_UNSUPPORTED_FORMATS;
  720.     if (!Compatible(pImg))
  721.     {
  722.         HX_ASSERT(FALSE);
  723.         return HXR_FAIL;
  724.     }
  725.     return ChangeSize32NN((UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  726.                           pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2,
  727.                           (UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  728.                           m_lSubImageHeight,              m_lRowJump >> 2);
  729. }
  730. HX_RESULT PXImage::ChangeSizeFromNNTransparent32(PXImage* pImg)
  731. {
  732.     HX_RESULT retVal = HXR_OK;
  733.     if (pImg)
  734.     {
  735.         if (m_bInitialized && pImg->m_bInitialized)
  736.         {
  737.             if (m_cBitmapInfo.biBitCount          == 32      &&
  738.                 pImg->m_cBitmapInfo.biBitCount    == 32      &&
  739.                 CompressionSupported()                       &&
  740.                 pImg->CompressionSupported())
  741.             {
  742.                 if (Compatible(pImg))
  743.                 {
  744.                     retVal = ChangeSize32NNTransparent((UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  745.                                                        pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2,
  746.                                                        (UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  747.                                                        m_lSubImageHeight,              m_lRowJump >> 2);
  748.                 }
  749.                 else
  750.                 {
  751.                     retVal = HXR_FAIL;
  752.                 }
  753.             }
  754.             else
  755.             {
  756.                 retVal = HXR_FAIL;
  757.             }
  758.         }
  759.         else
  760.         {
  761.             retVal = HXR_NOT_INITIALIZED;
  762.         }
  763.     }
  764.     else
  765.     {
  766.         retVal = HXR_INVALID_PARAMETER;
  767.     }
  768.     return retVal;
  769. }
  770. HX_RESULT PXImage::ChangeSizeIntoNN(PXImage* pImg)
  771. {
  772.     if (!pImg || !m_bInitialized || !pImg->m_bInitialized)
  773.     {
  774.         HX_ASSERT(FALSE);
  775.         return HXR_FAIL;
  776.     }
  777.     FILTER_OUT_UNSUPPORTED_FORMATS;
  778.     if (!Compatible(pImg))
  779.     {
  780.         HX_ASSERT(FALSE);
  781.         return HXR_FAIL;
  782.     }
  783.     return ChangeSize32NN((UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  784.                           m_lSubImageHeight,              m_lRowJump >> 2,
  785.                           (UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  786.                           pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2);
  787. }
  788. HX_RESULT PXImage::ChangeSizeIntoNNTransparent32(PXImage* pImg)
  789. {
  790.     HX_RESULT retVal = HXR_OK;
  791.     if (pImg)
  792.     {
  793.         if (m_bInitialized && pImg->m_bInitialized)
  794.         {
  795.             if (m_cBitmapInfo.biBitCount          == 32      &&
  796.                 pImg->m_cBitmapInfo.biBitCount    == 32      &&
  797.                 CompressionSupported()                       &&
  798.                 pImg->CompressionSupported())
  799.             {
  800.                 if (Compatible(pImg))
  801.                 {
  802.                     retVal = ChangeSize32NNTransparent((UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  803.                                                        m_lSubImageHeight,              m_lRowJump >> 2,
  804.                                                        (UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  805.                                                        pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2);
  806.                 }
  807.                 else
  808.                 {
  809.                     retVal = HXR_FAIL;
  810.                 }
  811.             }
  812.             else
  813.             {
  814.                 retVal = HXR_FAIL;
  815.             }
  816.         }
  817.         else
  818.         {
  819.             retVal = HXR_NOT_INITIALIZED;
  820.         }
  821.     }
  822.     else
  823.     {
  824.         retVal = HXR_INVALID_PARAMETER;
  825.     }
  826.     return retVal;
  827. }
  828. HX_RESULT PXImage::CopyFrom(PXImage* pImg)
  829. {
  830.     if (!pImg || !m_bInitialized)
  831.     {
  832.         HX_ASSERT(FALSE);
  833.         return HXR_FAIL;
  834.     }
  835.     FILTER_OUT_UNSUPPORTED_FORMATS;
  836.     if (!Compatible(pImg) || !SameSize(pImg))
  837.     {
  838.         HX_ASSERT(FALSE);
  839.         return HXR_FAIL;
  840.     }
  841.     Copy32((UINT32*) pImg->m_pImageBuffer, (UINT32*) m_pImageBuffer,
  842.             pImg->m_lRowJump >> 2,         m_lRowJump >> 2,
  843.             pImg->m_bHasAlpha);
  844.     return HXR_OK;
  845. }
  846. HX_RESULT PXImage::CopyFromTransparent32(PXImage* pImg)
  847. {
  848.     HX_RESULT retVal = HXR_OK;
  849.     if (pImg)
  850.     {
  851.         if (m_bInitialized && pImg->m_bInitialized)
  852.         {
  853.             if (m_cBitmapInfo.biBitCount          == 32      &&
  854.                 pImg->m_cBitmapInfo.biBitCount    == 32      &&
  855.                 CompressionSupported()                       &&
  856.                 pImg->CompressionSupported())
  857.             {
  858.                 if (Compatible(pImg) && SameSize(pImg))
  859.                 {
  860.                     CopyTransparent32((UINT32*) pImg->m_pImageBuffer,
  861.                                       (UINT32*) m_pImageBuffer,
  862.                                       pImg->m_lRowJump >> 2,
  863.                                       m_lRowJump >> 2);
  864.                 }
  865.                 else
  866.                 {
  867.                     retVal = HXR_INVALID_PARAMETER;
  868.                 }
  869.             }
  870.             else
  871.             {
  872.                 retVal = HXR_FAIL;
  873.             }
  874.         }
  875.         else
  876.         {
  877.             retVal = HXR_NOT_INITIALIZED;
  878.         }
  879.     }
  880.     else
  881.     {
  882.         retVal = HXR_INVALID_PARAMETER;
  883.     }
  884.     return retVal;
  885. }
  886. HX_RESULT PXImage::CopyFromAlpha32(PXImage* pImg, BYTE* pLUT)
  887. {
  888.     HX_RESULT retVal = HXR_FAIL;
  889.     if (pImg)
  890.     {
  891.         if (m_bInitialized && pImg->m_bInitialized)
  892.         {
  893.             if (m_cBitmapInfo.biBitCount          == 32      &&
  894.                 pImg->m_cBitmapInfo.biBitCount    == 32      &&
  895.                 CompressionSupported()                       &&
  896.                 pImg->CompressionSupported())
  897.             {
  898.                 if (Compatible(pImg) && SameSize(pImg))
  899.                 {
  900.                     CopyAlpha32((UINT32*) pImg->m_pImageBuffer,
  901.                                 (UINT32*) m_pImageBuffer,
  902.                                 pImg->m_lRowJump >> 2,
  903.                                 m_lRowJump >> 2,
  904.                                 pLUT);
  905.                     retVal = HXR_OK;
  906.                 }
  907.             }
  908.         }
  909.     }
  910.     return retVal;
  911. }
  912. HX_RESULT PXImage::CopyTo(PXImage* pImg)
  913. {
  914.     if (!pImg || !m_bInitialized)
  915.     {
  916.         HX_ASSERT(FALSE);
  917.         return HXR_FAIL;
  918.     }
  919.     FILTER_OUT_UNSUPPORTED_FORMATS;
  920.     if (!Compatible(pImg) || !SameSize(pImg))
  921.     {
  922.         HX_ASSERT(FALSE);
  923.         return HXR_FAIL;
  924.     }
  925.     Copy32((UINT32*) m_pImageBuffer, (UINT32*) pImg->m_pImageBuffer,
  926.            m_lRowJump >> 2,          pImg->m_lRowJump >> 2,
  927.            m_bHasAlpha);
  928.     return HXR_OK;
  929. }
  930. HX_RESULT PXImage::CopyToTransparent32(PXImage* pImg)
  931. {
  932.     HX_RESULT retVal = HXR_OK;
  933.     if (pImg)
  934.     {
  935.         if (m_bInitialized && pImg->m_bInitialized)
  936.         {
  937.             if (m_cBitmapInfo.biBitCount          == 32      &&
  938.                 pImg->m_cBitmapInfo.biBitCount    == 32      &&
  939.                 CompressionSupported()                       &&
  940.                 pImg->CompressionSupported())
  941.             {
  942.                 if (Compatible(pImg) && SameSize(pImg))
  943.                 {
  944.                     CopyTransparent32((UINT32*) m_pImageBuffer,
  945.                                       (UINT32*) pImg->m_pImageBuffer,
  946.                                       m_lRowJump >> 2,
  947.                                       pImg->m_lRowJump >> 2);
  948.                 }
  949.                 else
  950.                 {
  951.                     retVal = HXR_INVALID_PARAMETER;
  952.                 }
  953.             }
  954.             else
  955.             {
  956.                 retVal = HXR_FAIL;
  957.             }
  958.         }
  959.         else
  960.         {
  961.             retVal = HXR_NOT_INITIALIZED;
  962.         }
  963.     }
  964.     else
  965.     {
  966.         retVal = HXR_INVALID_PARAMETER;
  967.     }
  968.     return retVal;
  969. }
  970. HX_RESULT PXImage::CopyToAlpha32(PXImage* pImg, BYTE* pLUT)
  971. {
  972.     HX_RESULT retVal = HXR_FAIL;
  973.     if (pImg)
  974.     {
  975.         if (m_bInitialized && pImg->m_bInitialized)
  976.         {
  977.             if (m_cBitmapInfo.biBitCount          == 32      &&
  978.                 pImg->m_cBitmapInfo.biBitCount    == 32      &&
  979.                 CompressionSupported()                       &&
  980.                 pImg->CompressionSupported())
  981.             {
  982.                 if (Compatible(pImg) && SameSize(pImg))
  983.                 {
  984.                     CopyAlpha32((UINT32*) m_pImageBuffer,
  985.                                 (UINT32*) pImg->m_pImageBuffer,
  986.                                 m_lRowJump >> 2,
  987.                                 pImg->m_lRowJump >> 2,
  988.                                 pLUT);
  989.                     retVal = HXR_OK;
  990.                 }
  991.             }
  992.         }
  993.     }
  994.     return retVal;
  995. }
  996. HX_RESULT PXImage::FlipFrom(PXImage* pImg, BOOL bVerticalAxis)
  997. {
  998.     HX_RESULT retVal = HXR_OK;
  999.     if (pImg)
  1000.     {
  1001.         if (m_bInitialized)
  1002.         {
  1003.             if (Compatible(pImg) && SameSize(pImg))
  1004.             {
  1005.                 if (bVerticalAxis)
  1006.                 {
  1007.                     VertAxisFlip32((UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  1008.                                    pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2,
  1009.                                    (UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  1010.                                    m_lSubImageHeight,              m_lRowJump >> 2);
  1011.                 }
  1012.                 else
  1013.                 {
  1014.                     HorzAxisFlip32((UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  1015.                                    pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2,
  1016.                                    (UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  1017.                                    m_lSubImageHeight,              m_lRowJump >> 2);
  1018.                 }
  1019.             }
  1020.             else
  1021.             {
  1022.                 retVal = HXR_FAIL;
  1023.             }
  1024.         }
  1025.         else
  1026.         {
  1027.             retVal = HXR_NOT_INITIALIZED;
  1028.         }
  1029.     }
  1030.     else
  1031.     {
  1032.         retVal = HXR_INVALID_PARAMETER;
  1033.     }
  1034.     return retVal;
  1035. }
  1036. HX_RESULT PXImage::FlipTo(PXImage* pImg, BOOL bVerticalAxis)
  1037. {
  1038.     HX_RESULT retVal = HXR_OK;
  1039.     if (pImg)
  1040.     {
  1041.         if (m_bInitialized)
  1042.         {
  1043.             if (Compatible(pImg) && SameSize(pImg))
  1044.             {
  1045.                 if (bVerticalAxis)
  1046.                 {
  1047.                     VertAxisFlip32((UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  1048.                                    m_lSubImageHeight,              m_lRowJump >> 2,
  1049.                                    (UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  1050.                                    pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2);
  1051.                 }
  1052.                 else
  1053.                 {
  1054.                     HorzAxisFlip32((UINT32*) m_pImageBuffer,       m_lSubImageWidth,
  1055.                                    m_lSubImageHeight,              m_lRowJump >> 2,
  1056.                                    (UINT32*) pImg->m_pImageBuffer, pImg->m_lSubImageWidth,
  1057.                                    pImg->m_lSubImageHeight,        pImg->m_lRowJump >> 2);
  1058.                 }
  1059.             }
  1060.             else
  1061.             {
  1062.                 retVal = HXR_FAIL;
  1063.             }
  1064.         }
  1065.         else
  1066.         {
  1067.             retVal = HXR_NOT_INITIALIZED;
  1068.         }
  1069.     }
  1070.     else
  1071.     {
  1072.         retVal = HXR_INVALID_PARAMETER;
  1073.     }
  1074.     return retVal;
  1075. }
  1076. HX_RESULT PXImage::Wipe(PXImage* pStartImg, PXImage* pEndImg, UINT32 ulType,
  1077.                         UINT32 ulDirection, UINT32 ulTime, UINT32 ulDuration)
  1078. {
  1079.     HX_RESULT retVal = HXR_OK;
  1080.     if (pStartImg                                       &&
  1081.         pEndImg                                         &&
  1082.         (ulType == PXEffect::kWipeTypeNormal         ||
  1083.          ulType == PXEffect::kWipeTypePush)             &&
  1084.         (ulDirection == PXEffect::kWipeDirectionUp   ||
  1085.          ulDirection == PXEffect::kWipeDirectionDown ||
  1086.          ulDirection == PXEffect::kWipeDirectionLeft ||
  1087.          ulDirection == PXEffect::kWipeDirectionRight)  &&
  1088.         ulTime     > 0                                  &&
  1089.         ulTime     < ulDuration                         &&
  1090.         ulDuration > 0)
  1091.     {
  1092.         if (m_bInitialized)
  1093.         {
  1094.             if (Compatible(pStartImg) && SameSize(pStartImg) &&
  1095.                 Compatible(pEndImg)   && SameSize(pEndImg))
  1096.             {
  1097.                 // Set up src and dst rectangles for both
  1098.                 // the start and end images
  1099.                 PXRect cStartSrc;
  1100.                 PXRect cStartDst;
  1101.                 PXRect cEndSrc;
  1102.                 PXRect cEndDst;
  1103.                 UINT32 ulW = pStartImg->GetWidth();
  1104.                 UINT32 ulH = pStartImg->GetHeight();
  1105.                 if (ulType == PXEffect::kWipeTypeNormal)
  1106.                 {
  1107.                     if (ulDirection == PXEffect::kWipeDirectionUp)
  1108.                     {
  1109.                         UINT32 ulY = (ulDuration - ulTime) * ulH / ulDuration;
  1110.                         cStartSrc.Set(0, 0, ulW, ulY);
  1111.                         cEndSrc.Set(0, ulY, ulW, ulH - ulY);
  1112.                     }
  1113.                     else if (ulDirection == PXEffect::kWipeDirectionDown)
  1114.                     {
  1115.                         UINT32 ulY = ulTime * ulH / ulDuration;
  1116.                         cStartSrc.Set(0, ulY, ulW, ulH - ulY);
  1117.                         cEndSrc.Set(0, 0, ulW, ulY);
  1118.                     }
  1119.                     else if (ulDirection == PXEffect::kWipeDirectionLeft)
  1120.                     {
  1121.                         UINT32 ulX = (ulDuration - ulTime) * ulW / ulDuration;
  1122.                         cStartSrc.Set(0, 0, ulX, ulH);
  1123.                         cEndSrc.Set(ulX, 0, ulW - ulX, ulH);
  1124.                     }
  1125.                     else if (ulDirection == PXEffect::kWipeDirectionRight)
  1126.                     {
  1127.                         UINT32 ulX = ulTime * ulW / ulDuration;
  1128.                         cStartSrc.Set(ulX, 0, ulW - ulX, ulH);
  1129.                         cEndSrc.Set(0, 0, ulX, ulH);
  1130.                     }
  1131.                     cStartDst = cStartSrc;
  1132.                     cEndDst   = cEndSrc;
  1133.                 }
  1134.                 else
  1135.                 {
  1136.                     if (ulDirection == PXEffect::kWipeDirectionUp)
  1137.                     {
  1138.                         UINT32 ulY = (ulDuration - ulTime) * ulH / ulDuration;
  1139.                         cStartSrc.Set(0, ulH - ulY, ulW, ulY);
  1140.                         cStartDst.Set(0, 0, ulW, ulY);
  1141.                         cEndSrc.Set(0, 0, ulW, ulH - ulY);
  1142.                         cEndDst.Set(0, ulY, ulW, ulH - ulY);
  1143.                     }
  1144.                     else if (ulDirection == PXEffect::kWipeDirectionDown)
  1145.                     {
  1146.                         UINT32 ulY = ulTime * ulH / ulDuration;
  1147.                         cStartSrc.Set(0, 0, ulW, ulH - ulY);
  1148.                         cStartDst.Set(0, ulY, ulW, ulH - ulY);
  1149.                         cEndSrc.Set(0, ulH - ulY, ulW, ulY);
  1150.                         cEndDst.Set(0, 0, ulW, ulY);
  1151.                     }
  1152.                     else if (ulDirection == PXEffect::kWipeDirectionLeft)
  1153.                     {
  1154.                         UINT32 ulX = (ulDuration - ulTime) * ulW / ulDuration;
  1155.                         cStartSrc.Set(ulW - ulX, 0, ulX, ulH);
  1156.                         cStartDst.Set(0, 0, ulX, ulH);
  1157.                         cEndSrc.Set(0, 0, ulW - ulX, ulH);
  1158.                         cEndDst.Set(ulX, 0, ulW - ulX, ulH);
  1159.                     }
  1160.                     else if (ulDirection == PXEffect::kWipeDirectionRight)
  1161.                     {
  1162.                         UINT32 ulX = ulTime * ulW / ulDuration;
  1163.                         cStartSrc.Set(0, 0, ulW - ulX, ulH);
  1164.                         cStartDst.Set(ulX, 0, ulW - ulX, ulH);
  1165.                         cEndSrc.Set(ulW - ulX, 0,ulX, ulH);
  1166.                         cEndDst.Set(0, 0, ulX, ulH);
  1167.                     }
  1168.                 }
  1169.                 // Copy from the start image
  1170.                 if (cStartSrc.GetWidth() > 0 && cStartSrc.GetHeight() > 0)
  1171.                 {
  1172.                     // Create the start src image
  1173.                     PXImage cStartSrcImg;
  1174.                     retVal = cStartSrcImg.CreateSubImage(pStartImg, cStartSrc);
  1175.                     if (SUCCEEDED(retVal))
  1176.                     {
  1177.                         // Create the start dst image
  1178.                         PXImage cStartDstImg;
  1179.                         retVal = cStartDstImg.CreateSubImage(this, cStartDst);
  1180.                         if (SUCCEEDED(retVal))
  1181.                         {
  1182.                             // Now copy the start image
  1183.                             retVal = cStartDstImg.CopyFrom(&cStartSrcImg);
  1184.                         }
  1185.                     }
  1186.                 }
  1187.                 if (SUCCEEDED(retVal))
  1188.                 {
  1189.                     // Copy from the dst image
  1190.                     if (cEndSrc.GetWidth() > 0 && cEndSrc.GetHeight() > 0)
  1191.                     {
  1192.                         // Create the end src image
  1193.                         PXImage cEndSrcImg;
  1194.                         retVal = cEndSrcImg.CreateSubImage(pEndImg, cEndSrc);
  1195.                         if (SUCCEEDED(retVal))
  1196.                         {
  1197.                             // Create the end dst image
  1198.                             PXImage cEndDstImg;
  1199.                             retVal = cEndDstImg.CreateSubImage(this, cEndDst);
  1200.                             if (SUCCEEDED(retVal))
  1201.                             {
  1202.                                 // Now copy the end image
  1203.                                 retVal = cEndDstImg.CopyFrom(&cEndSrcImg);
  1204.                             }
  1205.                         }
  1206.                     }
  1207.                 }
  1208.             }
  1209.             else
  1210.             {
  1211.                 retVal = HXR_FAIL;
  1212.             }
  1213.         }
  1214.         else
  1215.         {
  1216.             retVal = HXR_NOT_INITIALIZED;
  1217.         }
  1218.     }
  1219.     else
  1220.     {
  1221.         retVal = HXR_INVALID_PARAMETER;
  1222.     }
  1223.     return retVal;
  1224. }
  1225. HX_RESULT PXImage::RecursiveWipe(PXImage* pEndImage, UINT32 ulType, UINT32 ulDirection, UINT32 ulLastTime,
  1226.                                  UINT32 ulTime, UINT32 ulDuration, PXRect& rDamageRect)
  1227. {
  1228.     HX_RESULT retVal = HXR_OK;
  1229.     if (pEndImage                                       &&
  1230.         (ulType == PXEffect::kWipeTypeNormal         ||
  1231.          ulType == PXEffect::kWipeTypePush)             &&
  1232.         (ulDirection == PXEffect::kWipeDirectionUp   ||
  1233.          ulDirection == PXEffect::kWipeDirectionDown ||
  1234.          ulDirection == PXEffect::kWipeDirectionLeft ||
  1235.          ulDirection == PXEffect::kWipeDirectionRight)  &&
  1236.         ulTime     > 0                                  &&
  1237.         ulTime     < ulDuration                         &&
  1238.         ulTime     > ulLastTime                         &&
  1239.         ulDuration > 0)
  1240.     {
  1241.         if (m_bInitialized)
  1242.         {
  1243.             if (Compatible(pEndImage) && SameSize(pEndImage))
  1244.             {
  1245.                 // Set up src and dst rectangles for both
  1246.                 // the start and end images
  1247.                 UINT32 ulW = pEndImage->GetWidth();
  1248.                 UINT32 ulH = pEndImage->GetHeight();
  1249.                 if (ulType == PXEffect::kWipeTypeNormal)
  1250.                 {
  1251.                     PXRect cRect;
  1252.                     if (ulDirection == PXEffect::kWipeDirectionUp)
  1253.                     {
  1254.                         UINT32 ulY     = (ulDuration - ulTime) * ulH / ulDuration;
  1255.                         UINT32 ulLastY = (ulDuration - ulLastTime) * ulH / ulDuration;
  1256.                         cRect.Set(0, ulY, ulW, ulLastY - ulY);
  1257.                     }
  1258.                     else if (ulDirection == PXEffect::kWipeDirectionDown)
  1259.                     {
  1260.                         UINT32 ulY     = ulTime * ulH / ulDuration;
  1261.                         UINT32 ulLastY = ulLastTime * ulH / ulDuration;
  1262.                         cRect.Set(0, ulLastY, ulW, ulY - ulLastY);
  1263.                     }
  1264.                     else if (ulDirection == PXEffect::kWipeDirectionLeft)
  1265.                     {
  1266.                         UINT32 ulX     = (ulDuration - ulTime) * ulW / ulDuration;
  1267.                         UINT32 ulLastX = (ulDuration - ulLastTime) * ulW / ulDuration;
  1268.                         cRect.Set(ulX, 0, ulLastX - ulX, ulH);
  1269.                     }
  1270.                     else if (ulDirection == PXEffect::kWipeDirectionRight)
  1271.                     {
  1272.                         UINT32 ulX     = ulTime * ulW / ulDuration;
  1273.                         UINT32 ulLastX = ulLastTime * ulW / ulDuration;
  1274.                         cRect.Set(ulLastX, 0, ulX - ulLastX, ulH);
  1275.                     }
  1276.                     // Make sure that we have something to copy
  1277.                     if (cRect.GetWidth() > 0 && cRect.GetHeight() > 0)
  1278.                     {
  1279.                         // Set up the source image
  1280.                         PXImage cEndSrcImg;
  1281.                         retVal = cEndSrcImg.CreateSubImage(pEndImage, cRect);
  1282.                         if (SUCCEEDED(retVal))
  1283.                         {
  1284.                             // Set up the destination image
  1285.                             PXImage cEndDstImg;
  1286.                             retVal = cEndDstImg.CreateSubImage(this, cRect);
  1287.                             if (SUCCEEDED(retVal))
  1288.                             {
  1289.                                 retVal = cEndDstImg.CopyFrom(&cEndSrcImg);
  1290.                                 if (SUCCEEDED(retVal))
  1291.                                 {
  1292.                                     rDamageRect = cRect;
  1293.                                 }
  1294.                             }
  1295.                         }
  1296.                     }
  1297.                 }
  1298.                 else
  1299.                 {
  1300.                     PXRect cIntraSrcRect;
  1301.                     PXRect cIntraDstRect;
  1302.                     PXRect cEndSrcRect;
  1303.                     PXRect cEndDstRect;
  1304.                     if (ulDirection == PXEffect::kWipeDirectionUp)
  1305.                     {
  1306.                         UINT32 ulY     = (ulDuration - ulTime) * ulH / ulDuration;
  1307.                         UINT32 ulLastY = (ulDuration - ulLastTime) * ulH / ulDuration;
  1308.                         UINT32 ulYDiff = ulLastY - ulY;
  1309.                         cIntraSrcRect.Set(0, ulYDiff, ulW, ulH - ulYDiff);
  1310.                         cIntraDstRect.Set(0, 0, ulW, ulH - ulYDiff);
  1311.                         cEndSrcRect.Set(0, ulH - ulLastY, ulW, ulYDiff);
  1312.                         cEndDstRect.Set(0, ulH - ulYDiff, ulW, ulYDiff);
  1313.                     }
  1314.                     else if (ulDirection == PXEffect::kWipeDirectionDown)
  1315.                     {
  1316.                         UINT32 ulY     = ulTime * ulH / ulDuration;
  1317.                         UINT32 ulLastY = ulLastTime * ulH / ulDuration;
  1318.                         UINT32 ulYDiff = ulY - ulLastY;
  1319.                         cIntraSrcRect.Set(0, 0, ulW, ulH - ulYDiff);
  1320.                         cIntraDstRect.Set(0, ulYDiff, ulW, ulH - ulYDiff);
  1321.                         cEndSrcRect.Set(0, ulH - ulY, ulW, ulYDiff);
  1322.                         cEndDstRect.Set(0, 0, ulW, ulYDiff);
  1323.                     }
  1324.                     else if (ulDirection == PXEffect::kWipeDirectionLeft)
  1325.                     {
  1326.                         UINT32 ulX     = (ulDuration - ulTime) * ulW / ulDuration;
  1327.                         UINT32 ulLastX = (ulDuration - ulLastTime) * ulW / ulDuration;
  1328.                         UINT32 ulXDiff = ulLastX - ulX;
  1329.                         cIntraSrcRect.Set(ulXDiff, 0, ulW - ulXDiff, ulH);
  1330.                         cIntraDstRect.Set(0, 0, ulW - ulXDiff, ulH);
  1331.                         cEndSrcRect.Set(ulW - ulLastX, 0, ulXDiff, ulH);
  1332.                         cEndDstRect.Set(ulW - ulXDiff, 0, ulXDiff, ulH);
  1333.                     }
  1334.                     else if (ulDirection == PXEffect::kWipeDirectionRight)
  1335.                     {
  1336.                         UINT32 ulX     = ulTime * ulW / ulDuration;
  1337.                         UINT32 ulLastX = ulLastTime * ulW / ulDuration;
  1338.                         UINT32 ulXDiff = ulX - ulLastX;
  1339.                         cIntraSrcRect.Set(0, 0, ulW - ulXDiff, ulH);
  1340.                         cIntraDstRect.Set(ulXDiff, 0, ulW - ulXDiff, ulH);
  1341.                         cEndSrcRect.Set(ulW - ulX, 0, ulXDiff, ulH);
  1342.                         cEndDstRect.Set(0, 0, ulXDiff, ulH);
  1343.                     }
  1344.                     // Make sure we have something to copy
  1345.                     if (cIntraSrcRect.GetWidth() == 0 || cIntraSrcRect.GetHeight() == 0)
  1346.                     {
  1347.                         // This is all end image, so just do a copy
  1348.                         retVal = CopyFrom(pEndImage);
  1349.                     }
  1350.                     else if (cEndSrcRect.GetWidth() > 0 && cEndSrcRect.GetHeight() > 0)
  1351.                     {
  1352.                         // First we do an intra copy to copy the part of 
  1353.                         // the image which is already there.
  1354.                         retVal = IntraCopy(cIntraSrcRect, cIntraDstRect);
  1355.                         if (SUCCEEDED(retVal))
  1356.                         {
  1357.                             PXImage cEndSrcImg;
  1358.                             retVal = cEndSrcImg.CreateSubImage(pEndImage, cEndSrcRect);
  1359.                             if (SUCCEEDED(retVal))
  1360.                             {
  1361.                                 PXImage cEndDstImg;
  1362.                                 retVal = cEndDstImg.CreateSubImage(this, cEndDstRect);
  1363.                                 if (SUCCEEDED(retVal))
  1364.                                 {
  1365.                                     retVal = cEndDstImg.CopyFrom(&cEndSrcImg);
  1366.                                     if (SUCCEEDED(retVal))
  1367.                                     {
  1368.                                         rDamageRect.Set(0, 0, ulW, ulH);
  1369.                                     }
  1370.                                 }
  1371.                             }
  1372.                         }
  1373.                     }
  1374.                 }
  1375.             }
  1376.             else
  1377.             {
  1378.                 retVal = HXR_FAIL;
  1379.             }
  1380.         }
  1381.         else
  1382.         {
  1383.             retVal = HXR_NOT_INITIALIZED;
  1384.         }
  1385.     }
  1386.     else
  1387.     {
  1388.         retVal = HXR_INVALID_PARAMETER;
  1389.     }
  1390.     return retVal;
  1391. }
  1392. HX_RESULT PXImage::IntraCopy(const PXRect& rSrcRect, const PXRect& rDstRect)
  1393. {
  1394.     HX_RESULT retVal = HXR_OK;
  1395.     if (rSrcRect.GetWidth()  == rDstRect.GetWidth()        &&
  1396.         rSrcRect.GetHeight() == rDstRect.GetHeight()       &&
  1397.         rSrcRect.GetWidth()  <= (UINT32) m_lSubImageWidth  &&
  1398.         rSrcRect.GetHeight() <= (UINT32) m_lSubImageHeight &&
  1399.         rSrcRect.GetX() + rSrcRect.GetWidth()  <= (UINT32) m_lSubImageWidth  &&
  1400.         rSrcRect.GetY() + rSrcRect.GetHeight() <= (UINT32) m_lSubImageHeight &&
  1401.         rDstRect.GetX() + rDstRect.GetWidth()  <= (UINT32) m_lSubImageWidth  &&
  1402.         rDstRect.GetY() + rDstRect.GetHeight() <= (UINT32) m_lSubImageHeight)
  1403.     {
  1404.         // Make sure this is not a null copy
  1405.         if (rSrcRect.GetX() != rDstRect.GetX() ||
  1406.             rSrcRect.GetY() != rDstRect.GetY())
  1407.         {
  1408.             BOOL bUpCopy = (rDstRect.GetY() <= rSrcRect.GetY() ? TRUE : FALSE);
  1409. //            if (m_bRowsInverted)
  1410. //            {
  1411. //                // If we are row-inverted, then we reverse whatever, operation
  1412. //                // we were going to do.
  1413. //                bUpCopy = (bUpCopy ? FALSE : TRUE);
  1414. //            }
  1415.             if (rDstRect.GetX() <= rSrcRect.GetX())
  1416.             {
  1417.                 // This is a left-ward copy
  1418.                 if (bUpCopy)
  1419.                 {
  1420.                     // This is an up-left copy, so we do L->R, T->B
  1421.                     UINT32* pSrcRow = (UINT32*) GetPixel(rSrcRect.GetX(), rSrcRect.GetY());
  1422.                     UINT32* pDstRow = (UINT32*) GetPixel(rDstRect.GetX(), rDstRect.GetY());
  1423.                     INT32   lJump   = m_lRowJump >> 2;
  1424.                     for (UINT32 ulY = rSrcRect.GetHeight(); ulY; ulY--)
  1425.                     {
  1426.                         UINT32* pSrcPixel = pSrcRow;
  1427.                         UINT32* pDstPixel = pDstRow;
  1428.                         for (UINT32 ulX = rSrcRect.GetWidth(); ulX; ulX--)
  1429.                         {
  1430.                             *pDstPixel++ = *pSrcPixel++;
  1431.                         }
  1432.                         pSrcRow += lJump;
  1433.                         pDstRow += lJump;
  1434.                     }
  1435.                 }
  1436.                 else
  1437.                 {
  1438.                     // This is a down-left copy, so we do L->R, B->T
  1439.                     UINT32* pSrcRow = (UINT32*) GetPixel(rSrcRect.GetX(), rSrcRect.GetY() + rSrcRect.GetHeight() - 1);
  1440.                     UINT32* pDstRow = (UINT32*) GetPixel(rDstRect.GetX(), rDstRect.GetY() + rDstRect.GetHeight() - 1);
  1441.                     INT32   lJump   = m_lRowJump >> 2;
  1442.                     for (UINT32 ulY = rSrcRect.GetHeight(); ulY; ulY--)
  1443.                     {
  1444.                         UINT32* pSrcPixel = pSrcRow;
  1445.                         UINT32* pDstPixel = pDstRow;
  1446.                         for (UINT32 ulX = rSrcRect.GetWidth(); ulX; ulX--)
  1447.                         {
  1448.                             *pDstPixel++ = *pSrcPixel++;
  1449.                         }
  1450.                         pSrcRow -= lJump;
  1451.                         pDstRow -= lJump;
  1452.                     }
  1453.                 }
  1454.             }
  1455.             else
  1456.             {
  1457.                 // This is a right-ward copy
  1458.                 if (bUpCopy)
  1459.                 {
  1460.                     // This is an up-right copy, so we do R->L, T->B
  1461.                     UINT32* pSrcRow = (UINT32*) GetPixel(rSrcRect.GetX() + rSrcRect.GetWidth() - 1, rSrcRect.GetY());
  1462.                     UINT32* pDstRow = (UINT32*) GetPixel(rDstRect.GetX() + rDstRect.GetWidth() - 1, rDstRect.GetY());
  1463.                     INT32   lJump   = m_lRowJump >> 2;
  1464.                     for (UINT32 ulY = rSrcRect.GetHeight(); ulY; ulY--)
  1465.                     {
  1466.                         UINT32* pSrcPixel = pSrcRow;
  1467.                         UINT32* pDstPixel = pDstRow;
  1468.                         for (UINT32 ulX = rSrcRect.GetWidth(); ulX; ulX--)
  1469.                         {
  1470.                             *pDstPixel-- = *pSrcPixel--;
  1471.                         }
  1472.                         pSrcRow += lJump;
  1473.                         pDstRow += lJump;
  1474.                     }
  1475.                 }
  1476.                 else
  1477.                 {
  1478.                     // This is a down-right copy, so we do R->L, B->T
  1479.                     UINT32* pSrcRow = (UINT32*) GetPixel(rSrcRect.GetX() + rSrcRect.GetWidth()  - 1,
  1480.                                                          rSrcRect.GetY() + rSrcRect.GetHeight() - 1);
  1481.                     UINT32* pDstRow = (UINT32*) GetPixel(rDstRect.GetX() + rDstRect.GetWidth()  - 1,
  1482.                                                          rDstRect.GetY() + rDstRect.GetHeight() - 1);
  1483.                     INT32   lJump   = m_lRowJump >> 2;
  1484.                     for (UINT32 ulY = rSrcRect.GetHeight(); ulY; ulY--)
  1485.                     {
  1486.                         UINT32* pSrcPixel = pSrcRow;
  1487.                         UINT32* pDstPixel = pDstRow;
  1488.                         for (UINT32 ulX = rSrcRect.GetWidth(); ulX; ulX--)
  1489.                         {
  1490.                             *pDstPixel-- = *pSrcPixel--;
  1491.                         }
  1492.                         pSrcRow -= lJump;
  1493.                         pDstRow -= lJump;
  1494.                     }
  1495.                 }
  1496.             }
  1497.         }
  1498.     }
  1499.     else
  1500.     {
  1501.         retVal = HXR_INVALID_PARAMETER;
  1502.     }
  1503.     return retVal;
  1504. }
  1505. HX_RESULT PXImage::DrawToHXSurface(IHXVideoSurface* pSurface, HXxRect& rDstRect)
  1506. {
  1507.     if (!m_bInitialized || !pSurface)
  1508.     {
  1509.         HX_ASSERT(FALSE);
  1510.         return HXR_FAIL;
  1511.     }
  1512.     // If the image has alpha, then we need to
  1513.     // blt a different colorspace
  1514.     UINT32 ulFormat = m_cBitmapInfo.biCompression;
  1515.     if (m_bHasAlpha)
  1516.     {
  1517.         m_cBitmapInfo.biCompression = HX_ARGB;
  1518.     }
  1519.     // Do the blt
  1520.     pSurface->AddRef();
  1521.     HX_RESULT retVal = pSurface->Blt(m_pImageStore->GetBuffer(), &m_cBitmapInfo, rDstRect, m_cSubImageRect);
  1522.     pSurface->Release();
  1523.     // Restore the old colorspace
  1524.     if (m_bHasAlpha)
  1525.     {
  1526.         m_cBitmapInfo.biCompression = ulFormat;
  1527.     }
  1528.     return retVal;
  1529. }
  1530. HX_RESULT PXImage::DrawToHXSurface(IHXVideoSurface* pSurface, HXxRect& rSrcRect, HXxRect& rDstRect)
  1531. {
  1532.     HX_RESULT retVal = HXR_OK;
  1533.     if (pSurface)
  1534.     {
  1535.         if (m_bInitialized)
  1536.         {
  1537.             // If the image has alpha, then we need to
  1538.             // blt a different colorspace
  1539.             UINT32 ulFormat = m_cBitmapInfo.biCompression;
  1540.             if (m_bHasAlpha)
  1541.             {
  1542.                 m_cBitmapInfo.biCompression = HX_ARGB;
  1543.             }
  1544.             // Do the blt
  1545.             pSurface->AddRef();
  1546.             retVal = pSurface->Blt(m_pImageStore->GetBuffer(), &m_cBitmapInfo, rDstRect, rSrcRect);
  1547.             pSurface->Release();
  1548.             // Restore the old colorspace
  1549.             if (m_bHasAlpha)
  1550.             {
  1551.                 m_cBitmapInfo.biCompression = ulFormat;
  1552.             }
  1553.         }
  1554.         else
  1555.         {
  1556.             retVal = HXR_UNEXPECTED;
  1557.         }
  1558.     }
  1559.     else
  1560.     {
  1561.         retVal = HXR_INVALID_PARAMETER;
  1562.     }
  1563.     return retVal;
  1564. }
  1565. HX_RESULT PXImage::GetPixel(INT32 lX, INT32 lY, BYTE** ppPixel)
  1566. {
  1567.     *ppPixel = GetPixel(lX, lY);
  1568.     return (*ppPixel ? HXR_OK : HXR_FAIL);
  1569. }
  1570. BYTE* PXImage::GetPixel(INT32 lX, INT32 lY)
  1571. {
  1572.     BYTE* pRet = NULL;
  1573.     if (m_bInitialized)
  1574.     {
  1575.         if (lX >= 0 && lX < m_lSubImageWidth &&
  1576.             lY >= 0 && lY < m_lSubImageHeight)
  1577.         {
  1578.             pRet = m_pImageBuffer + lY * m_lRowJump + lX * m_ulBytesPerPixel;
  1579.         }
  1580.     }
  1581.     return pRet;
  1582. }
  1583. HX_RESULT PXImage::GetImageStore(IHXBuffer** ppBuffer)
  1584. {
  1585.     HX_RESULT retVal = HXR_OK;
  1586.     if (ppBuffer && m_bInitialized)
  1587.     {
  1588.         m_pImageStore->AddRef();
  1589.         *ppBuffer = m_pImageStore;
  1590.     }
  1591.     else
  1592.     {
  1593.         retVal = HXR_FAIL;
  1594.     }
  1595.     return retVal;
  1596. }
  1597. void PXImage::ConvertToRGBOrder(INT32 lScanline, BYTE* pLine)
  1598. {
  1599.     if (lScanline >= 0 && lScanline < m_lSubImageHeight)
  1600.     {
  1601.         UINT32* pPixel = (UINT32*) GetPixel(0, lScanline);
  1602.         for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1603.         {
  1604.             UINT32 ulPixel = *pPixel++;
  1605.             *pLine++ = (BYTE) ((ulPixel & 0x00FF0000) >> 16); // R
  1606.             *pLine++ = (BYTE) ((ulPixel & 0x0000FF00) >>  8); // G
  1607.             *pLine++ = (BYTE)  (ulPixel & 0x000000FF);        // B
  1608.         }
  1609.     }
  1610. }
  1611. void PXImage::ConvertFromRGBOrder(INT32 lScanline, BYTE* pLine)
  1612. {
  1613.     if (lScanline >= 0 && lScanline < m_lSubImageHeight)
  1614.     {
  1615.         UINT32* pPixel = (UINT32*) GetPixel(0, lScanline);
  1616.         for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1617.         {
  1618.             UINT32 ulRed   = *pLine++;
  1619.             UINT32 ulGreen = *pLine++;
  1620.             UINT32 ulBlue  = *pLine++;
  1621.             *pPixel++      = (ulRed << 16) | (ulGreen << 8) | ulBlue;
  1622.         }
  1623.     }
  1624. }
  1625. void PXImage::GetSubRect(PXRect& rRect) const
  1626. {
  1627.     rRect.Set(m_cSubImageRect.left,
  1628.               m_cSubImageRect.top,
  1629.               HXxRECT_WIDTH(m_cSubImageRect),
  1630.               HXxRECT_HEIGHT(m_cSubImageRect));
  1631. }
  1632. BOOL PXImage::SameSize(PXImage* pImg) const
  1633. {
  1634.     if (pImg                                         &&
  1635.         m_lSubImageWidth  == pImg->m_lSubImageWidth  &&
  1636.         m_lSubImageHeight == pImg->m_lSubImageHeight)
  1637.     {
  1638.         return TRUE;
  1639.     }
  1640.     else
  1641.     {
  1642.         return FALSE;
  1643.     }
  1644. }
  1645. BOOL PXImage::Compatible(PXImage* pImg) const
  1646. {
  1647.     if (pImg                                                          &&
  1648.         m_cBitmapInfo.biBitCount    == pImg->m_cBitmapInfo.biBitCount &&
  1649.         m_cBitmapInfo.biCompression == pImg->m_cBitmapInfo.biCompression)
  1650.     {
  1651.         return TRUE;
  1652.     }
  1653.     else
  1654.     {
  1655.         return FALSE;
  1656.     }
  1657. }
  1658. void PXImage::Copy32(UINT32* pSrc, UINT32* pDst, INT32 lSrcJump, INT32 lDstJump, BOOL bUseAlpha)
  1659. {
  1660.     for (INT32 lY = m_lSubImageHeight; lY; lY--)
  1661.     {
  1662.         UINT32* pSrcPix = pSrc;
  1663.         UINT32* pDstPix = pDst;
  1664.         if (bUseAlpha)
  1665.         {
  1666.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1667.             {
  1668.                 UINT32 ulA = GETALPHA32(*pSrcPix);
  1669.                 ulA        = (ulA < 128 ? ulA : ulA + 1);
  1670.                 *pDstPix   = MAKE_RGB32(ALPHABLEND(GETRED32(*pDstPix),   GETRED32(*pSrcPix),   ulA),
  1671.                                         ALPHABLEND(GETGREEN32(*pDstPix), GETGREEN32(*pSrcPix), ulA),
  1672.                                         ALPHABLEND(GETBLUE32(*pDstPix),  GETBLUE32(*pSrcPix),  ulA));
  1673.                 pSrcPix++;
  1674.                 pDstPix++;
  1675.             }
  1676.         }
  1677.         else
  1678.         {
  1679.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1680.             {
  1681.                 *pDstPix++ = *pSrcPix++;
  1682.             }
  1683.         }
  1684.         pSrc += lSrcJump;
  1685.         pDst += lDstJump;
  1686.     }
  1687. }
  1688. void PXImage::CopyTransparent32(UINT32* pSrc, UINT32* pDst, INT32 lSrcJump, INT32 lDstJump)
  1689. {
  1690.     for (INT32 lY = m_lSubImageHeight; lY; lY--)
  1691.     {
  1692.         UINT32* pSrcPix = pSrc;
  1693.         UINT32* pDstPix = pDst;
  1694.         for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1695.         {
  1696.             if (!(*pSrcPix & 0xFF000000))
  1697.             {
  1698.                 *pDstPix = *pSrcPix;
  1699.             }
  1700.             pSrcPix++;
  1701.             pDstPix++;
  1702.         }
  1703.         pSrc += lSrcJump;
  1704.         pDst += lDstJump;
  1705.     }
  1706. }
  1707. void PXImage::CopyAlpha32(UINT32* pSrc, UINT32* pDst, INT32 lSrcJump, INT32 lDstJump, BYTE* pLUT)
  1708. {
  1709.     if (pLUT)
  1710.     {
  1711.         for (INT32 lY = m_lSubImageHeight; lY; lY--)
  1712.         {
  1713.             UINT32* pSrcPix = pSrc;
  1714.             UINT32* pDstPix = pDst;
  1715.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1716.             {
  1717.                 UINT32 ulAlpha = GETALPHA32(*pSrcPix);
  1718.                 BYTE*  pAlp    = &pLUT[ulAlpha << 8];
  1719.                 BYTE*  pInv    = &pLUT[(255 - ulAlpha) << 8];
  1720.                 *pDstPix       = MAKE_RGB32(pAlp[GETRED32(*pDstPix)]   + pInv[GETRED32(*pSrcPix)],
  1721.                                             pAlp[GETGREEN32(*pDstPix)] + pInv[GETGREEN32(*pSrcPix)],
  1722.                                             pAlp[GETBLUE32(*pDstPix)]  + pInv[GETBLUE32(*pSrcPix)]);
  1723.                 pSrcPix++;
  1724.                 pDstPix++;
  1725.             }
  1726.             pSrc += lSrcJump;
  1727.             pDst += lDstJump;
  1728.         }
  1729.     }
  1730.     else
  1731.     {
  1732.         for (INT32 lY = m_lSubImageHeight; lY; lY--)
  1733.         {
  1734.             UINT32* pSrcPix = pSrc;
  1735.             UINT32* pDstPix = pDst;
  1736.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1737.             {
  1738.                 UINT32 ulAlpha = GETALPHA32(*pSrcPix);
  1739.                 *pDstPix       = MAKE_RGB32(BLENDMULT(GETRED32(*pDstPix),   GETRED32(*pSrcPix),   ulAlpha),
  1740.                                             BLENDMULT(GETGREEN32(*pDstPix), GETGREEN32(*pSrcPix), ulAlpha),
  1741.                                             BLENDMULT(GETBLUE32(*pDstPix),  GETBLUE32(*pSrcPix),  ulAlpha));
  1742.                 pSrcPix++;
  1743.                 pDstPix++;
  1744.             }
  1745.             pSrc += lSrcJump;
  1746.             pDst += lDstJump;
  1747.         }
  1748.     }
  1749. }
  1750. HX_RESULT PXImage::ChangeSize32NN(UINT32* pSrc, INT32 lSrcW, INT32 lSrcH, INT32 lSrcJump,
  1751.                                   UINT32* pDst, INT32 lDstW, INT32 lDstH, INT32 lDstJump)
  1752. {
  1753.     // Allocate the divide LUT
  1754.     INT32* pSrcX = new INT32 [lDstW];
  1755.     if (!pSrcX)
  1756.     {
  1757.         return HXR_OUTOFMEMORY;
  1758.     }
  1759.     // Build the divide LUT
  1760.     INT32 lDstX;
  1761.     INT32 lDstWDiv2 = lDstW >> 1;
  1762.     for (lDstX = 0; lDstX < lDstW; lDstX++)
  1763.     {
  1764.         INT32 lSrcX = (lDstX * lSrcW + lDstWDiv2) / lDstW;
  1765.         if (lSrcX >= lSrcW)
  1766.         {
  1767.             lSrcX = lSrcW - 1;
  1768.         }
  1769.         pSrcX[lDstX] = lSrcX;
  1770.     }
  1771.     // Now run through the output image, doing nearest neighbor resampling
  1772.     INT32   lSrcY     = 0;
  1773.     INT32   lDstY     = 0;
  1774.     INT32   lLastSrcY = -1;
  1775.     UINT32* pDstRow   = pDst;
  1776.     INT32   lDstHDiv2 = lDstH >> 1;
  1777.     for (lDstY = 0; lDstY < lDstH; lDstY++)
  1778.     {
  1779.         lSrcY = (lDstY * lSrcH + lDstHDiv2) / lDstH;
  1780.         if (lSrcY >= lSrcH)
  1781.         {
  1782.             lSrcY = lSrcH - 1;
  1783.         }
  1784.         UINT32* pSrcRow = pSrc + lSrcY * lSrcJump;
  1785.         if (lSrcY == lLastSrcY)
  1786.         {
  1787.             // We're getting this resampled row from the same source row,
  1788.             // so just copy the last row.
  1789.             UINT32* pDstLastRow = pDstRow - lDstJump;
  1790.             for (lDstX = 0; lDstX < lDstW; lDstX++)
  1791.             {
  1792.                 pDstRow[lDstX] = pDstLastRow[lDstX];
  1793.             }
  1794.         }
  1795.         else
  1796.         {
  1797.             // New row, we must do the work
  1798.             for (lDstX = 0; lDstX < lDstW; lDstX++)
  1799.             {
  1800.                 pDstRow[lDstX] = pSrcRow[pSrcX[lDstX]];
  1801.             }
  1802.         }
  1803.         lLastSrcY = lSrcY;
  1804.         pDstRow  += lDstJump;
  1805.     }
  1806.     HX_VECTOR_DELETE(pSrcX);
  1807.     return HXR_OK;
  1808. }
  1809. HX_RESULT PXImage::ChangeSize32NNTransparent(UINT32* pSrc, INT32 lSrcW, INT32 lSrcH, INT32 lSrcJump,
  1810.                                              UINT32* pDst, INT32 lDstW, INT32 lDstH, INT32 lDstJump)
  1811. {
  1812.     // Allocate the divide LUT
  1813.     INT32* pSrcX = new INT32 [lDstW];
  1814.     if (!pSrcX)
  1815.     {
  1816.         return HXR_OUTOFMEMORY;
  1817.     }
  1818.     // Build the divide LUT
  1819.     INT32 lDstX;
  1820.     INT32 lDstWDiv2 = lDstW >> 1;
  1821.     for (lDstX = 0; lDstX < lDstW; lDstX++)
  1822.     {
  1823.         INT32 lSrcX = (lDstX * lSrcW + lDstWDiv2) / lDstW;
  1824.         if (lSrcX >= lSrcW)
  1825.         {
  1826.             lSrcX = lSrcW - 1;
  1827.         }
  1828.         pSrcX[lDstX] = lSrcX;
  1829.     }
  1830.     // Now run through the output image, doing nearest neighbor resampling
  1831.     INT32   lSrcY     = 0;
  1832.     INT32   lDstY     = 0;
  1833.     INT32   lLastSrcY = -1;
  1834.     UINT32* pDstRow   = pDst;
  1835.     INT32   lDstHDiv2 = lDstH >> 1;
  1836.     for (lDstY = 0; lDstY < lDstH; lDstY++)
  1837.     {
  1838.         lSrcY = (lDstY * lSrcH + lDstHDiv2) / lDstH;
  1839.         if (lSrcY >= lSrcH)
  1840.         {
  1841.             lSrcY = lSrcH - 1;
  1842.         }
  1843.         UINT32* pSrcRow = pSrc + lSrcY * lSrcJump;
  1844.         if (lSrcY == lLastSrcY)
  1845.         {
  1846.             // We're getting this resampled row from the same source row,
  1847.             // so just copy the last row.
  1848.             UINT32* pDstLastRow = pDstRow - lDstJump;
  1849.             for (lDstX = 0; lDstX < lDstW; lDstX++)
  1850.             {
  1851.                 pDstRow[lDstX] = pDstLastRow[lDstX];
  1852.             }
  1853.         }
  1854.         else
  1855.         {
  1856.             // New row, we must do the work
  1857.             for (lDstX = 0; lDstX < lDstW; lDstX++)
  1858.             {
  1859.                 UINT32 ulPixel = pSrcRow[pSrcX[lDstX]];
  1860.                 if (!(ulPixel & 0xFF000000))
  1861.                 {
  1862.                     pDstRow[lDstX] = ulPixel;
  1863.                 }
  1864.             }
  1865.         }
  1866.         lLastSrcY = lSrcY;
  1867.         pDstRow  += lDstJump;
  1868.     }
  1869.     HX_VECTOR_DELETE(pSrcX);
  1870.     return HXR_OK;
  1871. }
  1872. void PXImage::HorzAxisFlip32(UINT32* pSrc, INT32 lSrcW, INT32 lSrcH, INT32 lSrcJump,
  1873.                              UINT32* pDst, INT32 lDstW, INT32 lDstH, INT32 lDstJump)
  1874. {
  1875.     UINT32* pSrcRow = pSrc + (lSrcH - 1) * lSrcJump;
  1876.     UINT32* pDstRow = pDst;
  1877.     for (INT32 lY = 0; lY < lSrcH; lY++)
  1878.     {
  1879.         UINT32* pSrcPixel = pSrcRow;
  1880.         UINT32* pDstPixel = pDstRow;
  1881.         for (INT32 lX = lSrcW; lX; lX--)
  1882.         {
  1883.             *pDstPixel++ = *pSrcPixel++;
  1884.         }
  1885.         pSrcRow -= lSrcJump;
  1886.         pDstRow += lDstJump;
  1887.     }
  1888. }
  1889. void PXImage::VertAxisFlip32(UINT32* pSrc, INT32 lSrcW, INT32 lSrcH, INT32 lSrcJump,
  1890.                              UINT32* pDst, INT32 lDstW, INT32 lDstH, INT32 lDstJump)
  1891. {
  1892.     UINT32* pSrcRow = pSrc + lSrcW - 1;
  1893.     UINT32* pDstRow = pDst;
  1894.     for (INT32 lY = 0; lY < lSrcH; lY++)
  1895.     {
  1896.         UINT32 *pSrcPixel = pSrcRow;
  1897.         UINT32 *pDstPixel = pDstRow;
  1898.         for (INT32 lX = lSrcW; lX; lX--)
  1899.         {
  1900.             *pDstPixel++ = *pSrcPixel--;
  1901.         }
  1902.         pSrcRow += lSrcJump;
  1903.         pDstRow += lDstJump;
  1904.     }
  1905. }
  1906. void PXImage::ResetMembers()
  1907. {
  1908.     m_cBitmapInfo.biSize          = 40;
  1909.     m_cBitmapInfo.biWidth         = 0;
  1910.     m_cBitmapInfo.biHeight        = 0;
  1911.     m_cBitmapInfo.biPlanes        = 1;
  1912.     m_cBitmapInfo.biBitCount      = 0;
  1913.     m_cBitmapInfo.biCompression   = HX_RGB;
  1914.     m_cBitmapInfo.biSizeImage     = 0;
  1915.     m_cBitmapInfo.biXPelsPerMeter = 0;
  1916.     m_cBitmapInfo.biYPelsPerMeter = 0;
  1917.     m_cBitmapInfo.biClrUsed       = 0;
  1918.     m_cBitmapInfo.biClrImportant  = 0;
  1919.     m_cBitmapInfo.rcolor          = 0;
  1920.     m_cBitmapInfo.gcolor          = 0;
  1921.     m_cBitmapInfo.bcolor          = 0;
  1922.     m_cSubImageRect.left          = 0;
  1923.     m_cSubImageRect.top           = 0;
  1924.     m_cSubImageRect.right         = 0;
  1925.     m_cSubImageRect.bottom        = 0;
  1926.     m_lSubImageWidth              = 0;
  1927.     m_lSubImageHeight             = 0;
  1928.     m_ulBytesPerPixel             = 0;
  1929.     m_lRowBytes                   = 0;
  1930.     m_lRowStride                  = 0;
  1931.     m_lRowJump                    = 0;
  1932.     m_bRowsInverted               = FALSE;
  1933.     m_pImageBuffer                = NULL;
  1934.     m_bInitialized                = FALSE;
  1935.     m_bHasAlpha                   = FALSE;
  1936. }
  1937. void PXImage::Write(const char* pszFileName, UINT32 ulWriteFormat)
  1938. {
  1939.     if (m_bInitialized && pszFileName)
  1940.     {
  1941.         switch (ulWriteFormat)
  1942.         {
  1943.             case kWriteFormatBinaryRaw:
  1944.                 {
  1945.                     FILE* fp = fopen(pszFileName, "wb");
  1946.                     if (fp)
  1947.                     {
  1948.                         UINT32* pRow      = (UINT32*) m_pImageBuffer;
  1949.                         INT32   lJump     = m_lRowJump >> 2;
  1950.                         INT32   lNumBytes = m_lSubImageWidth << 2;
  1951.                         for (INT32 lY = m_lSubImageHeight; lY; lY--)
  1952.                         {
  1953.                             UINT32* pPixel = pRow;
  1954.                             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1955.                             {
  1956.                                 BYTE ucTmp = 0;
  1957.                                 ucTmp = (BYTE) GETRED32(*pPixel);
  1958.                                 fwrite(&ucTmp, 1, 1, fp);
  1959.                                 ucTmp = (BYTE) GETGREEN32(*pPixel);
  1960.                                 fwrite(&ucTmp, 1, 1, fp);
  1961.                                 ucTmp = (BYTE) GETBLUE32(*pPixel);
  1962.                                 fwrite(&ucTmp, 1, 1, fp);
  1963.                                 pPixel++;
  1964.                             }
  1965.                             pRow += lJump;
  1966.                         }
  1967.                     }
  1968.                     fclose(fp);
  1969.                 }
  1970.                 break;
  1971.             case kWriteFormatAscii:
  1972.                 {
  1973.                     FILE* fp = fopen(pszFileName, "w");
  1974.                     if (fp)
  1975.                     {
  1976.                         fprintf(fp, "Width=%ld, Height=%ldnFormat is RGBA RGBA ...n",
  1977.                                 m_lSubImageWidth, m_lSubImageHeight);
  1978.                         UINT32* pRow  = (UINT32*) m_pImageBuffer;
  1979.                         INT32   lJump = m_lRowJump >> 2;
  1980.                         for (INT32 lY = m_lSubImageHeight; lY; lY--)
  1981.                         {
  1982.                             UINT32* pPixel = pRow;
  1983.                             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  1984.                             {
  1985.                                 fprintf(fp, "%02X%02X%02X%02X ",
  1986.                                         GETRED32(*pPixel),
  1987.                                         GETGREEN32(*pPixel),
  1988.                                         GETBLUE32(*pPixel),
  1989.                                         GETALPHA32(*pPixel));
  1990.                                 pPixel++;
  1991.                             }
  1992.                             fprintf(fp, "n");
  1993.                             pRow += lJump;
  1994.                         }
  1995.                     }
  1996.                     fclose(fp);
  1997.                 }
  1998.                 break;
  1999.         }
  2000.     }
  2001. }
  2002. HX_RESULT PXImage::GetIterator(PXImageIterator** ppIterator, UINT32 ulType)
  2003. {
  2004.     HX_RESULT        retVal = HXR_OK;
  2005.     PXImageIterator* pIter  = NULL;
  2006.     switch (ulType)
  2007.     {
  2008.         case kIterLRTB:
  2009.             pIter = (PXImageIterator*) new PXImageIteratorLRTB(this);
  2010.             break;
  2011.         case kIterLRBT:
  2012.             pIter = (PXImageIterator*) new PXImageIteratorLRBT(this);
  2013.             break;
  2014.         case kIterRLTB:
  2015.             pIter = (PXImageIterator*) new PXImageIteratorRLTB(this);
  2016.             break;
  2017.         case kIterRLBT:
  2018.             pIter = (PXImageIterator*) new PXImageIteratorRLBT(this);
  2019.             break;
  2020.         case kIterTBLR:
  2021.             pIter = (PXImageIterator*) new PXImageIteratorTBLR(this);
  2022.             break;
  2023.         case kIterTBRL:
  2024.             pIter = (PXImageIterator*) new PXImageIteratorTBRL(this);
  2025.             break;
  2026.         case kIterBTLR:
  2027.             pIter = (PXImageIterator*) new PXImageIteratorBTLR(this);
  2028.             break;
  2029.         case kIterBTRL:
  2030.             pIter = (PXImageIterator*) new PXImageIteratorBTRL(this);
  2031.             break;
  2032.     }
  2033.     if (pIter)
  2034.     {
  2035.         *ppIterator = pIter;
  2036.     }
  2037.     else
  2038.     {
  2039.         *ppIterator = NULL;
  2040.         retVal      = HXR_OUTOFMEMORY;
  2041.     }
  2042.     return retVal;
  2043. }
  2044. void PXImage::SelfDetermineHasAlpha()
  2045. {
  2046.     if (m_bInitialized)
  2047.     {
  2048.         if (m_cBitmapInfo.biBitCount == 32 &&
  2049.             CompressionSupported())
  2050.         {
  2051.             // Pixels are stored as 0xAARRGGBB. If the image doesn't
  2052.             // use alpha, then all the AA bytes will be 0. If any
  2053.             // alpha bytes are non-zero, then the image uses alpha.
  2054.             BOOL    bHasAlpha = FALSE;
  2055.             UINT32* pRow      = (UINT32*) m_pImageBuffer;
  2056.             INT32   lJump     = m_lRowJump >> 2;
  2057.             for (UINT32 ulY = (UINT32) m_lSubImageHeight; ulY && !bHasAlpha; ulY--)
  2058.             {
  2059.                 UINT32* pPixel = pRow;
  2060.                 for (UINT32 ulX = (UINT32) m_lSubImageWidth; ulX && !bHasAlpha; ulX--)
  2061.                 {
  2062.                     if (GETALPHA32(*pPixel++))
  2063.                     {
  2064.                         bHasAlpha = TRUE;
  2065.                     }
  2066.                 }
  2067.                 pRow += lJump;
  2068.             }
  2069.             // Set the member
  2070.             m_bHasAlpha = bHasAlpha;
  2071.         }
  2072.     }
  2073. }
  2074. void PXImage::PreMultiplyAlphaChannel(UINT32 ulColor)
  2075. {
  2076.     if (m_bInitialized && m_bHasAlpha)
  2077.     {
  2078.         UINT32  ulR   = GETRED32(ulColor);
  2079.         UINT32  ulG   = GETGREEN32(ulColor);
  2080.         UINT32  ulB   = GETBLUE32(ulColor);
  2081.         UINT32* pRow  = (UINT32*) m_pImageBuffer;
  2082.         INT32   lJump = m_lRowJump >> 2;
  2083.         for (INT32 lY = m_lSubImageHeight; lY; lY--)
  2084.         {
  2085.             UINT32* pPix = pRow;
  2086.             for (INT32 lX = m_lSubImageWidth; lX; lX--)
  2087.             {
  2088.                 UINT32 ulA = GETALPHA32(*pPix);
  2089.                 ulA        = (ulA < 128 ? ulA : ulA + 1);
  2090.                 *pPix   = MAKE_RGB32(ALPHABLEND(ulR, GETRED32(*pPix),   ulA),
  2091.                                      ALPHABLEND(ulG, GETGREEN32(*pPix), ulA),
  2092.                                      ALPHABLEND(ulB, GETBLUE32(*pPix),  ulA));
  2093.                 pPix++;
  2094.             }
  2095.             pRow += lJump;
  2096.         }
  2097.         // Clear the HasAlpha flag, since we just removed the alpha channel
  2098.         m_bHasAlpha = FALSE;
  2099.     }
  2100. }
  2101. BOOL PXImage::CompressionSupported()
  2102. {
  2103.     BOOL bRet = FALSE;
  2104.     if (m_cBitmapInfo.biCompression == HX_RGB)
  2105.     {
  2106.         bRet = TRUE;
  2107.     }
  2108.     return bRet;
  2109. }