Symbian3/SDK/Source/GUID-A578ECBB-28C5-51C6-A040-4AE65AD38C07.dita
changeset 0 89d6a7a84779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-A578ECBB-28C5-51C6-A040-4AE65AD38C07.dita	Thu Jan 21 18:18:20 2010 +0000
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-A578ECBB-28C5-51C6-A040-4AE65AD38C07" xml:lang="en"><title>Stream
+Encoding And Stream Decoding</title><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>This document gives you more information about the stream encoding and
+stream decoding method. </p>
+<section><title>Purpose</title> <p>This tutorial explains how to encode and
+decode an image by passing pixel data block by block. </p> <p><b>Required
+Background</b> </p> <p>The image is decoded / encoded using <filepath>imageconversion.dll</filepath> and
+currently only JPEG codec is supported for the streaming block method, so <filepath>jpegcodec.dll</filepath> is
+used from the Imaging Plugins component. </p> <p><b>Introduction</b> </p> <p>An image is compressed into an image frame. This
+is decoded / encoded in one go which consumes more memory usage. </p> <p>The
+Symbian <filepath>JPEG</filepath> codec now supports enhanced functionality
+during the encode / decode operation using Stream Encoding and Stream Decoding
+methods. In these methods an image frame which is part of a compressed image
+can be divided into sub blocks and these are encoded / decoded block by block
+of YUV pixel data. </p> <p>For decoder <xref href="GUID-7EC0A873-5ABA-3D11-880B-65466CBAA399.dita"><apiname>MImageConvStreamedDecode</apiname></xref> and <xref href="GUID-D4A1D719-6A38-39E2-9664-789CBABAC92E.dita"><apiname>TImageConvStreamedDecode</apiname></xref> are
+used to adapt the streaming functionality. And for encoder <xref href="GUID-D95B2E2D-CBE9-3838-86F5-EC0FBC03C6A6.dita"><apiname>MImageConvStreamedEncode</apiname></xref> and <xref href="GUID-653CA65B-13B7-3EFE-A25E-3EF8C41AABBB.dita"><apiname>TImageConvStreamedEncode</apiname></xref> are used to adapt the streaming functionality. </p> <p> <b>Note:- </b> Only
+the Symbian JPEG codec supports decoding / encoding of an image using Stream
+Encoding and Stream Decoding methods which consumes less memory usage. No
+other Symbian codecs are modified to provide this support. </p> <p>The Stream
+Encoding And Stream Decoding methods also supports cropping or scaling an
+image in sequence order or random order. </p> <p><b>Setup
+and Configuration Requirements</b> </p> <p>For the encoder / the decoder to
+perform streaming you need to set up the navigation mode by using the streaming
+capabilities. </p> <ul>
+<li id="GUID-1936B31A-8043-5401-9D7F-4F2BCFE26B9A"><p>The
+streaming capabilities for decoding are supported by the <xref href="GUID-0EBD074D-49E9-5E3E-9FA9-3484E968ABDB.dita#GUID-0EBD074D-49E9-5E3E-9FA9-3484E968ABDB/GUID-A5E7656C-6537-5D06-B81B-119614B73DB9">Image Processor Adaptation Plug-in</xref> decoder. For example you can obtain
+the optimum number of blocks through streaming in a single request to get
+maximum performance by using the parameter <codeph>aOptimalBlocksPerRequest</codeph>. </p> </li>
+<li/>
+<li id="GUID-CF5BEF30-BE94-5982-A816-522323FE6C0B"><p>The streaming capabilities
+for encoding are supported by the <xref href="GUID-0EBD074D-49E9-5E3E-9FA9-3484E968ABDB.dita#GUID-0EBD074D-49E9-5E3E-9FA9-3484E968ABDB/GUID-A5E7656C-6537-5D06-B81B-119614B73DB9">Image
+Processor Adaptation Plug-in</xref> encoder. For example you can obtain the
+maximum number of blocks through streaming by using the parameter <codeph>aMaxBlocksPerRequest</codeph>. </p> </li>
+</ul> <p>During the decode operation, the blocks or sub-frames can be navigated
+in the following order : </p> <ul>
+<li id="GUID-CB2510A3-8BF8-5A13-8BB1-9B9820D9B584"><p>The sub-frames or blocks
+can be passed sequentially from top left of the image, left to right and top
+to bottom. </p> </li>
+<li id="GUID-DF38C7D7-DA96-5A42-999B-6A6FC5BB218B"><p>The blocks can be passed
+in random order to access each block. </p> </li>
+</ul> <p>During the encode operation,the blocks or sub-frames can be navigated
+: </p> <ul>
+<li id="GUID-23349B8D-C81D-5550-A49C-A50AE231AB7A"><p>Sequentially from top
+left of the image, left to right and top to bottom. </p> </li>
+<li id="GUID-74F35DB8-90A3-52DA-A207-B3519D25F925"><p>Randomly from top of
+the image to bottom and bottom of the image to top. </p> </li>
+</ul> </section>
+<section><title>Using Stream Encoding And Stream Decoding </title> <p>The
+Following tasks are covered in this tutorial: </p> <ul>
+<li id="GUID-BF113946-4EA4-5076-A88F-DC177873030F"><p><xref href="GUID-A578ECBB-28C5-51C6-A040-4AE65AD38C07.dita#GUID-A578ECBB-28C5-51C6-A040-4AE65AD38C07/GUID-FE6502E4-30C6-5E9F-A3A4-537352065026">How to encode and decode an image by the streaming block method</xref>  </p> </li>
+</ul> <p id="GUID-FE6502E4-30C6-5E9F-A3A4-537352065026"><b>Basic Procedure For Stream
+Encoding And Stream Decoding</b> </p> <p>The high level steps to perform streaming
+block during encode and decode operation are as follows: </p> <ol id="GUID-151BD6BB-9028-5DA0-B616-E93F3C328311">
+<li id="GUID-BFCC59BD-C76A-5AEF-AED7-CAD35E7171C4"><p>To create the encoder
+call <xref href="GUID-737DA130-9A66-39E2-9E68-2E65F37E02C8.dita#GUID-737DA130-9A66-39E2-9E68-2E65F37E02C8/GUID-1F25CC18-A8E4-3E1D-BA3D-F5F472E20CC0"><apiname>CImageEncoder::FileNewL()</apiname></xref> or <xref href="GUID-737DA130-9A66-39E2-9E68-2E65F37E02C8.dita#GUID-737DA130-9A66-39E2-9E68-2E65F37E02C8/GUID-51ECB4D3-5A87-35E7-82EB-DF2BAEAB2CAC"><apiname>CImageEncoder::DataNewL()</apiname></xref> and
+to create the decoder call <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-6DA07559-7DDC-32A9-9E09-D557348D46DE"><apiname>CImageDecoder::FileNewL()</apiname></xref> or <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-00FB83E8-3759-32BE-B6E8-6F04EC60A909"><apiname>CImageDecoder::DataNewL()</apiname></xref>. </p> </li>
+<li id="GUID-7D610B86-BF34-5772-B901-3582CD7A600D"><p>For the encoder streaming,
+requests a streaming interface through <xref href="GUID-737DA130-9A66-39E2-9E68-2E65F37E02C8.dita#GUID-737DA130-9A66-39E2-9E68-2E65F37E02C8/GUID-452047D4-E3A8-3200-9F10-697FF5200BB3"><apiname>CImageEncoder::BlockStreamerL()</apiname></xref> and
+for the decoder streaming, request an interface through <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-14A53DAA-DFCE-347F-AFC5-4C0F9FE3081F"><apiname>CImageDecoder::BlockStreamerL()</apiname></xref>. </p> <p>After
+requesting the streaming interface, if the streaming extension is supported
+then a T class pointer is returned which gives access to the JPEG codec extension. <xref href="GUID-D4A1D719-6A38-39E2-9664-789CBABAC92E.dita"><apiname>TImageConvStreamedDecode</apiname></xref> gives
+the extension functionality for stream decoding and <xref href="GUID-653CA65B-13B7-3EFE-A25E-3EF8C41AABBB.dita"><apiname>TImageConvStreamedEncode</apiname></xref> gives
+the extension functionality for stream encoding. </p> </li>
+<li id="GUID-1517FF6C-4F5E-55FD-A71F-18A200616BB5"><p>To
+set the navigation mode for the encode streaming call the Image Processor
+Adaptation Plug-in encoder navigator and for the decode streaming call the
+Image Processor Adaptation Plug-in decoder navigator. </p> <p>For
+decode streaming, the navigation possibilities are : </p> <ul>
+<li id="GUID-910F6950-4355-5989-BA29-1319EEFF26B0"><p>The blocks are returned
+from first to last. </p> </li>
+<li id="GUID-B5E34D8E-8DBD-5D63-AF5A-4D88E57BA6F2"><p>The blocks are returned
+from last to first. </p> </li>
+<li id="GUID-421A8EA9-FE99-59AB-BED7-4051DD798120"><p>The blocks are returned
+randomly e.g. 18, 5, 20. </p> </li>
+<li id="GUID-C1AD41C6-FD4D-5602-875F-A14F4778866F"><p>The blocks are returned
+in a random order but moving only from first to last e.g. 1, 5, 18. </p> </li>
+<li id="GUID-B0D25618-B77B-5F63-AF7D-8DC0B39277AC"><p>The blocks are returned
+in a random order but moving only from last to first e.g. 18, 5, 1. </p> </li>
+</ul> <p>The navigation are shown below: </p> <codeblock id="GUID-88CF01B6-2F4B-57C9-A30D-4651DB32496E" xml:space="preserve">
+
+enum TNavigation
+        {
+    
+        ENavigationSequentialForward = 0x01, // Sequential order from first to last
+  ENavigationSequentialBackwards = 0x10, // Sequential order from last to first
+  ENavigationRandom = 0x08, // random order
+        ENavigationRandomForward     = 0x02, // random order frist to last
+        ENavigationRandomBackwards   = 0x04, // random order last to first
+        
+        }
+
+</codeblock> <p>For encode streaming, the navigation possibilities are: </p> <ul>
+<li id="GUID-EC70F523-E8BE-5FC9-8B52-7550685FB77A"><p>The blocks are returned
+from first to last. </p> </li>
+<li id="GUID-7076D2D9-C438-5A56-9220-98C26D0D5D5C"><p>The blocks are returned
+in a random order but moving only from first to last e.g. 1, 5, 18. </p> </li>
+<li id="GUID-6E1049DC-165F-5B49-A2A9-7C0879E9F6AB"><p>The blocks are returned
+in a random order but moving only from last to first e.g. 1, 5, 18. </p> </li>
+</ul> <codeblock id="GUID-68FCCD3B-0616-584C-AB88-84F4F68732B2" xml:space="preserve">
+
+enum TNavigation
+        {
+    
+        ENavigationSequentialForward = 0x01, // sequential order from first to last        
+        ENavigationRandomForward     = 0x02, // random order from first to last    
+        EnavigationRandomBackwards   = 0x04, // random order from last to first     
+        
+  };
+
+</codeblock> </li>
+<li id="GUID-731867F0-3873-51BD-8CB6-6E549B1802F4"><p>To initialize the stream
+decoder use <xref href="GUID-D4A1D719-6A38-39E2-9664-789CBABAC92E.dita#GUID-D4A1D719-6A38-39E2-9664-789CBABAC92E/GUID-3DDDDAB5-DDF7-3904-BA67-B66FBBD19DCF"><apiname>TImageConvStreamedDecode::InitFrameL()</apiname></xref> and
+use its parameter. </p> </li>
+<li id="GUID-E3231926-0292-5A3D-88C5-47E798818294"><p>To initialize the encode
+streaming use <xref href="GUID-653CA65B-13B7-3EFE-A25E-3EF8C41AABBB.dita#GUID-653CA65B-13B7-3EFE-A25E-3EF8C41AABBB/GUID-C98EF919-247F-37EE-A10A-091441C940B9"><apiname>TImageConvStreamedEncode::InitFrameL()</apiname></xref> and
+use its parameter. </p> </li>
+<li id="GUID-91DAA7B8-9437-5F8C-9628-CA562080A923"><p>During decode function,
+the memory for storing <xref href="GUID-54159F7E-C9A9-3FB5-806D-751DAF213290.dita"><apiname>CImageFrame</apiname></xref> must be large enough
+to contain the decoded frame. To obtain the buffer size for a particular decode
+function call <xref href="GUID-D4A1D719-6A38-39E2-9664-789CBABAC92E.dita#GUID-D4A1D719-6A38-39E2-9664-789CBABAC92E/GUID-8DF0A327-AD84-3E66-939C-042BC266A8A5"><apiname>TImageConvStreamedDecode::GetBufferSize()</apiname></xref>. </p> <p>The <codeph>GetBufferSize()</codeph> function
+returns: </p> <ul>
+<li id="GUID-9A3EA468-28C5-592B-AAE6-FEA02E2B37A4"><p>The required size to
+store the image when using the Imaging plugins format code. </p> </li>
+<li id="GUID-91AC139C-7E44-50FC-8AEB-7BA7ADCF4AAD"><p>The size in pixels of
+the block from the stream are returned by calling <codeph> aBlockSizeInPixels</codeph>,
+when <codeph>aNumBlocks</codeph> of minimum block size are requested. </p> </li>
+</ul> </li>
+<li id="GUID-BE2118E1-0E23-5309-B4E1-7490BC228B2D"><p>To store the image data
+in any format or layout which is described by a format code UID, create an
+empty image frame using <xref href="GUID-54159F7E-C9A9-3FB5-806D-751DAF213290.dita"><apiname>CImageFrame</apiname></xref>. </p> </li>
+<li id="GUID-9B0A1F73-D1FA-543F-AA9A-96FFA8CE0225"><p>To set the image frame
+size in pixels call <xref href="GUID-54159F7E-C9A9-3FB5-806D-751DAF213290.dita#GUID-54159F7E-C9A9-3FB5-806D-751DAF213290/GUID-BC2B18A5-0C3C-388B-A613-80D623F26F08"><apiname>CImageFrame::SetFrameSizeInPixels()</apiname></xref>.
+The parameter <codeph>aFrameSize</codeph> is used to returned <codeph>aBlockSizeInPixels</codeph> from <codeph>GetBufferSize</codeph>. </p> </li>
+<li id="GUID-9F9887F0-D93F-54C7-8476-D2AC6413F4BE"><p>In decode streaming,
+in order to start asynchronous call to return blocks use <xref href="GUID-7EC0A873-5ABA-3D11-880B-65466CBAA399.dita#GUID-7EC0A873-5ABA-3D11-880B-65466CBAA399/GUID-92A9FB31-2B0D-305D-A8A2-04B63C2861CB"><apiname>MImageConvStreamedDecode::GetNextBlocks()</apiname></xref>. </p> </li>
+<li id="GUID-54FF23F9-5A7F-55B5-9AE3-599E78F755CB"><p>In encode streaming,
+in order to start asynchronous call to append blocks use <xref href="GUID-D95B2E2D-CBE9-3838-86F5-EC0FBC03C6A6.dita#GUID-D95B2E2D-CBE9-3838-86F5-EC0FBC03C6A6/GUID-F3618D7A-94C4-3259-AFBD-1E83C222765C"><apiname>MImageConvStreamedEncode::AppendBlocks()</apiname></xref>. </p> </li>
+</ol> <p> <b>Note:</b> The memory optimization is mainly achieved by <codeph>GetNextBlocks</codeph> and <codeph>AppendBlocks</codeph> applying
+effect to the image frame block. And the streaming is only supported by the
+images which are multiples of Minimum Coded Unit (MCU). </p> <p><b>Example </b> </p> <p>The example below shows how to use stream encoding
+and stream decoding methods: </p> <codeblock id="GUID-985CFE87-9321-5C4F-A112-B8A722DC35FE" xml:space="preserve">
+
+void CIclExample::StreamDecodeAndEncodeYuvFrameL(const TDesC&amp; aSrcFileName, const TDesC&amp; aDestFileName)
+    {
+    const TInt KFrameNumber = 0; // first frame
+    const TUid KFormat = KUidFormatYUV422Interleaved; // 422 sampling scheme
+    const TInt KNumBlocksToGet = 1;
+    RChunk chunk;
+    TSize streamBlockSizeInPixels;
+    TEncodeStreamImgProcPlugin ImgProcPlugin;
+    TInt numBlocksRead = 0;
+    TBool haveMoreBlocks = ETrue;
+    // Create the decoder, passing the filename. The image is recognised by the 
+    // Image Conversion Library, an appropriate codec plugin loaded and the image headers parsed.
+    // If the image is not recognised or valid then the call will leave with an error
+    CImageDecoder* jpegImageDecoder = static_cast&lt;CJPEGImageFrameDecoder*&gt;( CImageDecoder::FileNewL(iFs, aSrcFileName));
+    CleanupStack::PushL(jpegImageDecoder);
+
+    // Create the encoder, passing the filename. The image is recognised by the 
+    // Image Conversion Library, an appropriate codec plugin loaded and the image headers parsed.
+    // If the image is not recognised or valid then the call will leave with an error    
+    CImageEncoder* jpegImageEncoder = static_cast&lt;CJPEGImageFrameEncoder*&gt;( CImageEncoder::FileNewL(iFs, aDestFileName, CImageEncoder::EOptionNone, KImageTypeJPGUid));
+    CleanupStack::PushL(jpegImageEncoder);
+    
+    // Create encode &amp; decode Block Streamer
+    TImageConvStreamedDecode* streamDecode = jpegImageDecoder-&gt;BlockStreamerL();    
+    TImageConvStreamedEncode* streamEncode = jpegImageEncoder-&gt;BlockStreamerL();
+    
+    TFrameInfo frameInfo = jpegImageDecoder-&gt;FrameInfo();
+    TSize frameSizeInPixels(frameInfo.iOverallSizeInPixels); //NOTE: The image used for decoding should be multiple of MCU(Minimum coded unit)
+    
+    //set the navigation mode initialize decoder frame
+    TDecodeStreamImgProcPlugin::TNavigation decodeNavigation = TDecodeStreamImgProcPlugin::ENavigationSequentialForward;
+    streamDecode-&gt;InitFrameL(KFormat, KFrameNumber, decodeNavigation);
+    
+    streamEncode-&gt;GetCapabilities(KFormat,ImgProcPlugin);
+    TSize blockSizeInPixels = TSize(ImgProcPlugin.MinBlockSizeInPixels());
+    
+    //initialize encoder frameImgProcPlugin::ENavigationSequentialForward;
+    streamEncode-&gt;InitFrameL(KFormat, KFrameNumber, frameSizeInPixels, blockSizeInPixels, encodeNavigation, NULL);
+
+    //When decoding, the buffer wrapped by the destination CImageFrame must be large enough to contain the decoded frame.
+    //GetBufferSize() should be used to obtain the buffer size required for a particular decode
+    TInt imageSizeInBytes = streamDecode-&gt;GetBufferSize(KFormat, streamBlockSizeInPixels, KNumBlocksToGet);
+            
+    User::LeaveIfError(chunk.CreateGlobal(KRChunk, imageSizeInBytes, imageSizeInBytes, EOwnerProcess));    
+    CleanupClosePushL(chunk);
+        
+    // Create an empty imageframe   
+    CImageFrame* imageFrame = CImageFrame::NewL(&amp;chunk, imageSizeInBytes, 0);
+    CleanupStack::PushL(imageFrame);
+
+    imageFrame-&gt;SetFrameSizeInPixels(streamBlockSizeInPixels);
+    
+    while(haveMoreBlocks)
+        {
+        // See Note 1
+        CActiveListener* activeListener = CreateAndInitializeActiveListenerLC();
+        
+        //decoder get blocks
+        streamDecode-&gt;GetNextBlocks(activeListener-&gt;iStatus, *imageFrame, KNumBlocksToGet, numBlocksRead, haveMoreBlocks);
+        
+        // See Note 2
+        CActiveScheduler::Start();
+        User::LeaveIfError(activeListener-&gt;iStatus.Int()); // decode complete.
+        
+        //NOTE: Apply effects like adjust brightness etc in low memory conditions by use of streaming to the image frame block
+                
+        // See Note 1
+        activeListener-&gt;InitializeActiveListener();
+        
+        //encoder append blocks
+        streamEncode-&gt;AppendBlocks(activeListener-&gt;iStatus, *imageFrame, numBlocksRead);
+
+        // See Note 2
+        CActiveScheduler::Start();
+        User::LeaveIfError(activeListener-&gt;iStatus.Int()); // encode complete.
+        
+        CleanupStack::PopAndDestroy(activeListener); // encodeActiveListener 
+        }
+    
+    CleanupStack::PopAndDestroy(4); // imageFrame, chunk, jpegImageEncoder and jpegImageDecoder
+    }
+</codeblock> </section>
+</conbody><related-links>
+<link href="GUID-88091838-03FC-550F-9A3D-DA70907EF955.dita"><linktext>Imaging Frameworks
+overview</linktext></link>
+<link href="GUID-3D9C4B45-EEA0-581C-A9E5-8B2535014930.dita"><linktext>Image Conversion
+Overview</linktext></link>
+<link href="GUID-6DC34798-86CE-537D-B3B8-9A94FF77B283.dita"><linktext>Image Encoding
+Tutorial</linktext></link>
+<link href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita"><linktext>Image Decoding
+Tutorial</linktext></link>
+<link href="GUID-A825B62E-B5F6-5FDD-B267-E47103D57FD8.dita"><linktext>Guide to
+Symbian supplied Codecs </linktext></link>
+</related-links></concept>
\ No newline at end of file