camerauis/cameraxui/cxengine/src/cxesnapshotcontrolprivate.cpp
changeset 37 64817133cd1d
parent 29 699651f2666f
equal deleted inserted replaced
36:b12f3922a74f 37:64817133cd1d
    37 
    37 
    38 namespace
    38 namespace
    39 {
    39 {
    40     const int MAINTAIN_ASPECT = false;
    40     const int MAINTAIN_ASPECT = false;
    41 
    41 
       
    42     const QSize ASPECT_RATIO_SIZE_4BY3  = QSize(4,3);
       
    43     const QSize ASPECT_RATIO_SIZE_16BY9 = QSize(16, 9);
       
    44     const QSize ASPECT_RATIO_SIZE_11BY9 = QSize(11, 9);
       
    45 
    42 #ifdef Q_OS_SYMBIAN
    46 #ifdef Q_OS_SYMBIAN
    43     /*!
    47     /*!
    44     * Helper class for cleaning up MCameraBuffer instances.
    48     * Helper class for cleaning up MCameraBuffer instances.
    45     */
    49     */
    46     class CxeCameraBufferCleanup
    50     class CxeCameraBufferCleanup
   129 }
   133 }
   130 
   134 
   131 /*!
   135 /*!
   132 * Calculate snapshot size based on diplay size and image / video output resolution.
   136 * Calculate snapshot size based on diplay size and image / video output resolution.
   133 * @param displaySize Display size in pixels.
   137 * @param displaySize Display size in pixels.
   134 * @param outputResolution Resolution of the output image / video in pixels.
   138 * @param Cxe::AspectRatio Aspect ratio of image/video resolution.
   135 * @return Proposed best snapshot size.
   139 * @return Proposed best snapshot size.
   136 */
   140 */
   137 QSize CxeSnapshotControlPrivate::calculateSnapshotSize(const QSize &displaySize, const QSize &outputResolution) const
   141 
   138 {
   142 QSize CxeSnapshotControlPrivate::calculateSnapshotSize(const QSize& displaySize, Cxe::AspectRatio aspectRatio) const
   139     CX_DEBUG_ENTER_FUNCTION();
   143 {
   140     CX_DEBUG(("CxeSnapshotControlPrivate - output resolution (%d,%d)", outputResolution.width(), outputResolution.height()));
   144     CX_DEBUG_ENTER_FUNCTION();
   141     CX_DEBUG(("CxeSnapshotControlPrivate - display size      (%d,%d)", displaySize.width(), displaySize.height()));
   145     CX_DEBUG(("CxeSnapshotControlPrivate - display size      (%d,%d)", displaySize.width(), displaySize.height()));
   142 
   146 
   143     // Take resolution as reference for aspect ratio.
   147     // Take resolution as reference for aspect ratio.
   144     // Scale keeping aspect ratio to just fit display.
   148     // Scale keeping aspect ratio to just fit display.
   145     QSize size(outputResolution);
   149     QSize size;
       
   150     
       
   151     if (aspectRatio == Cxe::AspectRatio4to3) {
       
   152         size = ASPECT_RATIO_SIZE_4BY3;
       
   153     } else if (aspectRatio == Cxe::AspectRatio16to9) {
       
   154         size = ASPECT_RATIO_SIZE_16BY9;
       
   155     } else if (aspectRatio == Cxe::AspectRatio11to9) {
       
   156         size = ASPECT_RATIO_SIZE_11BY9;
       
   157     }
   146     size.scale(displaySize, Qt::KeepAspectRatio);
   158     size.scale(displaySize, Qt::KeepAspectRatio);
   147     CX_DEBUG(("CxeSnapshotControlPrivate - calculated size, (%d,%d)", size.width(), size.height()));
   159 
   148     size.setHeight(displaySize.height());
       
   149     CX_DEBUG(("CxeSnapshotControlPrivate - adjusted final size, (%d,%d)", size.width(), size.height()));
   160     CX_DEBUG(("CxeSnapshotControlPrivate - adjusted final size, (%d,%d)", size.width(), size.height()));
   150     CX_DEBUG_EXIT_FUNCTION();
   161 
       
   162     CX_DEBUG_EXIT_FUNCTION();
       
   163 
   151     return size;
   164     return size;
   152 }
   165 }
       
   166 
   153 
   167 
   154 /*!
   168 /*!
   155 * Start getting snapshots from camera.
   169 * Start getting snapshots from camera.
   156 * Throws CxeException with CxeError::Id if error encountered.
   170 * Throws CxeException with CxeError::Id if error encountered.
   157 * @param size Size of the snapshot in pixels.
   171 * @param size Size of the snapshot in pixels.
   203 }
   217 }
   204 
   218 
   205 /*!
   219 /*!
   206 * Helper method for getting the snapshot.
   220 * Helper method for getting the snapshot.
   207 * Throws exception if fetching the snapshot fails.
   221 * Throws exception if fetching the snapshot fails.
   208 * @return QPixmap containing the snapshot.
   222 * @return QImage containing the snapshot.
   209 */
   223 */
   210 QPixmap CxeSnapshotControlPrivate::snapshot()
   224 QImage CxeSnapshotControlPrivate::snapshot()
   211 {
   225 {
   212     CX_DEBUG_ENTER_FUNCTION();
   226     CX_DEBUG_ENTER_FUNCTION();
   213     QPixmap pixmap;
   227     QImage image;
   214 
   228 
   215 #ifdef Q_OS_SYMBIAN
   229     #ifdef Q_OS_SYMBIAN
   216     TRAPD(status, {
   230 
   217         RArray<TInt> frameIndex;
   231         CFbsBitmap *snapshot = NULL;
   218         CleanupClosePushL(frameIndex);
   232         TRAPD(status, {
   219 
   233             RArray<TInt> frameIndex;
   220         MCameraBuffer &buffer(mDevice.cameraSnapshot()->SnapshotDataL(frameIndex));
   234             CleanupClosePushL(frameIndex);
   221         // Make sure buffer is released on leave / exception.
   235 
   222         // Buffer is released once the cleanup item goes out of scope.
   236             MCameraBuffer &buffer(mDevice.cameraSnapshot()->SnapshotDataL(frameIndex));
   223         CxeCameraBufferCleanup cleaner(&buffer);
   237             // Make sure buffer is released on leave / exception.
   224 
   238             // Buffer is released once the cleanup item goes out of scope.
   225         TInt firstImageIndex(frameIndex.Find(0));
   239             CxeCameraBufferCleanup cleaner(&buffer);
   226         CFbsBitmap &snapshot(buffer.BitmapL(firstImageIndex));
   240 
   227 
   241             TInt firstImageIndex(frameIndex.Find(0));
   228         CleanupStack::PopAndDestroy(); // frameIndex
   242             snapshot = &buffer.BitmapL(firstImageIndex);
   229 
   243 
   230         TSize size = snapshot.SizeInPixels();
   244             CleanupStack::PopAndDestroy(); // frameIndex
   231         TInt sizeInWords = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU) / sizeof(TUint32);
   245 
   232         CX_DEBUG(("size %d x %d, sizeInWords = %d", size.iWidth, size.iHeight, sizeInWords ));
   246             TSize size = snapshot->SizeInPixels();
   233 
   247             TInt sizeInWords = size.iHeight * CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU) / sizeof(TUint32);
   234         TUint32 *pixelData = new (ELeave) TUint32[ sizeInWords ];
   248             CX_DEBUG(("size %d x %d, sizeInWords = %d", size.iWidth, size.iHeight, sizeInWords ));
   235         // Convert to QImage
   249 
   236         snapshot.LockHeap();
   250             CX_DEBUG(("Creating QImage"));
   237         TUint32 *dataPtr = snapshot.DataAddress();
   251             image = QImage(size.iWidth, size.iHeight, QImage::Format_RGB32);
   238         memcpy(pixelData, dataPtr, sizeof(TUint32)*sizeInWords);
   252 
   239         snapshot.UnlockHeap();
   253             // Convert to QImage
   240 
   254             snapshot->LockHeap();
   241         CX_DEBUG(("Creating QImage"));
   255             const uchar *dataPtr = (const uchar*) snapshot->DataAddress();
   242         QImage *snapImage = new QImage((uchar*)pixelData, size.iWidth, size.iHeight,
   256             uchar *dst = image.bits();
   243                                        CFbsBitmap::ScanLineLength(size.iWidth, EColor16MU),
   257             memcpy(dst, dataPtr, image.numBytes());
   244                                        QImage::Format_RGB32);
   258             snapshot->UnlockHeap();
   245 
   259 
   246         pixmap = QPixmap::fromImage(*snapImage);
   260         });
   247         delete [] pixelData;
   261         // We throw error with the Symbian error code if there was problems.
   248         delete snapImage;
   262         CxeException::throwIfError(status);
   249     });
   263 
   250     // We throw error with the Symbian error code if there was problems.
   264 
   251     CxeException::throwIfError(status);
   265     #endif // Q_OS_SYMBIAN
   252 #endif // Q_OS_SYMBIAN
   266 
   253 
   267         CX_DEBUG_EXIT_FUNCTION();
   254     CX_DEBUG_EXIT_FUNCTION();
   268         return image;
   255     return pixmap;
       
   256 }
   269 }
   257 
   270 
   258 /*!
   271 /*!
   259 * Handle camera snapshot events.
   272 * Handle camera snapshot events.
   260 * @param id Event uid.
   273 * @param id Event uid.
   266 
   279 
   267     // Ignoring all events if not active.
   280     // Ignoring all events if not active.
   268     if (state() == CxeSnapshotControl::Active) {
   281     if (state() == CxeSnapshotControl::Active) {
   269 #ifdef Q_OS_SYMBIAN
   282 #ifdef Q_OS_SYMBIAN
   270         if (id == KUidECamEventSnapshotUidValue) {
   283         if (id == KUidECamEventSnapshotUidValue) {
   271             QPixmap ss;
   284             QImage ss;
   272 
   285 
   273             if (!error) {
   286             if (!error) {
   274                 try {
   287                 try {
   275                     ss = snapshot();
   288                     ss = snapshot();
   276                 } catch (const CxeException& e) {
   289                 } catch (const CxeException& e) {