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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
/*
% Copyright (C) 2003 - 2019 GraphicsMagick Group
% Copyright (C) 2003 ImageMagick Studio
% Copyright 1991-1999 E. I. du Pont de Nemours and Company
%
% This program is covered by multiple licenses, which are described in
% Copyright.txt. You should have received a copy of Copyright.txt with this
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
%
% GraphicsMagick Gradient Image Methods.
%
*/
/*
Include declarations.
*/
#include "magick/studio.h"
#include "magick/alpha_composite.h"
#include "magick/color.h"
#include "magick/gradient.h"
#include "magick/monitor.h"
#include "magick/pixel_cache.h"
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
+ G r a d i e n t I m a g e %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% GradientImage() applies a continuously smooth color transitions along a
% vector from one color to another.
%
% Note, the interface of this method will change in the future to support
% more than one transistion.
%
% The format of the GradientImage method is:
%
% MagickPassFail GradientImage(Image *image,
% const PixelPacket *start_color,
% const PixelPacket *stop_color)
%
% A description of each parameter follows:
%
% o image: The image.
%
% o start_color: The start color.
%
% o stop_color: The stop color.
%
%
*/
#define GradientImageText "[%s] Gradient..."
MagickExport MagickPassFail GradientImage(Image *restrict image,
const PixelPacket *start_color,
const PixelPacket *stop_color)
{
const unsigned long
image_rows=image->rows,
image_columns=image->columns;
long
y;
unsigned long
row_count=0;
MagickBool
monitor_active;
MagickPassFail
status=MagickPass;
/*
Determine (Hue, Saturation, Brightness) gradient.
*/
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
assert(start_color != (const PixelPacket *) NULL);
assert(stop_color != (const PixelPacket *) NULL);
monitor_active=MagickMonitorActive();
/*
Generate gradient pixels.
*/
#if defined(HAVE_OPENMP)
# pragma omp parallel for shared(row_count, status)
#endif
for (y=0; y < (long) image->rows; y++)
{
MagickPassFail
thread_status;
register long
x;
register PixelPacket
*q;
thread_status=status;
if (thread_status == MagickFail)
continue;
q=SetImagePixelsEx(image,0,y,image->columns,1,&image->exception);
if (q == (PixelPacket *) NULL)
thread_status=MagickFail;
if (q != (PixelPacket *) NULL)
{
for (x=0; x < (long) image->columns; x++)
{
BlendCompositePixel(&q[x],start_color,stop_color,(double)
MaxRGB*(y*image_columns+x)/(image_columns*image_rows));
}
if (!SyncImagePixelsEx(image,&image->exception))
thread_status=MagickFail;
}
if (monitor_active)
{
unsigned long
thread_row_count;
#if defined(HAVE_OPENMP)
# pragma omp atomic
#endif
row_count++;
#if defined(HAVE_OPENMP)
# pragma omp flush (row_count)
#endif
thread_row_count=row_count;
if (QuantumTick(thread_row_count,image->rows))
if (!MagickMonitorFormatted(thread_row_count,image->rows,&image->exception,
GradientImageText,image->filename))
thread_status=MagickFail;
}
if (thread_status == MagickFail)
{
status=MagickFail;
#if defined(HAVE_OPENMP)
# pragma omp flush (status)
#endif
}
}
if (IsGray(*start_color) && IsGray(*stop_color))
image->is_grayscale=MagickTrue;
if (IsMonochrome(*start_color) && ColorMatch(start_color,stop_color))
image->is_monochrome=MagickTrue;
return(status);
}
|