|
1 // Copyright (c) 1999-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #ifndef __PNGCODEC_H__ |
|
17 #define __PNGCODEC_H__ |
|
18 |
|
19 #include <bitdev.h> |
|
20 #include <ezcompressor.h> |
|
21 #include <ezdecompressor.h> |
|
22 #include <icl/imageprocessor.h> |
|
23 #include <icl/imagecodec.h> |
|
24 |
|
25 #include "PNGConvert.h" |
|
26 |
|
27 /** @file |
|
28 @internalComponent */ |
|
29 |
|
30 // Constants. |
|
31 const TInt KPngFileSignatureLength = 8; |
|
32 const TUint8 KPngSignature[KPngFileSignatureLength] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; |
|
33 |
|
34 const TInt KPngChunkIdSize = 4; |
|
35 const TInt KPngMaxPLTESize = 256; |
|
36 const TInt KPngNumInterlacedPasses = 8; // 7 passes plus a safety entry |
|
37 |
|
38 const TInt KPngChunkLengthSize = 4; |
|
39 const TInt KPngChunkCRCSize = 4; |
|
40 |
|
41 const TInt KPngIHDRChunkSize = 13; |
|
42 const TInt KPngIENDChunkSize = 0; |
|
43 const TInt KPngcHRMChunkSize = 32; |
|
44 const TInt KPnggAMAChunkSize = 4; |
|
45 const TInt KPngpHYsChunkSize = 9; |
|
46 const TInt KPngtIMEChunkSize = 7; |
|
47 |
|
48 // KPngMaxImageSize is the maximum size for width and height, as defined in the PNG Specification v1.0 page 14 |
|
49 const TUint KPngMaxImageSize = ((TUint)2 << 30) - 1; |
|
50 const TInt KPngCrcTableLength = 256; |
|
51 const TUint KPngCrcMask = 0xffffffff; |
|
52 |
|
53 _LIT8(KPngIHDRChunkId,"IHDR"); |
|
54 _LIT8(KPngPLTEChunkId,"PLTE"); |
|
55 _LIT8(KPngIDATChunkId,"IDAT"); |
|
56 _LIT8(KPngIENDChunkId,"IEND"); |
|
57 _LIT8(KPngbKGDChunkId,"bKGD"); |
|
58 _LIT8(KPngpHYsChunkId,"pHYs"); |
|
59 _LIT8(KPngtRNSChunkId,"tRNS"); |
|
60 _LIT8(KPngZTXTChunkId,"zTXt"); |
|
61 _LIT8(KPngITXTChunkId,"iTXt"); |
|
62 _LIT8(KPngTEXTChunkId,"tEXt"); |
|
63 |
|
64 |
|
65 // Helper classes. |
|
66 // TPngImageInformation |
|
67 class TPngImageInformation : public TFrameInfo |
|
68 { |
|
69 public: |
|
70 TPngImageInformation(); |
|
71 public: |
|
72 enum TColorElements |
|
73 { |
|
74 EMonochrome = 0x0, |
|
75 EPaletteUsed = 0x1, |
|
76 EColorUsed = 0x2, |
|
77 EAlphaChannelUsed = 0x4 |
|
78 }; |
|
79 enum TColorType |
|
80 { |
|
81 EGrayscale = EMonochrome, // 0 |
|
82 EDirectColor = EColorUsed, // 2 |
|
83 EIndexedColor = EColorUsed | EPaletteUsed, // 3 |
|
84 EAlphaGrayscale = EMonochrome | EAlphaChannelUsed, // 4 |
|
85 EAlphaDirectColor = EColorUsed | EAlphaChannelUsed // 6 |
|
86 }; |
|
87 enum TCompressionMethod |
|
88 { |
|
89 EDeflateInflate32K = 0 |
|
90 }; |
|
91 enum TFilterMethod |
|
92 { |
|
93 EAdaptiveFiltering = 0 |
|
94 }; |
|
95 enum TInterlaceMethod |
|
96 { |
|
97 ENoInterlace = 0, |
|
98 EAdam7Interlace = 1 |
|
99 }; |
|
100 enum TPhysicalUnits |
|
101 { |
|
102 EUnknownUnits = 0, |
|
103 EMeters = 1 |
|
104 }; |
|
105 public: |
|
106 // IHDR chunk |
|
107 TSize iSize; // iWidth/iHeight = 1 ... (2^31)-1 |
|
108 TInt iBitDepth; // 1,2,4,8,16 subject to color type restrictions |
|
109 TColorType iColorType; // 0,2,3,4,6 |
|
110 TCompressionMethod iCompressionMethod; // 0 |
|
111 TFilterMethod iFilterMethod; // 0 |
|
112 TInterlaceMethod iInterlaceMethod; // 0 or 1 |
|
113 |
|
114 // PLTE chunk |
|
115 TBool iPalettePresent; |
|
116 TRgb iPalette[KPngMaxPLTESize]; |
|
117 |
|
118 // bKGD chunk |
|
119 TBool iBackgroundPresent; |
|
120 // TRgb iBackgroundColor; // declared in TFrameInfo |
|
121 |
|
122 // pHYs chunk |
|
123 TBool iPhysicalPresent; |
|
124 TPhysicalUnits iPhysicalUnits; |
|
125 TSize iPhysicalSize; |
|
126 |
|
127 // tRNS chunk |
|
128 TBool iTransparencyPresent; |
|
129 TUint16 iTransparentGray; |
|
130 TUint16 iTransparentRed; |
|
131 TUint16 iTransparentGreen; |
|
132 TUint16 iTransparentBlue; |
|
133 TUint8 iTransparencyValue[KPngMaxPLTESize]; |
|
134 }; |
|
135 |
|
136 /** |
|
137 The Base class for different conversion types. |
|
138 It is used when Image Processor is ignored for decoding 24 (or 32) bpp non-interlaced PNG images into 24 (or 32 bpp). |
|
139 All subclasses should provide implementations of SetPixels(). |
|
140 */ |
|
141 class CFastProcessor : public CBase |
|
142 { |
|
143 public: |
|
144 static CFastProcessor* NewL(const TPngImageInformation& aImageInfo, CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode); |
|
145 virtual ~CFastProcessor(); |
|
146 void End(); |
|
147 virtual void SetPixels(const TUint8* aDataPtr, const TUint8* aDataPtrLimit, TRgb* aLineCache, TPoint& aPos) = 0; |
|
148 void Begin(); |
|
149 |
|
150 private: |
|
151 void ConstructL(); |
|
152 |
|
153 protected: |
|
154 CFastProcessor(CFbsBitmap* aDestination, CFbsBitmap* aMask, TBool aRgbaMode); |
|
155 CFbsBitmap* iBitmap; |
|
156 CFbsBitmap* iMask; |
|
157 TUint8* iBitmapBuffer; |
|
158 TUint8* iMaskBuffer; |
|
159 TSize iBitmapSize; |
|
160 TPoint iPos; |
|
161 TBool iRgbaMode; |
|
162 }; |
|
163 |
|
164 // Read codec |
|
165 |
|
166 class CPngReadSubCodec : public CBase |
|
167 { |
|
168 public: |
|
169 static CPngReadSubCodec* NewL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo, CFastProcessor* aFastProc, TBool aFastProcessorMode); |
|
170 virtual ~CPngReadSubCodec(); |
|
171 TDes8& FirstBuffer(); |
|
172 TDes8& DecodeL(); |
|
173 void ResetL(); |
|
174 void SetRgbaMode(TBool aMode); |
|
175 void Start(); |
|
176 void Complete(); |
|
177 void SetAlphaMode(TBool aMode); |
|
178 |
|
179 protected: |
|
180 CPngReadSubCodec(); |
|
181 void WritePixel(TRgb aPixelColor); |
|
182 void WritePixel(TRgb aPixelColor,TUint8 aAlphaValue); |
|
183 private: |
|
184 void ConstructL(CImageProcessor* aImageProc,CImageProcessor* aMaskProc,const TPngImageInformation& aInfo,CFastProcessor* aFastProc, TBool aFastProcessorMode); |
|
185 void FilterScanlineDataL(TUint8* aDataPtr,const TUint8* aDataPtrLimit); |
|
186 TInt PaethPredictor(TInt aLeft,TInt aAbove,TInt aAboveLeft); |
|
187 virtual void DoConstructL() = 0; |
|
188 virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0; |
|
189 virtual void DoDecode(TUint8* aDataPtr,const TUint8* aDataPtrLimit) = 0; |
|
190 void UpdatePos(); |
|
191 TInt ClampValue(TInt aValue, TInt aMinValue, TInt aMaxValue) const; |
|
192 void SetFastProcessorMode(TBool aMode); //Sets iFastProcessorMode to True or False |
|
193 |
|
194 protected: |
|
195 CImageProcessor* iImageProc; |
|
196 CImageProcessor* iMaskProc; |
|
197 TPngImageInformation iInfo; |
|
198 TInt iScanlineBufferSize; |
|
199 TInt iBytesPerPixel; |
|
200 HBufC8* iScanlineBuffer1; |
|
201 HBufC8* iScanlineBuffer2; |
|
202 TPtr8 iScanlineDes1; |
|
203 TPtr8 iScanlineDes2; |
|
204 TInt iCurrentScanlineBuffer; |
|
205 TInt iInterlacedScanlineBufferSize[KPngNumInterlacedPasses]; |
|
206 TInt iPass; |
|
207 TPoint iPos; |
|
208 TBool iRgbaMode; |
|
209 TRgb* iLineCache; |
|
210 TBool iFastProcessorMode; //Sets the current mode |
|
211 CFastProcessor* iFastProc; |
|
212 TBool iAlphaMode; // Are we decoding to a bitmap that contains an alpha channel? |
|
213 }; |
|
214 |
|
215 |
|
216 class MPngDecoder; |
|
217 class CPngReadCodec : public CImageMaskProcessorReadCodec, public MEZBufferManager |
|
218 { |
|
219 public: |
|
220 ~CPngReadCodec(); |
|
221 |
|
222 static CPngReadCodec* NewL(MPngDecoder& aDecoderIFace); |
|
223 void SetImageProcessor(CImageProcessor* aImageProc, TBool aOwnsProcessor=ETrue); |
|
224 void SetMaskProcessor(CImageProcessor* aMaskProc, TBool aOwnsProcessor=ETrue); |
|
225 void SetFastProcessor(CFastProcessor* aFastProc, TBool aOwnsProcessor=ETrue); |
|
226 |
|
227 CImageProcessor* MaskProcessor() const; |
|
228 CImageProcessor* ImageProcessor() const; |
|
229 CFastProcessor* FastProcessor() const; |
|
230 |
|
231 // From CImageReadCodec |
|
232 virtual void InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& aFrameImageData, TBool aDisableErrorDiffusion, CFbsBitmap& aDestination, CFbsBitmap* aDestinationMask); |
|
233 virtual void InitFrameHeader(TFrameInfo& aFrameSettings, CFrameImageData& /* aFrameImageData */); |
|
234 TFrameState ProcessFrameHeaderL(TBufPtr8& aData); |
|
235 TFrameState ProcessFrameL(TBufPtr8& aSrc); |
|
236 TBool DoProcessDataL(); |
|
237 void GetNewDataPosition(TInt& aPosition, TInt& /*aLength*/ ); |
|
238 TBool SkipImageProcessor(CFbsBitmap& aDestination); //Checks if Image processor is to be used or skipped. If returns ETrue then skip ImageProcessor |
|
239 void Complete(); |
|
240 void SetMissingiENDChunkFail(TBool aValue); |
|
241 |
|
242 protected: |
|
243 CPngReadCodec(MPngDecoder& aDecoderIFace); |
|
244 void ConstructL(); |
|
245 |
|
246 protected: |
|
247 virtual void DoProcessPLTEL(const TUint8* aDataPtr,TInt aChunkLength); |
|
248 virtual void DoProcesstRNSL(const TUint8* aDataPtr,TInt aChunkLength); |
|
249 virtual void DoProcessbKGDL(const TUint8* aDataPtr,TInt aChunkLength); |
|
250 virtual void DoProcesspHYsL(const TUint8* aDataPtr,TInt aChunkLength); |
|
251 |
|
252 private: |
|
253 void DoProcessInfoL(const TUint8*& aDataPtr,const TUint8* aDataPtrLimit); |
|
254 void DoProcessIHDRL(const TUint8* aDataPtr,TInt aChunkLength); |
|
255 |
|
256 TBool SetupProcessData(TBufPtr8& aSrc, |
|
257 TUint8* aStartDataPtr, |
|
258 const TUint8*& aDataPtr, |
|
259 const TUint8* aDataPtrLimit); |
|
260 |
|
261 // From MEZBufferManager |
|
262 virtual void InitializeL(CEZZStream &aZStream); |
|
263 virtual void NeedInputL(CEZZStream &aZStream); |
|
264 virtual void NeedOutputL(CEZZStream &aZStream); |
|
265 virtual void FinalizeL(CEZZStream &aZStream); |
|
266 protected: |
|
267 MPngDecoder& iDecoderIFace; |
|
268 TFrameInfo* iFrameInfo; |
|
269 TPngImageInformation iImageInfo; |
|
270 TBuf8<KPngChunkIdSize> iChunkId; |
|
271 TInt iChunkBytesRemaining; |
|
272 CPngReadSubCodec* iDecoder; |
|
273 CEZDecompressor* iDecompressor; |
|
274 TPtrC8 iDataDes; |
|
275 // used for async decode... |
|
276 const TUint8* iDataPtr; |
|
277 TBufPtr8* iSavedSrc; |
|
278 TUint8* iStartDataPtr; |
|
279 CImageProcessor* iImageProc; |
|
280 TBool iOwnsImageProcessor; |
|
281 CImageProcessor* iMaskProc; |
|
282 TBool iOwnsMaskProcessor; |
|
283 CFastProcessor* iFastProc; |
|
284 TBool iOwnsFastProcessor; |
|
285 private: |
|
286 TInt iNewPosition; |
|
287 TBool iReadMore; |
|
288 TBool iPreviousChunkReadFailed; |
|
289 TBool iMissingiENDChunkFail; |
|
290 TInt iPreviousDataPos; |
|
291 TInt iPreviousDataLength; |
|
292 }; |
|
293 |
|
294 // Write sub-codec |
|
295 class CPngWriteSubCodec : public CBase |
|
296 { |
|
297 public: |
|
298 static CPngWriteSubCodec* NewL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource); |
|
299 virtual ~CPngWriteSubCodec(); |
|
300 protected: |
|
301 CPngWriteSubCodec(); |
|
302 private: |
|
303 void ConstructL(const TPngImageInformation& aInfo, const CFbsBitmap* aSource); |
|
304 public: |
|
305 TDes8& Buffer(); |
|
306 inline TInt BufferSize() const; |
|
307 TDes8& EncodeL(const TInt aScanline); |
|
308 inline CPalette* Palette() const; |
|
309 protected: |
|
310 TUint8 ReverseBits(const TUint8 aValue) const; |
|
311 void EncodePalettedScanline(TUint8* aDataPtr, const CFbsBitmap* aSource, const TInt aScanline, |
|
312 const TInt aPixelsPerByte, const TInt aShiftValue); |
|
313 private: |
|
314 virtual void DoConstructL(); |
|
315 virtual TInt ScanlineBufferSize(TInt aPixelLength) = 0; |
|
316 virtual void DoEncode(const CFbsBitmap* aSource, const TInt aScanline, |
|
317 TUint8* aDataPtr, const TUint8* aDataPtrLimit) = 0; |
|
318 protected: |
|
319 TPngImageInformation iInfo; |
|
320 const CFbsBitmap* iSource; |
|
321 TInt iScanlineBufferSize; |
|
322 HBufC8* iScanlineBuffer; |
|
323 TPtr8 iScanlineDes; |
|
324 CPalette* iPalette; |
|
325 |
|
326 friend class RPngWriteSubCodecTest; |
|
327 }; |
|
328 |
|
329 // Write codec |
|
330 class CPngWriteCodec : public CImageWriteCodec, public MEZBufferManager |
|
331 { |
|
332 private: |
|
333 enum TPngEncoderState |
|
334 { |
|
335 EPngInit, // Initialize compressor |
|
336 EPngDeflate, // Deflate encoded image data |
|
337 EPngWritePLTE, // Write PLTE chunk |
|
338 EPngWriteIDAT, // Write IDAT chunk |
|
339 EPngEndChunk // Write end chunk |
|
340 }; |
|
341 public: |
|
342 static CPngWriteCodec* NewL(CPngEncoder& aPlugin, TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel); |
|
343 |
|
344 virtual ~CPngWriteCodec(); |
|
345 public: |
|
346 void GetCrc(TUint32& aCrc, const TUint8* aPtr, const TInt aLength); |
|
347 TBool DeflateEncodedDataL(); |
|
348 private: |
|
349 CPngWriteCodec(CPngEncoder& aPlugin, TInt aBpp, TBool aColor, TBool aPaletted, TInt aCompressionLevel); |
|
350 |
|
351 void WritePngChunk(TUint8*& aDestPtr, const TDesC8& aChunkId, const TDesC8& aData, TInt& aLength); |
|
352 void InitializeCompressorL(TBufPtr8& aDst); |
|
353 void SetCompressorOutputL(TBufPtr8& aDst); |
|
354 void WritePLTEChunk(TBufPtr8& aDst); |
|
355 void WriteIDATChunk(TBufPtr8& aDst); |
|
356 void WriteEndChunk(TBufPtr8& aDst); |
|
357 TInt WriteHeaderChunk(TBufPtr8& aDst); |
|
358 void GetImageDataL(TInt& aBytesToProcess); |
|
359 void GetPngScanLine(TDes8& aBuf, const TPoint& aPixel, TInt& aLength); |
|
360 void CalcCrcTable(); |
|
361 // from CImageWriteCodec |
|
362 public: |
|
363 virtual void InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource); |
|
364 virtual TFrameState ProcessFrameL(TBufPtr8& aDst); |
|
365 // from MEZBufferManager |
|
366 private: |
|
367 virtual void InitializeL(CEZZStream &aZStream); |
|
368 virtual void NeedInputL(CEZZStream &aZStream); |
|
369 virtual void NeedOutputL(CEZZStream &aZStream); |
|
370 virtual void FinalizeL(CEZZStream &aZStream); |
|
371 private: |
|
372 TUint32 iCrcTable[KPngCrcTableLength]; |
|
373 TBool iCrcTableCalculated; |
|
374 CPngWriteSubCodec* iEncoder; |
|
375 TPngEncoderState iEncoderState; |
|
376 TInt iCompressionLevel; |
|
377 CEZCompressor* iCompressor; |
|
378 TInt iScanline; |
|
379 TUint8* iDestStartPtr; |
|
380 TUint8* iDestPtr; |
|
381 TUint8* iDestPtrLimit; |
|
382 TPngImageInformation iImageInfo; |
|
383 TPtr8 iCompressorPtr; // data area for compressor to write to |
|
384 TBool iCallAgain; |
|
385 CPngEncoder& iPlugin; |
|
386 |
|
387 friend class RPngWriteCodecTest; |
|
388 }; |
|
389 |
|
390 |
|
391 #include "PngCodec.inl" |
|
392 |
|
393 #endif // __PNGCODEC_H__ |