1 /* |
|
2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: CCmShrinker class in the Memory manager component |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32std.h> |
|
20 #include <imageconversion.h> // CImageDecoder, CImageEncoder |
|
21 #include <bitmaptransforms.h> // CBitmapScaler |
|
22 #include <fbs.h> // CFbsBitmap |
|
23 #include <w32std.h> // RWsSession, CWsScreenDevice |
|
24 |
|
25 #include "cmdmmain.h" |
|
26 #include "msdebug.h" |
|
27 #include "cmmmimagemetadataresolver.h" |
|
28 #include "cmmmobserver.h" |
|
29 #include "cmmmshrinker.h" |
|
30 |
|
31 // CONSTANTS |
|
32 const TInt KScreenWidth = 128; |
|
33 const TInt KScreenHeight = 128; |
|
34 |
|
35 |
|
36 // --------------------------------------------------------------------------- |
|
37 // CCmMmShrinker::NewL |
|
38 // --------------------------------------------------------------------------- |
|
39 // |
|
40 CCmMmShrinker* CCmMmShrinker::NewL( CCmDmMain& aDbManager ) |
|
41 { |
|
42 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewL() start")); |
|
43 CCmMmShrinker* self = CCmMmShrinker::NewLC( aDbManager ); |
|
44 CleanupStack::Pop( self ); |
|
45 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewL() end")); |
|
46 return self; |
|
47 } |
|
48 |
|
49 // --------------------------------------------------------------------------- |
|
50 // CCmMmShrinker::NewLC |
|
51 // --------------------------------------------------------------------------- |
|
52 // |
|
53 CCmMmShrinker* CCmMmShrinker::NewLC( CCmDmMain& aDbManager ) |
|
54 { |
|
55 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewLC() start")); |
|
56 CCmMmShrinker* self = new ( ELeave ) CCmMmShrinker( aDbManager ); |
|
57 CleanupStack::PushL( self ); |
|
58 self->ConstructL(); |
|
59 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::NewLC() end")); |
|
60 return self; |
|
61 } |
|
62 |
|
63 // --------------------------------------------------------------------------- |
|
64 // C++ constructor |
|
65 // --------------------------------------------------------------------------- |
|
66 // |
|
67 CCmMmShrinker::CCmMmShrinker( CCmDmMain& aDbManager ) : |
|
68 CActive( EPriorityIdle ), |
|
69 iShrinkIndex( 0 ), |
|
70 iState( EIdle ), |
|
71 iDbManager( aDbManager ) |
|
72 { |
|
73 |
|
74 CActiveScheduler::Add( this ); |
|
75 } |
|
76 |
|
77 |
|
78 // --------------------------------------------------------------------------- |
|
79 // CCmMmShrinker::ConstructL |
|
80 // --------------------------------------------------------------------------- |
|
81 // |
|
82 void CCmMmShrinker::ConstructL() |
|
83 { |
|
84 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ConstructL() start")); |
|
85 |
|
86 User::LeaveIfError( iFileSession.Connect() ); |
|
87 User::LeaveIfError( RFbsSession::Connect() ); |
|
88 |
|
89 // Get the screen size |
|
90 iScreenSize = ScreenSizeL(); |
|
91 |
|
92 iImageMetadataResolver = CCmMmImageMetadataResolver::NewL( iFileSession ); |
|
93 |
|
94 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ConstructL() end")); |
|
95 } |
|
96 |
|
97 |
|
98 // --------------------------------------------------------------------------- |
|
99 // C++ destructor |
|
100 // --------------------------------------------------------------------------- |
|
101 // |
|
102 CCmMmShrinker::~CCmMmShrinker() |
|
103 { |
|
104 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::~CCmMmShrinker() start")); |
|
105 Cancel(); |
|
106 delete iBitmap; |
|
107 iFileSession.Close(); |
|
108 |
|
109 delete iBitmapScaler; |
|
110 delete iFiles; |
|
111 delete iImageDecoder; |
|
112 delete iImageEncoder; |
|
113 RFbsSession::Disconnect(); |
|
114 delete iImageMetadataResolver; |
|
115 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::~CCmMmShrinker() end")); |
|
116 } |
|
117 |
|
118 // --------------------------------------------------------------------------- |
|
119 // CCmMmShrinker::DoCancel |
|
120 // --------------------------------------------------------------------------- |
|
121 // |
|
122 void CCmMmShrinker::DoCancel() |
|
123 { |
|
124 ClearShrinker(); |
|
125 } |
|
126 |
|
127 // --------------------------------------------------------------------------- |
|
128 // CCmMmShrinker::RunError |
|
129 // --------------------------------------------------------------------------- |
|
130 // |
|
131 #ifdef _DEBUG |
|
132 TInt CCmMmShrinker::RunError( TInt aError ) |
|
133 #else //_DEBUG |
|
134 TInt CCmMmShrinker::RunError( TInt /*aError*/ ) |
|
135 #endif // _DEBÚG |
|
136 { |
|
137 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunError error = %d"), |
|
138 aError )); |
|
139 |
|
140 // NOTE!!! |
|
141 // Should we continue from the next file, if there's error in the |
|
142 // middle of the shrinking operation |
|
143 iShrinkIndex++; |
|
144 iState = EIdle; |
|
145 SetActive(); |
|
146 TRequestStatus* status = &iStatus; |
|
147 User::RequestComplete( status, KErrNone ); |
|
148 return KErrNone; |
|
149 } |
|
150 |
|
151 // --------------------------------------------------------------------------- |
|
152 // CCmMmShrinker::ShrinkImagesL |
|
153 // --------------------------------------------------------------------------- |
|
154 // |
|
155 void CCmMmShrinker::ShrinkImagesL( CDesCArray& aFiles ) |
|
156 { |
|
157 // Cancel 1st |
|
158 Cancel(); |
|
159 |
|
160 // Add processed files |
|
161 if ( &aFiles ) |
|
162 { |
|
163 delete iFiles; |
|
164 iFiles = NULL; |
|
165 iFiles = new ( ELeave ) CDesC16ArrayFlat( aFiles.Count() ); |
|
166 for (TInt i = 0; i < aFiles.Count(); i++) |
|
167 { |
|
168 iFiles->AppendL( aFiles[i] ); |
|
169 } |
|
170 } |
|
171 // Start the action |
|
172 iShrinkIndex = 0; |
|
173 iState = EIdle; |
|
174 SetActive(); |
|
175 TRequestStatus* status = &iStatus; |
|
176 User::RequestComplete( status, KErrNone); |
|
177 } |
|
178 |
|
179 // --------------------------------------------------------------------------- |
|
180 // CCmMmShrinker::SetObserver |
|
181 // --------------------------------------------------------------------------- |
|
182 // |
|
183 void CCmMmShrinker::SetObserver( MCmMmObserver* aObserver ) |
|
184 { |
|
185 iObserver = aObserver; |
|
186 } |
|
187 |
|
188 // --------------------------------------------------------------------------- |
|
189 // CCmMmShrinker::RunL |
|
190 // --------------------------------------------------------------------------- |
|
191 // |
|
192 void CCmMmShrinker::RunL() |
|
193 { |
|
194 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL status = %d"), |
|
195 iStatus.Int() )); |
|
196 |
|
197 // If all files have been processed, notify the observer. |
|
198 if ( iShrinkIndex >= iFiles->Count() ) |
|
199 { |
|
200 if ( iObserver ) |
|
201 { |
|
202 iObserver->ShrinkCompleteL( KErrNone ); |
|
203 } |
|
204 } |
|
205 else |
|
206 { |
|
207 if ( iState == EIdle ) |
|
208 { |
|
209 const TDesC& origFilename = (*iFiles)[iShrinkIndex]; |
|
210 iImageMetadataResolver->CaptureOrginalMetadataL( origFilename ); |
|
211 // Check that file exists (entry is not actually used) |
|
212 TEntry entry; |
|
213 User::LeaveIfError( iFileSession.Entry( origFilename, entry )); |
|
214 iStartTime.HomeTime(); |
|
215 CImageDecoder* imageDecoder = NULL; |
|
216 TRAPD( error, |
|
217 imageDecoder = CImageDecoder::FileNewL( |
|
218 iFileSession, |
|
219 origFilename, |
|
220 CImageDecoder::EOptionNone ) ); |
|
221 if ( error ) |
|
222 { |
|
223 if ( iObserver ) |
|
224 { |
|
225 iObserver->ShrinkCompleteL( error ); |
|
226 } |
|
227 } |
|
228 else |
|
229 { |
|
230 TUid imageType = KNullUid; |
|
231 TUid imageSubType = KNullUid; |
|
232 imageDecoder->ImageType( 0, imageType, imageSubType ); |
|
233 |
|
234 if ( imageType == KImageTypeBMPUid ) |
|
235 { |
|
236 iState = EScale; |
|
237 } |
|
238 else if ( imageType == KImageTypeGIFUid || |
|
239 imageType == KImageTypePNGUid || |
|
240 imageType == KImageTypeJPGUid ) |
|
241 { |
|
242 iState = EDecode; |
|
243 } |
|
244 else |
|
245 { |
|
246 if ( iObserver ) |
|
247 { |
|
248 iObserver->ShrinkCompleteL( KErrNone ); |
|
249 } |
|
250 } |
|
251 |
|
252 delete imageDecoder; |
|
253 imageDecoder = NULL; |
|
254 } |
|
255 } |
|
256 |
|
257 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: status = %d"), |
|
258 iStatus.Int() )); |
|
259 |
|
260 switch ( iState ) |
|
261 { |
|
262 case EDecode: |
|
263 { |
|
264 const TDesC& origFilename = (*iFiles)[iShrinkIndex]; |
|
265 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: Decoding file \ |
|
266 %S"), &origFilename )); |
|
267 |
|
268 delete iImageDecoder; |
|
269 iImageDecoder = NULL; |
|
270 delete iBitmap; |
|
271 iBitmap = NULL; |
|
272 |
|
273 iImageDecoder = CImageDecoder::FileNewL( iFileSession, |
|
274 origFilename, CImageDecoder::EOptionNone ); |
|
275 iBitmap = new (ELeave) CFbsBitmap(); |
|
276 TInt error = iBitmap->Create( |
|
277 iImageDecoder->FrameInfo().iOverallSizeInPixels, |
|
278 iImageDecoder->FrameInfo().iFrameDisplayMode ); |
|
279 if ( error != KErrNone ) |
|
280 { |
|
281 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL \ |
|
282 error: %d"), error )); |
|
283 if ( iObserver ) |
|
284 { |
|
285 TRACE(Print(_L("[MEMORY MNGR]\t Clearing shrinker" ))); |
|
286 ClearShrinker(); |
|
287 iObserver->ShrinkCompleteL( error ); |
|
288 } |
|
289 Cancel(); |
|
290 } |
|
291 else |
|
292 { |
|
293 iImageDecoder->Convert( &iStatus, *iBitmap ); |
|
294 |
|
295 iState = EScale; |
|
296 SetActive(); |
|
297 } |
|
298 break; |
|
299 } |
|
300 case EScale: |
|
301 { |
|
302 const TDesC& origFilename = (*iFiles)[iShrinkIndex]; |
|
303 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: Scaling file \ |
|
304 %S"), &origFilename )); |
|
305 |
|
306 // If converting is still ongoing we should continue it |
|
307 if ( iStatus == KErrUnderflow ) |
|
308 { |
|
309 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: \ |
|
310 Still decoding file %S"), &origFilename )); |
|
311 iImageDecoder->ContinueConvert( &iStatus ); |
|
312 SetActive(); |
|
313 } |
|
314 else |
|
315 { |
|
316 delete iBitmapScaler; |
|
317 iBitmapScaler = NULL; |
|
318 iBitmapScaler = CBitmapScaler::NewL(); |
|
319 |
|
320 iBitmapScaler->Scale( &iStatus, *iBitmap, iScreenSize ); |
|
321 iState = EEncode; |
|
322 SetActive(); |
|
323 |
|
324 delete iImageDecoder; |
|
325 iImageDecoder = NULL; |
|
326 } |
|
327 |
|
328 break; |
|
329 } |
|
330 case EEncode: |
|
331 { |
|
332 const TDesC& origFilename = (*iFiles)[iShrinkIndex]; |
|
333 TRACE(Print(_L("[MEMORY MNGR]\t CCmMmShrinker: Encoding file \ |
|
334 %S"), &origFilename )); |
|
335 |
|
336 delete iImageEncoder; |
|
337 iImageEncoder = NULL; |
|
338 |
|
339 // Shrink into private directory |
|
340 PrivatePath( iFileSession, iTempFilename, origFilename ); |
|
341 |
|
342 // Check that if the file already exists somehow... |
|
343 if ( iTempFilename == origFilename ) |
|
344 { |
|
345 // Delete the original |
|
346 iFileSession.Delete( origFilename ); |
|
347 } |
|
348 iImageEncoder = CImageEncoder::FileNewL( |
|
349 iFileSession, |
|
350 iTempFilename, |
|
351 CImageEncoder::EOptionNone, |
|
352 KImageTypeJPGUid ); |
|
353 |
|
354 iImageEncoder->Convert( &iStatus, *iBitmap ); |
|
355 iState = EReplace; |
|
356 |
|
357 SetActive(); |
|
358 break; |
|
359 } |
|
360 case EReplace: |
|
361 { |
|
362 const TDesC& origFilename = (*iFiles)[iShrinkIndex]; |
|
363 TRACE( Print( |
|
364 _L("[MEMORY MNGR]\t CCmMmShrinker: Replacing file %S"), |
|
365 &origFilename) ); |
|
366 |
|
367 TInt error = iFileSession.Replace( |
|
368 iTempFilename, |
|
369 origFilename ); |
|
370 |
|
371 TRACE( Print( |
|
372 _L("[MEMORY MNGR]\t CCmMmShrinker: Replace done err: %d"), |
|
373 error ) ); |
|
374 |
|
375 // Resolve orginal image metadata!!! |
|
376 TRAPD( mdError, iImageMetadataResolver->ResolveMetadataL( |
|
377 origFilename ) ); |
|
378 if( mdError ) |
|
379 { |
|
380 TRACE( Print( |
|
381 _L("[MEMORY MNGR]\t Metadata resolving error : %d"), |
|
382 mdError ) ); |
|
383 } |
|
384 |
|
385 iStopTime.HomeTime(); |
|
386 |
|
387 TTimeIntervalMicroSeconds t = |
|
388 iStartTime.MicroSecondsFrom( iStopTime ); |
|
389 error = iDbManager.IncrementShrinkTimeL( |
|
390 iFiles->Count(), |
|
391 iStartTime.MicroSecondsFrom( iStopTime ).Int64() / 1000 ); |
|
392 |
|
393 iState = EIdle; |
|
394 iShrinkIndex++; |
|
395 SetActive(); |
|
396 TRequestStatus* status = &iStatus; |
|
397 User::RequestComplete( status, KErrNone ); |
|
398 break; |
|
399 } |
|
400 case EIdle: |
|
401 { |
|
402 TRACE( Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL() \ |
|
403 Idle state")) ); |
|
404 break; |
|
405 } |
|
406 default: |
|
407 { |
|
408 TRACE( Print(_L("[MEMORY MNGR]\t CCmMmShrinker::RunL() \ |
|
409 Incorrect state")) ); |
|
410 if ( iObserver ) |
|
411 { |
|
412 iObserver->ShrinkCompleteL( iStatus.Int() ); |
|
413 } |
|
414 Cancel(); |
|
415 break; |
|
416 } |
|
417 } |
|
418 } |
|
419 } |
|
420 |
|
421 |
|
422 // --------------------------------------------------------------------------- |
|
423 // CCmMmShrinker::ScreenSizeL |
|
424 // --------------------------------------------------------------------------- |
|
425 // |
|
426 TSize CCmMmShrinker::ScreenSizeL() |
|
427 { |
|
428 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ScreenSizeL() start")); |
|
429 |
|
430 TSize screenSize( KScreenWidth, KScreenHeight ); |
|
431 RWsSession session; |
|
432 |
|
433 TInt error = session.Connect() ; |
|
434 CleanupClosePushL( session ); |
|
435 if ( !error ) |
|
436 { |
|
437 CWsScreenDevice* screenDevice = |
|
438 new ( ELeave ) CWsScreenDevice( session ); |
|
439 if ( screenDevice && !screenDevice->Construct() ) |
|
440 { |
|
441 TSize temp( KScreenWidth, KScreenHeight ); |
|
442 temp = screenDevice->SizeInPixels(); |
|
443 // Use landscape mode in shrinking |
|
444 TRACE(Print(_L("[MEMORY MNGR]\t Image height = %d"),temp.iWidth)); |
|
445 TRACE(Print(_L("[MEMORY MNGR]\t Image width = %d"),temp.iHeight)); |
|
446 screenSize.iHeight = temp.iWidth; |
|
447 screenSize.iWidth = temp.iHeight; |
|
448 } |
|
449 delete screenDevice; |
|
450 screenDevice = NULL; |
|
451 } |
|
452 |
|
453 CleanupStack::PopAndDestroy( &session ); |
|
454 |
|
455 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::ScreenSizeL() end")); |
|
456 return screenSize; |
|
457 } |
|
458 |
|
459 // --------------------------------------------------------------------------- |
|
460 // CCmMmShrinker::PrivatePath |
|
461 // --------------------------------------------------------------------------- |
|
462 // |
|
463 void CCmMmShrinker::PrivatePath( RFs& aFs, |
|
464 TFileName& aPrivatePath, |
|
465 const TFileName& aOriginal ) |
|
466 { |
|
467 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::PrivatePath() start")); |
|
468 |
|
469 aPrivatePath.Zero(); |
|
470 |
|
471 TParse nameParse; |
|
472 nameParse.Set( aOriginal, NULL, NULL ); |
|
473 |
|
474 aPrivatePath.Append( nameParse.Drive() ); |
|
475 TFileName privatePath; |
|
476 TInt err = aFs.PrivatePath( privatePath ); |
|
477 if ( !err ) |
|
478 { |
|
479 aPrivatePath.Append( privatePath ); |
|
480 |
|
481 // Now the path contains everything but filename and extension |
|
482 // => check that the directory exists. If not, it will be created. |
|
483 // Possible error is ignored at the moment |
|
484 // (normal case is KErrAlreadyExists) |
|
485 err = aFs.MkDirAll( aPrivatePath ); |
|
486 |
|
487 |
|
488 aPrivatePath.Append( nameParse.NameAndExt() ); |
|
489 } |
|
490 LOG(_L("[MEMORY MNGR]\t CCmMmShrinker::PrivatePath() end")); |
|
491 } |
|
492 |
|
493 // --------------------------------------------------------------------------- |
|
494 // CCmMmShrinker::ClearShrinker |
|
495 // --------------------------------------------------------------------------- |
|
496 // |
|
497 void CCmMmShrinker::ClearShrinker() |
|
498 { |
|
499 if ( iImageDecoder ) |
|
500 { |
|
501 iImageDecoder->Cancel(); |
|
502 delete iImageDecoder; |
|
503 iImageDecoder = NULL; |
|
504 } |
|
505 if ( iBitmapScaler ) |
|
506 { |
|
507 iBitmapScaler->Cancel(); |
|
508 delete iBitmapScaler; |
|
509 iBitmapScaler = NULL; |
|
510 } |
|
511 if ( iImageEncoder ) |
|
512 { |
|
513 iImageEncoder->Cancel(); |
|
514 delete iImageEncoder; |
|
515 iImageEncoder = NULL; |
|
516 } |
|
517 if( iBitmap ) |
|
518 { |
|
519 delete iBitmap; |
|
520 iBitmap = NULL; |
|
521 } |
|
522 } |
|
523 |
|
524 // End of file |
|
525 |
|