00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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;
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
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
00066
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,
00083 EDirectColor = EColorUsed,
00084 EIndexedColor = EColorUsed | EPaletteUsed,
00085 EAlphaGrayscale = EMonochrome | EAlphaChannelUsed,
00086 EAlphaDirectColor = EColorUsed | EAlphaChannelUsed
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
00108 TSize iSize;
00109 TInt iBitDepth;
00110 TColorType iColorType;
00111 TCompressionMethod iCompressionMethod;
00112 TFilterMethod iFilterMethod;
00113 TInterlaceMethod iInterlaceMethod;
00114
00115
00116 TBool iPalettePresent;
00117 TRgb iPalette[KPngMaxPLTESize];
00118
00119
00120 TBool iBackgroundPresent;
00121
00122
00123 TBool iPhysicalPresent;
00124 TPhysicalUnits iPhysicalUnits;
00125 TSize iPhysicalSize;
00126
00127
00128 TBool iTransparencyPresent;
00129 TUint16 iTransparentGray;
00130 TUint16 iTransparentRed;
00131 TUint16 iTransparentGreen;
00132 TUint16 iTransparentBlue;
00133 TUint8 iTransparencyValue[KPngMaxPLTESize];
00134 };
00135
00136
00137
00138
00139
00140
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
00181
00182
00183
00184 class CPngReadCodec : public CImageMaskProcessorReadCodec, public MEZBufferManager
00185 {
00186 public:
00187
00188 ~CPngReadCodec();
00189 void ConstructL () { CImageMaskProcessorReadCodec::ConstructL(); }
00190
00191 private:
00192
00193
00194 void InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData,
00195 TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask);
00196
00197 void InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& );
00198
00199 TFrameState ProcessFrameHeaderL(TBufPtr8& aData);
00200
00201 TFrameState ProcessFrameL(TBufPtr8& aSrc);
00202
00203 private:
00204
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
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
00232
00233
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
00269
00270
00271 class CPngWriteCodec : public CImageWriteCodec, public MEZBufferManager
00272 {
00273 public:
00274
00275 CPngWriteCodec(TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel);
00276 void ConstructL () { CImageWriteCodec::ConstructL(); }
00277 ~CPngWriteCodec();
00278
00279 private:
00280
00281 void InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource);
00282 TFrameState ProcessFrameL(TBufPtr8& aDst);
00283
00284 private:
00285
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
00300
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,
00310 EPngFlush,
00311 EPngWritePLTE,
00312 EPngWriteIDAT,
00313 EPngEndChunk
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;
00329 TBool iCallAgain;
00330 };
00331
00332
00333
00334 void Panic(TInt aError);
00335
00336
00337
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__