symba (779893), страница 35
Текст из файла (страница 35)
This flag still doesn’tguarantee the ability to retrieve some meaningful transparency information by passing the aMaskbitmap parameter to the Convert() method. At thetime of writing, the only image decoder supplied bySymbian that supports this flag is the WMF imagedecoder.EPreferFastDecodeThis option instructs the image decoder to performdecoding as fast as possible. A decoder, at its owndiscretion, may sacrifice some quality and use lessprecise algorithms when decoding the image. Manydecoders silently ignore this flag, so it should be safeto specify whenever you favor performance at theexpense of quality.Decoding of the DRM-protected content is similar to decoding aregular image, apart from setting up some DRM-specific parameterswhen creating a decoder object:CImageDecoder* decoder = CImageDecoder::FileNewL(fs,TMMFileSource(aFileName,ContentAccess::KDefaultContentObject,ContentAccess::EView,EFalse));The TMMSource class defined in mm\mmcaf.h and its derivativesTMMFileSource and TMMFileHandleSource provide containers forDRM-specific parameters for the DRM content referred to by the filename and file handle respectively.
Decoding DRM content stored in amemory buffer is not supported for security reasons.DRM support in Symbian OS is covered in Chapter 2 and in theSymbian Developer Library documentation found in your chosen SDK.6.2.8 Interpreting Error CodesUnfortunately real-world applications have to deal with errors.
Errors mayarise due to input data being invalid, inconsistent application requests tothe API, implementation restrictions, and so on.The image decoder API uses normal system-wide error codes to letthe user know if something goes wrong. There are no CImageDecoderspecific error codes defined.DECODING IMAGES161The most common source of error codes is the set of CImageDecoderfactory functions such as FileNewL(). These methods may leave withvarious error codes, such as KErrNoMemory (which can be easilyinterpreted) or any other file-system-related error codes because the APIimplementation uses file system functionality and does not translate errorcodes but simply passes them on.Some error codes may mean different things depending on when theerrors occur. Table 6.4 lists the most common error codes which may beproduced by the CImageDecoder API.Table 6.4 Common CImageDecoder Error CodesKErrNotFoundThis error code may mean either ‘source file not found’ or ‘nodecoder capable of decoding the given image format found’.One way of avoiding this ambiguity is to use the version ofFileNewL() which accepts a file handle (RFile); if the file hasbeen successfully opened, then KErrNotFound means that nosuitable decoder plug-in has been found.KErrUnderflowThis error code should usually be read as ‘system has insufficientdata in the image file/buffer to complete an operation’.
This usuallyoccurs when an attempt is made to decode a partially downloaded(truncated) image file. This error code may be encountered duringthe creation of the decoder object or during decoding. In the lattercase, the error is not fatal, as the API client has the followingoptions to deal with the error code:KErrArgument•When more data can be obtained for the image (e.g. if thefile being streamed from a network connection), it can waitfor more data to arrive, append the data to the original fileor memory buffer and retry the decoding attempt by callingCImageDecoder::Convert() with the same parameters.•When no more data can be obtained, it can check the presenceof the EPartialDecodeInvalid flag for the given frame.If this flag is present, then the output bitmap doesn’t containany valid image data and the error is fatal. If the flag is absent,it means that the output bitmap has part of an image decodedinto it and the application may use this bitmap.
Unfortunately,due to API limitations, it is not possible to determine whichregions of the image have been successfully decoded.This error code usually means that the destination bitmap sizecannot be used for decoding this frame; it usually happens whenthe API client fails to use ReducedSize() and ReductionFactor() to calculate an achievable destination size (seeSection 6.2.4).(continued overleaf )162IMAGE CONVERSION LIBRARYTable 6.4 (continued )KErrNotSupportedThis error code usually means that the decoder failed to copeeither with the destination bitmap color mode (see Section 6.2.3)or with the image itself. For example, during the creation phasethe image headers may seem to be fine for the decoder loaded,however during the decoding process the decoder may run intosome image file format feature which prevents the image frombeing decoded correctly (since it is not supported by the givendecoder).KErrCorruptThis error may come from one of two sources:• the file system, in which case something serious has happenedto the underlying file system• the decoder plug-in, in which case the decoder has found somemajor image file format discrepancies and cannot proceedfurther with this decoding.
Unfortunately it is not possible tofigure out if there was any pixel data decoded at all.6.2.9 Additional Frame InformationThe TFrameInfo structure is a good source of information about openedimage frames. It has been designed to be quite generic and provide themost common (and most useful) information.Some image formats may provide much more information abouttheir frames than TFrameInfo may accommodate. There are two moremechanisms for retrieving information about image frames:• frame comment retrieval• frame metadata retrieval.Frame comment retrieval methods can be used to get hold of textualinformation which may exist in the image.
This is usually some sort ofauthor commentary about the image, copyright notices, and so on.The CImageDecoder API defines two groups of methods: one forretrieving image-wide data and one for frame-specific data:TInt NumberOfImageComments() constHBufC* ImageCommentL(TInt aCommentNumber) constIt is quite easy to get all the image comments once an instance of thedecoder object is created:const TInt KNumOfComments = aDecoder.NumberOfImageComments();DECODING IMAGES163for (TInt i=0; i < KNumOfComments; i++){HBufC* comment = aDecoder.ImageCommentL(i);// do something with the comment// de-allocate memorydelete comment;}The thing to be aware of is that ImageCommentL() returns a Unicodedescriptor, while many image formats have been designed to use 8-bitASCII comments.
Most of the decoders pad the 8-bit character set tothe 16-bit one using the standard TDes::Copy() method (the mostsignificant bytes are filled with zeros).Dealing with frame-specific comments is very similar to dealing withimage-wide ones but we have to use frame-specific methods and providea frame number:const TInt KNumOfComments = aDecoder.NumberOfFrameComments(aFrameNumber);for (TInt i = 0; i < KNumOfComments; i++){HBufC* comment = aDecoder.FrameCommentL(aFrameNumber, i);// do something with the comment// de-allocate memorydelete comment;}The following two methods can be used to retrieve human-readableinformation about the given frame of the image:CFrameInfoStrings* FrameInfoStringsLC(TInt aFrameNumber = 0)CFrameInfoStrings* FrameInfoStringsL(TInt aFrameNumber = 0)FrameInfoStringsL() should provide localized textual information i.e.
using the system’s current locale settings. You must delete theinstance of CFrameInfoStrings once you’ve finished with it.Apart from well-defined entities such as textual comments, manydecoder plug-ins may expose additional (at times quite low-level) information about image frames. This kind of information is specific to aformat and quite often applications don’t need to know about it.CImageDecoder defines the following method, which returns a collection of abstract pieces of frame information for the given frame number:const CFrameImageData& FrameData(TInt aFrameNumber = 0) constCFrameImageData exposes a collection of abstract frame and imageproperties (see Figure 6.5), which an application identifies using the164IMAGE CONVERSION LIBRARYCFrameImageDataGetFrameData(TInt) : TFrameDataBlock∗GetImageData(TInt) : TImageDataBlock∗AppendImageData(const TImageDataBlock∗) : TIntAppendFrameData(const TFrameDataBlock∗) : TIntImageDataCount() : TIntFrameDataCount() : TInt++++++0..∗0..∗TImageDataBlockTFrameDataBlock# TImageDataBlock(TUid)+ DataType() : TUid# TFrameDataBlock(TUid)+ DataType() : TUid++++++++++++++CImageDecoder«use»TTiffImageDataTJpegQTableiNewSubfileType: TUint32iSizeInPixels: TSizeiBitsPerSample: TIntiSamplesPerPixel: TIntiCompression: TIntiT4Options: TIntiT6Options: TIntiPhotometricInterpretation: TIntiFillOrder: TIntiWidthInTwips: TRealiHeightInTwips: TRealiRowsPerStrip: TIntiNumStrips: TIntiStripInfo: HBufC8∗+ iTableIndex: TInt+ iEntries: TBuf8<KJpgQTableEntries>+ TTiffImageData()+ TJpegQTable()TJpegImageData+ iSampleScheme: TColorSampling+ iQualityFactor: TInt+ TJpegImageData()TGifImageControl++++iDelayTimeInCentiseconds: TIntiTransparentColorIndex: TIntiUserInputFlag: TBooliDisposalMethod: TDisposalMethodTGifComment+ iComment: HBufC8∗+ TGifComment()+ TGifImageControl()Figure 6.5CFrameImageData class diagramDataType() method.
All the Symbian-defined data type Uid definitionscan be found in the icl\ImageCodecData.h header file along withspecialized definitions of the data structures.The API client should implement the following algorithm in order tocollect information from the format-specific frame properties:1.Retrieve an instance of CFrameImageData for the given frameindex.2.Iterate over all the properties using the CFrameImageData::FrameDataCount() and CFrameImageData::GetFrameData() methods.3.Using TFrameDataBlock::DataType(), make a decision onwhether the current property is of interest and cast it to the appropriatetype.It should be noted that CFrameImageData exposes two collections ofproperties; the second one can be retrieved by calling GetImageData().DECODING IMAGES165This collection is meant to contain the image-wide format-specific properties, despite the fact an API client has to retrieve it by specifying theframe number.