File indexing completed on 2024-04-21 15:12:10

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 }