Back to index

lightning-sunbird  0.9+nobinonly
nsImagePh.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "nsImagePh.h"
00039 #include "nsRenderingContextPh.h"
00040 #include "nsPhGfxLog.h"
00041 #include "nsDeviceContextPh.h"
00042 #include "nspr.h"
00043 #include <errno.h>
00044 #include <Pt.h>
00045 #include <photon/PxImage.h>
00046 #include "photon/PhRender.h"
00047 
00048 
00049 NS_IMPL_ISUPPORTS1(nsImagePh, nsIImage)
00050 
00051 /* for mImageFlags */
00052 #define IMAGE_SHMEM                                            0x1
00053 #define ALPHA_SHMEM                                            0x2
00054 #define ZOOM_SHMEM                                             0x4
00055 
00056 #define IMAGE_SHMEM_THRESHOLD      4096
00057 
00058 // ----------------------------------------------------------------
00059 nsImagePh :: nsImagePh()
00060 {
00061        mImageBits = nsnull;
00062        mWidth = 0;
00063        mHeight = 0;
00064        mDepth = 0;
00065        mAlphaBits = nsnull;
00066        mAlphaDepth = 0;
00067        mRowBytes = 0;
00068        mAlphaHeight = 0;
00069        mAlphaWidth = 0;
00070        mImageFlags = 0;
00071        mAlphaRowBytes = 0;
00072        mNaturalWidth = 0;
00073        mNaturalHeight = 0;
00074        memset(&mPhImage, 0, sizeof(PhImage_t));
00075        mPhImageZoom = NULL;
00076        mDecodedY2_when_scaled = 0;
00077        mDirtyFlags = 0;
00078 }
00079 
00080 // ----------------------------------------------------------------
00081 nsImagePh :: ~nsImagePh()
00082 {
00083   if (mImageBits != nsnull)
00084   {
00085        if( mImageFlags & IMAGE_SHMEM ) PgShmemDestroy( mImageBits );
00086               else delete [] mImageBits;
00087     mImageBits = nsnull;
00088   }
00089 
00090   if (mAlphaBits != nsnull)
00091   {
00092               if( mImageFlags & ALPHA_SHMEM ) PgShmemDestroy( mAlphaBits );
00093     else delete [] mAlphaBits;
00094     mAlphaBits = nsnull;
00095   }
00096 
00097        if( mPhImageZoom ) {
00098               if( mImageFlags & ZOOM_SHMEM ) PgShmemDestroy( mPhImageZoom->image );
00099               else free( mPhImageZoom->image );
00100               if( mPhImageZoom->mask_bm )
00101                      free( mPhImageZoom->mask_bm );
00102               free( mPhImageZoom );
00103               mPhImageZoom = NULL;
00104               }
00105 
00106   memset(&mPhImage, 0, sizeof(PhImage_t));
00107 }
00108 
00117 nsresult nsImagePh :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMaskRequirements aMaskRequirements)
00118 {
00119        int type = -1;
00120 
00121        mImageFlags = 0;
00122 
00123        if (mImageBits != nsnull)
00124        {
00125               if( mImageFlags & IMAGE_SHMEM ) PgShmemDestroy( mImageBits );
00126               else delete [] mImageBits;
00127               mImageBits = nsnull;
00128        }
00129 
00130        if (mAlphaBits != nsnull)
00131        {
00132               if( mImageFlags & ALPHA_SHMEM ) PgShmemDestroy( mAlphaBits );
00133               else delete [] mAlphaBits;
00134               mAlphaBits = nsnull;
00135        }
00136 
00137        if( mPhImageZoom ) {
00138               if( mImageFlags & ZOOM_SHMEM ) PgShmemDestroy( mPhImageZoom->image );
00139               else free( mPhImageZoom->image );
00140               if( mPhImageZoom->mask_bm )
00141                      free( mPhImageZoom->mask_bm );
00142               free( mPhImageZoom );
00143               mPhImageZoom = NULL;
00144               }
00145   
00146   SetDecodedRect(0,0,0,0);  //init
00147  
00148   switch (aDepth)
00149     {
00150         case 24:
00151             type = Pg_IMAGE_DIRECT_888;
00152             mNumBytesPixel = 3;
00153             break;
00154 //      case 16:
00155 //          type = Pg_IMAGE_DIRECT_555;
00156 //          mNumBytesPixel = 2;
00157 //          break;
00158       case 8:
00159 //          type = Pg_IMAGE_PALETTE_BYTE;
00160 //          mNumBytesPixel = 1;
00161 //          break;
00162         default:
00163             NS_ASSERTION(PR_FALSE, "unexpected image depth");
00164             return NS_ERROR_UNEXPECTED;
00165             break;
00166     }
00167  
00168        mWidth = aWidth;
00169        mHeight = aHeight;
00170        mDepth = aDepth;
00171 
00172        /* Allocate the Image Data */
00173        PRInt32 image_size = mNumBytesPixel * mWidth * mHeight;
00174 
00175        /* TODO: don't allow shared memory contexts if the graphics driver isn't a local device */
00176 
00177   if (image_size >= IMAGE_SHMEM_THRESHOLD)
00178   {
00179               mImageBits = (PRUint8 *) PgShmemCreate( image_size, NULL );
00180               mImageFlags |= IMAGE_SHMEM;
00181   }
00182   else
00183   {
00184               mImageBits = new PRUint8[ image_size ];
00185               memset( mImageBits, 0, image_size );
00186        }
00187 
00188        switch(aMaskRequirements)
00189        {
00190               default:
00191               case nsMaskRequirements_kNoMask:
00192                      mAlphaBits = nsnull;
00193                      mAlphaWidth = 0;
00194                      mAlphaHeight = 0;
00195                      mAlphaRowBytes = 0;
00196                      break;
00197 
00198               case nsMaskRequirements_kNeeds1Bit:
00199                      {
00200                      mAlphaRowBytes = (aWidth + 7) / 8;
00201                      mAlphaDepth = 1;
00202 
00203                      int alphasize = mAlphaRowBytes * aHeight;
00204                      mAlphaBits = new PRUint8[ alphasize ];
00205                      memset( mAlphaBits, 0, alphasize );
00206 
00207                      mAlphaWidth = aWidth;
00208                      mAlphaHeight = aHeight;
00209                      }
00210                      break;
00211 
00212               case nsMaskRequirements_kNeeds8Bit:
00213                      {
00214                      mAlphaRowBytes = aWidth;
00215                      mAlphaDepth = 8;
00216 
00217                      int alphasize = mAlphaRowBytes * aHeight;
00218                      if( alphasize > IMAGE_SHMEM_THRESHOLD ) {
00219                             mAlphaBits = ( PRUint8 * ) PgShmemCreate( alphasize, NULL );
00220                             mImageFlags |= ALPHA_SHMEM;
00221                             }
00222                      else mAlphaBits = new PRUint8[ alphasize ];
00223                      memset( mAlphaBits, 0, alphasize );
00224 
00225                      mAlphaWidth = aWidth;
00226                      mAlphaHeight = aHeight;
00227                      }
00228                      break;
00229        }
00230 
00231        // mPhImage.image_tag = PtCRC( (char *)mImageBits, image_size );
00232        mPhImage.image = (char *)mImageBits;
00233        mPhImage.size.w = mWidth;
00234        mPhImage.size.h = 0;
00235        mRowBytes = mPhImage.bpl = mNumBytesPixel * mWidth;
00236        mPhImage.type = type;
00237        if (aMaskRequirements == nsMaskRequirements_kNeeds1Bit)
00238        {
00239               mPhImage.mask_bm = (char *)mAlphaBits;
00240               mPhImage.mask_bpl = mAlphaRowBytes;
00241        }
00242 
00243        return NS_OK;
00244 }
00245 
00249 PRBool nsImagePh::GetIsImageComplete() {
00250   return mDecodedX1 == 0 &&
00251          mDecodedY1 == 0 &&
00252          mDecodedX2 == mWidth &&
00253          mDecodedY2 == mHeight;
00254 }
00255 
00271 NS_IMETHODIMP nsImagePh :: Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
00272                              PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight,
00273                              PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight)
00274 {
00275        PhRect_t clip = { {aDX, aDY}, {aDX + aDWidth-1, aDY + aDHeight-1} };
00276        PhPoint_t pos = { aDX - aSX, aDY - aSY};
00277        int use_zoom = 0;
00278 
00279        if( !aSWidth || !aSHeight || !aDWidth || !aDHeight ) return NS_OK;
00280 
00282 //this, mPhImage.size.w, mPhImage.size.h, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight );
00283 
00284               PhDrawContext_t *dc = ((nsDrawingSurfacePh*)aSurface)->GetDC();
00285               PhGC_t *gc = PgGetGCCx( dc );
00286               if( (aSWidth != aDWidth || aSHeight != aDHeight) ) {
00287 
00288                      /* the case below happens frequently - a 1x1 image needs to be stretched, or a line or a column */
00289                      if( aSWidth == 1 && aSHeight == 1 || aSWidth == 1 && aSHeight == aDHeight || aDHeight == 1 && aSWidth == aDWidth ) {
00290                             /* you can strech the image by drawing it repeateadly */
00291 
00292                             PhPoint_t space = { 0, 0 };
00293                             PhPoint_t rep = { aDWidth, aDHeight };
00294 
00295                             /* is this a 1x1 transparent image used for spacing? */
00296                             if( mWidth == 1 && mHeight == 1 && mAlphaDepth == 1 && mAlphaBits[0] == 0x0 ) return NS_OK;
00297 
00298               PgSetMultiClipCx( gc, 1, &clip );
00299               if ((mAlphaDepth == 1) || (mAlphaDepth == 0)) {
00300                                    if( mImageFlags & IMAGE_SHMEM )
00301                      PgDrawRepPhImageCxv( dc, &mPhImage, 0, &pos, &rep, &space );
00302                                    else PgDrawRepPhImageCx( dc, &mPhImage, 0, &pos, &rep, &space );
00303                                    }
00304               else
00305               {
00306                 PgMap_t map;
00307                 map.dim.w = mAlphaWidth;
00308                 map.dim.h = mAlphaHeight;
00309                 map.bpl = mAlphaRowBytes;
00310                 map.bpp = mAlphaDepth;
00311                 map.map = (unsigned char *)mAlphaBits;
00312                 PgSetAlphaBlendCx( gc, &map, 0 );
00313 
00314                 PgAlphaOnCx( gc );
00315                                    if( mImageFlags & IMAGE_SHMEM )
00316                      PgDrawRepPhImageCxv( dc, &mPhImage, 0, &pos, &rep, &space );
00317                 else PgDrawRepPhImageCx( dc, &mPhImage, 0, &pos, &rep, &space );
00318                 PgAlphaOffCx( gc );
00319 
00320                                    PgSetAlphaBlendCx( gc, NULL, 0 ); /* this shouldn't be necessary, but the ph lib's gc is holding onto our mAlphaBits */
00321               }
00322               PgSetMultiClipCx( gc, 0, NULL );
00323 
00324                             return NS_OK;
00325                             }
00326 
00327                      else if( mPhImage.size.h > 0 ) {
00328 
00329                             /* keeping the proportions, what is the size of mPhImageZoom that can give use the aDWidth and aDHeight? */
00330                             PRInt32 scaled_w = aDWidth * mPhImage.size.w / aSWidth;
00331                             PRInt32 scaled_h = aDHeight * mPhImage.size.h / aSHeight;
00332                             use_zoom = 1;
00333                             
00334                             if( mPhImageZoom == NULL || mPhImageZoom->size.w != scaled_w || mPhImageZoom->size.h != scaled_h || mDecodedY2_when_scaled != mDecodedY2 || mDirtyFlags != 0 ) {
00335 
00336                                    /* we already had a scaled image, but the scaling factor was different from what we need now */
00337                                    mDirtyFlags = 0;
00338 
00339               if ( mPhImageZoom ) {
00340                                           if( mImageFlags & ZOOM_SHMEM ) {
00341                                                  PgFlushCx( dc );
00342                                                  PgWaitHWIdle();
00343                                                  PgShmemDestroy( mPhImageZoom->image );
00344                                                  }
00345                                           else free( mPhImageZoom->image );
00346                                           if( mPhImageZoom->mask_bm )
00347                                        free( mPhImageZoom->mask_bm );
00348                                           free( mPhImageZoom );
00349                                           mPhImageZoom = NULL;
00350                 }
00351 
00352                                    /* record the mDecodedY1 at the time of scaling */
00353                                    mDecodedY2_when_scaled = mDecodedY2;
00354 
00355                                    /* this is trying to estimate the image data size of the zoom image */
00356                                    if (( mPhImage.bpl * scaled_w * scaled_h / mPhImage.size.w ) < IMAGE_SHMEM_THRESHOLD) {
00357                                           mPhImageZoom = PiResizeImage( &mPhImage, NULL, scaled_w, scaled_h, Pi_USE_COLORS);
00358                                           mImageFlags &= ~ZOOM_SHMEM;
00359                                           }
00360                                    else {
00361                                           mPhImageZoom = PiResizeImage( &mPhImage, NULL, scaled_w, scaled_h, Pi_USE_COLORS|Pi_SHMEM);
00362                                           mImageFlags |= ZOOM_SHMEM;
00363                                           }
00364 
00366                                    }
00367                             }
00368                      }
00369 
00370               PgSetMultiClipCx( gc, 1, &clip );
00371               if ((mAlphaDepth == 1) || (mAlphaDepth == 0)) {
00372                      if( use_zoom ) {
00373                             if( mImageFlags & ZOOM_SHMEM )
00374                                    PgDrawPhImageCxv( dc, &pos, mPhImageZoom, 0 );
00375                             else PgDrawPhImageCx( dc, &pos, mPhImageZoom, 0 );
00376                             }
00377                      else {
00378                             if( mImageFlags & IMAGE_SHMEM )
00379                                    PgDrawPhImageCxv( dc, &pos, &mPhImage, 0 );
00380                             else PgDrawPhImageCx( dc, &pos, &mPhImage, 0 );
00381                             }
00382                      }
00383               else
00384               {
00385                      PgMap_t map;
00386 
00387                      map.dim.w = mAlphaWidth;
00388                      map.dim.h = mAlphaHeight;
00389                      map.bpl = mAlphaRowBytes;
00390                      map.bpp = mAlphaDepth;
00391                      map.map = (unsigned char *)mAlphaBits;
00392                      PgSetAlphaBlendCx( gc, &map, 0 );
00393 
00394                      PgAlphaOnCx( gc );
00395                      if( use_zoom ) {
00396                             if( mImageFlags & ZOOM_SHMEM )
00397                                    PgDrawPhImageCxv( dc, &pos, mPhImageZoom, 0 );
00398                             else PgDrawPhImageCx( dc, &pos, mPhImageZoom, 0 );
00399                             }
00400                      else {
00401                             if( mImageFlags & IMAGE_SHMEM )
00402                                    PgDrawPhImageCxv( dc, &pos, &mPhImage, 0 );
00403                             else PgDrawPhImageCx( dc, &pos, &mPhImage, 0 );
00404                             }
00405                      PgAlphaOffCx( gc );
00406 
00407                      PgSetAlphaBlendCx( gc, NULL, 0 ); /* this shouldn't be necessary, but the ph lib's gc is holding onto our mAlphaBits */
00408               }
00409               PgSetMultiClipCx( gc, 0, NULL );
00410 
00411        return NS_OK;
00412 }
00413 
00414 NS_IMETHODIMP nsImagePh :: Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
00415                              PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
00416 {
00417        PhPoint_t pos = { aX, aY };
00418 
00419        if (!aSurface || !mImageBits)
00420               return (NS_ERROR_FAILURE);
00421 
00422        PhDrawContext_t *dc = ((nsDrawingSurfacePh*)aSurface)->GetDC();
00423 
00424        if ((mAlphaDepth == 1) || (mAlphaDepth == 0))
00425        {
00426               if( mImageFlags & IMAGE_SHMEM )
00427                      PgDrawPhImageCxv( dc, &pos, &mPhImage, 0 );
00428               else PgDrawPhImageCx( dc, &pos, &mPhImage, 0 );
00429        }
00430        else if (mAlphaDepth == 8)
00431        {
00432               PgMap_t map;
00433               PhGC_t *gc = PgGetGCCx( dc );
00434 
00435               map.dim.w = mAlphaWidth;
00436               map.dim.h = mAlphaHeight;
00437               map.bpl = mAlphaRowBytes;
00438               map.bpp = mAlphaDepth;
00439               map.map = (unsigned char *)mAlphaBits;
00440               PgSetAlphaBlendCx( gc, &map, 0 );
00441 
00442               PgAlphaOnCx( gc );
00443               if( mImageFlags & IMAGE_SHMEM )
00444                      PgDrawPhImageCxv( dc, &pos, &mPhImage, 0 );
00445               else PgDrawPhImageCx( dc, &pos, &mPhImage, 0 );
00446               PgAlphaOffCx( gc );
00447 
00448               PgSetAlphaBlendCx( gc, NULL, 0 ); /* this shouldn't be necessary, but the ph lib's gc is holding onto our mAlphaBits */
00449        }
00450 
00451        return NS_OK;
00452 }
00453 
00454 /* New Tile code *********************************************************************/
00455 NS_IMETHODIMP nsImagePh::DrawTile( nsIRenderingContext &aContext, nsIDrawingSurface* aSurface,
00456               PRInt32 aSXOffset, PRInt32 aSYOffset, PRInt32 aPadX, PRInt32 aPadY, const nsRect &aTileRect ) 
00457 {
00458        PhPoint_t pos, space, rep;
00459        PhDrawContext_t *dc ;
00460        PhGC_t *gc;
00461 
00462        /* is this a 1x1 transparent image used for spacing? */
00463        if( mWidth == 1 && mHeight == 1 && mAlphaDepth == 1 && mAlphaBits[0] == 0x0 ) return NS_OK;
00464 
00465        dc = ((nsDrawingSurfacePh*)aSurface)->GetDC();
00466        gc = PgGetGCCx( dc );
00467 
00468        // since there is an offset into the image and I only want to draw full
00469        // images, shift the position back and set clipping so that it looks right
00470        pos.x = aTileRect.x - aSXOffset;
00471        pos.y = aTileRect.y - aSYOffset;
00472 
00473        space.x = mPhImage.size.w + aPadX;
00474        space.y = mPhImage.size.h + aPadY;
00475        rep.x = ( aTileRect.width + aSXOffset + space.x - 1 ) / space.x;
00476        rep.y = ( aTileRect.height + aSYOffset + space.y - 1 ) / space.y;
00477 
00478        /* not sure if cliping is necessary */
00479        PhRect_t clip = { {aTileRect.x, aTileRect.y}, {aTileRect.x + aTileRect.width-1, aTileRect.y + aTileRect.height-1} };
00480        PgSetMultiClipCx( gc, 1, &clip );
00481 
00482        if ((mAlphaDepth == 1) || (mAlphaDepth == 0)) {
00483               if( mImageFlags & IMAGE_SHMEM )
00484               PgDrawRepPhImageCxv( dc, &mPhImage, 0, &pos, &rep, &space );
00485          else PgDrawRepPhImageCx( dc, &mPhImage, 0, &pos, &rep, &space );
00486               }
00487        else
00488               {
00489     PgMap_t map;
00490     map.dim.w = mAlphaWidth;
00491     map.dim.h = mAlphaHeight;
00492     map.bpl = mAlphaRowBytes;
00493     map.bpp = mAlphaDepth;
00494     map.map = (unsigned char *)mAlphaBits;
00495     PgSetAlphaBlendCx( gc, &map, 0 );
00496        
00497     PgAlphaOnCx( gc );
00498               if( mImageFlags & IMAGE_SHMEM )
00499        PgDrawRepPhImageCxv( dc, &mPhImage, 0, &pos, &rep, &space );
00500     else PgDrawRepPhImageCx( dc, &mPhImage, 0, &pos, &rep, &space );
00501     PgAlphaOffCx( gc );
00502 
00503               PgSetAlphaBlendCx( gc, NULL, 0 ); /* this shouldn't be necessary, but the ph lib's gc is holding onto our mAlphaBits */
00504               }
00505 
00506        PgSetMultiClipCx( gc, 0, NULL );
00507 
00508        return NS_OK;
00509 }
00510 /* End New Tile code *****************************************************************/
00511 
00512 
00513 //------------------------------------------------------------
00514 nsresult nsImagePh :: Optimize(nsIDeviceContext* aContext)
00515 {
00516        /* TODO: need to invalidate the caches if the graphics system has changed somehow (ie: mode switch, dragged to a remote
00517                      display, etc... */
00518 
00519        /* TODO: remote graphics drivers should always cache the images offscreen regardless of wether there is a mask or not,
00520                      the Draw code will need to be updated for this */
00521 
00522        return NS_OK;
00523 }
00524 
00525 
00536 NS_IMETHODIMP nsImagePh::DrawToImage(nsIImage* aDstImage,
00537                                       nscoord aDX, nscoord aDY,
00538                                       nscoord aDWidth, nscoord aDHeight)
00539 {
00540   nsImagePh *dest = NS_STATIC_CAST(nsImagePh *, aDstImage);
00541 
00542   if (!dest)
00543     return NS_ERROR_FAILURE;
00544 
00545   if (!dest->mPhImage.image)
00546     return NS_ERROR_FAILURE;
00547 
00548        PhArea_t sarea, darea;
00549        PhImage_t *pimage = NULL;
00550        int start, x, y;
00551        char mbit, mbyte;
00552        int release = 0;
00553               
00554        sarea.pos.x = sarea.pos.y = 0;
00555        darea.pos.x = aDX;
00556        darea.pos.y = aDY;
00557        darea.size.w = sarea.size.w = aDWidth;
00558        darea.size.h = sarea.size.h = aDHeight;
00559 
00560        if( mPhImage.size.h > 0 && ( aDWidth != mPhImage.size.w || aDHeight != mPhImage.size.h ) )
00561        {
00562               release = 1;
00563               if ((aDHeight * mPhImage.bpl) < IMAGE_SHMEM_THRESHOLD)
00564                      pimage = PiResizeImage(&mPhImage, NULL, aDWidth, aDHeight, Pi_USE_COLORS);
00565               else
00566                      pimage = PiResizeImage(&mPhImage, NULL, aDWidth, aDHeight, Pi_USE_COLORS|Pi_SHMEM);
00567        }
00568        else pimage = &mPhImage;
00569 
00570        if( pimage == NULL ) return NS_OK;
00571 
00572        start = (aDY * dest->mPhImage.bpl) + (aDX * mNumBytesPixel);
00573        for (y = 0; y < pimage->size.h; y++)
00574        {
00575               for (x = 0; x < pimage->size.w; x++)
00576               {
00577                      if (pimage->mask_bm)
00578                      {
00579                             mbyte = *(pimage->mask_bm + (pimage->mask_bpl * y) + (x >> 3));
00580                             mbit = x & 7;
00581                             if (!(mbyte & (0x80 >> mbit)))
00582                                    continue;
00583                      }
00584                      memcpy(dest->mPhImage.image + start + (dest->mPhImage.bpl * y) + (x*mNumBytesPixel), 
00585                                pimage->image + (pimage->bpl * y) + (x*mNumBytesPixel), mNumBytesPixel);
00586               }
00587        }
00588 
00589        if( release ) {
00590               pimage->flags = Ph_RELEASE_IMAGE_ALL;
00591               PhReleaseImage(pimage);
00592               free( pimage );
00593               }
00594 
00595        return NS_OK;
00596 }