// ---------------------------------------------------------------- nsImagePh :: ~nsImagePh() { if (mImageBits != nsnull) { if( mImageFlags & IMAGE_SHMEM ) PgShmemDestroy( mImageBits ); else delete [] mImageBits; mImageBits = nsnull; } if (mAlphaBits != nsnull) { if( mImageFlags & ALPHA_SHMEM ) PgShmemDestroy( mAlphaBits ); else delete [] mAlphaBits; mAlphaBits = nsnull; } if( mPhImageZoom ) { if( mImageFlags & ZOOM_SHMEM ) PgShmemDestroy( mPhImageZoom->image ); else free( mPhImageZoom->image ); if( mPhImageZoom->mask_bm ) free( mPhImageZoom->mask_bm ); free( mPhImageZoom ); mPhImageZoom = NULL; } memset(&mPhImage, 0, sizeof(PhImage_t)); }
// this function frees the image given void FreeBuffer(CoolImage *i) { // for blit type 0, we just free the memory previously malloced if (blittype==0) free(i->buffer); else if (blittype==1) PgShmemDestroy(i->buffer); else if (blittype==2) PhDCRelease(i->ctx); // free the structure as well free(i); }
void ph_DestroyImage(_THIS, SDL_Surface* screen) { #ifdef HAVE_OPENGL if ((screen->flags & SDL_OPENGL)==SDL_OPENGL) { if (oglctx) { PhDCSetCurrent(NULL); PhDCRelease(oglctx); oglctx=NULL; oglflags=0; oglbpp=0; } return; } #endif /* HAVE_OPENGL */ if (currently_fullscreen) { /* if we right now in 8bpp fullscreen we must release palette */ if ((screen->format->BitsPerPixel==8) && (desktopbpp!=8)) { PgSetPalette(syspalph, 0, -1, 0, 0, 0); PgSetPalette(savedpal, 0, 0, _Pg_MAX_PALETTE, Pg_PALSET_GLOBAL | Pg_PALSET_FORCE_EXPOSE, 0); PgFlush(); } ph_LeaveFullScreen(this); } if (OCImage.offscreen_context != NULL) { PhDCRelease(OCImage.offscreen_context); OCImage.offscreen_context = NULL; OCImage.FrameData0 = NULL; } if (OCImage.offscreen_backcontext != NULL) { PhDCRelease(OCImage.offscreen_backcontext); OCImage.offscreen_backcontext = NULL; OCImage.FrameData1 = NULL; } OCImage.CurrentFrameData = NULL; if (SDL_Image) { /* if palette allocated, free it */ if (SDL_Image->palette) { free(SDL_Image->palette); } PgShmemDestroy(SDL_Image->image); free(SDL_Image); } /* Must be zeroed everytime */ SDL_Image = NULL; if (screen) { screen->pixels = NULL; } }
/** ---------------------------------------------------------------- * Draw the bitmap, this method has a source and destination coordinates * @update dc - 11/20/98 * @param aContext - the rendering context to draw with * @param aSurface - The HDC in a nsDrawingsurfacePh to copy the bits to. * @param aSX - source horizontal location * @param aSY - source vertical location * @param aSWidth - source width * @param aSHeight - source height * @param aDX - destination location * @param aDY - destination location * @param aDWidth - destination width * @param aDHeight - destination height * @result NS_OK if the draw worked */ NS_IMETHODIMP nsImagePh :: Draw(nsIRenderingContext &aContext, nsIDrawingSurface* aSurface, PRInt32 aSX, PRInt32 aSY, PRInt32 aSWidth, PRInt32 aSHeight, PRInt32 aDX, PRInt32 aDY, PRInt32 aDWidth, PRInt32 aDHeight) { PhRect_t clip = { {aDX, aDY}, {aDX + aDWidth-1, aDY + aDHeight-1} }; PhPoint_t pos = { aDX - aSX, aDY - aSY}; int use_zoom = 0; if( !aSWidth || !aSHeight || !aDWidth || !aDHeight ) return NS_OK; ///* ATENTIE */ printf( "this=%p size=%d,%d src=(%d %d %d %d) dest=(%d %d %d %d)\n", //this, mPhImage.size.w, mPhImage.size.h, aSX, aSY, aSWidth, aSHeight, aDX, aDY, aDWidth, aDHeight ); PhDrawContext_t *dc = ((nsDrawingSurfacePh*)aSurface)->GetDC(); PhGC_t *gc = PgGetGCCx( dc ); if( (aSWidth != aDWidth || aSHeight != aDHeight) ) { /* the case below happens frequently - a 1x1 image needs to be stretched, or a line or a column */ if( aSWidth == 1 && aSHeight == 1 || aSWidth == 1 && aSHeight == aDHeight || aDHeight == 1 && aSWidth == aDWidth ) { /* you can strech the image by drawing it repeateadly */ PhPoint_t space = { 0, 0 }; PhPoint_t rep = { aDWidth, aDHeight }; /* is this a 1x1 transparent image used for spacing? */ if( mWidth == 1 && mHeight == 1 && mAlphaDepth == 1 && mAlphaBits[0] == 0x0 ) return NS_OK; PgSetMultiClipCx( gc, 1, &clip ); if ((mAlphaDepth == 1) || (mAlphaDepth == 0)) { if( mImageFlags & IMAGE_SHMEM ) PgDrawRepPhImageCxv( dc, &mPhImage, 0, &pos, &rep, &space ); else PgDrawRepPhImageCx( dc, &mPhImage, 0, &pos, &rep, &space ); } else { PgMap_t map; map.dim.w = mAlphaWidth; map.dim.h = mAlphaHeight; map.bpl = mAlphaRowBytes; map.bpp = mAlphaDepth; map.map = (unsigned char *)mAlphaBits; PgSetAlphaBlendCx( gc, &map, 0 ); PgAlphaOnCx( gc ); if( mImageFlags & IMAGE_SHMEM ) PgDrawRepPhImageCxv( dc, &mPhImage, 0, &pos, &rep, &space ); else PgDrawRepPhImageCx( dc, &mPhImage, 0, &pos, &rep, &space ); PgAlphaOffCx( gc ); PgSetAlphaBlendCx( gc, NULL, 0 ); /* this shouldn't be necessary, but the ph lib's gc is holding onto our mAlphaBits */ } PgSetMultiClipCx( gc, 0, NULL ); return NS_OK; } else if( mPhImage.size.h > 0 ) { /* keeping the proportions, what is the size of mPhImageZoom that can give use the aDWidth and aDHeight? */ PRInt32 scaled_w = aDWidth * mPhImage.size.w / aSWidth; PRInt32 scaled_h = aDHeight * mPhImage.size.h / aSHeight; use_zoom = 1; if( mPhImageZoom == NULL || mPhImageZoom->size.w != scaled_w || mPhImageZoom->size.h != scaled_h || mDecodedY2_when_scaled != mDecodedY2 || mDirtyFlags != 0 ) { /* we already had a scaled image, but the scaling factor was different from what we need now */ mDirtyFlags = 0; if ( mPhImageZoom ) { if( mImageFlags & ZOOM_SHMEM ) { PgFlushCx( dc ); PgWaitHWIdle(); PgShmemDestroy( mPhImageZoom->image ); } else free( mPhImageZoom->image ); if( mPhImageZoom->mask_bm ) free( mPhImageZoom->mask_bm ); free( mPhImageZoom ); mPhImageZoom = NULL; } /* record the mDecodedY1 at the time of scaling */ mDecodedY2_when_scaled = mDecodedY2; /* this is trying to estimate the image data size of the zoom image */ if (( mPhImage.bpl * scaled_w * scaled_h / mPhImage.size.w ) < IMAGE_SHMEM_THRESHOLD) { mPhImageZoom = PiResizeImage( &mPhImage, NULL, scaled_w, scaled_h, Pi_USE_COLORS); mImageFlags &= ~ZOOM_SHMEM; } else { mPhImageZoom = PiResizeImage( &mPhImage, NULL, scaled_w, scaled_h, Pi_USE_COLORS|Pi_SHMEM); mImageFlags |= ZOOM_SHMEM; } ///* ATENTIE */ printf( "\t\t\tzoom from=%d,%d to=%d,%d\n", mPhImage.size.w, mPhImage.size.h, scaled_w, scaled_h ); } } } PgSetMultiClipCx( gc, 1, &clip ); if ((mAlphaDepth == 1) || (mAlphaDepth == 0)) { if( use_zoom ) { if( mImageFlags & ZOOM_SHMEM ) PgDrawPhImageCxv( dc, &pos, mPhImageZoom, 0 ); else PgDrawPhImageCx( dc, &pos, mPhImageZoom, 0 ); } else { if( mImageFlags & IMAGE_SHMEM ) PgDrawPhImageCxv( dc, &pos, &mPhImage, 0 ); else PgDrawPhImageCx( dc, &pos, &mPhImage, 0 ); } } else { PgMap_t map; map.dim.w = mAlphaWidth; map.dim.h = mAlphaHeight; map.bpl = mAlphaRowBytes; map.bpp = mAlphaDepth; map.map = (unsigned char *)mAlphaBits; PgSetAlphaBlendCx( gc, &map, 0 ); PgAlphaOnCx( gc ); if( use_zoom ) { if( mImageFlags & ZOOM_SHMEM ) PgDrawPhImageCxv( dc, &pos, mPhImageZoom, 0 ); else PgDrawPhImageCx( dc, &pos, mPhImageZoom, 0 ); } else { if( mImageFlags & IMAGE_SHMEM ) PgDrawPhImageCxv( dc, &pos, &mPhImage, 0 ); else PgDrawPhImageCx( dc, &pos, &mPhImage, 0 ); } PgAlphaOffCx( gc ); PgSetAlphaBlendCx( gc, NULL, 0 ); /* this shouldn't be necessary, but the ph lib's gc is holding onto our mAlphaBits */ } PgSetMultiClipCx( gc, 0, NULL ); return NS_OK; }
/** ---------------------------------------------------------------- * Initialize the nsImagePh object * @param aWidth - Width of the image * @param aHeight - Height of the image * @param aDepth - Depth of the image * @param aMaskRequirements - A mask used to specify if alpha is needed. * @result NS_OK if the image was initied ok */ nsresult nsImagePh :: Init(PRInt32 aWidth, PRInt32 aHeight, PRInt32 aDepth,nsMaskRequirements aMaskRequirements) { int type = -1; mImageFlags = 0; if (mImageBits != nsnull) { if( mImageFlags & IMAGE_SHMEM ) PgShmemDestroy( mImageBits ); else delete [] mImageBits; mImageBits = nsnull; } if (mAlphaBits != nsnull) { if( mImageFlags & ALPHA_SHMEM ) PgShmemDestroy( mAlphaBits ); else delete [] mAlphaBits; mAlphaBits = nsnull; } if( mPhImageZoom ) { if( mImageFlags & ZOOM_SHMEM ) PgShmemDestroy( mPhImageZoom->image ); else free( mPhImageZoom->image ); if( mPhImageZoom->mask_bm ) free( mPhImageZoom->mask_bm ); free( mPhImageZoom ); mPhImageZoom = NULL; } SetDecodedRect(0,0,0,0); //init switch (aDepth) { case 24: type = Pg_IMAGE_DIRECT_888; mNumBytesPixel = 3; break; // case 16: // type = Pg_IMAGE_DIRECT_555; // mNumBytesPixel = 2; // break; case 8: // type = Pg_IMAGE_PALETTE_BYTE; // mNumBytesPixel = 1; // break; default: NS_ASSERTION(PR_FALSE, "unexpected image depth"); return NS_ERROR_UNEXPECTED; break; } mWidth = aWidth; mHeight = aHeight; mDepth = aDepth; /* Allocate the Image Data */ PRInt32 image_size = mNumBytesPixel * mWidth * mHeight; /* TODO: don't allow shared memory contexts if the graphics driver isn't a local device */ if (image_size >= IMAGE_SHMEM_THRESHOLD) { mImageBits = (PRUint8 *) PgShmemCreate( image_size, NULL ); mImageFlags |= IMAGE_SHMEM; } else { mImageBits = new PRUint8[ image_size ]; memset( mImageBits, 0, image_size ); } switch(aMaskRequirements) { default: case nsMaskRequirements_kNoMask: mAlphaBits = nsnull; mAlphaWidth = 0; mAlphaHeight = 0; mAlphaRowBytes = 0; break; case nsMaskRequirements_kNeeds1Bit: { mAlphaRowBytes = (aWidth + 7) / 8; mAlphaDepth = 1; int alphasize = mAlphaRowBytes * aHeight; mAlphaBits = new PRUint8[ alphasize ]; memset( mAlphaBits, 0, alphasize ); mAlphaWidth = aWidth; mAlphaHeight = aHeight; } break; case nsMaskRequirements_kNeeds8Bit: { mAlphaRowBytes = aWidth; mAlphaDepth = 8; int alphasize = mAlphaRowBytes * aHeight; if( alphasize > IMAGE_SHMEM_THRESHOLD ) { mAlphaBits = ( PRUint8 * ) PgShmemCreate( alphasize, NULL ); mImageFlags |= ALPHA_SHMEM; } else mAlphaBits = new PRUint8[ alphasize ]; memset( mAlphaBits, 0, alphasize ); mAlphaWidth = aWidth; mAlphaHeight = aHeight; } break; } // mPhImage.image_tag = PtCRC( (char *)mImageBits, image_size ); mPhImage.image = (char *)mImageBits; mPhImage.size.w = mWidth; mPhImage.size.h = 0; mRowBytes = mPhImage.bpl = mNumBytesPixel * mWidth; mPhImage.type = type; if (aMaskRequirements == nsMaskRequirements_kNeeds1Bit) { mPhImage.mask_bm = (char *)mAlphaBits; mPhImage.mask_bpl = mAlphaRowBytes; } return NS_OK; }