|
1 // Copyright (c) 1997-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 <barsread.h> |
|
17 #include <bidi.h> |
|
18 #include <eikenv.h> |
|
19 #include <techview/eikchlst.h> |
|
20 #include <techview/eikinfo.h> |
|
21 #include <techview/eikmenup.h> |
|
22 #include <e32math.h> |
|
23 #include <badesca.h> |
|
24 #include <techview/eikon.rsg> |
|
25 #include <eikpriv.rsg> |
|
26 #include <techview/eiktxlbx.h> |
|
27 #include <techview/eikmfne.h> |
|
28 #include <techview/eiktxlbm.h> |
|
29 #include <iclexif.h> |
|
30 |
|
31 #include <icl/icl_uids.hrh> |
|
32 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
33 #include <icl/icl_uids_const.hrh> |
|
34 #include <icl/icl_uids_def.hrh> |
|
35 #endif |
|
36 #include "TImageViewer.h" |
|
37 |
|
38 const TInt KVideoMinZoomFactor = -3; |
|
39 const TInt KVideoMaxZoomFactor = 0; |
|
40 |
|
41 const TInt KDefaultStreamDelay = 1000000; // 1s. Used when streaming non-animated |
|
42 const TInt KDefaultFolderDelay = 2000000; // 2s. Used when playing a folder |
|
43 |
|
44 const TInt KButtonMoveIncr = 16; |
|
45 const TInt KScaleFactor = 10; |
|
46 |
|
47 const TInt KInfoBufferSize = 1024; |
|
48 |
|
49 _LIT(KDefPath, "C:\\"); |
|
50 const TInt KShortestPossiblePath=4; |
|
51 |
|
52 // #define __USE_PURE_SCALING // fine scaling scales to 1/2, 1/4 and 1/8 - check non-universal scaling |
|
53 |
|
54 #define __CLEAR_BITMAPS_FIRST // for debugging purposes, get TImageViewer to clear bitmaps prior to |
|
55 // decode conversion. Really the codecs should do this, but... |
|
56 |
|
57 inline TBool IsMngImage(const CImageDecoder* aDecoder) |
|
58 { |
|
59 TUid type, subtype; |
|
60 aDecoder->ImageType(0, type, subtype); |
|
61 return (type.iUid==KMngMimeTypeUidValue); |
|
62 } |
|
63 |
|
64 inline TBool HasMoreMngFrames(const CImageDecoder* aDecoder) |
|
65 { |
|
66 const TFrameInfo& info=aDecoder->FrameInfo(0); |
|
67 return (info.iFlags & TFrameInfo::EMngMoreFramesToDecode); |
|
68 } |
|
69 |
|
70 CPluginInfoArray* CPluginInfoArray::NewL() |
|
71 { |
|
72 CPluginInfoArray* self = new (ELeave) CPluginInfoArray; |
|
73 CleanupStack::PushL(self); |
|
74 self->ConstructL(); |
|
75 CleanupStack::Pop(self); |
|
76 return self; |
|
77 } |
|
78 |
|
79 void CPluginInfoArray::ConstructL() |
|
80 { |
|
81 RefreshPluginListL(); |
|
82 } |
|
83 |
|
84 CPluginInfoArray::CPluginInfoArray() |
|
85 { |
|
86 } |
|
87 |
|
88 void CPluginInfoArray::Reset() |
|
89 { |
|
90 iPluginArray.ResetAndDestroy(); |
|
91 } |
|
92 |
|
93 void CPluginInfoArray::RefreshPluginListL() |
|
94 { |
|
95 Reset(); |
|
96 CImageEncoder::GetImageTypesL(iPluginArray); |
|
97 } |
|
98 |
|
99 CPluginInfoArray::~CPluginInfoArray() |
|
100 { |
|
101 Reset(); |
|
102 } |
|
103 |
|
104 TInt CPluginInfoArray::MdcaCount() const |
|
105 { |
|
106 return iPluginArray.Count(); |
|
107 } |
|
108 |
|
109 TPtrC CPluginInfoArray::MdcaPoint(TInt aIndex) const |
|
110 { |
|
111 return iPluginArray[aIndex]->Description(); |
|
112 } |
|
113 |
|
114 TUid CPluginInfoArray::ImageType(TInt aIndex) |
|
115 { |
|
116 return iPluginArray[aIndex]->ImageType(); |
|
117 } |
|
118 |
|
119 TUid CPluginInfoArray::SubType(TInt aIndex) |
|
120 { |
|
121 return iPluginArray[aIndex]->SubType(); |
|
122 } |
|
123 |
|
124 // CFrameInfoDialog |
|
125 class CFrameInfoDialog : public CEikDialog |
|
126 { |
|
127 public: |
|
128 CFrameInfoDialog(const TDesC& aPropertiesText, const TDesC& aImageCommentText, const TDesC& aFrameCommentText); |
|
129 |
|
130 protected: |
|
131 void PreLayoutDynInitL(); |
|
132 |
|
133 private: |
|
134 const TDesC& iPropertiesText; |
|
135 const TDesC& iImageCommentText; |
|
136 const TDesC& iFrameCommentText; |
|
137 }; |
|
138 |
|
139 CFrameInfoDialog::CFrameInfoDialog(const TDesC& aPropertiesText, const TDesC& aImageCommentText, const TDesC& aFrameCommentText) |
|
140 : iPropertiesText(aPropertiesText), iImageCommentText(aImageCommentText), iFrameCommentText(aFrameCommentText) |
|
141 { |
|
142 } |
|
143 |
|
144 void CFrameInfoDialog::PreLayoutDynInitL() |
|
145 { |
|
146 // Grab each Edwin and set the text. |
|
147 CEikEdwin* page = STATIC_CAST(CEikEdwin*, Control(EFramePropertiesPage)); |
|
148 page->SetTextL(&iPropertiesText); |
|
149 |
|
150 page = STATIC_CAST(CEikEdwin*, Control(EImageCommentsPage)); |
|
151 page->SetTextL(&iImageCommentText); |
|
152 |
|
153 page = STATIC_CAST(CEikEdwin*, Control(EFrameCommentsPage)); |
|
154 page->SetTextL(&iFrameCommentText); |
|
155 } |
|
156 |
|
157 // |
|
158 // CVideoWalker |
|
159 // |
|
160 |
|
161 class CVideoWalker : public CActive |
|
162 { |
|
163 public: |
|
164 static CVideoWalker* NewL(CVideoAppUi* aAppUi); |
|
165 ~CVideoWalker(); |
|
166 TRequestStatus& ActiveStatus(); |
|
167 void SelfComplete(TInt aError); |
|
168 protected: |
|
169 CVideoWalker(CVideoAppUi* aAppUi); |
|
170 // from CActive |
|
171 void RunL(); |
|
172 void DoCancel(); |
|
173 protected: |
|
174 CVideoAppUi* const iAppUi; // not owned |
|
175 }; |
|
176 |
|
177 |
|
178 // |
|
179 // CVideoAppUi |
|
180 // |
|
181 |
|
182 CVideoAppUi::CVideoAppUi(): |
|
183 iStreamBuffer(NULL,0,0) |
|
184 { |
|
185 iDecoderOptions = (CImageDecoder::EAllowGeneratedMask | CImageDecoder::EPreferFastDecode); |
|
186 } |
|
187 |
|
188 void CVideoAppUi::ConstructL() |
|
189 { |
|
190 CEikAppUi::ConstructL(); |
|
191 |
|
192 iAppView = CVideoAppView::NewL(ClientRect()); |
|
193 |
|
194 ::new(&iFrame) CWsBitmap(iEikonEnv->WsSession()); |
|
195 ::new(&iMask) CWsBitmap(iEikonEnv->WsSession()); |
|
196 |
|
197 iRotator = CBitmapRotator::NewL(); |
|
198 iScaler = CBitmapScaler::NewL(); |
|
199 |
|
200 iBackgroundColor = KRgbWhite.Color16(); |
|
201 |
|
202 iAppView->SetBackgroundColor(TRgb::Color16(iBackgroundColor), ENoDrawNow); |
|
203 |
|
204 iWalker = CVideoWalker::NewL(this); |
|
205 User::LeaveIfError(iTimer.CreateLocal()); |
|
206 iStreamGen = CVideoWalker::NewL(this); |
|
207 User::LeaveIfError(iStreamTimer.CreateLocal()); |
|
208 |
|
209 // Note iStreamSeed deliberated left as 0 to give consistent behaviour |
|
210 |
|
211 iSaveInfo.iImageTypeUid = KImageTypeJPGUid; |
|
212 iSaveInfo.iBpp = 6; |
|
213 iSaveInfo.iColor = ETrue; |
|
214 iSaveInfo.iQualityFactor = 40; |
|
215 iSaveInfo.iSampling = 2; |
|
216 |
|
217 iUseNativeDisplayMode = ETrue; |
|
218 |
|
219 iScalingCoefficient = 1; // Full size |
|
220 } |
|
221 |
|
222 CVideoAppUi::~CVideoAppUi() |
|
223 { |
|
224 Cancel(); |
|
225 |
|
226 iFrame.Reset(); |
|
227 iMask.Reset(); |
|
228 if (iAppView) |
|
229 { |
|
230 RemoveFromStack(iAppView); |
|
231 delete iAppView; |
|
232 } |
|
233 delete iFrameImageData; |
|
234 delete iLoadUtil; |
|
235 delete iSaveUtil; |
|
236 delete iRotator; |
|
237 delete iScaler; |
|
238 delete iWalker; |
|
239 iTimer.Close(); |
|
240 iStreamTimer.Close(); |
|
241 delete iStreamGen; |
|
242 User::Free(REINTERPRET_CAST(TAny*,CONST_CAST(TUint8*, iStreamBuffer.Ptr()))); |
|
243 delete iDir; |
|
244 iOperations.Close(); |
|
245 } |
|
246 |
|
247 void CVideoAppUi::Cancel() |
|
248 { |
|
249 if (iWalker) |
|
250 iWalker->Cancel(); // if active will callback on DoCancel() |
|
251 if (iStreamGen) |
|
252 iStreamGen->Cancel(); |
|
253 iState = EIdle; |
|
254 } |
|
255 |
|
256 TKeyResponse CVideoAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
257 { |
|
258 TKeyResponse ret = EKeyWasConsumed; |
|
259 |
|
260 if (aType!=EEventKey) |
|
261 return ret; |
|
262 |
|
263 TUint code = aKeyEvent.iCode; |
|
264 |
|
265 switch (code) |
|
266 { |
|
267 case EKeyLeftArrow: |
|
268 case EKeyRightArrow: |
|
269 case EKeyUpArrow: |
|
270 case EKeyDownArrow: |
|
271 { |
|
272 if ( aKeyEvent.iModifiers & EModifierShift ) |
|
273 { |
|
274 // update crop region |
|
275 UpdateClippingRect(code); |
|
276 } |
|
277 else |
|
278 { |
|
279 TPoint moveBy; |
|
280 switch (code) |
|
281 { |
|
282 case EKeyLeftArrow: |
|
283 moveBy.SetXY(KButtonMoveIncr,0); |
|
284 break; |
|
285 case EKeyRightArrow: |
|
286 moveBy.SetXY(-KButtonMoveIncr,0); |
|
287 break; |
|
288 case EKeyUpArrow: |
|
289 moveBy.SetXY(0,KButtonMoveIncr); |
|
290 break; |
|
291 case EKeyDownArrow: |
|
292 moveBy.SetXY(0,-KButtonMoveIncr); |
|
293 break; |
|
294 } |
|
295 iAppView->MoveBy(moveBy); |
|
296 } |
|
297 } |
|
298 break; |
|
299 case EKeyEscape: |
|
300 Cancel(); |
|
301 ASSERT(iState==EIdle); |
|
302 iEikonEnv->BusyMsgCancel(); |
|
303 iEikonEnv->InfoMsg(_L("Cancelled")); |
|
304 break; |
|
305 default: |
|
306 ret = EKeyWasNotConsumed; |
|
307 break; |
|
308 } |
|
309 return ret; |
|
310 } |
|
311 |
|
312 void CVideoAppUi::HandleCommandL(TInt aCommand) |
|
313 { |
|
314 switch (aCommand) |
|
315 { |
|
316 case EVideoCmdOpenFile: |
|
317 OpenFileL(EFileTypeUnknown); |
|
318 break; |
|
319 case EVideoCmdOpenOtaFile: |
|
320 OpenFileL(EFileTypeOta); |
|
321 break; |
|
322 case EVideoCmdOpenWbmpFile: |
|
323 OpenFileL(EFileTypeWbmp); |
|
324 break; |
|
325 case EVideoCmdOpenFolder: |
|
326 OpenFolderL(); |
|
327 break; |
|
328 case EVideoCmdSaveAs: |
|
329 SaveAsL(); |
|
330 break; |
|
331 case EVideoCmdMask: |
|
332 iDisableMask = ! iDisableMask; |
|
333 if (iDisableMask) |
|
334 { |
|
335 iEikonEnv->InfoMsg(_L("Mask reset")); |
|
336 } |
|
337 else |
|
338 { |
|
339 iEikonEnv->InfoMsg(_L("Mask enabled")); |
|
340 } |
|
341 if (iMask.Handle() && iDisableMask) |
|
342 { |
|
343 iMask.Reset(); |
|
344 } |
|
345 else if (iMask.Handle()==0 && !iDisableMask) |
|
346 { |
|
347 User::LeaveIfError(iMask.Create(TSize(0,0),EGray256)); |
|
348 } |
|
349 break; |
|
350 case EVideoCmdZoomIn: |
|
351 iZoomFactor++; |
|
352 if (iZoomFactor > KVideoMaxZoomFactor) |
|
353 iZoomFactor = KVideoMinZoomFactor; |
|
354 if ( iUseExtensions ) |
|
355 { |
|
356 iScalingCoefficient = iZoomFactor - 1; |
|
357 } |
|
358 LoadFileL(); |
|
359 break; |
|
360 case EVideoCmdZoomOut: |
|
361 iZoomFactor--; |
|
362 if (iZoomFactor < KVideoMinZoomFactor) |
|
363 iZoomFactor = KVideoMaxZoomFactor; |
|
364 if ( iUseExtensions ) |
|
365 { |
|
366 iScalingCoefficient = iZoomFactor - 1; |
|
367 } |
|
368 LoadFileL(); |
|
369 break; |
|
370 case EVideoCmdFineZoomIn: |
|
371 ZoomFrameL(ETrue); |
|
372 break; |
|
373 case EVideoCmdFineZoomOut: |
|
374 ZoomFrameL(EFalse); |
|
375 break; |
|
376 case EVideoCmdDisplayMode: |
|
377 DisplayModeL(); |
|
378 break; |
|
379 case EVideoCmdBackgroundColor: |
|
380 BackgroundColorL(); |
|
381 break; |
|
382 case EVideoCmdPlay: |
|
383 if (iState == EPlaying || iState == ELoading) |
|
384 iEikonEnv->InfoMsg(_L("Busy...")); |
|
385 else |
|
386 PlayClipL(); |
|
387 break; |
|
388 case EVideoCmdStream: |
|
389 StreamPlayL(EFileTypeUnknown); |
|
390 break; |
|
391 case EVideoCmdOtaStream: |
|
392 StreamPlayL(EFileTypeOta); |
|
393 break; |
|
394 case EVideoCmdWbmpStream: |
|
395 StreamPlayL(EFileTypeWbmp); |
|
396 break; |
|
397 case EVideoCmdDecoderOptions: |
|
398 DecoderOptionsL(); |
|
399 break; |
|
400 case EVideoCmdExtension: |
|
401 ExtensionOptionsL(); |
|
402 break; |
|
403 case EVideoCmdUseExtensions: |
|
404 iUseExtensions = !iUseExtensions; |
|
405 break; |
|
406 case EVideoCmdRefresh: |
|
407 LoadFileL(); |
|
408 break; |
|
409 case EVideoCmdExtractFrame: |
|
410 ExtractFrameL(); |
|
411 break; |
|
412 case EVideoCmdExtractStreamedFrame: |
|
413 StreamPlayL(EFileTypeUnknown, ETrue); |
|
414 break; |
|
415 case EVideoCmdFrameInfo: |
|
416 FrameInfoL(); |
|
417 break; |
|
418 case EVideoCmdRotateClockwise: |
|
419 FrameRotateL(ETrue); |
|
420 break; |
|
421 case EVideoCmdRotateAntiClockwise: |
|
422 FrameRotateL(EFalse); |
|
423 break; |
|
424 case EVideoCmdMirrorHorizontalAxis: |
|
425 FrameMirrorL(ETrue); |
|
426 break; |
|
427 case EVideoCmdMirrorVerticalAxis: |
|
428 FrameMirrorL(EFalse); |
|
429 break; |
|
430 case EEikCmdExit: |
|
431 Exit(); |
|
432 break; |
|
433 default: |
|
434 iEikonEnv->InfoMsg(R_VIDEO_UNKNOWN); |
|
435 break; |
|
436 } |
|
437 } |
|
438 |
|
439 TBool CVideoAppUi::ProcessCommandParametersL(TApaCommand aCommand,TFileName& aDocumentName,const TDesC8& aTail) |
|
440 { |
|
441 switch (aCommand) |
|
442 { |
|
443 case EApaCommandOpen: |
|
444 iLoadFileName = aDocumentName; |
|
445 break; |
|
446 case EApaCommandCreate: |
|
447 case EApaCommandRun: |
|
448 break; |
|
449 case EApaCommandBackground: |
|
450 default: |
|
451 break; |
|
452 } |
|
453 |
|
454 return CEikAppUi::ProcessCommandParametersL(aCommand,aDocumentName,aTail); |
|
455 } |
|
456 |
|
457 void CVideoAppUi::OpenFileL(TFileType aFileType) |
|
458 { |
|
459 if (iLoadFileName.Length() < KShortestPossiblePath) |
|
460 iLoadFileName = KDefPath; |
|
461 |
|
462 Cancel(); |
|
463 delete iLoadUtil; iLoadUtil = NULL; |
|
464 |
|
465 TInt title; |
|
466 switch (aFileType) |
|
467 { |
|
468 default: |
|
469 title = 0; |
|
470 break; |
|
471 case EFileTypeWbmp: |
|
472 title = R_VIDEO_OPEN_WBMP; |
|
473 break; |
|
474 case EFileTypeOta: |
|
475 title = R_VIDEO_OPEN_OTA; |
|
476 break; |
|
477 } |
|
478 CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&iLoadFileName, title); |
|
479 if (!dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN)) |
|
480 return; |
|
481 |
|
482 iLastFileType = aFileType; |
|
483 iOpeningFolder = EFalse; |
|
484 LoadFileL(); |
|
485 } |
|
486 |
|
487 void CVideoAppUi::OpenFolderL() |
|
488 { |
|
489 Cancel(); |
|
490 |
|
491 if (iLoadFileName.Length() < KShortestPossiblePath) |
|
492 iLoadFileName = KDefPath; |
|
493 |
|
494 TFileName folderName = iLoadFileName; |
|
495 |
|
496 CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&folderName, R_VIDEO_SELECT_FOLDER); |
|
497 if (!dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN)) |
|
498 return; |
|
499 |
|
500 iLastFileType = EFileTypeUnknown; |
|
501 iOpeningFolder = ETrue; |
|
502 LoadFolderL(folderName); |
|
503 } |
|
504 |
|
505 void CVideoAppUi::DecoderOptionsL() |
|
506 { |
|
507 CEikDialog* dialog = new(ELeave) CDecoderOptionsDialog(iDecoderOptions); |
|
508 dialog->ExecuteLD(R_VIDEO_DECODER_OPTIONS_DIALOG); |
|
509 } |
|
510 |
|
511 void CVideoAppUi::ExtensionOptionsL() |
|
512 { |
|
513 CEikDialog* dialog = new(ELeave) CExtensionOptionsDialog(iClippingRect, |
|
514 iOperations, |
|
515 iScalingCoefficient, |
|
516 iScalingQuality, |
|
517 iLockAspectRatio); |
|
518 TInt buttonPressed = dialog->ExecuteLD(R_VIDEO_DECODER_EXTENSION_DIALOG); |
|
519 if ( buttonPressed == EEikBidOk && iLoadUtil ) |
|
520 { |
|
521 // re-convert the image e.g. if clipping rect has changed |
|
522 LoadFileL(); |
|
523 } |
|
524 } |
|
525 |
|
526 void CVideoAppUi::LoadFileL() |
|
527 { |
|
528 Cancel(); |
|
529 if ( !iLoadUtil ) |
|
530 { |
|
531 if (iLoadFileName.Length() < KShortestPossiblePath) |
|
532 return; |
|
533 |
|
534 TUid format; |
|
535 switch (iLastFileType) |
|
536 { |
|
537 case EFileTypeOta: |
|
538 format = KImageTypeOTAUid; |
|
539 break; |
|
540 case EFileTypeWbmp: |
|
541 format = KImageTypeWBMPUid; |
|
542 break; |
|
543 default: |
|
544 format = KNullUid; |
|
545 } |
|
546 |
|
547 TRAPD(error,iLoadUtil = CImageDecoder::FileNewL(iCoeEnv->FsSession(), iLoadFileName, CImageDecoder::TOptions(iDecoderOptions), format)); |
|
548 if (error!=KErrNone) |
|
549 { |
|
550 iEikonEnv->HandleError(error); |
|
551 iAppView->Reset(EDrawNow); // ensure we redraw whole screen - replace previous cross if required |
|
552 return; |
|
553 } |
|
554 } |
|
555 |
|
556 HandleNewlyOpenedImageL(); |
|
557 |
|
558 StartFrameOpen(EPlaying); |
|
559 } |
|
560 |
|
561 void CVideoAppUi::LoadFolderL(const TDesC& aDirName) |
|
562 { |
|
563 delete iDir; iDir = NULL; |
|
564 |
|
565 TParsePtrC parse(aDirName); |
|
566 iDirName = parse.DriveAndPath(); |
|
567 |
|
568 iEikonEnv->FsSession().GetDir(iDirName, 0, 0, iDir); |
|
569 |
|
570 if (iDir->Count()==0) |
|
571 { |
|
572 iEikonEnv->InfoMsg(R_VIDEO_EMPTY_FOLDER); |
|
573 return; |
|
574 } |
|
575 |
|
576 iDirIndex = 0; |
|
577 OpenNextFolderEntry(); |
|
578 } |
|
579 |
|
580 void CVideoAppUi::OpenNextFolderEntry() |
|
581 { |
|
582 if (iDirIndex >= iDir->Count()) |
|
583 { |
|
584 // end of processing - so stop |
|
585 iEikonEnv->BusyMsgCancel(); |
|
586 Cancel(); |
|
587 iState = EIdle; |
|
588 return; |
|
589 } |
|
590 |
|
591 const TEntry& entry = (*iDir)[iDirIndex]; |
|
592 iLoadFileName.Copy(iDirName); |
|
593 iLoadFileName.Append(entry.iName); |
|
594 |
|
595 delete iLoadUtil; |
|
596 iLoadUtil = NULL; |
|
597 TRAPD(error, LoadFileL()); |
|
598 |
|
599 if (error==KErrNone) |
|
600 iEikonEnv->InfoMsg(entry.iName); |
|
601 else |
|
602 { |
|
603 TBuf<64> errorMsg; |
|
604 errorMsg.Format(_L("%S - error %d"), &entry.iName, error); |
|
605 iEikonEnv->InfoMsg(errorMsg); |
|
606 LoadFolderWait(); |
|
607 } |
|
608 } |
|
609 |
|
610 void CVideoAppUi::DynInitMenuPaneL(TInt aResourceId,CEikMenuPane* aMenuPane) |
|
611 { |
|
612 if(aResourceId==R_VIDEO_CLIP_MENU) |
|
613 { |
|
614 if (iLoadUtil==NULL || iState!=EIdle) // nothing open or we are busy |
|
615 aMenuPane->SetItemDimmed(EVideoCmdPlay,ETrue); |
|
616 } |
|
617 else if (aResourceId==R_VIDEO_OPERATE_MENU) |
|
618 { |
|
619 if (iLoadUtil==NULL || iState!=EIdle || iUseExtensions) |
|
620 { |
|
621 // nothing open or we are busy |
|
622 aMenuPane->SetItemDimmed(EVideoCmdRotateClockwise,ETrue); |
|
623 aMenuPane->SetItemDimmed(EVideoCmdRotateAntiClockwise,ETrue); |
|
624 aMenuPane->SetItemDimmed(EVideoCmdMirrorHorizontalAxis,ETrue); |
|
625 aMenuPane->SetItemDimmed(EVideoCmdMirrorVerticalAxis,ETrue); |
|
626 } |
|
627 } |
|
628 else if (aResourceId==R_VIDEO_ZOOM_MENU) |
|
629 { |
|
630 if (iLoadUtil==NULL || iState!=EIdle || iUseExtensions) |
|
631 { |
|
632 aMenuPane->SetItemDimmed(EVideoCmdZoomIn,ETrue); |
|
633 aMenuPane->SetItemDimmed(EVideoCmdZoomOut,ETrue); |
|
634 } |
|
635 } |
|
636 else if ( aResourceId==R_VIDEO_VIEW_MENU ) |
|
637 { |
|
638 aMenuPane->SetItemButtonState(EVideoCmdUseExtensions,(iUseExtensions) ? EEikMenuItemSymbolOn : 0); |
|
639 } |
|
640 } |
|
641 |
|
642 TBool CVideoAppUi::CheckHotKeyNotDimmedL(TInt aCommandId) |
|
643 { |
|
644 TInt result = ETrue; |
|
645 switch (aCommandId) |
|
646 { |
|
647 case EVideoCmdPlay: |
|
648 case EVideoCmdRotateClockwise: |
|
649 case EVideoCmdRotateAntiClockwise: |
|
650 case EVideoCmdFineZoomIn: |
|
651 case EVideoCmdFineZoomOut: |
|
652 case EVideoCmdMirrorHorizontalAxis: |
|
653 case EVideoCmdMirrorVerticalAxis: |
|
654 if (iLoadUtil==NULL || iState!=EIdle || iUseExtensions) |
|
655 result = EFalse; |
|
656 break; |
|
657 default: |
|
658 // do nothing |
|
659 break; |
|
660 } |
|
661 return result; |
|
662 } |
|
663 |
|
664 void CVideoAppUi::LoadFolderWait() |
|
665 { |
|
666 ASSERT(!iWalker->IsActive()); // if we get here, should not be doing anything |
|
667 |
|
668 iTimer.After(iWalker->ActiveStatus(), KDefaultFolderDelay); |
|
669 iState = EFolderWait; |
|
670 } |
|
671 |
|
672 void CVideoAppUi::HandleNewlyOpenedImageL() |
|
673 { |
|
674 ASSERT(iLoadUtil); // should have already been opened |
|
675 |
|
676 TFrameInfo frameInfo = iLoadUtil->FrameInfo(0); |
|
677 |
|
678 // jf 3/12/01. Assume frame 0 gives the main image characteristics |
|
679 iOverallSize = frameInfo.iOverallSizeInPixels; |
|
680 if (iOverallSize.iWidth==0 || iOverallSize.iHeight==0) |
|
681 { |
|
682 iOverallSize = frameInfo.iFrameCoordsInPixels.Size(); |
|
683 if (iOverallSize.iWidth==0 || iOverallSize.iHeight==0) |
|
684 { |
|
685 iEikonEnv->InfoMsg(_L("Invalid image dimensions.")); |
|
686 User::Leave(KErrCorrupt); |
|
687 } |
|
688 } |
|
689 |
|
690 iAnimating = (frameInfo.iDelay != TTimeIntervalMicroSeconds(0) || IsMngImage(iLoadUtil)); |
|
691 |
|
692 iFrameNumber = 0; |
|
693 |
|
694 iTime.HomeTime(); |
|
695 } |
|
696 |
|
697 void CVideoAppUi::ExtractFrameL() |
|
698 { |
|
699 if (iLoadFileName.Length() < KShortestPossiblePath) |
|
700 return; |
|
701 |
|
702 ASSERT(iLoadUtil); |
|
703 |
|
704 Cancel(); |
|
705 |
|
706 TInt frameCount = iLoadUtil->FrameCount(); |
|
707 |
|
708 if (iFrameNumber >= frameCount) |
|
709 iFrameNumber = 0; |
|
710 |
|
711 CEikDialog* dialog = new(ELeave) CVideoCurrentFrameDialog(iFrameNumber,frameCount); |
|
712 if (!dialog->ExecuteLD(R_VIDEO_FRAME_DIALOG)) |
|
713 return; |
|
714 |
|
715 StartFrameOpen(ELoading); |
|
716 } |
|
717 |
|
718 void CVideoAppUi::StartFrameOpen(TState aNextState, TBool aSizeFrame) |
|
719 { |
|
720 TRAPD(error, DoStartFrameOpenL(aSizeFrame)); |
|
721 if (error!=KErrNone) |
|
722 iWalker->SelfComplete(error); |
|
723 iState = aNextState; // what ever happens we go to next state, and will handle any error there |
|
724 } |
|
725 |
|
726 void CVideoAppUi::DoStartFrameOpenL(TBool aSizeFrame) |
|
727 { |
|
728 ASSERT(iLoadUtil); // should be true by now |
|
729 ASSERT(!iWalker->IsActive()); // we are going to use it |
|
730 |
|
731 ASSERT(iFrameNumber>=0 && iFrameNumber<iLoadUtil->FrameCount()); |
|
732 |
|
733 // Set up extensions |
|
734 if ( iClippingRect.IsEmpty() ) |
|
735 { |
|
736 TRAPD(err, iLoadUtil->SetClippingRectL(NULL)); |
|
737 // Plugin may not support the call at all |
|
738 if(err != KErrNone && err != KErrNotSupported) |
|
739 { |
|
740 User::Leave(err); |
|
741 } |
|
742 } |
|
743 else |
|
744 { |
|
745 TRAPD(err,iLoadUtil->SetClippingRectL((iUseExtensions) ? &iClippingRect : NULL )); |
|
746 // Plugin may not support the call at all |
|
747 if(err == KErrNotSupported) |
|
748 { |
|
749 iEikonEnv->InfoMsg(_L("Clipping Not Supported using this codec.")); |
|
750 } |
|
751 } |
|
752 |
|
753 TImageConvScaler* scaler = NULL; |
|
754 TRAPD(err,scaler = iLoadUtil->ScalerL()); |
|
755 if ( err == KErrNone ) |
|
756 { |
|
757 scaler->SetScalingL( (iUseExtensions) ? iScalingCoefficient : -1 , iScalingQuality); |
|
758 } |
|
759 else if ( iScalingCoefficient != -1 && err == KErrNotSupported ) |
|
760 { |
|
761 iEikonEnv->InfoMsg(_L("Scaler extension Not Supported using this codec.")); |
|
762 } |
|
763 |
|
764 |
|
765 if ( iOperations.Count() ) |
|
766 { |
|
767 TImageConvOperation* operation = NULL; |
|
768 TRAPD(err,operation = iLoadUtil->OperationL()); |
|
769 if ( err == KErrNone ) |
|
770 { |
|
771 operation->ClearOperationStack(); |
|
772 |
|
773 if ( iUseExtensions) |
|
774 { |
|
775 for ( TInt i = 0; i < iOperations.Count(); i++) |
|
776 { |
|
777 operation->AddOperationL(static_cast<TImageConvOperation::TOperation>(iOperations[i])); |
|
778 } |
|
779 } |
|
780 } |
|
781 else if ( err == KErrNotSupported ) |
|
782 { |
|
783 iEikonEnv->InfoMsg(_L("Operations Not Supported using this codec.")); |
|
784 } |
|
785 } |
|
786 |
|
787 if (aSizeFrame) |
|
788 { |
|
789 TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
790 |
|
791 if (iFrame.Handle() == 0) // Only create the bitmap if we haven't done it already. |
|
792 { |
|
793 if ( !iUseNativeDisplayMode && (frameInfo.iFlags & TFrameInfo::ECanDither) ) |
|
794 User::LeaveIfError(iFrame.Create(TSize(0,0),iAppView->DisplayMode())); |
|
795 else |
|
796 User::LeaveIfError(iFrame.Create(TSize(0,0),frameInfo.iFrameDisplayMode)); |
|
797 } |
|
798 |
|
799 // with 16MA and 16MAP we don't use the mask anymore, this since the introduction |
|
800 // with CR894 & CR1111 of alpha channel support in PNG decoding |
|
801 |
|
802 if (frameInfo.iFlags & TFrameInfo::ETransparencyPossible && !iDisableMask |
|
803 && iAppView->DisplayMode() != EColor16MA && iAppView->DisplayMode() != EColor16MAP ) |
|
804 { |
|
805 if (iMask.Handle() == 0) |
|
806 User::LeaveIfError(iMask.Create(TSize(0,0),EGray256)); |
|
807 } |
|
808 else |
|
809 { |
|
810 if (iMask.Handle()) |
|
811 iMask.Reset(); |
|
812 } |
|
813 |
|
814 |
|
815 SetFrameSizeAndPosL(frameInfo.iFrameCoordsInPixels,frameInfo.iOverallSizeInPixels); |
|
816 } |
|
817 |
|
818 ASSERT(iDisableMask && iMask.Handle()==0 || !iDisableMask); // iDisableMask -> iMask.Handle()==0 |
|
819 ASSERT(iMask.Handle()==0 || iFrame.SizeInPixels()==iMask.SizeInPixels()); // if mask must be same size |
|
820 |
|
821 // DEF090667: T: SetDisplayMode causes another file to be opened with wrong size |
|
822 if(iFrameNumber == 0) |
|
823 { |
|
824 iAppView->Reset(ENoDrawNow); |
|
825 } |
|
826 |
|
827 if (iMask.Handle()) |
|
828 iLoadUtil->Convert(&(iWalker->ActiveStatus()),iFrame,iMask,iFrameNumber); |
|
829 else |
|
830 iLoadUtil->Convert(&(iWalker->ActiveStatus()),iFrame,iFrameNumber); |
|
831 |
|
832 iViewResized = EFalse; |
|
833 } |
|
834 |
|
835 TBool CVideoAppUi::ExtensionIsSetup() |
|
836 { |
|
837 return ( ( !iClippingRect.IsEmpty() ) || Abs(iScalingCoefficient) > 1 || iOperations.Count() ); |
|
838 } |
|
839 |
|
840 void CVideoAppUi::PlayClipL() |
|
841 { |
|
842 iFrameNumber = 0; |
|
843 iTime.HomeTime(); |
|
844 |
|
845 StartFrameOpen(EPlaying); |
|
846 } |
|
847 |
|
848 void CVideoAppUi::SaveAsL() |
|
849 { |
|
850 if (iSaveFileName.Length() < KShortestPossiblePath) |
|
851 iSaveFileName = KDefPath; |
|
852 |
|
853 Cancel(); |
|
854 |
|
855 CEikDialog* dialog = new(ELeave) CVideoSaveAsDialog(&iSaveFileName,iSaveInfo,iEncodeOperations,iCreateThumbnail,iSaveAsEXIF); |
|
856 if (!dialog->ExecuteLD(R_VIDEO_FILE_SAVEAS_DIALOG)) |
|
857 return; |
|
858 iEikonEnv->FsSession().Delete(iSaveFileName); |
|
859 |
|
860 delete iFrameImageData; iFrameImageData = NULL; |
|
861 |
|
862 const TUid imageType = iSaveInfo.iImageTypeUid; |
|
863 TImageDataBlock *imageData = NULL; |
|
864 TFrameDataBlock *frameData = NULL; |
|
865 |
|
866 if(imageType == KImageTypeBMPUid) |
|
867 { |
|
868 imageData = new (ELeave) TBmpImageData; |
|
869 TBmpImageData* data = STATIC_CAST(TBmpImageData*, imageData); |
|
870 switch (iSaveInfo.iBpp) |
|
871 { |
|
872 case 0: data->iBitsPerPixel = 1; break; |
|
873 case 2: data->iBitsPerPixel = 4; break; |
|
874 case 3: data->iBitsPerPixel = 8; break; |
|
875 case 6: data->iBitsPerPixel = 24; break; |
|
876 default: ASSERT(EFalse); break; |
|
877 } |
|
878 } |
|
879 else if(imageType == KImageTypeGIFUid) |
|
880 {// gif does not have encoding options |
|
881 } |
|
882 else if(imageType == KImageTypeJPGUid) |
|
883 { |
|
884 imageData = new (ELeave) TJpegImageData; |
|
885 TJpegImageData* data = STATIC_CAST(TJpegImageData*, imageData); |
|
886 if (!iSaveInfo.iColor) |
|
887 data->iSampleScheme = TJpegImageData::EMonochrome; |
|
888 else |
|
889 data->iSampleScheme = TJpegImageData::TColorSampling(3 - iSaveInfo.iSampling); |
|
890 data->iQualityFactor = iSaveInfo.iQualityFactor; |
|
891 } |
|
892 else if(imageType == KImageTypeMBMUid) |
|
893 { |
|
894 frameData = new (ELeave) TMbmEncodeData; |
|
895 TMbmEncodeData* data = STATIC_CAST(TMbmEncodeData*, frameData); |
|
896 switch (iSaveInfo.iBpp) |
|
897 { |
|
898 case 0: data->iDisplayMode = EGray2; break; |
|
899 case 1: data->iDisplayMode = EGray4; break; |
|
900 case 2: data->iDisplayMode = iSaveInfo.iColor ? EColor16 : EGray16; break; |
|
901 case 3: data->iDisplayMode = iSaveInfo.iColor ? EColor256 : EGray256; break; |
|
902 case 4: data->iDisplayMode = EColor4K; break; |
|
903 case 5: data->iDisplayMode = EColor64K; break; |
|
904 case 6: data->iDisplayMode = EColor16M; break; |
|
905 case 7: data->iDisplayMode = EColor16MU; break; |
|
906 default: ASSERT(EFalse); break; |
|
907 } |
|
908 } |
|
909 else if(imageType == KImageTypePNGUid) |
|
910 { |
|
911 frameData = new (ELeave) TPngEncodeData; |
|
912 TPngEncodeData* data = STATIC_CAST(TPngEncodeData*, frameData); |
|
913 // bpp |
|
914 switch (iSaveInfo.iBpp) |
|
915 { |
|
916 case 0: data->iBitsPerPixel = 1; break; // 1 bpp |
|
917 case 1: data->iBitsPerPixel = 2; break; // 2 bpp |
|
918 case 2: data->iBitsPerPixel = 4; break; // 4 bpp |
|
919 case 3: data->iBitsPerPixel = 8; break; // 8 bpp |
|
920 case 6: data->iBitsPerPixel = 24; break; // 24 bpp |
|
921 default: ASSERT(EFalse); break; // unsupported bit depth |
|
922 } |
|
923 // colour or grayscale? |
|
924 data->iColor = iSaveInfo.iColor; |
|
925 // compression level |
|
926 switch (iSaveInfo.iCompression) |
|
927 { |
|
928 case 0: |
|
929 data->iLevel = TPngEncodeData::EDefaultCompression; |
|
930 break; |
|
931 case 1: |
|
932 data->iLevel = TPngEncodeData::ENoCompression; |
|
933 break; |
|
934 case 2: |
|
935 data->iLevel = TPngEncodeData::EBestSpeed; |
|
936 break; |
|
937 case 3: |
|
938 data->iLevel = TPngEncodeData::EBestCompression; |
|
939 break; |
|
940 default: // unsupported compression |
|
941 ASSERT(EFalse); |
|
942 break; |
|
943 } |
|
944 } |
|
945 else |
|
946 { |
|
947 //custom encoder |
|
948 } |
|
949 |
|
950 if (frameData) |
|
951 CleanupStack::PushL(frameData); |
|
952 |
|
953 if (imageData) |
|
954 CleanupStack::PushL(imageData); |
|
955 |
|
956 delete iSaveUtil; iSaveUtil = NULL; |
|
957 if ( iSaveAsEXIF && (imageType == KImageTypeJPGUid) ) |
|
958 { |
|
959 iSaveUtil = CJPEGExifEncoder::FileNewL(iCoeEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionNone, imageType); |
|
960 // force creation of metadata - this will cause save as EXIF rather than JFIF |
|
961 MExifMetadataWriter* metaData=static_cast<CJPEGExifEncoder*>(iSaveUtil)->ExifMetadata(); |
|
962 } |
|
963 else |
|
964 { |
|
965 iSaveUtil = CImageEncoder::FileNewL(iCoeEnv->FsSession(), iSaveFileName, CImageEncoder::EOptionNone, imageType); |
|
966 } |
|
967 |
|
968 |
|
969 ASSERT(iFrameImageData==NULL); // deleted above |
|
970 if (imageData) |
|
971 { |
|
972 iFrameImageData = CFrameImageData::NewL(); |
|
973 |
|
974 User::LeaveIfError(iFrameImageData->AppendImageData(imageData)); |
|
975 CleanupStack::Pop(); // imageData - ownership now passed to iFrameImageData |
|
976 } |
|
977 |
|
978 if (frameData) |
|
979 { |
|
980 if (iFrameImageData == NULL) |
|
981 iFrameImageData = CFrameImageData::NewL(); |
|
982 |
|
983 User::LeaveIfError(iFrameImageData->AppendFrameData(frameData)); |
|
984 CleanupStack::Pop(); // frameData - ownership now passed to iFrameImageData |
|
985 } |
|
986 |
|
987 if (iCreateThumbnail) |
|
988 { |
|
989 iSaveUtil->SetThumbnail(iCreateThumbnail); |
|
990 } |
|
991 |
|
992 if ( iEncodeOperations.Count() ) |
|
993 { |
|
994 TImageConvOperation* operation = NULL; |
|
995 TRAPD(err, operation = iSaveUtil->OperationL()); |
|
996 if ( err == KErrNone ) |
|
997 { |
|
998 operation->ClearOperationStack(); |
|
999 |
|
1000 for ( TInt i = 0; i < iEncodeOperations.Count(); i++) |
|
1001 { |
|
1002 operation->AddOperationL(static_cast<TImageConvOperation::TOperation>(iEncodeOperations[i])); |
|
1003 } |
|
1004 } |
|
1005 } |
|
1006 |
|
1007 StartFrameSave(); |
|
1008 } |
|
1009 |
|
1010 void CVideoAppUi::DisplayModeL() |
|
1011 { |
|
1012 Cancel(); |
|
1013 TDisplayMode displayMode = iAppView->DisplayMode(); |
|
1014 CEikDialog* dialog = new(ELeave) CVideoDisplayModeDialog(displayMode,iUseNativeDisplayMode); |
|
1015 if (dialog->ExecuteLD(R_VIDEO_DISPLAY_MODE_DIALOG)) |
|
1016 { |
|
1017 if ( iUseNativeDisplayMode && iLoadUtil ) |
|
1018 { |
|
1019 TFrameInfo frameInfo = iLoadUtil->FrameInfo(0); |
|
1020 displayMode = frameInfo.iFrameDisplayMode; |
|
1021 } |
|
1022 |
|
1023 iAppView->SetDisplayModeL(displayMode, &iFrame); |
|
1024 } |
|
1025 } |
|
1026 |
|
1027 void CVideoAppUi::BackgroundColorL() |
|
1028 { |
|
1029 Cancel(); |
|
1030 TInt backgroundColor = iBackgroundColor; |
|
1031 TBool override = iOverrideBackgroundColor; |
|
1032 CEikDialog* dialog = new(ELeave) CVideoBackgroundColorDialog(backgroundColor, override); |
|
1033 if (dialog->ExecuteLD(R_VIDEO_BACKGROUND_COLOR_DIALOG)) |
|
1034 { |
|
1035 iBackgroundColor = backgroundColor; |
|
1036 iOverrideBackgroundColor = override; |
|
1037 if (iOverrideBackgroundColor) |
|
1038 { |
|
1039 iAppView->SetBackgroundColor(TRgb::Color16(iBackgroundColor), ENoDrawNow); |
|
1040 iAppView->Clear(ENoDrawNow); |
|
1041 //redraw without reloading |
|
1042 if (iMask.Handle()==0) |
|
1043 iAppView->DrawImage(&iFrame, iOffset, EDrawNow); |
|
1044 else |
|
1045 iAppView->DrawImage(&iFrame, &iMask, iOffset, EDrawNow); |
|
1046 } |
|
1047 } |
|
1048 } |
|
1049 |
|
1050 void CVideoAppUi::StreamPlayL(TFileType aFileType, TBool aMultiFrameStreaming) |
|
1051 { |
|
1052 Cancel(); |
|
1053 iLastFileType = aFileType; |
|
1054 iMultiFrameStreaming = aMultiFrameStreaming; |
|
1055 |
|
1056 if (iLoadFileName.Length() < 4) |
|
1057 iLoadFileName = KDefPath; |
|
1058 CEikDialog* dialog = new(ELeave) CEikFileOpenDialog(&iLoadFileName); |
|
1059 if (!dialog->ExecuteLD(R_EIK_DIALOG_FILE_OPEN)) |
|
1060 return; |
|
1061 |
|
1062 delete iLoadUtil; iLoadUtil = NULL; |
|
1063 |
|
1064 User::Free(REINTERPRET_CAST(TAny*,CONST_CAST(TUint8*, iStreamBuffer.Ptr()))); |
|
1065 iStreamBuffer.Set(NULL, 0, 0); |
|
1066 |
|
1067 RFile file; |
|
1068 User::LeaveIfError(file.Open(iEikonEnv->FsSession(), iLoadFileName, EFileShareReadersOnly|EFileStream|EFileRead)); |
|
1069 CleanupClosePushL(file); |
|
1070 TInt fileSize; |
|
1071 User::LeaveIfError(file.Size(fileSize)); |
|
1072 iStreamBuffer.Set(STATIC_CAST(TUint8 *, User::AllocL(fileSize)), 0, fileSize); |
|
1073 User::LeaveIfError(file.Read(iStreamBuffer)); |
|
1074 CleanupStack::PopAndDestroy(); // file |
|
1075 |
|
1076 iEikonEnv->BusyMsgL(_L("Busy...")); |
|
1077 |
|
1078 // NB. State machine assumes no leaves after this point |
|
1079 |
|
1080 ASSERT(!iStreamGen->IsActive()); // no async behav should be going on at this point |
|
1081 ASSERT(!iWalker->IsActive()); |
|
1082 |
|
1083 // initialize the buffer |
|
1084 iStreamBuffer.SetLength(0); // data is in buffer, and we increase length to simulate data arriving |
|
1085 User::LeaveIfError(ExtendStreamBuffer()); |
|
1086 |
|
1087 iState = EStreamOpening; |
|
1088 } |
|
1089 |
|
1090 TInt CVideoAppUi::ExtendStreamBuffer() |
|
1091 { |
|
1092 // ASSERT(iStreamBuffer.Length()<iStreamBuffer.MaxLength()); // assumed we don't call when no more streaming to do |
|
1093 |
|
1094 // We CAN get called when there's no more data if the decoders have failed |
|
1095 // to detect end-of-data - e.g. when the input file's header contains a length |
|
1096 // greater than the file size - so return KErrUnderflow if this happens |
|
1097 ASSERT(iStreamBuffer.Length() <= iStreamBuffer.MaxLength()); |
|
1098 if (iStreamBuffer.Length() == iStreamBuffer.MaxLength()) |
|
1099 return KErrUnderflow; |
|
1100 |
|
1101 // 95% change of 128 bytes - else random 1..128 |
|
1102 TInt chance = Math::Rand(iStreamSeed) % 100; |
|
1103 TInt increment; |
|
1104 if (chance < 95) |
|
1105 increment = 128; |
|
1106 else |
|
1107 increment = Math::Rand(iStreamSeed) % 127 + 1; // 1 .. 128 |
|
1108 TInt newSize = Min(iStreamBuffer.Length()+increment, iStreamBuffer.MaxLength()); |
|
1109 iStreamBuffer.SetLength(newSize); |
|
1110 |
|
1111 // random time is 99% chance between 0 and 1/20s, with remainder between 0 and 5s |
|
1112 chance = Math::Rand(iStreamSeed) % 100; |
|
1113 TInt waitTime; |
|
1114 if (chance>=99) |
|
1115 waitTime = Math::Rand(iStreamSeed) % 5000000; |
|
1116 else |
|
1117 waitTime = Math::Rand(iStreamSeed) % 50000; |
|
1118 |
|
1119 iStreamTimer.After(iStreamGen->ActiveStatus(), waitTime); |
|
1120 iSourceHasGrown = ETrue; |
|
1121 |
|
1122 #if defined(_DEBUG) && defined(__ENABLE_DEBUG_OUTPUT) |
|
1123 RDebug::Print(_L("ExtendingStreamBuffer(%d,%d->%d)"), increment, waitTime, newSize); |
|
1124 #endif |
|
1125 |
|
1126 return KErrNone; |
|
1127 } |
|
1128 |
|
1129 void CVideoAppUi::FrameInfoL() |
|
1130 { |
|
1131 if (iFrame.Handle() == 0) |
|
1132 return; |
|
1133 |
|
1134 Cancel(); |
|
1135 |
|
1136 const TInt frameCount = iLoadUtil->FrameCount(); |
|
1137 if(iFrameNumber >= frameCount) |
|
1138 iFrameNumber = frameCount-1; |
|
1139 |
|
1140 HBufC* infoBuffer = HBufC::NewLC(KInfoBufferSize); |
|
1141 TPtr info(infoBuffer->Des()); |
|
1142 |
|
1143 CFrameInfoStrings *frameInfoStrings = iLoadUtil->FrameInfoStringsLC(iFrameNumber); |
|
1144 TInt count = frameInfoStrings->Count(); |
|
1145 TInt index; |
|
1146 for (index=0; index<count; index++) |
|
1147 { |
|
1148 TPtrC frameInfoString = frameInfoStrings->String(index); |
|
1149 info.Append(frameInfoString); |
|
1150 info.Append(TChar(CEditableText::ELineBreak)); |
|
1151 } |
|
1152 |
|
1153 HBufC* imageComments = HBufC::NewLC(0); |
|
1154 TInt numImageComments = iLoadUtil->NumberOfImageComments(); |
|
1155 for (index = 0; index<numImageComments; index++) |
|
1156 { |
|
1157 HBufC* nextComment = iLoadUtil->ImageCommentL(index); |
|
1158 CleanupStack::PushL(nextComment); |
|
1159 |
|
1160 TPtr commentTPtr(nextComment->Des()); |
|
1161 ReplaceNewlinesWithLineBreaks(commentTPtr); |
|
1162 |
|
1163 if (index==0) |
|
1164 { |
|
1165 // first go through, so should have nothing in comments - just assign |
|
1166 ASSERT(imageComments->Length()==0); |
|
1167 imageComments = imageComments->ReAllocL(nextComment->Length()); |
|
1168 *imageComments = *nextComment; |
|
1169 } |
|
1170 else |
|
1171 { |
|
1172 // append line break and then new comments |
|
1173 imageComments = imageComments->ReAllocL(imageComments->Length() + nextComment->Length() + 1); // 1 for linebreak character |
|
1174 TPtr imageCommentsPtr(imageComments->Des()); |
|
1175 imageCommentsPtr.Append(TChar(CEditableText::ELineBreak)); |
|
1176 imageCommentsPtr.Append(*nextComment); |
|
1177 } |
|
1178 CleanupStack::PopAndDestroy(); // nextComment |
|
1179 CleanupStack::Pop(); // old imageComments (already deleted by ReAlloc) |
|
1180 CleanupStack::PushL(imageComments); |
|
1181 } |
|
1182 |
|
1183 HBufC* frameComments = HBufC::NewLC(0); |
|
1184 TInt numFrameComments = iLoadUtil->NumberOfFrameComments(iFrameNumber); |
|
1185 for (index = 0; index<numFrameComments; index++) |
|
1186 { |
|
1187 HBufC* nextComment = iLoadUtil->FrameCommentL(iFrameNumber, index); |
|
1188 CleanupStack::PushL(nextComment); |
|
1189 |
|
1190 TPtr commentTPtr(nextComment->Des()); |
|
1191 ReplaceNewlinesWithLineBreaks(commentTPtr); |
|
1192 |
|
1193 if (index==0) |
|
1194 { |
|
1195 // first go through, so should have nothing in comments - just assign |
|
1196 ASSERT(frameComments->Length()==0); |
|
1197 frameComments = frameComments->ReAllocL(nextComment->Length()); |
|
1198 *frameComments = *nextComment; |
|
1199 } |
|
1200 else |
|
1201 { |
|
1202 // append line break and then new comments |
|
1203 frameComments->ReAllocL(frameComments->Length() + nextComment->Length() + 1); // 1 for linebreak character |
|
1204 TPtr frameCommentsPtr(frameComments->Des()); |
|
1205 frameCommentsPtr.Append(TChar(CEditableText::ELineBreak)); |
|
1206 frameCommentsPtr.Append(*nextComment); |
|
1207 } |
|
1208 CleanupStack::PopAndDestroy(); // nextComment |
|
1209 CleanupStack::Pop(); // old frameComments (already deleted by ReAlloc) |
|
1210 CleanupStack::PushL(frameComments); |
|
1211 } |
|
1212 |
|
1213 CEikDialog* dialog = new(ELeave) CFrameInfoDialog(info, *imageComments, *frameComments); |
|
1214 dialog->ExecuteLD(R_VIDEO_INFO_DIALOG); |
|
1215 |
|
1216 CleanupStack::PopAndDestroy(4); // frameComments, imageComments, frameInfoStrings + infoBuffer |
|
1217 } |
|
1218 |
|
1219 void CVideoAppUi::FrameRotateL(TBool aClockwise) |
|
1220 { |
|
1221 ASSERT(iState == EIdle); |
|
1222 CBitmapRotator::TRotationAngle angle = aClockwise ? |
|
1223 CBitmapRotator::ERotation90DegreesClockwise : |
|
1224 CBitmapRotator::ERotation270DegreesClockwise; |
|
1225 if (iMask.Handle() != 0) |
|
1226 { |
|
1227 iRotateAngle = angle; //keep for second phase |
|
1228 iRotator->Rotate(&(iWalker->ActiveStatus()), iMask, angle); |
|
1229 iState = ERotatingMask; |
|
1230 } |
|
1231 else |
|
1232 { |
|
1233 iRotator->Rotate(&(iWalker->ActiveStatus()), iFrame, angle); |
|
1234 iState = ERotating; |
|
1235 } |
|
1236 iViewResized = EFalse; |
|
1237 } |
|
1238 |
|
1239 void CVideoAppUi::FrameMirrorL(TBool aHorizontalAxis) |
|
1240 { |
|
1241 ASSERT(iState == EIdle); |
|
1242 CBitmapRotator::TRotationAngle angle = aHorizontalAxis ? |
|
1243 CBitmapRotator::EMirrorHorizontalAxis : |
|
1244 CBitmapRotator::EMirrorVerticalAxis; |
|
1245 if (iMask.Handle() != 0) |
|
1246 { |
|
1247 iRotateAngle = angle; //keep for second phase |
|
1248 iRotator->Rotate(&(iWalker->ActiveStatus()), iMask, angle); |
|
1249 iState = ERotatingMask; |
|
1250 } |
|
1251 else |
|
1252 { |
|
1253 iRotator->Rotate(&(iWalker->ActiveStatus()), iFrame, angle); |
|
1254 iState = ERotating; |
|
1255 } |
|
1256 iViewResized = EFalse; |
|
1257 } |
|
1258 |
|
1259 void CVideoAppUi::ZoomFrameL(TBool aZoomIn) |
|
1260 { |
|
1261 TSize size(iFrame.SizeInPixels()); |
|
1262 const TSize adjust(size.iWidth / KScaleFactor, size.iHeight / KScaleFactor); |
|
1263 |
|
1264 if (aZoomIn) |
|
1265 size += adjust; |
|
1266 else |
|
1267 size -= adjust; |
|
1268 |
|
1269 Cancel(); |
|
1270 |
|
1271 TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
1272 |
|
1273 if (!(frameInfo.iFlags&TFrameInfo::EFullyScaleable)) |
|
1274 { |
|
1275 if (iMask.Handle()!=0) |
|
1276 { |
|
1277 iScaleSize = size; // keep for second scale action |
|
1278 iScaler->Scale(&(iWalker->ActiveStatus()),iMask,size); |
|
1279 iViewResized = EFalse; |
|
1280 iState = EScalingMask; |
|
1281 } |
|
1282 else |
|
1283 { |
|
1284 iScaler->Scale(&(iWalker->ActiveStatus()),iFrame,size); |
|
1285 iViewResized = EFalse; |
|
1286 iState = EScaling; |
|
1287 } |
|
1288 } |
|
1289 else |
|
1290 { |
|
1291 SetFrameSizeAndPosL(frameInfo.iFrameCoordsInPixels,size); |
|
1292 |
|
1293 if (!(frameInfo.iFlags&TFrameInfo::ECanDither)) |
|
1294 { |
|
1295 iFrame.Reset(); |
|
1296 User::LeaveIfError(iFrame.Create(TSize(0,0),frameInfo.iFrameDisplayMode)); // We will dither later |
|
1297 } |
|
1298 |
|
1299 #if !defined(__CLEAR_BITMAPS_FIRST) |
|
1300 if (iFrame.SizeInPixels() != size) |
|
1301 #endif |
|
1302 { |
|
1303 #if defined(__CLEAR_BITMAPS_FIRST) |
|
1304 User::LeaveIfError(iFrame.Resize(TSize(0,0))); |
|
1305 #endif |
|
1306 User::LeaveIfError(iFrame.Resize(size)); |
|
1307 } |
|
1308 |
|
1309 if (iMask.Handle()) |
|
1310 { |
|
1311 if (iMask.SizeInPixels() != size) |
|
1312 User::LeaveIfError(iMask.Resize(size)); |
|
1313 #if defined(__CLEAR_BITMAPS_FIRST) |
|
1314 // set mask to black, so it is opaque and by default nothing is drawn |
|
1315 CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(&iMask); |
|
1316 CleanupStack::PushL(device); |
|
1317 CFbsBitGc* bmGc = CFbsBitGc::NewL(); |
|
1318 CleanupStack::PushL(bmGc); |
|
1319 bmGc->Activate(device); |
|
1320 bmGc->SetPenStyle(CGraphicsContext::ENullPen); |
|
1321 bmGc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
1322 bmGc->SetBrushColor(KRgbBlack); |
|
1323 const TRect drawRect(TPoint(0,0), iMask.SizeInPixels()); |
|
1324 bmGc->DrawRect(drawRect); |
|
1325 CleanupStack::PopAndDestroy(2); |
|
1326 #endif |
|
1327 } |
|
1328 |
|
1329 StartFrameOpen(ELoading, EFalse); |
|
1330 } |
|
1331 } |
|
1332 |
|
1333 void CVideoAppUi::StartFrameSave() |
|
1334 { |
|
1335 ASSERT(iSaveUtil); // should be true by now |
|
1336 ASSERT(iState==EIdle); |
|
1337 ASSERT(!iWalker->IsActive()); // we are going to use it |
|
1338 iSaveUtil->Convert(&(iWalker->ActiveStatus()),iFrame,iFrameImageData); |
|
1339 iState = ESaving; |
|
1340 } |
|
1341 |
|
1342 void CVideoAppUi::DrawConvertedFrameL() |
|
1343 { |
|
1344 ASSERT(iDisableMask && iMask.Handle()==0 || !iDisableMask); // iDisableMask -> iMask.Handle()==0 |
|
1345 ASSERT(iMask.Handle()==0 || iFrame.SizeInPixels()==iMask.SizeInPixels()); // if mask must be same size |
|
1346 |
|
1347 TBool fullRedrawReq = EFalse; |
|
1348 if (!iViewResized) |
|
1349 { |
|
1350 TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
1351 TRgb backgroundColor = iOverrideBackgroundColor ? TRgb::Color16(iBackgroundColor) : frameInfo.iBackgroundColor; |
|
1352 fullRedrawReq = iAppView->SetBackgroundColor(backgroundColor, ENoDrawNow); |
|
1353 if (iState == EScaling || iState == ERotating) |
|
1354 { |
|
1355 // size and center based on bitmap, rather than the official image size |
|
1356 TBool resized = iAppView->ResizeL(iFrame.SizeInPixels(), ETrue, ENoDrawNow); |
|
1357 if (resized) |
|
1358 iAppView->Center(ENoDrawNow); |
|
1359 fullRedrawReq = fullRedrawReq || resized; |
|
1360 } |
|
1361 else if (!iAnimating || iFrameNumber==0) |
|
1362 { |
|
1363 TBool resized = iAppView->ResizeL(iImageDisplaySize, ETrue, ENoDrawNow); |
|
1364 // implies Resize |
|
1365 |
|
1366 // PDEF088116: TImageViewer USER 0 with certain animated gifs |
|
1367 if(frameInfo.iFlags & TFrameInfo::EUsesFrameSizeInPixels) |
|
1368 { |
|
1369 if(iFrame.SizeInPixels() != frameInfo.iFrameSizeInPixels) |
|
1370 { |
|
1371 iFrame.Resize(frameInfo.iFrameSizeInPixels); |
|
1372 } |
|
1373 } |
|
1374 //Resize iFrame to iImageDisplaySize if they are different |
|
1375 else if (iFrame.SizeInPixels() != iImageDisplaySize) |
|
1376 { |
|
1377 iFrame.Resize(iImageDisplaySize); |
|
1378 } |
|
1379 |
|
1380 if (resized) |
|
1381 iAppView->Center(ENoDrawNow); |
|
1382 else if (IsMngImage(iLoadUtil) && (iLastFrameFlags & TFrameInfo::ERestoreToBackground)) |
|
1383 { |
|
1384 iAppView->Clear(EFalse, EDrawNow); |
|
1385 } |
|
1386 fullRedrawReq = fullRedrawReq || resized; |
|
1387 } |
|
1388 else if (iFrameNumber > 0 && iLastFrameFlags & TFrameInfo::ERestoreToBackground |
|
1389 || iState != EPlaying && iState != EStreamDecoding && iFrameNumber-1!=iPrevFrameNumber) |
|
1390 { |
|
1391 iAppView->Clear(EFalse, EDrawNow); |
|
1392 ASSERT(iAnimating); // should be true given above, avoids complicating below |
|
1393 if (iState != EPlaying && iState != EStreamDecoding && iFrameNumber-1!=iPrevFrameNumber) |
|
1394 fullRedrawReq = ETrue; |
|
1395 // usually will want to redraw _whole_ bitmap area - otherwise we only |
|
1396 // redraw that part of the bitmap we DrawImage to |
|
1397 // exception is when we are extracting frames in the correct sequence |
|
1398 } |
|
1399 else if (iAnimating && (iState==EPlaying||iState==EStreamDecoding)) |
|
1400 { |
|
1401 // if animating and playing, should have frame greater than 0 and no restore to background - or will trigger above |
|
1402 ASSERT(! (iLastFrameFlags & TFrameInfo::ERestoreToBackground)); |
|
1403 ASSERT(iFrameNumber>0 && iFrameNumber-1==iPrevFrameNumber); |
|
1404 fullRedrawReq = EFalse; // don't redraw full - even if background changed, want to just redraw our bit |
|
1405 } |
|
1406 iViewResized = ETrue; |
|
1407 } |
|
1408 |
|
1409 if (iMask.Handle()==0) |
|
1410 iAppView->DrawImage(&iFrame, iOffset, fullRedrawReq?ENoDrawNow:EDrawNow); |
|
1411 else |
|
1412 iAppView->DrawImage(&iFrame, &iMask, iOffset, fullRedrawReq?ENoDrawNow:EDrawNow); |
|
1413 |
|
1414 if (fullRedrawReq) |
|
1415 iAppView->DrawNow(); |
|
1416 } |
|
1417 |
|
1418 void CVideoAppUi::HandleConvertCompleteL() |
|
1419 { |
|
1420 DrawConvertedFrameL(); |
|
1421 |
|
1422 TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
1423 |
|
1424 iLastFrameFlags = frameInfo.iFlags; |
|
1425 iPrevFrameNumber = iFrameNumber; |
|
1426 |
|
1427 if (iAnimating && iState==EPlaying || |
|
1428 iState==EStreamDecoding && (iMultiFrameStreaming||iAnimating)) |
|
1429 { |
|
1430 ASSERT(!iWalker->IsActive()); // we will use it again |
|
1431 TBool mustSelfComplete=EFalse; |
|
1432 if ((iAnimating && frameInfo.iDelay > TTimeIntervalMicroSeconds(0))||iMultiFrameStreaming) |
|
1433 { |
|
1434 TTime endTime; |
|
1435 endTime.HomeTime(); |
|
1436 |
|
1437 TTimeIntervalMicroSeconds timeTaken = endTime.MicroSecondsFrom(iTime); |
|
1438 if (frameInfo.iDelay > timeTaken) |
|
1439 { |
|
1440 TInt64 delay = frameInfo.iDelay.Int64() - timeTaken.Int64(); |
|
1441 TInt delayPeriod = I64LOW(delay); |
|
1442 if (delayPeriod<0) |
|
1443 delayPeriod=0; // can get negative if we took longer on the streaming than this |
|
1444 iTimer.After(iWalker->ActiveStatus(), delayPeriod); |
|
1445 } |
|
1446 else if(iMultiFrameStreaming) |
|
1447 { |
|
1448 TInt delay = KDefaultStreamDelay - I64LOW(timeTaken.Int64()); |
|
1449 if (delay<0) |
|
1450 delay=0; // can get negative if we took longer on the streaming than this |
|
1451 iTimer.After(iWalker->ActiveStatus(), delay); |
|
1452 } |
|
1453 else |
|
1454 mustSelfComplete=ETrue; |
|
1455 } |
|
1456 else |
|
1457 mustSelfComplete=ETrue; |
|
1458 if (mustSelfComplete) |
|
1459 iWalker->SelfComplete(KErrNone); |
|
1460 if (iState==EPlaying) |
|
1461 iState = EPlayingWait; |
|
1462 else |
|
1463 { |
|
1464 ASSERT(iState==EStreamDecoding); |
|
1465 iState = EStreamDecodeWait; |
|
1466 } |
|
1467 } |
|
1468 else if (iOpeningFolder) |
|
1469 LoadFolderWait(); |
|
1470 else |
|
1471 { |
|
1472 iEikonEnv->BusyMsgCancel(); |
|
1473 Cancel(); // cancel any background streaming |
|
1474 iState = EIdle; |
|
1475 } |
|
1476 } |
|
1477 |
|
1478 void CVideoAppUi::RunL(CVideoWalker* aWalker, TInt aStatus) |
|
1479 { |
|
1480 ASSERT(aWalker==iWalker || aWalker==iStreamGen); // ones we know about |
|
1481 |
|
1482 #if defined(_DEBUG) && defined(__ENABLE_DEBUG_OUTPUT) |
|
1483 RDebug::Print(_L("RunL(%x,%d,%d)(%x,%x)"), aWalker, aStatus, iState, iWalker, iStreamGen); |
|
1484 #endif |
|
1485 |
|
1486 switch (iState) |
|
1487 { |
|
1488 case EIdle: |
|
1489 ASSERT(EFalse); // should not happen |
|
1490 break; |
|
1491 case ELoading: |
|
1492 case EPlaying: |
|
1493 case EScaling: |
|
1494 case ERotating: |
|
1495 { |
|
1496 ASSERT(aWalker==iWalker); |
|
1497 TInt error = aStatus; |
|
1498 if (error==KErrNone) |
|
1499 TRAP(error, HandleConvertCompleteL()); |
|
1500 if (error!=KErrNone) |
|
1501 HandleRunError(aWalker, error); |
|
1502 } |
|
1503 break; |
|
1504 case ERotatingMask: |
|
1505 { |
|
1506 ASSERT(aWalker == iWalker); |
|
1507 if (aStatus==KErrNone) |
|
1508 { |
|
1509 // having done mask, kick off rotate the image itself |
|
1510 iRotator->Rotate(&(iWalker->ActiveStatus()), iFrame, iRotateAngle); |
|
1511 iState = ERotating; |
|
1512 } |
|
1513 else |
|
1514 { |
|
1515 HandleRunError(aWalker, aStatus); |
|
1516 } |
|
1517 break; |
|
1518 } |
|
1519 case EScalingMask: |
|
1520 { |
|
1521 ASSERT(aWalker==iWalker); |
|
1522 if (aStatus==KErrNone) |
|
1523 { |
|
1524 // having done mask, kick off scale of normal |
|
1525 iScaler->Scale(&iWalker->ActiveStatus(), iFrame, iScaleSize); |
|
1526 iState = EScaling; |
|
1527 } |
|
1528 else |
|
1529 HandleRunError(aWalker, aStatus); |
|
1530 } |
|
1531 break; |
|
1532 case EPlayingWait: |
|
1533 { |
|
1534 ASSERT(iWalker==aWalker); |
|
1535 iTime.HomeTime(); // whatever reset the time here |
|
1536 if (aStatus!=KErrNone) |
|
1537 HandleRunError(aWalker, aStatus); |
|
1538 else if (iFrameNumber < iLoadUtil->FrameCount()-1 || (IsMngImage(iLoadUtil)&&HasMoreMngFrames(iLoadUtil)) ) |
|
1539 { |
|
1540 iFrameNumber += ( IsMngImage(iLoadUtil)==EFalse ); |
|
1541 StartFrameOpen(EPlaying); |
|
1542 } |
|
1543 else if (iOpeningFolder) |
|
1544 LoadFolderWait(); |
|
1545 else |
|
1546 { |
|
1547 ASSERT(!iWalker->IsActive() && !iStreamGen->IsActive()); // should have stopped naturally |
|
1548 iEikonEnv->BusyMsgCancel(); |
|
1549 iState = EIdle; |
|
1550 } |
|
1551 } |
|
1552 break; |
|
1553 case ESaving: |
|
1554 { |
|
1555 ASSERT(iWalker==aWalker); |
|
1556 iEikonEnv->BusyMsgCancel(); |
|
1557 iState = EIdle; |
|
1558 if (aStatus!=KErrNone) |
|
1559 HandleRunError(aWalker, aStatus); |
|
1560 } |
|
1561 break; |
|
1562 case EStreamOpening: |
|
1563 { |
|
1564 ASSERT(aWalker==iStreamGen); |
|
1565 TInt error = aStatus; |
|
1566 |
|
1567 if (error==KErrNone) |
|
1568 { |
|
1569 delete iLoadUtil; iLoadUtil = NULL; |
|
1570 |
|
1571 TUid format; |
|
1572 switch (iLastFileType) |
|
1573 { |
|
1574 case EFileTypeOta: |
|
1575 format = KImageTypeOTAUid; |
|
1576 break; |
|
1577 case EFileTypeWbmp: |
|
1578 format = KImageTypeWBMPUid; |
|
1579 break; |
|
1580 default: |
|
1581 format = KNullUid; |
|
1582 } |
|
1583 |
|
1584 TRAP(error, iLoadUtil = CImageDecoder::DataNewL(iCoeEnv->FsSession(), iStreamBuffer, |
|
1585 CImageDecoder::TOptions(iDecoderOptions | CImageDecoder::EOptionAllowZeroFrameOpen), format)); |
|
1586 } |
|
1587 |
|
1588 if (error==KErrUnderflow) |
|
1589 { |
|
1590 error = KErrNone; // clear so we don't hit the error handler below |
|
1591 if (!iStreamGen->IsActive()) |
|
1592 error = ExtendStreamBuffer(); // wait for more input. remain in current state |
|
1593 } |
|
1594 else if (error==KErrNone) |
|
1595 { |
|
1596 if (iLoadUtil->FrameCount()>0) |
|
1597 { |
|
1598 TRAP(error,HandleNewlyOpenedImageL()); |
|
1599 if (error==KErrNone) |
|
1600 TRAP(error,StreamOpenFrameIfPosL()); |
|
1601 } |
|
1602 else |
|
1603 { |
|
1604 // insufficient data, so wait until it comes along |
|
1605 if (!iStreamGen->IsActive()) |
|
1606 error = ExtendStreamBuffer(); // wait for more input. switch to EStreamWaitForFirstFrame |
|
1607 iState = EStreamWaitForFirstFrame; |
|
1608 } |
|
1609 } |
|
1610 |
|
1611 if (error!=KErrNone) |
|
1612 HandleRunError(aWalker, error); |
|
1613 } |
|
1614 break; |
|
1615 case EStreamWaitAndContinue: |
|
1616 #if defined(__BYPASS_CONTINUE_CONVERT) |
|
1617 ASSERT(EFalse); // should not happen when bypassing |
|
1618 #else |
|
1619 { |
|
1620 ASSERT(aWalker==iStreamGen); |
|
1621 |
|
1622 TInt error = aStatus; |
|
1623 |
|
1624 if (error==KErrNone) |
|
1625 { |
|
1626 if ((iStreamBuffer.Length()<iStreamBuffer.MaxLength()) && !iStreamGen->IsActive()) |
|
1627 error = ExtendStreamBuffer(); // "new data has arrived" |
|
1628 ASSERT(iSourceHasGrown); |
|
1629 ASSERT(iState==EStreamWaitAndContinue); |
|
1630 iLoadUtil->ContinueConvert(&(iWalker->ActiveStatus())); |
|
1631 iSourceHasGrown = EFalse; |
|
1632 iState = EStreamDecoding; |
|
1633 } |
|
1634 |
|
1635 if (error!=KErrNone) |
|
1636 HandleRunError(aWalker, error); |
|
1637 } |
|
1638 #endif |
|
1639 break; |
|
1640 case EStreamWaitForFirstFrame: |
|
1641 { |
|
1642 ASSERT(aWalker==iStreamGen); |
|
1643 |
|
1644 TInt error = aStatus; |
|
1645 |
|
1646 if (error==KErrNone) |
|
1647 { |
|
1648 ASSERT(!iLoadUtil->IsImageHeaderProcessingComplete()); // should not be reading more than we need to know |
|
1649 iLoadUtil->ContinueProcessingHeaderL(); |
|
1650 if (iLoadUtil->FrameCount()>0) |
|
1651 { |
|
1652 TRAP(error,HandleNewlyOpenedImageL()); |
|
1653 if (error==KErrNone) |
|
1654 TRAP(error,StreamOpenFrameIfPosL()); |
|
1655 } |
|
1656 else |
|
1657 { |
|
1658 // insufficient data, so wait until it comes along |
|
1659 if (!iStreamGen->IsActive()) |
|
1660 error = ExtendStreamBuffer(); // wait for more input. stay in same state |
|
1661 } |
|
1662 } |
|
1663 |
|
1664 if (error!=KErrNone) |
|
1665 HandleRunError(aWalker, error); |
|
1666 } |
|
1667 break; |
|
1668 case EStreamWaitForDetails: |
|
1669 { |
|
1670 ASSERT(aWalker==iStreamGen); |
|
1671 TInt error = aStatus; |
|
1672 |
|
1673 if (error==KErrNone) |
|
1674 { |
|
1675 TRAP(error, StreamOpenFrameIfPosL()); |
|
1676 } |
|
1677 if (error!=KErrNone) |
|
1678 HandleRunError(aWalker, error); |
|
1679 } |
|
1680 break; |
|
1681 case EStreamDecoding: |
|
1682 { |
|
1683 ASSERT(aWalker==iWalker || aWalker==iStreamGen); |
|
1684 TInt error = aStatus; |
|
1685 if (aWalker==iWalker) |
|
1686 { |
|
1687 TBool timerActive = iStreamGen->IsActive(); |
|
1688 if (error==KErrNone) |
|
1689 { |
|
1690 TRAP(error, HandleConvertCompleteL()); |
|
1691 } |
|
1692 else if (error==KErrUnderflow && (timerActive || iSourceHasGrown)) |
|
1693 { |
|
1694 // draw partial result to the screen if possible, else set error to KErrNone so we don't stop |
|
1695 TFrameInfo frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
1696 if (!(frameInfo.iFlags & TFrameInfo::EPartialDecodeInvalid)) |
|
1697 { |
|
1698 TRAP(error, DrawConvertedFrameL()); |
|
1699 } |
|
1700 else |
|
1701 error = KErrNone; |
|
1702 |
|
1703 if (error==KErrNone) |
|
1704 { |
|
1705 // wait for more data to arrive before we try again |
|
1706 #if defined(__BYPASS_CONTINUE_CONVERT) |
|
1707 iState = EStreamWaitForDetails; |
|
1708 #else |
|
1709 iState = EStreamWaitAndContinue; |
|
1710 #endif |
|
1711 if(!timerActive) |
|
1712 { // final buffer was added after last Convert()/ContinueConvert() |
|
1713 ASSERT(iStreamBuffer.Length()==iStreamBuffer.MaxLength()); |
|
1714 ASSERT(iSourceHasGrown); |
|
1715 // force a final decode |
|
1716 iStreamTimer.After(iStreamGen->ActiveStatus(),0); |
|
1717 } |
|
1718 } |
|
1719 } |
|
1720 } |
|
1721 else |
|
1722 { |
|
1723 ASSERT(aWalker==iStreamGen); |
|
1724 if (error==KErrNone && iStreamBuffer.Length()<iStreamBuffer.MaxLength()) |
|
1725 error = ExtendStreamBuffer(); // data can arrive concurrent with decode |
|
1726 } |
|
1727 if (error!=KErrNone) |
|
1728 HandleRunError(aWalker, error); |
|
1729 } |
|
1730 break; |
|
1731 case EStreamDecodeWait: |
|
1732 { |
|
1733 ASSERT(aWalker==iWalker || aWalker==iStreamGen); |
|
1734 TInt error = aStatus; |
|
1735 if (aWalker==iWalker) |
|
1736 { |
|
1737 iTime.HomeTime(); // whatever reset the time here |
|
1738 if (error==KErrNone) |
|
1739 { |
|
1740 if (iFrameNumber < iLoadUtil->FrameCount()-1 || !iLoadUtil->IsImageHeaderProcessingComplete()) |
|
1741 { |
|
1742 iFrameNumber += 1; |
|
1743 TRAP(error,StreamOpenFrameIfPosL()); |
|
1744 } |
|
1745 else |
|
1746 { |
|
1747 Cancel(); // may be required true, eg if there is data after the frame, other AO may be busy |
|
1748 iEikonEnv->BusyMsgCancel(); |
|
1749 iState = EIdle; |
|
1750 } |
|
1751 } |
|
1752 } |
|
1753 else |
|
1754 { |
|
1755 ASSERT(aWalker==iStreamGen); |
|
1756 if (error==KErrNone && iStreamBuffer.Length()<iStreamBuffer.MaxLength()) |
|
1757 error = ExtendStreamBuffer(); // data can arrive concurrent with wait |
|
1758 } |
|
1759 if (error!=KErrNone) |
|
1760 HandleRunError(aWalker, error); |
|
1761 } |
|
1762 break; |
|
1763 case EFolderWait: |
|
1764 iDirIndex++; |
|
1765 OpenNextFolderEntry(); |
|
1766 break; |
|
1767 default: |
|
1768 ASSERT(EFalse); // unknown state |
|
1769 } |
|
1770 } |
|
1771 |
|
1772 void CVideoAppUi::DoCancel(CVideoWalker *aWalker) |
|
1773 { |
|
1774 ASSERT(aWalker==iWalker || aWalker==iStreamGen); // only ones we know about |
|
1775 |
|
1776 #if defined(_DEBUG) && defined(__ENABLE_DEBUG_OUTPUT) |
|
1777 RDebug::Print(_L("DoCancel(%x,%d)(%x,%x)"), aWalker, iState, iWalker, iStreamGen); |
|
1778 #endif |
|
1779 |
|
1780 if (aWalker==iWalker) |
|
1781 { |
|
1782 switch (iState) |
|
1783 { |
|
1784 case ELoading: |
|
1785 case EPlaying: |
|
1786 case EStreamDecoding: |
|
1787 iLoadUtil->Cancel(); |
|
1788 break; |
|
1789 case ESaving: |
|
1790 iSaveUtil->Cancel(); |
|
1791 break; |
|
1792 case EScaling: |
|
1793 case EScalingMask: |
|
1794 iScaler->Cancel(); |
|
1795 break; |
|
1796 case ERotating: |
|
1797 case ERotatingMask: |
|
1798 iRotator->Cancel(); |
|
1799 break; |
|
1800 case EStreamDecodeWait: |
|
1801 case EPlayingWait: // ignore scenario where we self complete - will not get here |
|
1802 case EFolderWait: |
|
1803 iTimer.Cancel(); |
|
1804 break; |
|
1805 default: |
|
1806 ASSERT(EFalse); // unknown state or should not happen |
|
1807 } |
|
1808 } |
|
1809 else |
|
1810 { |
|
1811 ASSERT(aWalker==iStreamGen); |
|
1812 switch (iState) |
|
1813 { |
|
1814 case EStreamOpening: |
|
1815 case EStreamWaitForDetails: |
|
1816 case EStreamWaitAndContinue: |
|
1817 case EStreamDecoding: |
|
1818 case EStreamDecodeWait: |
|
1819 case EStreamWaitForFirstFrame: |
|
1820 iStreamTimer.Cancel(); |
|
1821 break; |
|
1822 default: |
|
1823 ASSERT(EFalse); // unknown state or should not happen |
|
1824 } |
|
1825 } |
|
1826 } |
|
1827 |
|
1828 void CVideoAppUi::HandleRunError(CVideoWalker* /*aWalker*/, TInt aError) |
|
1829 { |
|
1830 Cancel(); |
|
1831 iEikonEnv->BusyMsgCancel(); |
|
1832 iEikonEnv->HandleError(aError); |
|
1833 ASSERT(iState == EIdle); |
|
1834 } |
|
1835 |
|
1836 void CVideoAppUi::StreamOpenFrameIfPosL() |
|
1837 { |
|
1838 if (iFrameNumber >= iLoadUtil->FrameCount()) |
|
1839 { |
|
1840 // Continue processing headers if necessary and only if we are not in the middle of an image conversion. |
|
1841 ASSERT(!iLoadUtil->IsImageHeaderProcessingComplete()); // should not be reading more than we need to know |
|
1842 iLoadUtil->ContinueProcessingHeaderL(); |
|
1843 } |
|
1844 |
|
1845 if (iFrameNumber >= iLoadUtil->FrameCount()) |
|
1846 { |
|
1847 if (iLoadUtil->IsImageHeaderProcessingComplete()) |
|
1848 { |
|
1849 Cancel(); // other AO could still be busy if there were bytes after last frame data |
|
1850 iEikonEnv->BusyMsgCancel(); |
|
1851 iState = EIdle; |
|
1852 } |
|
1853 else |
|
1854 { |
|
1855 // not yet reached the frame header |
|
1856 iState = EStreamWaitForDetails; |
|
1857 if (!iStreamGen->IsActive()) |
|
1858 // this shuld cope with reaching end of stream prematurely : |
|
1859 User::LeaveIfError(ExtendStreamBuffer()); |
|
1860 } |
|
1861 } |
|
1862 else |
|
1863 { |
|
1864 if ((iStreamBuffer.Length()<iStreamBuffer.MaxLength()) && !iStreamGen->IsActive()) |
|
1865 User::LeaveIfError(ExtendStreamBuffer()); // "new data has arrived" |
|
1866 ASSERT(iSourceHasGrown); |
|
1867 StartFrameOpen(EStreamDecoding); |
|
1868 iSourceHasGrown = EFalse; |
|
1869 } |
|
1870 ASSERT(iState==EIdle||iStreamBuffer.Length()==iStreamBuffer.MaxLength()||iStreamGen->IsActive()); // either we've finished, reached the end or we expect more data |
|
1871 } |
|
1872 |
|
1873 void CVideoAppUi::SetFrameSizeAndPosL(const TRect& aFrameRect,const TSize& aOverallSize) |
|
1874 { |
|
1875 TRect zoomedFrame(aFrameRect); |
|
1876 TSize zoomedSize(aOverallSize); |
|
1877 TSize zoomedOverallSize(iOverallSize); // effectively size on frame 0 |
|
1878 if (aOverallSize.iWidth == 0 || aOverallSize.iHeight == 0) |
|
1879 zoomedSize = aFrameRect.Size(); |
|
1880 |
|
1881 if ( iUseExtensions ) |
|
1882 { |
|
1883 // using PREQ1630 extensions |
|
1884 TInt err = iLoadUtil->GetDestinationSize(zoomedSize,iFrameNumber); |
|
1885 if ( err != KErrNone ) |
|
1886 { |
|
1887 TBuf<256> buf; |
|
1888 buf.Format(_L("GetDestinationSize Error %d"),err); |
|
1889 iEikonEnv->InfoMsg(buf); |
|
1890 } |
|
1891 |
|
1892 User::LeaveIfError(iFrame.Resize(zoomedSize)); |
|
1893 } |
|
1894 else |
|
1895 { |
|
1896 if (iZoomFactor > 0) |
|
1897 { |
|
1898 zoomedFrame.iTl.iX <<= iZoomFactor; |
|
1899 zoomedFrame.iTl.iY <<= iZoomFactor; |
|
1900 zoomedFrame.iBr.iX <<= iZoomFactor; |
|
1901 zoomedFrame.iBr.iY <<= iZoomFactor; |
|
1902 zoomedSize.iWidth <<= iZoomFactor; |
|
1903 zoomedSize.iHeight <<= iZoomFactor; |
|
1904 zoomedOverallSize.iWidth <<= iZoomFactor; |
|
1905 zoomedOverallSize.iHeight <<= iZoomFactor; |
|
1906 } |
|
1907 else if (iZoomFactor < 0) |
|
1908 { |
|
1909 const TInt absZoomFactor = -iZoomFactor; |
|
1910 #if defined(__USE_PURE_SCALING) |
|
1911 const TInt roundingFactor = 0; // set 0 to get pure scaling |
|
1912 #else |
|
1913 const TInt roundingFactor = (1 << absZoomFactor) - 1; |
|
1914 #endif |
|
1915 zoomedFrame.iTl.iX = (zoomedFrame.iTl.iX) >> absZoomFactor; |
|
1916 zoomedFrame.iTl.iY = (zoomedFrame.iTl.iY) >> absZoomFactor; |
|
1917 // zoomedFrame.iBr.iX = (zoomedFrame.iBr.iX + roundingFactor) >> absZoomFactor; |
|
1918 // zoomedFrame.iBr.iY = (zoomedFrame.iBr.iY + roundingFactor) >> absZoomFactor; |
|
1919 |
|
1920 zoomedSize.iWidth = (zoomedSize.iWidth + roundingFactor) >> absZoomFactor; |
|
1921 zoomedSize.iHeight = (zoomedSize.iHeight + roundingFactor) >> absZoomFactor; |
|
1922 |
|
1923 zoomedFrame.iBr = zoomedFrame.iTl + zoomedSize; |
|
1924 |
|
1925 zoomedOverallSize.iWidth = (zoomedOverallSize.iWidth + roundingFactor) >> absZoomFactor; |
|
1926 zoomedOverallSize.iHeight = (zoomedOverallSize.iHeight + roundingFactor) >> absZoomFactor; |
|
1927 } |
|
1928 |
|
1929 #if !defined(__CLEAR_BITMAPS_FIRST) |
|
1930 if (iFrame.SizeInPixels() != zoomedFrame.Size()) |
|
1931 #endif |
|
1932 { |
|
1933 #if defined(__CLEAR_BITMAPS_FIRST) |
|
1934 // resize via 0 so that we clear original |
|
1935 User::LeaveIfError(iFrame.Resize(TSize(0,0))); |
|
1936 #endif |
|
1937 User::LeaveIfError(iFrame.Resize(zoomedSize)); |
|
1938 } |
|
1939 } |
|
1940 |
|
1941 if (iMask.Handle()) |
|
1942 { |
|
1943 if (iMask.SizeInPixels() != zoomedFrame.Size()) |
|
1944 User::LeaveIfError(iMask.Resize(zoomedSize)); |
|
1945 #if defined(__CLEAR_BITMAPS_FIRST) |
|
1946 // set mask to black, so it is opaque and by default nothing is drawn |
|
1947 CFbsBitmapDevice* device = CFbsBitmapDevice::NewL(&iMask); |
|
1948 CleanupStack::PushL(device); |
|
1949 CFbsBitGc* bmGc = CFbsBitGc::NewL(); |
|
1950 CleanupStack::PushL(bmGc); |
|
1951 bmGc->Activate(device); |
|
1952 bmGc->SetPenStyle(CGraphicsContext::ENullPen); |
|
1953 bmGc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
1954 bmGc->SetBrushColor(KRgbBlack); |
|
1955 const TRect drawRect(TPoint(0,0), zoomedSize); |
|
1956 bmGc->DrawRect(drawRect); |
|
1957 CleanupStack::PopAndDestroy(2); |
|
1958 #endif |
|
1959 } |
|
1960 |
|
1961 iImageDisplaySize = zoomedSize; |
|
1962 iOffset = zoomedFrame.iTl; |
|
1963 |
|
1964 ASSERT(iMask.Handle()==0 || iFrame.SizeInPixels()==iMask.SizeInPixels()); // if mask must be same size |
|
1965 } |
|
1966 |
|
1967 void CVideoAppUi::ReplaceNewlinesWithLineBreaks(TDes& aText) |
|
1968 { |
|
1969 TInt pos=0; |
|
1970 |
|
1971 for (;;) |
|
1972 { |
|
1973 if (pos >= aText.Length()) // will occur if last character in comment is new line |
|
1974 break; |
|
1975 const TPtrC restOfText(aText.Mid(pos)); |
|
1976 TInt posOfNextNewLine = restOfText.Locate(TChar('\n')); |
|
1977 if (posOfNextNewLine<0) // no more new lines in text |
|
1978 break; |
|
1979 posOfNextNewLine += pos; // position relative to whole descriptor |
|
1980 aText[posOfNextNewLine] = CEditableText::ELineBreak; |
|
1981 pos = posOfNextNewLine + 1; // next cycle, start at next character |
|
1982 } |
|
1983 } |
|
1984 |
|
1985 // update crop region |
|
1986 void CVideoAppUi::UpdateClippingRect(TUint code) |
|
1987 { |
|
1988 TFrameInfo frameInfo; |
|
1989 if ( iLoadUtil ) |
|
1990 { |
|
1991 switch (code) |
|
1992 { |
|
1993 case EKeyLeftArrow: |
|
1994 iClippingRect.Move(-Min(iClippingRect.Width(),iClippingRect.iTl.iX),0); |
|
1995 break; |
|
1996 case EKeyRightArrow: |
|
1997 { |
|
1998 const TFrameInfo& frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
1999 iClippingRect.Move(Min(iClippingRect.Width(),frameInfo.iOverallSizeInPixels.iWidth-iClippingRect.iBr.iX),0); |
|
2000 } |
|
2001 break; |
|
2002 case EKeyUpArrow: |
|
2003 iClippingRect.Move(0,-Min(iClippingRect.Height(),iClippingRect.iTl.iY)); |
|
2004 break; |
|
2005 case EKeyDownArrow: |
|
2006 { |
|
2007 const TFrameInfo& frameInfo = iLoadUtil->FrameInfo(iFrameNumber); |
|
2008 iClippingRect.Move(0,Min(iClippingRect.Height(),frameInfo.iOverallSizeInPixels.iHeight-iClippingRect.iBr.iY)); |
|
2009 } |
|
2010 break; |
|
2011 } |
|
2012 } |
|
2013 LoadFileL(); |
|
2014 } |
|
2015 // |
|
2016 // CVideoAppView |
|
2017 // |
|
2018 |
|
2019 CVideoAppView* CVideoAppView::NewL(const TRect& aRect) |
|
2020 { |
|
2021 CVideoAppView* self = new (ELeave) CVideoAppView; |
|
2022 CleanupStack::PushL(self); |
|
2023 self->ConstructL(aRect); |
|
2024 CleanupStack::Pop(); |
|
2025 return self; |
|
2026 } |
|
2027 |
|
2028 CVideoAppView::CVideoAppView(): |
|
2029 CCoeControl() |
|
2030 {} |
|
2031 |
|
2032 void CVideoAppView::ConstructL(const TRect& /*aRect*/) |
|
2033 { |
|
2034 CreateWindowL(); |
|
2035 #if defined(__WINS__) |
|
2036 Window().SetRequiredDisplayMode(SystemGc().Device()->DisplayMode()); |
|
2037 #endif |
|
2038 iDisplayMode = Window().DisplayMode(); |
|
2039 EnableDragEvents(); |
|
2040 SetExtentToWholeScreen(); |
|
2041 |
|
2042 iBmBuffer = new (ELeave) CWsBitmap(iCoeEnv->WsSession()); |
|
2043 ActivateL(); |
|
2044 } |
|
2045 |
|
2046 CVideoAppView::~CVideoAppView() |
|
2047 { |
|
2048 delete iBmGc; |
|
2049 delete iBmDevice; |
|
2050 delete iBmBuffer; |
|
2051 } |
|
2052 |
|
2053 void CVideoAppView::Draw(const TRect& aRect) const |
|
2054 { |
|
2055 CWindowGc& gc = SystemGc(); |
|
2056 TRect drawRect=Rect(); |
|
2057 |
|
2058 ASSERT(!iBitmapValid || iBmRect.Size() == iBmBuffer->SizeInPixels()); // either bitmap not valid or size of bmrect is same as the buffer |
|
2059 |
|
2060 if (iBitmapValid) |
|
2061 { |
|
2062 // if the required rect includes some background, then draw it |
|
2063 // check is to see if the passed aRect is a pure subset of the bitmap rect |
|
2064 TRect intersection(aRect); |
|
2065 intersection.Intersection(iBmRect); |
|
2066 if (intersection != aRect) |
|
2067 { |
|
2068 gc.SetPenStyle(CGraphicsContext::ENullPen); // solid background rect |
|
2069 gc.SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
2070 gc.SetBrushColor(KRgbWhite); |
|
2071 gc.DrawRect(drawRect); |
|
2072 TRect frame(iBmRect); // draw a frame one pixel larger than bitmap |
|
2073 frame.Grow(1,1); |
|
2074 gc.SetBrushStyle(CGraphicsContext::ENullBrush); |
|
2075 gc.SetPenStyle(CGraphicsContext::ESolidPen); |
|
2076 gc.DrawRect(frame); |
|
2077 } |
|
2078 // now if there is some bitmap to be drawn... |
|
2079 if (!intersection.IsEmpty()) |
|
2080 { |
|
2081 gc.BitBlt(iBmRect.iTl, iBmBuffer); |
|
2082 } |
|
2083 } |
|
2084 else |
|
2085 { |
|
2086 gc.Clear(); |
|
2087 drawRect.Shrink(10,10); |
|
2088 gc.DrawRect(drawRect); |
|
2089 gc.DrawLine(drawRect.iTl,drawRect.iBr); |
|
2090 gc.DrawLine(TPoint(drawRect.iTl.iX,drawRect.iBr.iY),TPoint(drawRect.iBr.iX,drawRect.iTl.iY)); |
|
2091 } |
|
2092 } |
|
2093 |
|
2094 void CVideoAppView::Reset(TDrawNow aDrawNow) |
|
2095 { |
|
2096 iBmBuffer->Reset(); |
|
2097 iBitmapValid = EFalse; |
|
2098 if (aDrawNow!=ENoDrawNow) |
|
2099 DrawNow(); |
|
2100 } |
|
2101 |
|
2102 void CVideoAppView::DrawImage(CFbsBitmap* aBitmap, const TPoint& aOffset, TDrawNow aDrawNow) |
|
2103 { |
|
2104 DrawImage(aBitmap, NULL, aOffset, aDrawNow); |
|
2105 } |
|
2106 |
|
2107 void CVideoAppView::DrawImage(CFbsBitmap* aBitmap, CFbsBitmap* aMask, const TPoint& aOffset, TDrawNow aDrawNow) |
|
2108 { |
|
2109 ASSERT(iBitmapValid && iBmBuffer->Handle()); // should only be called when size setup properly |
|
2110 ASSERT(aMask==NULL || aBitmap->SizeInPixels()==aMask->SizeInPixels()); |
|
2111 // if we have a mask, assumed to be the same size as the original |
|
2112 |
|
2113 const TPoint screenOffset = iBmRect.iTl + aOffset; // relative to screen instead of iBmRect |
|
2114 const TRect bitmapRect (screenOffset, aBitmap->SizeInPixels()); // the rect for this bitmap |
|
2115 |
|
2116 #if defined(_DEBUG) |
|
2117 TRect intersection (bitmapRect); // check that this rect is same or smaller than the bitmap |
|
2118 ASSERT(iBmRect.Size() == iBmBuffer->SizeInPixels()); |
|
2119 intersection.Intersection(iBmRect); |
|
2120 ASSERT(intersection==bitmapRect); |
|
2121 #endif |
|
2122 |
|
2123 // first draw to bitmap buffer |
|
2124 if (aMask) |
|
2125 iBmGc->BitBltMasked(aOffset, aBitmap, TRect(aBitmap->SizeInPixels()), aMask, EFalse); |
|
2126 else |
|
2127 iBmGc->BitBlt(aOffset, aBitmap); |
|
2128 |
|
2129 // if required, also draw to screen |
|
2130 if (aDrawNow!=ENoDrawNow) |
|
2131 { |
|
2132 ActivateGc(); |
|
2133 CWindowGc& gc = SystemGc(); |
|
2134 if (aMask) |
|
2135 gc.BitBltMasked(screenOffset, aBitmap, TRect(aBitmap->SizeInPixels()), aMask, EFalse); |
|
2136 else |
|
2137 gc.BitBlt(screenOffset, aBitmap); |
|
2138 DeactivateGc(); |
|
2139 } |
|
2140 } |
|
2141 |
|
2142 TBool CVideoAppView::ResizeL(const TSize& aNewSize, TBool aClear, TDrawNow aDrawNow) |
|
2143 { |
|
2144 //Resize iBmBuffer to iBmRect where iBmBuffer holds the aNewSize. |
|
2145 if(iBmRect.Size() != aNewSize) |
|
2146 { |
|
2147 iBmBuffer->Resize(iBmRect.Size()); |
|
2148 } |
|
2149 ASSERT(!iBitmapValid || iBmRect.Size() == iBmBuffer->SizeInPixels()); // either bitmap not valid or size of bmrect is same as the buffer |
|
2150 if (iBitmapValid && aNewSize==iBmRect.Size()) |
|
2151 { |
|
2152 // special cases where we don't actually modify the size |
|
2153 if (aDrawNow!=ENoDrawNow) |
|
2154 DrawNow(); |
|
2155 return EFalse; |
|
2156 } |
|
2157 |
|
2158 CFbsBitmap* tempBuffer = NULL; |
|
2159 |
|
2160 TBool preserveOrig = !aClear && iBitmapValid; |
|
2161 |
|
2162 if (preserveOrig) |
|
2163 { |
|
2164 // tempBuffer becomes copy of original |
|
2165 tempBuffer = new (ELeave) CWsBitmap(iCoeEnv->WsSession()); |
|
2166 CleanupStack::PushL(tempBuffer); |
|
2167 User::LeaveIfError(tempBuffer->Duplicate(iBmBuffer->Handle())); |
|
2168 } |
|
2169 |
|
2170 ResizeBufferL(aNewSize, iDisplayMode); |
|
2171 // resize bitmap |
|
2172 |
|
2173 iBitmapValid = ETrue; |
|
2174 iBmRect.SetRect(iBmRect.iTl, aNewSize); // rect with same Tl but new size |
|
2175 ASSERT(iBmRect.Size() == iBmBuffer->SizeInPixels()); // check resized bitmap OK |
|
2176 |
|
2177 if (preserveOrig) |
|
2178 { |
|
2179 // draw original back at new size |
|
2180 EnsureSizeInTwipsSet(tempBuffer); |
|
2181 EnsureSizeInTwipsSet(iBmBuffer); |
|
2182 iBmGc->DrawBitmap(TPoint(0,0), tempBuffer); |
|
2183 CleanupStack::PopAndDestroy(); // tempBuffer |
|
2184 } |
|
2185 else |
|
2186 Clear(EFalse, ENoDrawNow); // get background correct colour |
|
2187 |
|
2188 if (aDrawNow!=ENoDrawNow) |
|
2189 DrawNow(); |
|
2190 |
|
2191 return ETrue; |
|
2192 } |
|
2193 |
|
2194 void CVideoAppView::ResizeBufferL(const TSize& aNewSize, TDisplayMode aDisplayMode) |
|
2195 { |
|
2196 delete iBmGc; iBmGc = NULL; |
|
2197 delete iBmDevice; iBmDevice = NULL; |
|
2198 User::LeaveIfError(iBmBuffer->Create(aNewSize, aDisplayMode)); |
|
2199 iBmDevice = CFbsBitmapDevice::NewL(iBmBuffer); |
|
2200 iBmGc = CFbsBitGc::NewL(); |
|
2201 iBmGc->Activate(iBmDevice); |
|
2202 } |
|
2203 |
|
2204 void CVideoAppView::EnsureSizeInTwipsSet(CFbsBitmap* aBitmap) const |
|
2205 { |
|
2206 // ensure the bitmap has twips size set - this allows us to use DrawBitmap |
|
2207 // note this does not itself resize the bitmap - size in pixels remains unchanged |
|
2208 TSize size = aBitmap->SizeInTwips(); |
|
2209 ASSERT(size.iWidth==0 && size.iHeight==0 || size.iWidth>0 && size.iHeight>0); |
|
2210 // assumption that if we've set the size it is properly formatted |
|
2211 if (size==TSize(0,0)) |
|
2212 { |
|
2213 CWsScreenDevice *const screenDevice = iEikonEnv->ScreenDevice(); |
|
2214 size = aBitmap->SizeInPixels(); |
|
2215 size.iWidth = screenDevice->HorizontalTwipsToPixels(size.iWidth); |
|
2216 size.iHeight = screenDevice->VerticalTwipsToPixels(size.iHeight); |
|
2217 aBitmap->SetSizeInTwips(size); |
|
2218 } |
|
2219 } |
|
2220 |
|
2221 void CVideoAppView::Clear(TBool aClearFull, TDrawNow aDrawNow) |
|
2222 { |
|
2223 // if we have a bitmap buffer clear that. Otherwise clear the whole screen depending |
|
2224 // on aClearFull |
|
2225 if (iBmGc) |
|
2226 { |
|
2227 iBmGc->Reset(); |
|
2228 iBmGc->SetPenStyle(CGraphicsContext::ENullPen); |
|
2229 iBmGc->SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
2230 iBmGc->SetBrushColor(iBackgroundColor); |
|
2231 iBmGc->Clear(); |
|
2232 } |
|
2233 if (aDrawNow!=ENoDrawNow) |
|
2234 { |
|
2235 if (aClearFull) |
|
2236 DrawNow(); |
|
2237 else |
|
2238 { |
|
2239 ActivateGc(); |
|
2240 CWindowGc& gc = SystemGc(); |
|
2241 RWindow& window = Window(); |
|
2242 window.Invalidate(iBmRect); |
|
2243 window.BeginRedraw(iBmRect); |
|
2244 gc.SetPenStyle(CGraphicsContext::ENullPen); |
|
2245 gc.SetBrushStyle(CGraphicsContext::ESolidBrush); |
|
2246 gc.SetBrushColor(iBackgroundColor); |
|
2247 gc.Clear(); |
|
2248 window.EndRedraw(); |
|
2249 DeactivateGc(); |
|
2250 } |
|
2251 } |
|
2252 } |
|
2253 |
|
2254 |
|
2255 void CVideoAppView::MoveBy(const TPoint& aRelMove, TDrawNow aDrawNow) |
|
2256 { |
|
2257 iBmRect.Move(aRelMove); |
|
2258 |
|
2259 if (aDrawNow!=ENoDrawNow) |
|
2260 DrawNow(); |
|
2261 } |
|
2262 |
|
2263 void CVideoAppView::Center(TDrawNow aDrawNow) |
|
2264 { |
|
2265 ASSERT(iBitmapValid && iBmRect.Size() == iBmBuffer->SizeInPixels()); // should only be called when size setup properly |
|
2266 |
|
2267 #ifdef CENTRE_IMAGE |
|
2268 const TPoint center = Rect().Center(); |
|
2269 const TSize bitmapSize = iBmRect.Size(); |
|
2270 const TPoint requiredTl (center.iX-bitmapSize.iWidth/2, center.iY-bitmapSize.iHeight/2); |
|
2271 const TRect newRect(requiredTl, bitmapSize); |
|
2272 iBmRect = newRect; |
|
2273 #endif |
|
2274 |
|
2275 ASSERT(iBitmapValid && iBmRect.Size() == iBmBuffer->SizeInPixels()); // checked worked |
|
2276 |
|
2277 if (aDrawNow!=ENoDrawNow) |
|
2278 DrawNow(); |
|
2279 } |
|
2280 |
|
2281 TBool CVideoAppView::SetBackgroundColor(const TRgb& aColor, TDrawNow aDrawNow) |
|
2282 { |
|
2283 TBool changed = iBackgroundColor!=aColor; |
|
2284 |
|
2285 iBackgroundColor = aColor; |
|
2286 |
|
2287 if (aDrawNow!=ENoDrawNow) |
|
2288 DrawNow(); |
|
2289 |
|
2290 return changed; |
|
2291 } |
|
2292 |
|
2293 void CVideoAppView::SetDisplayModeL(TDisplayMode aDisplayMode, CWsBitmap* aFrame, TDrawNow aDrawNow) |
|
2294 { |
|
2295 |
|
2296 TBool change=aDisplayMode!=iDisplayMode; |
|
2297 |
|
2298 iDisplayMode = aDisplayMode; |
|
2299 |
|
2300 if (iBitmapValid && change) |
|
2301 { |
|
2302 ASSERT(iBmBuffer->Handle()); |
|
2303 |
|
2304 // temp buffer becomes copy of original |
|
2305 CFbsBitmap* tempBuffer = new (ELeave) CWsBitmap(iCoeEnv->WsSession()); |
|
2306 CleanupStack::PushL(tempBuffer); |
|
2307 User::LeaveIfError(tempBuffer->Duplicate(iBmBuffer->Handle())); |
|
2308 |
|
2309 ASSERT(iBmRect.Size()==iBmBuffer->SizeInPixels()); // should be the same |
|
2310 ResizeBufferL(iBmBuffer->SizeInPixels(), iDisplayMode); |
|
2311 // change bitmap |
|
2312 |
|
2313 // bitblt original back |
|
2314 iBmGc->BitBlt(TPoint(0,0), tempBuffer); |
|
2315 CleanupStack::PopAndDestroy(); // tempBuffer |
|
2316 |
|
2317 aFrame->Reset(); // reset the frame |
|
2318 aFrame->Duplicate(iBmBuffer->Handle()); // duplicate the aFrame bitmap handle |
|
2319 } |
|
2320 |
|
2321 Window().SetRequiredDisplayMode(iDisplayMode); |
|
2322 |
|
2323 if (aDrawNow!=ENoDrawNow) |
|
2324 DrawNow(); |
|
2325 } |
|
2326 |
|
2327 // |
|
2328 // CVideoDisplayModeDialog |
|
2329 // |
|
2330 |
|
2331 // list of supported display modes (it matches r_video_display_mode_array in TImageViewer.rss) |
|
2332 |
|
2333 const TDisplayMode KDispMode[] = { EGray2, EGray4, EGray16, EGray256, EColor16, EColor256, EColor4K, EColor64K, EColor16M, EColor16MU, EColor16MA, EColor16MAP }; |
|
2334 const TInt KNumDispMode = sizeof(KDispMode) / sizeof(KDispMode[0]); |
|
2335 |
|
2336 CVideoDisplayModeDialog::CVideoDisplayModeDialog(TDisplayMode& aDisplayMode,TBool& aUseNativeDisplayMode): |
|
2337 iDisplayMode(aDisplayMode), iUseNativeDisplayMode(aUseNativeDisplayMode) |
|
2338 {} |
|
2339 |
|
2340 void CVideoDisplayModeDialog::PreLayoutDynInitL() |
|
2341 { |
|
2342 TInt choice = -1; |
|
2343 |
|
2344 for (TInt index=0; index<KNumDispMode; index++) |
|
2345 { |
|
2346 if (KDispMode[index]==iDisplayMode) |
|
2347 { |
|
2348 choice = index; |
|
2349 break; |
|
2350 } |
|
2351 } |
|
2352 |
|
2353 SetCheckBoxState(EVideoIdUseImageNativeMode, iUseNativeDisplayMode ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2354 |
|
2355 ASSERT(choice>=0); // should always match something |
|
2356 SetChoiceListCurrentItem(EVideoIdDisplayMode,choice); |
|
2357 } |
|
2358 |
|
2359 TBool CVideoDisplayModeDialog::OkToExitL(TInt /*aButtonId*/) |
|
2360 { |
|
2361 const TInt chosenIndex = ChoiceListCurrentItem(EVideoIdDisplayMode); |
|
2362 ASSERT(chosenIndex<KNumDispMode); |
|
2363 iDisplayMode = KDispMode[chosenIndex]; |
|
2364 iUseNativeDisplayMode = CheckBoxState(EVideoIdUseImageNativeMode) == CEikButtonBase::ESet ? ETrue : EFalse; |
|
2365 return ETrue; |
|
2366 } |
|
2367 |
|
2368 // |
|
2369 // CVideoBackgroundColorDialog |
|
2370 // |
|
2371 |
|
2372 CVideoBackgroundColorDialog::CVideoBackgroundColorDialog(TInt& aColor16, TBool& aOverride): |
|
2373 iColor16(aColor16), iOverride(aOverride) |
|
2374 {} |
|
2375 |
|
2376 void CVideoBackgroundColorDialog::PreLayoutDynInitL() |
|
2377 { |
|
2378 CEikButtonBase::TState state = iOverride ? CEikButtonBase::ESet : CEikButtonBase::EClear; |
|
2379 SetCheckBoxState(EVideoIdOverrideBackgroundColor, state); |
|
2380 SetChoiceListCurrentItem(EVideoIdBackgroundColor,iColor16); |
|
2381 if (!iOverride) |
|
2382 SetLineDimmedNow(EVideoIdBackgroundColor,ETrue); |
|
2383 } |
|
2384 |
|
2385 TBool CVideoBackgroundColorDialog::OkToExitL(TInt /*aButtonId*/) |
|
2386 { |
|
2387 iColor16 = ChoiceListCurrentItem(EVideoIdBackgroundColor); |
|
2388 CEikButtonBase::TState state = CheckBoxState(EVideoIdOverrideBackgroundColor); |
|
2389 iOverride = state != CEikButtonBase::EClear; |
|
2390 return ETrue; |
|
2391 } |
|
2392 |
|
2393 void CVideoBackgroundColorDialog::HandleControlStateChangeL(TInt aControlId) |
|
2394 { |
|
2395 if (aControlId == EVideoIdOverrideBackgroundColor) |
|
2396 { |
|
2397 CEikButtonBase::TState state = CheckBoxState(EVideoIdOverrideBackgroundColor); |
|
2398 TBool isSet = state != CEikButtonBase::EClear; |
|
2399 SetLineDimmedNow(EVideoIdBackgroundColor,!isSet); |
|
2400 } |
|
2401 } |
|
2402 |
|
2403 // |
|
2404 // CVideoCurrentFrameDialog |
|
2405 // |
|
2406 |
|
2407 CVideoCurrentFrameDialog::CVideoCurrentFrameDialog(TInt& aCurrentFrame,TInt aNumberOfFrames): |
|
2408 iCurrentFrame(aCurrentFrame), |
|
2409 iNumberOfFrames(aNumberOfFrames) |
|
2410 {} |
|
2411 |
|
2412 void CVideoCurrentFrameDialog::PreLayoutDynInitL() |
|
2413 { |
|
2414 SetNumberEditorValue(EVideoIdNumberOfFrames,iNumberOfFrames); |
|
2415 SetLineDimmedNow(EVideoIdNumberOfFrames,ETrue); |
|
2416 const TInt lastFrame = iNumberOfFrames - 1; |
|
2417 SetNumberEditorMinAndMax(EVideoIdCurrentFrameNumber,0,lastFrame); |
|
2418 SetNumberEditorValue(EVideoIdCurrentFrameNumber,Min(iCurrentFrame,lastFrame)); |
|
2419 } |
|
2420 |
|
2421 TBool CVideoCurrentFrameDialog::OkToExitL(TInt /*aButtonId*/) |
|
2422 { |
|
2423 iCurrentFrame = NumberEditorValue(EVideoIdCurrentFrameNumber); |
|
2424 return ETrue; |
|
2425 } |
|
2426 |
|
2427 // |
|
2428 // CVideoSaveAsDialog |
|
2429 // |
|
2430 |
|
2431 CVideoSaveAsDialog::CVideoSaveAsDialog(TDes* aFileName,TFileSaveInfo& aSaveInfo,RArray<TInt>& aEncodeOperations,TBool& aCreateThumbnail,TBool& aSaveAsEXIF): |
|
2432 CEikFileSaveAsDialog(aFileName), |
|
2433 iSaveInfo(aSaveInfo), |
|
2434 iEncodeOperations(aEncodeOperations), |
|
2435 iCreateThumbnail(&aCreateThumbnail), |
|
2436 iSaveAsEXIF(&aSaveAsEXIF) |
|
2437 {} |
|
2438 |
|
2439 void CVideoSaveAsDialog::PreLayoutDynInitL() |
|
2440 { |
|
2441 SetTypeL(); |
|
2442 SetCheckBoxState(EVideoIdCreateThumbnailChbx, *iCreateThumbnail ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2443 SetCheckBoxState(EVideoIdSaveAsEXIFChbx, *iSaveAsEXIF ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2444 |
|
2445 CEikFileSaveAsDialog::PreLayoutDynInitL(); |
|
2446 } |
|
2447 |
|
2448 void CVideoSaveAsDialog::SetTypeL() |
|
2449 { |
|
2450 const TUid imageType = iSaveInfo.iImageTypeUid; |
|
2451 |
|
2452 if(imageType == KImageTypeBMPUid) |
|
2453 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_BMP); |
|
2454 else if(imageType == KImageTypeGIFUid) |
|
2455 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_GIF); |
|
2456 else if(imageType == KImageTypeJPGUid) |
|
2457 { |
|
2458 if ( *iSaveAsEXIF ) |
|
2459 { |
|
2460 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_EXIF); |
|
2461 } |
|
2462 else |
|
2463 { |
|
2464 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_JPEG); |
|
2465 } |
|
2466 } |
|
2467 else if(imageType == KImageTypeMBMUid) |
|
2468 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_MBM); |
|
2469 else if(imageType == KImageTypePNGUid) |
|
2470 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_PNG); |
|
2471 else |
|
2472 SetLabelL(EVideoIdSaveAsFormat,R_VIDEO_FILE_FORMAT_CUSTOM); |
|
2473 |
|
2474 } |
|
2475 |
|
2476 void CVideoSaveAsDialog::HandleControlStateChangeL(TInt aControlId) |
|
2477 { |
|
2478 if (aControlId == EVideoIdSaveAsEXIFChbx) |
|
2479 { |
|
2480 *iSaveAsEXIF = CheckBoxState(EVideoIdSaveAsEXIFChbx) == CEikButtonBase::ESet ? ETrue : EFalse; |
|
2481 SetTypeL(); |
|
2482 } |
|
2483 } |
|
2484 |
|
2485 TBool CVideoSaveAsDialog::OkToExitL(TInt aButtonId) |
|
2486 { |
|
2487 if (aButtonId == EVideoIdSaveAsFormat) |
|
2488 { |
|
2489 CEikDialog* dialog = new(ELeave) CVideoFormatDialog(iSaveInfo); |
|
2490 if (dialog->ExecuteLD(R_VIDEO_FILE_FORMAT_DIALOG)) |
|
2491 SetTypeL(); |
|
2492 |
|
2493 return EFalse; |
|
2494 } |
|
2495 else if (aButtonId == EVideoIdEncodeOperations) |
|
2496 { |
|
2497 CEikDialog* dialog = new(ELeave) CExtensionOptionsDialog(iEncodeOperations); |
|
2498 dialog->ExecuteLD(R_VIDEO_ENCODER_EXTENSION_DIALOG); |
|
2499 return EFalse; |
|
2500 } |
|
2501 else if (aButtonId == EEikBidOk) |
|
2502 { |
|
2503 *iCreateThumbnail = CheckBoxState(EVideoIdCreateThumbnailChbx) == CEikButtonBase::ESet ? ETrue : EFalse; |
|
2504 *iSaveAsEXIF = CheckBoxState(EVideoIdSaveAsEXIFChbx) == CEikButtonBase::ESet ? ETrue : EFalse; |
|
2505 } |
|
2506 |
|
2507 return CEikFileSaveAsDialog::OkToExitL(aButtonId); |
|
2508 } |
|
2509 |
|
2510 SEikControlInfo CVideoSaveAsDialog::CreateCustomControlL(TInt /*aControlType*/) |
|
2511 { |
|
2512 /* never called */ |
|
2513 SEikControlInfo info; |
|
2514 info.iTrailerTextId = 0; |
|
2515 info.iFlags = 0; |
|
2516 info.iControl = new (ELeave) CEikTextListBox; |
|
2517 return info; |
|
2518 } |
|
2519 // |
|
2520 // CVideoFormatDialog |
|
2521 // |
|
2522 |
|
2523 CVideoFormatDialog::CVideoFormatDialog(TFileSaveInfo& aSaveInfo): |
|
2524 iSaveInfo(aSaveInfo) |
|
2525 {} |
|
2526 |
|
2527 void CVideoFormatDialog::PreLayoutDynInitL() |
|
2528 { |
|
2529 CEikChoiceList* formatList = STATIC_CAST(CEikChoiceList*,Control(EVideoIdFileFormatType)); |
|
2530 |
|
2531 //Add the available encoders to the dialog |
|
2532 iEncoderList = CPluginInfoArray::NewL(); |
|
2533 formatList->SetArrayL(iEncoderList); //ownership of iEncoderList passed to dialog |
|
2534 |
|
2535 const TInt noOfEncoders = iEncoderList->MdcaCount(); |
|
2536 if(noOfEncoders == 0) |
|
2537 User::Leave(KErrNotFound); |
|
2538 |
|
2539 //Find the index for the selected encoder (via ImageTypeUid) |
|
2540 //if it is not found use the first |
|
2541 TInt index; |
|
2542 for(index=noOfEncoders-1; index > 0; index--) |
|
2543 { |
|
2544 if(iEncoderList->ImageType(index) == iSaveInfo.iImageTypeUid) |
|
2545 break; |
|
2546 } |
|
2547 iSaveInfo.iImageTypeUid = iEncoderList->ImageType(index); |
|
2548 |
|
2549 SetChoiceListCurrentItem(EVideoIdFileFormatType,index); |
|
2550 SetChoiceListCurrentItem(EVideoIdFileFormatBpp,iSaveInfo.iBpp); |
|
2551 SetChoiceListCurrentItem(EVideoIdFileFormatColor,iSaveInfo.iColor); |
|
2552 SetNumberEditorValue(EVideoIdFileFormatFactor,iSaveInfo.iQualityFactor); |
|
2553 SetChoiceListCurrentItem(EVideoIdFileFormatSampling,iSaveInfo.iSampling); |
|
2554 SetChoiceListCurrentItem(EVideoIdFileFormatCompression,iSaveInfo.iCompression); |
|
2555 |
|
2556 ValidateControlState(); |
|
2557 } |
|
2558 |
|
2559 void CVideoFormatDialog::HandleControlStateChangeL(TInt /*aControlId*/) |
|
2560 { |
|
2561 ValidateControlState(); |
|
2562 } |
|
2563 |
|
2564 void CVideoFormatDialog::ValidateControlState() |
|
2565 { |
|
2566 TInt type = ChoiceListCurrentItem(EVideoIdFileFormatType); |
|
2567 TInt bpp = ChoiceListCurrentItem(EVideoIdFileFormatBpp); |
|
2568 TInt color = ChoiceListCurrentItem(EVideoIdFileFormatColor); |
|
2569 TInt compression = ChoiceListCurrentItem(EVideoIdFileFormatCompression); |
|
2570 |
|
2571 TBool bppVisible = ETrue; |
|
2572 TBool colorVisible = ETrue; |
|
2573 TBool factorVisible = EFalse; |
|
2574 TBool samplingVisible = EFalse; |
|
2575 TBool compressionVisible = EFalse; |
|
2576 |
|
2577 |
|
2578 const TUid imageType = iEncoderList->ImageType(type); |
|
2579 |
|
2580 if(imageType == KImageTypeBMPUid) |
|
2581 { |
|
2582 colorVisible = EFalse; |
|
2583 if (bpp == 1) |
|
2584 bpp = 2; |
|
2585 else if ((bpp > 3) && (bpp < 6)) |
|
2586 bpp = 6; |
|
2587 else if (bpp > 6) |
|
2588 bpp = 0; |
|
2589 } |
|
2590 else if(imageType == KImageTypeGIFUid) |
|
2591 { |
|
2592 bppVisible = EFalse; |
|
2593 colorVisible = EFalse; |
|
2594 } |
|
2595 else if(imageType == KImageTypeJPGUid) |
|
2596 { |
|
2597 bppVisible = EFalse; |
|
2598 factorVisible = ETrue; |
|
2599 if (color) |
|
2600 samplingVisible = ETrue; |
|
2601 } |
|
2602 else if(imageType == KImageTypeMBMUid) |
|
2603 { |
|
2604 if (color == 0) |
|
2605 { |
|
2606 if (bpp > 3) |
|
2607 bpp = 0; |
|
2608 } |
|
2609 else |
|
2610 { |
|
2611 if (bpp < 2) |
|
2612 bpp = 2; |
|
2613 } |
|
2614 } |
|
2615 else if(imageType == KImageTypePNGUid) |
|
2616 { |
|
2617 if ((bpp > 3) && (bpp < 6)) |
|
2618 bpp = 6; |
|
2619 else if (bpp > 6) |
|
2620 bpp = 0; |
|
2621 compressionVisible = ETrue; |
|
2622 } |
|
2623 else //Custom encoder |
|
2624 { |
|
2625 bppVisible = EFalse; |
|
2626 colorVisible = EFalse; |
|
2627 } |
|
2628 |
|
2629 SetChoiceListCurrentItem(EVideoIdFileFormatBpp,bpp); |
|
2630 SetChoiceListCurrentItem(EVideoIdFileFormatColor,color); |
|
2631 SetChoiceListCurrentItem(EVideoIdFileFormatCompression,compression); |
|
2632 |
|
2633 MakeLineVisible(EVideoIdFileFormatBpp,bppVisible); |
|
2634 MakeLineVisible(EVideoIdFileFormatColor,colorVisible); |
|
2635 MakeLineVisible(EVideoIdFileFormatFactor,factorVisible); |
|
2636 MakeLineVisible(EVideoIdFileFormatSampling,samplingVisible); |
|
2637 MakeLineVisible(EVideoIdFileFormatCompression,compressionVisible); |
|
2638 } |
|
2639 |
|
2640 TBool CVideoFormatDialog::OkToExitL(TInt /*aButtonId*/) |
|
2641 { |
|
2642 TInt type = ChoiceListCurrentItem(EVideoIdFileFormatType); |
|
2643 iSaveInfo.iImageTypeUid = iEncoderList->ImageType(type); |
|
2644 iSaveInfo.iBpp = ChoiceListCurrentItem(EVideoIdFileFormatBpp); |
|
2645 iSaveInfo.iColor = ChoiceListCurrentItem(EVideoIdFileFormatColor); |
|
2646 iSaveInfo.iQualityFactor = NumberEditorValue(EVideoIdFileFormatFactor); |
|
2647 iSaveInfo.iSampling = ChoiceListCurrentItem(EVideoIdFileFormatSampling); |
|
2648 iSaveInfo.iCompression = ChoiceListCurrentItem(EVideoIdFileFormatCompression); |
|
2649 |
|
2650 return ETrue; |
|
2651 } |
|
2652 |
|
2653 CDecoderOptionsDialog::CDecoderOptionsDialog(TUint& aOptions):iOptions(aOptions) |
|
2654 { |
|
2655 } |
|
2656 |
|
2657 // from CEikDialog |
|
2658 void CDecoderOptionsDialog::PreLayoutDynInitL() |
|
2659 { |
|
2660 SetCheckBoxState(EVideoIdUseThreadForDecoder, iOptions&CImageDecoder::EOptionAlwaysThread ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2661 SetCheckBoxState(EVideoIdDecoderDisableDithering, iOptions&CImageDecoder::EOptionNoDither ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2662 SetCheckBoxState(EVideoIdDecoderAutogenMask, iOptions&CImageDecoder::EAllowGeneratedMask ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2663 SetCheckBoxState(EVideoIdDecodeHighSpeedDecode, iOptions&CImageDecoder::EPreferFastDecode ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2664 SetCheckBoxState(EVideoIdAutoRotateDecode, iOptions&CImageDecoder::EOptionAutoRotate ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2665 } |
|
2666 |
|
2667 TBool CDecoderOptionsDialog::OkToExitL(TInt /*aButtonId*/) |
|
2668 { |
|
2669 iOptions = CheckBoxState(EVideoIdUseThreadForDecoder) == CEikButtonBase::ESet ? CImageDecoder::EOptionAlwaysThread : 0; |
|
2670 iOptions|= CheckBoxState(EVideoIdDecoderDisableDithering) == CEikButtonBase::ESet ? CImageDecoder::EOptionNoDither : 0; |
|
2671 iOptions|= CheckBoxState(EVideoIdDecoderAutogenMask) == CEikButtonBase::ESet ? CImageDecoder::EAllowGeneratedMask : 0; |
|
2672 iOptions|= CheckBoxState(EVideoIdDecodeHighSpeedDecode) == CEikButtonBase::ESet ? CImageDecoder::EPreferFastDecode : 0; |
|
2673 iOptions|= CheckBoxState(EVideoIdAutoRotateDecode) == CEikButtonBase::ESet ? CImageDecoder::EOptionAutoRotate : 0; |
|
2674 |
|
2675 return ETrue; |
|
2676 } |
|
2677 |
|
2678 CExtensionOptionsDialog::CExtensionOptionsDialog(TRect& aClippingRect, |
|
2679 RArray<TInt>& aOperations, |
|
2680 TInt& aScalingCoefficient, |
|
2681 TImageConvScaler::TScalerQuality& aScalingQuality, |
|
2682 TBool& aLockAspectRatio) |
|
2683 : iClippingRect(&aClippingRect), iOperations(aOperations), iScalingCoefficient(&aScalingCoefficient), |
|
2684 iScalingQuality(&aScalingQuality), iLockAspectRatio(&aLockAspectRatio) |
|
2685 { |
|
2686 iSelectedOperations = new (ELeave) CDesCArrayFlat(20); |
|
2687 } |
|
2688 |
|
2689 CExtensionOptionsDialog::CExtensionOptionsDialog(RArray<TInt>& aOperations) |
|
2690 : iOperations(aOperations) |
|
2691 { |
|
2692 iSelectedOperations = new (ELeave) CDesCArrayFlat(20); |
|
2693 iOperationOnly = ETrue; |
|
2694 } |
|
2695 |
|
2696 void CExtensionOptionsDialog::PageChangedL(TInt /*aPageId*/) |
|
2697 { |
|
2698 // enable/disable add and clear buttons which are only enabled on Operation Page |
|
2699 // The lines below panic on teh Control call. Looks like a dialog button is not a control |
|
2700 // Control(EVideoIdAdd)->SetDimmed(aPageId != EDecoderExtensionOperationPage); |
|
2701 // Control(EVideoIdClear)->SetDimmed(aPageId != EDecoderExtensionOperationPage); |
|
2702 } |
|
2703 |
|
2704 // from CEikDialog |
|
2705 void CExtensionOptionsDialog::PreLayoutDynInitL() |
|
2706 { |
|
2707 if ( !iOperationOnly ) |
|
2708 { |
|
2709 // crop rect number edits |
|
2710 static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftX))->SetNumber(iClippingRect->iTl.iX); |
|
2711 static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftY))->SetNumber(iClippingRect->iTl.iY); |
|
2712 static_cast<CEikNumberEditor*>(Control(EVideoIdCropWidth))->SetNumber(iClippingRect->Width()); |
|
2713 static_cast<CEikNumberEditor*>(Control(EVideoIdCropHeight))->SetNumber(iClippingRect->Height()); |
|
2714 |
|
2715 /* scaling |
|
2716 coefficient number edit |
|
2717 quality choicelist |
|
2718 aspectratio checkbox |
|
2719 */ |
|
2720 static_cast<CEikNumberEditor*>(Control(EVideoIdScaleCoeff))->SetNumber(*iScalingCoefficient); |
|
2721 static_cast<CEikChoiceList*>(Control(EVideoIdScaleQuality))->SetCurrentItem(*iScalingQuality); |
|
2722 SetCheckBoxState(EVideoIdScalePreserveAspect, *iLockAspectRatio ? CEikButtonBase::ESet : CEikButtonBase::EClear); |
|
2723 } |
|
2724 |
|
2725 /* operations |
|
2726 fill selected operations |
|
2727 */ |
|
2728 CEikTextListBox* selectOpsListBox = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations)); |
|
2729 |
|
2730 selectOpsListBox->CreateScrollBarFrameL(); |
|
2731 selectOpsListBox->ScrollBarFrame()->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EOn); |
|
2732 |
|
2733 operationName[0] = _L("0x01 | ERotation90DegreesClockwise"); |
|
2734 operationName[1] = _L("0x02 | ERotation180DegreesClockwise"); |
|
2735 operationName[2] = _L("0x04 | ERotation270DegreesClockwise"); |
|
2736 operationName[3] = _L("0x08 | EMirrorHorizontalAxis"); |
|
2737 operationName[4] = _L("0x10 | EMirrorVerticalAxis"); |
|
2738 |
|
2739 for (TInt i = 0; i < iOperations.Count(); i++) |
|
2740 { |
|
2741 if ( iOperations[i] > 0 ) |
|
2742 { |
|
2743 TInt temp = iOperations[i]; |
|
2744 TInt shiftCount = 0; |
|
2745 while ( temp ) |
|
2746 { |
|
2747 temp = temp >> 1; |
|
2748 ++shiftCount; |
|
2749 } |
|
2750 iSelectedOperations->AppendL(operationName[shiftCount-1]); |
|
2751 } |
|
2752 } |
|
2753 |
|
2754 selectOpsListBox->Model()->SetItemTextArray(iSelectedOperations); |
|
2755 selectOpsListBox->Model()->SetOwnershipType(ELbmDoesNotOwnItemArray); |
|
2756 |
|
2757 } |
|
2758 |
|
2759 // DEF115967: Panic while editing Setup extensions Value |
|
2760 void CExtensionOptionsDialog::PrepareForFocusTransitionL() |
|
2761 { |
|
2762 // The dialog will check for blank input in the control that |
|
2763 // has been edited. If it is blank the value 9999...9 will be |
|
2764 // placed there to ensure control->Number() returns something. |
|
2765 // There appears to be no way of getting a different value put |
|
2766 // in a blank control (IsBlank function is protected). |
|
2767 |
|
2768 CEikDialog::PrepareForFocusTransitionL(); |
|
2769 } |
|
2770 |
|
2771 |
|
2772 SEikControlInfo CExtensionOptionsDialog::CreateCustomControlL(TInt /*aControlType*/) |
|
2773 { |
|
2774 /* never called */ |
|
2775 SEikControlInfo info; |
|
2776 info.iTrailerTextId = 0; |
|
2777 info.iFlags = 0; |
|
2778 info.iControl = new (ELeave) CEikTextListBox; |
|
2779 return info; |
|
2780 } |
|
2781 |
|
2782 TBool CExtensionOptionsDialog::OkToExitL(TInt aButtonId) |
|
2783 { |
|
2784 TBool exit = EFalse; |
|
2785 |
|
2786 switch ( aButtonId ) |
|
2787 { |
|
2788 case EEikBidOk: |
|
2789 { |
|
2790 if ( !iOperationOnly ) |
|
2791 { |
|
2792 // get crop rect |
|
2793 iClippingRect->iTl.iX = static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftX))->Number(); |
|
2794 iClippingRect->iTl.iY = static_cast<CEikNumberEditor*>(Control(EVideoIdCropTopLeftY))->Number(); |
|
2795 iClippingRect->SetWidth(static_cast<CEikNumberEditor*>(Control(EVideoIdCropWidth))->Number()); |
|
2796 iClippingRect->SetHeight(static_cast<CEikNumberEditor*>(Control(EVideoIdCropHeight))->Number()); |
|
2797 |
|
2798 // get scaling |
|
2799 *iScalingCoefficient = static_cast<CEikNumberEditor*>(Control(EVideoIdScaleCoeff))->Number(); |
|
2800 *iScalingQuality = static_cast<TImageConvScaler::TScalerQuality> |
|
2801 (static_cast<CEikChoiceList*>(Control(EVideoIdScaleQuality))->CurrentItem()); |
|
2802 *iLockAspectRatio = (CheckBoxState(EVideoIdScalePreserveAspect) == CEikButtonBase::ESet) ? ETrue : EFalse; |
|
2803 } |
|
2804 |
|
2805 // get operations |
|
2806 CTextListBoxModel * selectOpsModel = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations))->Model(); |
|
2807 iOperations.Reset(); |
|
2808 for (TInt i = 0; i < selectOpsModel->NumberOfItems(); i++) |
|
2809 { |
|
2810 TLex enumLex(selectOpsModel->ItemText(i).Mid(2,2)); // Hex value of enum |
|
2811 TUint operation = 0; |
|
2812 enumLex.Val(operation,EHex); |
|
2813 iOperations.Append(operation); |
|
2814 } |
|
2815 } |
|
2816 // deliberate fall through |
|
2817 case EEikBidCancel: |
|
2818 { |
|
2819 // iOperations fill up from iSeletedOperations |
|
2820 delete iSelectedOperations; |
|
2821 exit = ETrue; |
|
2822 } |
|
2823 break; |
|
2824 |
|
2825 case EVideoIdAdd: |
|
2826 { |
|
2827 TInt currentItem = static_cast<CEikChoiceList*>(Control(EVideoIdOperations))->CurrentItem(); |
|
2828 iSelectedOperations->AppendL(operationName[currentItem]); |
|
2829 CEikTextListBox* selectOpsListBox = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations)); |
|
2830 selectOpsListBox->Model()->SetItemTextArray(iSelectedOperations); |
|
2831 selectOpsListBox->HandleItemAdditionL(); |
|
2832 } |
|
2833 break; |
|
2834 |
|
2835 case EVideoIdClear: |
|
2836 { |
|
2837 iSelectedOperations->Reset(); |
|
2838 CEikTextListBox* selectOpsListBox = static_cast<CEikTextListBox*>(Control(EVideoIdSelectedOperations)); |
|
2839 selectOpsListBox->Model()->SetItemTextArray(iSelectedOperations); |
|
2840 selectOpsListBox->HandleItemAdditionL(); |
|
2841 } |
|
2842 break; |
|
2843 |
|
2844 default: |
|
2845 break; |
|
2846 } |
|
2847 |
|
2848 return exit; |
|
2849 } |
|
2850 |
|
2851 // |
|
2852 // CVideoWalker implementation |
|
2853 // |
|
2854 |
|
2855 CVideoWalker* CVideoWalker::NewL(CVideoAppUi* aAppUi) |
|
2856 { |
|
2857 CVideoWalker* result = new (ELeave) CVideoWalker(aAppUi); |
|
2858 return result; |
|
2859 } |
|
2860 |
|
2861 CVideoWalker::CVideoWalker(CVideoAppUi* aAppUi): |
|
2862 CActive(CActive::EPriorityStandard), |
|
2863 iAppUi(aAppUi) |
|
2864 { |
|
2865 CActiveScheduler::Add(this); |
|
2866 } |
|
2867 |
|
2868 CVideoWalker::~CVideoWalker() |
|
2869 { |
|
2870 Cancel(); |
|
2871 } |
|
2872 |
|
2873 // used when we need to pass status variable - simultaneously calls SetActive |
|
2874 TRequestStatus& CVideoWalker::ActiveStatus() |
|
2875 { |
|
2876 SetActive(); |
|
2877 return iStatus; |
|
2878 } |
|
2879 |
|
2880 // for completion ASAP on this |
|
2881 void CVideoWalker::SelfComplete(TInt aError) |
|
2882 { |
|
2883 TRequestStatus* status = &ActiveStatus(); |
|
2884 User::RequestComplete(status, aError); |
|
2885 } |
|
2886 |
|
2887 // calls AppUi->RunL() which is expected to handle the call |
|
2888 void CVideoWalker::RunL() |
|
2889 { |
|
2890 iAppUi->RunL(this, iStatus.Int()); |
|
2891 } |
|
2892 |
|
2893 // calls AppUi->DoCancel() which is expected to handle the call |
|
2894 void CVideoWalker::DoCancel() |
|
2895 { |
|
2896 iAppUi->DoCancel(this); |
|
2897 } |
|
2898 |
|
2899 // |
|
2900 // CVideoDocument |
|
2901 // |
|
2902 |
|
2903 CVideoDocument::CVideoDocument(CEikApplication& aApp) |
|
2904 : CEikDocument(aApp) |
|
2905 { |
|
2906 } |
|
2907 |
|
2908 CEikAppUi* CVideoDocument::CreateAppUiL() |
|
2909 { |
|
2910 return new(ELeave) CVideoAppUi; |
|
2911 } |
|
2912 |
|
2913 // |
|
2914 // CVideoApp |
|
2915 // |
|
2916 |
|
2917 TUid CVideoApp::AppDllUid() const |
|
2918 { |
|
2919 return KUidTVideo; |
|
2920 } |
|
2921 |
|
2922 CApaDocument* CVideoApp::CreateDocumentL() |
|
2923 { |
|
2924 return new(ELeave) CVideoDocument(*this); |
|
2925 } |
|
2926 |
|
2927 |
|
2928 // |
|
2929 // Base factory function |
|
2930 // |
|
2931 |
|
2932 #include <eikstart.h> |
|
2933 LOCAL_C CApaApplication* NewApplication() |
|
2934 { |
|
2935 return new CVideoApp; |
|
2936 } |
|
2937 |
|
2938 // |
|
2939 // EXE Entry point |
|
2940 // |
|
2941 |
|
2942 GLDEF_C TInt E32Main() |
|
2943 { |
|
2944 return EikStart::RunApplication(NewApplication); |
|
2945 } |
|
2946 |