symba (779893), страница 33
Текст из файла (страница 33)
The CImageDecoder class doesn’thave a notion of ‘the whole image’, instead an API user should thinkabout an image as a sequence of frames.Table 6.1 provides a summary of the information which can beobtained about the image frame using public data members or methods.DECODING IMAGES151Table 6.1 Contents of TFrameInfoTFrameInfoStateThe current frame processing state. Usually all the image framesare parsed once the CImageDecoder instance is created i.e. during object creation. However there is no strong guarantee that allthe decoder plug-ins work in this way.
Another case in whichframe status has to be checked is progressive image decoding (seeSection 6.2.13), which can be used when an image is streamedacross a network. It is safe to rely on the rest of this structure dataonly if TFrameInfo::CurrentFrameState() == EFrameInfoProcessingComplete.CurrentDataOffset()Retrieves the data pointer offset being used by the plug-in while processing this frame.
It is of little use to API clients but is used by theframework to interact with the plug-in.FrameDataOffset()Retrieves the frame data offset within the whole image file; again, it isused by the framework to manage data transfers to the plug-in duringimage decoding.iFrameCoordsInPixelsThe current frame coordinates in pixels within the animation sequence.Some animated image formats (e.g. GIF) support animation frames inwhich position and size may vary. Use iOverallSizeInPixels forsingle-frame images.iFrameSizeInTwipsCurrent frame size translated into twips.5 (You can ignore twips unlessyou are writing ‘what you see is what you get’ publishing software.)iBitsPerPixelThe native color depth of the frame, which may change from frame toframe.iDelayThe animation renderer should perform this delay (in microseconds)after presenting this frame to a viewer and before rendering the nextframe.iFlagsThis member holds a number of flags (see Table 6.2) that define thecurrent frame properties.iOverallSizeInPixelsThe size which is needed to compose this frame into an animationsequence taking into account the animation canvas size.
It can beseen, roughly, as the overall size of the animated image. In mostcases, it is equal to iFrameCoordsInPixels.Size(). The GIFimage decoder supplied by Symbian always sets this member to theiFrameCoordsInPixels.Size().iFrameDisplayModeThe frame’s original color mode. In most cases, it is better to use thesame color mode when creating the frame’s destination bitmap.iBackgroundColorThe background color, which you are advised to use when the animationcanvas is being drawn for the first time or is being cleared due to theERestoreToBackground instruction.iFrameSizeInPixelsThe current frame size in pixels.
It is valid only when EUsesFrameSizeInPixels is set. This member can be seen as redundant;however it was introduced in Symbian OS v9.2 to fix some ambiguitywhich arises when handling animated GIF images. This member, if valid,defines the original unadjusted frame size in pixels.5 The term ‘twip’ is derived from ‘twentieth of an inch point’ – it is a typographicalmeasurement defined as 1/20 of a typographical point, about 1/1440 inch.152IMAGE CONVERSION LIBRARYTable 6.2 Possible Contents of iFlagsEColorAn indicator that the frame has separate color channels; its absencemeans that the frame is grayscale.ETransparencyPossibleAn indicator that the frame has some transparent parts, i.e.
they aremasked out; its absence means that all the pixels of the frame areopaque and visible.EFullyScaleableAn indicator that the frame can be scaled to virtually any destinationsize; absence of this flag means that scaling capabilities are restrictedto a certain set of coefficients (see Section 6.2.4 for more informationabout scaling).EConstantAspectRatioAn indicator that the frame can only be scaled to a destination sizethat is of the same aspect ratio (i.e. width to height ratio) as the originalframe size.ECanDitherAn indicator that the frame can be decoded to virtually any destinationdisplay (color) mode; absence of this flag means that the frame isdecoded to the display mode specified by iFrameDisplayMode.EAlphaChannelAn indicator that the frame has an alpha channel; absence of this flagmeans that all the pixels are fully opaque.
This flag appears only ifthe ETransparencyPossible flag is present. In most cases, thealpha channel is obtained using the optional mask parameter of theConvert() method. It is not possible to enquire the bit depth of thealpha channel, so the EGray256 type of color mode should alwaysbe used to obtain alpha channel information.ELeaveInPlaceAn indicator that the animation canvas contents should be left asthey are before displaying this frame. This flag also defines a disposalbookmark (see ERestoreToPrevious). This flag, ERestoreToBackground and ERestoreToPrevious can be used by thedecoder plug-in to specify the frame composition instructions foranimated (multiframe) images. These flags are mutually exclusive.If none of these flags are present, you should replace the existingcontents of the animation canvas with this frame’s pixels and definethe frame disposal bookmark.ERestoreToBackgroundAn indicator that the animation canvas contents should be filledusing iBackgroundColor before displaying this frame.
This flagalso defines a disposal bookmark.ERestoreToPreviousAn indicator that the animation canvas contents should be restored tothe contents defined by the latest disposal bookmark before displayingthis frame’s contents.EPartialDecodeInvalidAn indicator that the output bitmaps do not contain image datasuitable for displaying. This flag may appear when a request to theConvert() method has been completed with a KErrUnderflowerror code (see Section 6.2.8 for more information).EMngMoreFramesToDecodeAn indicator that is used only by the MNG plug-in to indicate thatthere are more frames to decode.
See Section 6.2.12 for more details.EUsesFrameSizeInPixelsAn indicator that the iFrameSizeInPixels member is valid.Absence of this flag means that iFrameSizeInPixels should notbe used by the client application.DECODING IMAGES1536.2.4 Decoding to a Different SizeLet us consider a rather common use case of decoding an image to adifferent (usually reduced) size from its original. That use case can oftenbe seen in applications that do not control the way images are fed intoan application, such as image-viewing applications, applications that canexchange images, MMS applications, etc.We would like to be able to scale images to a certain size, either so itis possible to fit several image thumbnails into the application workspaceor to show a small image preview.
Another use case would be to obtainthe next smallest size to fit the screen whilst preserving the aspect ratio ofthe image (i.e. not stretching).There are several ways of scaling images to a certain size:• use features specific to an image format, such as thumbnail support(see Section 6.2.5)• use output bitmap scaling (see Section 6. 6.1)• use CImageDecoder API support for decoding images to a differentsize.6The latter option is probably the most difficult to use because its levelof support may vary across the range of decoder plug-ins.
It is usually themost efficient option in terms of performance and memory consumption,as a decoder plug-in may perform the scaling operation efficiently in thecourse of image decoding and even skip decoding of image regions andpixels which are not required. Using decoder-supplied features is notstraightforward, as it requires discovery of decoder plug-in capabilities atrun time.A well-written application should follow an algorithm such as the oneshown in Figure 6.4.Calculating the SizeHow can that algorithm be translated into code? Most pieces of thepuzzle are already there – the algorithm has references to the CImageDecoder::ReductionFactor() and CImageDecoder::ReducedSize() methods.
Let us take a closer look at them.6 In Symbian OS v9.5, the CImageDecoder API has explicit support only for scalingdown images. Support for scaling up will probably be made available in a later version ofSymbian OS. Symbian OS v9.5 has prototypes of the APIs, so curious readers may exploreimageconversion.h.154IMAGE CONVERSION LIBRARY[EFullyScaleableis NOT set]Calculate reduction factor using theCImageDecoder::ReductionFactor()[EFullyScaleable is set]Calculate destination size using theCImageDecoder::ReducedSize()Decreasereductioncoefficient[KErrNone]Convert the frame tothe desired sizeConvert the frame to thecalculated sizeScale the output bitmapusing the bitmap scaler[Desired size has been reached]Figure 6.4 Decoding an image to a desired sizeDECODING IMAGES155TInt ReductionFactor(const TSize& aOriginalSize,const TSize& aReducedSize) const• aOriginalSize is the frame’s original size which can be obtainedfrom the TFrameInfo.• aReducedSize is the desired destination size.The result of this method would be an integer which is the scalingcoefficient calculated by the decoder plug-in based on the parametersprovided.