symba (779893), страница 36
Текст из файла (страница 36)
As can be seen from Figure 6.5, there are a fair amount ofimage-wide properties defined.The application should iterate over all the image frames in order tocollect the image-wide format properties as they can be spread acrossall the frames. Some implementations may use frame zero to storeimage-wide properties; that is implementation-specific and a well-writtenapplication should not make this assumption.Here is a fairly simple implementation of the algorithm describedabove:// get number of frames in the imageconst TInt KFrameCount = aDecoder.FrameCount();// iterate all the framesfor (TInt frameIndex = 0; frameIndex < KFrameCount; frameIndex++){// retrieve properties collectionconst CFrameImageData& data = aDecoder.FrameData(frameIndex);// get number of the elements in the collectionconst TInt KNumDataElements = data.ImageDataCount();// iterate all the propertiesfor (TInt i = 0; i < KNumDataElements; i++){// retrieve the current abstract blockconst TImageDataBlock* block = data.GetImageData(i);// depending on the block type, do something with itswitch ( block->DataType().iUid ){case KJPGQTableUidValue:{const TJpegQTable* jpegQTable = static_cast<constTJpegQTable*>(block);// use this information somehow}break;case KGIFBackgroundColorUidValue:{const TGifBackgroundColor* gifBgColor =static_cast<const TGifBackgroundColor*>(block);// use this information somehow}break;}}}6.2.10 Plug-in DiscoveryThe CImageDecoder class has some functionality which allows retrievalof information about the decoder plug-in being used.
These informational166IMAGE CONVERSION LIBRARYmethods can be useful for debugging or for implementing plug-in specificbehavior (which is, in general, not very good practice).The following method allows you to get the UID that uniquely identifiesthe plug-in:TUid ImplementationUid() constIn fact there could be several plug-ins (each one with its own uniqueUID) able to handle the same image type UID. It is the framework’s jobto decide which plug-in to load for the given image, unless the API clientexplicitly specifies a plug-in UID to be loaded.There are a number of static methods of CImageDecoder that allowdiscovery of the available plug-ins installed on the system the imageformats they support prior to creation of the decoder object:static void GetImageTypesL(RImageTypeDescriptionArray& aImageTypeArray);static void GetFileTypesL(RFileExtensionMIMETypeArray&aFileExtensionArray);static void GetImageSubTypesL(const TUid aImageType,RImageTypeDescriptionArray& aSubTypeArray);static void GetMimeTypeFileL(RFs& aFs, const TDesC& aFileName,TDes8& aMimeType);static void GetMimeTypeDataL(const TDesC8& aImageData, TDes8& aMimeType);static CImplementationInformationType* GetImplementationInformationL(TUid aImplementationUid);Figure 6.6 describes the relationships between different entities whichcan be retrieved using these methods.GetImageTypesL() and GetFileTypesL() can be used to retrieve CFileExtensionMIMEType and CImageTypeDescriptionstructures, respectively, for all the installed plug-ins.
These structures canbe used to find out which image types can be handled by the system alongwith their attributes (the file extension by which a file can be recognized,MIME type, image type UID, etc.).The GetImageSubTypesL() method can be seen as a helper thatcan be used to get all the image sub-types for the given image type.The GetMimeTypeFileL() and the GetMimeTypeDataL() methods can be used to detect the underlying file and data buffer MIME typesrespectively. These methods do not use system-wide MIME type recognition routines; instead they match against all of the installed decoderplug-ins.The GetImplementationInformationL() method can be usedto retrieve the ECOM-like implementation information for a given decoderplug-in UID.DECODING IMAGES167Plug-in+ interface_uid: TUid1+Description1..∗TUid0..+ ImageType: TUid+ ImageSubType: TUid∗0..∗11+1 +++++10..∗0..∗«binary data»HeaderMatchData«CImplementationInformation of ECOM»CImplementationInformationTypeDecoder Implementation+Decoder Class Uid0..1CBase1ImplementationUid() : TUid {query}Version() : TInt {query}DisplayName() : TDesC& {query}DataType() : TDesC8& {query}OpaqueData() : TDesC8& {query}Drive() : TDriveUnit+ displayName0..110..∗0..∗«string»MimeType«string»FileSuffix0..10..1+displayNameCBaseCBaseCFileExtensionMIMETypeCImageTypeDescription+ Description() : TDesC& {query}+ ImageType() : TUid {query}+ SubType() : TUid {query}++++++FileExtension() : TDesC& {query}MIMEType() : TDesC8& {query}DisplayName() : TDesC& {query}ImageType() : TUid {query}ImageSubType() : TUid {query}ImplementationUid() : TUid {query}RPointerArray<CImageTypeDescription>RPointerArray<CFileExtensionMIMEType>«typedef»RImageTypeDescriptionArray«typedef»RFileExtensionMIMETypeArrayFigure 6.6 Relationships between plug-in information entities6.2.11 Exif Metadata ProcessingExif metadata processing is closely coupled with the CImageDecoderAPI,7 which means that an image decoder object has to be instantiatedin order to gain access to the metadata information.7 Nokia had created an API for Exif metadata processing before Exif support wasintroduced in Symbian OS v9.1.
Nokia-owned APIs are not part of the core Symbian OSSDK. All the Symbian-provided Exif APIs are excluded from the S60 3rd Edition SDKs. Allthe UIQ 3 SDKs use core Symbian Exif APIs.168IMAGE CONVERSION LIBRARYExif metadata support is not a part of the core CImageDecoder API,but rather an optional extension to it implemented by the CJPEGExifDecoder class which is derived from CImageDecoder.It is not possible to explicitly create an instance of the CJPEGExifDecoder, so an API client has to use a special technique to createan instance of the decoder object and then use standard C++ typecasting. It is advisable to use the aDecoderUid parameter during thedecoder instantiation in order to ensure type-safety when casting toCJPEGExifDecoder later on.In order to get a decoder that supports the Symbian-defined Exifinterface, an application should do something like this:// We ask for the decoder object which supports the "Exif Jpeg Interface"// by specifying the "class Uid" parameterCImageDecoder* decoder = CImageDecoder::FileNewL(fs, aFileName,CImageDecoder::EOptionNone,KNullUid, KNullUid,TUid::Uid(KUidICLJpegEXIFInterface));// now it is safe to cast that decoder object to the CJPEGExifDecoderCJPEGExifDecoder* jpegExifDecoder =static_cast<CJPEGExifDecoder*>(decoder);// now we can obtain MExifMetadata interface and use it to read raw Exif// metadata or create an instance of the TExifReaderUtilityMExifMetadata* exifMetadata = jpegExifDecoder->ExifMetadata();TExifReaderUtility exifReader(exifMetadata);// We can get the "orientation" tag value, for example, like thisTUint16 exifOrientation;if (KErrNone == exifReader.GetOrientation(exifOrientation)){// make use of the tag value}The Exif API is quite straightforward and easy to use (apart from theinitial step of Exif-compliant decoder creation).
One thing missing fromthis API is that it is not possible to enquire which Exif metadata is presentin a given image. The client has to try to get every Exif tag value it isinterested in and handle the KErrNotFound error code if this tag is notdefined in the image.6.2.12 Decoder Plug-ins Provided by SymbianSymbian supplies a number of CImageDecoder plug-ins in its referenceSDK (see Table 6.5). Device manufacturers are free to ship these plugins with their phones, replace them with their own specific versions orremove them (if they do not need them).DECODING IMAGES169Table 6.5 Decoder Plug-insImage Format Decoder UIDNotesWindows Bitmap (.bmp)KBMPDecoderImplementationUidValueThe 1, 4, 8, 16, 24, and 32 bpp and RLE-encoded formatsare supported.
Device manufacturers usually use this plug-inwithout changes.Graphics Interchange Format (.gif)KGIFDecoderImplementationUidValueGIF87a and GIF89a formats are supported but the ‘NetscapeApplication Loop Block’ is not supported. Device manufacturers usually use this plug-in without changes.JPEG (.jpg)KJPGDecoderImplementationUidValueBaseline, extended sequential (single scan) and progressivewith non-differential Huffman coding JFIF/Exif images aresupported.
Thumbnails are supported. JPEG2000 imagesare not supported.The maximum downscaling coefficient supported is 1/8.Many device manufacturers replace this plug-in with ahardware-accelerated version (the plug-in may be left butassigned a low priority).Symbian OS MBM (.mbm)KMBMDecoderImplementationUidValueIt is possible to handle native Symbian OS bitmaps (MBMfiles) in the same way as other images and load them usingthe CImageDecoder interface. However, using CFbsBitmap::Load() is the recommended way to do it.Device manufacturers usually use this plug-in withoutchanges.Portable Network Graphics (.png)KPNGDecoderImplementationUidValueAll valid images are supported.
Downscaling is not supported when decoding to EColor16MA or EColor16MAP.Device manufacturers usually use this plug-in withoutchanges.Windows Icon (.ico)KICODecoderImplementationUidValueAll valid 1, 4 and 8 bpp images, including multiframe iconsare supported. Device manufacturers usually use this plug-inwithout changes.TIFF Fax (.tiff)KTIFFDecoderImplementationUidValueGroup3, 1d and 2d coding, and Group4 fax compression,including multiframe faxes, are supported. Device manufacturers usually use this plug-in without changes.Windows metafile (.wmf)KWMFDecoderImplementationUidValueAll valid Windows metafiles are supported.
Device manufacturers usually use this plug-in without changes.Wireless Bitmap (.wbmp)KWBMPDecoderImplementationUidValueAll valid bitmaps are supported. Device manufacturers usually use this plug-in without changes.Over The Air Bitmap (.ota)KOTADecoderImplementationUidValueAll valid bitmaps are supported. Device manufacturers usually use this plug-in without changes.Multiple-image Network Graphics (.mng)KUidIclMngPluginImplUidThe ‘low complexity’ (LC) profile is supported. Embedded JNG images are not supported. CImageDecoder::FrameCount() is not supported.