1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/* ============================================================
*
* This file is a part of digiKam project
* http://www.digikam.org
*
* Date : 2005-05-25
* Description : Emboss threaded image filter.
*
* Copyright (C) 2005-2007 by Gilles Caulier <caulier dot gilles at gmail dot com>
* Copyright (C) 2006-2007 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
*
* Original Emboss algorithm copyrighted 2004 by
* Pieter Z. Voloshyn <pieter dot voloshyn at gmail dot com>.
*
* 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, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* ============================================================ */
// C++ includes.
#include <cmath>
#include <cstdlib>
// Local includes.
#include "dimg.h"
#include "dimgimagefilters.h"
#include "emboss.h"
namespace DigikamEmbossImagesPlugin
{
Emboss::Emboss(Digikam::DImg *orgImage, TQObject *parent, int depth)
: Digikam::DImgThreadedFilter(orgImage, parent, "Emboss")
{
m_depth = depth;
initFilter();
}
void Emboss::filterImage(void)
{
embossImage(&m_orgImage, &m_destImage, m_depth);
}
// This method have been ported from Pieter Z. Voloshyn algorithm code.
/* Function to apply the Emboss effect
*
* data => The image data in RGBA mode.
* Width => Width of image.
* Height => Height of image.
* d => Emboss value
*
* Theory => This is an amazing effect. And the theory is very simple to
* understand. You get the diference between the colors and
* increase it. After this, get the gray tone
*/
void Emboss::embossImage(Digikam::DImg *orgImage, Digikam::DImg *destImage, int d)
{
int Width = orgImage->width();
int Height = orgImage->height();
uchar* data = orgImage->bits();
bool sixteenBit = orgImage->sixteenBit();
int bytesDepth = orgImage->bytesDepth();
uchar* Bits = destImage->bits();
// Initial copy
memcpy (Bits, data, destImage->numBytes());
double Depth = d / 10.0;
int progress;
int red, green, blue, gray;
Digikam::DColor color, colorOther;
int offset, offsetOther;
for (int h = 0 ; !m_cancel && (h < Height) ; h++)
{
for (int w = 0 ; !m_cancel && (w < Width) ; w++)
{
offset = getOffset(Width, w, h, bytesDepth);
offsetOther = getOffset(Width, w + Lim_Max (w, 1, Width), h + Lim_Max (h, 1, Height), bytesDepth);
color.setColor(Bits + offset, sixteenBit);
colorOther.setColor(Bits + offsetOther, sixteenBit);
if (sixteenBit)
{
red = abs ((int)((color.red() - colorOther.red()) * Depth + 32768));
green = abs ((int)((color.green() - colorOther.green()) * Depth + 32768));
blue = abs ((int)((color.blue() - colorOther.blue()) * Depth + 32768));
gray = CLAMP065535 ((red + green + blue) / 3);
}
else
{
red = abs ((int)((color.red() - colorOther.red()) * Depth + 128));
green = abs ((int)((color.green() - colorOther.green()) * Depth + 128));
blue = abs ((int)((color.blue() - colorOther.blue()) * Depth + 128));
gray = CLAMP0255 ((red + green + blue) / 3);
}
// Overwrite RGB values to destination. Alpha remains unchanged.
color.setRed(gray);
color.setGreen(gray);
color.setBlue(gray);
color.setPixel(Bits + offset);
}
progress = (int) (((double)h * 100.0) / Height);
if ( progress%5 == 0 )
postProgress( progress );
}
}
} // NameSpace DigikamEmbossImagesPlugin
|