--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmplugins/imagingplugins/codecs/PNGCodec/PNGCodec.h Wed Sep 01 12:38:50 2010 +0100
@@ -0,0 +1,393 @@
+// Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef __PNGCODEC_H__
+#define __PNGCODEC_H__
+
+#include <bitdev.h>
+#include <ezcompressor.h>
+#include <ezdecompressor.h>
+#include <icl/imageprocessor.h>
+#include <icl/imagecodec.h>
+
+#include "PNGConvert.h"
+
+/** @file
+ @internalComponent */
+
+// Constants.
+const TInt KPngFileSignatureLength = 8;
+const TUint8 KPngSignature[KPngFileSignatureLength] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A };
+
+const TInt KPngChunkIdSize = 4;
+const TInt KPngMaxPLTESize = 256;
+const TInt KPngNumInterlacedPasses = 8; // 7 passes plus a safety entry
+
+const TInt KPngChunkLengthSize = 4;
+const TInt KPngChunkCRCSize = 4;
+
+const TInt KPngIHDRChunkSize = 13;
+const TInt KPngIENDChunkSize = 0;
+const TInt KPngcHRMChunkSize = 32;
+const TInt KPnggAMAChunkSize = 4;
+const TInt KPngpHYsChunkSize = 9;
+const TInt KPngtIMEChunkSize = 7;
+
+// KPngMaxImageSize is the maximum size for width and height, as defined in the PNG Specification v1.0 page 14
+const TUint KPngMaxImageSize = ((TUint)2 << 30) - 1;
+const TInt KPngCrcTableLength = 256;
+const TUint KPngCrcMask = 0xffffffff;
+
+_LIT8(KPngIHDRChunkId,"IHDR");
+_LIT8(KPngPLTEChunkId,"PLTE");
+_LIT8(KPngIDATChunkId,"IDAT");
+_LIT8(KPngIENDChunkId,"IEND");
+_LIT8(KPngbKGDChunkId,"bKGD");
+_LIT8(KPngpHYsChunkId,"pHYs");
+_LIT8(KPngtRNSChunkId,"tRNS");
+_LIT8(KPngZTXTChunkId,"zTXt");
+_LIT8(KPngITXTChunkId,"iTXt");
+_LIT8(KPngTEXTChunkId,"tEXt");
+
+
+// Helper classes.
+// TPngImageInformation
+class TPngImageInformation : public TFrameInfo
+ {
+public:
+ TPngImageInformation();
+public:
+ enum TColorElements
+ {
+ EMonochrome = 0x0,
+ EPaletteUsed = 0x1,
+ EColorUsed = 0x2,
+ EAlphaChannelUsed = 0x4
+ };
+ enum TColorType
+ {
+ EGrayscale = EMonochrome, // 0
+ EDirectColor = EColorUsed, // 2
+ EIndexedColor = EColorUsed | EPaletteUsed, // 3
+ EAlphaGrayscale = EMonochrome | EAlphaChannelUsed, // 4
+ EAlphaDirectColor = EColorUsed | EAlphaChannelUsed // 6
+ };
+ enum TCompressionMethod
+ {
+ EDeflateInflate32K = 0
+ };
+ enum TFilterMethod
+ {
+ EAdaptiveFiltering = 0
+ };
+ enum TInterlaceMethod
+ {
+ ENoInterlace = 0,
+ EAdam7Interlace = 1
+ };
+ enum TPhysicalUnits
+ {
+ EUnknownUnits = 0,
+ EMeters = 1
+ };
+public:
+ // IHDR chunk
+ TSize iSize; // iWidth/iHeight = 1 ... (2^31)-1
+ TInt iBitDepth; // 1,2,4,8,16 subject to color type restrictions
+ TColorType iColorType; // 0,2,3,4,6
+ TCompressionMethod iCompressionMethod; // 0
+ TFilterMethod iFilterMethod; // 0
+ TInterlaceMethod iInterlaceMethod; // 0 or 1
+
+ // PLTE chunk
+ TBool iPalettePresent;
+ TRgb iPalette[KPngMaxPLTESize];
+
+ // bKGD chunk
+ TBool iBackgroundPresent;
+// TRgb iBackgroundColor; // declared in TFrameInfo
+
+ // pHYs chunk
+ TBool iPhysicalPresent;
+ TPhysicalUnits iPhysicalUnits;
+ TSize iPhysicalSize;
+
+ // tRNS chunk
+ TBool iTransparencyPresent;
+ TUint16 iTransparentGray;
+ TUint16 iTransparentRed;
+ TUint16 iTransparentGreen;
+ TUint16 iTransparentBlue;
+ TUint8 iTransparencyValue[KPngMaxPLTESize];
+ };
+
+/**
+The Base class for different conversion types.
+It is used when Image Processor is ignored for decoding 24 (or 32) bpp non-interlaced PNG images into 24 (or 32 bpp).
+All subclasses should provide implementations of SetPixels().
+*/
+class CFastProcessor : public CBase
+ {
+public:
+ static CFastProcessor* NewL(const TPngImageInformation& aImageInfo, CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode);
+ virtual ~CFastProcessor();
+ void End();
+ virtual void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos) = 0;
+ void Begin();
+
+private:
+ void ConstructL();
+
+protected:
+ CFastProcessor(CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode);
+ CFbsBitmap* iBitmap;
+ CFbsBitmap* iMask;
+ TUint8* iBitmapBuffer;
+ TUint8* iMaskBuffer;
+ TSize iBitmapSize;
+ TPoint iPos;
+ TBool iRgbaMode;
+ };
+
+// Read codec
+
+class CPngReadSubCodec : public CBase
+ {
+public:
+ static CPngReadSubCodec* NewL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo, CFastProcessor* aFastProc, TBool aFastProcessorMode);
+ virtual ~CPngReadSubCodec();
+ TDes8& FirstBuffer();
+ TDes8& DecodeL();
+ void ResetL();
+ void SetRgbaMode(TBool aMode);
+ void Start();
+ void Complete();
+ void SetAlphaMode(TBool aMode);
+
+protected:
+ CPngReadSubCodec();
+ void WritePixel(TRgb aPixelColor);
+ void WritePixel(TRgb aPixelColor,TUint8 aAlphaValue);
+private:
+ void ConstructL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo,CFastProcessor* aFastProc, TBool aFastProcessorMode);
+ void FilterScanlineDataL(TUint8* aDataPtr,const TUint8* aDataPtrLimit);
+ TInt PaethPredictor(TInt aLeft,TInt aAbove,TInt aAboveLeft);
+ virtual void DoConstructL() = 0;
+ virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0;
+ virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit) = 0;
+ void UpdatePos();
+ TInt ClampValue(TInt aValue, TInt aMinValue, TInt aMaxValue) const;
+ void SetFastProcessorMode(TBool aMode); //Sets iFastProcessorMode to True or False
+
+protected:
+ CImageProcessor* iImageProc;
+ CImageProcessor* iMaskProc;
+ TPngImageInformation iInfo;
+ TInt iScanlineBufferSize;
+ TInt iBytesPerPixel;
+ HBufC8* iScanlineBuffer1;
+ HBufC8* iScanlineBuffer2;
+ TPtr8 iScanlineDes1;
+ TPtr8 iScanlineDes2;
+ TInt iCurrentScanlineBuffer;
+ TInt iInterlacedScanlineBufferSize[KPngNumInterlacedPasses];
+ TInt iPass;
+ TPoint iPos;
+ TBool iRgbaMode;
+ TRgb* iLineCache;
+ TBool iFastProcessorMode; //Sets the current mode
+ CFastProcessor* iFastProc;
+ TBool iAlphaMode; // Are we decoding to a bitmap that contains an alpha channel?
+ };
+
+
+class MPngDecoder;
+class CPngReadCodec : public CImageMaskProcessorReadCodec, public MEZBufferManager
+ {
+public:
+ ~CPngReadCodec();
+
+ static CPngReadCodec* NewL(MPngDecoder& aDecoderIFace);
+ void SetImageProcessor(CImageProcessor* aImageProc, TBool aOwnsProcessor=ETrue);
+ void SetMaskProcessor(CImageProcessor* aMaskProc, TBool aOwnsProcessor=ETrue);
+ void SetFastProcessor(CFastProcessor* aFastProc, TBool aOwnsProcessor=ETrue);
+
+ CImageProcessor* MaskProcessor() const;
+ CImageProcessor* ImageProcessor() const;
+ CFastProcessor* FastProcessor() const;
+
+ // From CImageReadCodec
+ virtual void InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData, TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask);
+ virtual void InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& /* aFrameImageData */);
+ TFrameState ProcessFrameHeaderL(TBufPtr8& aData);
+ TFrameState ProcessFrameL(TBufPtr8& aSrc);
+ TBool DoProcessDataL();
+ void GetNewDataPosition(TInt& aPosition, TInt& /*aLength*/ );
+ TBool SkipImageProcessor(CFbsBitmap& aDestination); //Checks if Image processor is to be used or skipped. If returns ETrue then skip ImageProcessor
+ void Complete();
+ void SetMissingiENDChunkFail(TBool aValue);
+
+protected:
+ CPngReadCodec(MPngDecoder& aDecoderIFace);
+ void ConstructL();
+
+protected:
+ virtual void DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength);
+ virtual void DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength);
+ virtual void DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength);
+ virtual void DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength);
+
+private:
+ void DoProcessInfoL(const TUint8*& aDataPtr,const TUint8* aDataPtrLimit);
+ void DoProcessIHDRL(const TUint8* aDataPtr,TInt aChunkLength);
+
+ TBool SetupProcessData(TBufPtr8& aSrc,
+ TUint8* aStartDataPtr,
+ const TUint8*& aDataPtr,
+ const TUint8* aDataPtrLimit);
+
+ // From MEZBufferManager
+ virtual void InitializeL(CEZZStream &aZStream);
+ virtual void NeedInputL(CEZZStream &aZStream);
+ virtual void NeedOutputL(CEZZStream &aZStream);
+ virtual void FinalizeL(CEZZStream &aZStream);
+protected:
+ MPngDecoder& iDecoderIFace;
+ TFrameInfo* iFrameInfo;
+ TPngImageInformation iImageInfo;
+ TBuf8<KPngChunkIdSize> iChunkId;
+ TInt iChunkBytesRemaining;
+ CPngReadSubCodec* iDecoder;
+ CEZDecompressor* iDecompressor;
+ TPtrC8 iDataDes;
+ // used for async decode...
+ const TUint8* iDataPtr;
+ TBufPtr8* iSavedSrc;
+ TUint8* iStartDataPtr;
+ CImageProcessor* iImageProc;
+ TBool iOwnsImageProcessor;
+ CImageProcessor* iMaskProc;
+ TBool iOwnsMaskProcessor;
+ CFastProcessor* iFastProc;
+ TBool iOwnsFastProcessor;
+private:
+ TInt iNewPosition;
+ TBool iReadMore;
+ TBool iPreviousChunkReadFailed;
+ TBool iMissingiENDChunkFail;
+ TInt iPreviousDataPos;
+ TInt iPreviousDataLength;
+ };
+
+// Write sub-codec
+class CPngWriteSubCodec : public CBase
+ {
+public:
+ static CPngWriteSubCodec* NewL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource);
+ virtual ~CPngWriteSubCodec();
+protected:
+ CPngWriteSubCodec();
+private:
+ void ConstructL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource);
+public:
+ TDes8& Buffer();
+ inline TInt BufferSize() const;
+ TDes8& EncodeL(const TInt aScanline);
+ inline CPalette* Palette() const;
+protected:
+ TUint8 ReverseBits(const TUint8 aValue) const;
+ void EncodePalettedScanline(TUint8* aDataPtr, const CFbsBitmap* aSource, const TInt aScanline,
+ const TInt aPixelsPerByte, const TInt aShiftValue);
+private:
+ virtual void DoConstructL();
+ virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0;
+ virtual void DoEncode(const CFbsBitmap* aSource, const TInt aScanline,
+ TUint8* aDataPtr, const TUint8* aDataPtrLimit) = 0;
+protected:
+ TPngImageInformation iInfo;
+ const CFbsBitmap* iSource;
+ TInt iScanlineBufferSize;
+ HBufC8* iScanlineBuffer;
+ TPtr8 iScanlineDes;
+ CPalette* iPalette;
+
+ friend class RPngWriteSubCodecTest;
+ };
+
+// Write codec
+class CPngWriteCodec : public CImageWriteCodec, public MEZBufferManager
+ {
+private:
+ enum TPngEncoderState
+ {
+ EPngInit, // Initialize compressor
+ EPngDeflate, // Deflate encoded image data
+ EPngWritePLTE, // Write PLTE chunk
+ EPngWriteIDAT, // Write IDAT chunk
+ EPngEndChunk // Write end chunk
+ };
+public:
+ static CPngWriteCodec* NewL(CPngEncoder& aPlugin, TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel);
+
+ virtual ~CPngWriteCodec();
+public:
+ void GetCrc(TUint32& aCrc, const TUint8* aPtr, const TInt aLength);
+ TBool DeflateEncodedDataL();
+private:
+ CPngWriteCodec(CPngEncoder& aPlugin, TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel);
+
+ void WritePngChunk(TUint8*& aDestPtr, const TDesC8& aChunkId, const TDesC8& aData, TInt& aLength);
+ void InitializeCompressorL(TBufPtr8& aDst);
+ void SetCompressorOutputL(TBufPtr8& aDst);
+ void WritePLTEChunk(TBufPtr8& aDst);
+ void WriteIDATChunk(TBufPtr8& aDst);
+ void WriteEndChunk(TBufPtr8& aDst);
+ TInt WriteHeaderChunk(TBufPtr8& aDst);
+ void GetImageDataL(TInt& aBytesToProcess);
+ void GetPngScanLine(TDes8& aBuf, const TPoint& aPixel, TInt& aLength);
+ void CalcCrcTable();
+ // from CImageWriteCodec
+public:
+ virtual void InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource);
+ virtual TFrameState ProcessFrameL(TBufPtr8& aDst);
+ // from MEZBufferManager
+private:
+ virtual void InitializeL(CEZZStream &aZStream);
+ virtual void NeedInputL(CEZZStream &aZStream);
+ virtual void NeedOutputL(CEZZStream &aZStream);
+ virtual void FinalizeL(CEZZStream &aZStream);
+private:
+ TUint32 iCrcTable[KPngCrcTableLength];
+ TBool iCrcTableCalculated;
+ CPngWriteSubCodec* iEncoder;
+ TPngEncoderState iEncoderState;
+ TInt iCompressionLevel;
+ CEZCompressor* iCompressor;
+ TInt iScanline;
+ TUint8* iDestStartPtr;
+ TUint8* iDestPtr;
+ TUint8* iDestPtrLimit;
+ TPngImageInformation iImageInfo;
+ TPtr8 iCompressorPtr; // data area for compressor to write to
+ TBool iCallAgain;
+ CPngEncoder& iPlugin;
+
+ friend class RPngWriteCodecTest;
+ };
+
+
+#include "PngCodec.inl"
+
+#endif // __PNGCODEC_H__