|
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 #include <fbs.h> |
|
17 #include "PPM2Codec.h" |
|
18 #include "PPM2Panic.h" |
|
19 |
|
20 |
|
21 // CPpmReadCodec |
|
22 |
|
23 CPpmReadCodec* CPpmReadCodec::NewL(CPpmDecoder& aDecoder) |
|
24 { |
|
25 CPpmReadCodec* result = new (ELeave) CPpmReadCodec(aDecoder); |
|
26 CleanupStack::PushL(result); |
|
27 result->ConstructL(); |
|
28 CleanupStack::Pop(result); |
|
29 return result; |
|
30 } |
|
31 |
|
32 CPpmReadCodec::CPpmReadCodec(CPpmDecoder& aDecoder): |
|
33 iDecoder(&aDecoder) |
|
34 {} |
|
35 |
|
36 CPpmReadCodec::~CPpmReadCodec() |
|
37 { |
|
38 } |
|
39 |
|
40 void CPpmReadCodec::ProcessFrameL() |
|
41 { |
|
42 if (iDecoder->Compressed()) |
|
43 { |
|
44 DoProcessCompressedL(); |
|
45 } |
|
46 else |
|
47 { |
|
48 DoProcessUncompressedL(); |
|
49 } |
|
50 } |
|
51 |
|
52 TFrameState CPpmReadCodec::ProcessFrameL(TBufPtr8& /*aSrc*/) |
|
53 { |
|
54 __ASSERT_ALWAYS(EFalse, Panic(EIllegalCall)); |
|
55 return EFrameIncomplete; |
|
56 } |
|
57 |
|
58 void CPpmReadCodec::Complete() |
|
59 { |
|
60 ImageProcessor()->FlushPixels(); |
|
61 } |
|
62 |
|
63 void CPpmReadCodec::DoProcessUncompressedL() |
|
64 { |
|
65 CImageProcessor*const imageProc = ImageProcessor(); |
|
66 #if defined(__CONTINUE_CONVERT) |
|
67 iDecoder->ResetPosition(iMarkedPosition); |
|
68 for (; iPixelsProcessed<iPixelsExpected; iPixelsProcessed++) |
|
69 #else |
|
70 iDecoder->ResetPosition(0); |
|
71 for (TInt pixelsProcessed=0; pixelsProcessed<iPixelsExpected; pixelsProcessed++) |
|
72 #endif // defined(__CONTINUE_CONVERT) |
|
73 { |
|
74 if (ShouldAbort()) |
|
75 { |
|
76 break; |
|
77 } |
|
78 |
|
79 iDecoder->SkipCommentAndWhiteSpaceL(); |
|
80 TUint rVal = iDecoder->ReadIntL(); |
|
81 iDecoder->SkipCommentAndWhiteSpaceL(); |
|
82 TUint gVal = iDecoder->ReadIntL(); |
|
83 iDecoder->SkipCommentAndWhiteSpaceL(); |
|
84 TUint bVal = iDecoder->ReadIntL(); |
|
85 |
|
86 TInt dataShift = iDecoder->DataShift(); |
|
87 TRgb rgb (rVal<<dataShift, gVal<<dataShift, bVal<<dataShift); |
|
88 |
|
89 imageProc->SetPixel(rgb); |
|
90 |
|
91 #if defined(__CONTINUE_CONVERT) |
|
92 iMarkedPosition = iDecoder->Position(); |
|
93 #endif // defined(__CONTINUE_CONVERT) |
|
94 } |
|
95 } |
|
96 |
|
97 void CPpmReadCodec::DoProcessCompressedL() |
|
98 { |
|
99 CImageProcessor*const imageProc = ImageProcessor(); |
|
100 #if defined(__CONTINUE_CONVERT) |
|
101 iDecoder->ResetPosition(iMarkedPosition); |
|
102 for (; iPixelsProcessed<iPixelsExpected; iPixelsProcessed++) |
|
103 #else |
|
104 iDecoder->ResetPosition(0); |
|
105 for (TInt pixelsProcessed=0; pixelsProcessed<iPixelsExpected; pixelsProcessed++) |
|
106 #endif // defined(__CONTINUE_CONVERT) |
|
107 { |
|
108 if (ShouldAbort()) |
|
109 { |
|
110 break; |
|
111 } |
|
112 |
|
113 TUint rVal = iDecoder->GetByteL(); |
|
114 TUint gVal = iDecoder->GetByteL(); |
|
115 TUint bVal = iDecoder->GetByteL(); |
|
116 |
|
117 TInt dataShift = iDecoder->DataShift(); |
|
118 TRgb rgb (rVal<<dataShift, gVal<<dataShift, bVal<<dataShift); |
|
119 |
|
120 imageProc->SetPixel(rgb); |
|
121 |
|
122 #if defined(__CONTINUE_CONVERT) |
|
123 iMarkedPosition = iDecoder->Position(); // remember where we get to |
|
124 #endif // defined(__CONTINUE_CONVERT) |
|
125 } |
|
126 } |
|
127 |
|
128 void CPpmReadCodec::InitFrameL(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameImageData*/, TBool aDisableErrorDiffusion, CFbsBitmap& aFrame, CFbsBitmap* /*aDestinationMask*/) |
|
129 { |
|
130 TSize& originalSize = aFrameInfo.iOverallSizeInPixels; |
|
131 CImageProcessor* imageProc = ImageProcessorUtility::NewImageProcessorL(aFrame,originalSize,aFrameInfo.iFrameDisplayMode, aDisableErrorDiffusion); |
|
132 SetImageProcessor(imageProc); |
|
133 |
|
134 #if defined(__CONTINUE_CONVERT) |
|
135 ResetFrameL(aFrameInfo, aFrame); |
|
136 #endif // defined(__CONTINUE_CONVERT) |
|
137 |
|
138 ClearBitmapL(aFrame, KRgbWhite); |
|
139 // do something sensible for partial streamed decodes |
|
140 |
|
141 iPixelsExpected = originalSize.iWidth * originalSize.iHeight; |
|
142 #if defined(__CONTINUE_CONVERT) |
|
143 iMarkedPosition = 0; |
|
144 iPixelsProcessed = 0; |
|
145 #endif // defined(__CONTINUE_CONVERT) |
|
146 } |
|
147 |
|
148 void CPpmReadCodec::InitFrameHeader(TFrameInfo& aFrameInfo, CFrameImageData& /*aFrameData*/) |
|
149 { |
|
150 ASSERT(aFrameInfo.CurrentFrameState() == TFrameInfo::EFrameInfoUninitialised); |
|
151 iFrameInfo = &aFrameInfo; |
|
152 aFrameInfo.SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingFrameHeader); |
|
153 } |
|
154 |
|
155 TFrameState CPpmReadCodec::ProcessFrameHeaderL(TBufPtr8&/* aData*/) |
|
156 { |
|
157 ASSERT(iFrameInfo); |
|
158 iFrameInfo->SetCurrentFrameState(TFrameInfo::EFrameInfoProcessingComplete); |
|
159 return EFrameComplete; |
|
160 } |
|
161 |
|
162 void CPpmReadCodec::ResetFrameL(TFrameInfo& aFrameInfo, CFbsBitmap& aFrame) |
|
163 { |
|
164 Pos().SetXY(0,0); |
|
165 |
|
166 TSize& originalSize = aFrameInfo.iOverallSizeInPixels; |
|
167 CImageProcessor*const imageProc = ImageProcessor(); |
|
168 ASSERT(imageProc); |
|
169 imageProc->PrepareL(aFrame,originalSize); |
|
170 } |
|
171 |
|
172 // CPpm2WriteCodec |
|
173 |
|
174 const TInt KMaxColourValue=255; |
|
175 |
|
176 CPpm2WriteCodec::CPpm2WriteCodec(CPpmEncoder* aEncoder): |
|
177 iEncoder(aEncoder) |
|
178 {} |
|
179 |
|
180 CPpm2WriteCodec::~CPpm2WriteCodec() |
|
181 {} |
|
182 |
|
183 void CPpm2WriteCodec::ConstructL() |
|
184 { |
|
185 CImageWriteCodec::ConstructL(); |
|
186 } |
|
187 |
|
188 CPpm2WriteCodec* CPpm2WriteCodec::NewL(CPpmEncoder* aEncoder) |
|
189 { |
|
190 CPpm2WriteCodec* result = new (ELeave) CPpm2WriteCodec(aEncoder); |
|
191 CleanupStack::PushL(result); |
|
192 result->ConstructL(); |
|
193 CleanupStack::Pop(result); |
|
194 return result; |
|
195 } |
|
196 |
|
197 void CPpm2WriteCodec::InitFrameL(TBufPtr8& aDst, const CFbsBitmap& aSource) |
|
198 { |
|
199 SetSource(&aSource); |
|
200 TUint8* destStartPtr = const_cast<TUint8*>(aDst.Ptr()); |
|
201 TUint8* destPtr = destStartPtr; |
|
202 #if defined(_DEBUG) |
|
203 TUint8* destPtrLimit = destPtr + aDst.MaxLength(); |
|
204 #endif // defined(_DEBUG) |
|
205 |
|
206 TSize size = aSource.SizeInPixels(); |
|
207 iSourceRect = TRect(size); |
|
208 iPos.SetXY(0,0); |
|
209 iPos.iY = iSourceRect.iBr.iY - 1; |
|
210 |
|
211 TBuf8<256> header; // set up header in buffer |
|
212 header.Zero(); |
|
213 |
|
214 // now the standard header lines |
|
215 _LIT8(KMagicHeader, "P6\n"); |
|
216 header.AppendFormat(KMagicHeader); // ppm magic for compressed |
|
217 _LIT8(KSizeHeader, "%d %d\n"); |
|
218 header.AppendFormat(KSizeHeader, size.iWidth, size.iHeight); |
|
219 _LIT8(KMaxValueHeader, "%d\n"); |
|
220 header.AppendFormat(KMaxValueHeader, KMaxColourValue); |
|
221 |
|
222 TInt headerSize = header.Length(); |
|
223 aDst.Copy(header); |
|
224 destPtr+=headerSize; |
|
225 |
|
226 ASSERT(destPtr < destPtrLimit); // should always be true |
|
227 } |
|
228 |
|
229 TFrameState CPpm2WriteCodec::ProcessFrameL(TBufPtr8& /*aDst*/) |
|
230 { |
|
231 ASSERT(EFalse); // won't be called in this version |
|
232 return EFrameIncomplete; |
|
233 } |
|
234 |
|
235 void CPpm2WriteCodec::DoProcessL(const CFbsBitmap& aSource) |
|
236 { |
|
237 TSize size = aSource.SizeInPixels(); |
|
238 TInt numLines = size.iHeight; |
|
239 |
|
240 TInt scanLength = aSource.ScanLineLength(size.iWidth, EColor16M); |
|
241 // create buffer of the appropriate length |
|
242 TUint8* scanBuffer = STATIC_CAST(TUint8*, User::AllocLC(scanLength)); |
|
243 |
|
244 for (TInt line=0; line<numLines; line++) |
|
245 { |
|
246 if (ShouldAbort()) |
|
247 { |
|
248 User::Leave(KErrCancel); |
|
249 } |
|
250 |
|
251 TPtr8 scanLine (scanBuffer, 0, scanLength); |
|
252 |
|
253 TPoint pos (0, line); |
|
254 aSource.GetScanLine(scanLine, pos, scanLength, EColor16M); |
|
255 // this comes out in order BGR, so switch |
|
256 SwitchRGB(scanLine); |
|
257 |
|
258 AppendDataL(scanLine); |
|
259 } |
|
260 |
|
261 CleanupStack::PopAndDestroy(); // scanBuffer |
|
262 } |
|
263 |
|
264 // Assume original has pixels with BGR in order - switch to RGB |
|
265 void CPpm2WriteCodec::SwitchRGB(TDes8 &aBuf) |
|
266 { |
|
267 TUint8* buf = const_cast<TUint8*>(aBuf.Ptr()); |
|
268 TUint8* bufMax = buf + aBuf.Length(); |
|
269 |
|
270 while (buf<bufMax) |
|
271 { |
|
272 TUint8 b = buf[0]; |
|
273 TUint8 g = buf[1]; |
|
274 TUint8 r = buf[2]; |
|
275 buf[0] = r; |
|
276 buf[1] = g; |
|
277 buf[2] = b; |
|
278 |
|
279 buf += 3; |
|
280 } |
|
281 } |