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

  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;
         }
      }
Exemple #16
0
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;
}