examples/Multimedia/ICL/ICLCodec/PNGCodec.h

00001 // PngCodec.H
00002 //
00003 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
00004 // All rights reserved.
00005 // This component and the accompanying materials are made available
00006 // under the terms of "Eclipse Public License v1.0"
00007 // which accompanies this distribution, and is available
00008 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00009 //
00010 // Initial Contributors:
00011 // Nokia Corporation - initial contribution.
00012 //
00013 // Contributors:
00014 //
00015 // Description:
00016 //
00017 //
00018 
00019 #ifndef __PNGCODEC_H__
00020 #define __PNGCODEC_H__
00021 
00022 #include <bitdev.h>
00023 #include <ezcompressor.h>
00024 #include <ezdecompressor.h>
00025 #include <icl/imageprocessor.h>
00026 #include <icl/imagecodec.h>
00027 
00028 #include "PNGConvert.h"
00029 
00030 //.
00031 // Constants.relating to PNG standard 
00032 //
00033 const TInt KPngFileSignatureLength = 8;
00034 const TUint8 KPngSignature[KPngFileSignatureLength] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
00035 
00036 const TInt KPngChunkIdSize = 4;
00037 const TInt KPngMaxPLTESize = 256;
00038 const TInt KPngNumInterlacedPasses = 8; // 7 passes plus a safety entry
00039 
00040 const TInt KPngChunkLengthSize = 4;
00041 const TInt KPngChunkCRCSize = 4;
00042 
00043 const TInt KPngIHDRChunkSize = 13;
00044 const TInt KPngIENDChunkSize = 0;
00045 const TInt KPngcHRMChunkSize = 32;
00046 const TInt KPnggAMAChunkSize = 4;
00047 const TInt KPngpHYsChunkSize = 9;
00048 const TInt KPngtIMEChunkSize = 7;
00049 
00050 // KPngMaxImageSize is the maximum size for width and height, as defined in the PNG Specification v1.0 page 14
00051 const TUint KPngMaxImageSize = ((TUint)2 << 30) - 1;
00052 const TInt KPngCrcTableLength = 256;
00053 const TUint KPngCrcMask = 0xffffffff;
00054 
00055 _LIT8(KPngIHDRChunkId,"IHDR");
00056 _LIT8(KPngPLTEChunkId,"PLTE");
00057 _LIT8(KPngIDATChunkId,"IDAT");
00058 _LIT8(KPngIENDChunkId,"IEND");
00059 _LIT8(KPngbKGDChunkId,"bKGD");
00060 _LIT8(KPngpHYsChunkId,"pHYs");
00061 _LIT8(KPngtRNSChunkId,"tRNS");
00062 
00063 
00064 // .
00065 // Encapsulates information about a PNG image
00066 // See PNG standard for details.
00067 // 
00068 class TPngImageInformation : public TFrameInfo
00069         {
00070 public:
00071         TPngImageInformation();
00072 public:
00073         enum TColorElements
00074                 {
00075                 EMonochrome = 0x0,
00076                 EPaletteUsed = 0x1,
00077                 EColorUsed = 0x2,
00078                 EAlphaChannelUsed = 0x4
00079                 };
00080         enum TColorType
00081                 {
00082                 EGrayscale = EMonochrome, // 0
00083                 EDirectColor = EColorUsed, // 2
00084                 EIndexedColor = EColorUsed | EPaletteUsed, // 3
00085                 EAlphaGrayscale = EMonochrome | EAlphaChannelUsed, // 4
00086                 EAlphaDirectColor = EColorUsed | EAlphaChannelUsed // 6
00087                 };
00088         enum TCompressionMethod
00089                 {
00090                 EDeflateInflate32K = 0
00091                 };
00092         enum TFilterMethod
00093                 {
00094                 EAdaptiveFiltering = 0
00095                 };
00096         enum TInterlaceMethod
00097                 {
00098                 ENoInterlace = 0,
00099                 EAdam7Interlace = 1
00100                 };
00101         enum TPhysicalUnits
00102                 {
00103                 EUnknownUnits = 0,
00104                 EMeters = 1
00105                 };
00106 public:
00107         // IHDR chunk
00108         TSize iSize; // iWidth/iHeight = 1 ... (2^31)-1
00109         TInt iBitDepth; // 1,2,4,8,16 subject to color type restrictions
00110         TColorType iColorType; // 0,2,3,4,6
00111         TCompressionMethod iCompressionMethod; // 0
00112         TFilterMethod iFilterMethod; // 0
00113         TInterlaceMethod iInterlaceMethod; // 0 or 1
00114 
00115         // PLTE chunk
00116         TBool iPalettePresent;
00117         TRgb iPalette[KPngMaxPLTESize];
00118 
00119         // bKGD chunk
00120         TBool iBackgroundPresent;
00121 
00122         // pHYs chunk
00123         TBool iPhysicalPresent;
00124         TPhysicalUnits iPhysicalUnits;
00125         TSize iPhysicalSize;
00126 
00127         // tRNS chunk
00128         TBool iTransparencyPresent;
00129         TUint16 iTransparentGray;
00130         TUint16 iTransparentRed;
00131         TUint16 iTransparentGreen;
00132         TUint16 iTransparentBlue;
00133         TUint8 iTransparencyValue[KPngMaxPLTESize];
00134         };
00135 
00136 //
00137 // Handles reading raw PNG scanlines and preparing the data
00138 // to be decompressed. A helper to CPngReadCodec.
00139 // It is abstract, and subclassed to implement readers for 
00140 // scanlines of different bitmap depths
00141 //
00142 class CPngReadSubCodec : public CBase
00143         {
00144 public:
00145         static CPngReadSubCodec* NewL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo);
00146         virtual ~CPngReadSubCodec();
00147         TDes8& FirstBuffer();
00148         TDes8& DecodeL();
00149 protected:
00150         CPngReadSubCodec();
00151         void WritePixel(TRgb aPixelColor);
00152         void WritePixel(TRgb aPixelColor,TUint8 aAlphaValue);
00153 private:
00154         void ConstructL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo);
00155         void FilterScanlineDataL(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00156         TInt PaethPredictor(TInt aLeft,TInt aAbove,TInt aAboveLeft);
00157         virtual void DoConstructL() = 0;
00158         virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0;
00159         virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit) = 0;
00160         void UpdatePos();
00161 protected:
00162         CImageProcessor* iImageProc;
00163         CImageProcessor* iMaskProc;
00164         TPngImageInformation iInfo;
00165         TInt iScanlineBufferSize;
00166         TInt iBytesPerPixel;
00167         HBufC8* iScanlineBuffer1;
00168         HBufC8* iScanlineBuffer2;
00169         TPtr8 iScanlineDes1;
00170         TPtr8 iScanlineDes2;
00171         TInt iCurrentScanlineBuffer;
00172         TInt iInterlacedScanlineBufferSize[KPngNumInterlacedPasses];
00173         TInt iPass;
00174         TPoint iPos;
00175         };
00176 
00177 class CPngDecoder;
00178 
00179 //
00180 // Codec class that does the real work of reading a PNG image.
00181 // Inherits base classes that provide image mask processing
00182 // and interface to unzip functionality
00183 //
00184 class CPngReadCodec : public CImageMaskProcessorReadCodec, public MEZBufferManager
00185         {
00186 public:
00187         // Construction
00188         ~CPngReadCodec();
00189         void ConstructL () { CImageMaskProcessorReadCodec::ConstructL(); } // make public, since we don't have NewL
00190 
00191 private:
00192         // From CImageReadCodec
00193         // Initialise frame to read
00194         void InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData, 
00195                 TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask);
00196         // Initialise from header
00197         void InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& /* aFrameImageData */);
00198         // Process header
00199         TFrameState ProcessFrameHeaderL(TBufPtr8& aData);
00200         // Process frame
00201         TFrameState ProcessFrameL(TBufPtr8& aSrc);
00202 
00203 private:
00204         // Helper functions to process PNG chunk types
00205         void DoNewFrameL(CPngDecoder* aPngDecoder);
00206         void DoProcessInfoL(const TUint8*& aDataPtr,const TUint8* aDataPtrLimit);
00207         void DoProcessIHDRL(const TUint8* aDataPtr,TInt aChunkLength);
00208         void DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength);
00209         void DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength);
00210         void DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength);
00211         void DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength);
00212         void DoProcessDataL(const TUint8*& aDataPtr,const TUint8* aDataPtrLimit);
00213 
00214         // From MEZBufferManager: feed data to unzip
00215         void InitializeL(CEZZStream &aZStream);
00216         void NeedInputL(CEZZStream &aZStream);
00217         void NeedOutputL(CEZZStream &aZStream);
00218         void FinalizeL(CEZZStream &aZStream);
00219 
00220 private:
00221         TFrameInfo* iFrameInfo;
00222         TPngImageInformation iImageInfo;
00223         TBuf8<KPngChunkIdSize> iChunkId;
00224         TInt iChunkBytesRemaining;
00225         CPngReadSubCodec* iDecoder;
00226         CEZDecompressor* iDecompressor;
00227         TPtrC8 iDataDes;
00228         };
00229 
00230 //
00231 // Handles preparing image data
00232 // for compression and writing raw scanlines 
00233 // A helper to CPngWriteCodec
00234 // 
00235 class CPngWriteSubCodec : public CBase
00236         {
00237 public:
00238         static CPngWriteSubCodec* NewL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource);
00239         virtual ~CPngWriteSubCodec();
00240 protected:
00241         CPngWriteSubCodec();
00242 private:
00243         void ConstructL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource);
00244 public:
00245         TDes8& Buffer();
00246         inline TInt BufferSize() const;
00247         TDes8& EncodeL(const TInt aScanline);
00248         inline CPalette* Palette() const;
00249 protected:
00250         TUint8 ReverseBits(const TUint8 aValue) const;
00251         void EncodePalettedScanline(TUint8* aDataPtr, const CFbsBitmap* aSource, const TInt aScanline,
00252                                                                 const TInt aPixelsPerByte, const TInt aShiftValue);
00253 private:
00254         virtual void DoConstructL();
00255         virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0;
00256         virtual void DoEncode(const CFbsBitmap* aSource, const TInt aScanline,
00257                                         TUint8* aDataPtr, const TUint8* aDataPtrLimit) = 0;
00258 protected:
00259         TPngImageInformation iInfo;
00260         const CFbsBitmap* iSource;
00261         TInt iScanlineBufferSize;
00262         HBufC8* iScanlineBuffer;
00263         TPtr8 iScanlineDes;
00264         CPalette* iPalette;
00265         };
00266 
00267 //
00268 // Codec class that does the real work of writing a PNG image.
00269 // Inherits base classes to interface to zip functionality
00270 //
00271 class CPngWriteCodec : public CImageWriteCodec, public MEZBufferManager
00272         {
00273 public:
00274         // Construction
00275         CPngWriteCodec(TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel);
00276         void ConstructL () { CImageWriteCodec::ConstructL(); } // make public, since we don't have NewL
00277         ~CPngWriteCodec();
00278 
00279 private:
00280         // from CImageWriteCodec
00281         void InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource);
00282         TFrameState ProcessFrameL(TBufPtr8& aDst);
00283 
00284 private:
00285         // Helper functions to write PNG chunks
00286         void WritePngChunk(TUint8*& aDestPtr, const TDesC8& aChunkId, const TDesC8& aData, TInt& aLength);
00287         void DeflateEncodedDataL(TBufPtr8& aDst, TFrameState& aState);
00288         void FlushCompressedDataL(TBufPtr8& aDst, TFrameState& aState);
00289         void WritePLTEChunk(TBufPtr8& aDst);
00290         void WriteIDATChunk(TBufPtr8& aDst);
00291         void WriteEndChunk(TBufPtr8& aDst);
00292         TInt WriteHeaderChunk(TBufPtr8& aDst);
00293         void GetImageDataL(TInt& aBytesToProcess);
00294         void GetPngScanLine(TDes8& aBuf, const TPoint& aPixel, TInt& aLength);
00295         void CalcCrcTable();
00296         void GetCrc(TUint32& aCrc, const TUint8* aPtr, const TInt aLength);
00297 
00298 private:
00299         // from MEZBufferManager
00300         // feeds data to zip
00301         void InitializeL(CEZZStream &aZStream);
00302         void NeedInputL(CEZZStream &aZStream);
00303         void NeedOutputL(CEZZStream &aZStream);
00304         void FinalizeL(CEZZStream &aZStream);
00305 
00306 private:
00307         enum TPngEncoderState
00308                 {
00309                 EPngDeflate,    // Deflate encoded image data
00310                 EPngFlush,              // Flush encoded image data
00311                 EPngWritePLTE,  // Write PLTE chunk
00312                 EPngWriteIDAT,  // Write IDAT chunk
00313                 EPngEndChunk    // Write end chunk
00314                 };
00315         
00316 private:
00317         TUint32 iCrcTable[KPngCrcTableLength];
00318         TBool iCrcTableCalculated;
00319         CPngWriteSubCodec* iEncoder;
00320         TPngEncoderState iEncoderState;
00321         TInt iCompressionLevel;
00322         CEZCompressor* iCompressor;
00323         TInt iScanline;
00324         TUint8* iDestStartPtr;
00325         TUint8* iDestPtr;
00326         TUint8* iDestPtrLimit;
00327         TPngImageInformation iImageInfo;
00328         TPtr8 iCompressorPtr;   // data area for compressor to write to
00329         TBool iCallAgain;
00330         };
00331 
00332 
00333 // Global panic function
00334 void Panic(TInt aError);
00335 
00336 //
00337 // inline definitions
00338 //
00339 inline TInt CPngWriteSubCodec::BufferSize() const
00340         { return iScanlineBufferSize; }
00341 
00342 inline CPalette* CPngWriteSubCodec::Palette() const
00343         { return iPalette; }
00344 
00345 
00346 #endif // __PNGCODEC_H__

Generated by  doxygen 1.6.2