Testwidget removed, not necessary anymore.
svn path=/trunk/kdenlive/; revision=4616
widgets/vectorscope_ui.ui
widgets/colorplaneexport_ui.ui
widgets/waveform_ui.ui
- widgets/testwidget_ui.ui
+ widgets/rgbparade_ui.ui
)
set(kdenlive_SRCS
colortools.cpp
rebuildgroupcommand.cpp
waveform.cpp
+ rgbparade.cpp
colorcorrection/waveformgenerator.cpp
colorcorrection/vectorscopegenerator.cpp
- testwidget.cpp
+ colorcorrection/rgbparadegenerator.cpp
razorgroupcommand.cpp
)
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
+ * This file is part of kdenlive. See www.kdenlive.org. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include "rgbparadegenerator.h"
+
+#include <QColor>
+#include <QDebug>
+#include <QPainter>
+#include <QPoint>
+#include <QTime>
+
+#define CHOP255(a) ((255) < (a) ? (255) : (a))
+
+const QColor RGBParadeGenerator::colHighlight(255, 245, 235, 255);
+const QColor RGBParadeGenerator::colLight(200, 200, 200, 255);
+const QColor RGBParadeGenerator::colSoft(150, 150, 150, 255);
+
+RGBParadeGenerator::RGBParadeGenerator()
+{
+}
+
+QImage RGBParadeGenerator::calculateRGBParade(const QSize ¶deSize, const QImage &image, const bool &drawAxis, const uint &accelFactor)
+{
+ Q_ASSERT(accelFactor >= 1);
+
+ QImage parade(paradeSize, QImage::Format_ARGB32);
+
+ if (paradeSize.width() <= 0 || paradeSize.height() <= 0) {
+ qCritical("Wave size should not be 0.");
+
+ } else {
+
+ qDebug() << "Wave calculation started.";
+
+ // Fill with transparent color
+ parade.fill(qRgba(0,0,0,0));
+
+ QRgb *col;
+ QRgb paradeCol;
+ QPoint paradePoint;
+ QPainter davinci(¶de);
+
+ double dx, dy;
+
+ const uint ww = paradeSize.width();
+ const uint wh = paradeSize.height();
+ const uint iw = image.bytesPerLine();
+ const uint ih = image.height();
+ const uint byteCount = iw*ih;
+
+ const uchar offset = 10;
+ const uchar right = 40;
+ const uchar bottom = 40;
+ const int partW = (ww - 2*offset - right) / 3;
+ const int partH = wh - bottom;
+
+ // To get constant brightness, independant of acceleration factor and input image size
+ // Must be a float because the acceleration factor can be high, leading to <1 expected px per px.
+ const float avgPxPerPx = ((float)(image.width() * image.height()) / (500*partW*accelFactor));
+ const float weaken = (avgPxPerPx == 0) ? 1 : (float)4/avgPxPerPx;
+ const int vh = weaken*27;
+ const int vm = weaken*18;
+ const int vl = weaken*9;
+
+ uchar minR = 255, minG = 255, minB = 255, maxR = 0, maxG = 0, maxB = 0, r, g, b;
+ qDebug() << "Expecting about " << avgPxPerPx << " pixels per pixel in the RGB parade. Weakening by " << weaken
+ << " with an acceleration factor of " << accelFactor;
+
+
+ QImage unscaled(ww-right, 256, QImage::Format_ARGB32);
+ unscaled.fill(qRgba(0, 0, 0, 0));
+
+ const float wPrediv = (float)(partW-1)/(iw-1);
+
+ const uchar *bits = image.bits();
+ const uint stepsize = 4*accelFactor;
+
+ for (uint i = 0, x = 0; i < byteCount; i += stepsize) {
+
+ col = (QRgb *)bits;
+ r = qRed(*col);
+ g = qGreen(*col);
+ b = qBlue(*col);
+
+ dx = x*wPrediv;
+
+ paradePoint = QPoint((int)dx, r);
+ paradeCol = QRgb(unscaled.pixel(paradePoint));
+ unscaled.setPixel(paradePoint, qRgba(CHOP255(vh + qRed(paradeCol)), CHOP255(vm + qGreen(paradeCol)),
+ CHOP255(vl + qBlue(paradeCol)), 255));
+
+ paradePoint = QPoint((int) (dx + partW + offset), g);
+ paradeCol = QRgb(unscaled.pixel(paradePoint));
+ unscaled.setPixel(paradePoint, qRgba(CHOP255(vl + qRed(paradeCol)), CHOP255(vh + qGreen(paradeCol)),
+ CHOP255(vm + qBlue(paradeCol)), 255));
+
+ paradePoint = QPoint((int) (dx + 2*partW + 2*offset), b);
+ paradeCol = QRgb(unscaled.pixel(paradePoint));
+ unscaled.setPixel(paradePoint, qRgba(CHOP255(vm + qRed(paradeCol)), CHOP255(vl + qGreen(paradeCol)),
+ CHOP255(vh + qBlue(paradeCol)), 255));
+
+
+ if (r < minR) { minR = r; }
+ if (g < minG) { minG = g; }
+ if (b < minB) { minB = b; }
+ if (r > maxR) { maxR = r; }
+ if (g > maxG) { maxG = g; }
+ if (b > maxB) { maxB = b; }
+
+ bits += stepsize;
+ x += stepsize;
+ x %= iw; // Modulo image width, to represent the current x position in the image
+ }
+ // Scale the image to the target height. Scaling is not accomplished before because
+ // there are only 255 different values which would lead to gaps if the height is not exactly 255.
+ // Don't use bilinear transformation because the fast transformation meets the goal better.
+ davinci.drawImage(0, 0, unscaled.mirrored(false, true).scaled(unscaled.width(), partH, Qt::IgnoreAspectRatio, Qt::FastTransformation));
+
+ if (drawAxis) {
+ QRgb opx;
+ for (uint i = 0; i <= 10; i++) {
+ dy = (float)i/10 * (partH-1);
+ for (uint x = 0; x < ww-right; x++) {
+ opx = parade.pixel(x, dy);
+ parade.setPixel(x,dy, qRgba(CHOP255(150+qRed(opx)), 255,
+ CHOP255(200+qBlue(opx)), CHOP255(32+qAlpha(opx))));
+ }
+ }
+ }
+
+
+ const int d = 50;
+
+ // Show numerical minimum
+ if (minR == 0) { davinci.setPen(colHighlight); } else { davinci.setPen(colSoft); }
+ davinci.drawText(0, wh, "min: ");
+ if (minG == 0) { davinci.setPen(colHighlight); } else { davinci.setPen(colSoft); }
+ davinci.drawText(partW + offset, wh, "min: ");
+ if (minB == 0) { davinci.setPen(colHighlight); } else { davinci.setPen(colSoft); }
+ davinci.drawText(2*partW + 2*offset, wh, "min: ");
+
+ // Show numerical maximum
+ if (maxR == 255) { davinci.setPen(colHighlight); } else { davinci.setPen(colSoft); }
+ davinci.drawText(0, wh-20, "max: ");
+ if (maxG == 255) { davinci.setPen(colHighlight); } else { davinci.setPen(colSoft); }
+ davinci.drawText(partW + offset, wh-20, "max: ");
+ if (maxB == 255) { davinci.setPen(colHighlight); } else { davinci.setPen(colSoft); }
+ davinci.drawText(2*partW + 2*offset, wh-20, "max: ");
+
+ davinci.setPen(colLight);
+ davinci.drawText(d, wh, QString::number(minR, 'f', 0));
+ davinci.drawText(partW + offset + d, wh, QString::number(minG, 'f', 0));
+ davinci.drawText(2*partW + 2*offset + d, wh, QString::number(minB, 'f', 0));
+
+ davinci.drawText(d, wh-20, QString::number(maxR, 'f', 0));
+ davinci.drawText(partW + offset + d, wh-20, QString::number(maxG, 'f', 0));
+ davinci.drawText(2*partW + 2*offset + d, wh-20, QString::number(maxB, 'f', 0));
+
+ davinci.drawText(ww-right+5, 10, "255");
+ davinci.drawText(ww-right+5, partH+5, "0");
+
+
+
+
+ }
+
+ return parade;
+}
+
+#undef CHOP255
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
+ * This file is part of kdenlive. See www.kdenlive.org. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#ifndef RGBPARADEGENERATOR_H
+#define RGBPARADEGENERATOR_H
+
+#include <QObject>
+
+class QColor;
+class QImage;
+class QSize;
+class RGBParadeGenerator : public QObject
+{
+public:
+ RGBParadeGenerator();
+ QImage calculateRGBParade(const QSize ¶deSize, const QImage &image, const bool &drawAxis, const uint &accelFactor = 1);
+
+ static const QColor colHighlight;
+ static const QColor colLight;
+ static const QColor colSoft;
+};
+
+#endif // RGBPARADEGENERATOR_H
return wave;
}
+#undef CHOP255
#include "ui_templateclip_ui.h"
#include "vectorscope.h"
#include "waveform.h"
-#include "testwidget.h"
+#include "rgbparade.h"
#include <KApplication>
#include <KAction>
m_vectorscope = new Vectorscope(m_projectMonitor, m_clipMonitor, this);
m_vectorscopeDock = new QDockWidget(i18n("Vectorscope"), this);
- m_vectorscopeDock->setObjectName("vectorscope");
+ m_vectorscopeDock->setObjectName(m_vectorscope->widgetName());
m_vectorscopeDock->setWidget(m_vectorscope);
addDockWidget(Qt::TopDockWidgetArea, m_vectorscopeDock);
m_waveform = new Waveform(m_projectMonitor, m_clipMonitor, this);
m_waveformDock = new QDockWidget(i18n("Waveform"), this);
- m_waveformDock->setObjectName("waveform");
+ m_waveformDock->setObjectName(m_waveform->widgetName());
m_waveformDock->setWidget(m_waveform);
addDockWidget(Qt::TopDockWidgetArea, m_waveformDock);
- m_test = new TestWidget(m_projectMonitor, m_clipMonitor, this);
- m_testDock = new QDockWidget("Test", this);
- m_testDock->setObjectName("test");
- m_testDock->setWidget(m_test);
- addDockWidget(Qt::TopDockWidgetArea, m_testDock);
+ m_RGBParade = new RGBParade(m_projectMonitor, m_clipMonitor, this);
+ m_RGBParadeDock = new QDockWidget("RGB Parade", this);
+ m_RGBParadeDock->setObjectName(m_RGBParade->widgetName());
+ m_RGBParadeDock->setWidget(m_RGBParade);
+ addDockWidget(Qt::TopDockWidgetArea, m_RGBParadeDock);
m_undoViewDock = new QDockWidget(i18n("Undo History"), this);
#endif
tabifyDockWidget(m_vectorscopeDock, m_waveformDock);
+ tabifyDockWidget(m_vectorscopeDock, m_RGBParadeDock);
tabifyDockWidget(m_vectorscopeDock, m_undoViewDock);
tabifyDockWidget(m_vectorscopeDock, m_effectListDock);
connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), this, SLOT(slotRaiseMonitor(bool)));
connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), m_vectorscope, SLOT(slotActiveMonitorChanged(bool)));
connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), m_waveform, SLOT(slotActiveMonitorChanged(bool)));
+ connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), m_RGBParade, SLOT(slotActiveMonitorChanged(bool)));
connect(m_effectList, SIGNAL(addEffect(const QDomElement)), this, SLOT(slotAddEffect(const QDomElement)));
connect(m_effectList, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
m_undoViewDock->setTitleBarWidget(0);
m_vectorscopeDock->setTitleBarWidget(0);
m_waveformDock->setTitleBarWidget(0);
+ m_RGBParadeDock->setTitleBarWidget(0);
} else {
if (!m_effectStackDock->isFloating()) { m_effectStackDock->setTitleBarWidget(new QWidget(this)); }
if (!m_clipMonitorDock->isFloating()) { m_clipMonitorDock->setTitleBarWidget(new QWidget(this)); }
if (!m_undoViewDock->isFloating()) { m_undoViewDock->setTitleBarWidget(new QWidget(this)); }
if (!m_vectorscopeDock->isFloating()) { m_vectorscopeDock->setTitleBarWidget(new QWidget(this)); }
if (!m_waveformDock->isFloating()) { m_waveformDock->setTitleBarWidget(new QWidget(this)); }
+ if (!m_RGBParadeDock->isFloating()) { m_RGBParadeDock->setTitleBarWidget(new QWidget(this)); }
}
KdenliveSettings::setShowtitlebars(show);
}
class Transition;
class Vectorscope;
class Waveform;
-class TestWidget;
+class RGBParade;
class KActionCollection;
class MainWindow : public KXmlGuiWindow
QDockWidget *m_waveformDock;
Waveform *m_waveform;
- QDockWidget *m_testDock;
- TestWidget *m_test;
+ QDockWidget *m_RGBParadeDock;
+ RGBParade *m_RGBParade;
QDockWidget *m_undoViewDock;
QUndoView *m_undoView;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
+ * This file is part of kdenlive. See www.kdenlive.org. *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+
+#include <QRect>
+#include <QTime>
+#include "renderer.h"
+#include "rgbparade.h"
+#include "rgbparadegenerator.h"
+
+RGBParade::RGBParade(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
+ AbstractScopeWidget(projMonitor, clipMonitor, parent)
+{
+ ui = new Ui::RGBParade_UI();
+ ui->setupUi(this);
+ m_rgbParadeGenerator = new RGBParadeGenerator();
+}
+
+RGBParade::~RGBParade()
+{
+ delete ui;
+ delete m_rgbParadeGenerator;
+}
+
+QString RGBParade::widgetName() const { return "RGB Parade"; }
+
+QRect RGBParade::scopeRect()
+{
+ QPoint topleft(offset, ui->line->y() + 2*offset);
+ return QRect(topleft, QPoint(this->size().width() - offset, this->size().height() - offset) - topleft);
+}
+
+QImage RGBParade::renderHUD(uint) { return QImage(); }
+QImage RGBParade::renderScope(uint accelerationFactor)
+{
+ QTime start = QTime::currentTime();
+ start.start();
+ QImage parade = m_rgbParadeGenerator->calculateRGBParade(m_scopeRect.size(), m_activeRender->extractFrame(m_activeRender->seekFramePosition()),
+ true, accelerationFactor);
+ emit signalScopeRenderingFinished(start.elapsed(), accelerationFactor);
+ return parade;
+}
+QImage RGBParade::renderBackground(uint) { return QImage(); }
+
+bool RGBParade::isHUDDependingOnInput() const { return false; }
+bool RGBParade::isScopeDependingOnInput() const { return true; }
+bool RGBParade::isBackgroundDependingOnInput() const { return false; }
* (at your option) any later version. *
***************************************************************************/
-#ifndef TESTWIDGET_H
-#define TESTWIDGET_H
+#ifndef RGBPARADE_H
+#define RGBPARADE_H
-#include <QWidget>
+#include <QObject>
#include "abstractscopewidget.h"
-#include "ui_testwidget_ui.h"
+#include "ui_rgbparade_ui.h"
-class AbstractScopeWidget;
-class TestWidget_UI;
+class Monitor;
+class QImage;
+class RGBParade_UI;
+class RGBParadeGenerator;
-class TestWidget : public AbstractScopeWidget {
- Q_OBJECT
+class RGBParade : public AbstractScopeWidget
+{
public:
- TestWidget(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent = 0);
- virtual ~TestWidget();
-
+ RGBParade(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent = 0);
+ ~RGBParade();
QString widgetName() const;
- /// Implemented methods ///
- QImage renderHUD(uint accelerationFactor);
- QImage renderScope(uint accelerationFactor);
- QImage renderBackground(uint accelerationFactor);
- bool isHUDDependingOnInput() const;
- bool isScopeDependingOnInput() const;
- bool isBackgroundDependingOnInput() const;
-
protected:
QRect scopeRect();
private:
- Ui::TestWidget_UI *ui;
+ Ui::RGBParade_UI *ui;
+ RGBParadeGenerator *m_rgbParadeGenerator;
- QAction *m_aTest;
+ bool isHUDDependingOnInput() const;
+ bool isScopeDependingOnInput() const;
+ bool isBackgroundDependingOnInput() const;
+ QImage renderHUD(uint accelerationFactor);
+ QImage renderScope(uint accelerationFactor);
+ QImage renderBackground(uint accelerationFactor);
};
-#endif // TESTWIDGET_H
+#endif // RGBPARADE_H
+++ /dev/null
-/***************************************************************************
- * Copyright (C) 2010 by Simon Andreas Eugster (simon.eu@gmail.com) *
- * This file is part of kdenlive. See www.kdenlive.org. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- ***************************************************************************/
-
-#include "testwidget.h"
-#include "ui_testwidget_ui.h"
-
-#include <QMenu>
-#include <QDebug>
-
-TestWidget::TestWidget(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
- AbstractScopeWidget(projMonitor, clipMonitor, parent)
-{
- ui = new Ui::TestWidget_UI();
- ui->setupUi(this);
-
- m_aTest = new QAction("Hallo. ", this);
- m_menu->addAction(m_aTest);
-}
-
-TestWidget::~TestWidget()
-{
- delete ui;
- delete m_aTest;
-}
-
-///// Implemented Methods /////
-
-QImage TestWidget::renderHUD(uint)
-{
- emit signalHUDRenderingFinished(0, 1);
- return QImage();
-}
-
-QImage TestWidget::renderScope(uint)
-{
- emit signalScopeRenderingFinished(0, 1);
- return QImage();
-}
-
-QImage TestWidget::renderBackground(uint)
-{
- emit signalBackgroundRenderingFinished(0, 1);
- return QImage();
-}
-
-QString TestWidget::widgetName() const { return "Testwidget"; }
-bool TestWidget::isHUDDependingOnInput() const { return false; }
-bool TestWidget::isScopeDependingOnInput() const { return false; }
-bool TestWidget::isBackgroundDependingOnInput() const { return false; }
-
-QRect TestWidget::scopeRect()
-{
- return QRect(QPoint(offset, ui->line->y() + 2*offset), this->rect().bottomRight() - QPoint(offset, offset));
-}
-
const float P75 = .75;
const unsigned char DEFAULT_Y = 255;
-//const unsigned int REALTIME_FPS = 15; // in fps.
const QPointF YUV_R(-.147, .615);
const QPointF YUV_G(-.289, -.515);
delete m_a75PBox;
}
-QString Vectorscope::widgetName() const {
- return QString("Vectorscope");
-}
+QString Vectorscope::widgetName() const { return QString("Vectorscope"); }
QRect Vectorscope::scopeRect()
{
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>TestWidget_UI</class>
- <widget class="QWidget" name="TestWidget_UI">
+ <class>RGBParade_UI</class>
+ <widget class="QWidget" name="RGBParade_UI">
<property name="geometry">
<rect>
<x>0</x>
</rect>
</property>
<property name="windowTitle">
- <string>Form</string>
+ <string>RGB Parade</string>
</property>
<layout class="QGridLayout" name="gridLayout">
+ <property name="horizontalSpacing">
+ <number>5</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QComboBox" name="cbPaintmode">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
<item row="0" column="0">
- <widget class="QComboBox" name="comboBox"/>
+ <widget class="QLabel" name="lblPaintmode">
+ <property name="text">
+ <string>Paint mode</string>
+ </property>
+ </widget>
</item>
- <item row="2" column="0">
+ <item row="2" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
- <item row="1" column="0">
+ <item row="1" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>