tahoma2d/toonz/sources/stopmotion/stopmotion.cpp

4992 lines
170 KiB
C++
Raw Normal View History

#include "stopmotion.h"
#ifdef WIN32
#include <Windows.h>
#include <mfobjects.h>
#include <mfapi.h>
#include <mfidl.h>
#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"
2020-04-09 15:36:38 +12:00
#include "filebrowserpopup.h"
2020-04-20 09:50:32 +12:00
#include "tunit.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 <QApplication>
#include <QCamera>
#include <QCameraInfo>
#include <QCoreApplication>
#include <QDesktopWidget>
#include <QDialog>
#include <QFile>
#include <QString>
#include <QTimer>
2020-04-07 20:40:46 +12:00
#include <QXmlStreamWriter>
#include <QXmlStreamReader>
2020-04-19 14:29:13 +12:00
#include <QSerialPort>
#include <QSerialPortInfo>
// Connected camera
2020-04-16 10:02:02 +12:00
TEnv::IntVar StopMotionUseScaledImages("StopMotionUseScaledImages", 1);
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);
2020-04-10 18:01:27 +12:00
TEnv::IntVar StopMotionDrawBeneathLevels("StopMotionDrawBeneathLevels", 1);
// 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<TXsheet *>(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<TFrameId> &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<TFrameId> 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() {}
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
void JpgConverter::setStream(EdsStreamRef stream) { m_stream = stream; }
void JpgConverter::convertFromJpg() {
2020-04-16 10:02:02 +12:00
#ifdef MACOSX
UInt64 mySize = 0;
#else
unsigned __int64 mySize = 0;
#endif
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;
flags |= TJFLAG_BOTTOMUP;
2020-04-14 15:42:50 +12:00
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(); }
2020-04-10 11:06:47 +12:00
#endif
//-----------------------------------------------------------------------------
StopMotion::StopMotion() {
m_opacity = StopMotionOpacity;
m_useScaledImages = StopMotionUseScaledImages;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
buildAvMap();
buildIsoMap();
buildTvMap();
buildModeMap();
buildExposureMap();
buildWhiteBalanceMap();
buildColorTemperatures();
buildImageQualityMap();
buildPictureStyleMap();
2020-04-10 11:06:47 +12:00
#endif
m_useDirectShow = StopMotionUseDirectShow;
m_useMjpg = StopMotionUseMjpg;
m_alwaysLiveView = StopMotionAlwaysLiveView;
m_blackCapture = StopMotionBlackCapture;
m_placeOnXSheet = StopMotionPlaceOnXSheet;
m_reviewTime = StopMotionReviewTime;
m_useNumpadShortcuts = StopMotionUseNumpad;
2020-04-10 18:01:27 +12:00
m_drawBeneathLevels = StopMotionDrawBeneathLevels;
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;");
}
}
2020-04-19 14:29:13 +12:00
m_serialPort = new QSerialPort(this);
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();
}
//-----------------------------------------------------------------
StopMotion::~StopMotion() {
2020-04-14 09:21:13 +12:00
disconnectAllCameras();
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
if (m_camera) releaseCamera();
if (m_cameraList != NULL) releaseCameraList();
if (m_isSDKLoaded) closeCanonSDK();
2020-04-10 11:06:47 +12:00
#endif
}
//-----------------------------------------------------------------------------
void StopMotion::onSceneSwitched() {
2020-04-14 09:21:13 +12:00
disconnectAllCameras();
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();
2020-04-14 09:21:13 +12:00
m_frameNumber = 1;
TLevelSet *levelSet = scene->getLevelSet();
std::vector<TXshLevel *> levels;
levelSet->listLevels(levels);
2020-04-14 09:21:13 +12:00
int size = levels.size();
bool found = false;
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);
2020-04-07 20:40:46 +12:00
loadXmlFile();
2020-04-14 09:21:13 +12:00
found = true;
break;
}
}
}
2020-04-14 09:21:13 +12:00
if (!found) {
setXSheetFrameNumber(1);
}
emit(levelNameChanged(m_levelName));
emit(filePathChanged(m_filePath));
emit(frameNumberChanged(m_frameNumber));
emit(xSheetFrameNumberChanged(m_xSheetFrameNumber));
refreshFrameInfo();
}
//-----------------------------------------------------------------
2020-04-14 09:21:13 +12:00
void StopMotion::disconnectAllCameras() {
m_active = false;
m_webcamDeviceName = QString();
m_webcamDescription = QString();
m_webcamIndex = -1;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-14 09:21:13 +12:00
m_proxyDpi = TPointD(0.0, 0.0);
m_proxyImageDimensions = TDimension(0, 0);
2020-04-14 15:49:03 +12:00
if (m_sessionOpen && getCameraCount() > 0) {
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed) {
2020-04-14 09:21:13 +12:00
endCanonLiveView();
}
closeCameraSession();
}
#endif
if (m_usingWebcam) {
releaseWebcam();
m_usingWebcam = false;
}
m_liveViewStatus = LiveViewClosed;
setTEnvCameraName("");
emit(liveViewChanged(false));
emit(newCameraSelected(0, false));
toggleNumpadShortcuts(false);
}
//-----------------------------------------------------------------
void StopMotion::onPlaybackChanged() {
2020-04-21 09:55:16 +12:00
if (TApp::instance()->getCurrentFrame()->isPlaying() ||
m_liveViewStatus == LiveViewClosed)
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);
}
//-----------------------------------------------------------------
2020-04-12 16:11:49 +12:00
void StopMotion::removeStopMotionFrame() {
2020-04-14 09:21:13 +12:00
if (m_xSheetFrameNumber == 1) return;
TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene();
TXsheet *xsh = scene->getXsheet();
int row = m_xSheetFrameNumber - 2;
// find which column the level is on.
// check with the current column first
int col = app->getCurrentColumn()->getColumnIndex();
TXshCell cell = xsh->getCell(row, col);
TXshSimpleLevelP sl;
bool found = false;
if (!cell.isEmpty()) {
if (cell.getSimpleLevel() != 0) {
sl = cell.getSimpleLevel();
if (sl.getPointer()->getName() == m_levelName.toStdWString()) {
found = true;
}
2020-04-12 16:11:49 +12:00
}
2020-04-14 09:21:13 +12:00
}
if (!found) {
int cols = xsh->getColumnCount();
for (int i = 0; i < cols; i++) {
cell = xsh->getCell(row, i);
if (!cell.isEmpty()) {
if (cell.getSimpleLevel() != 0) {
sl = cell.getSimpleLevel();
if (sl.getPointer()->getName() == m_levelName.toStdWString()) {
found = true;
col = i;
break;
}
2020-04-12 16:11:49 +12:00
}
2020-04-14 09:21:13 +12:00
}
2020-04-12 16:11:49 +12:00
}
2020-04-14 09:21:13 +12:00
}
if (!found) {
// DVGui::error(tr("Could not find an xsheet level with the current
// level"));
return;
}
2020-04-12 16:11:49 +12:00
2020-04-14 09:21:13 +12:00
TXshCellColumn *xshCellColumn = xsh->getColumn(col)->getCellColumn();
if (!xshCellColumn) return;
2020-04-12 16:11:49 +12:00
2020-04-14 09:21:13 +12:00
xshCellColumn->removeCells(row, 1);
2020-04-12 16:11:49 +12:00
2020-04-14 09:21:13 +12:00
app->getCurrentScene()->getScene()->getXsheet()->updateFrameCount();
setXSheetFrameNumber(m_xSheetFrameNumber - 1);
app->getCurrentFrame()->prevFrame();
app->getCurrentScene()->notifySceneChanged();
app->getCurrentXsheet()->notifyXsheetChanged();
2020-04-12 16:11:49 +12:00
}
//-----------------------------------------------------------------
void StopMotion::setUseNumpadShortcuts(bool on) {
m_useNumpadShortcuts = on;
StopMotionUseNumpad = int(on);
emit(useNumpadSignal(on));
}
2020-04-07 20:40:46 +12:00
//-----------------------------------------------------------------
2020-04-10 18:01:27 +12:00
void StopMotion::setDrawBeneathLevels(bool on) {
m_drawBeneathLevels = on;
StopMotionDrawBeneathLevels = int(on);
emit(drawBeneathLevelsSignal(on));
}
//-----------------------------------------------------------------
2020-04-07 20:40:46 +12:00
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;
2020-04-09 15:45:17 +12:00
CommandManager *comm = CommandManager::instance();
if (on) {
2020-04-07 20:40:46 +12:00
m_oldActionMap.clear();
// if turning it on, get all old shortcuts
if (m_numpadForStyleSwitching) {
2020-01-05 06:37:34 +13:00
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<std::string, QAction *>(shortcut, action));
action->setShortcut(QKeySequence(""));
action = NULL;
}
}
shortcut = "+";
action = comm->getActionFromShortcut(shortcut);
if (action) {
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
}
shortcut = "-";
action = comm->getActionFromShortcut(shortcut);
if (action) {
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
}
2020-04-07 20:40:46 +12:00
shortcut = "Enter";
action = comm->getActionFromShortcut(shortcut);
if (action) {
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
}
2020-04-12 16:11:49 +12:00
shortcut = "Backspace";
2020-04-14 09:21:13 +12:00
action = comm->getActionFromShortcut(shortcut);
2020-04-12 16:11:49 +12:00
if (action) {
2020-04-14 09:21:13 +12:00
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
2020-04-12 16:11:49 +12:00
}
2020-04-09 15:36:38 +12:00
shortcut = "Return";
2020-04-09 15:45:17 +12:00
action = comm->getActionFromShortcut(shortcut);
2020-04-09 15:36:38 +12:00
if (action) {
2020-04-09 15:45:17 +12:00
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
2020-04-09 15:36:38 +12:00
}
shortcut = "*";
action = comm->getActionFromShortcut(shortcut);
if (action) {
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
}
2020-04-09 15:36:38 +12:00
shortcut = ".";
2020-04-09 15:45:17 +12:00
action = comm->getActionFromShortcut(shortcut);
2020-04-09 15:36:38 +12:00
if (action) {
2020-04-09 15:45:17 +12:00
m_oldActionMap.insert(
std::pair<std::string, QAction *>(shortcut, action));
action = NULL;
2020-04-09 15:36:38 +12:00
}
// 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) {
2020-04-09 15:36:38 +12:00
action->setShortcut(QKeySequence("Return"));
action = NULL;
}
2020-04-12 16:11:49 +12:00
action = comm->getAction(MI_StopMotionRemoveFrame);
if (action) {
2020-04-14 09:21:13 +12:00
action->setShortcut(QKeySequence("Backspace"));
action = NULL;
2020-04-12 16:11:49 +12:00
}
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;
}
2020-04-09 15:36:38 +12:00
action = comm->getAction(MI_StopMotionPickFocusCheck);
if (action) {
2020-04-09 15:45:17 +12:00
action->setShortcut(QKeySequence("."));
action = NULL;
2020-04-09 15:36:38 +12:00
}
2020-04-07 20:40:46 +12:00
action = comm->getAction(MI_ShortPlay);
if (action) {
2020-04-09 15:45:17 +12:00
action->setShortcut(QKeySequence("6"));
action = NULL;
}
2020-04-09 15:45:17 +12:00
2020-04-07 20:40:46 +12:00
} else {
// unset the new shortcuts first
2020-04-09 15:45:17 +12:00
if (m_oldActionMap.size() > 0) {
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;
}
action = comm->getAction(MI_ShortPlay);
if (action) {
action->setShortcut(
QKeySequence(comm->getShortcutFromAction(action).c_str()));
action = NULL;
}
action = comm->getAction(MI_StopMotionPickFocusCheck);
if (action) {
action->setShortcut(
QKeySequence(comm->getShortcutFromAction(action).c_str()));
action = NULL;
}
2020-04-12 16:11:49 +12:00
action = comm->getAction(MI_StopMotionRemoveFrame);
if (action) {
2020-04-14 09:21:13 +12:00
action->setShortcut(
QKeySequence(comm->getShortcutFromAction(action).c_str()));
action = NULL;
2020-04-12 16:11:49 +12:00
}
2020-04-07 20:40:46 +12:00
2020-04-09 15:45:17 +12:00
// 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;
2020-04-07 20:40:46 +12:00
}
2020-04-09 15:45:17 +12:00
}
Preferences::instance()->setValue(useNumpadForSwitchingStyles, true);
2020-04-07 20:40:46 +12:00
}
2020-04-09 15:45:17 +12:00
}
2020-04-07 20:40:46 +12:00
}
}
//-----------------------------------------------------------------
void StopMotion::toggleNumpadForFocusCheck(bool on) {
2020-04-09 15:45:17 +12:00
CommandManager *comm = CommandManager::instance();
if (m_useNumpadShortcuts) {
if (on) {
QAction *action;
action = comm->getAction(MI_PrevDrawing);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_NextDrawing);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_StopMotionJumpToCamera);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_Loop);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_Play);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_StopMotionToggleLiveView);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_ShortPlay);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
action = comm->getAction(MI_StopMotionCapture);
if (action) {
action->setShortcut(QKeySequence(""));
action = NULL;
}
} else {
QAction *action;
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_StopMotionToggleLiveView);
if (action) {
action->setShortcut(QKeySequence("5"));
action = NULL;
}
action = comm->getAction(MI_ShortPlay);
if (action) {
action->setShortcut(QKeySequence("6"));
action = NULL;
}
action = comm->getAction(MI_StopMotionCapture);
if (action) {
action->setShortcut(QKeySequence("Return"));
action = NULL;
}
}
2020-04-09 15:45:17 +12:00
}
}
//-----------------------------------------------------------------
void StopMotion::setXSheetFrameNumber(int frameNumber) {
m_xSheetFrameNumber = frameNumber;
2020-04-16 10:02:02 +12:00
TApp::instance()->getCurrentFrame()->setFrame(frameNumber - 1);
loadLineUpImage();
emit(xSheetFrameNumberChanged(m_xSheetFrameNumber));
2020-04-19 14:29:13 +12:00
sendSerialData();
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
}
//-----------------------------------------------------------------
bool StopMotion::loadLineUpImage() {
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus == LiveViewClosed || m_liveViewStatus == LiveViewPaused)
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<TXshSimpleLevel *>(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<FlexibleNameCreator> nameCreator(new FlexibleNameCreator());
if (!nameCreator->setCurrent(m_levelName.toStdWString())) {
setToNextNewLevel();
return;
}
std::wstring levelName = nameCreator->getNext();
updateLevelNameAndFrame(levelName);
}
//-----------------------------------------------------------------
void StopMotion::previousName() {
std::unique_ptr<FlexibleNameCreator> 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<TXshSimpleLevel *>(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<TXshSimpleLevel *>(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;
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed && m_liveViewStatus < LiveViewPaused &&
!TApp::instance()->getCurrentFrame()->isPlaying()) {
if (getAlwaysLiveView() || (currentFrame == m_xSheetFrameNumber - 1)) {
2020-04-10 11:06:47 +12:00
if (!m_usingWebcam) {
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
downloadEVFData();
2020-04-10 11:06:47 +12:00
#endif
} else {
getWebcamImage();
2020-04-10 11:06:47 +12:00
}
if (getAlwaysLiveView() && currentFrame != m_xSheetFrameNumber - 1 ||
m_pickLiveViewZoom) {
m_showLineUpImage = false;
} else {
m_showLineUpImage = true;
}
2020-04-21 09:55:16 +12:00
} else if (m_liveViewStatus == LiveViewOpen) {
m_liveViewStatus = LiveViewPaused;
TApp::instance()->getCurrentScene()->notifySceneChanged();
}
2020-04-21 09:55:16 +12:00
} else if (m_liveViewStatus == LiveViewPaused && !m_userCalledPause) {
if (getAlwaysLiveView() || (currentFrame == m_xSheetFrameNumber - 1)) {
2020-04-10 11:06:47 +12:00
if (!m_usingWebcam) {
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
downloadEVFData();
2020-04-10 11:06:47 +12:00
#endif
} else
getWebcamImage();
}
}
}
//-----------------------------------------------------------------------------
void StopMotion::onReviewTimeout() {
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed) {
m_liveViewStatus = LiveViewOpen;
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();
}
}
}
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);
2020-04-10 11:06:47 +12:00
TFilePath actualFile(actualLevelFp.withFrame(frameNumber));
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();
2020-04-09 15:45:17 +12:00
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);
2020-04-09 15:45:17 +12:00
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);
2020-04-09 15:45:17 +12:00
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);
}
}
2020-04-10 11:06:47 +12:00
if (m_usingWebcam) {
// saveJpg(m_newImage, actualFile);
}
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();
2020-04-19 18:09:59 +12:00
if (getReviewTime() > 0 && !m_isTimeLapse) {
2020-04-14 09:21:13 +12:00
m_liveViewStatus = LiveViewPaused;
m_reviewTimer->start(getReviewTime() * 1000);
}
/* 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);
2020-04-19 18:09:59 +12:00
if (getReviewTime() == 0 || m_isTimeLapse)
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);
2020-04-19 18:09:59 +12:00
if (getReviewTime() == 0 || m_isTimeLapse)
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);
2020-04-19 18:09:59 +12:00
if (getReviewTime() == 0 || m_isTimeLapse)
app->getCurrentFrame()->setFrame(row + 1);
m_xSheetFrameNumber = row + 2;
emit(xSheetFrameNumberChanged(m_xSheetFrameNumber));
}
postImportProcess();
return true;
}
//-----------------------------------------------------------------
void StopMotion::captureImage() {
2020-04-10 11:06:47 +12:00
bool sessionOpen = false;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-10 11:06:47 +12:00
sessionOpen = m_sessionOpen;
#endif
2020-04-21 09:55:16 +12:00
if ((!m_usingWebcam && !sessionOpen) || m_liveViewStatus == LiveViewPaused) {
2020-01-05 06:37:34 +13:00
DVGui::warning(tr("Please start live view before capturing an image."));
return;
}
if (m_usingWebcam) {
if (!m_hasLiveViewImage) {
2020-01-05 06:37:34 +13:00
DVGui::warning(
tr("Cannot capture webcam image unless live view is active."));
return;
}
2020-04-19 18:09:59 +12:00
if (getReviewTime() > 0 && !m_isTimeLapse) {
m_timer->stop();
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed) {
m_liveViewStatus = LiveViewPaused;
}
}
m_lineUpImage = m_liveViewImage;
m_hasLineUpImage = true;
emit(newLiveViewImageReady());
importImage();
return;
}
2020-04-19 18:09:59 +12:00
if (getBlackCapture() && !m_isTimeLapse) {
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);
}
2020-04-19 18:09:59 +12:00
if (getReviewTime() > 0 && !m_isTimeLapse) {
m_timer->stop();
}
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed && !m_isTimeLapse) {
m_liveViewStatus = LiveViewPaused;
}
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();
2020-04-10 11:06:47 +12:00
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
takePicture();
2020-04-10 11:06:47 +12:00
#endif
}
//-----------------------------------------------------------------------------
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;
flags |= TJFLAG_BOTTOMUP;
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)
2020-04-09 15:45:17 +12:00
success = false;
if (success && size == 0) success = false;
2020-04-09 15:45:17 +12:00
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;
2020-04-09 15:45:17 +12:00
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;
flags |= TJFLAG_BOTTOMUP;
2020-04-09 15:45:17 +12:00
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() {
2020-04-07 20:40:46 +12:00
saveXmlFile();
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();
}
//-----------------------------------------------------------------------------
2020-04-07 20:40:46 +12:00
void StopMotion::saveXmlFile() {
2020-04-09 15:45:17 +12:00
TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene();
TXsheet *xsh = scene->getXsheet();
2020-04-07 20:40:46 +12:00
2020-04-09 15:45:17 +12:00
std::wstring levelName = m_levelName.toStdWString();
TFilePath parentDir = scene->decodeFilePath(TFilePath(m_filePath));
TFilePath tempFile = parentDir + TFilePath(levelName + L".xml");
QString xmlFileName = tempFile.getQString();
QFile xmlFile(xmlFileName);
xmlFile.open(QIODevice::WriteOnly);
QXmlStreamWriter xmlWriter(&xmlFile);
xmlWriter.setAutoFormatting(true);
xmlWriter.writeStartDocument();
xmlWriter.writeStartElement("body");
xmlWriter.writeStartElement("SceneInfo");
xmlWriter.writeTextElement("LevelName", QString::fromStdWString(levelName));
xmlWriter.writeTextElement("CurrentFrame",
QString::number(m_xSheetFrameNumber));
xmlWriter.writeEndElement();
xmlWriter.writeStartElement("CameraInfo");
if (m_usingWebcam) {
xmlWriter.writeTextElement("Webcam", "yes");
xmlWriter.writeTextElement("CameraName", m_webcamDescription);
xmlWriter.writeTextElement("CameraResolutionX",
QString::number(m_webcamWidth));
xmlWriter.writeTextElement("CameraResolutionY",
QString::number(m_webcamHeight));
} else {
xmlWriter.writeTextElement("Webcam", "no");
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-09 15:45:17 +12:00
xmlWriter.writeTextElement("CameraName",
QString::fromStdString(m_cameraName));
xmlWriter.writeTextElement("Aperture", getCurrentAperture());
xmlWriter.writeTextElement("ShutterSpeed", getCurrentShutterSpeed());
xmlWriter.writeTextElement("ISO", getCurrentIso());
xmlWriter.writeTextElement("PictureStyle", getCurrentPictureStyle());
xmlWriter.writeTextElement("ImageQuality", getCurrentImageQuality());
xmlWriter.writeTextElement("WhiteBalance", getCurrentWhiteBalance());
xmlWriter.writeTextElement("ColorTemperature",
getCurrentColorTemperature());
xmlWriter.writeTextElement("ExposureCompensation",
getCurrentExposureCompensation());
xmlWriter.writeTextElement("FocusCheckLocationX",
QString::number(m_finalZoomPoint.x));
xmlWriter.writeTextElement("FocusCheckLocationY",
QString::number(m_finalZoomPoint.y));
2020-04-10 11:06:47 +12:00
#endif
2020-04-09 15:45:17 +12:00
}
xmlWriter.writeEndElement();
xmlWriter.writeStartElement("Images");
xmlWriter.writeTextElement("Frame", "Yes");
xmlWriter.writeEndElement();
xmlWriter.writeEndElement();
xmlWriter.writeEndDocument();
xmlFile.close();
2020-04-07 20:40:46 +12:00
}
//-----------------------------------------------------------------------------
bool StopMotion::loadXmlFile() {
2020-04-09 15:45:17 +12:00
TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene();
TXsheet *xsh = scene->getXsheet();
bool webcam = false;
bool foundCamera = false;
QString text;
int x;
int y;
std::wstring levelName = m_levelName.toStdWString();
TFilePath parentDir = scene->decodeFilePath(TFilePath(m_filePath));
TFilePath tempFile = parentDir + TFilePath(levelName + L".xml");
QString xmlFileName = tempFile.getQString();
QFile xmlFile(xmlFileName);
if (!xmlFile.exists()) return false;
xmlFile.open(QIODevice::ReadOnly);
QXmlStreamReader xmlReader;
xmlReader.setDevice(&xmlFile);
xmlReader.readNext();
while (!xmlReader.atEnd()) {
if (xmlReader.isStartElement()) {
if (xmlReader.name() == "Webcam") {
text = xmlReader.readElementText();
if (text == "yes") webcam = true;
}
if (xmlReader.name() == "CameraName") {
text = xmlReader.readElementText();
if (webcam) {
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
if (cameras.size() > 0) {
for (int i = 0; i < cameras.size(); i++) {
if (cameras.at(i).description() == text) {
changeCameras(i + 1);
foundCamera = true;
break;
}
2020-04-07 20:40:46 +12:00
}
2020-04-09 15:45:17 +12:00
}
} else {
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-16 10:02:02 +12:00
QString camName = "";
if (getCameraCount() > 0) {
openCameraSession();
camName = QString::fromStdString(getCameraName());
closeCameraSession();
}
2020-04-09 15:45:17 +12:00
if (text == camName) {
changeCameras(-1);
foundCamera = true;
}
2020-04-10 11:06:47 +12:00
#endif
2020-04-09 15:45:17 +12:00
}
}
if (xmlReader.name() == "CameraResolutionX") {
text = xmlReader.readElementText();
x = text.toInt();
}
if (xmlReader.name() == "CameraResolutionY") {
text = xmlReader.readElementText();
y = text.toInt();
if (foundCamera == true && webcam == true) {
setWebcamResolution(
QString(QString::number(x) + " x " + QString::number(y)));
2020-04-07 20:40:46 +12:00
}
2020-04-09 15:45:17 +12:00
}
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-09 15:45:17 +12:00
if (xmlReader.name() == "Aperture") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setAperture(text);
}
}
if (xmlReader.name() == "ShutterSpeed") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setShutterSpeed(text);
}
}
if (xmlReader.name() == "ISO") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setIso(text);
}
}
if (xmlReader.name() == "PictureStyle") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setPictureStyle(text);
}
}
if (xmlReader.name() == "ImageQuality") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setImageQuality(text);
}
}
if (xmlReader.name() == "WhiteBalance") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setWhiteBalance(text);
}
}
if (xmlReader.name() == "ColorTemperature") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setColorTemperature(text);
}
}
if (xmlReader.name() == "ExposureCompensation") {
text = xmlReader.readElementText();
if (foundCamera == true && webcam == false) {
setExposureCompensation(text);
}
}
if (xmlReader.name() == "FocusCheckLocationX") {
text = xmlReader.readElementText();
m_finalZoomPoint.x = text.toInt();
}
if (xmlReader.name() == "FocusCheckLocationY") {
text = xmlReader.readElementText();
m_finalZoomPoint.y = text.toInt();
}
2020-04-10 11:06:47 +12:00
#endif
2020-04-07 20:40:46 +12:00
}
2020-04-09 15:45:17 +12:00
xmlReader.readNext();
}
return true;
2020-04-07 20:40:46 +12:00
}
//-----------------------------------------------------------------------------
2020-04-09 15:36:38 +12:00
bool StopMotion::exportImageSequence() {
2020-04-09 15:45:17 +12:00
TApp *app = TApp::instance();
ToonzScene *scene = app->getCurrentScene()->getScene();
TXsheet *xsh = scene->getXsheet();
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
std::wstring levelName = m_levelName.toStdWString();
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
if (levelName.empty()) {
DVGui::error(
tr("No level name specified: please choose a valid level name"));
return false;
}
int frameNumber = m_frameNumber;
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
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"));
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
TFilePath levelFp = TFilePath(m_filePath) +
TFilePath(levelName + L".." + m_fileType.toStdWString());
TFilePath actualLevelFp = scene->decodeFilePath(levelFp);
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
TFilePath fullResFp =
scene->decodeFilePath(fullResFolder + TFilePath(levelName + L"..jpg"));
TFilePath fullResFile(fullResFp.withFrame(frameNumber));
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
TFilePath liveViewFp =
scene->decodeFilePath(liveViewFolder + TFilePath(levelName + L"..jpg"));
TFilePath liveViewFile(liveViewFp.withFrame(frameNumber));
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
TFilePath tempFile = parentDir + "temp.jpg";
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
TXshSimpleLevel *sl = 0;
TXshLevel *level = scene->getLevelSet()->getLevel(levelName);
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
if (level == NULL) {
DVGui::error(tr("No level exists with the current name."));
return false;
}
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
/* if the existing level is not a raster level, then return */
if (level->getType() != OVL_XSHLEVEL) {
DVGui::error(tr("This is not an image level."));
return false;
}
if (!level->getSimpleLevel()->getProperties()->isStopMotionLevel()) {
DVGui::error(tr("This is not a stop motion level."));
return false;
}
sl = level->getSimpleLevel();
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
if (scene->decodeFilePath(sl->getPath()) != actualLevelFp) {
DVGui::error(
tr("The save in path specified does not match with the existing "
"level."));
return false;
}
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
// find which column the level is on.
// check with the first column
int col = TApp::instance()->getCurrentColumn()->getColumnIndex();
int r0, r1, row;
xsh->getColumn(col)->getRange(r0, r1);
TXshSimpleLevel *colLevel = xsh->getCell(r0, col).getSimpleLevel();
if (colLevel != sl) {
int cols = xsh->getColumnCount();
for (int i = 0; i < cols; i++) {
xsh->getColumn(col)->getRange(r0, r1);
colLevel = xsh->getCell(r0, col).getSimpleLevel();
if (colLevel == sl) {
col = i;
break;
}
2020-04-09 15:36:38 +12:00
}
2020-04-09 15:45:17 +12:00
DVGui::error(tr("Could not find an xsheet level with the current level"));
return false;
}
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
row = r0;
xsh->getColumn(col)->getLevelRange(row, r0, r1);
2020-04-09 15:36:38 +12:00
2020-04-09 15:45:17 +12:00
GenericSaveFilePopup *m_saveSequencePopup =
new GenericSaveFilePopup("Export Image Sequence");
m_saveSequencePopup->setFileMode(true);
TFilePath fp = m_saveSequencePopup->getPath();
if (fp == TFilePath()) {
DVGui::error(tr("No export path given."));
return false;
}
TFilePath sourceFile;
TFilePath exportFilePath =
scene->decodeFilePath(fp + TFilePath(levelName + L"..jpg"));
TFilePath exportFile;
int exportFrameNumber = 1;
for (int i = r0; i <= r1; i++) {
int cellNumber = xsh->getCell(i, col).getFrameId().getNumber();
fullResFile = fullResFp.withFrame(cellNumber);
if (TFileStatus(fullResFile).doesExist()) {
sourceFile = fullResFile;
} else {
sourceFile = actualLevelFp.withFrame(cellNumber);
2020-04-09 15:36:38 +12:00
}
2020-04-09 15:45:17 +12:00
if (!TFileStatus(sourceFile).doesExist()) {
DVGui::error(tr("Could not find the source file."));
return false;
}
exportFile = exportFilePath.withFrame(exportFrameNumber);
if (TFileStatus(exportFile).doesExist()) {
QString question = tr("Overwrite existing files?");
int ret = DVGui::MsgBox(question, QObject::tr("Overwrite"),
QObject::tr("Cancel"));
if (ret == 0 || ret == 2) return false;
}
TSystem::copyFile(exportFile, sourceFile);
exportFrameNumber++;
if (!TFileStatus(exportFile).doesExist()) {
DVGui::error(tr("An error occurred. Aborting."));
return false;
}
}
QString message1 = tr("Successfully exported ");
QString message2 = tr(" images.");
QString finalMessage =
message1 + QString::number(exportFrameNumber - 1) + message2;
DVGui::MsgBoxInPopup(DVGui::MsgType(DVGui::INFORMATION), finalMessage);
return true;
2020-04-09 15:36:38 +12:00
}
//-----------------------------------------------------------------------------
// Refresh information that how many & which frames are saved for the current
// level
void StopMotion::refreshFrameInfo() {
2020-04-10 11:06:47 +12:00
bool sessionOpen = false;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-10 11:06:47 +12:00
sessionOpen = m_sessionOpen;
#endif
2020-04-21 09:55:16 +12:00
if ((!sessionOpen && m_liveViewStatus < LiveViewOpen) && !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;
2020-04-10 11:06:47 +12:00
bool checkRes = true;
if (m_usingWebcam) stopMotionRes = m_liveViewImageDimensions;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
else if (m_useScaledImages || !getCurrentImageQuality().contains("Large")) {
stopMotionRes = m_proxyImageDimensions;
if (m_proxyImageDimensions == TDimension(0, 0)) {
checkRes = false;
}
2020-04-10 11:06:47 +12:00
}
#endif
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));
2020-04-09 15:45:17 +12:00
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<TFrameId> 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<TFrameId> 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<TFrameId> 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(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);
}
//-----------------------------------------------------------------
2020-04-14 09:21:13 +12:00
void StopMotion::refreshCameraList() {
2020-04-16 10:02:02 +12:00
QString camera = "";
bool hasCamera = false;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-16 11:39:20 +12:00
if (m_sessionOpen && getCameraCount() > 0 && !m_usingWebcam &&
m_cameraName == getCameraName()) {
hasCamera = true;
camera = QString::fromStdString(m_cameraName);
}
2020-04-16 10:02:02 +12:00
#endif
2020-04-16 11:39:20 +12:00
if (m_usingWebcam) {
2020-04-16 10:02:02 +12:00
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
if (m_usingWebcam && cameras.size() > 0) {
for (int i = 0; i < cameras.size(); i++) {
if (cameras.at(i).description() == m_webcamDescription) {
hasCamera = true;
camera = m_webcamDescription;
break;
}
}
}
}
if (!hasCamera) disconnectAllCameras();
emit(updateCameraList(camera));
2020-04-14 09:21:13 +12:00
}
//-----------------------------------------------------------------
void StopMotion::changeCameras(int index) {
QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
// if selected the non-connected state, then disconnect the current camera
if (index == 0) {
2020-04-14 09:21:13 +12:00
disconnectAllCameras();
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
2020-04-07 20:40:46 +12:00
if (index < 0 || 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;
}
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-14 15:49:03 +12:00
if (m_sessionOpen && getCameraCount() > 0) {
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed) {
2020-04-14 09:21:13 +12:00
endCanonLiveView();
closeCameraSession();
}
}
2020-04-10 11:06:47 +12:00
#endif
setWebcam(new QCamera(cameras.at(index)));
m_webcamDeviceName = cameras.at(index).deviceName();
m_webcamDescription = cameras.at(index).description();
// loading new camera
getWebcam()->load();
m_webcamResolutions.clear();
m_webcamResolutions = getWebcam()->supportedViewfinderResolutions();
2020-04-07 20:40:46 +12:00
int sizeCount = m_webcamResolutions.count() - 1;
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();
}
2020-04-07 20:40:46 +12:00
// see if we can set the webcam resolution to the current camera resolution
2020-04-09 15:45:17 +12:00
TDimension res = TApp::instance()
->getCurrentScene()
->getScene()
->getCurrentCamera()
->getRes();
2020-04-07 20:40:46 +12:00
if (m_webcamResolutions.contains(QSize(res.lx, res.ly))) {
2020-04-09 15:45:17 +12:00
width = res.lx;
height = res.ly;
sizeCount = m_webcamResolutions.indexOf(QSize(res.lx, res.ly));
2020-04-07 20:40:46 +12:00
}
getWebcam()->unload();
setWebcamResolution(
QString(QString::number(width) + " x " + QString::number(height)));
setTEnvCameraName(m_webcamDescription.toStdString());
emit(newCameraSelected(index + 1, true));
emit(webcamResolutionsChanged());
2020-04-07 20:40:46 +12:00
emit(newWebcamResolutionSelected(sizeCount));
} else {
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-09 15:45:17 +12:00
if (index == -2) {
index = cameras.size();
}
m_webcamDeviceName = QString();
m_webcamDescription = QString();
m_webcamIndex = -1;
openCameraSession();
setTEnvCameraName(getCameraName());
emit(newCameraSelected(index + 1, false));
2020-04-10 11:06:47 +12:00
#endif
}
if (m_useNumpadShortcuts) toggleNumpadShortcuts(true);
m_liveViewDpi = TPointD(0.0, 0.0);
refreshFrameInfo();
}
//-----------------------------------------------------------------
QList<QCameraInfo> 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
2020-04-09 15:45:17 +12:00
// 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) {
2020-04-19 14:29:13 +12:00
#ifdef WIN32
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;
}
#else
2020-04-23 07:41:00 +12:00
m_webcamIndex = index;
2020-04-14 09:21:13 +12:00
m_cvWebcam.open(index);
2020-04-23 07:41:00 +12:00
if (m_cvWebcam.isOpened() == false) {
return false;
}
#endif
return true;
}
//-----------------------------------------------------------------
void StopMotion::releaseWebcam() {
m_cvWebcam.release();
2020-04-21 09:55:16 +12:00
m_liveViewStatus = LiveViewClosed;
emit(liveViewStopped());
}
//-----------------------------------------------------------------
void StopMotion::setWebcamResolution(QString resolution) {
m_cvWebcam.release();
// resolution is written in the itemText with the format "<width> x
// <height>" (e.g. "800 x 600")
QStringList texts = resolution.split(' ');
2020-04-07 20:40:46 +12:00
// the split text must be "<width>" "x" and "<height>"
if (texts.size() != 3) return;
int tempStatus = m_liveViewStatus;
2020-04-21 09:55:16 +12:00
m_liveViewStatus = LiveViewClosed;
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;
2020-04-21 09:55:16 +12:00
m_liveViewStatus = LiveViewOpen;
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);
2020-04-09 15:45:17 +12:00
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() {
2020-04-10 11:06:47 +12:00
bool sessionOpen = false;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-10 16:46:04 +12:00
sessionOpen = m_sessionOpen;
2020-04-10 11:06:47 +12:00
#endif
2020-04-21 09:55:16 +12:00
if ((sessionOpen || m_usingWebcam) && m_liveViewStatus == LiveViewClosed) {
m_liveViewDpi = TPointD(0.0, 0.0);
m_liveViewImageDimensions = TDimension(0, 0);
if (!m_usingWebcam) {
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-14 09:21:13 +12:00
startCanonLiveView();
2020-04-10 11:06:47 +12:00
#endif
} else
2020-04-21 09:55:16 +12:00
m_liveViewStatus = LiveViewStarting;
loadLineUpImage();
m_timer->start(40);
emit(liveViewChanged(true));
Preferences::instance()->setValue(rewindAfterPlayback, false);
2020-01-05 06:37:34 +13:00
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
return true;
2020-04-21 09:55:16 +12:00
} else if ((sessionOpen || m_usingWebcam) &&
m_liveViewStatus > LiveViewClosed) {
2020-04-10 11:06:47 +12:00
if (!m_usingWebcam) {
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-14 09:21:13 +12:00
endCanonLiveView();
2020-04-10 11:06:47 +12:00
#endif
} else
releaseWebcam();
m_timer->stop();
emit(liveViewChanged(false));
if (m_turnOnRewind) {
2020-01-05 06:37:34 +13:00
Preferences::instance()->setValue(rewindAfterPlayback, true);
}
2020-01-05 06:37:34 +13:00
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
2020-04-14 09:21:13 +12:00
m_liveViewStatus = LiveViewClosed;
return false;
2020-04-10 16:46:04 +12:00
} else {
DVGui::warning(tr("No camera selected."));
return false;
}
}
//-----------------------------------------------------------------
void StopMotion::pauseLiveView() {
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus == LiveViewOpen) {
m_liveViewStatus = LiveViewPaused;
m_userCalledPause = true;
emit(liveViewStopped());
2020-04-21 09:55:16 +12:00
} else if (m_liveViewStatus == LiveViewPaused) {
m_liveViewStatus = LiveViewOpen;
m_userCalledPause = false;
2020-04-21 09:55:16 +12:00
} else if (m_liveViewStatus == LiveViewClosed) {
2020-04-19 18:09:59 +12:00
toggleLiveView();
}
}
2020-04-10 16:46:04 +12:00
//-----------------------------------------------------------------
void StopMotion::onImageReady(const bool &status) {
m_converterSucceeded = status;
}
2020-04-10 11:06:47 +12:00
//-----------------------------------------------------------------
2020-04-10 16:46:04 +12:00
void StopMotion::onFinished() { l_quitLoop = true; }
//-----------------------------------------------------------------
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
EdsError StopMotion::initializeCanonSDK() {
m_error = EdsInitializeSDK();
if (m_error == EDS_ERR_OK) {
m_isSDKLoaded = true;
}
2020-04-09 16:27:30 +12:00
if (!m_error)
m_error = EdsSetCameraAddedHandler(StopMotion::handleCameraAddedEvent,
(EdsVoid *)this);
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;
2020-04-21 09:55:16 +12:00
m_liveViewStatus = LiveViewClosed;
}
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) {
2020-04-09 15:45:17 +12:00
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");
2020-04-09 15:45:17 +12:00
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();
2020-04-09 15:45:17 +12:00
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);
}
//-----------------------------------------------------------------
2020-04-07 20:40:46 +12:00
QString StopMotion::getCurrentBatteryLevel() {
2020-04-09 15:45:17 +12:00
EdsError err = EDS_ERR_OK;
EdsDataType batteryLevelType;
EdsUInt32 size;
EdsUInt32 data;
QString result;
err = EdsGetPropertySize(m_camera, kEdsPropID_BatteryLevel, 0,
&batteryLevelType, &size);
err = EdsGetPropertyData(m_camera, kEdsPropID_BatteryLevel, 0, sizeof(size),
&data);
if (data == 0xffffffff) {
result = tr("AC Power");
} else if (data >= 80) {
result = tr("Full");
} else {
// at least the 60D reports battery values as 59, 49. . .
// round up
if (data % 10 == 9) data += 1;
result = QString::number(data) + "%";
}
return result;
2020-04-07 20:40:46 +12:00
}
//-----------------------------------------------------------------
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;
2020-04-14 09:21:13 +12:00
err =
EdsSetPropertyData(m_camera, kEdsPropID_Av, 0, sizeof(value), &value);
if (err == EDS_ERR_OK) {
break;
} else {
// some aperture values have two entries in the avMap
it++;
value = it->first;
err = EdsSetPropertyData(m_camera, kEdsPropID_Av, 0, sizeof(value),
&value);
break;
}
}
it++;
}
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);
2020-04-16 10:02:02 +12:00
// tj code
2020-04-16 10:02:02 +12:00
#ifdef MACOSX
UInt64 mySize = 0;
#else
unsigned __int64 mySize = 0;
#endif
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;
flags |= TJFLAG_BOTTOMUP;
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);
2020-04-09 15:45:17 +12:00
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;
}
//-----------------------------------------------------------------
2020-04-16 10:02:02 +12:00
void StopMotion::extendCameraOnTime() {
EdsError err;
EdsInt32 param = 0;
err = EdsSendCommand(m_camera, kEdsCameraCommand_ExtendShutDownTimer, param);
}
//-----------------------------------------------------------------
2020-04-14 09:21:13 +12:00
EdsError StopMotion::startCanonLiveView() {
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;
}
//-----------------------------------------------------------------
2020-04-14 09:21:13 +12:00
EdsError StopMotion::endCanonLiveView() {
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() {
2020-04-21 09:55:16 +12:00
if (!m_sessionOpen || !m_liveViewStatus > LiveViewClosed)
return EDS_ERR_DEVICE_INVALID;
EdsError err = EDS_ERR_OK;
2020-04-07 20:40:46 +12:00
if (m_pickLiveViewZoom) toggleZoomPicking();
if (m_liveViewZoom == 1) {
m_liveViewZoom = 5;
m_zooming = true;
2020-04-07 20:40:46 +12:00
toggleNumpadForFocusCheck(true);
} else if (m_liveViewZoom == 5) {
m_liveViewZoom = 1;
m_zooming = false;
2020-04-07 20:40:46 +12:00
toggleNumpadForFocusCheck(false);
}
err = EdsSetPropertyData(m_camera, kEdsPropID_Evf_Zoom, 0,
sizeof(m_liveViewZoom), &m_liveViewZoom);
if (m_liveViewZoom == 5) setZoomPoint();
2020-04-16 10:02:02 +12:00
emit(focusCheckToggled(m_liveViewZoom > 1));
return err;
}
//-----------------------------------------------------------------
void StopMotion::makeZoomPoint(TPointD pos) {
m_liveViewZoomPickPoint = pos;
2020-04-07 20:40:46 +12:00
calculateZoomPoint();
}
//-----------------------------------------------------------------
void StopMotion::toggleZoomPicking() {
2020-04-21 09:55:16 +12:00
if (!m_sessionOpen || !m_liveViewStatus > LiveViewClosed) return;
2020-04-09 15:45:17 +12:00
if (m_pickLiveViewZoom) {
m_pickLiveViewZoom = false;
toggleNumpadForFocusCheck(false);
} else {
m_pickLiveViewZoom = true;
toggleNumpadForFocusCheck(true);
}
2020-04-16 10:02:02 +12:00
emit(pickFocusCheckToggled(m_pickLiveViewZoom));
}
//-----------------------------------------------------------------
EdsError StopMotion::setZoomPoint() {
2020-04-09 15:45:17 +12:00
EdsError err = EDS_ERR_OK;
2020-04-07 20:40:46 +12:00
m_liveViewZoomReadyToPick = false;
EdsPoint zoomPoint;
2020-04-07 20:40:46 +12:00
calculateZoomPoint();
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);
2020-04-07 20:40:46 +12:00
m_liveViewZoomReadyToPick = true;
return err;
}
//-----------------------------------------------------------------
2020-04-07 20:40:46 +12:00
void StopMotion::calculateZoomPoint() {
2020-04-09 15:45:17 +12:00
bool outOfBounds = false;
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_zoomRectDimensions.x / 2);
m_finalZoomPoint.y = m_calculatedZoomPoint.y - (m_zoomRectDimensions.y / 2);
} else {
2020-04-07 20:40:46 +12:00
// get the image size in OpenToonz dimensions
double maxFullWidth =
(double)m_fullImageDimensions.lx / m_fullImageDpi.x * Stage::inch;
double maxFullHeight =
(double)m_fullImageDimensions.ly / m_fullImageDpi.y * Stage::inch;
2020-04-09 15:45:17 +12:00
// OpenToonz coordinates are based on center at 0, 0
// convert that to top left based coordinates
double newX = m_liveViewZoomPickPoint.x + maxFullWidth / 2.0;
double newY = -m_liveViewZoomPickPoint.y + maxFullHeight / 2.0;
// convert back to the normal image dimensions to talk to the camera
m_calculatedZoomPoint.x = newX / Stage::inch * m_fullImageDpi.x;
m_calculatedZoomPoint.y = newY / Stage::inch * m_fullImageDpi.x;
// the Canon SDK wants the top left corner of the zoom rect, not the center
m_finalZoomPoint.x = m_calculatedZoomPoint.x - (m_zoomRectDimensions.x / 2);
m_finalZoomPoint.y = m_calculatedZoomPoint.y - (m_zoomRectDimensions.y / 2);
// finally make sure everything actually fits on the image
if (m_finalZoomPoint.x < 0) {
m_finalZoomPoint.x = 0;
outOfBounds = true;
}
if (m_finalZoomPoint.y < 0) {
m_finalZoomPoint.y = 0;
outOfBounds = true;
}
if (m_finalZoomPoint.x >
m_fullImageDimensions.lx - (m_zoomRectDimensions.x)) {
m_finalZoomPoint.x = m_fullImageDimensions.lx - (m_zoomRectDimensions.x);
outOfBounds = true;
}
if (m_finalZoomPoint.y >
m_fullImageDimensions.ly - (m_zoomRectDimensions.y)) {
m_finalZoomPoint.y = m_fullImageDimensions.ly - (m_zoomRectDimensions.y);
outOfBounds = true;
}
2020-04-07 20:40:46 +12:00
2020-04-09 15:45:17 +12:00
// if out of bounds, recalculate backwards to get the correct location
if (outOfBounds) {
TPoint tempCalculated;
// recenter the point in the rect
tempCalculated.x = m_finalZoomPoint.x + (m_zoomRectDimensions.x / 2);
tempCalculated.y = m_finalZoomPoint.y + (m_zoomRectDimensions.y / 2);
// convert to OpenToonz Dimensions
newX = tempCalculated.x / m_fullImageDpi.x * Stage::inch;
newY = tempCalculated.y / m_fullImageDpi.y * Stage::inch;
// get center based coordinates
m_liveViewZoomPickPoint.x = newX - (maxFullWidth / 2.0);
m_liveViewZoomPickPoint.y = (newY - (maxFullHeight / 2.0)) * -1;
}
}
2020-04-07 20:40:46 +12:00
2020-04-09 15:45:17 +12:00
// calculate the zoom rectangle position on screen
// get the image size in OpenToonz dimensions
double maxFullWidth =
(double)m_fullImageDimensions.lx / m_fullImageDpi.x * Stage::inch;
double maxFullHeight =
(double)m_fullImageDimensions.ly / m_fullImageDpi.y * Stage::inch;
m_zoomRect =
TRect(m_finalZoomPoint.x, m_finalZoomPoint.y + m_zoomRectDimensions.y,
m_finalZoomPoint.x + m_zoomRectDimensions.x, m_finalZoomPoint.y);
TRect tempCalculated;
// convert to OpenToonz Dimensions
tempCalculated.x0 = m_zoomRect.x0 / m_fullImageDpi.x * Stage::inch;
tempCalculated.y0 = m_zoomRect.y0 / m_fullImageDpi.y * Stage::inch;
tempCalculated.x1 = m_zoomRect.x1 / m_fullImageDpi.x * Stage::inch;
tempCalculated.y1 = m_zoomRect.y1 / m_fullImageDpi.y * Stage::inch;
// get center based coordinates
m_zoomRect.x0 = tempCalculated.x0 - (maxFullWidth / 2.0);
m_zoomRect.y0 = (tempCalculated.y0 - (maxFullHeight / 2.0)) * -1;
m_zoomRect.x1 = tempCalculated.x1 - (maxFullWidth / 2.0);
m_zoomRect.y1 = (tempCalculated.y1 - (maxFullHeight / 2.0)) * -1;
2020-04-07 20:40:46 +12:00
}
//-----------------------------------------------------------------
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);
2020-04-07 20:40:46 +12:00
// this is the top left corner of the zoomed image
err = EdsGetPropertySize(evfImage, kEdsPropID_Evf_ZoomPosition, 0,
&evfZoomPos, &sizePos);
err = EdsGetPropertyData(evfImage, kEdsPropID_Evf_ZoomPosition, 0, sizePos,
&zoomPos);
2020-04-07 20:40:46 +12:00
// this is 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);
// 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
2020-04-21 09:55:16 +12:00
if (m_liveViewStatus > LiveViewClosed &&
m_liveViewStatus < LiveViewPaused) {
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);
2020-04-09 15:45:17 +12:00
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);
2020-04-09 15:45:17 +12:00
m_fullImageDpi = TPointD(minimumDpi, minimumDpi);
emit(newDimensions());
}
2020-04-07 20:40:46 +12:00
// sometimes zoomRect returns the wrong dimensions if called too fast
if (zoomRect.size.width < 5000 && zoomRect.size.height < 5000) {
2020-04-09 15:45:17 +12:00
m_zoomRectDimensions = TPoint(zoomRect.size.width, zoomRect.size.height);
if (m_zoomRect == TRect(0, 0, 0, 0)) {
m_zoomRect = TRect(zoomPos.x, zoomPos.y + zoomRect.size.height,
zoomPos.x + zoomRect.size.width, zoomPos.y);
calculateZoomPoint();
}
2020-04-07 20:40:46 +12:00
}
if (zoomAmount == 5 && m_zoomRectDimensions == TPoint(0, 0)) {
2020-04-09 15:45:17 +12:00
setZoomPoint();
2020-04-07 20:40:46 +12:00
}
}
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;
}
//-----------------------------------------------------------------
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());
}
2020-04-07 20:40:46 +12:00
if (property == kEdsPropID_BatteryLevel &&
event == kEdsPropertyEvent_PropertyChanged) {
2020-04-09 15:45:17 +12:00
emit(instance()->modeChanged());
2020-04-07 20:40:46 +12:00
}
if (property == kEdsPropID_Av &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->apertureOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_Av && event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->apertureChangedSignal(instance()->getCurrentAperture()));
}
if (property == kEdsPropID_Tv &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->shutterSpeedOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_Tv && event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->shutterSpeedChangedSignal(
instance()->getCurrentShutterSpeed()));
}
if (property == kEdsPropID_ISOSpeed &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->isoOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_ISOSpeed &&
event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->isoChangedSignal(instance()->getCurrentIso()));
}
if (property == kEdsPropID_ExposureCompensation &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->exposureOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_ExposureCompensation &&
event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->exposureChangedSignal(
instance()->getCurrentExposureCompensation()));
}
if (property == kEdsPropID_WhiteBalance &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->whiteBalanceOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_WhiteBalance &&
event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->whiteBalanceChangedSignal(
instance()->getCurrentWhiteBalance()));
}
if (property == kEdsPropID_PictureStyle &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->pictureStyleOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_PictureStyle &&
event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->pictureStyleChangedSignal(
instance()->getCurrentPictureStyle()));
}
if (property == kEdsPropID_ImageQuality &&
event == kEdsPropertyEvent_PropertyDescChanged) {
emit(instance()->imageQualityOptionsChanged());
}
2020-04-14 09:21:13 +12:00
if (property == kEdsPropID_ImageQuality &&
event == kEdsPropertyEvent_PropertyChanged) {
emit(instance()->imageQualityChangedSignal(
instance()->getCurrentImageQuality()));
}
return EDS_ERR_OK;
}
//-----------------------------------------------------------------
EdsError StopMotion::handleStateEvent(EdsStateEvent event, EdsUInt32 parameter,
EdsVoid *context) {
if (event == kEdsStateEvent_Shutdown) {
2020-04-14 15:42:50 +12:00
if (instance()->m_sessionOpen && instance()->getCameraCount() > 0) {
instance()->closeCameraSession();
instance()->releaseCamera();
}
2020-04-14 15:49:03 +12:00
instance()->m_liveViewStatus = LiveViewClosed;
2020-04-16 10:02:02 +12:00
emit(instance()->cameraChanged(QString("")));
}
if (event == kEdsStateEvent_WillSoonShutDown) {
instance()->extendCameraOnTime();
2020-04-21 09:55:16 +12:00
if (instance()->m_liveViewStatus > LiveViewStarting) {
2020-04-16 10:02:02 +12:00
instance()->toggleLiveView();
}
}
return EDS_ERR_OK;
}
//-----------------------------------------------------------------
EdsError StopMotion::handleCameraAddedEvent(EdsVoid *context) {
instance()->cameraAdded();
return EDS_ERR_OK;
}
//-----------------------------------------------------------------
void StopMotion::buildAvMap() {
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x00, "00"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x08, "1"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x0B, "1.1"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x0C, "1.2"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x0D, "1.2"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x10, "1.4"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x13, "1.6"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x14, "1.8"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x15, "1.8"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x18, "2"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x1B, "2.2"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x1C, "2.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x1D, "2.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x20, "2.8"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x23, "3.2"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x24, "3.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x25, "3.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x28, "4"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x2B, "4.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x2C, "4.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x2D, "5.0"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x30, "5.6"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x33, "6.3"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x34, "6.7"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x35, "7.1"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x38, "8"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x3B, "9"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x3C, "9.5"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x3D, "10"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x40, "11"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x43, "13"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x44, "13"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x45, "14"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x48, "16"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x4B, "18"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x4C, "19"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x4D, "20"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x50, "22"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x53, "25"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x54, "27"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x55, "29"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x58, "32"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x5B, "36"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x5C, "38"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x5D, "40"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x60, "45"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x63, "51"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x64, "54"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x65, "57"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x68, "64"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x6B, "72"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x6C, "76"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x6D, "80"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0x70, "91"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0xFF, "Auto"));
m_avMap.insert(std::pair<EdsUInt32, const char *>(0xffffffff, "unknown"));
}
//-----------------------------------------------------------------
void StopMotion::buildIsoMap() {
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x00, "Auto"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x28, "6"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x30, "12"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x38, "25"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x40, "50"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x48, "100"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x4b, "125"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x4d, "160"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x50, "200"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x53, "250"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x55, "320"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x58, "400"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x5b, "500"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x5d, "640"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x60, "800"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x63, "1000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x65, "1250"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x68, "1600"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x6b, "2000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x6d, "2500"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x70, "3200"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x73, "4000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x75, "5000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x78, "6400"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x7b, "8000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x7d, "10000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x80, "12800"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x83, "16000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x85, "20000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x88, "25600"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x8b, "32000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x8d, "40000"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x90, "51200"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0x98, "102400"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0xa0, "204800"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0xa8, "409600"));
m_isoMap.insert(std::pair<EdsUInt32, const char *>(0xffffffff, "unknown"));
}
//-----------------------------------------------------------------
void StopMotion::buildTvMap() {
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x04, "Auto"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x0c, "Bulb"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x10, "30\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x13, "25\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x14, "20\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x15, "20\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x18, "15\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x1B, "13\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x1C, "10\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x1D, "10\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x20, "8\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x23, "6\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x24, "6\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x25, "5\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x28, "4\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x2B, "3\"2"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x2C, "3\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x2D, "2\"5"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x30, "2\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x33, "1\"6"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x34, "1\"5"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x35, "1\"3"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x38, "1\""));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x3B, "0\"8"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x3C, "0\"7"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x3D, "0\"6"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x40, "0\"5"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x43, "0\"4"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x44, "0\"3"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x45, "0\"3"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x48, "1/4"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x4B, "1/5"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x4C, "1/6"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x4D, "1/6"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x50, "1/8"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x53, "1/10"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x54, "1/10"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x55, "1/13"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x58, "1/15"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x5B, "1/20"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x5C, "1/20"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x5D, "1/25"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x60, "1/30"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x63, "1/40"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x64, "1/45"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x65, "1/50"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x68, "1/60"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x6B, "1/80"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x6C, "1/90"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x6D, "1/100"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x70, "1/125"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x73, "1/160"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x74, "1/180"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x75, "1/200"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x78, "1/250"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x7B, "1/320"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x7C, "1/350"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x7D, "1/400"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x80, "1/500"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x83, "1/640"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x84, "1/750"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x85, "1/800"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x88, "1/1000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x8B, "1/1250"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x8C, "1/1500"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x8D, "1/1600"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x90, "1/2000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x93, "1/2500"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x94, "1/3000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x95, "1/3200"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x98, "1/4000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x9B, "1/5000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x9C, "1/6000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0x9D, "1/6400"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0xA0, "1/8000"));
m_tvMap.insert(std::pair<EdsUInt32, const char *>(0xffffffff, "unknown"));
}
//-----------------------------------------------------------------
void StopMotion::buildModeMap() {
m_modeMap.insert(std::pair<EdsUInt32, const char *>(0, "P"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(1, "Tv"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(2, "Av"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(3, "M"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(55, "FV"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(4, "Bulb"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(5, "A-DEP"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(6, "DEP"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(7, "C1"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(16, "C2"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(17, "C3"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(8, "Lock"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(9, "GreenMode"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(10, "Night Portrait"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(11, "Sports"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(13, "LandScape"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(14, "Close-Up"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(15, "No Strobo"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(12, "Portrait"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(19, "Creative Auto"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(20, "Movies"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(25, "SCN"));
m_modeMap.insert(
std::pair<EdsUInt32, const char *>(22, "Scene Intelligent Auto"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(29, "Creative filters"));
m_modeMap.insert(std::pair<EdsUInt32, const char *>(0xffffffff, "unknown"));
}
//-----------------------------------------------------------------
void StopMotion::buildExposureMap() {
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x28, "+5"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x25, "+4 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x24, "+4 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x23, "+4 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x20, "+4"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x1D, "+3 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x1C, "+3 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x1B, "+3 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x18, "+3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x15, "+2 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x14, "+2 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x13, "+2 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x10, "+2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x0d, "+1 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x0c, "+1 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x0b, "+1 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x08, "+1"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x05, "+2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x04, "+1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x03, "+1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0x00, "0"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xfd, "-1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xfc, "-1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xfb, "-2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xf8, "-1"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xf5, "-1 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xf4, "-1 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xf3, "-1 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xf0, "-2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xed, "-2 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xec, "-2 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xeb, "-2 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xe8, "-3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xE5, "-3 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xE4, "-3 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xE3, "-3 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xE0, "-4"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xDD, "-4 1/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xDC, "-4 1/2"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xDB, "-4 2/3"));
m_exposureMap.insert(std::pair<EdsUInt32, const char *>(0xD8, "-5"));
m_exposureMap.insert(
std::pair<EdsUInt32, const char *>(0xffffffff, "unknown"));
}
//-----------------------------------------------------------------
void StopMotion::buildWhiteBalanceMap() {
m_whiteBalanceMap.insert(
std::pair<EdsUInt32, const char *>(0, "Auto: Ambience Priority"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(1, "Daylight"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(2, "Cloudy"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(3, "Tungsten"));
m_whiteBalanceMap.insert(
std::pair<EdsUInt32, const char *>(4, "Fluorescent"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(5, "Flash"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(6, "Manual"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(8, "Shade"));
m_whiteBalanceMap.insert(
std::pair<EdsUInt32, const char *>(9, "Color Temperature"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(10, "Custom 1"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(11, "Custom 2"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(12, "Custom 3"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(15, "Manual 2"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(16, "Manual 3"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(18, "Manual 4"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(19, "Manual 5"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(20, "Custom 4"));
m_whiteBalanceMap.insert(std::pair<EdsUInt32, const char *>(21, "Custom 5"));
m_whiteBalanceMap.insert(
std::pair<EdsUInt32, const char *>(23, "Auto: White Priority"));
}
//-----------------------------------------------------------------
void StopMotion::buildImageQualityMap() {
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_LR, "RAW"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRLJF, "RAW + Large Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRMJF, "RAW + Middle Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRSJF, "RAW + Small Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRLJN, "RAW + Large Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRMJN, "RAW + Middle Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRSJN, "RAW + Small Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRS1JF, "RAW + Small1 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRS1JN, "RAW + Small1 Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRS2JF, "RAW + Small2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRS3JF, "RAW + Small3 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRLJ, "RAW + Large Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRM1J, "RAW + Middle1 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRM2J, "RAW + Middle2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LRSJ, "RAW + Small Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MR, "Middle Raw(Small RAW1)"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRLJF, "Middle Raw(Small RAW1) + Large Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRMJF, "Middle Raw(Small RAW1) + Middle Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRSJF, "Middle Raw(Small RAW1) + Small Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRLJN, "Middle Raw(Small RAW1) + Large Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRMJN, "Middle Raw(Small RAW1) + Middle Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRSJN, "Middle Raw(Small RAW1) + Small Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRS1JF, "Middle RAW + Small1 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRS1JN, "Middle RAW + Small1 Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRS2JF, "Middle RAW + Small2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRS3JF, "Middle RAW + Small3 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRLJ, "Middle Raw + Large Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRM1J, "Middle Raw + Middle1 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRM2J, "Middle Raw + Middle2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MRSJ, "Middle Raw + Small Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SR, "Small RAW(Small RAW2)"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRLJF, "Small RAW(Small RAW2) + Large Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRMJF, "Small RAW(Small RAW2) + Middle Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRSJF, "Small RAW(Small RAW2) + Small Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRLJN, "Small RAW(Small RAW2) + Large Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRMJN, "Small RAW(Small RAW2) + Middle Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRSJN, "Small RAW(Small RAW2) + Small Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRS1JF, "Small RAW + Small1 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRS1JN, "Small RAW + Small1 Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRS2JF, "Small RAW + Small2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRS3JF, "Small RAW + Small3 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRLJ, "Small RAW + Large Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRM1J, "Small RAW + Middle1 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRM2J, "Small RAW + Middle2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SRSJ, "Small RAW + Small Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_CR, "CRAW"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRLJF, "CRAW + Large Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRMJF, "CRAW + Middle Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRM1JF, "CRAW + Middle1 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRM2JF, "CRAW + Middle2 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRSJF, "CRAW + Small Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRS1JF, "CRAW + Small1 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRS2JF, "CRAW + Small2 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRS3JF, "CRAW + Small3 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRLJN, "CRAW + Large Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRMJN, "CRAW + Middle Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRM1JN, "CRAW + Middle1 Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRM2JN, "CRAW + Middle2 Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRSJN, "CRAW + Small Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRS1JN, "CRAW + Small1 Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRLJ, "CRAW + Large Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRM1J, "CRAW + Middle1 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRM2J, "CRAW + Middle2 Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_CRSJ, "CRAW + Small Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LJF, "Large Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_LJN, "Large Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MJF, "Middle Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_MJN, "Middle Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SJF, "Small Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_SJN, "Small Normal Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_S1JF, "Small1 Fine Jpeg"));
m_imageQualityMap.insert(std::pair<EdsUInt32, const char *>(
EdsImageQuality_S1JN, "Small1 Normal Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_S2JF, "Small2 Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_S3JF, "Small3 Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_LJ, "Large Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_M1J, "Middle1 Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_M2J, "Middle2 Jpeg"));
m_imageQualityMap.insert(
std::pair<EdsUInt32, const char *>(EdsImageQuality_SJ, "Small Jpeg"));
}
//-----------------------------------------------------------------
void StopMotion::buildPictureStyleMap() {
m_pictureStyleMap.insert(std::pair<EdsUInt32, const char *>(
kEdsPictureStyle_Standard, "Standard"));
m_pictureStyleMap.insert(std::pair<EdsUInt32, const char *>(
kEdsPictureStyle_Portrait, "Portrait"));
m_pictureStyleMap.insert(std::pair<EdsUInt32, const char *>(
kEdsPictureStyle_Landscape, "Landscape"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_Neutral, "Neutral"));
m_pictureStyleMap.insert(std::pair<EdsUInt32, const char *>(
kEdsPictureStyle_Faithful, "Faithful"));
m_pictureStyleMap.insert(std::pair<EdsUInt32, const char *>(
kEdsPictureStyle_Monochrome, "Monochrome"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_Auto, "Auto"));
m_pictureStyleMap.insert(std::pair<EdsUInt32, const char *>(
kEdsPictureStyle_FineDetail, "Fine Detail"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_User1, "User 1"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_User2, "User 2"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_User3, "User 3"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_PC1, "Computer 1"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_PC2, "Computer 2"));
m_pictureStyleMap.insert(
std::pair<EdsUInt32, const char *>(kEdsPictureStyle_PC3, "Computer 3"));
}
2020-04-10 11:06:47 +12:00
#endif
2020-04-19 14:29:13 +12:00
//-----------------------------------------------------------------
QStringList StopMotion::getAvailableSerialPorts() {
QList<QSerialPortInfo> list = QSerialPortInfo::availablePorts();
QStringList ports;
ports.push_back(tr("No Device"));
int size = list.size();
for (int i = 0; i < size; i++) {
std::string desc = list.at(i).description().toStdString();
std::string port = list.at(i).portName().toStdString();
std::string maker = list.at(i).manufacturer().toStdString();
ports.push_back(list.at(i).portName());
if (list.at(i).hasProductIdentifier()) {
std::string id =
QString::number(list.at(i).productIdentifier()).toStdString();
}
if (list.at(i).hasVendorIdentifier()) {
std::string id =
QString::number(list.at(i).vendorIdentifier()).toStdString();
}
}
return ports;
}
//-----------------------------------------------------------------
bool StopMotion::setSerialPort(QString port) {
if (m_serialPort->isOpen()) m_serialPort->close();
QList<QSerialPortInfo> list = QSerialPortInfo::availablePorts();
QStringList ports;
bool success = false;
int size = list.size();
for (int i = 0; i < size; i++) {
if (port == list.at(i).portName()) {
m_serialPort->setPort(list.at(i));
}
}
// m_serialPort->setBaudRate(9600);
bool connected = m_serialPort->open(QIODevice::ReadWrite);
if (connected) {
success = m_serialPort->setBaudRate(QSerialPort::Baud9600) &
m_serialPort->setParity(QSerialPort::NoParity) &
m_serialPort->setDataBits(QSerialPort::Data8) &
m_serialPort->setStopBits(QSerialPort::OneStop) &
m_serialPort->setFlowControl(QSerialPort::NoFlowControl);
std::string fNumber = std::to_string(m_xSheetFrameNumber);
char const *fNumberChar = fNumber.c_str();
m_serialPort->write(fNumberChar);
m_serialPort->waitForBytesWritten(10);
QByteArray DataReceive = m_serialPort->readLine();
while (m_serialPort->waitForReadyRead(30)) {
DataReceive += m_serialPort->readLine();
}
QByteArray response = DataReceive;
QString s(response);
std::string text = response.toStdString();
//}
}
return success;
}
//-----------------------------------------------------------------
void StopMotion::sendSerialData() {
if (m_serialPort->isOpen()) {
std::string fNumber = std::to_string(m_xSheetFrameNumber);
char const *fNumberChar = fNumber.c_str();
m_serialPort->write(fNumberChar);
m_serialPort->waitForBytesWritten(10);
QByteArray DataReceive = m_serialPort->readLine();
while (m_serialPort->waitForReadyRead(30)) {
DataReceive += m_serialPort->readLine();
}
QByteArray response = DataReceive;
QString s(response);
std::string text = response.toStdString();
}
2020-04-20 09:50:32 +12:00
2020-04-21 09:55:16 +12:00
// for not data sending is not implemented yet, just the frame number.
2020-04-20 09:50:32 +12:00
// These lines are here to be a reference for using column data as movement.
2020-04-21 09:55:16 +12:00
// TDoubleParam *param =
// TApp::instance()->getCurrentScene()->getScene()->getXsheet()->getStageObjectTree()->getStageObject(0)->getParam(TStageObject::T_X);
// double value =
// TApp::instance()->getCurrentScene()->getScene()->getXsheet()->getStageObjectTree()->getStageObject(0)->getParam(TStageObject::T_X,
// m_xSheetFrameNumber - 1);
// QString isCam =
// TApp::instance()->getCurrentScene()->getScene()->getXsheet()->getStageObjectTree()->getStageObject(0)->getId().isCamera()
// ? "yep" : "nope";
// std::string name =
// TApp::instance()->getCurrentScene()->getScene()->getXsheet()->getStageObjectTree()->getStageObject(0)->getName();
// TMeasure *measure =param->getMeasure();
// const TUnit *unit = measure->getCurrentUnit();
// double newValue = unit->convertTo(value);
2020-04-19 14:29:13 +12:00
}
//-----------------------------------------------------------------
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 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();
}
2020-04-09 15:36:38 +12:00
} StopMotionJumpToCameraCommand;
//=============================================================================
2020-04-10 11:06:47 +12:00
class StopMotionExportImageSequence : public MenuItemHandler {
public:
StopMotionExportImageSequence()
: MenuItemHandler(MI_StopMotionExportImageSequence) {}
void execute() {
StopMotion *sm = StopMotion::instance();
sm->exportImageSequence();
}
} StopMotionExportImageSequence;
2020-04-12 16:11:49 +12:00
//=============================================================================
class StopMotionRemoveFrame : public MenuItemHandler {
public:
2020-04-14 09:21:13 +12:00
StopMotionRemoveFrame() : MenuItemHandler(MI_StopMotionRemoveFrame) {}
void execute() {
StopMotion *sm = StopMotion::instance();
sm->removeStopMotionFrame();
}
2020-04-12 16:11:49 +12:00
} StopMotionRemoveFrame;
2020-04-19 14:29:13 +12:00
#ifdef WITH_CANON
2020-04-10 11:06:47 +12:00
//=============================================================================
2020-04-09 15:36:38 +12:00
class StopMotionPickFocusCheck : public MenuItemHandler {
public:
2020-04-09 15:45:17 +12:00
StopMotionPickFocusCheck() : MenuItemHandler(MI_StopMotionPickFocusCheck) {}
void execute() {
StopMotion *sm = StopMotion::instance();
sm->toggleZoomPicking();
}
2020-04-09 15:36:38 +12:00
} StopMotionPickFocusCheck;
//=============================================================================
2020-04-10 11:06:47 +12:00
class StopMotionToggleZoomCommand : public MenuItemHandler {
2020-04-09 15:36:38 +12:00
public:
2020-04-10 11:06:47 +12:00
StopMotionToggleZoomCommand() : MenuItemHandler(MI_StopMotionToggleZoom) {}
2020-04-09 15:45:17 +12:00
void execute() {
StopMotion *sm = StopMotion::instance();
2020-04-10 11:06:47 +12:00
sm->zoomLiveView();
2020-04-09 15:45:17 +12:00
}
2020-04-10 11:06:47 +12:00
} StopMotionToggleZoomCommand;
#endif