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
        }
Example #5
0
/*
 * 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);
}