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__
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.