symba (779893), страница 32
Текст из файла (страница 32)
Theplug-in system is not limited to just one plug-in for the given imagetype.• Manual resolution: The API user explicitly specifies which plug-in touse by supplying its UID. The plug-in system is built on top of ECOM,so the usual plug-in identification mechanism applies.There are several overloaded methods which can be used to create animage decoder object; they can be divided into two groups:CImageDecoder::FileNewL()CImageDecoder::DataNewL()DECODING IMAGES147The first group creates an image decoder object for an image which isto be read from the file system or DRM-enabled storage during decoding.The second group can be used to decode an image whose data resides ina memory buffer.
Let’s consider one of the FileNewL() methods:FileNewL(RFs& aFs, const TDesC& aSourceFilename,const TOptions aOptions = EOptionNone,const TUid aImageType = KNullUid,const TUid aImageSubType = KNullUid,const TUid aDecoderUid = KNullUid);• aFs is a reference to a file server session object, this saves somememory and time by sharing the same file server connection betweenseveral objects.• aSourceFilename is a file name (including path). There is a versionof the same method which accepts a handle (RFile) to an alreadyopened file.• aOptions is a very important parameter as it can be used to setcertain decoding options which can be specified only during thecreation of the decoder object.
We will come back to this parameterdescription in Section 6.2.6).• aImageType is the image type UID that can be used to trigger thesemi-automatic plug-in resolution mode. This parameter narrows thelist of plug-ins to be considered as candidates for the image decoding.For example, an API user may want to handle only JPG images; in suchcases, KImageTypeJPGUid should be used.
Other Symbian-definedimage type UIDs can be found in the icl\imagecodecdata.hheader file.• aImageSubType can be used to narrow a list of decoder plug-ins toa certain image subtype. You can specify this parameter only if theimage type has been supplied. Certain image types may have definedsubtypes which may be handled differently. Symbian-defined imagesubtypes can be found in the icl\imagecodecdata.h headerfile. For example, KImageTypeTIFFUid has two subtypes, KImageTypeTIFFSubTypeLittleEndianUid and KImageTypeTIFFSubTypeBigEndianUid for little-endian and big-endian formats respectively.• aDecoderUid has a dual meaning.
It can either mean that the plug-inresolver has to load a specific plug-in (for example, in the case ofthe BMP plug-in, it is KBMPDecoderImplementationUidValue)or one of a class of decoder plug-ins (that is, a set of plug-ins whichmay support different image formats but share some common features,148IMAGE CONVERSION LIBRARYsuch as, Exif metadata support). These decoder plug-ins may wish toexpose extra features which are not a part of the standard CImageDecoder class by implementing a class derived from CImageDecoder. For example, there is a CJpegEXIFDecoder class whichis derived from CImageDecoder; how can we get an instance ofthat class if FileNewL() returns CImageDecoder? It can be doneby using a standard C++ typecast such as static_cast<>, but onlyif the decoder object has been created using the KUidICLJpegEXIFInterface value for the aDecoderUid parameter.Once a decoder object has been created using one of the factorymethods, the plug-in has been selected and it’s too late to specify aspecific implementation.
You can query the decoder’s implementationUID after creation and typecast to the appropriate sub-class to useextended functionality, but this is likely to make your code structure morecomplex.The following overload can be used to create an image decoder objectby supplying the image MIME type, thus narrowing the list of potentialplug-ins to be considered:CImageDecoder* FileNewL(RFs& aFs, const TDesC& aSourceFilename,const TDesC8& aMIMEType,const TOptions aOptions = EOptionNone);There is no list of predefined MIME types supported by the system,instead it can be discovered at run time by calling the static methodCImageDecoder::GetMimeTypeFileL().6.2.3 Getting Information about the Opened ImageOur first attempt to open and decode the image used quite a naı̈veapproach to the destination bitmap size – we just used a square bitmapof size 20 by 20 pixels.
The following methods of the CImageDecoderclass can be used to obtain the most vital information about the openedimage:TInt FrameCount() constconst TFrameInfo& FrameInfo(TInt aFrameNumber = 0) constFrameCount() is used to obtain the number of frames from whichthis image is made (except for the special case of the MNG format,which is discussed in Section 6.2.12). This enables CImageDecoderto handle multiframe or animated image formats such as GIF.
In mostDECODING IMAGES149cases, FrameCount() returns 1 for still image formats, such as PNG,however some still image formats (such as the Symbian OS MBMimage format) allow the embedding of several images into a singlefile and FrameCount() should return the number of such images.Neither CImageDecoder::FrameInfo() nor CImageDecoder::Convert() can be used with frame numbers greater than or equalto CImageDecoder::FrameCount().FrameInfo() retrieves information about the specific frame of theimage. It returns a TFrameInfo structure. At the moment, we areinterested in just three public members of this structure:TDisplayMode iFrameDisplayMode;TRect iFrameCoordsInPixels;TSize iOverallSizeInPixels;iFrameDisplayModeTDisplayMode provides information about the frame’s native colormode.
This color mode should be used for the frame decoding in order forthe output bitmap to be as close to the original image as possible. An application may consider using the current system-wide display mode insteadof the frame’s original color mode in the case when a converted framewill be displayed within the application UI (the custom icon use case).When you use the image’s native color mode, the decoder may haveto do less work. If the image’s original color mode differs from thesystem-wide one, then (depending on the screen driver and underlyinghardware), the final image presented to an end user may appear of lowerquality in comparison to the decoder-converted image.When you use the system-wide color mode, the decoder plug-inproduces the best-looking (from its point of view) frame when convertedto the destination color mode.
However that may come at the price ofreduced decoder performance as it involves perceptual color conversion.There is no rule of thumb in this situation. In many cases, decoding a frame to the widest color mode (EColor16M or EColor16MA,if supported) produces the best performance–quality ratio, at someexpense of memory consumption. Performance issues are discussed inSection 6.2.15.iFrameCoordsInPixelsThis TRect contains the coordinates and size of the given frame withinthe image. For animated image formats (such as GIF), a frame may besituated somewhere within the whole image, hence the use of a TRectrather than just a TSize.
For still images, in most cases, the TRect wouldlook like this: (0, 0, image_width, image_height).150IMAGE CONVERSION LIBRARYiOverallSizeInPixelsWe can easily obtain the frame size by using the Size() method of theTRect class. Alternatively, where we know we are dealing with singleframe images we would typically use the third member, iOverallSizeInPixels, rather than the frame coordinates to get the image size.However, when we are dealing with an animation this member has adifferent interpretation (as shown in Figure 6.3) and we would typicallyuse the frame coordinates for individual frame sizes.iOverallSizeInPixelsFrame 0Animation canvasFrame 2Frame 1iFrameCoordsInPixelsCurrent frame (2)Figure 6.3 Animation composition and frame coordinatesNote how individual frames within an animation can change size andposition on the animation canvas.Using the TFrameInfo StructureSo, to be accurate we should refine our simple image decoding class bycreating the destination bitmap as shown in this code:// get the first frame informationconst TFrameInfo frameInfo( iDecoder->FrameInfo(0) );// create a destination bitmap of the frame size and native color modeUser::LeaveIfError( iBitmap->Create(frameInfo.iFrameCoordsInPixels.Size(),frameInfo.iFrameDisplayMode) );The TFrameInfo structure is the main source of information aboutsuccessfully opened image frames.