1 /* This file is part of the KDE Project
2 Copyright (C) 2002 Klaas Freitag <freitag@suse.de>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "kgammatable.h"
21
22 #include <math.h>
23
24 #include <qregexp.h>
25
26 #include <QDebug>
27
KGammaTable(int gamma,int brightness,int contrast)28 KGammaTable::KGammaTable(int gamma, int brightness, int contrast)
29 : QObject()
30 {
31 mGamma = (gamma < 1) ? 1 : gamma;
32 mBrightness = brightness;
33 mContrast = contrast;
34 init();
35 }
36
KGammaTable(const KGammaTable & other)37 KGammaTable::KGammaTable(const KGammaTable &other)
38 : QObject()
39 {
40 mGamma = other.mGamma;
41 mBrightness = other.mBrightness;
42 mContrast = other.mContrast;
43 init();
44 }
45
init()46 void KGammaTable::init()
47 {
48 mDirty = true;
49 }
50
51 // Adapted from LabeledGamma::calculateGT()
52 // in kdegraphics/libksane/libksane/widgets/labeled_gamma.cpp
53 //
54 // Input values are expected to be:
55 // brightness -50 ... +50
56 // contrast -50 ... +50
57 // gamma 30 ... 300 = 0.3 ... 3.0
58 //
calcTable()59 void KGammaTable::calcTable()
60 {
61 if (mGamma < 1.0) { // impossibly small
62 //qDebug() << "invalid gamma" << mGamma;
63 mDirty = false; // pointless, but don't repeat
64 return;
65 }
66
67 if (mData.isEmpty()) { // not allocated yet
68 mData.resize(256); // do it now
69 //qDebug() << "allocated table size" << mData.size();
70 }
71
72 ////qDebug() << "b=" << mBrightness << "c=" << mContrast << "g=" << mGamma;
73
74 const double maxval = (KGammaTable::valueRange - 1);
75 double gam = 100.0 / mGamma;
76 double con = (200.0 / (100.0 - mContrast)) - 1;
77 double halfmax = maxval / 2.0;
78 double bri = (mBrightness / halfmax) * maxval;
79 ////qDebug() << "bri=" << bri << "con=" << con << "gam=" << gam;
80
81 for (int i = 0; i < mData.size(); ++i) {
82 double x = pow(i / maxval, gam) * maxval; // apply gamma
83 x = (con * (x - halfmax)) + halfmax; // apply contrast
84 x += bri; // apply brightness
85 mData[i] = qRound(qBound(0.0, x, maxval)); // limit value, save in table
86 ////qDebug() << " " << i << "->" << mData[i];
87 }
88
89 mDirty = false; // table now calculated
90 }
91
setBrightness(int brightness)92 void KGammaTable::setBrightness(int brightness) // slot
93 {
94 mBrightness = brightness;
95 mDirty = true;
96 emit tableChanged();
97 }
98
setContrast(int contrast)99 void KGammaTable::setContrast(int contrast) // slot
100 {
101 mContrast = contrast;
102 mDirty = true;
103 emit tableChanged();
104 }
105
setGamma(int gamma)106 void KGammaTable::setGamma(int gamma) // slot
107 {
108 mGamma = gamma;
109 mDirty = true;
110 emit tableChanged();
111 }
112
setAll(int gamma,int brightness,int contrast)113 void KGammaTable::setAll(int gamma, int brightness, int contrast)
114 {
115 mGamma = gamma < 1 ? 1 : gamma;
116 mBrightness = brightness;
117 mContrast = contrast;
118
119 mDirty = true;
120 emit tableChanged();
121 }
122
getTable(int size)123 const int *KGammaTable::getTable(int size)
124 {
125 if (size > 0 && size != mData.size()) {
126 //qDebug() << "resize from" << mData.size() << "to" << size;
127 mData.resize(size);
128 mDirty = true;
129 }
130
131 if (mDirty) {
132 calcTable();
133 }
134 return (mData.constData());
135 }
136
137 // originally done in KScanOption::set(const QByteArray &)
setFromString(const QString & str)138 bool KGammaTable::setFromString(const QString &str)
139 {
140 QRegExp re("(\\d+),(\\d+),(\\d+)");
141 if (!re.exactMatch(str)) {
142 return (false); // unrecognised format
143 }
144
145 int g = re.cap(1).toInt();
146 int b = re.cap(2).toInt();
147 int c = re.cap(3).toInt();
148
149 setAll(g, b, c);
150 return (true); // matched and set
151 }
152
153 // originally done in KScanOption::get()
toString() const154 QString KGammaTable::toString() const
155 {
156 return (QString("%1,%2,%3").arg(mGamma).arg(mBrightness).arg(mContrast));
157 }
158