00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef __PNGCODEC_H__
00032 #define __PNGCODEC_H__
00033
00034 #include <bitdev.h>
00035 #include <ezcompressor.h>
00036 #include <ezdecompressor.h>
00037 #include <icl/imageprocessor.h>
00038 #include <icl/imagecodec.h>
00039
00040 #include "PNGConvert.h"
00041
00042
00043
00044
00045 const TInt KPngFileSignatureLength = 8;
00046 const TUint8 KPngSignature[KPngFileSignatureLength] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
00047
00048 const TInt KPngChunkIdSize = 4;
00049 const TInt KPngMaxPLTESize = 256;
00050 const TInt KPngNumInterlacedPasses = 8;
00051
00052 const TInt KPngChunkLengthSize = 4;
00053 const TInt KPngChunkCRCSize = 4;
00054
00055 const TInt KPngIHDRChunkSize = 13;
00056 const TInt KPngIENDChunkSize = 0;
00057 const TInt KPngcHRMChunkSize = 32;
00058 const TInt KPnggAMAChunkSize = 4;
00059 const TInt KPngpHYsChunkSize = 9;
00060 const TInt KPngtIMEChunkSize = 7;
00061
00062
00063 const TUint KPngMaxImageSize = ((TUint)2 << 30) - 1;
00064 const TInt KPngCrcTableLength = 256;
00065 const TUint KPngCrcMask = 0xffffffff;
00066
00067 _LIT8(KPngIHDRChunkId,"IHDR");
00068 _LIT8(KPngPLTEChunkId,"PLTE");
00069 _LIT8(KPngIDATChunkId,"IDAT");
00070 _LIT8(KPngIENDChunkId,"IEND");
00071 _LIT8(KPngbKGDChunkId,"bKGD");
00072 _LIT8(KPngpHYsChunkId,"pHYs");
00073 _LIT8(KPngtRNSChunkId,"tRNS");
00074
00075
00076
00077
00078
00079
00080 class TPngImageInformation : public TFrameInfo
00081 {
00082 public:
00083 TPngImageInformation();
00084 public:
00085 enum TColorElements
00086 {
00087 EMonochrome = 0x0,
00088 EPaletteUsed = 0x1,
00089 EColorUsed = 0x2,
00090 EAlphaChannelUsed = 0x4
00091 };
00092 enum TColorType
00093 {
00094 EGrayscale = EMonochrome,
00095 EDirectColor = EColorUsed,
00096 EIndexedColor = EColorUsed | EPaletteUsed,
00097 EAlphaGrayscale = EMonochrome | EAlphaChannelUsed,
00098 EAlphaDirectColor = EColorUsed | EAlphaChannelUsed
00099 };
00100 enum TCompressionMethod
00101 {
00102 EDeflateInflate32K = 0
00103 };
00104 enum TFilterMethod
00105 {
00106 EAdaptiveFiltering = 0
00107 };
00108 enum TInterlaceMethod
00109 {
00110 ENoInterlace = 0,
00111 EAdam7Interlace = 1
00112 };
00113 enum TPhysicalUnits
00114 {
00115 EUnknownUnits = 0,
00116 EMeters = 1
00117 };
00118 public:
00119
00120 TSize iSize;
00121 TInt iBitDepth;
00122 TColorType iColorType;
00123 TCompressionMethod iCompressionMethod;
00124 TFilterMethod iFilterMethod;
00125 TInterlaceMethod iInterlaceMethod;
00126
00127
00128 TBool iPalettePresent;
00129 TRgb iPalette[KPngMaxPLTESize];
00130
00131
00132 TBool iBackgroundPresent;
00133
00134
00135 TBool iPhysicalPresent;
00136 TPhysicalUnits iPhysicalUnits;
00137 TSize iPhysicalSize;
00138
00139
00140 TBool iTransparencyPresent;
00141 TUint16 iTransparentGray;
00142 TUint16 iTransparentRed;
00143 TUint16 iTransparentGreen;
00144 TUint16 iTransparentBlue;
00145 TUint8 iTransparencyValue[KPngMaxPLTESize];
00146 };
00147
00148
00149
00150
00151
00152
00153
00154 class CPngReadSubCodec : public CBase
00155 {
00156 public:
00157 static CPngReadSubCodec* NewL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo);
00158 virtual ~CPngReadSubCodec();
00159 TDes8& FirstBuffer();
00160 TDes8& DecodeL();
00161 protected:
00162 CPngReadSubCodec();
00163 void WritePixel(TRgb aPixelColor);
00164 void WritePixel(TRgb aPixelColor,TUint8 aAlphaValue);
00165 private:
00166 void ConstructL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo);
00167 void FilterScanlineDataL(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
00168 TInt PaethPredictor(TInt aLeft,TInt aAbove,TInt aAboveLeft);
00169 virtual void DoConstructL() = 0;
00170 virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0;
00171 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit) = 0;
00172 void UpdatePos();
00173 protected:
00174 CImageProcessor* iImageProc;
00175 CImageProcessor* iMaskProc;
00176 TPngImageInformation iInfo;
00177 TInt iScanlineBufferSize;
00178 TInt iBytesPerPixel;
00179 HBufC8* iScanlineBuffer1;
00180 HBufC8* iScanlineBuffer2;
00181 TPtr8 iScanlineDes1;
00182 TPtr8 iScanlineDes2;
00183 TInt iCurrentScanlineBuffer;
00184 TInt iInterlacedScanlineBufferSize[KPngNumInterlacedPasses];
00185 TInt iPass;
00186 TPoint iPos;
00187 };
00188
00189 class CPngDecoder;
00190
00191
00192
00193
00194
00195
00196 class CPngReadCodec : public CImageMaskProcessorReadCodec, public MEZBufferManager
00197 {
00198 public:
00199
00200 ~CPngReadCodec();
00201 void ConstructL () { CImageMaskProcessorReadCodec::ConstructL(); }
00202
00203 private:
00204
00205
00206 void InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData,
00207 TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask);
00208
00209 void InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& );
00210
00211 TFrameState ProcessFrameHeaderL(TBufPtr8& aData);
00212
00213 TFrameState ProcessFrameL(TBufPtr8& aSrc);
00214
00215 private:
00216
00217 void DoNewFrameL(CPngDecoder* aPngDecoder);
00218 void DoProcessInfoL(const TUint8*& aDataPtr,const TUint8* aDataPtrLimit);
00219 void DoProcessIHDRL(const TUint8* aDataPtr,TInt aChunkLength);
00220 void DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength);
00221 void DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength);
00222 void DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength);
00223 void DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength);
00224 void DoProcessDataL(const TUint8*& aDataPtr,const TUint8* aDataPtrLimit);
00225
00226
00227 void InitializeL(CEZZStream &aZStream);
00228 void NeedInputL(CEZZStream &aZStream);
00229 void NeedOutputL(CEZZStream &aZStream);
00230 void FinalizeL(CEZZStream &aZStream);
00231
00232 private:
00233 TFrameInfo* iFrameInfo;
00234 TPngImageInformation iImageInfo;
00235 TBuf8<KPngChunkIdSize> iChunkId;
00236 TInt iChunkBytesRemaining;
00237 CPngReadSubCodec* iDecoder;
00238 CEZDecompressor* iDecompressor;
00239 TPtrC8 iDataDes;
00240 };
00241
00242
00243
00244
00245
00246
00247 class CPngWriteSubCodec : public CBase
00248 {
00249 public:
00250 static CPngWriteSubCodec* NewL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource);
00251 virtual ~CPngWriteSubCodec();
00252 protected:
00253 CPngWriteSubCodec();
00254 private:
00255 void ConstructL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource);
00256 public:
00257 TDes8& Buffer();
00258 inline TInt BufferSize() const;
00259 TDes8& EncodeL(const TInt aScanline);
00260 inline CPalette* Palette() const;
00261 protected:
00262 TUint8 ReverseBits(const TUint8 aValue) const;
00263 void EncodePalettedScanline(TUint8* aDataPtr, const CFbsBitmap* aSource, const TInt aScanline,
00264 const TInt aPixelsPerByte, const TInt aShiftValue);
00265 private:
00266 virtual void DoConstructL();
00267 virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0;
00268 virtual void DoEncode(const CFbsBitmap* aSource, const TInt aScanline,
00269 TUint8* aDataPtr, const TUint8* aDataPtrLimit) = 0;
00270 protected:
00271 TPngImageInformation iInfo;
00272 const CFbsBitmap* iSource;
00273 TInt iScanlineBufferSize;
00274 HBufC8* iScanlineBuffer;
00275 TPtr8 iScanlineDes;
00276 CPalette* iPalette;
00277 };
00278
00279
00280
00281
00282
00283 class CPngWriteCodec : public CImageWriteCodec, public MEZBufferManager
00284 {
00285 public:
00286
00287 CPngWriteCodec(TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel);
00288 void ConstructL () { CImageWriteCodec::ConstructL(); }
00289 ~CPngWriteCodec();
00290
00291 private:
00292
00293 void InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource);
00294 TFrameState ProcessFrameL(TBufPtr8& aDst);
00295
00296 private:
00297
00298 void WritePngChunk(TUint8*& aDestPtr, const TDesC8& aChunkId, const TDesC8& aData, TInt& aLength);
00299 void DeflateEncodedDataL(TBufPtr8& aDst, TFrameState& aState);
00300 void FlushCompressedDataL(TBufPtr8& aDst, TFrameState& aState);
00301 void WritePLTEChunk(TBufPtr8& aDst);
00302 void WriteIDATChunk(TBufPtr8& aDst);
00303 void WriteEndChunk(TBufPtr8& aDst);
00304 TInt WriteHeaderChunk(TBufPtr8& aDst);
00305 void GetImageDataL(TInt& aBytesToProcess);
00306 void GetPngScanLine(TDes8& aBuf, const TPoint& aPixel, TInt& aLength);
00307 void CalcCrcTable();
00308 void GetCrc(TUint32& aCrc, const TUint8* aPtr, const TInt aLength);
00309
00310 private:
00311
00312
00313 void InitializeL(CEZZStream &aZStream);
00314 void NeedInputL(CEZZStream &aZStream);
00315 void NeedOutputL(CEZZStream &aZStream);
00316 void FinalizeL(CEZZStream &aZStream);
00317
00318 private:
00319 enum TPngEncoderState
00320 {
00321 EPngDeflate,
00322 EPngFlush,
00323 EPngWritePLTE,
00324 EPngWriteIDAT,
00325 EPngEndChunk
00326 };
00327
00328 private:
00329 TUint32 iCrcTable[KPngCrcTableLength];
00330 TBool iCrcTableCalculated;
00331 CPngWriteSubCodec* iEncoder;
00332 TPngEncoderState iEncoderState;
00333 TInt iCompressionLevel;
00334 CEZCompressor* iCompressor;
00335 TInt iScanline;
00336 TUint8* iDestStartPtr;
00337 TUint8* iDestPtr;
00338 TUint8* iDestPtrLimit;
00339 TPngImageInformation iImageInfo;
00340 TPtr8 iCompressorPtr;
00341 TBool iCallAgain;
00342 };
00343
00344
00345
00346 void Panic(TInt aError);
00347
00348
00349
00350
00351 inline TInt CPngWriteSubCodec::BufferSize() const
00352 { return iScanlineBufferSize; }
00353
00354 inline CPalette* CPngWriteSubCodec::Palette() const
00355 { return iPalette; }
00356
00357
00358 #endif // __PNGCODEC_H__