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 }
//------------------------------------------------------------------------ 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 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 }
//------------------------------------------------------------------------ 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 }
/* * 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); }