File indexing completed on 2025-01-19 12:59:18
0001 /* This file is part of the KDE Project 0002 Copyright (C) 2002 Klaas Freitag <freitag@suse.de> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 0020 #include "kgammatable.h" 0021 0022 #include <math.h> 0023 0024 #include <qregexp.h> 0025 0026 #include "libkookascan_logging.h" 0027 0028 0029 KGammaTable::KGammaTable(int gamma, int brightness, int contrast) 0030 : QObject() 0031 { 0032 mGamma = (gamma < 1) ? 1 : gamma; 0033 mBrightness = brightness; 0034 mContrast = contrast; 0035 init(); 0036 } 0037 0038 KGammaTable::KGammaTable(const KGammaTable &other) 0039 : QObject() 0040 { 0041 mGamma = other.mGamma; 0042 mBrightness = other.mBrightness; 0043 mContrast = other.mContrast; 0044 init(); 0045 } 0046 0047 void KGammaTable::init() 0048 { 0049 mDirty = true; 0050 } 0051 0052 // Adapted from LabeledGamma::calculateGT() 0053 // in kdegraphics/libksane/libksane/widgets/labeled_gamma.cpp 0054 // 0055 // Input values are expected to be: 0056 // brightness -50 ... +50 0057 // contrast -50 ... +50 0058 // gamma 30 ... 300 = 0.3 ... 3.0 0059 // 0060 void KGammaTable::calcTable() 0061 { 0062 if (mGamma < 1.0) { // impossibly small 0063 qCWarning(LIBKOOKASCAN_LOG) << "invalid gamma" << mGamma; 0064 mDirty = false; // pointless, but don't repeat 0065 return; 0066 } 0067 0068 if (mData.isEmpty()) { // not allocated yet 0069 mData.resize(256); // do it now 0070 qCDebug(LIBKOOKASCAN_LOG) << "allocated table size" << mData.size(); 0071 } 0072 0073 qCDebug(LIBKOOKASCAN_LOG) << "initial b" << mBrightness << "c" << mContrast << "g" << mGamma; 0074 0075 const double maxval = (KGammaTable::valueRange - 1); 0076 double gam = 100.0 / mGamma; 0077 double con = (200.0 / (100.0 - mContrast)) - 1; 0078 double halfmax = maxval / 2.0; 0079 double bri = (mBrightness / halfmax) * maxval; 0080 qCDebug(LIBKOOKASCAN_LOG) << "adjusted bri" << bri << "con" << con << "gam" << gam; 0081 0082 for (int i = 0; i < mData.size(); ++i) { 0083 double x = pow(i / maxval, gam) * maxval; // apply gamma 0084 x = (con * (x - halfmax)) + halfmax; // apply contrast 0085 x += bri; // apply brightness 0086 mData[i] = qRound(qBound(0.0, x, maxval)); // limit value, save in table 0087 //qCDebug(LIBKOOKASCAN_LOG) << " " << i << "->" << mData[i]; 0088 } 0089 0090 mDirty = false; // table now calculated 0091 } 0092 0093 void KGammaTable::setBrightness(int brightness) // slot 0094 { 0095 mBrightness = brightness; 0096 mDirty = true; 0097 emit tableChanged(); 0098 } 0099 0100 void KGammaTable::setContrast(int contrast) // slot 0101 { 0102 mContrast = contrast; 0103 mDirty = true; 0104 emit tableChanged(); 0105 } 0106 0107 void KGammaTable::setGamma(int gamma) // slot 0108 { 0109 mGamma = gamma; 0110 mDirty = true; 0111 emit tableChanged(); 0112 } 0113 0114 void KGammaTable::setAll(int gamma, int brightness, int contrast) 0115 { 0116 mGamma = gamma < 1 ? 1 : gamma; 0117 mBrightness = brightness; 0118 mContrast = contrast; 0119 0120 mDirty = true; 0121 emit tableChanged(); 0122 } 0123 0124 const int *KGammaTable::getTable(int size) 0125 { 0126 if (size > 0 && size != mData.size()) { 0127 qCDebug(LIBKOOKASCAN_LOG) << "resize from" << mData.size() << "to" << size; 0128 mData.resize(size); 0129 mDirty = true; 0130 } 0131 0132 if (mDirty) { 0133 calcTable(); 0134 } 0135 return (mData.constData()); 0136 } 0137 0138 // originally done in KScanOption::set(const QByteArray &) 0139 bool KGammaTable::setFromString(const QString &str) 0140 { 0141 QRegExp re("(\\d+),(\\d+),(\\d+)"); 0142 if (!re.exactMatch(str)) { 0143 return (false); // unrecognised format 0144 } 0145 0146 int g = re.cap(1).toInt(); 0147 int b = re.cap(2).toInt(); 0148 int c = re.cap(3).toInt(); 0149 0150 setAll(g, b, c); 0151 return (true); // matched and set 0152 } 0153 0154 // originally done in KScanOption::get() 0155 QString KGammaTable::toString() const 0156 { 0157 return (QString("%1,%2,%3").arg(mGamma).arg(mBrightness).arg(mContrast)); 0158 }