#include "stopmotion.h" #ifdef WIN32 #include #include #include #include #pragma comment(lib, "Mfplat.lib") #pragma comment(lib, "Mf.lib") #pragma comment(lib, "Mfreadwrite.lib") #pragma comment(lib, "mfuuid.lib") #pragma comment(lib, "shlwapi.lib") #endif // TnzCore includes #include "menubarcommandids.h" #include "tapp.h" #include "tenv.h" #include "tsystem.h" #include "filebrowsermodel.h" #include "penciltestpopup.h" #include "tlevel_io.h" #include "toutputproperties.h" #include "toonz/namebuilder.h" #include "toonz/preferences.h" #include "toonz/tcamera.h" #include "toonz/tcolumnhandle.h" #include "toonz/tframehandle.h" #include "toonz/levelset.h" #include "toonz/sceneproperties.h" #include "toonz/toonzscene.h" #include "toonz/tscenehandle.h" #include "toonz/stage.h" #include "toonz/txsheethandle.h" #include "toonz/txshlevelhandle.h" #include "toonz/txshsimplelevel.h" #include "toonz/levelproperties.h" #include "toonz/tstageobjecttree.h" #include "toonzqt/menubarcommand.h" #include #include #include #include #include #include #include #include #include // Connected camera TEnv::IntVar StopMotionUseScaledImages("StopMotionUseScaledImages", 0); TEnv::IntVar StopMotionOpacity("StopMotionOpacity", 100); TEnv::IntVar StopMotionUseDirectShow("StopMotionUseDirectShow", 1); TEnv::IntVar StopMotionAlwaysLiveView("StopMotionAlwaysLiveView", 0); TEnv::IntVar StopMotionBlackCapture("StopMotionBlackCapture", 0); TEnv::IntVar StopMotionPlaceOnXSheet("StopMotionPlaceOnXSheet", 1); TEnv::IntVar StopMotionReviewTime("StopMotionReviewTime", 1); TEnv::IntVar StopMotionUseMjpg("StopMotionUseMjpg", 1); TEnv::IntVar StopMotionUseNumpad("StopMotionUseNumpad", 0); // Connected camera TEnv::StringVar StopMotionCameraName("CamCapCameraName", ""); // Camera resolution TEnv::StringVar StopMotionCameraResolution("CamCapCameraResolution", ""); namespace { bool l_quitLoop = false; TPointD getCurrentCameraDpi() { TCamera *camera = TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); TDimensionD size = camera->getSize(); TDimension res = camera->getRes(); return TPointD(res.lx / size.lx, res.ly / size.ly); } //----------------------------------------------------------------------------- bool findCell(TXsheet *xsh, int col, const TXshCell &targetCell, int &bottomRowWithTheSameLevel) { bottomRowWithTheSameLevel = -1; TXshColumnP column = const_cast(xsh)->getColumn(col); if (!column) return false; TXshCellColumn *cellColumn = column->getCellColumn(); if (!cellColumn) return false; int r0, r1; if (!cellColumn->getRange(r0, r1)) return false; for (int r = r0; r <= r1; r++) { TXshCell cell = cellColumn->getCell(r); if (cell == targetCell) { bottomRowWithTheSameLevel = r; return true; } if (cell.m_level == targetCell.m_level) bottomRowWithTheSameLevel = r; } return false; } //----------------------------------------------------------------------------- QChar numToLetter(int letterNum) { switch (letterNum) { case 0: return QChar(); break; case 1: return 'A'; break; case 2: return 'B'; break; case 3: return 'C'; break; case 4: return 'D'; break; case 5: return 'E'; break; case 6: return 'F'; break; case 7: return 'G'; break; case 8: return 'H'; break; case 9: return 'I'; break; default: return QChar(); break; } } //----------------------------------------------------------------------------- QString convertToFrameWithLetter(int value, int length = -1) { QString str; str.setNum((int)(value / 10)); while (str.length() < length) str.push_front("0"); QChar letter = numToLetter(value % 10); if (!letter.isNull()) str.append(letter); return str; } //----------------------------------------------------------------------------- QString fidsToString(const std::vector &fids, bool letterOptionEnabled) { if (fids.empty()) return StopMotion::tr("No", "frame id"); QString retStr(""); if (letterOptionEnabled) { bool beginBlock = true; for (int f = 0; f < fids.size() - 1; f++) { int num = fids[f].getNumber(); int next_num = fids[f + 1].getNumber(); if (num % 10 == 0 && num + 10 == next_num) { if (beginBlock) { retStr += convertToFrameWithLetter(num) + " - "; beginBlock = false; } } else { retStr += convertToFrameWithLetter(num) + ", "; beginBlock = true; } } retStr += convertToFrameWithLetter(fids.back().getNumber()); } else { bool beginBlock = true; for (int f = 0; f < fids.size() - 1; f++) { int num = fids[f].getNumber(); int next_num = fids[f + 1].getNumber(); if (num + 1 == next_num) { if (beginBlock) { retStr += QString::number(num) + " - "; beginBlock = false; } } else { retStr += QString::number(num) + ", "; beginBlock = true; } } retStr += QString::number(fids.back().getNumber()); } return retStr; } //----------------------------------------------------------------------------- bool getRasterLevelSize(TXshLevel *level, TDimension &dim) { std::vector fids; level->getFids(fids); if (fids.empty()) return false; TXshSimpleLevel *simpleLevel = level->getSimpleLevel(); if (!simpleLevel) return false; TRasterImageP rimg = (TRasterImageP)simpleLevel->getFrame(fids[0], false); if (!rimg || rimg->isEmpty()) return false; dim = rimg->getRaster()->getSize(); return true; } }; // namespace //============================================================================= //============================================================================= JpgConverter::JpgConverter() {} JpgConverter::~JpgConverter() {} void JpgConverter::setStream(EdsStreamRef stream) { m_stream = stream; } void JpgConverter::convertFromJpg() { unsigned __int64 mySize = 0; unsigned char *data = NULL; EdsError err = EdsGetPointer(m_stream, (EdsVoid **)&data); err = EdsGetLength(m_stream, &mySize); int width, height, pixelFormat; int inSubsamp, inColorspace; tjhandle tjInstance = NULL; unsigned char *imgBuf = NULL; tjInstance = tjInitDecompress(); tjDecompressHeader3(tjInstance, data, mySize, &width, &height, &inSubsamp, &inColorspace); if (width < 0 || height < 0) { emit(imageReady(false)); return; } pixelFormat = TJPF_BGRX; imgBuf = (unsigned char *)tjAlloc(width * height * tjPixelSize[pixelFormat]); int flags = 0; #ifdef WIN32 flags |= TJFLAG_BOTTOMUP; #endif int factorsNum; tjscalingfactor scalingFactor = {1, 1}; tjscalingfactor *factor = tjGetScalingFactors(&factorsNum); int i = 0; int tempWidth, tempHeight; while (i < factorsNum) { scalingFactor = factor[i]; i++; tempWidth = TJSCALED(width, scalingFactor); tempHeight = TJSCALED(height, scalingFactor); } tjDecompress2(tjInstance, data, mySize, imgBuf, width, width * tjPixelSize[pixelFormat], height, pixelFormat, flags); m_finalImage = TRaster32P(width, height); m_finalImage->lock(); uchar *rawData = m_finalImage->getRawData(); memcpy(rawData, imgBuf, width * height * tjPixelSize[pixelFormat]); m_finalImage->unlock(); tjFree(imgBuf); imgBuf = NULL; tjDestroy(tjInstance); tjInstance = NULL; if (m_stream != NULL) { EdsRelease(m_stream); m_stream = NULL; } data = NULL; emit(imageReady(true)); } void JpgConverter::run() { convertFromJpg(); } //----------------------------------------------------------------------------- StopMotion::StopMotion() { m_opacity = StopMotionOpacity; m_useScaledImages = StopMotionUseScaledImages; buildAvMap(); buildIsoMap(); buildTvMap(); buildModeMap(); buildExposureMap(); buildWhiteBalanceMap(); buildColorTemperatures(); buildImageQualityMap(); buildPictureStyleMap(); m_useDirectShow = StopMotionUseDirectShow; m_useMjpg = StopMotionUseMjpg; m_alwaysLiveView = StopMotionAlwaysLiveView; m_blackCapture = StopMotionBlackCapture; m_placeOnXSheet = StopMotionPlaceOnXSheet; m_reviewTime = StopMotionReviewTime; m_useNumpadShortcuts = StopMotionUseNumpad; m_numpadForStyleSwitching = Preferences::instance()->isUseNumpadForSwitchingStylesEnabled(); setUseNumpadShortcuts(m_useNumpadShortcuts); m_turnOnRewind = Preferences::instance()->rewindAfterPlaybackEnabled(); m_timer = new QTimer(this); m_reviewTimer = new QTimer(this); m_reviewTimer->setSingleShot(true); m_fullScreen1 = new QDialog(); m_fullScreen1->setModal(false); m_fullScreen1->setStyleSheet("background-color:black;"); m_screenCount = QApplication::desktop()->screenCount(); if (m_screenCount > 1) { m_fullScreen2 = new QDialog(); m_fullScreen2->setModal(false); m_fullScreen2->setStyleSheet("background-color:black;"); if (m_screenCount == 3) { m_fullScreen3 = new QDialog(); m_fullScreen3->setModal(false); m_fullScreen3->setStyleSheet("background-color:black;"); } } TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet(); TSceneHandle *sceneHandle = TApp::instance()->getCurrentScene(); TFrameHandle *frameHandle = TApp::instance()->getCurrentFrame(); bool ret = true; ret = ret && connect(xsheetHandle, SIGNAL(xsheetSwitched()), this, SLOT(update())); ret = ret && connect(m_reviewTimer, SIGNAL(timeout()), this, SLOT(onReviewTimeout())); ret = ret && connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); ret = ret && connect(this, SIGNAL(newImageReady()), this, SLOT(importImage())); ret = ret && connect(sceneHandle, SIGNAL(sceneSwitched()), this, SLOT(onSceneSwitched())); ret = ret && connect(frameHandle, SIGNAL(isPlayingStatusChanged()), this, SLOT(onPlaybackChanged())); assert(ret); ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); setToNextNewLevel(); m_filePath = scene->getDefaultLevelPath(OVL_TYPE, m_levelName.toStdWString()) .getParentDir() .getQString(); // set handler for a camera detected initializeCanonSDK(); if (!m_error) m_error = EdsSetCameraAddedHandler(StopMotion::handleCameraAddedEvent, (EdsVoid *)this); } //----------------------------------------------------------------- StopMotion::~StopMotion() { if (m_liveViewStatus != LiveViewClosed) endLiveView(); if (m_sessionOpen) closeCameraSession(); if (m_camera) releaseCamera(); if (m_cameraList != NULL) releaseCameraList(); if (m_isSDKLoaded) closeCanonSDK(); setUseNumpadShortcuts(false); } //----------------------------------------------------------------------------- void StopMotion::onSceneSwitched() { TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); setToNextNewLevel(); m_filePath = scene->getDefaultLevelPath(OVL_TYPE, m_levelName.toStdWString()) .getParentDir() .getQString(); m_frameNumber = 1; m_xSheetFrameNumber = 0; TLevelSet *levelSet = scene->getLevelSet(); std::vector levels; levelSet->listLevels(levels); int size = levels.size(); for (int i = 0; i < size; i++) { TXshLevel *level = levels[i]; if (level->getType() == OVL_XSHLEVEL) { TXshSimpleLevel *sl = 0; sl = level->getSimpleLevel(); bool isStopMotionLevel = sl->getProperties()->isStopMotionLevel(); if (isStopMotionLevel) { m_filePath = sl->getPath().getParentDir().getQString(); m_levelName = QString::fromStdWString(sl->getName()); m_frameNumber = sl->getFrameCount() + 1; setXSheetFrameNumber(xsh->getFrameCount() + 1); break; } } } emit(levelNameChanged(m_levelName)); emit(filePathChanged(m_filePath)); emit(frameNumberChanged(m_frameNumber)); emit(xSheetFrameNumberChanged(m_xSheetFrameNumber)); refreshFrameInfo(); } //----------------------------------------------------------------- void StopMotion::onPlaybackChanged() { if (TApp::instance()->getCurrentFrame()->isPlaying() || m_liveViewStatus == 0) return; int r0, r1, step; ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); scene->getProperties()->getPreviewProperties()->getRange(r0, r1, step); if (r1 > -1) return; int frame = TApp::instance()->getCurrentFrame()->getFrame(); int lastFrame = TApp::instance()->getCurrentFrame()->getMaxFrameIndex(); if (frame == 0 || frame == lastFrame) { TApp::instance()->getCurrentFrame()->setFrame(m_xSheetFrameNumber - 1); } } //----------------------------------------------------------------- void StopMotion::setOpacity(int opacity) { m_opacity = opacity; StopMotionOpacity = m_opacity; emit(opacityChanged(m_opacity)); } //----------------------------------------------------------------- void StopMotion::lowerOpacity() { int opacity = round((double)m_opacity / 255.0 * 10.0); opacity *= 10; opacity -= 10; m_opacity = double(opacity) / 100.0 * 255.0; m_opacity = max(0, m_opacity); StopMotionOpacity = m_opacity; emit(opacityChanged(m_opacity)); } //----------------------------------------------------------------- void StopMotion::raiseOpacity() { int opacity = round((double)m_opacity / 255.0 * 10.0); opacity *= 10; opacity += 10; m_opacity = double(opacity) / 100.0 * 255.0; m_opacity = min(255, m_opacity); StopMotionOpacity = m_opacity; emit(opacityChanged(m_opacity)); } //----------------------------------------------------------------- void StopMotion::setUseScaledImages(bool on) { m_useScaledImages = on; StopMotionUseScaledImages = int(on); emit(scaleFullSizeImagesSignal(on)); } //----------------------------------------------------------------- void StopMotion::setAlwaysLiveView(bool on) { m_alwaysLiveView = on; StopMotionAlwaysLiveView = int(on); emit(liveViewOnAllFramesSignal(on)); } //----------------------------------------------------------------- void StopMotion::setBlackCapture(bool on) { m_blackCapture = on; StopMotionBlackCapture = int(on); emit(blackCaptureSignal(on)); } //----------------------------------------------------------------- void StopMotion::setPlaceOnXSheet(bool on) { m_placeOnXSheet = on; StopMotionPlaceOnXSheet = int(on); emit(placeOnXSheetSignal(on)); } //----------------------------------------------------------------- void StopMotion::setReviewTime(int time) { m_reviewTime = time; StopMotionReviewTime = time; emit(reviewTimeChangedSignal(time)); } //----------------------------------------------------------------- void StopMotion::setUseMjpg(bool on) { m_useMjpg = on; StopMotionUseMjpg = int(on); emit(useMjpgSignal(on)); } //----------------------------------------------------------------- void StopMotion::jumpToCameraFrame() { TApp::instance()->getCurrentFrame()->setFrame(m_xSheetFrameNumber - 1); } //----------------------------------------------------------------- void StopMotion::setUseNumpadShortcuts(bool on) { m_useNumpadShortcuts = on; StopMotionUseNumpad = int(on); emit(useNumpadSignal(on)); } void StopMotion::toggleNumpadShortcuts(bool on) { // can't just return if this feature is off // it could have been toggled while the camera was active if (!m_useNumpadShortcuts) on = false; CommandManager *comm = CommandManager::instance(); if (on) { // if turning it on, get all old shortcuts if (m_numpadForStyleSwitching) { Preferences::instance()->setValue(useNumpadForSwitchingStyles, false); } std::string shortcut; QAction *action; for (int i = 0; i <= 9; i++) { shortcut = QString::number(i).toStdString(); action = comm->getActionFromShortcut(shortcut); if (action) { m_oldActionMap.insert( std::pair(shortcut, action)); action->setShortcut(QKeySequence("")); action = NULL; } } shortcut = "+"; action = comm->getActionFromShortcut(shortcut); if (action) { m_oldActionMap.insert( std::pair(shortcut, action)); action = NULL; } shortcut = "-"; action = comm->getActionFromShortcut(shortcut); if (action) { m_oldActionMap.insert( std::pair(shortcut, action)); action = NULL; } shortcut = "Return"; action = comm->getActionFromShortcut(shortcut); if (action) { m_oldActionMap.insert( std::pair(shortcut, action)); action = NULL; } shortcut = "*"; action = comm->getActionFromShortcut(shortcut); if (action) { m_oldActionMap.insert( std::pair(shortcut, action)); action = NULL; } // now set all new shortcuts action = comm->getAction(MI_PrevDrawing); if (action) { action->setShortcut(QKeySequence("1")); action = NULL; } action = comm->getAction(MI_NextDrawing); if (action) { action->setShortcut(QKeySequence("2")); action = NULL; } action = comm->getAction(MI_StopMotionJumpToCamera); if (action) { action->setShortcut(QKeySequence("3")); action = NULL; } action = comm->getAction(MI_Loop); if (action) { action->setShortcut(QKeySequence("8")); action = NULL; } action = comm->getAction(MI_Play); if (action) { action->setShortcut(QKeySequence("0")); action = NULL; } action = comm->getAction(MI_StopMotionRaiseOpacity); if (action) { action->setShortcut(QKeySequence("+")); action = NULL; } action = comm->getAction(MI_StopMotionLowerOpacity); if (action) { action->setShortcut(QKeySequence("-")); action = NULL; } action = comm->getAction(MI_StopMotionCapture); if (action) { action->setShortcut(QKeySequence("Enter")); action = NULL; } action = comm->getAction(MI_StopMotionToggleLiveView); if (action) { action->setShortcut(QKeySequence("5")); action = NULL; } action = comm->getAction(MI_StopMotionToggleZoom); if (action) { action->setShortcut(QKeySequence("*")); action = NULL; } } else { // unset the new shortcuts first QAction *action; action = comm->getAction(MI_PrevDrawing); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_NextDrawing); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_StopMotionJumpToCamera); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_Loop); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_Play); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_StopMotionCapture); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_StopMotionLowerOpacity); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_StopMotionRaiseOpacity); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_StopMotionToggleLiveView); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } action = comm->getAction(MI_StopMotionToggleZoom); if (action) { action->setShortcut( QKeySequence(comm->getShortcutFromAction(action).c_str())); action = NULL; } // now put back the old shortcuts auto it = m_oldActionMap.begin(); while (it != m_oldActionMap.end()) { it->second->setShortcut(QKeySequence(it->first.c_str())); it++; } if (m_numpadForStyleSwitching) { std::string shortcut; QAction *action; for (int i = 0; i <= 9; i++) { shortcut = QString::number(i).toStdString(); action = comm->getActionFromShortcut(shortcut); if (action) { action->setShortcut(QKeySequence("")); action = NULL; } } Preferences::instance()->setValue(useNumpadForSwitchingStyles, true); } } } //----------------------------------------------------------------- void StopMotion::setXSheetFrameNumber(int frameNumber) { m_xSheetFrameNumber = frameNumber; loadLineUpImage(); emit(xSheetFrameNumberChanged(m_xSheetFrameNumber)); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); } //----------------------------------------------------------------- bool StopMotion::loadLineUpImage() { if (m_liveViewStatus < 1) return false; m_hasLineUpImage = false; // first see if the level exists in the current level set ToonzScene *currentScene = TApp::instance()->getCurrentScene()->getScene(); TLevelSet *levelSet = currentScene->getLevelSet(); std::wstring levelName = m_levelName.toStdWString(); // level with the same name TXshLevel *level_sameName = levelSet->getLevel(levelName); TFilePath levelFp = TFilePath(m_filePath) + TFilePath(levelName + L".." + m_fileType.toStdWString()); // level with the same path TXshLevel *level_samePath = levelSet->getLevel(*(currentScene), levelFp); TFilePath actualLevelFp = currentScene->decodeFilePath(levelFp); TXshSimpleLevelP sl; if (level_sameName && level_samePath && level_sameName == level_samePath) { sl = dynamic_cast(level_sameName); bool isRasterLevel = sl && (sl->getType() == OVL_XSHLEVEL); if (!isRasterLevel) { return false; } } else return false; // next we need to find the column the level is on TApp *app = TApp::instance(); TXsheet *xsh = currentScene->getXsheet(); int row; if (m_xSheetFrameNumber == 1) { row = 0; } else { row = m_xSheetFrameNumber - 2; } int col = app->getCurrentColumn()->getColumnIndex(); int foundCol = -1; // most possibly, it's in the current column int rowCheck; findCell(xsh, col, TXshCell(level_sameName, TFrameId(1)), rowCheck); if (rowCheck >= 0) { foundCol = col; } else { // search entire xsheet for (int c = 0; c < xsh->getColumnCount(); c++) { if (c == col) continue; findCell(xsh, c, TXshCell(level_sameName, TFrameId(1)), rowCheck); if (rowCheck >= 0) { foundCol = c; } } } if (rowCheck < 0) return false; // note found row represents the last row found that uses // the active level TFrameId frameId = xsh->getCell(row, foundCol).getFrameId(); int frameNumber = frameId.getNumber(); if (m_usingWebcam) { if (frameNumber > 0) { m_lineUpImage = sl->getFrame(frameId, false)->raster(); m_hasLineUpImage = true; return true; } else return false; } // now check to see if a file actually exists there TFilePath liveViewFolder = currentScene->decodeFilePath( TFilePath(m_filePath) + TFilePath(levelName + L"_LiveView")); TFilePath liveViewFp = currentScene->decodeFilePath( liveViewFolder + TFilePath(levelName + L"..jpg")); TFilePath liveViewFile(liveViewFp.withFrame(frameNumber)); if (TFileStatus(liveViewFile).doesExist()) { if (loadJpg(liveViewFile, m_lineUpImage)) { m_hasLineUpImage = true; return true; } } return false; } //----------------------------------------------------------------- void StopMotion::setFrameNumber(int frameNumber) { m_frameNumber = frameNumber; emit(frameNumberChanged(m_frameNumber)); } //----------------------------------------------------------------------------- void StopMotion::nextFrame() { if (Preferences::instance()->isShowFrameNumberWithLettersEnabled()) { int f = m_frameNumber; if (f % 10 == 0) // next number m_frameNumber = ((int)(f / 10) + 1) * 10; else // next alphabet m_frameNumber = f + 1; } else m_frameNumber = m_frameNumber + 1; emit(frameNumberChanged(m_frameNumber)); refreshFrameInfo(); } //----------------------------------------------------------------------------- void StopMotion::lastFrame() {} //----------------------------------------------------------------------------- void StopMotion::previousFrame() { int f = m_frameNumber; if (f > 1) { if (Preferences::instance()->isShowFrameNumberWithLettersEnabled()) { if (f % 10 == 0) // next number m_frameNumber = ((int)(f / 10) - 1) * 10; else // next alphabet m_frameNumber = f - 1; } else m_frameNumber = f - 1; emit(frameNumberChanged(m_frameNumber)); refreshFrameInfo(); } } //----------------------------------------------------------------- void StopMotion::setLevelName(QString levelName) { m_levelName = levelName; } //----------------------------------------------------------------- void StopMotion::nextName() { std::unique_ptr nameCreator(new FlexibleNameCreator()); if (!nameCreator->setCurrent(m_levelName.toStdWString())) { setToNextNewLevel(); return; } std::wstring levelName = nameCreator->getNext(); updateLevelNameAndFrame(levelName); } //----------------------------------------------------------------- void StopMotion::previousName() { std::unique_ptr nameCreator(new FlexibleNameCreator()); std::wstring levelName; // if the current level name is non-sequencial, then try to switch the last // sequencial level in the scene. if (!nameCreator->setCurrent(m_levelName.toStdWString())) { TLevelSet *levelSet = TApp::instance()->getCurrentScene()->getScene()->getLevelSet(); nameCreator->setCurrent(L"ZZ"); for (;;) { levelName = nameCreator->getPrevious(); if (levelSet->getLevel(levelName) != 0) break; if (levelName == L"A") { setToNextNewLevel(); return; } } } else levelName = nameCreator->getPrevious(); updateLevelNameAndFrame(levelName); } //----------------------------------------------------------------- void StopMotion::setFileType(QString fileType) { m_fileType = fileType; emit(fileTypeChanged(m_fileType)); } //----------------------------------------------------------------- void StopMotion::setFilePath(QString filePath) { m_filePath = filePath; ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); TFilePath saveInPath(filePath.toStdWString()); scene->getProperties()->setCameraCaptureSaveInPath(saveInPath); refreshFrameInfo(); emit(filePathChanged(m_filePath)); } //----------------------------------------------------------------- void StopMotion::setSubsamplingValue(int subsampling) { m_subsampling = subsampling; } //----------------------------------------------------------------- void StopMotion::getSubsampling() { ToonzScene *currentScene = TApp::instance()->getCurrentScene()->getScene(); TLevelSet *levelSet = currentScene->getLevelSet(); std::wstring levelName = m_levelName.toStdWString(); // level with the same name TXshLevel *level_sameName = levelSet->getLevel(levelName); TFilePath levelFp = TFilePath(m_filePath) + TFilePath(levelName + L".." + m_fileType.toStdWString()); // level with the same path TXshLevel *level_samePath = levelSet->getLevel(*(currentScene), levelFp); TFilePath actualLevelFp = currentScene->decodeFilePath(levelFp); if (level_sameName && level_samePath && level_sameName == level_samePath) { TXshSimpleLevelP m_sl; m_sl = dynamic_cast(level_sameName); bool isRasterLevel = m_sl && (m_sl->getType() == OVL_XSHLEVEL); if (isRasterLevel) { int currSubsampling = m_sl->getProperties()->getSubsampling(); m_subsampling = currSubsampling; emit(subsamplingChanged(m_subsampling)); } else emit(subsamplingChanged(-1)); } else emit(subsamplingChanged(-1)); } //----------------------------------------------------------------------------- void StopMotion::update() { getSubsampling(); } //----------------------------------------------------------------------------- void StopMotion::setSubsampling() { ToonzScene *currentScene = TApp::instance()->getCurrentScene()->getScene(); TLevelSet *levelSet = currentScene->getLevelSet(); std::wstring levelName = m_levelName.toStdWString(); // level with the same name TXshLevel *level_sameName = levelSet->getLevel(levelName); TFilePath levelFp = TFilePath(m_filePath) + TFilePath(levelName + L".." + m_fileType.toStdWString()); // level with the same path TXshLevel *level_samePath = levelSet->getLevel(*(currentScene), levelFp); TFilePath actualLevelFp = currentScene->decodeFilePath(levelFp); if (level_sameName && level_samePath && level_sameName == level_samePath) { TXshSimpleLevelP m_sl; m_sl = dynamic_cast(level_sameName); bool isRasterLevel = m_sl && (m_sl->getType() & RASTER_TYPE); if (isRasterLevel) { int currSubsampling = m_sl->getProperties()->getSubsampling(); int newSubsampling = m_subsampling; if (currSubsampling != newSubsampling) { m_sl->getProperties()->setSubsampling(newSubsampling); m_sl->invalidateFrames(); TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance() ->getCurrentXsheet() ->getXsheet() ->getStageObjectTree() ->invalidateAll(); TApp::instance()->getCurrentLevel()->notifyLevelChange(); emit(subsamplingChanged(m_subsampling)); } } } } //----------------------------------------------------------------------------- void StopMotion::onTimeout() { int currentFrame = TApp::instance()->getCurrentFrame()->getFrame(); // int destinationFrame = m_xSheetFrameNumber - 1; if (m_liveViewStatus > 0 && m_liveViewStatus < 3 && !TApp::instance()->getCurrentFrame()->isPlaying()) { if (getAlwaysLiveView() || (currentFrame == m_xSheetFrameNumber - 1)) { if (!m_usingWebcam) downloadEVFData(); else getWebcamImage(); if (getAlwaysLiveView() && currentFrame != m_xSheetFrameNumber - 1 || m_pickLiveViewZoom) { m_showLineUpImage = false; } else { m_showLineUpImage = true; } } else if (m_liveViewStatus == 2) { m_liveViewStatus = 3; TApp::instance()->getCurrentScene()->notifySceneChanged(); } } else if (m_liveViewStatus == 3 && !m_userCalledPause) { if (getAlwaysLiveView() || (currentFrame == m_xSheetFrameNumber - 1)) { if (!m_usingWebcam) downloadEVFData(); else getWebcamImage(); } } } //----------------------------------------------------------------------------- void StopMotion::onReviewTimeout() { if (m_liveViewStatus > 0) { m_liveViewStatus = 2; m_timer->start(40); } TApp::instance()->getCurrentFrame()->setFrame(m_xSheetFrameNumber - 1); } //----------------------------------------------------------------------------- bool StopMotion::importImage() { if (getBlackCapture()) { m_fullScreen1->hide(); if (m_screenCount > 1) { m_fullScreen2->hide(); if (m_screenCount == 3) { m_fullScreen3->hide(); } } } if (getReviewTime() > 0) { m_reviewTimer->start(getReviewTime() * 1000); } TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); TXsheet *xsh = scene->getXsheet(); std::wstring levelName = m_levelName.toStdWString(); if (levelName.empty()) { DVGui::error( tr("No level name specified: please choose a valid level name")); return false; } if (m_usingWebcam) { m_newImage = m_liveViewImage; } int frameNumber = m_frameNumber; /* create parent directory if it does not exist */ TFilePath parentDir = scene->decodeFilePath(TFilePath(m_filePath)); TFilePath fullResFolder = scene->decodeFilePath( TFilePath(m_filePath) + TFilePath(levelName + L"_FullRes")); TFilePath liveViewFolder = scene->decodeFilePath( TFilePath(m_filePath) + TFilePath(levelName + L"_LiveView")); TFilePath levelFp = TFilePath(m_filePath) + TFilePath(levelName + L".." + m_fileType.toStdWString()); TFilePath actualLevelFp = scene->decodeFilePath(levelFp); TFilePath fullResFp = scene->decodeFilePath(fullResFolder + TFilePath(levelName + L"..jpg")); TFilePath fullResFile(fullResFp.withFrame(frameNumber)); TFilePath liveViewFp = scene->decodeFilePath(liveViewFolder + TFilePath(levelName + L"..jpg")); TFilePath liveViewFile(liveViewFp.withFrame(frameNumber)); TFilePath tempFile = parentDir + "temp.jpg"; TXshSimpleLevel *sl = 0; TXshLevel *level = scene->getLevelSet()->getLevel(levelName); enum State { NEWLEVEL = 0, ADDFRAME, OVERWRITE } state; /* if the level already exists in the scene cast */ if (level) { /* if the existing level is not a raster level, then return */ if (level->getType() != OVL_XSHLEVEL) { DVGui::error( tr("The level name specified is already used: please choose a " "different level name.")); return false; } /* if the existing level does not match file path and pixel size, then * return */ sl = level->getSimpleLevel(); if (scene->decodeFilePath(sl->getPath()) != actualLevelFp) { DVGui::error( tr("The save in path specified does not match with the existing " "level.")); return false; } if (sl->getProperties()->getImageRes() != TDimension(m_newImage->getLx(), m_newImage->getLy())) { DVGui::error(tr( "The captured image size does not match with the existing level.")); return false; } /* if the level already have the same frame, then ask if overwrite it */ TFilePath frameFp(actualLevelFp.withFrame(frameNumber)); if (TFileStatus(frameFp).doesExist()) { QString question = tr("File %1 already exists.\nDo you want to overwrite it?") .arg(toQString(frameFp)); int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"), QObject::tr("Cancel")); if (ret == 0 || ret == 2) return false; state = OVERWRITE; } else state = ADDFRAME; } /* if the level does not exist in the scene cast */ else { /* if the file does exist, load it first */ if (TSystem::doesExistFileOrLevel(actualLevelFp)) { level = scene->loadLevel(actualLevelFp); if (!level) { DVGui::error(tr("Failed to load %1.").arg(toQString(actualLevelFp))); return false; } /* if the loaded level does not match in pixel size, then return */ sl = level->getSimpleLevel(); if (!sl || sl->getProperties()->getImageRes() != TDimension(m_newImage->getLx(), m_newImage->getLy())) { DVGui::error( tr("The captured image size does not match with the existing " "level.")); return false; } /* confirm overwrite */ TFilePath frameFp(actualLevelFp.withFrame(frameNumber)); if (TFileStatus(frameFp).doesExist()) { QString question = tr("File %1 already exists.\nDo you want to overwrite it?") .arg(toQString(frameFp)); int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"), QObject::tr("Cancel")); if (ret == 0 || ret == 2) return false; } } /* if the file does not exist, then create a new level */ else { TXshLevel *level = scene->createNewLevel(OVL_XSHLEVEL, levelName, TDimension(), 0, levelFp); sl = level->getSimpleLevel(); sl->setPath(levelFp, true); sl->getProperties()->setDpiPolicy(LevelProperties::DP_CustomDpi); TPointD dpi; // Right now always set the dpi to scale to the camera width if (Preferences::instance()->getPixelsOnly() && false) dpi = getCurrentCameraDpi(); // Compute the dpi so that the image will fit // to the camera frame else { TCamera *camera = TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); TDimensionD size = camera->getSize(); double minimumDpi = std::min(m_newImage->getLx() / size.lx, m_newImage->getLy() / size.ly); dpi = TPointD(minimumDpi, minimumDpi); } sl->getProperties()->setDpi(dpi.x); sl->getProperties()->setImageDpi(dpi); sl->getProperties()->setImageRes( TDimension(m_newImage->getLx(), m_newImage->getLy())); } state = NEWLEVEL; getSubsampling(); } if (!TFileStatus(parentDir).doesExist()) { QString question; question = tr("Folder %1 doesn't exist.\nDo you want to create it?") .arg(toQString(parentDir)); int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No")); if (ret == 0 || ret == 2) return false; try { TSystem::mkDir(parentDir); DvDirModel::instance()->refreshFolder(parentDir.getParentDir()); } catch (...) { DVGui::error(tr("Unable to create") + toQString(parentDir)); return false; } } if (!m_usingWebcam) { if (!TFileStatus(fullResFolder).doesExist()) { try { TSystem::mkDir(fullResFolder); DvDirModel::instance()->refreshFolder(fullResFolder.getParentDir()); } catch (...) { DVGui::error(tr("Unable to create") + toQString(fullResFolder)); return false; } } if (!TFileStatus(liveViewFolder).doesExist()) { try { TSystem::mkDir(liveViewFolder); DvDirModel::instance()->refreshFolder(liveViewFolder.getParentDir()); } catch (...) { DVGui::error(tr("Unable to create") + toQString(liveViewFolder)); return false; } } } // move the temp file if (!m_usingWebcam) { if (m_useScaledImages) { TSystem::copyFile(fullResFile, tempFile); TSystem::deleteFile(tempFile); } if (m_hasLineUpImage) { saveJpg(m_lineUpImage, liveViewFile); } } TFrameId fid(frameNumber); TPointD levelDpi = sl->getDpi(); /* create the raster */ TRaster32P raster = m_newImage; TRasterImageP ri(raster); ri->setDpi(levelDpi.x, levelDpi.y); /* setting the frame */ sl->setFrame(fid, ri); /* set dirty flag */ sl->getProperties()->setDirtyFlag(true); sl->getProperties()->setIsStopMotion(true); sl->setIsReadOnly(true); // if (m_saveOnCaptureCB->isChecked()) sl->save(); // for now always save. This can be tweaked later sl->save(); /* placement in xsheet */ if (!getPlaceOnXSheet()) { postImportProcess(); return true; } int row = m_xSheetFrameNumber - 1; int col = app->getCurrentColumn()->getColumnIndex(); // if the level is newly created or imported, then insert a new column if (state == NEWLEVEL) { if (!xsh->isColumnEmpty(col)) { col += 1; xsh->insertColumn(col); } xsh->insertCells(row, col); xsh->setCell(row, col, TXshCell(sl, fid)); app->getCurrentColumn()->setColumnIndex(col); if (getReviewTime() == 0) app->getCurrentFrame()->setFrame(row + 1); m_xSheetFrameNumber = row + 2; emit(xSheetFrameNumberChanged(m_xSheetFrameNumber)); postImportProcess(); // if (m_newImage->getLx() > 2000) { // m_subsampling = 4; // setSubsampling(); //} return true; } // state == OVERWRITE, ADDFRAME // if the same cell is already in the column, then just replace the content // and do not set a new cell int foundCol, foundRow = -1; // most possibly, it's in the current column int rowCheck; if (findCell(xsh, col, TXshCell(sl, fid), rowCheck)) { postImportProcess(); return true; } if (rowCheck >= 0) { foundRow = rowCheck; foundCol = col; } // search entire xsheet for (int c = 0; c < xsh->getColumnCount(); c++) { if (c == col) continue; if (findCell(xsh, c, TXshCell(sl, fid), rowCheck)) { postImportProcess(); return true; } if (rowCheck >= 0) { foundRow = rowCheck; foundCol = c; } } // note found row represents the last row found that uses // the active level // if there is a column containing the same level if (foundRow >= 0) { // put the cell at the bottom xsh->insertCells(row, foundCol); xsh->setCell(row, foundCol, TXshCell(sl, fid)); app->getCurrentColumn()->setColumnIndex(foundCol); if (getReviewTime() == 0) app->getCurrentFrame()->setFrame(row + 1); m_xSheetFrameNumber = row + 2; emit(xSheetFrameNumberChanged(m_xSheetFrameNumber)); } // if the level is registered in the scene, but is not placed in the xsheet, // then insert a new column else { if (!xsh->isColumnEmpty(col)) { col += 1; xsh->insertColumn(col); } xsh->setCell(row, col, TXshCell(sl, fid)); app->getCurrentColumn()->setColumnIndex(col); if (getReviewTime() == 0) app->getCurrentFrame()->setFrame(row + 1); m_xSheetFrameNumber = row + 2; emit(xSheetFrameNumberChanged(m_xSheetFrameNumber)); } postImportProcess(); return true; } //----------------------------------------------------------------- void StopMotion::captureImage() { if (!m_usingWebcam && !m_sessionOpen) { DVGui::warning(tr("Please start live view before capturing an image.")); return; } if (m_usingWebcam) { if (!m_hasLiveViewImage) { DVGui::warning( tr("Cannot capture webcam image unless live view is active.")); return; } if (getReviewTime() > 0) { m_timer->stop(); if (m_liveViewStatus > 0) { m_liveViewStatus = 3; } } m_lineUpImage = m_liveViewImage; m_hasLineUpImage = true; emit(newLiveViewImageReady()); importImage(); return; } if (getBlackCapture()) { m_fullScreen1->showFullScreen(); m_fullScreen1->setGeometry(QApplication::desktop()->screenGeometry(0)); if (m_screenCount > 1) { m_fullScreen2->showFullScreen(); m_fullScreen2->setGeometry(QApplication::desktop()->screenGeometry(1)); if (m_screenCount == 3) { m_fullScreen3->showFullScreen(); m_fullScreen3->setGeometry(QApplication::desktop()->screenGeometry(2)); } } // this allows the full screen qdialogs to go full screen before // taking a photo qApp->processEvents(QEventLoop::AllEvents, 1500); } if (getReviewTime() > 0) { m_timer->stop(); } if (m_liveViewStatus > 0) { m_liveViewStatus = 3; } if (m_hasLiveViewImage) { m_lineUpImage = m_liveViewImage; m_hasLineUpImage = true; emit(newLiveViewImageReady()); } TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); int frameNumber = m_frameNumber; std::wstring levelName = m_levelName.toStdWString(); TFilePath parentDir = scene->decodeFilePath(TFilePath(m_filePath)); TFilePath tempFile = parentDir + "temp.jpg"; if (!TFileStatus(parentDir).doesExist()) { TSystem::mkDir(parentDir); } m_tempFile = tempFile.getQString(); takePicture(); } //----------------------------------------------------------------------------- void StopMotion::saveJpg(TRaster32P image, TFilePath path) { unsigned char *jpegBuf = NULL; /* Dynamically allocate the JPEG buffer */ unsigned long jpegSize = 0; int pixelFormat = TJPF_BGRX; int outQual = 95; int subSamp = TJSAMP_411; bool success = false; tjhandle tjInstance; int width = image->getLx(); int height = image->getLy(); int flags = 0; #ifdef WIN32 flags |= TJFLAG_BOTTOMUP; #endif image->lock(); uchar *rawData = image->getRawData(); if ((tjInstance = tjInitCompress()) != NULL) { if (tjCompress2(tjInstance, rawData, width, 0, height, pixelFormat, &jpegBuf, &jpegSize, subSamp, outQual, flags) >= 0) { success = true; } } image->unlock(); tjDestroy(tjInstance); tjInstance = NULL; if (success) { /* Write the JPEG image to disk. */ QFile fullImage(path.getQString()); fullImage.open(QIODevice::WriteOnly); QDataStream dataStream(&fullImage); dataStream.writeRawData((const char *)jpegBuf, jpegSize); fullImage.close(); } tjFree(jpegBuf); jpegBuf = NULL; } //----------------------------------------------------------------------------- bool StopMotion::loadJpg(TFilePath path, TRaster32P &image) { long size; int inSubsamp, inColorspace, width, height; unsigned long jpegSize; unsigned char *jpegBuf; FILE *jpegFile; QString qPath = path.getQString(); QByteArray ba = qPath.toLocal8Bit(); const char *c_path = ba.data(); bool success = true; tjhandle tjInstance; /* Read the JPEG file into memory. */ if ((jpegFile = fopen(c_path, "rb")) == NULL) success = false; if (success && fseek(jpegFile, 0, SEEK_END) < 0 || ((size = ftell(jpegFile)) < 0) || fseek(jpegFile, 0, SEEK_SET) < 0) success = false; if (success && size == 0) success = false; jpegSize = (unsigned long)size; if (success && (jpegBuf = (unsigned char *)tjAlloc(jpegSize)) == NULL) success = false; if (success && fread(jpegBuf, jpegSize, 1, jpegFile) < 1) success = false; fclose(jpegFile); jpegFile = NULL; if (success && (tjInstance = tjInitDecompress()) == NULL) success = false; if (success && tjDecompressHeader3(tjInstance, jpegBuf, jpegSize, &width, &height, &inSubsamp, &inColorspace) < 0) success = false; int pixelFormat = TJPF_BGRX; unsigned char *imgBuf = NULL; if (success && (imgBuf = tjAlloc(width * height * tjPixelSize[pixelFormat])) == NULL) success = false; int flags = 0; #ifdef WIN32 flags |= TJFLAG_BOTTOMUP; #endif if (success && tjDecompress2(tjInstance, jpegBuf, jpegSize, imgBuf, width, 0, height, pixelFormat, flags) < 0) success = false; tjFree(jpegBuf); jpegBuf = NULL; tjDestroy(tjInstance); tjInstance = NULL; image = TRaster32P(width, height); image->lock(); uchar *rawData = image->getRawData(); memcpy(rawData, imgBuf, width * height * tjPixelSize[pixelFormat]); image->unlock(); tjFree(imgBuf); imgBuf = NULL; return success; } //----------------------------------------------------------------------------- void StopMotion::postImportProcess() { if (Preferences::instance()->isShowFrameNumberWithLettersEnabled()) { int f = m_frameNumber; if (f % 10 == 0) // next number m_frameNumber = ((int)(f / 10) + 1) * 10; else // next alphabet m_frameNumber = f + 1; } else m_frameNumber += 1; emit(frameNumberChanged(m_frameNumber)); /* notify */ refreshFrameInfo(); TApp::instance()->getCurrentScene()->notifySceneChanged(); TApp::instance()->getCurrentScene()->notifyCastChange(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); } //----------------------------------------------------------------------------- // Refresh information that how many & which frames are saved for the current // level void StopMotion::refreshFrameInfo() { if ((!m_sessionOpen && m_liveViewStatus < 2) && !m_usingWebcam) { m_frameInfoText = ""; return; } QString tooltipStr, labelStr; enum InfoType { NEW = 0, ADD, OVERWRITE, WARNING } infoType(WARNING); static QColor infoColors[4] = {Qt::cyan, Qt::green, Qt::yellow, Qt::red}; ToonzScene *currentScene = TApp::instance()->getCurrentScene()->getScene(); TLevelSet *levelSet = currentScene->getLevelSet(); std::wstring levelName = m_levelName.toStdWString(); int frameNumber = m_frameNumber; TDimension stopMotionRes; bool checkRes = true; if (m_usingWebcam) stopMotionRes = m_liveViewImageDimensions; else if (m_useScaledImages || !getCurrentImageQuality().contains("Large")) { stopMotionRes = m_proxyImageDimensions; if (m_proxyImageDimensions == TDimension(0, 0)) { checkRes = false; } } else stopMotionRes = m_fullImageDimensions; bool letterOptionEnabled = Preferences::instance()->isShowFrameNumberWithLettersEnabled(); // level with the same name TXshLevel *level_sameName = levelSet->getLevel(levelName); TFilePath levelFp = TFilePath(m_filePath) + TFilePath(levelName + L".." + m_fileType.toStdWString()); // level with the same path TXshLevel *level_samePath = levelSet->getLevel(*(currentScene), levelFp); TFilePath actualLevelFp = currentScene->decodeFilePath(levelFp); // level existence bool levelExist = TSystem::doesExistFileOrLevel(actualLevelFp); // frame existence TFilePath frameFp(actualLevelFp.withFrame(frameNumber)); bool frameExist = false; if (levelExist) frameExist = TFileStatus(frameFp).doesExist(); // reset acceptable camera size m_allowedCameraSize = QSize(); // ### CASE 1 ### // If there is no same level registered in the scene cast if (!level_sameName && !level_samePath) { // If there is a level in the file system if (levelExist) { TLevelReaderP lr; TLevelP level_p; try { lr = TLevelReaderP(actualLevelFp); } catch (...) { // TODO: output something m_frameInfoText = tr("UNDEFINED WARNING"); return; } if (!lr) { // TODO: output something m_frameInfoText = tr("UNDEFINED WARNING"); return; } try { level_p = lr->loadInfo(); } catch (...) { // TODO: output something m_frameInfoText = tr("UNDEFINED WARNING"); return; } if (!level_p) { // TODO: output something m_frameInfoText = tr("UNDEFINED WARNING"); return; } int frameCount = level_p->getFrameCount(); TLevel::Iterator it = level_p->begin(); std::vector fids; for (int i = 0; it != level_p->end(); ++it, ++i) fids.push_back(it->first); tooltipStr += tr("The level is not registered in the scene, but exists in the file " "system."); // check resolution const TImageInfo *ii; try { ii = lr->getImageInfo(fids[0]); } catch (...) { // TODO: output something m_frameInfoText = tr("UNDEFINED WARNING"); return; } TDimension dim(ii->m_lx, ii->m_ly); // if the saved images has not the same resolution as the current camera // resolution if (checkRes && m_hasLiveViewImage && stopMotionRes != dim) { tooltipStr += tr("\nWARNING : Image size mismatch. The saved image " "size is %1 x %2.") .arg(dim.lx) .arg(dim.ly); labelStr += tr("WARNING "); infoType = WARNING; } // if the resolutions are matched { if (frameCount == 1) tooltipStr += tr("\nFrame %1 exists.") .arg(fidsToString(fids, letterOptionEnabled)); else tooltipStr += tr("\nFrames %1 exist.") .arg(fidsToString(fids, letterOptionEnabled)); // if the frame exists, then it will be overwritten if (frameExist) { labelStr += tr("OVERWRITE 1 of"); infoType = OVERWRITE; } else { labelStr += tr("ADD to"); infoType = ADD; } if (frameCount == 1) labelStr += tr(" %1 frame").arg(frameCount); else labelStr += tr(" %1 frames").arg(frameCount); } m_allowedCameraSize = QSize(dim.lx, dim.ly); } // If no level exists in the file system, then it will be a new level else { tooltipStr += tr("The level will be newly created."); labelStr += tr("NEW"); infoType = NEW; } } // ### CASE 2 ### // If there is already the level registered in the scene cast else if (level_sameName && level_samePath && level_sameName == level_samePath) { tooltipStr += tr("The level is already registered in the scene."); if (!levelExist) tooltipStr += tr("\nNOTE : The level is not saved."); std::vector fids; level_sameName->getFids(fids); // check resolution TDimension dim; bool ret = getRasterLevelSize(level_sameName, dim); if (!ret) { tooltipStr += tr("\nWARNING : Failed to get image size of the existing level %1.") .arg(QString::fromStdWString(levelName)); labelStr += tr("WARNING "); infoType = WARNING; } // if the saved images has not the same resolution as the current camera // resolution else if (checkRes && m_hasLiveViewImage && stopMotionRes != dim) { tooltipStr += tr("\nWARNING : Image size mismatch. The existing level " "size is %1 x %2.") .arg(dim.lx) .arg(dim.ly); labelStr += tr("WARNING "); infoType = WARNING; } // if the resolutions are matched { int frameCount = fids.size(); if (fids.size() == 1) tooltipStr += tr("\nFrame %1 exists.") .arg(fidsToString(fids, letterOptionEnabled)); else tooltipStr += tr("\nFrames %1 exist.") .arg(fidsToString(fids, letterOptionEnabled)); // Check if the target frame already exist in the level bool hasFrame = false; for (int f = 0; f < frameCount; f++) { if (fids.at(f).getNumber() == frameNumber) { hasFrame = true; break; } } // If there is already the frame then it will be overwritten if (hasFrame) { labelStr += tr("OVERWRITE 1 of"); infoType = OVERWRITE; } // Or, the frame will be added to the level else { labelStr += tr("ADD to"); infoType = ADD; } if (frameCount == 1) labelStr += tr(" %1 frame").arg(frameCount); else labelStr += tr(" %1 frames").arg(frameCount); } m_allowedCameraSize = QSize(dim.lx, dim.ly); } // ### CASE 3 ### // If there are some conflicts with the existing level. else { if (level_sameName) { TFilePath anotherPath = level_sameName->getPath(); tooltipStr += tr("WARNING : Level name conflicts. There already is a level %1 in the scene with the path\ \n %2.") .arg(QString::fromStdWString(levelName)) .arg(toQString(anotherPath)); // check resolution TDimension dim; bool ret = getRasterLevelSize(level_sameName, dim); if (ret && checkRes && m_hasLiveViewImage && stopMotionRes != dim) tooltipStr += tr("\nWARNING : Image size mismatch. The size of level " "with the same name is is %1 x %2.") .arg(dim.lx) .arg(dim.ly); m_allowedCameraSize = QSize(dim.lx, dim.ly); } if (level_samePath) { std::wstring anotherName = level_samePath->getName(); if (!tooltipStr.isEmpty()) tooltipStr += QString("\n"); tooltipStr += tr("WARNING : Level path conflicts. There already is a level with the path %1\ \n in the scene with the name %2.") .arg(toQString(levelFp)) .arg(QString::fromStdWString(anotherName)); // check resolution TDimension dim; bool ret = getRasterLevelSize(level_samePath, dim); if (ret && checkRes && m_hasLiveViewImage && stopMotionRes != dim) tooltipStr += tr("\nWARNING : Image size mismatch. The size of level " "with the same path is %1 x %2.") .arg(dim.lx) .arg(dim.ly); m_allowedCameraSize = QSize(dim.lx, dim.ly); } labelStr += tr("WARNING"); infoType = WARNING; } QColor infoColor = infoColors[(int)infoType]; m_infoColorName = infoColor.name(); m_frameInfoText = labelStr; m_frameInfoToolTip = tooltipStr; emit(frameInfoTextChanged(m_frameInfoText)); } //----------------------------------------------------------------------------- void StopMotion::updateLevelNameAndFrame(std::wstring levelName) { if (levelName != m_levelName.toStdWString()) { m_levelName = QString::fromStdWString(levelName); loadLineUpImage(); } emit(levelNameChanged(m_levelName)); // m_previousLevelButton->setDisabled(levelName == L"A"); // set the start frame 10 if the option in preferences // "Show ABC Appendix to the Frame Number in Xsheet Cell" is active. // (frame 10 is displayed as "1" with this option) bool withLetter = Preferences::instance()->isShowFrameNumberWithLettersEnabled(); TLevelSet *levelSet = TApp::instance()->getCurrentScene()->getScene()->getLevelSet(); TXshLevel *level_p = levelSet->getLevel(levelName); int startFrame; if (!level_p) { startFrame = withLetter ? 10 : 1; } else { std::vector fids; level_p->getFids(fids); if (fids.empty()) { startFrame = withLetter ? 10 : 1; } else { int lastNum = fids.back().getNumber(); startFrame = withLetter ? ((int)(lastNum / 10) + 1) * 10 : lastNum + 1; } } m_frameNumber = startFrame; emit(frameNumberChanged(startFrame)); refreshFrameInfo(); getSubsampling(); } //----------------------------------------------------------------------------- void StopMotion::setToNextNewLevel() { const std::unique_ptr nameBuilder(NameBuilder::getBuilder(L"")); TLevelSet *levelSet = TApp::instance()->getCurrentScene()->getScene()->getLevelSet(); ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene(); std::wstring levelName = L""; // Select a different unique level name in case it already exists (either in // scene or on disk) TFilePath fp; TFilePath actualFp; for (;;) { levelName = nameBuilder->getNext(); if (levelSet->getLevel(levelName) != 0) continue; fp = TFilePath(m_filePath) + TFilePath(levelName + L".." + m_fileType.toStdWString()); actualFp = scene->decodeFilePath(fp); if (TSystem::doesExistFileOrLevel(actualFp)) { continue; } break; } updateLevelNameAndFrame(levelName); } //----------------------------------------------------------------- void StopMotion::refreshCameraList() { emit(updateCameraList()); } //----------------------------------------------------------------- void StopMotion::changeCameras(int index) { QList cameras = QCameraInfo::availableCameras(); // if selected the non-connected state, then disconnect the current camera if (index == 0) { m_active = false; m_webcamDeviceName = QString(); m_webcamDescription = QString(); m_webcamIndex = -1; m_proxyDpi = TPointD(0.0, 0.0); m_proxyImageDimensions = TDimension(0, 0); if (m_sessionOpen || m_usingWebcam) { if (m_liveViewStatus > 0) { endLiveView(); } closeCameraSession(); m_usingWebcam = false; } setTEnvCameraName(""); emit(newCameraSelected(index, false)); toggleNumpadShortcuts(false); return; } // There is a "Select Camera" as the first index index -= 1; m_active = true; // Check if its a webcam or DSLR // Webcams are listed first, so see if one of them is selected if (index > cameras.size() - 1) { m_usingWebcam = false; } else { m_usingWebcam = true; m_webcamIndex = index; } // in case the camera is not changed if (m_usingWebcam) { if (cameras.at(index).deviceName() == m_webcamDeviceName) { return; } if (m_sessionOpen) { if (m_liveViewStatus > 0) { endLiveView(); closeCameraSession(); } } setWebcam(new QCamera(cameras.at(index))); m_webcamDeviceName = cameras.at(index).deviceName(); m_webcamDescription = cameras.at(index).description(); #ifdef MACOSX // this line is needed only in macosx m_stopMotion->getWebcam()->setViewfinder(m_dummyViewFinder); #endif // loading new camera getWebcam()->load(); m_webcamResolutions.clear(); m_webcamResolutions = getWebcam()->supportedViewfinderResolutions(); int sizeCount = m_webcamResolutions.count(); int width; int height; for (int s = 0; s < m_webcamResolutions.size(); s++) { width = m_webcamResolutions.at(s).width(); height = m_webcamResolutions.at(s).height(); } getWebcam()->unload(); setWebcamResolution( QString(QString::number(width) + " x " + QString::number(height))); setTEnvCameraName(m_webcamDescription.toStdString()); emit(newCameraSelected(index + 1, true)); emit(webcamResolutionsChanged()); emit(newWebcamResolutionSelected(sizeCount - 1)); } else { m_webcamDeviceName = QString(); m_webcamDescription = QString(); m_webcamIndex = -1; openCameraSession(); setTEnvCameraName(getCameraName()); emit(newCameraSelected(index + 1, false)); } if (m_useNumpadShortcuts) toggleNumpadShortcuts(true); m_liveViewDpi = TPointD(0.0, 0.0); refreshFrameInfo(); } //----------------------------------------------------------------- QList StopMotion::getWebcams() { m_webcams.clear(); m_webcams = QCameraInfo::availableCameras(); return m_webcams; } //----------------------------------------------------------------- void StopMotion::setWebcam(QCamera *camera) { m_webcam = camera; } //----------------------------------------------------------------- bool StopMotion::translateIndex(int index) { // We are using Qt to get the camera info and supported resolutions, but // we are using OpenCV to actually get the images. // The camera index from OpenCV and from Qt don't always agree, // So this checks the name against the correct index. m_webcamIndex = index; #ifdef WIN32 // Thanks to: // https://elcharolin.wordpress.com/2017/08/28/webcam-capture-with-the-media-foundation-sdk/ // for the webcam enumeration here #define CLEAN_ATTRIBUTES() \ if (attributes) { \ attributes->Release(); \ attributes = NULL; \ } \ for (DWORD i = 0; i < count; i++) { \ if (&devices[i]) { \ devices[i]->Release(); \ devices[i] = NULL; \ } \ } \ CoTaskMemFree(devices); \ return hr; HRESULT hr = S_OK; // this is important!! hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); UINT32 count = 0; IMFAttributes *attributes = NULL; IMFActivate **devices = NULL; if (FAILED(hr)) { CLEAN_ATTRIBUTES() } // Create an attribute store to specify enumeration parameters. hr = MFCreateAttributes(&attributes, 1); if (FAILED(hr)) { CLEAN_ATTRIBUTES() } // The attribute to be requested is devices that can capture video hr = attributes->SetGUID(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID); if (FAILED(hr)) { CLEAN_ATTRIBUTES() } // Enummerate the video capture devices hr = MFEnumDeviceSources(attributes, &devices, &count); if (FAILED(hr)) { CLEAN_ATTRIBUTES() } // if there are any available devices if (count > 0) { WCHAR *nameString = NULL; // Get the human-friendly name of the device UINT32 cchName; for (int i = 0; i < count; i++) { hr = devices[i]->GetAllocatedString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, &nameString, &cchName); std::string desc = m_webcamDescription.toStdString(); if (nameString == m_webcamDescription.toStdWString()) { m_webcamIndex = i; break; } // devices[0]->ShutdownObject(); } CoTaskMemFree(nameString); } // clean CLEAN_ATTRIBUTES() #else return true; #endif } //----------------------------------------------------------------- bool StopMotion::initWebcam(int index) { if (!m_useDirectShow) { // the webcam order obtained from Qt isn't always the same order as // the one obtained from OpenCV without DirectShow translateIndex(index); m_cvWebcam.open(m_webcamIndex); } else { m_webcamIndex = index; m_cvWebcam.open(m_webcamIndex, cv::CAP_DSHOW); } if (m_cvWebcam.isOpened() == false) { return false; } return true; } //----------------------------------------------------------------- void StopMotion::releaseWebcam() { m_cvWebcam.release(); m_liveViewStatus = 0; emit(liveViewStopped()); } //----------------------------------------------------------------- void StopMotion::setWebcamResolution(QString resolution) { m_cvWebcam.release(); // resolution is written in the itemText with the format " x // " (e.g. "800 x 600") QStringList texts = resolution.split(' '); // the splited text must be "" "x" and "" if (texts.size() != 3) return; int tempStatus = m_liveViewStatus; m_liveViewStatus = 0; bool startTimer = false; if (m_timer->isActive()) { m_timer->stop(); startTimer = true; } qApp->processEvents(QEventLoop::AllEvents, 1000); m_webcamWidth = texts[0].toInt(); m_webcamHeight = texts[2].toInt(); m_liveViewDpi = TPointD(0.0, 0.0); m_liveViewStatus = tempStatus; if (startTimer) m_timer->start(40); // update env setTEnvCameraResolution(resolution.toStdString()); refreshFrameInfo(); int index = m_webcamResolutions.indexOf(QSize(m_webcamWidth, m_webcamHeight)); emit(newWebcamResolutionSelected(index)); } //----------------------------------------------------------------- void StopMotion::getWebcamImage() { bool error = false; cv::Mat imgOriginal; cv::Mat imgCorrected; if (m_cvWebcam.isOpened() == false) { initWebcam(m_webcamIndex); // mjpg is used by many webcams // opencv runs very slow on some webcams without it. if (m_useMjpg) { m_cvWebcam.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('m', 'j', 'p', 'g')); m_cvWebcam.set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'J', 'P', 'G')); } m_cvWebcam.set(3, m_webcamWidth); m_cvWebcam.set(4, m_webcamHeight); if (!m_cvWebcam.isOpened()) { m_hasLiveViewImage = false; error = true; } } bool blnFrameReadSuccessfully = m_cvWebcam.read(imgOriginal); // get next frame if (!blnFrameReadSuccessfully || imgOriginal.empty()) { // if frame not read successfully std::cout << "error: frame not read from webcam\n"; error = true; // print error message to std out } if (!error) { cv::cvtColor(imgOriginal, imgCorrected, cv::COLOR_BGR2BGRA); cv::flip(imgCorrected, imgCorrected, 0); int width = m_cvWebcam.get(3); int height = m_cvWebcam.get(4); int size = imgCorrected.total() * imgCorrected.elemSize(); m_liveViewImage = TRaster32P(width, height); m_liveViewImage->lock(); uchar *imgBuf = imgCorrected.data; uchar *rawData = m_liveViewImage->getRawData(); memcpy(rawData, imgBuf, size); m_liveViewImage->unlock(); m_hasLiveViewImage = true; m_liveViewStatus = 2; if (m_hasLiveViewImage && (m_liveViewDpi.x == 0.0 || m_liveViewImageDimensions.lx == 0)) { TCamera *camera = TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); TDimensionD size = camera->getSize(); m_liveViewImageDimensions = TDimension(m_liveViewImage->getLx(), m_liveViewImage->getLy()); double minimumDpi = std::min(m_liveViewImageDimensions.lx / size.lx, m_liveViewImageDimensions.ly / size.ly); m_liveViewDpi = TPointD(minimumDpi, minimumDpi); m_fullImageDimensions = m_liveViewImageDimensions; m_fullImageDpi = m_liveViewDpi; emit(newDimensions()); } emit(newLiveViewImageReady()); } else m_hasLiveViewImage = false; } //----------------------------------------------------------------- void StopMotion::setUseDirectShow(int state) { m_useDirectShow = state; StopMotionUseDirectShow = state; emit(useDirectShowSignal(state)); } //----------------------------------------------------------------- bool StopMotion::toggleLiveView() { if ((m_sessionOpen || m_usingWebcam) && m_liveViewStatus == 0) { m_liveViewDpi = TPointD(0.0, 0.0); m_liveViewImageDimensions = TDimension(0, 0); if (!m_usingWebcam) { startLiveView(); } else m_liveViewStatus = 1; loadLineUpImage(); m_timer->start(40); emit(liveViewChanged(true)); Preferences::instance()->setValue(rewindAfterPlayback, false); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); return true; } else if ((m_sessionOpen || m_usingWebcam) && m_liveViewStatus > 0) { if (!m_usingWebcam) endLiveView(); else releaseWebcam(); m_timer->stop(); emit(liveViewChanged(false)); if (m_turnOnRewind) { Preferences::instance()->setValue(rewindAfterPlayback, true); } TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); return false; } else { DVGui::warning(tr("No camera selected.")); return false; } } //----------------------------------------------------------------- void StopMotion::pauseLiveView() { if (m_liveViewStatus == 2) { m_liveViewStatus = 3; m_userCalledPause = true; emit(liveViewStopped()); } else if (m_liveViewStatus == 3) { m_liveViewStatus = 2; m_userCalledPause = false; } } //----------------------------------------------------------------- EdsError StopMotion::initializeCanonSDK() { m_error = EdsInitializeSDK(); if (m_error == EDS_ERR_OK) { m_isSDKLoaded = true; } return m_error; } //----------------------------------------------------------------- EdsCameraListRef StopMotion::getCameraList() { if (!m_isSDKLoaded) initializeCanonSDK(); if (m_isSDKLoaded) { m_error = EdsGetCameraList(&m_cameraList); } return m_cameraList; } //----------------------------------------------------------------- EdsError StopMotion::releaseCameraList() { if (m_cameraList != NULL) m_error = EdsRelease(m_cameraList); return m_error; } //----------------------------------------------------------------- int StopMotion::getCameraCount() { if (m_cameraList == NULL) { getCameraList(); } if (m_cameraList != NULL) { m_error = EdsGetChildCount(m_cameraList, &m_count); if (m_count == 0) { m_error = EDS_ERR_DEVICE_NOT_FOUND; m_sessionOpen = false; m_liveViewStatus = 0; } return m_count; } else return -1; } //----------------------------------------------------------------- EdsError StopMotion::getCamera(int index) { if (m_count == 0) { m_error = EDS_ERR_DEVICE_NOT_FOUND; } if (m_count > 0) { m_error = EdsGetChildAtIndex(m_cameraList, index, &m_camera); } return m_error; } //----------------------------------------------------------------- EdsError StopMotion::releaseCamera() { if (m_camera != NULL) { m_error = EdsRelease(m_camera); } return m_error; } //----------------------------------------------------------------- void StopMotion::cameraAdded() { if (!m_active) refreshCameraList(); } //----------------------------------------------------------------- void StopMotion::closeCanonSDK() { if (m_isSDKLoaded) { EdsTerminateSDK(); } } //----------------------------------------------------------------- EdsError StopMotion::openCameraSession() { if (m_camera != NULL) { m_error = EdsOpenSession(m_camera); if (m_error == EDS_ERR_OK) m_sessionOpen = true; } m_error = EdsSetObjectEventHandler(m_camera, kEdsObjectEvent_All, StopMotion::handleObjectEvent, (EdsVoid *)this); m_error = EdsSetPropertyEventHandler(m_camera, kEdsPropertyEvent_All, StopMotion::handlePropertyEvent, (EdsVoid *)this); m_error = EdsSetCameraStateEventHandler(m_camera, kEdsStateEvent_All, StopMotion::handleStateEvent, (EdsVoid *)this); // We can't handle raw images yet, so make sure we are getting jpgs if (getCurrentImageQuality().contains("RAW")) setImageQuality("Large Fine Jpeg"); EdsUInt32 saveto = kEdsSaveTo_Host; m_error = EdsSetPropertyData(m_camera, kEdsPropID_SaveTo, 0, sizeof(EdsUInt32), &saveto); EdsCapacity newCapacity = {0x7FFFFFFF, 0x1000, 1}; m_error = EdsSetCapacity(m_camera, newCapacity); return m_error; } //----------------------------------------------------------------- EdsError StopMotion::closeCameraSession() { if (m_camera != NULL) { m_error = EdsCloseSession(m_camera); m_sessionOpen = false; } return m_error; } //----------------------------------------------------------------- void StopMotion::refreshOptions() { getAvailableShutterSpeeds(); getAvailableIso(); getAvailableApertures(); getAvailableExposureCompensations(); getAvailableWhiteBalances(); buildColorTemperatures(); getAvailableImageQualities(); getAvailablePictureStyles(); } //----------------------------------------------------------------- std::string StopMotion::getCameraName() { EdsChar name[EDS_MAX_NAME]; EdsError err = EDS_ERR_OK; EdsDataType dataType; EdsUInt32 dataSize; m_error = EdsGetPropertySize(m_camera, kEdsPropID_ProductName, 0, &dataType, &dataSize); if (m_error == EDS_ERR_OK) { m_error = EdsGetPropertyData(m_camera, kEdsPropID_ProductName, 0, dataSize, name); } m_cameraName = name; return m_cameraName; } //----------------------------------------------------------------- QString StopMotion::getMode() { EdsError err = EDS_ERR_OK; EdsDataType modeType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_AEMode, 0, &modeType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_AEMode, 0, sizeof(size), &data); return QString::fromStdString(m_modeMap[data]); } //----------------------------------------------------------------- EdsError StopMotion::getAvailableIso() { EdsPropertyDesc *IsoDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_isoOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_ISOSpeed, IsoDesc); int count = IsoDesc->numElements; if (count > 0) { int i = 0; while (i < count) { m_isoOptions.push_back( QString::fromStdString(m_isoMap[IsoDesc->propDesc[i]])); i++; } } delete IsoDesc; return err; } //----------------------------------------------------------------- EdsError StopMotion::getAvailableShutterSpeeds() { EdsPropertyDesc *TvDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_shutterSpeedOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_Tv, TvDesc); int count = TvDesc->numElements; if (count > 0) { int i = 0; while (i < count) { m_shutterSpeedOptions.push_back( QString::fromStdString(m_tvMap[TvDesc->propDesc[i]])); i++; } } delete TvDesc; return err; } //----------------------------------------------------------------- EdsError StopMotion::getAvailableApertures() { EdsPropertyDesc *AvDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_apertureOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_Av, AvDesc); int count = AvDesc->numElements; if (count > 0) { int i = 0; while (i < count) { m_apertureOptions.push_back( QString::fromStdString(m_avMap[AvDesc->propDesc[i]])); i++; } } delete AvDesc; return err; } //----------------------------------------------------------------- EdsError StopMotion::getAvailableExposureCompensations() { EdsPropertyDesc *exposureDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_exposureOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_ExposureCompensation, exposureDesc); int count = exposureDesc->numElements; if (count > 0) { int i = 0; while (i < count) { m_exposureOptions.push_back( QString::fromStdString(m_exposureMap[exposureDesc->propDesc[i]])); i++; } } delete exposureDesc; return err; } //----------------------------------------------------------------- EdsError StopMotion::getAvailableWhiteBalances() { EdsPropertyDesc *whiteBalanceDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_whiteBalanceOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_WhiteBalance, whiteBalanceDesc); int count = whiteBalanceDesc->numElements; if (count > 0) { int i = 0; while (i < count) { m_whiteBalanceOptions.push_back(QString::fromStdString( m_whiteBalanceMap[whiteBalanceDesc->propDesc[i]])); i++; } } delete whiteBalanceDesc; return err; } //----------------------------------------------------------------- EdsError StopMotion::getAvailableImageQualities() { EdsPropertyDesc *imageQualityDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_imageQualityOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_ImageQuality, imageQualityDesc); int count = imageQualityDesc->numElements; if (count > 0) { int i = 0; while (i < count) { QString quality = QString::fromStdString( m_imageQualityMap[imageQualityDesc->propDesc[i]]); if (!quality.contains("RAW")) { m_imageQualityOptions.push_back(quality); } i++; } } delete imageQualityDesc; return err; } //----------------------------------------------------------------- EdsError StopMotion::getAvailablePictureStyles() { EdsPropertyDesc *pictureStyleDesc = new EdsPropertyDesc; EdsError err = EDS_ERR_OK; m_pictureStyleOptions.clear(); err = EdsGetPropertyDesc(m_camera, kEdsPropID_PictureStyle, pictureStyleDesc); int count = pictureStyleDesc->numElements; if (count > 0) { int i = 0; while (i < count) { m_pictureStyleOptions.push_back(QString::fromStdString( m_pictureStyleMap[pictureStyleDesc->propDesc[i]])); i++; } } delete pictureStyleDesc; return err; } //----------------------------------------------------------------- void StopMotion::buildColorTemperatures() { m_colorTempOptions.clear(); int i = 2800; while (i <= 10000) { m_colorTempOptions.push_back(QString::number(i)); i += 100; } } //----------------------------------------------------------------- QString StopMotion::getCurrentShutterSpeed() { EdsError err = EDS_ERR_OK; EdsDataType tvType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_Tv, 0, &tvType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_Tv, 0, sizeof(size), &data); return QString::fromStdString(m_tvMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentIso() { EdsError err = EDS_ERR_OK; EdsDataType isoType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_ISOSpeed, 0, &isoType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_ISOSpeed, 0, sizeof(size), &data); return QString::fromStdString(m_isoMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentAperture() { EdsError err = EDS_ERR_OK; EdsDataType avType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_Av, 0, &avType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_Av, 0, sizeof(size), &data); return QString::fromStdString(m_avMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentExposureCompensation() { EdsError err = EDS_ERR_OK; EdsDataType exposureType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_ExposureCompensation, 0, &exposureType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_ExposureCompensation, 0, sizeof(size), &data); return QString::fromStdString(m_exposureMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentWhiteBalance() { EdsError err = EDS_ERR_OK; EdsDataType whiteBalanceType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_WhiteBalance, 0, &whiteBalanceType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_WhiteBalance, 0, sizeof(size), &data); std::string wbString = m_whiteBalanceMap[data]; return QString::fromStdString(m_whiteBalanceMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentImageQuality() { EdsError err = EDS_ERR_OK; EdsDataType imageQualityType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_ImageQuality, 0, &imageQualityType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_ImageQuality, 0, sizeof(size), &data); std::string wbString = m_imageQualityMap[data]; return QString::fromStdString(m_imageQualityMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentPictureStyle() { EdsError err = EDS_ERR_OK; EdsDataType pictureStyleType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_PictureStyle, 0, &pictureStyleType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_PictureStyle, 0, sizeof(size), &data); std::string wbString = m_pictureStyleMap[data]; return QString::fromStdString(m_pictureStyleMap[data]); } //----------------------------------------------------------------- QString StopMotion::getCurrentColorTemperature() { EdsError err = EDS_ERR_OK; EdsDataType colorTempType; EdsUInt32 size; EdsUInt32 data; err = EdsGetPropertySize(m_camera, kEdsPropID_ColorTemperature, 0, &colorTempType, &size); err = EdsGetPropertyData(m_camera, kEdsPropID_ColorTemperature, 0, sizeof(size), &data); return QString::number(data); } //----------------------------------------------------------------- EdsError StopMotion::setShutterSpeed(QString shutterSpeed) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_tvMap.begin(); while (it != m_tvMap.end()) { if (it->second == shutterSpeed.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_Tv, 0, sizeof(value), &value); emit(shutterSpeedChangedSignal(shutterSpeed)); return err; } //----------------------------------------------------------------- EdsError StopMotion::setIso(QString iso) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_isoMap.begin(); while (it != m_isoMap.end()) { if (it->second == iso.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_ISOSpeed, 0, sizeof(value), &value); emit(isoChangedSignal(iso)); return err; } //----------------------------------------------------------------- EdsError StopMotion::setAperture(QString aperture) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_avMap.begin(); while (it != m_avMap.end()) { if (it->second == aperture.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_Av, 0, sizeof(value), &value); emit(apertureChangedSignal(aperture)); return err; } //----------------------------------------------------------------- EdsError StopMotion::setExposureCompensation(QString exposure) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_exposureMap.begin(); while (it != m_exposureMap.end()) { if (it->second == exposure.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_ExposureCompensation, 0, sizeof(value), &value); emit(exposureChangedSignal(exposure)); return err; } //----------------------------------------------------------------- EdsError StopMotion::setWhiteBalance(QString whiteBalance) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_whiteBalanceMap.begin(); while (it != m_whiteBalanceMap.end()) { if (it->second == whiteBalance.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_WhiteBalance, 0, sizeof(value), &value); emit(whiteBalanceChangedSignal(whiteBalance)); return err; } //----------------------------------------------------------------- EdsError StopMotion::setImageQuality(QString quality) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_imageQualityMap.begin(); while (it != m_imageQualityMap.end()) { if (it->second == quality.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_ImageQuality, 0, sizeof(value), &value); emit(imageQualityChangedSignal(quality)); m_proxyImageDimensions = TDimension(0, 0); m_proxyDpi = TPointD(0.0, 0.0); return err; } //----------------------------------------------------------------- EdsError StopMotion::setPictureStyle(QString style) { EdsError err = EDS_ERR_OK; EdsUInt32 value; auto it = m_pictureStyleMap.begin(); while (it != m_pictureStyleMap.end()) { if (it->second == style.toStdString()) { value = it->first; break; } it++; } err = EdsSetPropertyData(m_camera, kEdsPropID_PictureStyle, 0, sizeof(value), &value); err = EdsSetPropertyData(m_camera, kEdsPropID_PictureStyle, 0, sizeof(value), &value); emit(pictureStyleChangedSignal(style)); return err; } //----------------------------------------------------------------- EdsError StopMotion::setColorTemperature(QString temp) { EdsError err = EDS_ERR_OK; EdsUInt32 value; value = temp.toInt(); err = EdsSetPropertyData(m_camera, kEdsPropID_ColorTemperature, 0, sizeof(value), &value); err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_ColorTemperature, 0, sizeof(value), &value); emit(colorTemperatureChangedSignal(temp)); return err; } //----------------------------------------------------------------- EdsError StopMotion::downloadImage(EdsBaseRef object) { EdsError err = EDS_ERR_OK; EdsStreamRef stream = NULL; EdsDirectoryItemInfo dirItemInfo; err = EdsGetDirectoryItemInfo(object, &dirItemInfo); err = EdsCreateMemoryStream(0, &stream); err = EdsDownload(object, dirItemInfo.size, stream); EdsDownloadComplete(object); // tj code unsigned __int64 mySize = 0; unsigned char *data = NULL; err = EdsGetPointer(stream, (EdsVoid **)&data); err = EdsGetLength(stream, &mySize); int width, height, pixelFormat; // long size; int inSubsamp, inColorspace; // unsigned long jpegSize; tjhandle tjInstance = NULL; unsigned char *imgBuf = NULL; tjInstance = tjInitDecompress(); tjDecompressHeader3(tjInstance, data, mySize, &width, &height, &inSubsamp, &inColorspace); pixelFormat = TJPF_BGRX; imgBuf = (unsigned char *)tjAlloc(width * height * tjPixelSize[pixelFormat]); int flags = 0; #ifdef WIN32 flags |= TJFLAG_BOTTOMUP; #endif int tempWidth, tempHeight; if (m_useScaledImages) { int factorsNum; tjscalingfactor scalingFactor = {1, 1}; tjscalingfactor *factor = tjGetScalingFactors(&factorsNum); int intRatio = (float)width / (float)height * 100.0; int i = 0; TCamera *camera = TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); TDimension res = camera->getRes(); // find the scaling factor that is at least as big as the current camera while (i < factorsNum) { scalingFactor = factor[i]; tempWidth = TJSCALED(width, scalingFactor); if (tempWidth < res.lx && i > 0) { scalingFactor = factor[i - 1]; break; } i++; } // make sure the scaling factor has the right aspect ratio while (i >= 0) { tempWidth = TJSCALED(width, scalingFactor); tempHeight = TJSCALED(height, scalingFactor); if ((int)((float)tempWidth / (float)tempHeight * 100.0) == intRatio) { break; } i--; scalingFactor = factor[i]; } } else { tempWidth = width; tempHeight = height; } if (m_useScaledImages || !getCurrentImageQuality().contains("Large")) { TCamera *camera = TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); TDimensionD size = camera->getSize(); m_proxyImageDimensions = TDimension(tempWidth, tempHeight); double minimumDpi = std::min(m_proxyImageDimensions.lx / size.lx, m_proxyImageDimensions.ly / size.ly); m_proxyDpi = TPointD(minimumDpi, minimumDpi); } tjDecompress2(tjInstance, data, mySize, imgBuf, tempWidth, tempWidth * tjPixelSize[pixelFormat], tempHeight, pixelFormat, flags); m_newImage = TRaster32P(tempWidth, tempHeight); m_newImage->lock(); uchar *rawData = m_newImage->getRawData(); memcpy(rawData, imgBuf, tempWidth * tempHeight * tjPixelSize[pixelFormat]); m_newImage->unlock(); tjFree(imgBuf); imgBuf = NULL; tjDestroy(tjInstance); tjInstance = NULL; // end tj code if (m_useScaledImages) { QFile fullImage(m_tempFile); fullImage.open(QIODevice::WriteOnly); QDataStream dataStream(&fullImage); dataStream.writeRawData((const char *)data, mySize); fullImage.close(); } EdsRelease(stream); stream = NULL; if (object) EdsRelease(object); if (err == EDS_ERR_OK) { emit(newImageReady()); } return err; } //----------------------------------------------------------------- EdsError StopMotion::takePicture() { EdsError err; err = EdsSendCommand(m_camera, kEdsCameraCommand_PressShutterButton, kEdsCameraCommand_ShutterButton_Completely_NonAF); err = EdsSendCommand(m_camera, kEdsCameraCommand_PressShutterButton, kEdsCameraCommand_ShutterButton_OFF); return err; } //----------------------------------------------------------------- EdsError StopMotion::startLiveView() { if (m_camera && m_sessionOpen) { EdsError err = EDS_ERR_OK; // Get the output device for the live view image EdsUInt32 device; err = EdsGetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); // PC live view starts by setting the PC as the output device for the live // view image. if (err == EDS_ERR_OK) { device |= kEdsEvfOutputDevice_PC; err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); } if (err == EDS_ERR_OK) { m_liveViewStatus = LiveViewStarting; } // A property change event notification is issued from the camera if // property settings are made successfully. Start downloading of the live // view image once the property change notification arrives. return err; } else return EDS_ERR_DEVICE_NOT_FOUND; } //----------------------------------------------------------------- EdsError StopMotion::endLiveView() { EdsError err = EDS_ERR_OK; // Get the output device for the live view image EdsUInt32 device; err = EdsGetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); // PC live view ends if the PC is disconnected from the live view image output // device. if (err == EDS_ERR_OK) { device &= ~kEdsEvfOutputDevice_PC; err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_OutputDevice, 0, sizeof(device), &device); } m_liveViewStatus = LiveViewClosed; return err; } //----------------------------------------------------------------- EdsError StopMotion::zoomLiveView() { if (!m_sessionOpen) return EDS_ERR_DEVICE_INVALID; EdsError err = EDS_ERR_OK; if (m_liveViewZoom == 1) { m_liveViewZoom = 5; m_zooming = true; } else if (m_liveViewZoom == 5) { m_liveViewZoom = 1; m_zooming = false; } err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_Zoom, 0, sizeof(m_liveViewZoom), &m_liveViewZoom); if (m_liveViewZoom == 5) setZoomPoint(); return err; } //----------------------------------------------------------------- void StopMotion::makeZoomPoint(TPointD pos) { m_liveViewZoomPickPoint = pos; double maxFullWidth = (double)m_fullImageDimensions.lx / m_fullImageDpi.x * Stage::inch; double maxFullHeight = (double)m_fullImageDimensions.ly / m_fullImageDpi.y * Stage::inch; double newX = m_liveViewZoomPickPoint.x + maxFullWidth / 2.0; double newY = -m_liveViewZoomPickPoint.y + maxFullHeight / 2.0; m_calculatedZoomPoint.x = newX / Stage::inch * m_fullImageDpi.x; m_calculatedZoomPoint.y = newY / Stage::inch * m_fullImageDpi.x; } //----------------------------------------------------------------- EdsError StopMotion::setZoomPoint() { EdsError err = EDS_ERR_OK; EdsPoint zoomPoint; if (m_liveViewZoomPickPoint == TPointD(0.0, 0.0)) { m_calculatedZoomPoint = TPoint(m_fullImageDimensions.lx / 2, m_fullImageDimensions.ly / 2); m_finalZoomPoint.x = m_calculatedZoomPoint.x - (m_zoomRect.x / 2); m_finalZoomPoint.y = m_calculatedZoomPoint.y - (m_zoomRect.y / 2); } else { m_finalZoomPoint.x = m_calculatedZoomPoint.x - (m_zoomRect.x / 2); m_finalZoomPoint.y = m_calculatedZoomPoint.y - (m_zoomRect.y / 2); if (m_finalZoomPoint.x < 0) m_finalZoomPoint.x = 0; if (m_finalZoomPoint.y < 0) m_finalZoomPoint.y = 0; if (m_finalZoomPoint.x > m_fullImageDimensions.lx - (m_zoomRect.x)) { m_finalZoomPoint.x = m_fullImageDimensions.lx - (m_zoomRect.x); } if (m_finalZoomPoint.y > m_fullImageDimensions.ly - (m_zoomRect.y)) { m_finalZoomPoint.y = m_fullImageDimensions.ly - (m_zoomRect.y); } } zoomPoint.x = m_finalZoomPoint.x; zoomPoint.y = m_finalZoomPoint.y; // make sure this is set AFTER starting zoom err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_ZoomPosition, 0, sizeof(zoomPoint), &zoomPoint); return err; } //----------------------------------------------------------------- EdsError StopMotion::downloadEVFData() { EdsError err = EDS_ERR_OK; EdsStreamRef stream = NULL; EdsEvfImageRef evfImage = NULL; // Create memory stream. err = EdsCreateMemoryStream(0, &stream); // Create EvfImageRef. if (err == EDS_ERR_OK) { err = EdsCreateEvfImageRef(stream, &evfImage); } // Download live view image data. if (err == EDS_ERR_OK) { err = EdsDownloadEvfImage(m_camera, evfImage); } EdsDataType evfZoom; EdsDataType evfZoomPos; EdsDataType evfZoomRect; EdsUInt32 size; EdsUInt32 sizePos; EdsUInt32 sizeRect; EdsUInt32 sizeImagePos; EdsUInt32 sizeCoordSys; EdsUInt32 zoomAmount; EdsPoint zoomPos; EdsRect zoomRect; EdsPoint imagePos; EdsSize coordSys; err = EdsGetPropertySize(evfImage, kEdsPropID_Evf_Zoom, 0, &evfZoom, &size); err = EdsGetPropertyData(evfImage, kEdsPropID_Evf_Zoom, 0, sizeof(size), &zoomAmount); // this is the top corner? of the zoomed image err = EdsGetPropertySize(evfImage, kEdsPropID_Evf_ZoomPosition, 0, &evfZoomPos, &sizePos); err = EdsGetPropertyData(evfImage, kEdsPropID_Evf_ZoomPosition, 0, sizePos, &zoomPos); // this is the top corner of the zoomed image and the size of the zoomed image err = EdsGetPropertySize(evfImage, kEdsPropID_Evf_ZoomRect, 0, &evfZoomRect, &sizeRect); err = EdsGetPropertyData(evfImage, kEdsPropID_Evf_ZoomRect, 0, sizeRect, &zoomRect); err = EdsGetPropertySize(evfImage, kEdsPropID_Evf_ImagePosition, 0, &evfZoomRect, &sizeImagePos); err = EdsGetPropertyData(evfImage, kEdsPropID_Evf_ImagePosition, 0, sizeImagePos, &imagePos); // this returns the size of the full image err = EdsGetPropertySize(evfImage, kEdsPropID_Evf_CoordinateSystem, 0, &evfZoomRect, &sizeCoordSys); err = EdsGetPropertyData(evfImage, kEdsPropID_Evf_CoordinateSystem, 0, sizeCoordSys, &coordSys); m_zoomRect = TPoint(zoomRect.size.width, zoomRect.size.height); if (zoomAmount == 5 && m_zoomRect == TPoint(0, 0)) { setZoomPoint(); } // Get the incidental data of the image. if (err == EDS_ERR_OK) { JpgConverter *converter = new JpgConverter; converter->setStream(stream); converter->setScale(m_useScaledImages); connect(converter, SIGNAL(imageReady(bool)), this, SLOT(onImageReady(bool)), Qt::QueuedConnection); connect(converter, SIGNAL(finished()), this, SLOT(onFinished()), Qt::QueuedConnection); converter->start(); while (!l_quitLoop) QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents); l_quitLoop = false; m_liveViewImage = converter->getImage(); m_hasLiveViewImage = true; delete converter; if (!m_converterSucceeded) return EDS_ERR_UNEXPECTED_EXCEPTION; // make sure not to set to LiveViewOpen if it has been turned off if (m_liveViewStatus > 0) { m_liveViewStatus = LiveViewOpen; } emit(newLiveViewImageReady()); if (m_hasLiveViewImage && (m_liveViewDpi.x == 0.0 || m_liveViewImageDimensions.lx == 0)) { TCamera *camera = TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera(); TDimensionD size = camera->getSize(); m_liveViewImageDimensions = TDimension(m_liveViewImage->getLx(), m_liveViewImage->getLy()); double minimumDpi = std::min(m_liveViewImageDimensions.lx / size.lx, m_liveViewImageDimensions.ly / size.ly); m_liveViewDpi = TPointD(minimumDpi, minimumDpi); m_fullImageDimensions = TDimension(coordSys.width, coordSys.height); minimumDpi = std::min(m_fullImageDimensions.lx / size.lx, m_fullImageDimensions.ly / size.ly); m_fullImageDpi = TPointD(minimumDpi, minimumDpi); emit(newDimensions()); } } if (stream != NULL) { EdsRelease(stream); } stream = NULL; if (evfImage != NULL) { EdsRelease(evfImage); evfImage = NULL; } // calculate dpi data return err; } //----------------------------------------------------------------- EdsError StopMotion::focusNear() { EdsError err = EDS_ERR_OK; err = EdsSendCommand(m_camera, kEdsCameraCommand_DriveLensEvf, kEdsEvfDriveLens_Near1); return err; } //----------------------------------------------------------------- EdsError StopMotion::focusFar() { EdsError err = EDS_ERR_OK; err = EdsSendCommand(m_camera, kEdsCameraCommand_DriveLensEvf, kEdsEvfDriveLens_Far1); return err; } //----------------------------------------------------------------- EdsError StopMotion::focusNear2() { EdsError err = EDS_ERR_OK; err = EdsSendCommand(m_camera, kEdsCameraCommand_DriveLensEvf, kEdsEvfDriveLens_Near2); return err; } //----------------------------------------------------------------- EdsError StopMotion::focusFar2() { EdsError err = EDS_ERR_OK; err = EdsSendCommand(m_camera, kEdsCameraCommand_DriveLensEvf, kEdsEvfDriveLens_Far2); return err; } //----------------------------------------------------------------- EdsError StopMotion::focusNear3() { EdsError err = EDS_ERR_OK; err = EdsSendCommand(m_camera, kEdsCameraCommand_DriveLensEvf, kEdsEvfDriveLens_Near3); return err; } //----------------------------------------------------------------- EdsError StopMotion::focusFar3() { EdsError err = EDS_ERR_OK; err = EdsSendCommand(m_camera, kEdsCameraCommand_DriveLensEvf, kEdsEvfDriveLens_Far3); return err; } //----------------------------------------------------------------- void StopMotion::onImageReady(const bool &status) { m_converterSucceeded = status; } //----------------------------------------------------------------- void StopMotion::onFinished() { l_quitLoop = true; } //----------------------------------------------------------------- //----------------------------------------------------------------- EdsError StopMotion::handleObjectEvent(EdsObjectEvent event, EdsBaseRef object, EdsVoid *context) { if (event == kEdsObjectEvent_DirItemRequestTransfer) { instance()->downloadImage(object); } return EDS_ERR_OK; } //----------------------------------------------------------------- EdsError StopMotion::handlePropertyEvent(EdsPropertyEvent event, EdsPropertyID property, EdsUInt32 param, EdsVoid *context) { if (property == kEdsPropID_Evf_OutputDevice && event == kEdsPropertyEvent_PropertyChanged) { if (instance()->m_liveViewStatus == LiveViewStarting) instance()->m_liveViewStatus = LiveViewOpen; } if (property == kEdsPropID_AEMode && event == kEdsPropertyEvent_PropertyChanged) { emit(instance()->modeChanged()); } if (property == kEdsPropID_Av && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->apertureOptionsChanged()); } if (property == kEdsPropID_Tv && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->shutterSpeedOptionsChanged()); } if (property == kEdsPropID_ISOSpeed && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->isoOptionsChanged()); } if (property == kEdsPropID_ExposureCompensation && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->exposureOptionsChanged()); } if (property == kEdsPropID_WhiteBalance && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->whiteBalanceOptionsChanged()); } if (property == kEdsPropID_PictureStyle && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->pictureStyleOptionsChanged()); } if (property == kEdsPropID_ImageQuality && event == kEdsPropertyEvent_PropertyDescChanged) { emit(instance()->imageQualityOptionsChanged()); } return EDS_ERR_OK; } //----------------------------------------------------------------- EdsError StopMotion::handleStateEvent(EdsStateEvent event, EdsUInt32 parameter, EdsVoid *context) { if (event == kEdsStateEvent_Shutdown) { if (instance()->m_sessionOpen) { instance()->closeCameraSession(); instance()->releaseCamera(); instance()->m_liveViewStatus = LiveViewClosed; emit(instance()->cameraChanged()); } } return EDS_ERR_OK; } //----------------------------------------------------------------- EdsError StopMotion::handleCameraAddedEvent(EdsVoid *context) { instance()->cameraAdded(); return EDS_ERR_OK; } //----------------------------------------------------------------- void StopMotion::buildAvMap() { m_avMap.insert(std::pair(0x00, "00")); m_avMap.insert(std::pair(0x08, "1")); m_avMap.insert(std::pair(0x0B, "1.1")); m_avMap.insert(std::pair(0x0C, "1.2")); m_avMap.insert(std::pair(0x0D, "1.2")); m_avMap.insert(std::pair(0x10, "1.4")); m_avMap.insert(std::pair(0x13, "1.6")); m_avMap.insert(std::pair(0x14, "1.8")); m_avMap.insert(std::pair(0x15, "1.8")); m_avMap.insert(std::pair(0x18, "2")); m_avMap.insert(std::pair(0x1B, "2.2")); m_avMap.insert(std::pair(0x1C, "2.5")); m_avMap.insert(std::pair(0x1D, "2.5")); m_avMap.insert(std::pair(0x20, "2.8")); m_avMap.insert(std::pair(0x23, "3.2")); m_avMap.insert(std::pair(0x24, "3.5")); m_avMap.insert(std::pair(0x25, "3.5")); m_avMap.insert(std::pair(0x28, "4")); m_avMap.insert(std::pair(0x2B, "4.5")); m_avMap.insert(std::pair(0x2C, "4.5")); m_avMap.insert(std::pair(0x2D, "5.0")); m_avMap.insert(std::pair(0x30, "5.6")); m_avMap.insert(std::pair(0x33, "6.3")); m_avMap.insert(std::pair(0x34, "6.7")); m_avMap.insert(std::pair(0x35, "7.1")); m_avMap.insert(std::pair(0x38, "8")); m_avMap.insert(std::pair(0x3B, "9")); m_avMap.insert(std::pair(0x3C, "9.5")); m_avMap.insert(std::pair(0x3D, "10")); m_avMap.insert(std::pair(0x40, "11")); m_avMap.insert(std::pair(0x43, "13")); m_avMap.insert(std::pair(0x44, "13")); m_avMap.insert(std::pair(0x45, "14")); m_avMap.insert(std::pair(0x48, "16")); m_avMap.insert(std::pair(0x4B, "18")); m_avMap.insert(std::pair(0x4C, "19")); m_avMap.insert(std::pair(0x4D, "20")); m_avMap.insert(std::pair(0x50, "22")); m_avMap.insert(std::pair(0x53, "25")); m_avMap.insert(std::pair(0x54, "27")); m_avMap.insert(std::pair(0x55, "29")); m_avMap.insert(std::pair(0x58, "32")); m_avMap.insert(std::pair(0x5B, "36")); m_avMap.insert(std::pair(0x5C, "38")); m_avMap.insert(std::pair(0x5D, "40")); m_avMap.insert(std::pair(0x60, "45")); m_avMap.insert(std::pair(0x63, "51")); m_avMap.insert(std::pair(0x64, "54")); m_avMap.insert(std::pair(0x65, "57")); m_avMap.insert(std::pair(0x68, "64")); m_avMap.insert(std::pair(0x6B, "72")); m_avMap.insert(std::pair(0x6C, "76")); m_avMap.insert(std::pair(0x6D, "80")); m_avMap.insert(std::pair(0x70, "91")); m_avMap.insert(std::pair(0xFF, "Auto")); m_avMap.insert(std::pair(0xffffffff, "unknown")); } //----------------------------------------------------------------- void StopMotion::buildIsoMap() { m_isoMap.insert(std::pair(0x00, "Auto")); m_isoMap.insert(std::pair(0x28, "6")); m_isoMap.insert(std::pair(0x30, "12")); m_isoMap.insert(std::pair(0x38, "25")); m_isoMap.insert(std::pair(0x40, "50")); m_isoMap.insert(std::pair(0x48, "100")); m_isoMap.insert(std::pair(0x4b, "125")); m_isoMap.insert(std::pair(0x4d, "160")); m_isoMap.insert(std::pair(0x50, "200")); m_isoMap.insert(std::pair(0x53, "250")); m_isoMap.insert(std::pair(0x55, "320")); m_isoMap.insert(std::pair(0x58, "400")); m_isoMap.insert(std::pair(0x5b, "500")); m_isoMap.insert(std::pair(0x5d, "640")); m_isoMap.insert(std::pair(0x60, "800")); m_isoMap.insert(std::pair(0x63, "1000")); m_isoMap.insert(std::pair(0x65, "1250")); m_isoMap.insert(std::pair(0x68, "1600")); m_isoMap.insert(std::pair(0x6b, "2000")); m_isoMap.insert(std::pair(0x6d, "2500")); m_isoMap.insert(std::pair(0x70, "3200")); m_isoMap.insert(std::pair(0x73, "4000")); m_isoMap.insert(std::pair(0x75, "5000")); m_isoMap.insert(std::pair(0x78, "6400")); m_isoMap.insert(std::pair(0x7b, "8000")); m_isoMap.insert(std::pair(0x7d, "10000")); m_isoMap.insert(std::pair(0x80, "12800")); m_isoMap.insert(std::pair(0x83, "16000")); m_isoMap.insert(std::pair(0x85, "20000")); m_isoMap.insert(std::pair(0x88, "25600")); m_isoMap.insert(std::pair(0x8b, "32000")); m_isoMap.insert(std::pair(0x8d, "40000")); m_isoMap.insert(std::pair(0x90, "51200")); m_isoMap.insert(std::pair(0x98, "102400")); m_isoMap.insert(std::pair(0xa0, "204800")); m_isoMap.insert(std::pair(0xa8, "409600")); m_isoMap.insert(std::pair(0xffffffff, "unknown")); } //----------------------------------------------------------------- void StopMotion::buildTvMap() { m_tvMap.insert(std::pair(0x04, "Auto")); m_tvMap.insert(std::pair(0x0c, "Bulb")); m_tvMap.insert(std::pair(0x10, "30\"")); m_tvMap.insert(std::pair(0x13, "25\"")); m_tvMap.insert(std::pair(0x14, "20\"")); m_tvMap.insert(std::pair(0x15, "20\"")); m_tvMap.insert(std::pair(0x18, "15\"")); m_tvMap.insert(std::pair(0x1B, "13\"")); m_tvMap.insert(std::pair(0x1C, "10\"")); m_tvMap.insert(std::pair(0x1D, "10\"")); m_tvMap.insert(std::pair(0x20, "8\"")); m_tvMap.insert(std::pair(0x23, "6\"")); m_tvMap.insert(std::pair(0x24, "6\"")); m_tvMap.insert(std::pair(0x25, "5\"")); m_tvMap.insert(std::pair(0x28, "4\"")); m_tvMap.insert(std::pair(0x2B, "3\"2")); m_tvMap.insert(std::pair(0x2C, "3\"")); m_tvMap.insert(std::pair(0x2D, "2\"5")); m_tvMap.insert(std::pair(0x30, "2\"")); m_tvMap.insert(std::pair(0x33, "1\"6")); m_tvMap.insert(std::pair(0x34, "1\"5")); m_tvMap.insert(std::pair(0x35, "1\"3")); m_tvMap.insert(std::pair(0x38, "1\"")); m_tvMap.insert(std::pair(0x3B, "0\"8")); m_tvMap.insert(std::pair(0x3C, "0\"7")); m_tvMap.insert(std::pair(0x3D, "0\"6")); m_tvMap.insert(std::pair(0x40, "0\"5")); m_tvMap.insert(std::pair(0x43, "0\"4")); m_tvMap.insert(std::pair(0x44, "0\"3")); m_tvMap.insert(std::pair(0x45, "0\"3")); m_tvMap.insert(std::pair(0x48, "1/4")); m_tvMap.insert(std::pair(0x4B, "1/5")); m_tvMap.insert(std::pair(0x4C, "1/6")); m_tvMap.insert(std::pair(0x4D, "1/6")); m_tvMap.insert(std::pair(0x50, "1/8")); m_tvMap.insert(std::pair(0x53, "1/10")); m_tvMap.insert(std::pair(0x54, "1/10")); m_tvMap.insert(std::pair(0x55, "1/13")); m_tvMap.insert(std::pair(0x58, "1/15")); m_tvMap.insert(std::pair(0x5B, "1/20")); m_tvMap.insert(std::pair(0x5C, "1/20")); m_tvMap.insert(std::pair(0x5D, "1/25")); m_tvMap.insert(std::pair(0x60, "1/30")); m_tvMap.insert(std::pair(0x63, "1/40")); m_tvMap.insert(std::pair(0x64, "1/45")); m_tvMap.insert(std::pair(0x65, "1/50")); m_tvMap.insert(std::pair(0x68, "1/60")); m_tvMap.insert(std::pair(0x6B, "1/80")); m_tvMap.insert(std::pair(0x6C, "1/90")); m_tvMap.insert(std::pair(0x6D, "1/100")); m_tvMap.insert(std::pair(0x70, "1/125")); m_tvMap.insert(std::pair(0x73, "1/160")); m_tvMap.insert(std::pair(0x74, "1/180")); m_tvMap.insert(std::pair(0x75, "1/200")); m_tvMap.insert(std::pair(0x78, "1/250")); m_tvMap.insert(std::pair(0x7B, "1/320")); m_tvMap.insert(std::pair(0x7C, "1/350")); m_tvMap.insert(std::pair(0x7D, "1/400")); m_tvMap.insert(std::pair(0x80, "1/500")); m_tvMap.insert(std::pair(0x83, "1/640")); m_tvMap.insert(std::pair(0x84, "1/750")); m_tvMap.insert(std::pair(0x85, "1/800")); m_tvMap.insert(std::pair(0x88, "1/1000")); m_tvMap.insert(std::pair(0x8B, "1/1250")); m_tvMap.insert(std::pair(0x8C, "1/1500")); m_tvMap.insert(std::pair(0x8D, "1/1600")); m_tvMap.insert(std::pair(0x90, "1/2000")); m_tvMap.insert(std::pair(0x93, "1/2500")); m_tvMap.insert(std::pair(0x94, "1/3000")); m_tvMap.insert(std::pair(0x95, "1/3200")); m_tvMap.insert(std::pair(0x98, "1/4000")); m_tvMap.insert(std::pair(0x9B, "1/5000")); m_tvMap.insert(std::pair(0x9C, "1/6000")); m_tvMap.insert(std::pair(0x9D, "1/6400")); m_tvMap.insert(std::pair(0xA0, "1/8000")); m_tvMap.insert(std::pair(0xffffffff, "unknown")); } //----------------------------------------------------------------- void StopMotion::buildModeMap() { m_modeMap.insert(std::pair(0, "P")); m_modeMap.insert(std::pair(1, "Tv")); m_modeMap.insert(std::pair(2, "Av")); m_modeMap.insert(std::pair(3, "M")); m_modeMap.insert(std::pair(55, "FV")); m_modeMap.insert(std::pair(4, "Bulb")); m_modeMap.insert(std::pair(5, "A-DEP")); m_modeMap.insert(std::pair(6, "DEP")); m_modeMap.insert(std::pair(7, "C1")); m_modeMap.insert(std::pair(16, "C2")); m_modeMap.insert(std::pair(17, "C3")); m_modeMap.insert(std::pair(8, "Lock")); m_modeMap.insert(std::pair(9, "GreenMode")); m_modeMap.insert(std::pair(10, "Night Portrait")); m_modeMap.insert(std::pair(11, "Sports")); m_modeMap.insert(std::pair(13, "LandScape")); m_modeMap.insert(std::pair(14, "Close-Up")); m_modeMap.insert(std::pair(15, "No Strobo")); m_modeMap.insert(std::pair(12, "Portrait")); m_modeMap.insert(std::pair(19, "Creative Auto")); m_modeMap.insert(std::pair(20, "Movies")); m_modeMap.insert(std::pair(25, "SCN")); m_modeMap.insert( std::pair(22, "Scene Intelligent Auto")); m_modeMap.insert(std::pair(29, "Creative filters")); m_modeMap.insert(std::pair(0xffffffff, "unknown")); } //----------------------------------------------------------------- void StopMotion::buildExposureMap() { m_exposureMap.insert(std::pair(0x28, "+5")); m_exposureMap.insert(std::pair(0x25, "+4 2/3")); m_exposureMap.insert(std::pair(0x24, "+4 1/2")); m_exposureMap.insert(std::pair(0x23, "+4 1/3")); m_exposureMap.insert(std::pair(0x20, "+4")); m_exposureMap.insert(std::pair(0x1D, "+3 2/3")); m_exposureMap.insert(std::pair(0x1C, "+3 1/2")); m_exposureMap.insert(std::pair(0x1B, "+3 1/3")); m_exposureMap.insert(std::pair(0x18, "+3")); m_exposureMap.insert(std::pair(0x15, "+2 2/3")); m_exposureMap.insert(std::pair(0x14, "+2 1/2")); m_exposureMap.insert(std::pair(0x13, "+2 1/3")); m_exposureMap.insert(std::pair(0x10, "+2")); m_exposureMap.insert(std::pair(0x0d, "+1 2/3")); m_exposureMap.insert(std::pair(0x0c, "+1 1/2")); m_exposureMap.insert(std::pair(0x0b, "+1 1/3")); m_exposureMap.insert(std::pair(0x08, "+1")); m_exposureMap.insert(std::pair(0x05, "+2/3")); m_exposureMap.insert(std::pair(0x04, "+1/2")); m_exposureMap.insert(std::pair(0x03, "+1/3")); m_exposureMap.insert(std::pair(0x00, "0")); m_exposureMap.insert(std::pair(0xfd, "-1/3")); m_exposureMap.insert(std::pair(0xfc, "-1/2")); m_exposureMap.insert(std::pair(0xfb, "-2/3")); m_exposureMap.insert(std::pair(0xf8, "-1")); m_exposureMap.insert(std::pair(0xf5, "-1 1/3")); m_exposureMap.insert(std::pair(0xf4, "-1 1/2")); m_exposureMap.insert(std::pair(0xf3, "-1 2/3")); m_exposureMap.insert(std::pair(0xf0, "-2")); m_exposureMap.insert(std::pair(0xed, "-2 1/3")); m_exposureMap.insert(std::pair(0xec, "-2 1/2")); m_exposureMap.insert(std::pair(0xeb, "-2 2/3")); m_exposureMap.insert(std::pair(0xe8, "-3")); m_exposureMap.insert(std::pair(0xE5, "-3 1/3")); m_exposureMap.insert(std::pair(0xE4, "-3 1/2")); m_exposureMap.insert(std::pair(0xE3, "-3 2/3")); m_exposureMap.insert(std::pair(0xE0, "-4")); m_exposureMap.insert(std::pair(0xDD, "-4 1/3")); m_exposureMap.insert(std::pair(0xDC, "-4 1/2")); m_exposureMap.insert(std::pair(0xDB, "-4 2/3")); m_exposureMap.insert(std::pair(0xD8, "-5")); m_exposureMap.insert( std::pair(0xffffffff, "unknown")); } //----------------------------------------------------------------- void StopMotion::buildWhiteBalanceMap() { m_whiteBalanceMap.insert( std::pair(0, "Auto: Ambience Priority")); m_whiteBalanceMap.insert(std::pair(1, "Daylight")); m_whiteBalanceMap.insert(std::pair(2, "Cloudy")); m_whiteBalanceMap.insert(std::pair(3, "Tungsten")); m_whiteBalanceMap.insert( std::pair(4, "Fluorescent")); m_whiteBalanceMap.insert(std::pair(5, "Flash")); m_whiteBalanceMap.insert(std::pair(6, "Manual")); m_whiteBalanceMap.insert(std::pair(8, "Shade")); m_whiteBalanceMap.insert( std::pair(9, "Color Temperature")); m_whiteBalanceMap.insert(std::pair(10, "Custom 1")); m_whiteBalanceMap.insert(std::pair(11, "Custom 2")); m_whiteBalanceMap.insert(std::pair(12, "Custom 3")); m_whiteBalanceMap.insert(std::pair(15, "Manual 2")); m_whiteBalanceMap.insert(std::pair(16, "Manual 3")); m_whiteBalanceMap.insert(std::pair(18, "Manual 4")); m_whiteBalanceMap.insert(std::pair(19, "Manual 5")); m_whiteBalanceMap.insert(std::pair(20, "Custom 4")); m_whiteBalanceMap.insert(std::pair(21, "Custom 5")); m_whiteBalanceMap.insert( std::pair(23, "Auto: White Priority")); } //----------------------------------------------------------------- void StopMotion::buildImageQualityMap() { m_imageQualityMap.insert( std::pair(EdsImageQuality_LR, "RAW")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRLJF, "RAW + Large Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRMJF, "RAW + Middle Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRSJF, "RAW + Small Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRLJN, "RAW + Large Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRMJN, "RAW + Middle Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRSJN, "RAW + Small Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRS1JF, "RAW + Small1 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRS1JN, "RAW + Small1 Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRS2JF, "RAW + Small2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRS3JF, "RAW + Small3 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRLJ, "RAW + Large Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRM1J, "RAW + Middle1 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRM2J, "RAW + Middle2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LRSJ, "RAW + Small Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MR, "Middle Raw(Small RAW1)")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRLJF, "Middle Raw(Small RAW1) + Large Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRMJF, "Middle Raw(Small RAW1) + Middle Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRSJF, "Middle Raw(Small RAW1) + Small Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRLJN, "Middle Raw(Small RAW1) + Large Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRMJN, "Middle Raw(Small RAW1) + Middle Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRSJN, "Middle Raw(Small RAW1) + Small Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRS1JF, "Middle RAW + Small1 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRS1JN, "Middle RAW + Small1 Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRS2JF, "Middle RAW + Small2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRS3JF, "Middle RAW + Small3 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRLJ, "Middle Raw + Large Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRM1J, "Middle Raw + Middle1 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRM2J, "Middle Raw + Middle2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MRSJ, "Middle Raw + Small Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SR, "Small RAW(Small RAW2)")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRLJF, "Small RAW(Small RAW2) + Large Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRMJF, "Small RAW(Small RAW2) + Middle Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRSJF, "Small RAW(Small RAW2) + Small Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRLJN, "Small RAW(Small RAW2) + Large Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRMJN, "Small RAW(Small RAW2) + Middle Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRSJN, "Small RAW(Small RAW2) + Small Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRS1JF, "Small RAW + Small1 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRS1JN, "Small RAW + Small1 Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRS2JF, "Small RAW + Small2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRS3JF, "Small RAW + Small3 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRLJ, "Small RAW + Large Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRM1J, "Small RAW + Middle1 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRM2J, "Small RAW + Middle2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SRSJ, "Small RAW + Small Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_CR, "CRAW")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRLJF, "CRAW + Large Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRMJF, "CRAW + Middle Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRM1JF, "CRAW + Middle1 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRM2JF, "CRAW + Middle2 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRSJF, "CRAW + Small Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRS1JF, "CRAW + Small1 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRS2JF, "CRAW + Small2 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRS3JF, "CRAW + Small3 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRLJN, "CRAW + Large Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRMJN, "CRAW + Middle Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRM1JN, "CRAW + Middle1 Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRM2JN, "CRAW + Middle2 Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRSJN, "CRAW + Small Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRS1JN, "CRAW + Small1 Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRLJ, "CRAW + Large Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRM1J, "CRAW + Middle1 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRM2J, "CRAW + Middle2 Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_CRSJ, "CRAW + Small Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LJF, "Large Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_LJN, "Large Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MJF, "Middle Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_MJN, "Middle Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SJF, "Small Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_SJN, "Small Normal Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_S1JF, "Small1 Fine Jpeg")); m_imageQualityMap.insert(std::pair( EdsImageQuality_S1JN, "Small1 Normal Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_S2JF, "Small2 Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_S3JF, "Small3 Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_LJ, "Large Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_M1J, "Middle1 Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_M2J, "Middle2 Jpeg")); m_imageQualityMap.insert( std::pair(EdsImageQuality_SJ, "Small Jpeg")); } //----------------------------------------------------------------- void StopMotion::buildPictureStyleMap() { m_pictureStyleMap.insert(std::pair( kEdsPictureStyle_Standard, "Standard")); m_pictureStyleMap.insert(std::pair( kEdsPictureStyle_Portrait, "Portrait")); m_pictureStyleMap.insert(std::pair( kEdsPictureStyle_Landscape, "Landscape")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_Neutral, "Neutral")); m_pictureStyleMap.insert(std::pair( kEdsPictureStyle_Faithful, "Faithful")); m_pictureStyleMap.insert(std::pair( kEdsPictureStyle_Monochrome, "Monochrome")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_Auto, "Auto")); m_pictureStyleMap.insert(std::pair( kEdsPictureStyle_FineDetail, "Fine Detail")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_User1, "User 1")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_User2, "User 2")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_User3, "User 3")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_PC1, "Computer 1")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_PC2, "Computer 2")); m_pictureStyleMap.insert( std::pair(kEdsPictureStyle_PC3, "Computer 3")); } //----------------------------------------------------------------- std::string StopMotion::getTEnvCameraName() { return StopMotionCameraName; } //----------------------------------------------------------------- void StopMotion::setTEnvCameraName(std::string name) { StopMotionCameraName = name; } //----------------------------------------------------------------- std::string StopMotion::getTEnvCameraResolution() { return StopMotionCameraResolution; } //----------------------------------------------------------------- void StopMotion::setTEnvCameraResolution(std::string resolution) { StopMotionCameraResolution = resolution; } //============================================================================= class StopMotionCaptureCommand : public MenuItemHandler { public: StopMotionCaptureCommand() : MenuItemHandler(MI_StopMotionCapture) {} void execute() { StopMotion *sm = StopMotion::instance(); if (sm->m_liveViewStatus > 0) sm->captureImage(); } } StopMotionCaptureCommand; //============================================================================= class StopMotionRaiseOpacityCommand : public MenuItemHandler { public: StopMotionRaiseOpacityCommand() : MenuItemHandler(MI_StopMotionRaiseOpacity) {} void execute() { StopMotion *sm = StopMotion::instance(); if (sm->m_liveViewStatus > 0) sm->raiseOpacity(); } } StopMotionRaiseOpacityCommand; //============================================================================= class StopMotionLowerOpacityCommand : public MenuItemHandler { public: StopMotionLowerOpacityCommand() : MenuItemHandler(MI_StopMotionLowerOpacity) {} void execute() { StopMotion *sm = StopMotion::instance(); if (sm->m_liveViewStatus > 0) sm->lowerOpacity(); } } StopMotionLowerOpacityCommand; //============================================================================= class StopMotionToggleLiveViewCommand : public MenuItemHandler { public: StopMotionToggleLiveViewCommand() : MenuItemHandler(MI_StopMotionToggleLiveView) {} void execute() { StopMotion *sm = StopMotion::instance(); sm->pauseLiveView(); } } StopMotionToggleLiveViewCommand; //============================================================================= class StopMotionToggleZoomCommand : public MenuItemHandler { public: StopMotionToggleZoomCommand() : MenuItemHandler(MI_StopMotionToggleZoom) {} void execute() { StopMotion *sm = StopMotion::instance(); sm->zoomLiveView(); } } StopMotionToggleZoomCommand; //============================================================================= class StopMotionLowerSubsamplingCommand : public MenuItemHandler { public: StopMotionLowerSubsamplingCommand() : MenuItemHandler(MI_StopMotionLowerSubsampling) {} void execute() { StopMotion *sm = StopMotion::instance(); sm->setSubsamplingValue(std::max(1, sm->getSubsamplingValue() - 1)); sm->setSubsampling(); } } StopMotionLowerSubsamplingCommand; //============================================================================= class StopMotionRaiseSubsamplingCommand : public MenuItemHandler { public: StopMotionRaiseSubsamplingCommand() : MenuItemHandler(MI_StopMotionRaiseSubsampling) {} void execute() { StopMotion *sm = StopMotion::instance(); sm->setSubsamplingValue(std::min(30, sm->getSubsamplingValue() + 1)); sm->setSubsampling(); } } StopMotionRaiseSubsamplingCommand; //============================================================================= class StopMotionJumpToCameraCommand : public MenuItemHandler { public: StopMotionJumpToCameraCommand() : MenuItemHandler(MI_StopMotionJumpToCamera) {} void execute() { StopMotion *sm = StopMotion::instance(); sm->jumpToCameraFrame(); } } StopMotionJumpToCameraCommand;