examples/Multimedia/ICL/ICLCodec/PNGCodec.h

00001 /*
00002 Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description:  
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 // Constants.relating to PNG standard 
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; // 7 passes plus a safety entry
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 // KPngMaxImageSize is the maximum size for width and height, as defined in the PNG Specification v1.0 page 14
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 // Encapsulates information about a PNG image
00078 // See PNG standard for details.
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, // 0
00095                 EDirectColor = EColorUsed, // 2
00096                 EIndexedColor = EColorUsed | EPaletteUsed, // 3
00097                 EAlphaGrayscale = EMonochrome | EAlphaChannelUsed, // 4
00098                 EAlphaDirectColor = EColorUsed | EAlphaChannelUsed // 6
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         // IHDR chunk
00120         TSize iSize; // iWidth/iHeight = 1 ... (2^31)-1
00121         TInt iBitDepth; // 1,2,4,8,16 subject to color type restrictions
00122         TColorType iColorType; // 0,2,3,4,6
00123         TCompressionMethod iCompressionMethod; // 0
00124         TFilterMethod iFilterMethod; // 0
00125         TInterlaceMethod iInterlaceMethod; // 0 or 1
00126 
00127         // PLTE chunk
00128         TBool iPalettePresent;
00129         TRgb iPalette[KPngMaxPLTESize];
00130 
00131         // bKGD chunk
00132         TBool iBackgroundPresent;
00133 
00134         // pHYs chunk
00135         TBool iPhysicalPresent;
00136         TPhysicalUnits iPhysicalUnits;
00137         TSize iPhysicalSize;
00138 
00139         // tRNS chunk
00140         TBool iTransparencyPresent;
00141         TUint16 iTransparentGray;
00142         TUint16 iTransparentRed;
00143         TUint16 iTransparentGreen;
00144         TUint16 iTransparentBlue;
00145         TUint8 iTransparencyValue[KPngMaxPLTESize];
00146         };
00147 
00148 //
00149 // Handles reading raw PNG scanlines and preparing the data
00150 // to be decompressed. A helper to CPngReadCodec.
00151 // It is abstract, and subclassed to implement readers for 
00152 // scanlines of different bitmap depths
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 // Codec class that does the real work of reading a PNG image.
00193 // Inherits base classes that provide image mask processing
00194 // and interface to unzip functionality
00195 //
00196 class CPngReadCodec : public CImageMaskProcessorReadCodec, public MEZBufferManager
00197         {
00198 public:
00199         // Construction
00200         ~CPngReadCodec();
00201         void ConstructL () { CImageMaskProcessorReadCodec::ConstructL(); } // make public, since we don't have NewL
00202 
00203 private:
00204         // From CImageReadCodec
00205         // Initialise frame to read
00206         void InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData, 
00207                 TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask);
00208         // Initialise from header
00209         void InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& /* aFrameImageData */);
00210         // Process header
00211         TFrameState ProcessFrameHeaderL(TBufPtr8& aData);
00212         // Process frame
00213         TFrameState ProcessFrameL(TBufPtr8& aSrc);
00214 
00215 private:
00216         // Helper functions to process PNG chunk types
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         // From MEZBufferManager: feed data to unzip
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 // Handles preparing image data
00244 // for compression and writing raw scanlines 
00245 // A helper to CPngWriteCodec
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 // Codec class that does the real work of writing a PNG image.
00281 // Inherits base classes to interface to zip functionality
00282 //
00283 class CPngWriteCodec : public CImageWriteCodec, public MEZBufferManager
00284         {
00285 public:
00286         // Construction
00287         CPngWriteCodec(TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel);
00288         void ConstructL () { CImageWriteCodec::ConstructL(); } // make public, since we don't have NewL
00289         ~CPngWriteCodec();
00290 
00291 private:
00292         // from CImageWriteCodec
00293         void InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource);
00294         TFrameState ProcessFrameL(TBufPtr8& aDst);
00295 
00296 private:
00297         // Helper functions to write PNG chunks
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         // from MEZBufferManager
00312         // feeds data to zip
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,    // Deflate encoded image data
00322                 EPngFlush,              // Flush encoded image data
00323                 EPngWritePLTE,  // Write PLTE chunk
00324                 EPngWriteIDAT,  // Write IDAT chunk
00325                 EPngEndChunk    // Write end chunk
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;   // data area for compressor to write to
00341         TBool iCallAgain;
00342         };
00343 
00344 
00345 // Global panic function
00346 void Panic(TInt aError);
00347 
00348 //
00349 // inline definitions
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__

Generated by  doxygen 1.6.2