File indexing completed on 2024-05-12 04:19:35
0001 /* 0002 Gwenview: an image viewer 0003 Copyright 2000-2004 Aurélien Gâteau <agateau@kde.org> 0004 Copyright 2022 Ilya Pominov <ipominov@astralinux.ru> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU General Public License 0008 as published by the Free Software Foundation; either version 2 0009 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 GNU General Public License for more details. 0015 0016 You should have received a copy of the GNU General Public License 0017 along with this program; if not, write to the Free Software 0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 0019 0020 */ 0021 #include "imageutils.h" 0022 0023 #include <cmath> 0024 0025 namespace Gwenview 0026 { 0027 namespace ImageUtils 0028 { 0029 inline int changeBrightness(int value, int brightness) 0030 { 0031 return qBound(0, value + brightness * 255 / 100, 255); 0032 } 0033 0034 inline int changeContrast(int value, int contrast) 0035 { 0036 return qBound(0, ((value - 127) * contrast / 100) + 127, 255); 0037 } 0038 0039 inline int changeGamma(int value, int gamma) 0040 { 0041 return qBound(0, int(pow(value / 255.0, 100.0 / gamma) * 255), 255); 0042 } 0043 0044 inline int changeUsingTable(int value, const int table[]) 0045 { 0046 return table[value]; 0047 } 0048 0049 /* 0050 Applies either brightness, contrast or gamma conversion on the image. 0051 If the image is not truecolor, the color table is changed. If it is 0052 truecolor, every pixel has to be changed. In order to make it as fast 0053 as possible, alpha value is converted only if necessary. Additionally, 0054 since color components (red/green/blue/alpha) can have only 256 values 0055 but images usually have many pixels, a conversion table is first 0056 created for every color component value, and pixels are converted 0057 using this table. 0058 */ 0059 0060 template<int operation(int, int)> 0061 static QImage changeImage(const QImage &image, int value) 0062 { 0063 QImage im = image; 0064 im.detach(); 0065 if (im.colorCount() == 0) { /* truecolor */ 0066 if (im.depth() != 32) { /* just in case */ 0067 // im = im.convertDepth( 32 ); in old version 0068 im.convertTo(im.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32); 0069 } 0070 int table[256]; 0071 for (int i = 0; i < 256; ++i) { 0072 table[i] = operation(i, value); 0073 } 0074 if (im.hasAlphaChannel()) { 0075 for (int y = 0; y < im.height(); ++y) { 0076 QRgb *line = reinterpret_cast<QRgb *>(im.scanLine(y)); 0077 for (int x = 0; x < im.width(); ++x) { 0078 line[x] = qRgba(changeUsingTable(qRed(line[x]), table), 0079 changeUsingTable(qGreen(line[x]), table), 0080 changeUsingTable(qBlue(line[x]), table), 0081 changeUsingTable(qAlpha(line[x]), table)); 0082 } 0083 } 0084 } else { 0085 for (int y = 0; y < im.height(); ++y) { 0086 QRgb *line = reinterpret_cast<QRgb *>(im.scanLine(y)); 0087 for (int x = 0; x < im.width(); ++x) { 0088 line[x] = qRgb(changeUsingTable(qRed(line[x]), table), changeUsingTable(qGreen(line[x]), table), changeUsingTable(qBlue(line[x]), table)); 0089 } 0090 } 0091 } 0092 } else { 0093 auto colors = im.colorTable(); 0094 for (int i = 0; i < im.colorCount(); ++i) { 0095 colors[i] = qRgb(operation(qRed(colors[i]), value), operation(qGreen(colors[i]), value), operation(qBlue(colors[i]), value)); 0096 } 0097 } 0098 return im; 0099 } 0100 0101 // brightness is multiplied by 100 in order to avoid floating point numbers 0102 QImage changeBrightness(const QImage &image, int brightness) 0103 { 0104 if (brightness == 0) { // no change 0105 return image; 0106 } 0107 return changeImage<changeBrightness>(image, brightness); 0108 } 0109 0110 // contrast is multiplied by 100 in order to avoid floating point numbers 0111 QImage changeContrast(const QImage &image, int contrast) 0112 { 0113 if (contrast == 100) { // no change 0114 return image; 0115 } 0116 return changeImage<changeContrast>(image, contrast); 0117 } 0118 0119 // gamma is multiplied by 100 in order to avoid floating point numbers 0120 QImage changeGamma(const QImage &image, int gamma) 0121 { 0122 if (gamma == 100) { // no change 0123 return image; 0124 } 0125 return changeImage<changeGamma>(image, gamma); 0126 } 0127 0128 } // Namespace 0129 } // Namespace