×

Discussion Board

Results 1 to 3 of 3
  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    9

    Question Synchronous CImageDecoder fine for files, NOT for descriptors

    Hi all. Have been bashing my head against the wall for 2 days trying to modify my texture loader to load in JPEGs instead of BMPs.
    I'm using CImageDecoder to do the decoding into a CFbsBitmap, which I guess is a pretty common thing to do.

    The following code works fine:

    Code:
    CImageDecoder* jpegDecoder = CImageDecoder::FileNewL(fs, aJPGFileName, CImageDecoder::EOptionAlwaysThread);
    CleanupStack::PushL(jpegDecoder);
    		
    TFrameInfo frameInfo = jpegDecoder->FrameInfo(0);
    		
    CFbsBitmap *tex = new (ELeave) CFbsBitmap();
    tex->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode);
    CleanupStack::PushL(tex);
    		
    TRequestStatus status;
    jpegDecoder->Convert( &status, *tex);
    User::WaitForRequest(status);			// Convert() is asynchronous, wait on it
    		
    		
    // Now assign the textures (my own function, mostly just openGL calls)
    BMPtoGL(tex);
    			
    CleanupStack::PopAndDestroy(2);	// tex, jpegDecoder
    BUT when I go to use the same code, only using a JPEG stored in a HBufC8 descriptor (extracted from a zip-file), the system hangs on User::WaitForRequest(). (That is, the carbide emulator, I haven't bothered trying on a phone yet!)

    I don't understand the difference, why the above code should work fine with files but not descriptors?

    In an attempt to remedy this I spent the day brushing up my knowledge of Active Objects and setup a CActive derivative class, using a CImageDecoder as a service provider, using which I am currently able to do nothing - besides which, even if it was working - I don't want it to be asynchronous! I don't want to do anything else until the JPEGs are loaded, I don't mind waiting half a second.


    Any clues how to make a synchronous JPEG decoder based on descriptor memory?

    Big thanks to anyone that can help!

    Mete

  2. #2
    Nokia Developer Moderator
    Join Date
    Feb 2006
    Location
    Oslo, Norway
    Posts
    28,673

    Re: Synchronous CImageDecoder fine for files, NOT for descriptors

    Check if decoding has some trace in the logfile: http://wiki.forum.nokia.com/index.php/Epocwind.out
    Anyway, it can happen that it does not work.
    Note that you can serialize asynchronous happenings via starting a nested scheduler loop (and stopping it from the RunL of the AO).
    For this case simple CActiveScheduler::Start and Stop should work (the sophisticated way would be using CActiveSchedulerWait)
    Last edited by wizard_hu_; 2009-05-05 at 09:53.

  3. #3
    Registered User
    Join Date
    Dec 2008
    Posts
    9

    Cool Re: Synchronous CImageDecoder fine for files, NOT for descriptors

    Ah brilliant! CActiveSchedulerWait was just the fix I needed.

    This is what I did, for anyone else that has the same problem:

    1) Went back to my Active Object CActive class derivative, CH3DJPEGLoader which used the CImageDecoder as a service provider.

    2) Added a class member CActiverSchedulerWait* iSynchroniser to CH3DJPEGLoader.

    3) Called the methods iSynchroniser->Start() at the end of my function call to start the decode service, and iSynchroniser->AsyncStop() at the end of my RunL() implementation (which of course gets called once the service is finished, returning a value to CActive::iStatus)

    That is, my two key functions (abbreviated) for CH3DJPEGLoader look like this:

    Code:
    /**
     * Commence conversion, and block active scheduler, waiting on results from RunL.
     */
    void CH3DJPEGLoader::CommenceConversionL(RFs fs, TPtr8 aJPEGDesc)
    	{
    		
    	// Set up a converter
    	iConverter = CImageDecoder::DataNewL(fs, aJPEGDesc, CImageDecoder::EOptionAlwaysThread);
    	
            ...
    
    	// make it synchronous with a CActiveSchedulerWait object
    	iSynchroniser = new (ELeave) CActiveSchedulerWait();
    			
            // Send request to asynchronous function CImageDecoder::Convert
    	iConverter->Convert(&iStatus, *iBMP);
    	SetActive();
    	
    	// Waiting for results!
    	iSynchroniser->Start();
    	
    	}

    Code:
    /**
     * On completion, RunL is called - inherited from CActive.
     */
    void CH3DJPEGLoader::RunL()
    	{
    
    	
    	if( iStatus == KErrUnderflow ) // continue converting
            {
            iConverter->ContinueConvert( &iStatus );
            SetActive();
            }
    	
    	else if( iStatus == KErrNone ) 
    	    {
    		 // Nothing to do, we're done
    	    }
    	
            else // error
                {
                ConsoleError(_L("Error while opening image:%d" ), iStatus.Int()); // ConsoleError is my own error reporting function
                }
    	
            // Stop blocking the Active Scheduler
    	iSynchroniser->AsyncStop();
    	
    	// Free up resources for next time.
    	if(iConverter)
    		{
    		delete iConverter;
    		iConverter = NULL;
    		}
    	if(iSynchroniser)
    		{
    		delete iSynchroniser;
    		iSynchroniser = NULL;
    		}
    	}

    That should be enough to help anyone else out that's stuck on the same!
    Cheers,
    Mete

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
×