examples/Multimedia/ICL/ICLExample/icldecodeexample.cpp

Go to the documentation of this file.
00001 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 // 
00015 //
00016 
00022 #include "iclexample.h"
00023 
00052 void CIclExample::DecodeFromDescriptorToBitmapL(const TDesC& aFileName)
00053         {
00054         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00055 
00056         // Try to create the decoder. If it's successful the image headers are read.
00057         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00058         CleanupStack::PushL(imageDecoder);
00059 
00060         // Decoder found, create a bitmap for it to render the image to.
00061         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00062         CleanupStack::PushL(destBitmap);
00063 
00064         // Since the image header has been read we can find out the image size and
00065         // can create the bitmap to match the display mode we wish to support
00066         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00067         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00068 
00069         // See Note 1
00070         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00071 
00072     // Convert the image (first frame)
00073         imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00074 
00075         // See Note 2
00076         CActiveScheduler::Start();
00077         User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.
00078 
00079         // Just verifying the presence of some output. The image can also be displayed instead.
00080         _LIT(KOutputFile, "c:\\ICLExample\\DecodedBitmapFromDescriptor.mbm");
00081         destBitmap->Save(KOutputFile); // Ignore return code.
00082 
00083         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
00084         }
00085 
00086 
00102 void CIclExample::DecodeFromFileToBitmapL(const TDesC& aFileName)
00103         {
00104         // Create the decoder, passing the filename. The image is recognised by the
00105         // Image Conversion Library, an appropriate codec plugin loaded and the image
00106         // headers parsed.
00107         // If the image is not recognised or valid then the call will leave with an error
00108         CImageDecoder* imageDecoder = CImageDecoder::FileNewL(iFs, aFileName);
00109         CleanupStack::PushL(imageDecoder);
00110 
00111         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00112         CleanupStack::PushL(destBitmap);
00113 
00114         // Since the image header has been parsed we can find out the image size and
00115         // can create the bitmap to match the display mode we wish to support
00116         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00117         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00118 
00119         // See Note 1
00120         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00121 
00122         // Convert the image (first frame)
00123         imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00124 
00125         // See Note 2
00126         CActiveScheduler::Start();
00127         User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.
00128 
00129         // Just verifying the presence of some output. The image can also be displayed instead.
00130         _LIT(KOutputFile, "c:\\ICLExample\\DecodedBitmapFromFile.mbm");
00131         destBitmap->Save(KOutputFile);  // Ignore return code.
00132 
00133         CleanupStack::PopAndDestroy(3); // activeListener, destBitmap and imageDecoder
00134         }
00135 
00136 
00149 void CIclExample::DecodeToYuvFrameL(const TDesC& aFileName)
00150         {
00151         RChunk chunk;
00152         TInt imageSizeInBytes = 0;
00153 
00154         // Create the decoder, passing the filename. The image is recognised by the
00155         // Image Conversion Library, an appropriate codec plugin loaded and the image
00156         // headers parsed.
00157         // If the image is not recognised or valid then the call will leave with an error
00158         CJPEGImageFrameDecoder* jpegImageDecoder = static_cast<CJPEGImageFrameDecoder*>(CJPEGImageFrameDecoder::FileNewL(iFs, aFileName));
00159         CleanupStack::PushL(jpegImageDecoder);
00160 
00161         // Check the image whether it's supporting YUV or not
00162         if (jpegImageDecoder->RecommendedBufferSize(imageSizeInBytes) == EFalse)
00163                 {
00164                 User::Leave(KErrNotSupported);
00165                 }
00166 
00167         User::LeaveIfError(chunk.CreateGlobal(KRChunk, imageSizeInBytes, imageSizeInBytes, EOwnerProcess));
00168         CleanupClosePushL(chunk);
00169 
00170         // Create an empty imageframe
00171         CImageFrame* imageFrame = CImageFrame::NewL(&chunk, imageSizeInBytes, 0);
00172         CleanupStack::PushL(imageFrame);
00173 
00174         // See Note 1
00175         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00176 
00177         // Convert the image to YUV image frame
00178         jpegImageDecoder->ConvertFrame(&activeListener->iStatus, *imageFrame, KFirstFrame);
00179 
00180         // See Note 2
00181         CActiveScheduler::Start();
00182         User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.
00183 
00184         // NOTE: YUV pixel buffer can be used if appropriate screen driver is available
00185 
00186         CleanupStack::PopAndDestroy(4); // activeListener, imageFrame, chunk and jpegImageDecoder
00187     }
00188 
00189 
00201 void CIclExample::AccessThumbnailToDecodeL(const TDesC& aFileName)
00202         {
00203         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00204 
00205         // Create the decoder, passing the image buffer. The image is recognised by the
00206         // Image Conversion Library, an appropriate codec plugin loaded and the image
00207         // headers parsed.
00208         // If the image is not recognised or valid then the call will leave with an error
00209         CJPEGExifDecoder* exifDecoder = static_cast<CJPEGExifDecoder*>(CJPEGExifDecoder::DataNewL(iFs, imageInMemory));
00210         CleanupStack::PushL(exifDecoder);
00211 
00212         exifDecoder->SetImageTypeL(CImageDecoder::EImageTypeThumbnail);
00213 
00214         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00215         CleanupStack::PushL(destBitmap);
00216 
00217         // Since the image header has been parsed we can find out the image size and
00218         // can create the bitmap to match the display mode we wish to support
00219         const TFrameInfo& frameInfo = exifDecoder->FrameInfo(KFirstFrame);
00220         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00221 
00222         // See Note 1
00223         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00224 
00225         // Convert the image
00226         exifDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00227 
00228         // See Note 2
00229         CActiveScheduler::Start();
00230         User::LeaveIfError(activeListener->iStatus.Int()); // access and decode to thumbnail complete either display the image or report an error.
00231 
00232         // Just verifying the presence of some output. The image can also be displayed instead.
00233 
00234         _LIT(KOutputFile, "c:\\ICLExample\\DecodedDescThumbnail.mbm");
00235         destBitmap->Save(KOutputFile);  // Ignore return code.
00236 
00237         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, exifDecoder and imageInMemory
00238         }
00239 
00240 
00254 void CIclExample::AccessExifMetadataL(const TDesC& aFileName)
00255         {
00256         // Create the decoder, passing the image buffer. The image is recognised by the
00257         // Image Conversion Library, an appropriate codec plugin loaded and the image
00258         // headers parsed.
00259         // If the image is not recognised or valid then the call will leave with an error
00260         CJPEGExifDecoder* exifDecoder = static_cast<CJPEGExifDecoder*>(CJPEGExifDecoder::FileNewL(iFs, aFileName));
00261         CleanupStack::PushL(exifDecoder);
00262 
00263         // Create a MExifMetadata object and Initializes to metadata associated with the CJPEGExifDecoder
00264         MExifMetadata* metaData = exifDecoder->ExifMetadata();
00265         if (metaData != NULL)
00266                 {
00267                 // Create a TExifReaderUtility object and pass the metadata to read it
00268                 TExifReaderUtility reader(metaData);
00269 
00270                 HBufC8* buffer8Bit = NULL;
00271                 User::LeaveIfError(reader.GetImageDescription(buffer8Bit));
00272 
00273                 // NOTE: Image metadata buffer can be used here
00274 
00275                 delete buffer8Bit;
00276                 }
00277 
00278         CleanupStack::PopAndDestroy(exifDecoder);
00279         }
00280 
00281 
00298 void CIclExample::DecodeTheThumbnailL(const TDesC& aFileName)
00299         {
00300         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00301 
00302         // Create the decoder, passing the image buffer . The image is recognised by the
00303         // Image Conversion Library, an appropriate codec plugin loaded and the image
00304         // headers parsed.
00305         // If the image is not recognised or valid then the call will leave with an error
00306         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00307         CleanupStack::PushL(imageDecoder);
00308 
00309         // Set the image type to thumbnail to decode only the thumbnail part of the image
00310         imageDecoder->SetImageTypeL(CImageDecoder::EImageTypeThumbnail);
00311 
00312         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00313         CleanupStack::PushL(destBitmap);
00314 
00315         // Since the image header has been parsed we can find out the image size and
00316         // can create the bitmap to match the display mode we wish to support.
00317         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00318         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00319 
00320         // See Note 1
00321         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00322 
00323         // Convert the thumbnail part of the image
00324         imageDecoder->Convert(&activeListener->iStatus, *destBitmap);
00325 
00326         // See Note 2
00327         CActiveScheduler::Start();
00328         User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.
00329 
00330         // Just verifying the presence of some output. The image can also be displayed instead.
00331         _LIT(KOutputFile, "c:\\ICLExample\\DecodedBitmapWithThumbnail.mbm");
00332         destBitmap->Save(KOutputFile);
00333 
00334         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
00335         }
00336 
00337 
00351 void CIclExample::DecodeUsingSepThreadL(const TDesC& aFileName)
00352         {
00353         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00354 
00355         // Create the decoder, passing the image buffer and decoder option as EOptionAlwaysThread. The image is recognised by the
00356         // Image Conversion Library, an appropriate codec plugin loaded and the image
00357         // headers parsed.
00358         // If the image is not recognised or valid then the call will leave with an error
00359         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory, CImageDecoder::EOptionAlwaysThread);
00360         CleanupStack::PushL(imageDecoder);
00361 
00362         // Since the image header has been parsed we can find out the image size and
00363         // can create the bitmap to match the display mode we wish to support
00364         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00365 
00366         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00367         CleanupStack::PushL(destBitmap);
00368         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00369 
00370         // See Note 1
00371         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00372 
00373         // Convert the image
00374         imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00375 
00376         // See Note 2
00377         CActiveScheduler::Start();
00378         User::LeaveIfError(activeListener->iStatus.Int()); // decode complete using separate thread either display the image or report an error.
00379 
00380         // Just verifying the presence of some output. The image can also be displayed instead.
00381         _LIT(KOutputFile, "c:\\ICLExample\\DecodedBitmapsUsingSeparateThread.mbm");
00382         destBitmap->Save(KOutputFile);  // Ignore return code.
00383 
00384         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
00385         }
00386 
00387 
00401 void CIclExample::DecodeToHalfFourthAndEighthSizedBitmapL(const TDesC& aFileName)
00402         {
00403         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00404 
00405         // Create the decoder, passing the image buffer. The image is recognised by the
00406         // Image Conversion Library, an appropriate codec plugin loaded and the image
00407         // headers parsed.
00408         // If the image is not recognised or valid then the call will leave with an error
00409         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00410         CleanupStack::PushL(imageDecoder);
00411 
00412         // Since the image header has been parsed we can find out the image size and
00413         // can create the bitmap to match the display mode we wish to support
00414         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00415 
00416         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00417         CleanupStack::PushL(destBitmap);
00418 
00419         // Create a new TSize object which is half the size of original size
00420         // and pass this size to the destination bitmap
00421         TSize halfSize;
00422         TInt reductionFactor = 1; // half size, but quarter (2) and eighth (3) size are possible too
00423         User::LeaveIfError(imageDecoder->ReducedSize(frameInfo.iOverallSizeInPixels, reductionFactor, halfSize));
00424         User::LeaveIfError(destBitmap->Create(halfSize, frameInfo.iFrameDisplayMode));
00425 
00426         // See Note 1
00427         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00428 
00429         // Convert the image to half sized bitmap
00430         imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00431 
00432         // See Note 2
00433         CActiveScheduler::Start();
00434         User::LeaveIfError(activeListener->iStatus.Int()); // decode to half sized bitmap complete either display the image or report an error.
00435 
00436 
00437         // Just verifying the presence of some output. The image can also be displayed instead.
00438         _LIT(KOutputFile, "c:\\ICLExample\\HalfSizeDecodedBitmap.mbm");
00439         destBitmap->Save(KOutputFile);
00440 
00441         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
00442         }
00443 
00444 
00458 void CIclExample::DecodeUsingImageMaskL(const TDesC& aFileName)
00459         {
00460         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00461 
00462         // Create the decoder, passing the image buffer. The image is recognised by the
00463         // Image Conversion Library, an appropriate codec plugin loaded and the image
00464         // headers parsed.
00465         // If the image is not recognised or valid then the call will leave with an error
00466         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00467         CleanupStack::PushL(imageDecoder);
00468 
00469         // Since the image header has been parsed we can find out the image size and
00470         // can create the bitmap to match the display mode we wish to support
00471         // for both destination bitmap and destination mask bitmap
00472         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00473 
00474         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00475         CleanupStack::PushL(destBitmap);
00476         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00477 
00478         // See note 1.
00479         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00480 
00481         if (frameInfo.iFlags & TFrameInfo::ETransparencyPossible)
00482                 {
00483                 // we can decode the mask
00484                 CFbsBitmap* destBitmapMask = new(ELeave) CFbsBitmap();
00485                 CleanupStack::PushL(destBitmapMask);
00486 
00487                 // mask bitmap type depends on presence of alpha channel
00488                 TDisplayMode bitmapMode = (frameInfo.iFlags & TFrameInfo::EAlphaChannel) ? EGray256 : EGray2;
00489                 User::LeaveIfError(destBitmapMask->Create(frameInfo.iOverallSizeInPixels, bitmapMode));
00490 
00491                 // Decoding the frame and separating the mask from the main image.
00492                 imageDecoder->Convert(&activeListener->iStatus, *destBitmap, *destBitmapMask, KFirstFrame);
00493 
00494                 // See Note 2
00495                 CActiveScheduler::Start();
00496                 User::LeaveIfError(activeListener->iStatus.Int()); // decode complete using an image mask either display the image or report an error.
00497 
00498                 // Just verifying the presence of some output. The image can also be displayed instead.
00499                 _LIT(KOutputFile1, "c:\\ICLExample\\DecodedBitmapMask.mbm");
00500                 _LIT(KOutputFile2, "c:\\ICLExample\\DecodedBitmapWithMask.mbm");
00501                 destBitmapMask->Save(KOutputFile1);     // Ignore error code.
00502                 destBitmap->Save(KOutputFile2);         // Ignore error code.
00503 
00504                 CleanupStack::PopAndDestroy(); // destBitmapMask
00505                 }
00506         else
00507                 {
00508                 // no mask available - in this case we decode without mask
00509                 // Convert the image
00510                 imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00511 
00512                 // See Note 2
00513                 CActiveScheduler::Start();
00514                 User::LeaveIfError(activeListener->iStatus.Int()); // decode complete without using mask either display the image or report an error.
00515 
00516                 // Just verifying the presence of some output. The image can also be displayed instead.
00517                 _LIT(KOutputFile, "c:\\ICLExample\\DecodedBitmapWithoutMask.mbm");
00518                 destBitmap->Save(KOutputFile);  // Ignore error code.
00519                 }
00520 
00521         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
00522         }
00523 
00524 
00539 void CIclExample::MultiFrameImageDecodeL(const TDesC& aFileName)
00540         {
00541         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00542 
00543         // Create the decoder, passing the image buffer. The image is recognised by the
00544         // Image Conversion Library, an appropriate codec plugin loaded and the image
00545         // headers parsed.
00546         // If the image is not recognised or valid then the call will leave with an error
00547         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00548         CleanupStack::PushL(imageDecoder);
00549 
00550         // Since the image header has been parsed we can find out the image size and
00551         // can create the bitmap to match the display mode we wish to support
00552         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00553 
00554         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00555         CleanupStack::PushL(destBitmap);
00556         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00557 
00558         // Read the number of frames
00559         const TInt KNumberOfFrames = imageDecoder->FrameCount();
00560 
00561         // See Note 1
00562         CActiveListener* activeListener = CActiveListener::NewLC();
00563 
00564         // Iterate all the frames and display them
00565         for (TInt frameNumber = 0; frameNumber < KNumberOfFrames; ++frameNumber)
00566                 {
00567                 // See Note 1
00568                 activeListener->Initialize();
00569 
00570                 // Convert the multi frame image
00571                 imageDecoder->Convert(&activeListener->iStatus, *destBitmap, frameNumber);
00572 
00573                 // See Note 2
00574                 CActiveScheduler::Start();
00575                 User::LeaveIfError(activeListener->iStatus.Int()); // decode complete using multiframe image either display the image or report an error.
00576 
00577                 // DoSomethingWithTheFrame(destBitmap);
00578                 }
00579 
00580         _LIT(KOutputFile, "c:\\ICLExample\\DecodedMultiFrameBitmap.mbm");
00581     destBitmap->Save(KOutputFile);
00582 
00583         CleanupStack::PopAndDestroy(4); // activeListener, destBitmap, imageDecoder and imageInMemory
00584         }
00585 
00586 
00600 void CIclExample::DecodeUsingContinueConvertL(const TDesC& aFileName)
00601         {
00602         const TInt KChunkSize = 32;
00603 
00604         // Open the file containing the image and get the size.
00605         // Create a TPtr object to wrap the pointer to the buffer.
00606         RFile file;
00607         TUint flags = EFileShareReadersOnly | EFileStream | EFileRead;
00608         User::LeaveIfError(file.Open(iFs, aFileName, flags));
00609         CleanupClosePushL(file);
00610 
00611         // Read the file size
00612         TInt fileSize = 0;
00613         User::LeaveIfError(file.Size(fileSize));
00614 
00615         // Allocate the buffer for the file read in chunks
00616         HBufC8* buffer = HBufC8::NewLC(KChunkSize);
00617         TPtr8 bufferPtr(buffer->Des());
00618 
00619         // Read the first chunk from the file
00620         User::LeaveIfError(file.Read(bufferPtr, KChunkSize));
00621 
00622         // Create the decoder passing the File Server session and attempt to open the decoder
00623         CBufferedImageDecoder* decoder = CBufferedImageDecoder::NewL(iFs);
00624         CleanupStack::PushL(decoder);
00625 
00626         // The image is recognised by the Image Conversion Library, an appropriate codec plugin loaded and
00627         // the image headers parsed.
00628 
00629         decoder->OpenL(bufferPtr);
00630         while (!decoder->ValidDecoder())
00631                 {
00632                 User::LeaveIfError(file.Read(bufferPtr, KChunkSize));
00633         if(0 == bufferPtr.Length() )
00634             {//no more bytes read from file. so end of file reached.
00635             // image is corrupted as header processing is incomplete
00636             _LIT(KErrMsg,"Error: image corrupted. Processing will stop\n");
00637             iConsole->Printf(KErrMsg);
00638             User::Leave(KErrCorrupt);
00639             }           
00640                 decoder->AppendDataL(bufferPtr);
00641                 decoder->ContinueOpenL();
00642                 }
00643         // Make sure the header has been fully processed.
00644         while (!decoder->IsImageHeaderProcessingComplete())
00645                 {
00646                 User::LeaveIfError(file.Read(bufferPtr, KChunkSize));
00647         if(0 == bufferPtr.Length())
00648             {//no more bytes read from file. so end of file reached.
00649             break;
00650             }   
00651                 decoder->AppendDataL(bufferPtr);
00652 
00653                 }
00654 
00655         // Create the destination bitmap
00656         const TFrameInfo frameInfo = decoder->FrameInfo(KFirstFrame);
00657 
00658         CFbsBitmap* bitmap = new (ELeave) CFbsBitmap();
00659         CleanupStack::PushL(bitmap);
00660 
00661         User::LeaveIfError(bitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00662 
00663         // Convert the image (first frame) using Convert() function for the first piece of code
00664         // and ContinueConvert() function for the remaining piece of code
00665         // Feed the image data piece by piece into decoder while the error code is KErrUnderflow
00666         // until it becomes KErrNone (or any other system error code).
00667         TInt err = KErrNone;
00668         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00669         decoder->Convert(&activeListener->iStatus, *bitmap, KFirstFrame);
00670         CActiveScheduler::Start();
00671 
00672         while ((err = activeListener->iStatus.Int()) == KErrUnderflow)
00673                 {
00674                 if ((err != KErrNone) && (err != KErrUnderflow))
00675                         {
00676                         User::Leave(err);
00677                         }
00678 
00679                 User::LeaveIfError(file.Read(bufferPtr, KChunkSize));
00680         if(0 == bufferPtr.Length())
00681             {//no more bytes read from file. so end of file reached.
00682             break;
00683             }                           
00684                 decoder->AppendDataL(bufferPtr);
00685                 activeListener->Initialize();
00686                 decoder->ContinueConvert(&activeListener->iStatus);
00687                 CActiveScheduler::Start();
00688                 }
00689 
00690         // Just verifying the presence of some output. The image can also be displayed instead.
00691         _LIT(KOutputFile, "c:\\ICLExample\\DecodedBitmapWithContinueConvert.mbm");
00692         bitmap->Save(KOutputFile);
00693 
00694         CleanupStack::PopAndDestroy(5); // file, buffer, decoder, bitmap and activeListener
00695         }
00696 
00697 
00709 void CIclExample::DisplayingImageCommentsL(const TDesC& aFileName)
00710         {
00711         TInt numberOfImageComments;
00712 
00713         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00714 
00715         // Create the decoder, passing the image buffer. The image is recognised by the
00716         // Image Conversion Library, an appropriate codec plugin loaded and the image
00717         // headers parsed.
00718         // If the image is not recognised or valid then the call will leave with an error
00719         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00720         CleanupStack::PushL(imageDecoder);
00721 
00722         // Count the number of image comments attached to the specified image
00723         numberOfImageComments = imageDecoder->NumberOfImageComments();
00724 
00725         for (TInt commentNumber = 0; commentNumber < numberOfImageComments; ++commentNumber)
00726                 {
00727                 HBufC* imageComment = imageDecoder->ImageCommentL(commentNumber);
00728                 CleanupStack::PushL(imageComment);
00729 
00730                 TPtrC commentPtr = imageComment->Des();
00731 
00732                 // Decoded image comments can be displayed here
00733                 CleanupStack::PopAndDestroy(imageComment);
00734                 }
00735 
00736         CleanupStack::PopAndDestroy(2); // imageDecoder and imageInMemory
00737         }
00738 
00739 
00751 void CIclExample::DisplayingFrameCommentsL(const TDesC& aFileName)
00752         {
00753         TInt numberOfComments = 0;
00754 
00755         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00756 
00757         // Create the decoder, passing the image buffer. The image is recognised by the
00758         // Image Conversion Library, an appropriate codec plugin loaded and the image
00759         // headers parsed.
00760         // If the image is not recognised or valid then the call will leave with an error
00761         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00762         CleanupStack::PushL(imageDecoder);
00763 
00764         for (TInt frameNumber = 0; frameNumber < imageDecoder->FrameCount(); ++frameNumber)
00765                 {
00766                 // Count the number of frame comments
00767                 numberOfComments = imageDecoder->NumberOfFrameComments(frameNumber);
00768 
00769                 for (TInt commentNumber = 0; commentNumber < numberOfComments; ++commentNumber)
00770                         {
00771                         HBufC* frameComment = imageDecoder->FrameCommentL(frameNumber, commentNumber);
00772                         CleanupStack::PushL(frameComment);
00773 
00774                         TPtrC commentPtr = frameComment->Des();
00775 
00776                 // Decoded frame comments can be displayed here
00777 
00778                         CleanupStack::PopAndDestroy(frameComment);
00779                         }
00780                 }
00781 
00782         CleanupStack::PopAndDestroy(2); // imageDecoder and imageInMemory
00783         }
00784 
00785 
00798 void CIclExample::GettingMimeTypeOfSourceDescriptorL(const TDesC& aFileName)
00799         {
00800         TBuf8<128> theMimeType;
00801 
00802         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00803 
00804         // Call GetMimeTypeDataL() function of CImageDecoder to get the mime type of specified file
00805         CImageDecoder::GetMimeTypeDataL(imageInMemory, theMimeType);
00806 
00807         // Create the decoder, passing the image buffer. The image is recognised by the
00808         // Image Conversion Library, an appropriate codec plugin loaded and the image
00809         // headers parsed.
00810         // If the image is not recognised or valid then the call will leave with an error
00811         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory, theMimeType);
00812         CleanupStack::PushL(imageDecoder);
00813 
00814         // Decoded image mime can be displayed here after convert operation.
00815 
00816         CleanupStack::PopAndDestroy(2); // imageDecoder and imageInMemory
00817         }
00818 
00819 
00831 void CIclExample::GettingMimeTypeOfSourceFileL(const TDesC& aFileName)
00832         {
00833         TBuf8<128> theMimeType;
00834 
00835         // Call GetMimeTypeFileL() function of CImageDecoderGet to get the mime type of source file
00836         CImageDecoder::GetMimeTypeFileL(iFs, aFileName, theMimeType);
00837 
00838         // Create the decoder, passing the filename and mime type. The image is recognised by the
00839         // Image Conversion Library, an appropriate codec plugin loaded and the image
00840         // headers parsed.
00841         // If the image is not recognised or valid then the call will leave with an error
00842         CImageDecoder* imageDecoder = CImageDecoder::FileNewL(iFs, aFileName, theMimeType);
00843         CleanupStack::PushL(imageDecoder);
00844 
00845         // Decoded image mime can be displayed here after convert operation
00846 
00847         CleanupStack::PopAndDestroy(imageDecoder);
00848         }
00849 
00850 
00859 void CIclExample::LoadPluginByUidL(const TDesC& aFileName, TUid aCodecUid)
00860         {
00861         // create the decoder, passing the filename. The image is recognised by the
00862         // Image Conversion Library, an appropriate codec plugin loaded and the image
00863         // headers parsed according to Uid.
00864         // If the image is not recognised or valid then the call will leave with an error
00865         CImageDecoder* imageDecoder = NULL;
00866 
00867         imageDecoder = CImageDecoder::FileNewL(iFs, aFileName, CImageDecoder::EOptionNone, aCodecUid);
00868         CleanupStack::PushL(imageDecoder);
00869 
00870         // Decoder can be used here
00871 
00872         CleanupStack::PopAndDestroy(imageDecoder);
00873         }
00874 
00875 
00891 void CIclExample::DecodeWithRotateL(const TDesC& aFileName)
00892         {
00893         TPtr8 imageInMemory = LoadImageIntoMemoryLC(aFileName);
00894 
00895         // create the decoder, passing in the image memory. The image is recognised by the
00896         // Image Conversion Library, an appropriate codec plugin loaded and the image
00897         // headers parsed.
00898         // If the image is not recognised or valid then the call will leave with an error
00899         CImageDecoder* imageDecoder = CImageDecoder::DataNewL(iFs, imageInMemory);
00900         CleanupStack::PushL(imageDecoder);
00901 
00902         // Since the image header has been parsed we can find out the image size and can create
00903         // the bitmap to match the display mode we wish to support.
00904         const TFrameInfo& frameInfo = imageDecoder->FrameInfo(KFirstFrame);
00905 
00906         CFbsBitmap* destBitmap = new(ELeave) CFbsBitmap();
00907         CleanupStack::PushL(destBitmap);
00908 
00909         User::LeaveIfError(destBitmap->Create(frameInfo.iOverallSizeInPixels, frameInfo.iFrameDisplayMode));
00910 
00911         // See Note 1
00912         CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
00913 
00914         // Convert the image (first frame)
00915         imageDecoder->Convert(&activeListener->iStatus, *destBitmap, KFirstFrame);
00916 
00917         // See Note 2
00918         CActiveScheduler::Start();
00919         User::LeaveIfError(activeListener->iStatus.Int()); // decode complete either display the image or report an error.
00920 
00921         // Create a CBitmapRotator object and push it on the cleanup stack
00922         CBitmapRotator* rotator = CBitmapRotator::NewL();
00923         CleanupStack::PushL(rotator);
00924 
00925         // Rotate the bitmap through the specified angle
00926         activeListener->Initialize();
00927         rotator->Rotate(&activeListener->iStatus, *destBitmap, CBitmapRotator::ERotation180DegreesClockwise);
00928 
00929         // See Note 2
00930         CActiveScheduler::Start();
00931         User::LeaveIfError(activeListener->iStatus.Int()); // rotate complete either display the image or report an error.
00932 
00933         // Just verifying the presence of some output. The rotated image can also be displayed instead.
00934         _LIT(KOutputFile, "c:\\ICLExample\\RotatedBitmap.mbm");
00935         destBitmap->Save(KOutputFile);
00936 
00937         CleanupStack::PopAndDestroy(5); // rotator, destBitmap, activeListener, imageDecoder and imageInMemory
00938         }
00939 
00940 //
00941 // Illustrates how to clip and rotate images during decode.
00942 //
00943 const TDecodeParams KDecodeParams[] =
00944         {       // Clip - R90 - MirrorV  - Scale - Output
00945                 {EFalse, EFalse, EFalse, 1, _S("\\ICLExample\\NormalFull.mbm")},
00946                 {ETrue,  EFalse, EFalse, -1, _S("\\ICLExample\\ClipFull.mbm")},
00947                 {ETrue,  EFalse, ETrue,  -2, _S("\\ICLExample\\MirrorVertClipQuarter.mbm")},
00948                 {ETrue,  ETrue,  ETrue,  -3, _S("\\ICLExample\\Rotate90MirrorVertClipEighth.mbm")},
00949                 {EFalse, ETrue,  EFalse, 1, _S("\\ICLExample\\Rotate90Full.mbm")},
00950                 {EFalse, EFalse, EFalse, 1, NULL}
00951         };
00952 
00953 void CIclExample::ClipAndRotateDuringDecodeL()
00954         {
00955         TRect clipRect(TPoint(50, 65), TSize(170, 160));        // The wheel in thumbimage.jpg
00956         TSize finalSize;
00957 
00958         // The decoder must support *all* the operations we're going to perform.
00959         TUint options = CImageDecoder::EOptionExtRotation |
00960                                         CImageDecoder::EOptionExtMirrorHorizontalAxis |
00961                                         CImageDecoder::EOptionExtCrop |
00962                                         CImageDecoder::EOptionExtScaling;
00963 
00964         // The installed decoders must support *all* the operations requested in aOptions.
00965         _LIT(KInputFile, "c:\\ICLExample\\thumbimage.jpg");
00966         CImageDecoder* decoder = CImageDecoder::FileNewL(iFs, KInputFile, static_cast<CImageDecoder::TOptions>(options));
00967         CleanupStack::PushL(decoder);
00968 
00969         const TFrameInfo& frameInfo = decoder->FrameInfo(KFirstFrame);
00970         CFbsBitmap* output = new(ELeave) CFbsBitmap();
00971         CleanupStack::PushL(output);
00972         User::LeaveIfError(output->Create(frameInfo.iFrameSizeInPixels, frameInfo.iFrameDisplayMode));
00973 
00974         CActiveListener* ao = CActiveListener::NewLC();
00975 
00976         TImageConvOperation* operation = decoder->OperationL();
00977         TImageConvScaler* scaler = decoder->ScalerL();
00978 
00979         TInt i = 0;
00980         while (KDecodeParams[i].iOutputFile != NULL)
00981                 {
00982                 const TDecodeParams& params = KDecodeParams[i++];
00983 
00984                 operation->ClearOperationStack();
00985                 if (params.iRotate90)
00986                         {
00987                         operation->AddOperationL(TImageConvOperation::ERotation90DegreesClockwise);
00988                         }
00989 
00990                 if (params.iMirrorVerticalAxis)
00991                         {
00992                         operation->AddOperationL(TImageConvOperation::EMirrorVerticalAxis);
00993                         }
00994 
00995                 // Some codecs may have a limit on the amount of scaling they can do.
00996                 scaler->SetScalingL(params.iScalingCoeff, TImageConvScaler::EMaximumQuality);
00997 
00998                 // Setting the clipping rect to NULL will decode the whole image.
00999                 decoder->SetClippingRectL(params.iClip ? &clipRect : NULL);
01000                 User::LeaveIfError(decoder->GetDestinationSize(finalSize, KFirstFrame));
01001                 User::LeaveIfError(output->Resize(finalSize));
01002 
01003                 // See Note 1
01004                 ao->Initialize();
01005                 decoder->Convert(&ao->iStatus, *output, KFirstFrame);
01006 
01007                 // See Note 2
01008                 CActiveScheduler::Start();
01009 
01010                 TPtrC outputFile(params.iOutputFile);
01011                 output->Save(outputFile);       // Ignore error code.
01012                 }
01013 
01014         CleanupStack::PopAndDestroy(3); // decoder, output, ao
01015         }
01016 
01017 
01033 void CIclExample::BlockStreamDecodeAndEncodeYuvFrameL(const TDesC& aSrcFileName, const TDesC& aDestFileName)
01034         {
01035         const TInt KNumBlocksToGet = 1;
01036         RChunk chunk;
01037         TSize streamBlockSizeInPixels;
01038         TEncodeStreamCaps encodeCaps;
01039         TDecodeStreamCaps decodeCaps;
01040         TInt numBlocksRead = 0;
01041         TBool haveMoreBlocks = ETrue;
01042         // Create the decoder, passing the filename. The image is recognised by the 
01043         // Image Conversion Library, an appropriate codec plugin loaded and the image headers parsed.
01044         // If the image is not recognised or valid then the call will leave with an error
01045         CImageDecoder* jpegImageDecoder = CImageDecoder::FileNewL(iFs, aSrcFileName);
01046         CleanupStack::PushL(jpegImageDecoder);
01047 
01048         // Create the encoder, passing the filename. The image is recognised by the 
01049         // Image Conversion Library, an appropriate codec plugin loaded and the image headers parsed.
01050         // If the image is not recognised or valid then the call will leave with an error       
01051         CImageEncoder* jpegImageEncoder = CImageEncoder::FileNewL(iFs, aDestFileName, CImageEncoder::EOptionNone, KImageTypeJPGUid);
01052         CleanupStack::PushL(jpegImageEncoder);
01053         
01054         // Create encode & decode Block Streamer
01055         TImageConvStreamedDecode* streamDecode = jpegImageDecoder->BlockStreamerL();    
01056         TImageConvStreamedEncode* streamEncode = jpegImageEncoder->BlockStreamerL();
01057         
01058         TFrameInfo frameInfo = jpegImageDecoder->FrameInfo();
01059         TSize frameSizeInPixels(frameInfo.iOverallSizeInPixels); //NOTE: For JPEG codec, the image used for stream decoding and encoding should be multiple of MCU(Minimum coded unit)
01060         
01061         // Get decoder capabilities
01062         TDecodeStreamCaps::TNavigation decodeNavigation = TDecodeStreamCaps::ENavigationSequentialForward;
01063         
01064         TUid KFormat;
01065         RArray<TUid> supportedFormats;
01066         CleanupClosePushL(supportedFormats);
01067         
01068         streamDecode->GetSupportedFormatsL(supportedFormats, KFormat);
01069         
01070         streamDecode->GetCapabilities(KFormat, KFirstFrame, decodeCaps);
01071 
01072         // Check that the decoder supports sequential navigation capabilities
01073         if(decodeCaps.Navigation() & TDecodeStreamCaps::ENavigationSequentialForward != decodeNavigation)
01074                 {
01075                 User::Leave(KErrNotSupported);
01076                 }
01077 
01078         // set the navigation mode initialize decoder frame
01079         streamDecode->InitFrameL(KFormat, KFirstFrame, decodeNavigation);
01080         
01081         // Get decoder capabilities
01082         streamEncode->GetCapabilities(KFormat,encodeCaps);
01083         
01084         TSize blockSizeInPixels = encodeCaps.MinBlockSizeInPixels();
01085         
01086         // initialize encoder frame
01087         TEncodeStreamCaps::TNavigation encodeNavigation = TEncodeStreamCaps::ENavigationSequentialForward;
01088         
01089         // Check that the encoder supports sequential navigation capabilities
01090         if(encodeCaps.Navigation() & TEncodeStreamCaps::ENavigationSequentialForward != encodeNavigation)
01091                 {
01092                 User::Leave(KErrNotSupported);
01093                 }
01094         
01095         // create frame image data
01096         CFrameImageData* frameImageData = CFrameImageData::NewL();
01097         CleanupStack::PushL(frameImageData);
01098         
01099         TJpegImageData* jpegImageData = new(ELeave) TJpegImageData;             
01100         frameImageData->AppendImageData(jpegImageData);
01101         
01102         streamEncode->InitFrameL(KFormat, KFirstFrame, frameSizeInPixels, blockSizeInPixels, encodeNavigation, NULL);
01103         
01104         // When decoding, the buffer wrapped by the destination CImageFrame must be large enough to contain the decoded frame.
01105         // GetBufferSize() should be used to obtain the buffer size required for a particular decode
01106         TInt imageSizeInBytes = streamDecode->GetBufferSize(KFormat, streamBlockSizeInPixels, KNumBlocksToGet);
01107                         
01108         User::LeaveIfError(chunk.CreateLocal(imageSizeInBytes, imageSizeInBytes));
01109         CleanupClosePushL(chunk);
01110                 
01111         // Create an empty imageframe   
01112         CImageFrame* imageFrame = CImageFrame::NewL(&chunk, imageSizeInBytes, 0);
01113         CleanupStack::PushL(imageFrame);
01114 
01115         imageFrame->SetFrameSizeInPixels(streamBlockSizeInPixels);
01116         
01117         while(haveMoreBlocks)
01118                 {
01119                 // See Note 1
01120                 CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
01121                 
01122                 // decoder get blocks
01123                 streamDecode->GetNextBlocks(activeListener->iStatus, *imageFrame, KNumBlocksToGet, numBlocksRead, haveMoreBlocks);
01124                 
01125                 // See Note 2
01126                 CActiveScheduler::Start();
01127                 User::LeaveIfError(activeListener->iStatus.Int()); // decode complete.
01128                 
01129                 // NOTE: Apply effects like adjust brightness etc in low memory conditions by use of streaming to the image frame block
01130                                 
01131                 // See Note 1
01132                 activeListener->Initialize();
01133                 
01134                 // encoder append blocks
01135                 streamEncode->AppendBlocks(activeListener->iStatus, *imageFrame, numBlocksRead);
01136 
01137                 // See Note 2
01138                 CActiveScheduler::Start();
01139                 User::LeaveIfError(activeListener->iStatus.Int()); // encode complete.
01140                 
01141                 CleanupStack::PopAndDestroy(activeListener); // encodeActiveListener 
01142                 }
01143         
01144         CleanupStack::PopAndDestroy(6, jpegImageDecoder); // imageFrame, chunk, supportedFormats, jpegImageEncoder and jpegImageDecoder
01145     }
01146 
01147 

Generated on Thu Jan 21 10:32:59 2010 for TB10.1 Example Applications by  doxygen 1.5.3