Commit 2ce698b9 authored by Simon Eugster's avatar Simon Eugster
Browse files

RGB Parade added.

Testwidget removed, not necessary anymore.

svn path=/trunk/kdenlive/; revision=4616
parent 7f8ee4ba
......@@ -93,7 +93,7 @@ kde4_add_ui_files(kdenlive_UI
widgets/vectorscope_ui.ui
widgets/colorplaneexport_ui.ui
widgets/waveform_ui.ui
widgets/testwidget_ui.ui
widgets/rgbparade_ui.ui
)
set(kdenlive_SRCS
......@@ -201,9 +201,10 @@ set(kdenlive_SRCS
colortools.cpp
rebuildgroupcommand.cpp
waveform.cpp
rgbparade.cpp
colorcorrection/waveformgenerator.cpp
colorcorrection/vectorscopegenerator.cpp
testwidget.cpp
colorcorrection/rgbparadegenerator.cpp
razorgroupcommand.cpp
)
......
/***************************************************************************
* 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 &paradeSize, 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(&parade);
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
......@@ -8,55 +8,23 @@
* (at your option) any later version. *
***************************************************************************/
#include "testwidget.h"
#include "ui_testwidget_ui.h"
#ifndef RGBPARADEGENERATOR_H
#define RGBPARADEGENERATOR_H
#include <QMenu>
#include <QDebug>
#include <QObject>
TestWidget::TestWidget(Monitor *projMonitor, Monitor *clipMonitor, QWidget *parent) :
AbstractScopeWidget(projMonitor, clipMonitor, parent)
class QColor;
class QImage;
class QSize;
class RGBParadeGenerator : public QObject
{
ui = new Ui::TestWidget_UI();
ui->setupUi(this);
public:
RGBParadeGenerator();
QImage calculateRGBParade(const QSize &paradeSize, const QImage &image, const bool &drawAxis, const uint &accelFactor = 1);
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));
}
static const QColor colHighlight;
static const QColor colLight;
static const QColor colSoft;
};
#endif // RGBPARADEGENERATOR_H
......@@ -111,3 +111,4 @@ QImage WaveformGenerator::calculateWaveform(const QSize &waveformSize, const QIm
return wave;
}
#undef CHOP255
......@@ -54,7 +54,7 @@
#include "ui_templateclip_ui.h"
#include "vectorscope.h"
#include "waveform.h"
#include "testwidget.h"
#include "rgbparade.h"
#include <KApplication>
#include <KAction>
......@@ -217,21 +217,21 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
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);
......@@ -263,6 +263,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
#endif
tabifyDockWidget(m_vectorscopeDock, m_waveformDock);
tabifyDockWidget(m_vectorscopeDock, m_RGBParadeDock);
tabifyDockWidget(m_vectorscopeDock, m_undoViewDock);
tabifyDockWidget(m_vectorscopeDock, m_effectListDock);
......@@ -423,6 +424,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
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()));
......@@ -3610,6 +3612,7 @@ void MainWindow::slotShowTitleBars(bool show)
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)); }
......@@ -3623,6 +3626,7 @@ void MainWindow::slotShowTitleBars(bool show)
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);
}
......
......@@ -63,7 +63,7 @@ class Render;
class Transition;
class Vectorscope;
class Waveform;
class TestWidget;
class RGBParade;
class KActionCollection;
class MainWindow : public KXmlGuiWindow
......@@ -159,8 +159,8 @@ private:
QDockWidget *m_waveformDock;
Waveform *m_waveform;
QDockWidget *m_testDock;
TestWidget *m_test;
QDockWidget *m_RGBParadeDock;
RGBParade *m_RGBParade;
QDockWidget *m_undoViewDock;
QUndoView *m_undoView;
......
/***************************************************************************
* 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; }
......@@ -8,40 +8,39 @@
* (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
......@@ -26,7 +26,6 @@
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);
......@@ -114,9 +113,7 @@ Vectorscope::~Vectorscope()
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>
......@@ -11,13 +11,30 @@
</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>
......@@ -30,7 +47,7 @@
</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>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment