void AConvolute64KBlurGauss( CFbsBitmap& aTarget, const CFbsBitmap& aSource, const TInt aBlendFactor ) { TInt width = aTarget.SizeInPixels().iWidth; TInt height = aTarget.SizeInPixels().iHeight; // CFbsBitmap::ScanLineLength returns bytes TInt targetScanW = CFbsBitmap::ScanLineLength( aTarget.SizeInPixels().iWidth, aTarget.DisplayMode()); TInt sourceScanW = CFbsBitmap::ScanLineLength( aSource.SizeInPixels().iWidth, aSource.DisplayMode()); TInt combinedScanW = (targetScanW << 16) + sourceScanW; // Prepare the data addresses aTarget.LockHeap( ETrue ); // Lock the global bitmap heap TUint* targetAddr = reinterpret_cast<TUint*>( aTarget.DataAddress() ); TUint* sourceAddr = reinterpret_cast<TUint*>( aSource.DataAddress() ); ADoConvolute64KBlurGauss(targetAddr, sourceAddr, combinedScanW, width, height, aBlendFactor); aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap }
TBool CWsGceCscBase::Compare(CFbsBitmap& aBitmap1, CFbsBitmap& aBitmap2) { if ((aBitmap1.SizeInPixels() == aBitmap2.SizeInPixels()) && (aBitmap1.DisplayMode() == aBitmap2.DisplayMode())) { TSize size = aBitmap1.SizeInPixels(); TInt width = size.iWidth; TInt height = size.iHeight; TRgb color1, color2; for (TInt i = 0; i < width; i++) { for (TInt j = 0; j < height; j++) { aBitmap1.GetPixel(color1, TPoint(i, j)); aBitmap2.GetPixel(color2, TPoint(i, j)); if (color1 != color2) { return EFalse; } } } return ETrue; } return EFalse; }
TBool CScreenCaptureUtil::VerifyBitmapFormatL(const CFbsBitmap& aBitmap) { RSurfaceManager::TInfoBuf infoBuf; RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)); return ((info.iSize == aBitmap.SizeInPixels()) && (EColor16MU == aBitmap.DisplayMode())); }
//------------------------------------------------------------------------ static void ProcessRgbToGray( const CFbsBitmap& aTarget, const CFbsBitmap& aSource, const TInt aTreshold ) { TInt width = aSource.SizeInPixels().iWidth; TInt height = aSource.SizeInPixels().iHeight; // ScanLineLength returns bytes, but width must match the Type TInt scanT = CFbsBitmap::ScanLineLength(width, aTarget.DisplayMode()); TInt scanS = CFbsBitmap::ScanLineLength(width, aSource.DisplayMode()) / sizeof(Type); TInt shade; TInt pitchT = scanT - width; TInt pitchS = scanS - width; aTarget.LockHeap( ETrue ); // Lock the global bitmap heap TUint8* dataT = reinterpret_cast<TUint8*>( aTarget.DataAddress() ); Type* dataS = reinterpret_cast<Type*>( aSource.DataAddress() ); TInt x, y; for( y=0; y < height; y++ ) { for( x=0; x < width; x++ ) { // Pixel intensity = grayscale value shade = AknsRlUtil::Grayscale( AknsRlRgb<Type,X,R,G,B>::R8(*dataS), AknsRlRgb<Type,X,R,G,B>::G8(*dataS), AknsRlRgb<Type,X,R,G,B>::B8(*dataS) ); // Convert to B&W if( shade < aTreshold ) *dataT = 0; else *dataT = 255; dataT++; dataS++; } dataT = dataT + pitchT; dataS = dataS + pitchS; } aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap }
/** Override of base class virtual @return - TVerdict code */ TVerdict CTBitBltPerfDirectGdi::doTestStepPreambleL() { CTDirectGdiTestBase::doTestStepPreambleL(); // Create a CFbsBitmap image for each source mode we are testing. for (TInt srcMode = 0; srcMode < iSourcePixelFormatArray.Count(); ++srcMode) { TDisplayMode bitmapDisplayMode = TDisplayModeMapping::MapPixelFormatToDisplayMode(iSourcePixelFormatArray[srcMode]); CFbsBitmap* bitmapImage = NULL; switch(bitmapDisplayMode) { case EColor4K: case EGray256: bitmapImage = LoadBitmapL(KBitmap12bit, 0); break; case EColor64K: bitmapImage = LoadBitmapL(KBitmap16bit, 0); break; case EColor16M: bitmapImage = LoadBitmapL(KBitmap24bit, 0); break; default: bitmapImage = LoadBitmapL(KBitmap32bit, 0); break; } if (bitmapImage && bitmapImage->DisplayMode() != bitmapDisplayMode) { CleanupStack::PushL(bitmapImage); CFbsBitmap* tempBitmap = CopyIntoNewBitmapL(bitmapImage, bitmapDisplayMode); CleanupStack::PopAndDestroy(1, bitmapImage); //bitmapImage bitmapImage = tempBitmap; } iBitmapImage.AppendL(bitmapImage); } // Create 8bit alpha bitmap CFbsBitmap* tempBitmap = LoadBitmapL(KBitmap12bit, 0); CleanupStack::PushL(tempBitmap); iAlpha8bit = CopyIntoNewBitmapL(tempBitmap, EGray256); CleanupStack::PopAndDestroy(tempBitmap); // tempBitmap // Create CFbsBitmaps for the tile images of various pixel formats. // The first entry in the array is always the default pixelformat loaded from the mbm. // Then in the rest of the array are bitmaps converted to the source pixel formats. CFbsBitmap* tile = LoadBitmapL(KBitmapTile, 0); iBitmapTile.AppendL(tile); for (TInt srcMode = 0; srcMode < iSourcePixelFormatArray.Count(); ++srcMode) { TDisplayMode bitmapDisplayMode = TDisplayModeMapping::MapPixelFormatToDisplayMode(iSourcePixelFormatArray[srcMode]); CFbsBitmap* tileCopy = CopyIntoNewBitmapL(tile, bitmapDisplayMode); iBitmapTile.AppendL(tileCopy); } return TestStepResult(); }
//------------------------------------------------------------------------ static void ProcessRgbToRgb( const CFbsBitmap& aTarget, const CFbsBitmap& aSource, const TInt aTreshold, const TInt aBlendFactor ) { // ScanLineLength returns bytes, but width must match the Type TInt width = CFbsBitmap::ScanLineLength( aSource.SizeInPixels().iWidth, aSource.DisplayMode() ) / sizeof(Type); TInt height = aSource.SizeInPixels().iHeight; TInt pixelCount = width * height; TInt shade; TInt r,g,b; aTarget.LockHeap( ETrue ); // Lock the global bitmap heap Type* dataT = reinterpret_cast<Type*>( aTarget.DataAddress() ); Type* dataS = reinterpret_cast<Type*>( aSource.DataAddress() ); for( TInt index = 0; index < pixelCount; ++index ) { r = AknsRlRgb<Type,X,R,G,B>::R8(*dataS); g = AknsRlRgb<Type,X,R,G,B>::G8(*dataS); b = AknsRlRgb<Type,X,R,G,B>::B8(*dataS); // Pixel intensity = grayscale value shade = AknsRlUtil::Grayscale( TUint8(r), TUint8(g), TUint8(b) ); // Convert to B&W if( shade < aTreshold ) shade = 0; else shade = 255; // Exposure blending // Note: It is assumed that arithmetic shifting is supported // -> negative values are shifted correctly r = (shade * aBlendFactor + (255 - aBlendFactor) * r) >> 8; g = (shade * aBlendFactor + (255 - aBlendFactor) * g) >> 8; b = (shade * aBlendFactor + (255 - aBlendFactor) * b) >> 8; if( r < 0 ) r = 0; else if( r > 255 ) r = 255; if( g < 0 ) g = 0; else if( g > 255 ) g = 255; if( b < 0 ) b = 0; else if( b > 255 ) b = 255; AknsRlRgb<Type,X,R,G,B>::SetRgb8( dataT, TUint8(r), TUint8(g), TUint8(b) ); dataT++; dataS++; } aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap }
//------------------------------------------------------------------------ static void ProcessGrayToRgb( const CFbsBitmap& aTarget, const CFbsBitmap& aSource, const TInt aTreshold ) { TInt width = aSource.SizeInPixels().iWidth; TInt height = aSource.SizeInPixels().iHeight; // ScanLineLength returns bytes, but width must match the Type TInt scanT = CFbsBitmap::ScanLineLength(width, aTarget.DisplayMode()) / sizeof(Type); TInt scanS = CFbsBitmap::ScanLineLength(width, aSource.DisplayMode()); TInt pitchT = scanT - width; TInt pitchS = scanS - width; aTarget.LockHeap( ETrue ); // Lock the global bitmap heap Type* dataT = reinterpret_cast<Type*>( aTarget.DataAddress() ); TUint8* dataS = reinterpret_cast<TUint8*>( aSource.DataAddress() ); TInt x, y; for( y=0; y < height; y++ ) { for( x=0; x < width; x++ ) { // Convert to B&W if( *dataS < aTreshold ) AknsRlRgb<Type,X,R,G,B>::SetRgb8( dataT, TUint8(0), TUint8(0), TUint8(0) ); else AknsRlRgb<Type,X,R,G,B>::SetRgb8( dataT, TUint8(255), TUint8(255), TUint8(255) ); dataT++; dataS++; } dataT = dataT + pitchT; dataS = dataS + pitchS; } aTarget.UnlockHeap( ETrue ); // Unlock the global bitmap heap }
// ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- // CMaskedBitmap::CopyBitmap // ----------------------------------------------------------------------------- TInt BitmapUtil::CopyBitmap( const CFbsBitmap& aSource, CFbsBitmap& aDestination ) { TSize size( aSource.SizeInPixels() ); TDisplayMode displayMode( aSource.DisplayMode() ); TInt err( aDestination.Create( size, displayMode ) ); if( !err ) { err = BitmapUtil::CopyBitmapData( aSource, aDestination, size, displayMode ); if( err ) { aDestination.Reset(); } } return err; }
void AknBitmapMirrorUtils::LoadPartialBitmapL(CFbsBitmap* aBitmap, const TDesC& aFileName,TInt32 aId, TRect aRect, TBool aMirrorHorizontally) { CFbsBitmap* destinationBitmap = aBitmap; User::LeaveIfNull(destinationBitmap); CFbsBitmap* sourceBitmap = new (ELeave) CFbsBitmap(); CleanupStack::PushL(sourceBitmap); User::LeaveIfError(sourceBitmap->Load(aFileName, aId, ETrue)); TSize sourceBitmapSize = sourceBitmap->SizeInPixels(); TRect sourceRect = TRect(aRect); if (sourceRect == KWholeBitmapRect) { sourceRect.iTl.iX = 0; sourceRect.iTl.iY = 0; sourceRect.iBr.iX = sourceBitmapSize.iWidth; sourceRect.iBr.iY = sourceBitmapSize.iHeight; } TSize destinationBitmapSize(sourceRect.Width(), sourceRect.Height()); User::LeaveIfError(destinationBitmap->Create(destinationBitmapSize, sourceBitmap->DisplayMode())); CFbsBitmapDevice* destinationDevice = CFbsBitmapDevice::NewL( destinationBitmap ); CleanupStack::PushL(destinationDevice); CFbsBitGc* destinationGc; User::LeaveIfError( destinationDevice->CreateContext( destinationGc ) ); if (aMirrorHorizontally) { TRect sourceBitmapBlittingRect( sourceRect.iTl.iX,sourceRect.iTl.iY,sourceRect.iTl.iX + 1,sourceRect.iBr.iY ); for ( TInt xPos=destinationBitmapSize.iWidth-1; xPos >= 0; xPos-- ) { destinationGc->BitBlt( TPoint(xPos,0), sourceBitmap, sourceBitmapBlittingRect ); sourceBitmapBlittingRect.iTl.iX++; sourceBitmapBlittingRect.iBr.iX++; } } else { destinationGc->BitBlt( TPoint(0,0), sourceBitmap, sourceRect ); } delete destinationGc; CleanupStack::PopAndDestroy(2); // sourceBitmap, destinationDevice }
void CMMABitmapWindow::DrawFrameL(const CFbsBitmap* aBitmap) { if (iBitmap) { // leave in this function will panic thread CFbsBitmap* bitmap = new(ELeave)CFbsBitmap(); CleanupStack::PushL(bitmap); User::LeaveIfError(bitmap->Duplicate(aBitmap->Handle())); // set incoming bitmap display mode to 16MA if (EColor16MU == bitmap->DisplayMode()) { bitmap->SetDisplayMode(EColor16MA); } AknIconUtils::ScaleBitmapL(iDrawRect, iBitmap, bitmap); CleanupStack::PopAndDestroy(bitmap); } }
TInt CScreenCaptureUtil::CopySurfaceToBitmapL(CFbsBitmap& aCopyToBitmap) { RSurfaceManager::TInfoBuf infoBuf; RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); User::LeaveIfError(iSurfaceManager.SurfaceInfo(iLocalSurface, infoBuf)); TInt bytesPerPixel=0; TDisplayMode bitmapMode = ENone; switch (info.iPixelFormat) { case EUidPixelFormatXRGB_8888: { bitmapMode = EColor16MU; bytesPerPixel = 4; break; } default: { return KErrCorrupt; } } if ((aCopyToBitmap.SizeInPixels() != info.iSize) || (aCopyToBitmap.DisplayMode() != bitmapMode)) { return KErrCorrupt; } RChunk chunk; CleanupClosePushL(chunk); User::LeaveIfError(iSurfaceManager.MapSurface(iLocalSurface, chunk)); TUint8* surfacePtr = chunk.Base(); TUint8* bitmapPtr = (TUint8*)aCopyToBitmap.DataAddress(); TInt copyBytes=info.iSize.iWidth*bytesPerPixel; for (TInt y=0; y<info.iSize.iHeight; y++) { Mem::Copy(bitmapPtr,surfacePtr,copyBytes); surfacePtr += info.iStride; bitmapPtr += aCopyToBitmap.DataStride(); } CleanupStack::PopAndDestroy(&chunk); return KErrNone; }
/** Adds a VGImage to the cache using the associated CFbsBitmap as a reference. A new image cache item is created which stores the VGImage, the size of the image in pixels, the serial number of the CFbsBitmap (which acts as a unique identifier) and the touch count of the CFbsBitmap. The touch count determines the number of times the underlying data of the CFbsBitmap has changed. The least-recently used items will be removed from the cache to create space for the new item, if needed. @param aBitmap The bitmap from which the VGImage was created. @param aImage The VGImage to store in the cache. @param aOrigin The origin used to create a tiled VGImage. @return ETrue if the VGImage was successfully added to the cache, EFalse if not. */ TBool CVgImageCache::AddImage(const CFbsBitmap& aBitmap, VGImage& aImage, const TPoint& aOrigin) { // Calculate approximate size in bytes of image TDisplayMode vgCompatibleDisplayMode = ClosestVgCompatibleDisplayMode(aBitmap.DisplayMode()); TSize imageSize = aBitmap.SizeInPixels(); TInt dataStride = CFbsBitmap::ScanLineLength(imageSize.iWidth, vgCompatibleDisplayMode); TInt imageSizeInBytes = imageSize.iHeight * dataStride; // if size of image is too large to fit in cache if(imageSizeInBytes > iMaxCacheSizeInBytes) { return EFalse; } CVgImageCacheItem* newItem = new CVgImageCacheItem; if (newItem == NULL) { return EFalse; } // check there is enough room in the cache // i.e. less than user-specified max memory allowed for cache // if not enough space, remove items from end of cache until enough space is available. while(iMaxCacheSizeInBytes < iCacheSizeInBytes + imageSizeInBytes) { DeleteItem(iVgImageCache.Last()); } newItem->iSerialNumber = aBitmap.SerialNumber(); newItem->iImage = aImage; newItem->iTouchCount = aBitmap.TouchCount(); newItem->iOrigin = aOrigin; newItem->iImageSizeInBytes = imageSizeInBytes; TInt err = iCacheItemMap.Insert(newItem->iSerialNumber, newItem); if (err != KErrNone) { delete newItem; return EFalse; } iVgImageCache.AddFirst(*newItem); iCacheSizeInBytes += newItem->iImageSizeInBytes; return ETrue; }
/* * Landmark objects will make use of an SVG file for rendering (demo purposes) */ void CLMXObject::ConstructL() { _LIT(KIconFile, "\\resource\\apps\\Landmarks_0x2002E1AF.mif"); CGulIcon* icon = CreateIconL(KIconFile, EMbmLandmarks_0x2002e1afIcon, EMbmLandmarks_0x2002e1afIcon_mask); CleanupStack::PushL(icon); CFbsBitmap* bitmap = icon->Bitmap(); // Ownership NOT transferred CFbsBitmap* mask = icon->Mask(); // Ownership NOT transferred // Always expect 16M bitmap to make conversion to GL_RGBA easier if (bitmap->DisplayMode() != EColor16M) { bitmap = new(ELeave) CFbsBitmap; CleanupStack::PushL(bitmap); User::LeaveIfError(bitmap->Create(icon->Bitmap()->SizeInPixels(), EColor16M)); CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(bitmap); CleanupStack::PushL(bitmapDevice); CFbsBitGc* bitmapContext = 0; User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext)); CleanupStack::PushL(bitmapContext); bitmapContext->BitBlt(TPoint(0, 0), icon->Bitmap()); CleanupStack::PopAndDestroy(2, bitmapDevice); icon->SetBitmap(bitmap); // Ownership transferred CleanupStack::Pop(bitmap); } // Always expect 256 mask to make conversion to GL_RGBA easier if (mask->DisplayMode() != EGray256) { mask = new(ELeave) CFbsBitmap; CleanupStack::PushL(mask); User::LeaveIfError(mask->Create(icon->Mask()->SizeInPixels(), EGray256)); CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(mask); CleanupStack::PushL(bitmapDevice); CFbsBitGc* bitmapContext = 0; User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext)); CleanupStack::PushL(bitmapContext); bitmapContext->BitBlt(TPoint(0, 0), icon->Mask()); CleanupStack::PopAndDestroy(2, bitmapDevice); icon->SetMask(mask); // Ownership transferred CleanupStack::Pop(mask); } // Now bitmap and mask point to either original or converted bitmaps, // and ownership belongs to icon const TSize bitmapSize = bitmap->SizeInPixels(); // sizeof(TUint32) == sizeof(RGBA) const TInt dataSize = bitmapSize.iWidth * bitmapSize.iHeight * sizeof(TUint32); TUint8* data = new(ELeave) TUint8[dataSize]; // Perform copy and conversion from BGR(A) to RGB(A) bitmap->LockHeap(); mask->LockHeap(); // TODO: Alpha component removed, as it seems to be corrupted from // subsequent reads from SVG file TUint8* rgb = reinterpret_cast<TUint8*>(bitmap->DataAddress()); // TUint8* alpha = reinterpret_cast<TUint8*>(mask->DataAddress()); for(TInt i = 0, j = 0; i < dataSize; i += 4, j += 3) { data[i + 0] = rgb[j + 2]; data[i + 1] = rgb[j + 1]; data[i + 2] = rgb[j + 0]; data[i + 3] = 0xc0; //alpha[i / 4]; } // Generate OpenGL texture ::glGenTextures(1, &iTextureId); ::glBindTexture(GL_TEXTURE_2D, iTextureId); ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); ::glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); ::glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bitmapSize.iWidth, bitmapSize.iHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); mask->UnlockHeap(); bitmap->UnlockHeap(); delete data; CleanupStack::PopAndDestroy(icon); }
/* ----------------------------------------------------------------------------- ProcessL Process image referenced by aImage (modify aImage). May leave with KErrNoMemory if no memory available Return Values: none ----------------------------------------------------------------------------- */ void CDCDithering::ProcessL(CFbsBitmap& aImage) { TUint r, g, b; // Color components TUint8* dataPtr; // Pointer to data //Dithering variables, init to 0 TInt count=0; TInt16 dither=0; //EColor16M image is needed if (aImage.DisplayMode() != EColor16M || aImage.DisplayMode() != EColor16M) return; // Line Buffer and pointer to the data TUint imageWidth = aImage.SizeInPixels().iWidth; TUint scanLineLengthInBytes = aImage.ScanLineLength(imageWidth, aImage.DisplayMode()); //Allocate buffer for scanline iScanLineBuffer = HBufC8::NewMaxL(scanLineLengthInBytes); //Pointer to scanline TPtr8 linePtr = iScanLineBuffer->Des(); //Step through image lines for (TInt lineNo=0; lineNo<aImage.SizeInPixels().iHeight; ++lineNo) { //Get line aImage.GetScanLine(linePtr, TPoint(0, lineNo), imageWidth, aImage.DisplayMode()); //CHECK! CONST_CAST not used in every algorithm which way is better? dataPtr = CONST_CAST(TUint8*, linePtr.Ptr()); //Step through image pixels for (TUint x=0; x < imageWidth; ++x) { // Get original values b = *dataPtr++; g = *dataPtr++; r = *dataPtr++; //Compute DCDithering factor from base count switch (count&1) { case 0: dither = (TInt16)(dither*0x7ffd); break; case 1: dither = (TInt16)(dither+0x7f21); break; } //Add DCDithering factor, adjust gain according to quantization factors. r = Limit255((TInt)r + (dither>>13)); g = Limit255((TInt)g - (dither>>14)); b = Limit255((TInt)b + (dither>>13)); //Move to the previous pixel dataPtr -= 3; /* Set the result */ *dataPtr++ = (TUint8)b; *dataPtr++ = (TUint8)g; *dataPtr++ = (TUint8)r; //Increase bae count count++; } //Set scan line aImage.SetScanLine(linePtr, lineNo); } //Free allocated memory delete(iScanLineBuffer); iScanLineBuffer = 0; }
void S60ImageUtil::calculateVisibleRect(Image* aImage) { if (aImage->iHasMask) { CFbsBitmap* mask = aImage->GetMask(); TInt xmin = aImage->iWidth; TInt xmax = 0; TInt ymin = aImage->iHeight; TInt ymax = 0; #if defined USE_AKN_LIB //Iterating the pixels with GetPixel() works for sure on all symbian, //but it's pretty slow and we have to look at every one pixel. //On a 800 x 800 image we do 640 000 GetPixel() iterations. TRgb color; TRgb white(255, 255, 255); for (TInt y = 0; y < aImage->iHeight; y++) { for (TInt x = 0; x < aImage->iWidth; x++) { mask->GetPixel(color, TPoint(x, y)); if (color == white) { if (xmin > x) { xmin = x; } if (xmax < x) { xmax = x; } if (ymin > y) { ymin = y; } if (ymax < y) { ymax = y; } } } } #else //Iterating the pixels by hand in memory probably works on all symbian, //it's much faster since we look at 8 pixels at a time, //It needs some testing and verification. //On a 800 x 800 image we do roughly 83 000 iterations. TDisplayMode dMode = mask->DisplayMode(); if (dMode == EGray2) { # ifndef NAV2_CLIENT_SERIES60_V1 mask->LockHeap(); # endif TUint32* imgPtr = mask->DataAddress(); TSize imgSize = mask->SizeInPixels(); TInt imgByteWidth = imgSize.iWidth >> 3; TInt imgBitsLeft = imgSize.iWidth % 8; TInt lineLength = CFbsBitmap::ScanLineLength(imgSize.iWidth, dMode); TUint8* pCurrByteLine = (TUint8*) imgPtr; TUint8 currByte; TInt currXPixelOffset; TInt currXPixel; for (TInt y = 0; y < imgSize.iHeight; y++) { for (TInt x = 0; x < imgByteWidth; x++) { currByte = pCurrByteLine[x]; //If currByte is != 0, it contains at least one white pixel. if (currByte) { if (ymin > y) { ymin = y; } if (ymax < y) { ymax = y; } currXPixelOffset = x << 3; //Check if this byte of pixels might contain xmin or xmax. if ((currXPixelOffset < xmin) || ((currXPixelOffset + 7) > xmax)) { for (TInt b = 0; b < 8; b++) { //Some of the 8 pixels in the byte are visible. //Find which ones that mather for the x-axis. if (currByte & (1 << b)) { currXPixel = currXPixelOffset + b; if (xmin > currXPixel) { xmin = currXPixel; } if (xmax < currXPixel) { xmax = currXPixel; } } } } } } //Here we take care of bit padded bytes when the //image width is not evenly dividable by a byte. if (imgBitsLeft != 0) { currByte = pCurrByteLine[imgByteWidth]; currXPixelOffset = imgByteWidth << 3; for (TInt b = 0; b < imgBitsLeft; b++) { if (currByte & (1 << b)) { currXPixel = currXPixelOffset + b; if (xmax < currXPixel) { xmax = currXPixel; } } } } //Move to next line in image. pCurrByteLine = pCurrByteLine + lineLength; } }
void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) { if (type == QPixmapData::SgImage && pixmap) { #if defined(QT_SYMBIAN_SUPPORTS_SGIMAGE) && !defined(QT_NO_EGL) RSgImage *sgImage = reinterpret_cast<RSgImage*>(pixmap); destroyImages(); prevSize = QSize(); TInt err = 0; RSgDriver driver; err = driver.Open(); if (err != KErrNone) { cleanup(); return; } if (sgImage->IsNull()) { cleanup(); driver.Close(); return; } TSgImageInfo sgImageInfo; err = sgImage->GetInfo(sgImageInfo); if (err != KErrNone) { cleanup(); driver.Close(); return; } pfnVgCreateEGLImageTargetKHR vgCreateEGLImageTargetKHR = (pfnVgCreateEGLImageTargetKHR) eglGetProcAddress("vgCreateEGLImageTargetKHR"); if (eglGetError() != EGL_SUCCESS || !(QEgl::hasExtension("EGL_KHR_image") || QEgl::hasExtension("EGL_KHR_image_pixmap")) || !vgCreateEGLImageTargetKHR) { cleanup(); driver.Close(); return; } const EGLint KEglImageAttribs[] = {EGL_IMAGE_PRESERVED_SYMBIAN, EGL_TRUE, EGL_NONE}; EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)sgImage, (EGLint*)KEglImageAttribs); if (eglGetError() != EGL_SUCCESS) { cleanup(); driver.Close(); return; } vgImage = vgCreateEGLImageTargetKHR(eglImage); if (vgGetError() != VG_NO_ERROR) { cleanup(); QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); driver.Close(); return; } w = sgImageInfo.iSizeInPixels.iWidth; h = sgImageInfo.iSizeInPixels.iHeight; d = 32; // We always use ARGB_Premultiplied for VG pixmaps. is_null = (w <= 0 || h <= 0); source = QImage(); recreate = false; prevSize = QSize(w, h); setSerialNumber(++qt_vg_pixmap_serial); // release stuff QEgl::eglDestroyImageKHR(QEgl::display(), eglImage); driver.Close(); #endif } else if (type == QPixmapData::FbsBitmap) { CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); bool deleteSourceBitmap = false; #ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE // Rasterize extended bitmaps TUid extendedBitmapType = bitmap->ExtendedBitmapType(); if (extendedBitmapType != KNullUid) { bitmap = createBlitCopy(bitmap); deleteSourceBitmap = true; } #endif if (bitmap->IsCompressedInRAM()) { bitmap = createBlitCopy(bitmap); deleteSourceBitmap = true; } TDisplayMode displayMode = bitmap->DisplayMode(); QImage::Format format = qt_TDisplayMode2Format(displayMode); TSize size = bitmap->SizeInPixels(); bitmap->BeginDataAccess(); uchar *bytes = (uchar*)bitmap->DataAddress(); QImage img = QImage(bytes, size.iWidth, size.iHeight, format); img = img.copy(); bitmap->EndDataAccess(); if(displayMode == EGray2) { //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid //So invert mono bitmaps so that masks work correctly. img.invertPixels(); } else if(displayMode == EColor16M) { img = img.rgbSwapped(); // EColor16M is BGR } fromImage(img, Qt::AutoColor); if(deleteSourceBitmap) delete bitmap; } }
/* ------------------------------------------------------------------------------- internal icon re-sizer function ------------------------------------------------------------------------------- */ CGulIcon* CYBRecognizer1::GetListIconL(const TDesC& aFileName,TInt aImage,TInt aMask, TSize aSize) { CGulIcon* RetIcon(NULL); TBool OkToAdd(EFalse); CFbsBitmap* MyBitmap = new(ELeave)CFbsBitmap(); CleanupStack::PushL(MyBitmap); CFbsBitmap* MyMask = new(ELeave)CFbsBitmap(); CleanupStack::PushL(MyMask); if(KErrNone == MyBitmap->Load(aFileName,aImage)) { if(KErrNone == MyMask->Load(aFileName,aMask)) { OkToAdd = ETrue; } } if(OkToAdd) { TSize ImgSiz = MyBitmap->SizeInPixels(); if(aSize.iWidth != ImgSiz.iWidth || aSize.iHeight!= ImgSiz.iHeight) { CFbsBitmap* TmpBackBitmap = new(ELeave)CFbsBitmap(); CleanupStack::PushL(TmpBackBitmap); if(KErrNone == TmpBackBitmap->Create(aSize,MyBitmap->DisplayMode())) { CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(TmpBackBitmap); CleanupStack::PushL(bitmapDevice); CFbsBitGc* graphicsContext = NULL; User::LeaveIfError(bitmapDevice->CreateContext(graphicsContext)); CleanupStack::PushL(graphicsContext); graphicsContext->DrawBitmap(TRect(0,0,aSize.iWidth,aSize.iHeight),MyBitmap); CleanupStack::PopAndDestroy(2);//graphicsContext,bitmapDevice, } CFbsBitmap* TmpBackMask = new(ELeave)CFbsBitmap(); CleanupStack::PushL(TmpBackMask); if(KErrNone == TmpBackMask->Create(aSize,MyMask->DisplayMode())) { CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(TmpBackMask); CleanupStack::PushL(bitmapDevice); CFbsBitGc* graphicsContext = NULL; User::LeaveIfError(bitmapDevice->CreateContext(graphicsContext)); CleanupStack::PushL(graphicsContext); graphicsContext->DrawBitmap(TRect(0,0,aSize.iWidth,aSize.iHeight),MyMask); CleanupStack::PopAndDestroy(2);//graphicsContext,bitmapDevice, } CleanupStack::Pop(2);//TmpBackBitmap, TmpBackMask RetIcon = CGulIcon::NewL(TmpBackBitmap, TmpBackMask); } } if(!RetIcon && OkToAdd) { CleanupStack::Pop(2);//MyBitmap, MyMask RetIcon = CGulIcon::NewL(MyBitmap, MyMask); } else { CleanupStack::PopAndDestroy(2);//MyBitmap, MyMask } return RetIcon; }