Bug Summary

File:home/HaikuArchives/ArtPaint/addons/AddOns/Halftone/Halftone.cpp
Warning:line 212, column 8
Value stored to 'target_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 Halftone.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/Halftone -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++ Halftone.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 <Window.h>
12
13#include "AddOns.h"
14#include "Halftone.h"
15#include "RandomNumberGenerator.h"
16#include "ManipulatorInformer.h"
17#include "Selection.h"
18
19#undef B_TRANSLATION_CONTEXT"AddOns_Halftone"
20#define B_TRANSLATION_CONTEXT"AddOns_Halftone" "AddOns_Halftone"
21
22
23#ifdef __cplusplus201402L
24extern "C" {
25#endif
26 char name[255] = B_TRANSLATE_MARK("Halftone")("Halftone");
27 char menu_help_string[255] =
28 B_TRANSLATE_MARK("Makes a halftone-pattern with fore- and background colors.")("Makes a halftone-pattern with fore- and background colors."
)
;
29 int32 add_on_api_version = ADD_ON_API_VERSION;
30 add_on_types add_on_type = GENERIC_ADD_ON;
31#ifdef __cplusplus201402L
32}
33#endif
34
35
36Manipulator* instantiate_add_on(BBitmap*,ManipulatorInformer *i)
37{
38 return new Halftone(i);
39}
40
41
42
43Halftone::Halftone(ManipulatorInformer *i)
44 : Manipulator(), round_dot_size(ROUND_DOT_SIZE8), diagonal_line_size(DIAGONAL_LINE_SIZE5)
45 , ordered_matrix_size(ORDERED_MATRIX_SIZE4)
46{
47 informer = i;
48 round_dot_pattern[0][0] = 1;
49 round_dot_pattern[0][1] = 8;
50 round_dot_pattern[0][2] = 16;
51 round_dot_pattern[0][3] = 29;
52 round_dot_pattern[0][4] = 25;
53 round_dot_pattern[0][5] = 22;
54 round_dot_pattern[0][6] = 6;
55 round_dot_pattern[0][7] = 2;
56
57 round_dot_pattern[1][0] = 5;
58 round_dot_pattern[1][1] = 12;
59 round_dot_pattern[1][2] = 33;
60 round_dot_pattern[1][3] = 42;
61 round_dot_pattern[1][4] = 46;
62 round_dot_pattern[1][5] = 38;
63 round_dot_pattern[1][6] = 13;
64 round_dot_pattern[1][7] = 9;
65
66 round_dot_pattern[2][0] = 21;
67 round_dot_pattern[2][1] = 37;
68 round_dot_pattern[2][2] = 49;
69 round_dot_pattern[2][3] = 58;
70 round_dot_pattern[2][4] = 54;
71 round_dot_pattern[2][5] = 50;
72 round_dot_pattern[2][6] = 34;
73 round_dot_pattern[2][7] = 17;
74
75 round_dot_pattern[3][0] = 24;
76 round_dot_pattern[3][1] = 45;
77 round_dot_pattern[3][2] = 53;
78 round_dot_pattern[3][3] = 62;
79 round_dot_pattern[3][4] = 63;
80 round_dot_pattern[3][5] = 59;
81 round_dot_pattern[3][6] = 43;
82 round_dot_pattern[3][7] = 30;
83
84 round_dot_pattern[4][0] = 28;
85 round_dot_pattern[4][1] = 41;
86 round_dot_pattern[4][2] = 57;
87 round_dot_pattern[4][3] = 61;
88 round_dot_pattern[4][4] = 60;
89 round_dot_pattern[4][5] = 55;
90 round_dot_pattern[4][6] = 47;
91 round_dot_pattern[4][7] = 26;
92
93 round_dot_pattern[5][0] = 19;
94 round_dot_pattern[5][1] = 32;
95 round_dot_pattern[5][2] = 48;
96 round_dot_pattern[5][3] = 52;
97 round_dot_pattern[5][4] = 56;
98 round_dot_pattern[5][5] = 51;
99 round_dot_pattern[5][6] = 39;
100 round_dot_pattern[5][7] = 23;
101
102 round_dot_pattern[6][0] = 11;
103 round_dot_pattern[6][1] = 15;
104 round_dot_pattern[6][2] = 36;
105 round_dot_pattern[6][3] = 44;
106 round_dot_pattern[6][4] = 40;
107 round_dot_pattern[6][5] = 35;
108 round_dot_pattern[6][6] = 14;
109 round_dot_pattern[6][7] = 7;
110
111 round_dot_pattern[7][0] = 0;
112 round_dot_pattern[7][1] = 4;
113 round_dot_pattern[7][2] = 20;
114 round_dot_pattern[7][3] = 27;
115 round_dot_pattern[7][4] = 31;
116 round_dot_pattern[7][5] = 18;
117 round_dot_pattern[7][6] = 10;
118 round_dot_pattern[7][7] = 3;
119
120
121 diagonal_line_pattern[2][2] = 24;
122 diagonal_line_pattern[1][3] = 23;
123 diagonal_line_pattern[3][1] = 22;
124 diagonal_line_pattern[0][4] = 21;
125 diagonal_line_pattern[4][0] = 20;
126
127 diagonal_line_pattern[1][0] = 19;
128 diagonal_line_pattern[0][1] = 18;
129
130 diagonal_line_pattern[4][3] = 17;
131 diagonal_line_pattern[3][4] = 16;
132
133 diagonal_line_pattern[1][1] = 15;
134 diagonal_line_pattern[0][2] = 14;
135 diagonal_line_pattern[2][0] = 13;
136
137 diagonal_line_pattern[3][3] = 12;
138 diagonal_line_pattern[2][4] = 11;
139 diagonal_line_pattern[4][2] = 10;
140
141 diagonal_line_pattern[2][1] = 9;
142 diagonal_line_pattern[1][2] = 8;
143 diagonal_line_pattern[3][0] = 7;
144 diagonal_line_pattern[0][3] = 6;
145
146 diagonal_line_pattern[3][2] = 5;
147 diagonal_line_pattern[2][3] = 4;
148 diagonal_line_pattern[4][1] = 3;
149 diagonal_line_pattern[1][4] = 2;
150
151 diagonal_line_pattern[0][0] = 1;
152 diagonal_line_pattern[4][4] = 0;
153
154 ordered_matrix[0][0] = 0;
155 ordered_matrix[0][1] = 8;
156 ordered_matrix[0][2] = 2;
157 ordered_matrix[0][3] = 10;
158
159 ordered_matrix[1][0] = 12;
160 ordered_matrix[1][1] = 4;
161 ordered_matrix[1][2] = 14;
162 ordered_matrix[1][3] = 16;
163
164 ordered_matrix[2][0] = 3;
165 ordered_matrix[2][1] = 11;
166 ordered_matrix[2][2] = 1;
167 ordered_matrix[2][3] = 9;
168
169 ordered_matrix[3][0] = 15;
170 ordered_matrix[3][1] = 7;
171 ordered_matrix[3][2] = 13;
172 ordered_matrix[3][3] = 5;
173}
174
175
176Halftone::~Halftone()
177{
178 delete informer;
179}
180
181
182BBitmap* Halftone::ManipulateBitmap(BBitmap *original,Selection *selection,BStatusBar *status_bar)
183{
184 return round_dot_halftone(original,selection,status_bar);
185// return diagonal_line_halftone(original,selection,status_bar);
186// return ordered_dither_halftone(original,selection,status_bar);
187// return fs_dither_halftone(original,selection,status_bar);
188// return ncandidate_dither_halftone(original,selection,status_bar);
189}
190
191
192const char* Halftone::ReturnHelpString()
193{
194 return B_TRANSLATE("Makes a halftone-pattern with fore- and background colors.")BLocaleRoster::Default()->GetCatalog()->GetString(("Makes a halftone-pattern with fore- and background colors."
), "AddOns_Halftone")
;
195}
196
197
198const char* Halftone::ReturnName()
199{
200 return B_TRANSLATE("Halftone")BLocaleRoster::Default()->GetCatalog()->GetString(("Halftone"
), "AddOns_Halftone")
;
201}
202
203
204BBitmap* Halftone::round_dot_halftone(BBitmap *original,Selection *selection, BStatusBar *status_bar)
205{
206 if (original == NULL__null)
207 return NULL__null;
208
209 uint32 *source_bits = (uint32*)original->Bits();
210 uint32 *target_bits = (uint32*)original->Bits();
211 int32 source_bpr = original->BytesPerRow()/4;
212 int32 target_bpr = original->BytesPerRow()/4;
Value stored to 'target_bpr' during its initialization is never read
213 int32 top,bottom,left,right;
214
215 left = original->Bounds().left;
216 right = original->Bounds().right + 1;
217 top = original->Bounds().top;
218 bottom = original->Bounds().bottom + 1;
219
220
221 union {
222 uint8 bytes[4];
223 uint32 word;
224 } color,c1,c2;
225 rgb_color c = informer->GetBackgroundColor();
226 c1.bytes[0] = c.blue;
227 c1.bytes[1] = c.green;
228 c1.bytes[2] = c.red;
229 c1.bytes[3] = c.alpha;
230
231 c = informer->GetForegroundColor();
232 c2.bytes[0] = c.blue;
233 c2.bytes[1] = c.green;
234 c2.bytes[2] = c.red;
235 c2.bytes[3] = c.alpha;
236
237 if (selection->IsEmpty()) {
238 // Here handle the whole image.
239 float normalizer = 1.0/255.0*round_dot_size*round_dot_size;
240 for (int32 y=top;y<bottom;y+=round_dot_size) {
241 for (int32 x=left;x<right;x+=round_dot_size) {
242 int32 r =min_c(x+round_dot_size,right)((x+round_dot_size)>(right)?(right):(x+round_dot_size));
243 int32 b = min_c(y+round_dot_size,bottom)((y+round_dot_size)>(bottom)?(bottom):(y+round_dot_size));
244 uint32 *s_delta_bits;
245
246 int32 number_of_pixels = 0;
247 for (int32 dy=y;dy<b;dy++) {
248 s_delta_bits = source_bits + dy*source_bpr + x;
249 for (int32 dx=x;dx<r;dx++) {
250 color.word = *s_delta_bits;
251 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
252 int threshold = luminance * normalizer;
253 *s_delta_bits++ = (round_dot_pattern[dy-y][dx-x]>threshold?c1.word:c2.word);
254 }
255 }
256 }
257 }
258 }
259 else {
260 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
261 float normalizer = 1.0/255.0*round_dot_size*round_dot_size;
262 for (int32 y=top;y<bottom;y+=round_dot_size) {
263 for (int32 x=left;x<right;x+=round_dot_size) {
264 int32 r =min_c(x+round_dot_size,right)((x+round_dot_size)>(right)?(right):(x+round_dot_size));
265 int32 b = min_c(y+round_dot_size,bottom)((y+round_dot_size)>(bottom)?(bottom):(y+round_dot_size));
266 uint32 *s_delta_bits;
267
268 int32 number_of_pixels = 0;
269 for (int32 dy=y;dy<b;dy++) {
270 s_delta_bits = source_bits + dy*source_bpr + x;
271 for (int32 dx=x;dx<r;dx++) {
272 if (selection->ContainsPoint(dx,dy)) {
273 color.word = *s_delta_bits;
274 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
275 int threshold = luminance * normalizer;
276 *s_delta_bits = (round_dot_pattern[dy-y][dx-x]>threshold?c1.word:c2.word);
277 }
278 s_delta_bits++;
279 }
280 }
281 }
282 }
283 }
284
285 return original;
286}
287
288
289BBitmap* Halftone::diagonal_line_halftone(BBitmap *original,Selection *selection, BStatusBar *status_bar)
290{
291 if (original == NULL__null)
292 return NULL__null;
293
294 uint32 *source_bits = (uint32*)original->Bits();
295 uint32 *target_bits = (uint32*)original->Bits();
296 int32 source_bpr = original->BytesPerRow()/4;
297 int32 target_bpr = original->BytesPerRow()/4;
298 int32 top,bottom,left,right;
299
300 left = original->Bounds().left;
301 right = original->Bounds().right + 1;
302 top = original->Bounds().top;
303 bottom = original->Bounds().bottom + 1;
304
305
306 union {
307 uint8 bytes[4];
308 uint32 word;
309 } color,c1,c2;
310 rgb_color c = informer->GetForegroundColor();
311 c1.bytes[0] = c.blue;
312 c1.bytes[1] = c.green;
313 c1.bytes[2] = c.red;
314 c1.bytes[3] = c.alpha;
315
316 c = informer->GetBackgroundColor();
317 c2.bytes[0] = c.blue;
318 c2.bytes[1] = c.green;
319 c2.bytes[2] = c.red;
320 c2.bytes[3] = c.alpha;
321
322 if (selection->IsEmpty()) {
323 // Here handle the whole image.
324 float normalizer = 1.0/255.0*diagonal_line_size*diagonal_line_size;
325 for (int32 y=top;y<bottom;y+=diagonal_line_size) {
326 for (int32 x=left;x<right;x+=diagonal_line_size) {
327 int32 r =min_c(x+diagonal_line_size,right)((x+diagonal_line_size)>(right)?(right):(x+diagonal_line_size
))
;
328 int32 b = min_c(y+diagonal_line_size,bottom)((y+diagonal_line_size)>(bottom)?(bottom):(y+diagonal_line_size
))
;
329 uint32 *s_delta_bits;
330
331 int32 number_of_pixels = 0;
332 for (int32 dy=y;dy<b;dy++) {
333 s_delta_bits = source_bits + dy*source_bpr + x;
334 for (int32 dx=x;dx<r;dx++) {
335 color.word = *s_delta_bits;
336 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
337 int threshold = luminance * normalizer;
338 *s_delta_bits++ = (diagonal_line_pattern[dy-y][dx-x]>threshold?c1.word:c2.word);
339 }
340 }
341 }
342 }
343 }
344 else {
345 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
346 float normalizer = 1.0/255.0*diagonal_line_size*diagonal_line_size;
347 for (int32 y=top;y<bottom;y+=diagonal_line_size) {
348 for (int32 x=left;x<right;x+=diagonal_line_size) {
349 int32 r =min_c(x+diagonal_line_size,right)((x+diagonal_line_size)>(right)?(right):(x+diagonal_line_size
))
;
350 int32 b = min_c(y+diagonal_line_size,bottom)((y+diagonal_line_size)>(bottom)?(bottom):(y+diagonal_line_size
))
;
351 uint32 *s_delta_bits;
352
353 int32 number_of_pixels = 0;
354 for (int32 dy=y;dy<b;dy++) {
355 s_delta_bits = source_bits + dy*source_bpr + x;
356 for (int32 dx=x;dx<r;dx++) {
357 if (selection->ContainsPoint(dx,dy)) {
358 color.word = *s_delta_bits;
359 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
360 int threshold = luminance * normalizer;
361 *s_delta_bits = (diagonal_line_pattern[dy-y][dx-x]>threshold?c1.word:c2.word);
362 }
363 s_delta_bits++;
364 }
365 }
366 }
367 }
368 }
369
370 return original;
371}
372
373BBitmap* Halftone::ordered_dither_halftone(BBitmap *original,Selection *selection, BStatusBar *status_bar)
374{
375 if (original == NULL__null)
376 return NULL__null;
377
378 uint32 *source_bits = (uint32*)original->Bits();
379 uint32 *target_bits = (uint32*)original->Bits();
380 int32 source_bpr = original->BytesPerRow()/4;
381 int32 target_bpr = original->BytesPerRow()/4;
382 int32 top,bottom,left,right;
383
384 left = original->Bounds().left;
385 right = original->Bounds().right + 1;
386 top = original->Bounds().top;
387 bottom = original->Bounds().bottom + 1;
388
389
390 union {
391 uint8 bytes[4];
392 uint32 word;
393 } color,c1,c2;
394 rgb_color c = informer->GetForegroundColor();
395 c1.bytes[0] = c.blue;
396 c1.bytes[1] = c.green;
397 c1.bytes[2] = c.red;
398 c1.bytes[3] = c.alpha;
399
400 c = informer->GetBackgroundColor();
401 c2.bytes[0] = c.blue;
402 c2.bytes[1] = c.green;
403 c2.bytes[2] = c.red;
404 c2.bytes[3] = c.alpha;
405
406 if (selection->IsEmpty()) {
407 // Here handle the whole image.
408 float normalizer = 1.0/255.0*ordered_matrix_size*ordered_matrix_size;
409 for (int32 y=top;y<bottom;y+=ordered_matrix_size) {
410 for (int32 x=left;x<right;x+=ordered_matrix_size) {
411 int32 r =min_c(x+ordered_matrix_size,right)((x+ordered_matrix_size)>(right)?(right):(x+ordered_matrix_size
))
;
412 int32 b = min_c(y+ordered_matrix_size,bottom)((y+ordered_matrix_size)>(bottom)?(bottom):(y+ordered_matrix_size
))
;
413 uint32 *s_delta_bits;
414
415 int32 number_of_pixels = 0;
416 for (int32 dy=y;dy<b;dy++) {
417 s_delta_bits = source_bits + dy*source_bpr + x;
418 for (int32 dx=x;dx<r;dx++) {
419 color.word = *s_delta_bits;
420 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
421 int threshold = luminance * normalizer;
422 *s_delta_bits++ = (ordered_matrix[dy-y][dx-x]>threshold?c1.word:c2.word);
423 }
424 }
425 }
426 }
427 }
428 else {
429 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
430 float normalizer = 1.0/255.0*ordered_matrix_size*ordered_matrix_size;
431 for (int32 y=top;y<bottom;y+=ordered_matrix_size) {
432 for (int32 x=left;x<right;x+=ordered_matrix_size) {
433 int32 r =min_c(x+ordered_matrix_size,right)((x+ordered_matrix_size)>(right)?(right):(x+ordered_matrix_size
))
;
434 int32 b = min_c(y+ordered_matrix_size,bottom)((y+ordered_matrix_size)>(bottom)?(bottom):(y+ordered_matrix_size
))
;
435 uint32 *s_delta_bits;
436
437 int32 number_of_pixels = 0;
438 for (int32 dy=y;dy<b;dy++) {
439 s_delta_bits = source_bits + dy*source_bpr + x;
440 for (int32 dx=x;dx<r;dx++) {
441 if (selection->ContainsPoint(dx,dy)) {
442 color.word = *s_delta_bits;
443 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
444 int threshold = luminance * normalizer;
445 *s_delta_bits = (ordered_matrix[dy-y][dx-x]>threshold?c1.word:c2.word);
446 }
447 s_delta_bits++;
448 }
449 }
450 }
451 }
452 }
453
454 return original;
455}
456
457
458BBitmap* Halftone::fs_dither_halftone(BBitmap *original,Selection *selection, BStatusBar *status_bar)
459{
460 if (original == NULL__null)
461 return NULL__null;
462
463 uint32 *source_bits = (uint32*)original->Bits();
464 uint32 *target_bits = (uint32*)original->Bits();
465 int32 source_bpr = original->BytesPerRow()/4;
466 int32 target_bpr = original->BytesPerRow()/4;
467 int32 top,bottom,left,right;
468
469 left = original->Bounds().left;
470 right = original->Bounds().right + 1;
471 top = original->Bounds().top;
472 bottom = original->Bounds().bottom + 1;
473
474 float *errors = new float[right-left+3];
475 for (int32 i=0;i<right-left+3;i++)
476 errors[i] = 0;
477
478 float right_error = 0;
479
480 union {
481 uint8 bytes[4];
482 uint32 word;
483 } color,c1,c2;
484 rgb_color c = informer->GetForegroundColor();
485 c1.bytes[0] = c.blue;
486 c1.bytes[1] = c.green;
487 c1.bytes[2] = c.red;
488 c1.bytes[3] = c.alpha;
489
490 c = informer->GetBackgroundColor();
491 c2.bytes[0] = c.blue;
492 c2.bytes[1] = c.green;
493 c2.bytes[2] = c.red;
494 c2.bytes[3] = c.alpha;
495
496 if (selection->IsEmpty()) {
497 // Here handle the whole image.
498 for (int32 y=top;y<bottom;y++) {
499 for (int32 x=left;x<right;x++) {
500 color.word = *source_bits;
501 float threshold = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
502 float value = min_c(255,max_c(threshold+right_error+errors[x+1],0))((255)>(((threshold+right_error+errors[x+1])>(0)?(threshold
+right_error+errors[x+1]):(0)))?(((threshold+right_error+errors
[x+1])>(0)?(threshold+right_error+errors[x+1]):(0))):(255)
)
;
503 errors[x+1] = 0;
504 right_error = 0;
505 float error;
506 if (value > 127) {
507 error = -(255 - value);
508 *source_bits++ = c2.word;
509 }
510 else {
511 error = -(0 - value);
512 *source_bits++ = c1.word;
513 }
514 right_error = .4375 * error;
515 errors[x] += .1875 * error;
516 errors[x+1] += .3125 * error;
517 errors[x+2] += .0625 * error;
518 }
519 }
520 }
521 else {
522 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
523 float normalizer = 1.0/255.0*ordered_matrix_size*ordered_matrix_size;
524 for (int32 y=top;y<bottom;y+=ordered_matrix_size) {
525 for (int32 x=left;x<right;x+=ordered_matrix_size) {
526 int32 r =min_c(x+ordered_matrix_size,right)((x+ordered_matrix_size)>(right)?(right):(x+ordered_matrix_size
))
;
527 int32 b = min_c(y+ordered_matrix_size,bottom)((y+ordered_matrix_size)>(bottom)?(bottom):(y+ordered_matrix_size
))
;
528 uint32 *s_delta_bits;
529
530 int32 number_of_pixels = 0;
531 for (int32 dy=y;dy<b;dy++) {
532 s_delta_bits = source_bits + dy*source_bpr + x;
533 for (int32 dx=x;dx<r;dx++) {
534 if (selection->ContainsPoint(dx,dy)) {
535 color.word = *s_delta_bits;
536 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
537 int threshold = luminance * normalizer;
538 *s_delta_bits = (ordered_matrix[dy-y][dx-x]>threshold?c1.word:c2.word);
539 }
540 s_delta_bits++;
541 }
542 }
543 }
544 }
545 }
546
547 return original;
548}
549
550
551BBitmap* Halftone::ncandidate_dither_halftone(BBitmap *original,Selection *selection, BStatusBar *status_bar)
552{
553 if (original == NULL__null)
554 return NULL__null;
555
556 uint32 *source_bits = (uint32*)original->Bits();
557 uint32 *target_bits = (uint32*)original->Bits();
558 int32 source_bpr = original->BytesPerRow()/4;
559 int32 target_bpr = original->BytesPerRow()/4;
560 int32 top,bottom,left,right;
561
562 left = original->Bounds().left;
563 right = original->Bounds().right + 1;
564 top = original->Bounds().top;
565 bottom = original->Bounds().bottom + 1;
566
567 float *errors = new float[right-left+3];
568 for (int32 i=0;i<right-left+3;i++)
569 errors[i] = 0;
570
571 float right_error = 0;
572
573 union {
574 uint8 bytes[4];
575 uint32 word;
576 } color,c1,c2;
577 rgb_color c = informer->GetForegroundColor();
578 c1.bytes[0] = c.blue;
579 c1.bytes[1] = c.green;
580 c1.bytes[2] = c.red;
581 c1.bytes[3] = c.alpha;
582
583 c = informer->GetBackgroundColor();
584 c2.bytes[0] = c.blue;
585 c2.bytes[1] = c.green;
586 c2.bytes[2] = c.red;
587 c2.bytes[3] = c.alpha;
588
589 float probs[256];
590 for (int32 i=0;i<256;i++) {
591 probs[i] = (float)i/256.0; // probability to get white
592 }
593
594 RandomNumberGenerator *generator = new RandomNumberGenerator(1027,1000000);
595 if (selection->IsEmpty()) {
596 // Here handle the whole image.
597 for (int32 y=top;y<bottom;y++) {
598 for (int32 x=left;x<right;x++) {
599 color.word = *source_bits;
600 int32 threshold = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
601 float r = generator->UniformDistribution(0.0,1.0);
602 if (probs[threshold] >= r)
603 *source_bits++ = c2.word;
604 else
605 *source_bits++ = c1.word;
606 }
607 }
608 }
609 else {
610 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
611 float normalizer = 1.0/255.0*ordered_matrix_size*ordered_matrix_size;
612 for (int32 y=top;y<bottom;y+=ordered_matrix_size) {
613 for (int32 x=left;x<right;x+=ordered_matrix_size) {
614 int32 r =min_c(x+ordered_matrix_size,right)((x+ordered_matrix_size)>(right)?(right):(x+ordered_matrix_size
))
;
615 int32 b = min_c(y+ordered_matrix_size,bottom)((y+ordered_matrix_size)>(bottom)?(bottom):(y+ordered_matrix_size
))
;
616 uint32 *s_delta_bits;
617
618 int32 number_of_pixels = 0;
619 for (int32 dy=y;dy<b;dy++) {
620 s_delta_bits = source_bits + dy*source_bpr + x;
621 for (int32 dx=x;dx<r;dx++) {
622 if (selection->ContainsPoint(dx,dy)) {
623 color.word = *s_delta_bits;
624 float luminance = color.bytes[0] * .114 + color.bytes[1]*.587 + color.bytes[2]*.299;
625 int threshold = luminance * normalizer;
626 *s_delta_bits = (ordered_matrix[dy-y][dx-x]>threshold?c1.word:c2.word);
627 }
628 s_delta_bits++;
629 }
630 }
631 }
632 }
633 }
634 delete generator;
635 return original;
636}
637