Symbian3/SDK/Source/GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Fri, 11 Jun 2010 12:39:03 +0100
changeset 8 ae94777fff8f
parent 0 89d6a7a84779
permissions -rw-r--r--
Week 23 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 2714, Bug 462.

<?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-B10B048F-37FF-53E7-92B9-83F8C197566A" xml:lang="en"><title>Image
Decoding</title><prolog><metadata><keywords/></metadata></prolog><conbody>
<p>This document gives you more information about the Image Decoding functionality. </p>
<section id="GUID-41872C2C-A6EB-446B-AA79-62BAA6B69437"><title>Purpose</title> <p>The image decoding class <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> provides
functions to decode images held in descriptors or files from standard formats
for use with devices such as screens, browsers and viewer applications. </p> <p><b>Required Background</b> </p> <p>Image decoding features are provided through
Imaging Frameworks and Imaging plugins. The standard formats supported by
the decode plugins are shown in the table in <xref href="GUID-88091838-03FC-550F-9A3D-DA70907EF955.dita">Imaging
Frameworks Overview</xref>. </p> <p><b>Introduction</b> </p> <p>The decoding process comprises the following sections: </p> <ul>
<li id="GUID-BE3B993F-3793-55B4-9ADB-9456FE73CA19"><p> <b>Creation</b> - The
creation of the <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> object and any requirements
necessary. </p> </li>
<li id="GUID-D5FE22F6-687F-560D-A336-4F01B5945273"><p> <b>Conversion</b> -
Covers the basic form of image decoding. More advanced features such as progressive
and buffered decoding are described separately. </p> </li>
<li id="GUID-9A4AD0DE-AFCF-5F33-AAC7-007FD9F8A291"><p> <b>Enquiry features</b> -
Additional features that enable you to retrieve information stored in certain
types of images, for example frame information and comments. </p> </li>
<li id="GUID-643CE012-6C73-5068-A7AD-FDA810FBBFD8"><p> <b>Streamed and progressive
decoding</b> - Reading partial image files and displaying image data before
the entire image is read. </p> </li>
<li id="GUID-E3D6BB50-DBE9-5967-9FAC-B56BCBCCADAC"><p> <b>Buffered decoding</b> -
The decoding of an image using a buffered input rather than a file or descriptor. </p> </li>
</ul> <p><b>Setup
and Configuration Requirements</b> </p> <p>The <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> classes
use synchronous methods to open an image and asynchronous methods to perform
conversions or transformations. The asynchronous operations use the standard
system of taking a pointer to a <xref href="GUID-E0B34F3E-D4C4-3232-B8B1-7DB35B454646.dita"><apiname>TRequestStatus</apiname></xref> object that
is signalled on completion of the requested action. The assumption is that
the client application or the calling DLL holds the <codeph>TRequestStatus</codeph> values
within active objects. The structure of the active objects is dependent on
the code that uses the Imaging Frameworks and its own requirements, particularly
its internal architecture and how many images are opened simultaneously. </p> <p>In
addition to the use of active objects in the interfacing, many of the Imaging
Frameworks internal functions make extensive use of them to provide asynchronous
behaviour. As with any use of an active object it is necessary to have an
active scheduler in the same thread as the application making use of the object.
The Decoders can also be created so the plugin and framework runs in a separate
thread. This is achieved by setting the <codeph>EOptionAlwaysThread</codeph> option
when constructing the decoder objects. By running the object in its own thread,
the application is shielded from any latency that can occur during image conversion,
or possibly due to a badly written plugin. </p> </section>
<section id="GUID-6741516A-A0A7-4021-9A5A-6855E4AE9E8B"><title>Using Image Decoding </title> <p>The Following tasks are covered
in this tutorial: </p> <ul>
<li id="GUID-085EEC3C-C78B-5FDC-B630-C3A28DF0CA1F"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-1F8A0DCC-CB95-5245-9ED0-FE4A775152D0">How to create the object during decoding</xref> </p> </li>
<li id="GUID-A5E71C36-E811-509B-A547-04F174B7000B"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-7A3F98C2-C86B-5DC4-9F0E-EAE030341325">How to convert encoded data to decoded data</xref>  </p> </li>
<li id="GUID-D6EDE32F-F011-5191-AD15-AD8FAEFC5C75"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-FF418A2D-436B-515F-B9D1-E0A0C87E7394"> How to retrieve the information stored in certain types of images</xref>  </p> </li>
<li id="GUID-05966714-BB75-5DB1-86E5-4FE075507C2D"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-AA950124-42DE-5A65-B371-7D85F43D71A6">How to perform the streaming and the progressive during decoding</xref>  </p> </li>
<li id="GUID-3BBA8FBB-FB2E-5774-921E-8BBAC95DF55C"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-C7FEA8F9-B367-52B1-9D26-84F9E225D17C">How to perform the buffered decoding</xref>  </p> </li>
</ul> <p id="GUID-1F8A0DCC-CB95-5245-9ED0-FE4A775152D0"><b>Basic Procedure For Creation</b> </p> <p>The
high level steps to create the object during decoding are as follows: </p> <ol id="GUID-A8F73379-5277-5ACC-82A4-9199BE24142A">
<li id="GUID-166216C0-5CAA-5FF4-8B40-BB562EEF3C61"><p> <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> decodes
images stored in files or in descriptors. The decoder object is owned by the
client and must be deleted once decoding is finished. <codeph>CImageDecoder</codeph> objects
cannot be reused to decode other images, each image requires its own instance
of the decoder. </p> </li>
<li id="GUID-BB617D39-8A46-5C7F-A28B-7C334F24594C"><p> <codeph>CImageDecoder</codeph> objects
are created using the <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> and <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> factory
functions for images held in descriptors or files respectively. </p> </li>
<li id="GUID-F1D28859-A28F-56EA-8755-25C8FF70BB50"><p>When you create a <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> object,
a suitable plugin must be associated with the image to be decoded. The Imaging
plugin depends on the factory function you use to create the object and what
parameters you specify. There are four alternatives: </p> <ul>
<li id="GUID-A40501AD-3679-5612-AA43-06DB6345C79D"><p> <b>MIME type</b> The
plugin is determined by looking up a specified MIME type against a list of
known MIME type/plugin implementations. Use the following "File" factory function
(or its "Data" equivalent). </p> <codeblock id="GUID-FF20429E-3D1D-5D99-9548-9AA701AC1B32" xml:space="preserve">static CImageDecoder* FileNewL(RFs&amp; aFs, const TDesC&amp; aSourceFilename, const TDesC8&amp; aMIMEType, const TOptions aOptions = EOptionNone);
</codeblock> </li>
<li id="GUID-9D96F47A-F784-5252-AAC9-3DDEF2E96764"><p> <b>Image type and sub-type</b> The
plugin is determined by looking up the specified image type and sub-types
against a list of known type/sub-type plugin implementations. Use the following
"File" factory function (or its "Data" equivalent). </p> <codeblock id="GUID-2D5A7779-CBE9-5B3E-B9E7-C5CD7631DB33" xml:space="preserve">static CImageDecoder* FileNewL(RFs&amp; aFs, const TDesC&amp; aSourceFilename, const TOptions aOptions = EOptionNone, const TUid aImageType = KNullUid, const TUid aImageSubType = KNullUid, const TUid aDecoderUid = KNullUid);
</codeblock> <p> <b>Note:</b> For images types that do not have sub-types
use <codeph>KNullUid</codeph>. </p> </li>
<li id="GUID-D80A799E-E49E-547C-9286-1AB38F8EB819"><p> <b>Implementation UID</b> The
plugin is determined by looking up its specific UID and the image type and
sub-type. Use the same <codeph>FileNewL()</codeph> factory function shown
in "Image type and sub-type", but in addition to the type and sub-type parameters,
also specify the plugin UID using <codeph>aDecoderUid</codeph>. </p> <p> <b>Note:</b> Implementation
UID is supported because it is possible to have more than one plugin for a
particular image type. This method is recommended if the application or calling
DLL needs to exploit features of a particular plugin. </p> </li>
<li id="GUID-A08944FA-6BE6-574A-AE00-5F12F5A07F0B"><p> <b>Automatic detection</b> -
no MIME type, format type/sub-type or UIDs are specified. The plugin analyses
the header information of the specified image. Use the same <codeph>FileNewL()</codeph> factory
function shown in "Image type and sub-type", but do not specify any values
for <codeph>aImageType</codeph>  <codeph>aImageSubType</codeph> or <codeph>aDecoderUid</codeph>. </p> <p>If
a suitable plugin cannot be found, the factory function leaves with <codeph>KErrNotFound</codeph>.
If a suitable plugin is found, but that plugin cannot interpret the image
data the factory function leaves with <codeph>KErrCorrupt</codeph>. </p> <p>Note:
Some image formats cannot be automatically detected because they do not contain
sufficient header information, for example, WBMP and OTA images. Under such
circumstances, use one of the other three alternative for opening the image. </p> </li>
</ul> </li>
</ol> <p>It is possible for more than one valid plugin decoder to be available
for a specific image format. If a plugin determined by MIME type or type/sub-type
fails to open an image due to <codeph>KErrCorrupt</codeph>, it will continue
to try with subsequent valid plugins if available. This mechanism is carried
out in the system and is not visible to the application. If you require a
specific function available within a specific plugin, specify that plugin
using <codeph>aDecoderUid</codeph>. </p> <p id="GUID-7A3F98C2-C86B-5DC4-9F0E-EAE030341325"><b>Basic Procedure For Conversion </b> </p> <p>The
high level steps to convert encoded data to decoded data are as follow: </p> <ol id="GUID-495365EB-B53D-5229-AD45-F9700A22F2AB">
<li id="GUID-4B6AEB44-3426-5B83-A12E-755230627D23"><p>As part of the <codeph>CImageDecoder</codeph> creation
basic information about the image is pre-read from the image headers. This
information is used to support certain enquiry methods such as <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-6506DA99-55E9-3524-BD64-528E145915F4"><apiname>CImageDecoder::FrameCount()</apiname></xref> and <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-7CE85F05-6D58-30F1-87D3-324BFB6131FB"><apiname>CImageDecoder::FrameInfo()</apiname></xref> (For more information about the retrieve information stored in certain types
of images is supplied in <xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-FF418A2D-436B-515F-B9D1-E0A0C87E7394">Retrieve
Information features</xref>). </p> </li>
<li id="GUID-18D5494C-BECC-52A5-9C51-60A9E560C816"><p>You can decode any subset
of individual frames, in any order, and to repeat the decoding if necessary.
To decode an image frame use the asynchronous conversion method <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-8118AC37-471E-3CB6-9F71-4E93507DDE57"><apiname>CImageDecoder::Convert()</apiname></xref>,
as follows. </p> </li>
</ol> <codeblock id="GUID-557B2DE9-6AA7-593B-A1A7-0D1E4352E184" xml:space="preserve">
void Convert(TRequestStatus* aRequestStatus, CFbsBitmap&amp; aDestination, TInt aFrameNumber = 0);

void ContinueConvert(TRequestStatus* aRequestStatus);</codeblock> <p> <b> Note:</b> The
use of <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-F4F5A5F6-03E5-3801-93CC-A023363F35F8"><apiname>CImageDecoder::ContinueConvert()</apiname></xref> is described in <xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-AA950124-42DE-5A65-B371-7D85F43D71A6">Streamed
and progressive decoding</xref>. </p> <p>There are different type of sub-procedures
which have to be followed before decode conversion, they are: </p> <ul>
<li id="GUID-1F27341A-4A6A-5269-AA61-CBB0FB620258"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-52CAB4D2-BFA9-528C-ADB6-88515893F2B1">Bitmap Masks conversion</xref>  </p> </li>
<li id="GUID-3537322C-B7E7-502D-A773-294DEC45A6DC"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-03A3E6BD-8702-5C0D-8265-F956EC03CD73">Scaling and display modes</xref>  </p> </li>
<li id="GUID-D11765E3-CD93-5CF2-A530-B7725F742861"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-9C2E0BFC-61FE-5F83-A78A-C9248C5D6FA3">Animations</xref>  </p> </li>
<li id="GUID-EA7899D9-F950-514D-9696-072C14116B44"><p><xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-9BD9C48A-B582-5730-B03F-CF6CB00DF6D1">Background colours </xref>  </p> </li>
</ul> <p id="GUID-52CAB4D2-BFA9-528C-ADB6-88515893F2B1"><b>Basic Procedure For Bitmap
Masks conversion</b> </p> <p>The high level steps to Bitmap Masks conversion
are as follows: </p> <ol id="GUID-A330923C-DA1E-55CF-A01C-151CD203D37B">
<li id="GUID-E493B5B2-D8A2-5428-846B-0BA902EAF641"><p>There is a second variant
of the <codeph>Convert()</codeph> function intended for use when decoding
images with bitmap masks. </p> <codeblock id="GUID-F6213C82-A604-57F0-B4C2-5667007CAD53" xml:space="preserve">
void Convert(TRequestStatus* aRequestStatus, CFbsBitmap&amp; aDestination, CFbsBitmap&amp; aDestinationMask, TInt aFrameNumber = 0);
</codeblock> </li>
<li id="GUID-1E7DC04E-A101-5C33-B6B5-BE5F83E95801"><p>Within the Symbian platform
it is normal to store the bitmap mask separately from the main image data.
Calls such as <xref href="GUID-2395FA67-5DCD-3CD7-BBB6-66625A3E2B6E.dita"><apiname>BitBltMasked()</apiname></xref> expect this data to be provided
separately. This separation is true for both <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> objects
and MBM files. </p> </li>
<li id="GUID-B9CE26DF-AE1C-592F-8C0E-DD0AAD69BF60"><p>To determine whether
an image contains a bitmap mask use <codeph>FrameInfo()</codeph>, the presence
or absence of a mask will be indicated the <codeph>ETransparencyPossible</codeph> flag. </p> <p>The
following two types of mask are available: </p> <ul>
<li id="GUID-1A03053A-C797-57EF-978E-C25A1D32163A"><p> <b>8-bit alpha blend</b> -
indicated by the <codeph>EAlphaChannel</codeph> flag of <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-7CE85F05-6D58-30F1-87D3-324BFB6131FB"><apiname>CImageDecoder::FrameInfo()</apiname></xref>  <codeph>iFlags</codeph>.
The destination mask bitmap must be of type <codeph>EGray256</codeph>. </p> </li>
<li id="GUID-9B51A424-66ED-584F-A3CD-55D575B38FEA"><p> <b>Simple on/off mask</b> -
if no <codeph>EAlphaChannel</codeph> flag is set. The destination bitmap mask
can be either <codeph>EGray2</codeph> or <codeph>EGray256</codeph>. </p> </li>
</ul> </li>
</ol> <p> <b>Note:</b> Images that contain bitmap masks do not have to have
those masks decoded if they are not required. </p> <p id="GUID-03A3E6BD-8702-5C0D-8265-F956EC03CD73"><b>Basic Procedure For Scaling
and display modes</b> </p> <p>The high level steps to Scale and display are
shown here: </p> <ol id="GUID-DE0D4041-CBBF-5841-BE53-A8F6EA2CDE38">
<li id="GUID-921CCDF6-7346-577E-AEC2-217C82329D44"><p>Before <codeph>Convert()</codeph> is
used, the destination <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> objects for image data
and bitmap masks are created. The simplest way to do this is to use a 1 to
1 approach, that is, create the <codeph>CFbsBitmap</codeph> object with the
same properties as the source image. This is achieved by using something similar
to: </p> <codeblock id="GUID-198859CC-C33A-5BE8-B75C-C32746D65DF7" xml:space="preserve">iFrameInfo = &amp;imageDecoder-&gt;FrameInfo(FrameNum);

iBitmap-&gt;Create(iFrameInfo-&gt;iOverallSizeInPixels, iFrameInfo-&gt;iFrameDisplayMode );
</codeblock> </li>
<li id="GUID-B3559310-560A-5671-9560-509F14B729ED"><p>If the <codeph>ECanDither</codeph> flag
of <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-7CE85F05-6D58-30F1-87D3-324BFB6131FB"><apiname>CImageDecoder::FrameInfo()</apiname></xref>  <codeph>iFlags</codeph> is
set then the destination display mode can be adjusted. It is recommended that
the window display mode is used as it is more efficient. </p> <p> <b>Note:</b> The
mask bitmap must have the same size in pixels as the main image, even though
the display mode is generally different. </p> </li>
<li id="GUID-B517656C-3294-5D3A-92E3-442CAE099FE1"><p>The size of the image
bitmap is available via <codeph>FrameInfo()</codeph> (<codeph>iOverallSizeInPixels</codeph>).
However, in addition to a direct mapping of the size of an image, <xref href="GUID-062B8E74-EDEF-3A98-9728-79C3E5A8C829.dita"><apiname>ReducedSize()</apiname></xref> function
can be used to calculate the reduced size of the decoded bitmap based on the
input parameters. </p> </li>
<li id="GUID-52299AC9-377C-5DEB-B16A-BDA0538D91A7"><p>If the <codeph>EFullyScaleable</codeph> flag
of <codeph>FrameInfo()</codeph>  <codeph>iFlags</codeph> is set, you can specify
any size for the <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> and the image will be resized
accordingly. </p> </li>
</ol> <p id="GUID-9C2E0BFC-61FE-5F83-A78A-C9248C5D6FA3"><b>Basic Procedure For Animations</b> </p> <p>The
high level steps to decode a GIF multi-frame image are as follow: </p> <ol id="GUID-C7E99D55-48C9-5329-B07B-28A65AB102D6">
<li id="GUID-53364690-F9D3-5A80-9FAA-2046F8DB80AB"><p>Included in the <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-7CE85F05-6D58-30F1-87D3-324BFB6131FB"><apiname>CImageDecoder::FrameInfo()</apiname></xref> result
are flags that enable the support of GIF animation. These flags are <codeph>iDelay</codeph>, <codeph>ELeaveInPlace</codeph>, <codeph>ERestoreToBackground</codeph> and <codeph>ERestoreToPrevious</codeph>. ICL provides these flags to enable
the application to implement the animation; ICL does not provide functions
to display the animation directly. </p> </li>
<li id="GUID-3BAC1045-E210-5B1A-93E9-BB15C9FC1871"><p>Processing the information
from these flags will inevitably require a state machine, and additional timers,
within the application. Requirements will vary depending on the architecture
of the client application itself. </p> </li>
</ol> <p id="GUID-9BD9C48A-B582-5730-B03F-CF6CB00DF6D1"><b>Basic Procedure For Background
colours</b> </p> <ol id="GUID-2D46054E-1344-5B17-B353-8A68A0C97DB0">
<li id="GUID-41959955-766E-5AAD-AA6D-65C4F99E5581"><p>Some image formats contain
background colour information. This is information is presented through <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-7CE85F05-6D58-30F1-87D3-324BFB6131FB"><apiname>CImageDecoder::FrameInfo()</apiname></xref>  <codeph>iBackgroundColor</codeph>. </p> </li>
<li id="GUID-B3419EC0-109F-5A37-9A4F-CD0F7A96FCDC"><p>If a non-masked image
with background colour is decoded, the colour is included in the image data.
If the decoded image also contains a bitmap mask, then the background colour
will be a component of the mask <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> object. Depending
on your application, you may want to choose your own background colour rather
than use the one provided by the source image. </p> </li>
</ol> <p id="GUID-FF418A2D-436B-515F-B9D1-E0A0C87E7394"><b>Basic Procedure To Retrieve
Information From An Image</b> </p> <p>The high level steps to retrieve the
information stored in certain types of images are shown here: </p> <ol id="GUID-2D40722B-5BEA-52ED-B143-A4E85CE8EB22">
<li id="GUID-B40D32A1-CC43-50B8-A873-A6E14C27D165"><p> <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-01F212DD-0A35-3702-948B-1CBFB6675456"><apiname>CImageDecoder::FrameData()</apiname></xref> Provides
access to additional chunks of data within the images, for example, palette
and similar lookup tables, copyright information and other strings. This information
should be used with care, the returned data is merely a reference to the original
data within the <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> object, and is only valid
for the lifetime of the object. </p> </li>
<li id="GUID-875B1CFA-CE86-50D7-BD8A-4E7453EEF35F"><p> <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-B237AB64-0A03-3356-AA51-FCFD59E1A513"><apiname>CImageDecoder::NumberOfImageComments()</apiname></xref> and <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-F7CADA2E-4B76-3B23-B5CA-92CD652E9A97"><apiname>CImageDecoder::ImageCommentL()</apiname></xref> Images can have comments embedded in them. These comments are usually either
embedded as a single repository which can be retrieved on an image level,
or multiple repositories attached to individual frames within the image. The
two functions above return the number of comments attached to the entire image
and provide a mechanism for retrieving any of those comments. </p> </li>
<li id="GUID-6854DEC9-4348-56DD-B5E2-47DEE3DC43AE"><p> <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-3057B1A5-9F03-363B-9E84-9CFE2A2892EB"><apiname>CImageDecoder::NumberOfFrameComments()</apiname></xref> and <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-28A8EF22-C0C8-32BB-B9F3-96588F63A321"><apiname>CImageDecoder::FrameCommentL()</apiname></xref> Similar functionality to above, but these functions return the number of
comments attached to individually specified frames and provide a mechanism
for retrieving any of those comments. </p> </li>
<li id="GUID-F51D81A1-61A7-5C1C-B0FB-99B18C1203DC"><p> <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-78BF07BC-5338-3A60-B8BF-47DAFE2CA82C"><apiname>CImageDecoder::FrameInfoStringsLC</apiname></xref> and <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-7B3BDF3B-43BA-3206-AF62-174B7C3AF516"><apiname>CImageDecoder::FrameInfoStringsL()</apiname></xref> Provide a list of data for a specified frame, including data items such
as format, plugin description, size and so on, in a readable format. Although
the property strings can be accessed by name, it is recommended that they
be generally treated as a list of strings. </p> </li>
</ol> <p id="GUID-AA950124-42DE-5A65-B371-7D85F43D71A6"><b>Basic Procedure Streamed
and Progressive Decoding</b> </p> <p> <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> includes
facilities to support the simultaneous decoding and display of images as they
are being loaded. The decoder does not wait for the entire image to be loaded
before processing it, rather it begins as soon as possible, stops when it
runs out of data and then carries on when more data is available. </p> <p>The
high level steps to perform the streaming and the progressive during decoding
are shown here: </p> <ol id="GUID-0E29E833-4435-5E55-908F-938A13473B79">
<li id="GUID-CE64D3C8-8923-5BAF-AF29-9BA6470008F8"><p>If there is insufficient
data to work out the image format (plugin decoder to use) <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
its "Data" equivalent) leaves with <codeph>KErrUnderflow</codeph>. This is
only applicable to instances where automatic detection of the plugin decoder
is used. For more information see, "Automatic detection" in <xref href="GUID-B10B048F-37FF-53E7-92B9-83F8C197566A.dita#GUID-B10B048F-37FF-53E7-92B9-83F8C197566A/GUID-1F8A0DCC-CB95-5245-9ED0-FE4A775152D0">Creation</xref>. </p> </li>
<li id="GUID-23175979-940A-507D-B478-0C4ACB5F9071"><p>As soon as the correct
plugin decoder has been determined it is opened and whatever addition image
data available is scanned. The plugin decoder continues to decode image data
as it arrives, updating <codeph>FrameCount()</codeph> whenever it becomes
aware of a new frame within the data. The internal flag <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-26084926-42C1-38FC-9F30-E1801AE5167D"><apiname>CImageDecoder::IsHeaderProcessingComplete()</apiname></xref> is
maintained at <codeph>EFalse</codeph> until the entire image has been loaded. </p> </li>
<li id="GUID-75959B88-7CE2-598E-9F83-EC0189BD2F6C"><p>Frames can be decoded
before the entire image is loaded, but the frame to be decoded must be at
least partially loaded. If <codeph>IsHeaderProcessingComplete()</codeph> is
set to <codeph>EFalse</codeph> and <codeph>FrameCount()</codeph> is equal
to or less than the frame to decode, the application must wait for the relevant
frame to load. In such circumstances a call to <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-A74CEA6D-ED47-3EA4-8917-FEE4B51B7639"><apiname>CImageDecoder::ContinueProcessingHeadersL()</apiname></xref> should
be made that scans for any further headers. <codeph>FrameCount()</codeph> and <codeph>IsHeaderProcessingComplete()</codeph> should
then be recalled to determine if the frame has arrived. </p> </li>
<li id="GUID-C390495B-840E-541B-A0C5-061D3706AD8A"><p>Once <codeph>FrameCount()</codeph> is
greater than the frame the application wants to decode, it is possible to
start to decoding the frame using <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-8118AC37-471E-3CB6-9F71-4E93507DDE57"><apiname>CImageDecoder::Convert()</apiname></xref>.
Frame headers and their associated data do not always follow each other in
some image formats. This has the implication that although <codeph>FrameCount()</codeph> has
indicated that the frame is available, it may not yet be fully loaded. Under
such circumstances as much decoding as possible is undertaken, and <codeph>Convert()</codeph> then
completes with the error code <codeph>KErrUnderflow</codeph>. If the <codeph>EPartialDecodeInvalid</codeph> flag
(from <codeph>FrameInfo()</codeph>) is not set, the partially decoded image
can be displayed - for some image formats, a partially decoded image is not
generally usable, but this facility is supported by most known formats. Obviously,
if all of the image is present, <codeph>Convert()</codeph> completes with <codeph>KErrNone</codeph> as
normal. </p> </li>
<li id="GUID-44864401-5DB5-56A5-BE6D-5B8B4570CCBF"><p>Where only a partial
conversion has been completed, <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita#GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4/GUID-F4F5A5F6-03E5-3801-93CC-A023363F35F8"><apiname>CImageDecoder::ContinueConvert()</apiname></xref> should
be used to continue converting when new data arrives. <codeph>ContinueConvert()</codeph> continues
to convert the frame data where the previous call left off. This function
should continue to be called until it returns the error code <codeph>KErrNone</codeph> rather
than <codeph>KErrUnderflow</codeph>. </p> <p>Note: The <xref href="GUID-683A1D42-2764-3EB7-BD19-9E12559199AB.dita"><apiname>CFbsBitmap</apiname></xref> must
never be resized during a conversion session using <codeph>ContinueConvert()</codeph>,
if resizing does occur, a panic will be raised by the function. If resizing
or any other parameter changes need to be made to the <codeph>CFbsBitmap</codeph>,
frame decoding should be restarted by using <codeph>Convert()</codeph> rather
than trying to continue an existing conversion session. </p> </li>
</ol> <p>There is no explicit decoder call to say "all of the data is now
present". This could be done via inference, continuously checking <codeph>IsHeaderProcessingComplete()</codeph> until
it returns <codeph>ETrue</codeph>. However, this is not advisable as it is
possible that <codeph>IsHeaderProcessingComplete()</codeph> could continue
to return <codeph>EFalse</codeph> even after the application has finished
sending image data. Your state machine should be written so that it takes
this possibility into account. </p> <p id="GUID-C7FEA8F9-B367-52B1-9D26-84F9E225D17C"><b>Basic Procedure For Buffered
Decoding</b> </p> <p> <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita"><apiname>CBufferedImageDecoder</apiname></xref> is a wrapper
that encapsulates not only a <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> but also the
descriptor used to store the image, and in some circumstances can replace
the use of <codeph>CImageDecoder</codeph> itself. <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita"><apiname>CBufferedImageDecoder</apiname></xref> can
always be created, even if there is no data available at the time of creation.
Another key feature of <codeph>CBufferedImageDecoder</codeph> is that it can
be reused to decode multiple images. </p> <p>The high level steps to perform
the buffered decoding are shown here: </p> <ol id="GUID-0EEA3303-59C3-5326-8E10-3C54BE69B336">
<li id="GUID-8749D5E2-2E9D-578B-A02C-C4C1309E2AC5"><p>The decoder is created
using the <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita#GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378/GUID-D255B2EF-1DA0-336E-A173-0FD03210B349"><apiname>CBufferedImageDecoder::NewL()</apiname></xref> factory function,
and the decoding process is started with one of the two <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita#GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378/GUID-A8D36C2B-C057-3F6A-A1AF-F7421D204B11"><apiname>CBufferedImageDecoder::OpenL()</apiname></xref> calls,
specifying either MIME-type or image type/sub-type and UID, which are similar
to <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>. If not enough data is available
to create an internal decoder a call to <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita#GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378/GUID-0C7E0E24-8352-353E-9E55-D216300D1CFA"><apiname>CBufferedImageDecoder::ValidDecoder()</apiname></xref> returns <codeph>EFalse</codeph>.
The decoder keeps an internal copy of the data provided so the client can
discard its own copy. </p> <p> <b>Warning:</b> The decoding and enquiry functions
must not be used until an internal decoder has been created, otherwise calls
will panic with <codeph>EDecoderNotCreated</codeph>. </p> </li>
<li id="GUID-A1DD251D-D1B2-57EE-9A2D-94AE75DBA35B"><p>Additional data can
be supplied to the decoder, when it becomes available, by using <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita#GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378/GUID-5CF4094C-A829-347A-835C-17ABF439445A"><apiname>CBufferedImageDecoder::AppendDataL()</apiname></xref> and <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita#GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378/GUID-B85FD15C-337A-393F-A9DA-65EC1EB546C5"><apiname>CBufferedImageDecoder::ContinueOpenL()</apiname></xref>, which will copy the data and try to find an appropriate plugin. This step
should be repeated until enough data is available to create the internal decoder,
indicated by <codeph>ValidDecoder()</codeph> returning <codeph>ETrue</codeph>. <codeph>OpenL()</codeph> and <codeph>ContinueOpenL()</codeph> will
leave with <codeph>KErrCorrupt</codeph> if a suitable decoder is found, but
that decoder was unable to interpret the supplied image data. </p> <p>Note:
As with <codeph>OpenL()</codeph>, data provided by <codeph>AppendDataL()</codeph> is
kept in an internal buffer by the decoder so the client can discard its own
copy. </p> </li>
<li id="GUID-E4E67E99-0D9A-5CA9-8FE3-6A32A36C3F42"><p>The process for decoding
the image header and frames are the same as for <xref href="GUID-8F2953B2-E64E-3D8B-B30B-B35B373368D4.dita"><apiname>CImageDecoder</apiname></xref> with <codeph>IsHeaderProcessingComplete()</codeph>, <codeph>FrameCount()</codeph>, <codeph>Convert()</codeph> and <codeph>ContinueConvert()</codeph> calls
except that the data is not appended to a descriptor, but supplied to the
decoder with <codeph>AppendDataL()</codeph>. </p> </li>
<li id="GUID-E40CF367-2601-5B9F-9E20-34CD8F2754EB"><p>The decoder can be reused
by calling a <xref href="GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378.dita#GUID-DD2EDAB6-784C-3FC9-A53D-84D133049378/GUID-44030283-5CB8-3317-8498-0B70C0C358A9"><apiname>CBufferedImageDecoder::Reset()</apiname></xref>, which destroys
the internal data buffer and decoder. A new decoder plugin can then be started
using <codeph>OpenL()</codeph>. </p> </li>
</ol> </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-A825B62E-B5F6-5FDD-B267-E47103D57FD8.dita"><linktext>Guide to
Symbian supplied Codecs </linktext></link>
</related-links></concept>