Bug Summary

File:home/HaikuArchives/ArtPaint/addons/AddOns/WoodRelief/Wood.cpp
Warning:line 158, column 10
Value stored to 'y_times_bpr' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-haiku -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name Wood.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /boot/system/lib/clang/12.0.1 -iquote ./ -iquote ../../UtilityClasses/ -iquote ./ -iquote ../../../artpaint/application -iquote ../../../artpaint/controls -iquote ../../../artpaint/layers -iquote ../../../artpaint/paintwindow -iquote ../../../artpaint/tools -iquote ../../../artpaint/viewmanipulators -iquote ../../../artpaint/windows -internal-isystem /system/develop/headers/c++ -internal-isystem /system/develop/headers/c++/x86_64-unknown-haiku -internal-isystem /system/develop/headers/c++/backward -O3 -fdeprecated-macro -fdebug-compilation-dir /boot/home/HaikuArchives/ArtPaint/addons/AddOns/WoodRelief -ferror-limit 19 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /tmp/scan-build-2022-06-19-103017-1294-1 -x c++ Wood.cpp
1/*
2 * Copyright 2003, Heikki Suhonen
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Heikki Suhonen <heikki.suhonen@gmail.com>
7 *
8 */
9#include <Bitmap.h>
10#include <Catalog.h>
11#include <StatusBar.h>
12#include <StopWatch.h>
13#include <Window.h>
14
15#include "AddOns.h"
16#include "ManipulatorInformer.h"
17#include "Wood.h"
18#include "PixelOperations.h"
19#include "PerlinNoiseGenerator.h"
20#include "Selection.h"
21
22#undef B_TRANSLATION_CONTEXT"AddOns_Wood"
23#define B_TRANSLATION_CONTEXT"AddOns_Wood" "AddOns_Wood"
24
25
26#ifdef __cplusplus201402L
27extern "C" {
28#endif
29 char name[255] = B_TRANSLATE_MARK("Wood")("Wood");
30 char menu_help_string[255] = B_TRANSLATE_MARK("Puts a wood-like texture over the image.")("Puts a wood-like texture over the image.");
31 int32 add_on_api_version = ADD_ON_API_VERSION;
32 add_on_types add_on_type = EFFECT_FILTER_ADD_ON;
33#ifdef __cplusplus201402L
34}
35#endif
36
37
38Manipulator* instantiate_add_on(BBitmap*,ManipulatorInformer *i)
39{
40 delete i;
41 return new WoodManipulator();
42}
43
44
45
46WoodManipulator::WoodManipulator()
47 : Manipulator()
48{
49 processor_count = GetSystemCpuCount();
50}
51
52
53WoodManipulator::~WoodManipulator()
54{
55}
56
57
58BBitmap* WoodManipulator::ManipulateBitmap(BBitmap *original,Selection *selection,BStatusBar *status_bar)
59{
60 BStopWatch watch("PerlinWood");
61
62 source_bitmap = original;
63 target_bitmap = original;
64 the_selection = selection;
65 progress_bar = status_bar;
66
67 thread_id *threads = new thread_id[processor_count];
68
69 spare_copy_bitmap = DuplicateBitmap(original,-1);
70
71 for (int32 i = 0;i < processor_count;i++) {
72 threads[i] = spawn_thread(thread_entrythread_func,"perlin_fade_thread",B_NORMAL_PRIORITY10,this);
73 resume_thread(threads[i]);
74 send_data(threads[i],i,NULL__null,0);
75 }
76
77 for (int32 i = 0;i < processor_count;i++) {
78 int32 return_value;
79 wait_for_thread(threads[i],&return_value);
80 }
81
82 delete[] threads;
83
84 delete spare_copy_bitmap;
85
86 // Return the original.
87 return original;
88}
89
90
91const char* WoodManipulator::ReturnHelpString()
92{
93 return B_TRANSLATE("Puts a wood-like texture over the image.")BLocaleRoster::Default()->GetCatalog()->GetString(("Puts a wood-like texture over the image."
), "AddOns_Wood")
;
94}
95
96
97const char* WoodManipulator::ReturnName()
98{
99 return B_TRANSLATE("Wood")BLocaleRoster::Default()->GetCatalog()->GetString(("Wood"
), "AddOns_Wood")
;
100}
101
102
103int32 WoodManipulator::thread_entrythread_func(void *data)
104{
105 int32 thread_number;
106 thread_number = receive_data(NULL__null,NULL__null,0);
107
108 WoodManipulator *this_pointer = (WoodManipulator*)data;
109
110 return this_pointer->thread_function(thread_number);
111}
112
113
114int32 WoodManipulator::thread_function(int32 thread_number)
115{
116 BWindow *progress_bar_window = NULL__null;
117 if (progress_bar != NULL__null)
118 progress_bar_window = progress_bar->Window();
119
120 uint32 *source = (uint32*)source_bitmap->Bits();
121 int32 source_bpr = source_bitmap->BytesPerRow()/4;
122
123 uint32 *spare_bits = (uint32*)spare_copy_bitmap->Bits();
124 int32 spare_bpr = spare_copy_bitmap->BytesPerRow()/4;
125
126 PerlinNoiseGenerator generator(0.7,7);
127
128 // This union must be used to guarantee endianness compatibility.
129 union {
130 uint8 bytes[4];
131 uint32 word;
132 } color,color1,color2,color3;
133
134 if (the_selection->IsEmpty()) {
135 // Here handle the whole image.
136 float left = target_bitmap->Bounds().left;
137 float right = target_bitmap->Bounds().right;
138 float top = target_bitmap->Bounds().top;
139 float bottom = target_bitmap->Bounds().bottom;
140
141 int32 height = (bottom - top+1)/processor_count;
142 top = min_c(bottom,top+thread_number*height)((bottom)>(top+thread_number*height)?(top+thread_number*height
):(bottom))
;
143 bottom = min_c(bottom,top + height-1)((bottom)>(top + height-1)?(top + height-1):(bottom));
144
145 int32 update_interval = 10;
146 float update_amount = 100.0/(bottom-top)*update_interval/(float)processor_count;
147 float missed_update = 0;
148
149 spare_bits += (int32)left + 1 + ((int32)top+1)*spare_bpr;
150
151 // Loop through all pixels in original.
152 float one_per_width = 1.0/8;
153 float one_per_height = 1.0/256;
154 float one_per_depth = 1.0/1024;
155 source += (int32)top*source_bpr;
156
157 for (float y=top;y<=bottom;++y) {
158 int32 y_times_bpr = y*source_bpr;
Value stored to 'y_times_bpr' during its initialization is never read
159 for (float x=left;x<=right;++x) {
160
161 color1.word = *(spare_bits - spare_bpr - 1);
162 color2.word = *(spare_bits + spare_bpr + 1);
163 color3.word = *source;
164
165 float difference = .144*(color1.bytes[0] - color2.bytes[0]) +
166 .587*(color1.bytes[1] - color2.bytes[1]) +
167 .299*(color1.bytes[2] - color2.bytes[2]);
168
169// if (difference != 0)
170// difference /= abs(difference);
171
172 difference /= 255.0;
173
174// This creates a woodlike texture when one_per_width is 1/8 and one_per_height is 1/256,
175// and generator is initialized with 0.7,8.
176 float z = .144*color3.bytes[0] +
177 .597*color3.bytes[1] +
178 .299*color3.bytes[2];
179
180 float noise = generator.PerlinNoise3D(x*one_per_width,y*one_per_height,z*one_per_depth);
181
182 float coeff = 0.5+(1+noise)*.25;
183 color3.bytes[0] = min_c(255,max_c(0,30*coeff+difference*200))((255)>(((0)>(30*coeff+difference*200)?(0):(30*coeff+difference
*200)))?(((0)>(30*coeff+difference*200)?(0):(30*coeff+difference
*200))):(255))
;
184 color3.bytes[1] = min_c(255,max_c(0,140*coeff+difference*200))((255)>(((0)>(140*coeff+difference*200)?(0):(140*coeff+
difference*200)))?(((0)>(140*coeff+difference*200)?(0):(140
*coeff+difference*200))):(255))
;
185 color3.bytes[2] = min_c(255,max_c(0,200*coeff+difference*200))((255)>(((0)>(200*coeff+difference*200)?(0):(200*coeff+
difference*200)))?(((0)>(200*coeff+difference*200)?(0):(200
*coeff+difference*200))):(255))
;
186
187 *source++ = color3.word;
188
189 spare_bits++;
190 }
191 spare_bits += 2;
192 // Update the status-bar
193 if ( (((int32)y % update_interval) == 0) && (progress_bar_window != NULL__null)
194 && (progress_bar_window->LockWithTimeout(0) == B_OK((int)0)) ) {
195 progress_bar->Update(update_amount+missed_update);
196 progress_bar_window->Unlock();
197 missed_update = 0;
198 }
199 else if (((int32)y % update_interval) == 0) {
200 missed_update += update_amount;
201 }
202 }
203
204 }
205 else {
206 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
207 BRect rect = the_selection->GetBoundingRect();
208
209 int32 left = rect.left;
210 int32 right = rect.right;
211 int32 top = rect.top;
212 int32 bottom = rect.bottom;
213
214 int32 height = (bottom - top+1)/processor_count;
215 top = min_c(bottom,top+thread_number*height)((bottom)>(top+thread_number*height)?(top+thread_number*height
):(bottom))
;
216 bottom = min_c(bottom,top + height-1)((bottom)>(top + height-1)?(top + height-1):(bottom));
217
218 int32 update_interval = 10;
219 float update_amount = 100.0/(bottom-top)*update_interval/(float)processor_count;
220 float missed_update = 0;
221
222 spare_bits += (int32)left + 1 + ((int32)top+1)*spare_bpr;
223
224 // Loop through all pixels in original.
225 float one_per_width = 1.0/8;
226 float one_per_height = 1.0/256;
227 float one_per_depth = 1.0/1024;
228 source += (int32)left + (int32)top*source_bpr;
229
230 // Loop through all pixels in original.
231 for (int32 y=top;y<=bottom;++y) {
232 for (int32 x=left;x<=right;++x) {
233 if (the_selection->ContainsPoint(x,y)) {
234
235 color1.word = *(spare_bits - spare_bpr - 1);
236 color2.word = *(spare_bits + spare_bpr + 1);
237 color3.word = *source;
238
239 float difference = .144*(color1.bytes[0] - color2.bytes[0]) +
240 .587*(color1.bytes[1] - color2.bytes[1]) +
241 .299*(color1.bytes[2] - color2.bytes[2]);
242 difference /= 255.0;
243
244// This creates a woodlike texture when one_per_width is 1/8 and one_per_height is 1/256,
245// and generator is initialized with 0.7,8.
246 float z = .144*color3.bytes[0] +
247 .597*color3.bytes[1] +
248 .299*color3.bytes[2];
249
250 float noise = generator.PerlinNoise3D(x*one_per_width,y*one_per_height,z*one_per_depth);
251
252 float coeff = 0.5+(1+noise)*.25;
253 color3.bytes[0] = min_c(255,max_c(0,30*coeff+difference*200))((255)>(((0)>(30*coeff+difference*200)?(0):(30*coeff+difference
*200)))?(((0)>(30*coeff+difference*200)?(0):(30*coeff+difference
*200))):(255))
;
254 color3.bytes[1] = min_c(255,max_c(0,140*coeff+difference*200))((255)>(((0)>(140*coeff+difference*200)?(0):(140*coeff+
difference*200)))?(((0)>(140*coeff+difference*200)?(0):(140
*coeff+difference*200))):(255))
;
255 color3.bytes[2] = min_c(255,max_c(0,200*coeff+difference*200))((255)>(((0)>(200*coeff+difference*200)?(0):(200*coeff+
difference*200)))?(((0)>(200*coeff+difference*200)?(0):(200
*coeff+difference*200))):(255))
;
256
257 *source++ = color3.word;
258
259 spare_bits++;
260 }
261 else {
262 ++source; ++spare_bits;
263 }
264 }
265 spare_bits += (spare_bpr - (int32)(right-left)-1);
266 source += (source_bpr - (int32)(right-left)-1);
267
268 // Update the status-bar
269 if ( (((int32)y % update_interval) == 0) && (progress_bar_window != NULL__null) && (progress_bar_window->LockWithTimeout(0) == B_OK((int)0)) ) {
270 progress_bar->Update(update_amount+missed_update);
271 progress_bar_window->Unlock();
272 missed_update = 0;
273 }
274 else if (((int32)y % update_interval) == 0) {
275 missed_update += update_amount;
276 }
277 }
278 }
279
280 return B_OK((int)0);
281}