18bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling/* 28bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * Copyright (C) 2011 The Android Open Source Project 38bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * 48bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * Licensed under the Apache License, Version 2.0 (the "License"); 58bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * you may not use this file except in compliance with the License. 68bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * You may obtain a copy of the License at 78bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * 88bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * http://www.apache.org/licenses/LICENSE-2.0 98bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * 108bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * Unless required by applicable law or agreed to in writing, software 118bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * distributed under the License is distributed on an "AS IS" BASIS, 128bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * See the License for the specific language governing permissions and 148bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling * limitations under the License. 158bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling */ 168bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 178bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling/////////////////////////////////////////////////// 188bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling// Mosaic.pp 198bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling// S.O. # : 208bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling// Author(s): zkira 218bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling// $Id: Mosaic.cpp,v 1.20 2011/06/24 04:22:14 mbansal Exp $ 228bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 238bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#include <stdio.h> 248bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#include <string.h> 258bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 268bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#include "Mosaic.h" 278bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#include "trsMatrix.h" 288bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 298bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#include "Log.h" 308bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling#define LOG_TAG "MOSAIC" 318bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 328bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingMosaic::Mosaic() 338bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 348bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling initialized = false; 358bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling imageMosaicYVU = NULL; 368bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames_size = 0; 378bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling max_frames = 200; 388bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 398bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 408bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingMosaic::~Mosaic() 418bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 428bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling for (int i = 0; i < frames_size; i++) 438bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 448bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (frames[i]) 458bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete frames[i]; 468bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 478bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete frames; 488bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete rframes; 498bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 508bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling for (int j = 0; j < owned_size; j++) 518bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete owned_frames[j]; 528bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete owned_frames; 538bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 548bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (aligner != NULL) 558bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete aligner; 568bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (blender != NULL) 578bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling delete blender; 588bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 598bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 608bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint Mosaic::initialize(int blendingType, int stripType, int width, int height, int nframes, bool quarter_res, float thresh_still) 618bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 628bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling this->blendingType = blendingType; 638bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 648bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // TODO: Review this logic if enabling FULL or PAN mode 658bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (blendingType == Blend::BLEND_TYPE_FULL || 668bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blendingType == Blend::BLEND_TYPE_PAN) 678bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 688bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling stripType = Blend::STRIP_TYPE_THIN; 698bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 708bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 718bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling this->stripType = stripType; 728bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling this->width = width; 738bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling this->height = height; 748bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 758bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 768bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling mosaicWidth = mosaicHeight = 0; 778bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling imageMosaicYVU = NULL; 788bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 798bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames = new MosaicFrame *[max_frames]; 808bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling rframes = new MosaicFrame *[max_frames]; 818bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 828bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if(nframes>-1) 838bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 848bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling for(int i=0; i<nframes; i++) 858bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 868bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames[i] = new MosaicFrame(this->width,this->height,false); // Do no allocate memory for YUV data 878bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 888bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 898bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling else 908bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 918bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling for(int i=0; i<max_frames; i++) 928bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 938bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames[i] = NULL; 948bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 958bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 968bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 978bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling owned_frames = new ImageType[max_frames]; 988bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling owned_size = 0; 998bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1008bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling LOGV("Initialize %d %d", width, height); 1018bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling LOGV("Frame width %d,%d", width, height); 1028bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling LOGV("Max num frames %d", max_frames); 1038bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1048bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling aligner = new Align(); 1058bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling aligner->initialize(width, height,quarter_res,thresh_still); 1068bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1078bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (blendingType == Blend::BLEND_TYPE_FULL || 1088bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blendingType == Blend::BLEND_TYPE_PAN || 1098bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blendingType == Blend::BLEND_TYPE_CYLPAN || 1108bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blendingType == Blend::BLEND_TYPE_HORZ) { 1118bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blender = new Blend(); 1128bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blender->initialize(blendingType, stripType, width, height); 1138bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } else { 1148bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling blender = NULL; 1158bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling LOGE("Error: Unknown blending type %d",blendingType); 1168bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return MOSAIC_RET_ERROR; 1178bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 1188bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1198bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling initialized = true; 1208bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1218bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return MOSAIC_RET_OK; 1228bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 1238bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1248bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint Mosaic::addFrameRGB(ImageType imageRGB) 1258bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 1268bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ImageType imageYVU; 1278bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Convert to YVU24 which is used by blending 1288bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling imageYVU = ImageUtils::allocateImage(this->width, this->height, ImageUtils::IMAGE_TYPE_NUM_CHANNELS); 1298bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ImageUtils::rgb2yvu(imageYVU, imageRGB, width, height); 1308bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1318bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling int existing_frames_size = frames_size; 1328bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling int ret = addFrame(imageYVU); 1338bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1348bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (frames_size > existing_frames_size) 1358bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling owned_frames[owned_size++] = imageYVU; 1368bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling else 1378bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ImageUtils::freeImage(imageYVU); 1388bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1398bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return ret; 1408bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 1418bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1428bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint Mosaic::addFrame(ImageType imageYVU) 1438bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 1448bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if(frames[frames_size]==NULL) 1458bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames[frames_size] = new MosaicFrame(this->width,this->height,false); 1468bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1478bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling MosaicFrame *frame = frames[frames_size]; 1488bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1498bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frame->image = imageYVU; 1508bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1518bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Add frame to aligner 1528bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling int ret = MOSAIC_RET_ERROR; 1538bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (aligner != NULL) 1548bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 1558bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Note aligner takes in RGB images 1568bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling int align_flag = Align::ALIGN_RET_OK; 1578bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling align_flag = aligner->addFrame(frame->image); 1588bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling aligner->getLastTRS(frame->trs); 1598bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1608bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (frames_size >= max_frames) 1618bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 1628bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling LOGV("WARNING: More frames than preallocated, ignoring." 1638bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling "Increase maximum number of frames (-f <max_frames>) to avoid this"); 1648bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return MOSAIC_RET_ERROR; 1658bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 1668bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1678bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling switch (align_flag) 1688bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 1698bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Align::ALIGN_RET_OK: 1708bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames_size++; 1718bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_OK; 1728bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 1738bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Align::ALIGN_RET_FEW_INLIERS: 1748bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames_size++; 1758bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_FEW_INLIERS; 1768bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 1778bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Align::ALIGN_RET_LOW_TEXTURE: 1788bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_LOW_TEXTURE; 1798bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 1808bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Align::ALIGN_RET_ERROR: 1818bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_ERROR; 1828bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 1838bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling default: 1848bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 1858bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 1868bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 1878bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1888bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return ret; 1898bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 1908bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1918bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 1928bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint Mosaic::createMosaic(float &progress, bool &cancelComputation) 1938bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 1948bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (frames_size <= 0) 1958bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 1968bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Haven't accepted any frame in aligner. No need to do blending. 1978bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling progress = TIME_PERCENT_ALIGN + TIME_PERCENT_BLEND 1988bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling + TIME_PERCENT_FINAL; 1998bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return MOSAIC_RET_OK; 2008bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 2018bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2028bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (blendingType == Blend::BLEND_TYPE_PAN) 2038bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 2048bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2058bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling balanceRotations(); 2068bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2078bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 2088bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2098bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling int ret = Blend::BLEND_RET_ERROR; 2108bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2118bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Blend the mosaic (alignment has already been done) 2128bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling if (blender != NULL) 2138bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 2148bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = blender->runBlend((MosaicFrame **) frames, (MosaicFrame **) rframes, 2158bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling frames_size, imageMosaicYVU, 2168bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling mosaicWidth, mosaicHeight, progress, cancelComputation); 2178bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 2188bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2198bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling switch(ret) 2208bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 2218bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Blend::BLEND_RET_ERROR: 2228bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Blend::BLEND_RET_ERROR_MEMORY: 2238bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_ERROR; 2248bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 2258bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Blend::BLEND_RET_CANCELLED: 2268bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_CANCELLED; 2278bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling break; 2288bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling case Blend::BLEND_RET_OK: 2298bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling ret = MOSAIC_RET_OK; 2308bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 2318bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return ret; 2328bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 2338bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2348bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha HaeberlingImageType Mosaic::getMosaic(int &width, int &height) 2358bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 2368bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling width = mosaicWidth; 2378bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling height = mosaicHeight; 2388bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2398bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return imageMosaicYVU; 2408bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 2418bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2428bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2438bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2448bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberlingint Mosaic::balanceRotations() 2458bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling{ 2468bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Normalize to the mean angle of rotation (Smiley face) 2478bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling double sineAngle = 0.0; 2488bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2498bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling for (int i = 0; i < frames_size; i++) sineAngle += frames[i]->trs[0][1]; 2508bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling sineAngle /= frames_size; 2518bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling // Calculate the cosineAngle (1 - sineAngle*sineAngle) = cosineAngle*cosineAngle 2528bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling double cosineAngle = sqrt(1.0 - sineAngle*sineAngle); 2538bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling double m[3][3] = { 2548bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { cosineAngle, -sineAngle, 0 }, 2558bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { sineAngle, cosineAngle, 0}, 2568bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling { 0, 0, 1}}; 2578bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling double tmp[3][3]; 2588bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2598bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling for (int i = 0; i < frames_size; i++) { 2608bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling memcpy(tmp, frames[i]->trs, sizeof(tmp)); 2618bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling mult33d(frames[i]->trs, m, tmp); 2628bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling } 2638bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling 2648bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling return MOSAIC_RET_OK; 2658bddf8ce4f3dcbb56edb12cee7e93f3a9daa3f96Sascha Haeberling} 266