Bug Summary

File:home/HaikuArchives/ArtPaint/addons/AddOns/Threshold/Threshold.cpp
Warning:line 295, column 56
The left operand of '<' is a garbage value

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 Threshold.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/Threshold -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++ Threshold.cpp

Threshold.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
10
11/*
12 This file shows how to create an add-on that creates a GUI.
13 This also shows how the ManipulatorInformer-class is used.
14*/
15
16#include <Bitmap.h>
17#include <Catalog.h>
18#include <LayoutBuilder.h>
19#include <Node.h>
20#include <StatusBar.h>
21#include <stdio.h>
22#include <Window.h>
23
24#include "AddOns.h"
25#include "ManipulatorInformer.h"
26#include "Selection.h"
27#include "Threshold.h"
28#include "ThresholdView.h"
29
30#undef B_TRANSLATION_CONTEXT"AddOns_Threshold"
31#define B_TRANSLATION_CONTEXT"AddOns_Threshold" "AddOns_Threshold"
32
33
34#ifdef __cplusplus201402L
35extern "C" {
36#endif
37 char name[255] = B_TRANSLATE_MARK("Threshold" B_UTF8_ELLIPSIS)("Threshold" "\xE2\x80\xA6");
38 char menu_help_string[255] = B_TRANSLATE_MARK("Shows only pixels of a specified threshold.")("Shows only pixels of a specified threshold.");
39 int32 add_on_api_version = ADD_ON_API_VERSION;
40 add_on_types add_on_type = COLOR_ADD_ON;
41#ifdef __cplusplus201402L
42}
43#endif
44
45
46Manipulator* instantiate_add_on(BBitmap *bm,ManipulatorInformer *i)
47{
48 return new ThresholdManipulator(bm,i);
49}
50
51
52
53ThresholdManipulator::ThresholdManipulator(BBitmap *bm,ManipulatorInformer *i)
54 : WindowGUIManipulator()
55{
56 preview_bitmap = NULL__null;
57 config_view = NULL__null;
58 copy_of_the_preview_bitmap = NULL__null;
59
60 previous_settings.threshold = settings.threshold + 1;
61 settings.mode = HISTOGRAM_MODE_INTENSITY;
62
63 SetPreviewBitmap(bm);
64
65 light_color = i->GetForegroundColor();
66 dark_color = i->GetBackgroundColor();
67
68 delete i; // This is not needed anymore
69}
70
71
72ThresholdManipulator::~ThresholdManipulator()
73{
74 delete copy_of_the_preview_bitmap;
75 delete config_view;
76}
77
78
79BBitmap* ThresholdManipulator::ManipulateBitmap(ManipulatorSettings *set,BBitmap *original,Selection *selection,BStatusBar *status_bar)
80{
81 ThresholdManipulatorSettings *new_settings = dynamic_cast<ThresholdManipulatorSettings*>(set);
82
83 if (new_settings == NULL__null)
84 return NULL__null;
85
86 if (original == NULL__null)
87 return NULL__null;
88
89 if (original == preview_bitmap) {
90 if ((*new_settings == previous_settings) && (last_calculated_resolution <= 1))
91 return original;
92
93 source_bitmap = copy_of_the_preview_bitmap;
94 target_bitmap = original;
95 }
96 else {
97 source_bitmap = original;
98 target_bitmap = new BBitmap(original->Bounds(),B_RGB32,FALSE0);
99 }
100
101
102 current_resolution = 1;
103 current_selection = selection;
104 current_settings = *new_settings;
105 progress_bar = status_bar;
106
107 start_threads();
108
109 return target_bitmap;
110}
111
112int32 ThresholdManipulator::PreviewBitmap(Selection *selection,bool full_quality,BRegion *updated_region)
113{
114 progress_bar = NULL__null;
115 current_selection = selection;
116 if (settings == previous_settings ) {
117 if ((last_calculated_resolution != highest_available_quality) && (last_calculated_resolution > 0))
118 last_calculated_resolution = max_c(highest_available_quality,floor(last_calculated_resolution/2.0))((highest_available_quality)>(floor(last_calculated_resolution
/2.0))?(highest_available_quality):(floor(last_calculated_resolution
/2.0)))
;
119 else
120 last_calculated_resolution = 0;
121 }
122 else
123 last_calculated_resolution = lowest_available_quality;
124
125 if (full_quality) {
126 last_calculated_resolution = min_c(1,last_calculated_resolution)((1)>(last_calculated_resolution)?(last_calculated_resolution
):(1))
;
127 }
128 previous_settings = settings;
129
130 if (last_calculated_resolution > 0) {
131 current_resolution = last_calculated_resolution;
132 updated_region->Set(preview_bitmap->Bounds());
133
134 target_bitmap = preview_bitmap;
135 source_bitmap = copy_of_the_preview_bitmap;
136 current_settings = settings;
137
138 start_threads();
139 }
140
141 return last_calculated_resolution;
142}
143
144
145void ThresholdManipulator::start_threads()
146{
147 number_of_threads = GetSystemCpuCount();
148
149 thread_id *threads = new thread_id[number_of_threads];
150
151 for (int32 i=0;i<number_of_threads;i++) {
152 threads[i] = spawn_thread(thread_entrythread_func,"threshold_thread",B_NORMAL_PRIORITY10,this);
153 resume_thread(threads[i]);
154 send_data(threads[i],i,NULL__null,0);
155 }
156
157 for (int32 i=0;i<number_of_threads;i++) {
158 int32 return_value;
159 wait_for_thread(threads[i],&return_value);
160 }
161
162 delete[] threads;
163}
164
165int32 ThresholdManipulator::thread_entrythread_func(void *data)
166{
167 int32 thread_number;
168 thread_number = receive_data(NULL__null,NULL__null,0);
169
170 ThresholdManipulator *this_pointer = (ThresholdManipulator*)data;
171
172 return this_pointer->thread_function(thread_number);
1
Calling 'ThresholdManipulator::thread_function'
173}
174
175
176int32 ThresholdManipulator::thread_function(int32 thread_number)
177{
178 int32 step = current_resolution;
179 uint32 threshold = settings.threshold;
180 int32 mode = settings.mode;
181
182 BWindow *progress_bar_window = NULL__null;
183 if (progress_bar != NULL__null)
2
Assuming field 'progress_bar' is equal to NULL
3
Taking false branch
184 progress_bar_window = progress_bar->Window();
185
186
187 uint32 *source_bits = (uint32*)source_bitmap->Bits();
188 uint32 *target_bits = (uint32*)target_bitmap->Bits();
189 int32 source_bpr = source_bitmap->BytesPerRow()/4;
190 int32 target_bpr = target_bitmap->BytesPerRow()/4;
191
192 // This union must be used to guarantee endianness compatibility.
193 union {
194 uint8 bytes[4];
195 uint32 word;
196 } color,dark,light;
197
198 dark.bytes[0] = dark_color.blue;
199 dark.bytes[1] = dark_color.green;
200 dark.bytes[2] = dark_color.red;
201 dark.bytes[3] = dark_color.alpha;
202
203 light.bytes[0] = light_color.blue;
204 light.bytes[1] = light_color.green;
205 light.bytes[2] = light_color.red;
206 light.bytes[3] = light_color.alpha;
207
208 if (current_selection->IsEmpty()) {
4
Assuming the condition is false
5
Taking false branch
209 // Here handle the whole image.
210 int32 left = target_bitmap->Bounds().left;
211 int32 right = target_bitmap->Bounds().right;
212 int32 top = target_bitmap->Bounds().top;
213 int32 bottom = target_bitmap->Bounds().bottom;
214
215 float height = bottom - top;
216 top = height/number_of_threads*thread_number;
217 top = ceil(top/(float)step);
218 top *= step;
219 bottom = min_c(bottom,top + (height+1)/number_of_threads)((bottom)>(top + (height+1)/number_of_threads)?(top + (height
+1)/number_of_threads):(bottom))
;
220 int32 update_interval = 10;
221 float update_amount = 100.0/(bottom-top)*update_interval/(float)number_of_threads;
222 float missed_update = 0;
223
224 // Loop through all pixels in original.
225 uint32 value;
226
227 for (int32 y=top;y<=bottom;y+=step) {
228 int32 y_times_source_bpr = y*source_bpr;
229 int32 y_times_target_bpr = y*target_bpr;
230 for (int32 x=left;x<=right;x+=step) {
231 color.word = *(source_bits + x + y_times_source_bpr);
232
233 if (mode == HISTOGRAM_MODE_INTENSITY)
234 value = (0.114*color.bytes[0] + 0.587*color.bytes[1] + 0.299*color.bytes[2]);
235 else if (mode == HISTOGRAM_MODE_RED)
236 value = color.bytes[2];
237 else if (mode == HISTOGRAM_MODE_GREEN)
238 value = color.bytes[1];
239 else if (mode == HISTOGRAM_MODE_BLUE)
240 value = color.bytes[0];
241
242 *(target_bits + x + y_times_target_bpr) = ((value < threshold) ? dark.word : light.word);
243 }
244
245
246 // Update the status-bar
247 if ( ((y % update_interval) == 0) && (progress_bar_window != NULL__null) && (progress_bar_window->LockWithTimeout(0) == B_OK((int)0)) ) {
248 progress_bar->Update(update_amount+missed_update);
249 progress_bar_window->Unlock();
250 missed_update = 0;
251 }
252 else if ((y % update_interval) == 0) {
253 missed_update += update_amount;
254 }
255 }
256 }
257 else {
258 // Here handle only those pixels for which selection->ContainsPoint(x,y) is true.
259 BRect rect = current_selection->GetBoundingRect();
260
261 int32 left = rect.left;
262 int32 right = rect.right;
263 int32 top = rect.top;
264 int32 bottom = rect.bottom;
265
266 float height = bottom - top;
267 top += height/number_of_threads*thread_number;
268 top *= step;
269 top /= step;
270
271 bottom = min_c(bottom,top + (height+1)/number_of_threads)((bottom)>(top + (height+1)/number_of_threads)?(top + (height
+1)/number_of_threads):(bottom))
;
6
Assuming the condition is false
7
'?' condition is false
272
273 int32 update_interval = 10;
274 float update_amount = 100.0/(bottom-top)*update_interval/(float)number_of_threads;
275
276 // Loop through all pixels in original.
277 uint32 value;
8
'value' declared without an initial value
278
279 for (int32 y=top;y<=bottom;y+=step) {
9
Assuming 'y' is <= 'bottom'
10
Loop condition is true. Entering loop body
280 int32 y_times_source_bpr = y*source_bpr;
281 int32 y_times_target_bpr = y*target_bpr;
282 for (int32 x=left;x<=right;x+=step) {
11
Assuming 'x' is <= 'right'
12
Loop condition is true. Entering loop body
283 if (current_selection->ContainsPoint(x,y)) { // Adjust only the pixels inside the selection.
13
Calling 'Selection::ContainsPoint'
16
Returning from 'Selection::ContainsPoint'
17
Taking true branch
284 color.word = *(source_bits + x + y_times_source_bpr);
285
286 if (mode == HISTOGRAM_MODE_INTENSITY)
18
Assuming 'mode' is not equal to HISTOGRAM_MODE_INTENSITY
19
Taking false branch
287 value = (0.114*color.bytes[0] + 0.587*color.bytes[1] + 0.299*color.bytes[2]);
288 else if (mode == HISTOGRAM_MODE_RED)
20
Assuming 'mode' is not equal to HISTOGRAM_MODE_RED
21
Taking false branch
289 value = color.bytes[2];
290 else if (mode == HISTOGRAM_MODE_GREEN)
22
Assuming 'mode' is not equal to HISTOGRAM_MODE_GREEN
23
Taking false branch
291 value = color.bytes[1];
292 else if (mode == HISTOGRAM_MODE_BLUE)
24
Assuming 'mode' is not equal to HISTOGRAM_MODE_BLUE
25
Taking false branch
293 value = color.bytes[0];
294
295 *(target_bits + x + y_times_target_bpr) = ((value < threshold) ? dark.word : light.word);
26
The left operand of '<' is a garbage value
296 }
297 }
298
299 // Update the status-bar
300 if ( ((y % update_interval) == 0) && (progress_bar_window != NULL__null) && (progress_bar_window->LockWithTimeout(0) == B_OK((int)0)) ) {
301 progress_bar->Update(update_amount);
302 progress_bar_window->Unlock();
303 }
304 }
305 }
306
307 return B_OK((int)0);
308}
309
310
311void ThresholdManipulator::MouseDown(BPoint point,uint32,BView*,bool first_click)
312{
313 // This function does nothing in ThresholdManipulator.
314}
315
316
317void ThresholdManipulator::SetPreviewBitmap(BBitmap *bm)
318{
319 if (preview_bitmap != bm) {
320 delete copy_of_the_preview_bitmap;
321 if (bm != NULL__null) {
322 preview_bitmap = bm;
323 copy_of_the_preview_bitmap = DuplicateBitmap(bm,0);
324 }
325 else {
326 preview_bitmap = NULL__null;
327 copy_of_the_preview_bitmap = NULL__null;
328 }
329 }
330
331 if (preview_bitmap != NULL__null) {
332 // Let's select a resolution that can handle all the pixels at least
333 // 10 times in a second while assuming that one pixel calculation takes
334 // about 50 CPU cycles.
335 double speed = GetSystemClockSpeed() / (10*50);
336 BRect bounds = preview_bitmap->Bounds();
337 float num_pixels = (bounds.Width()+1) * (bounds.Height() + 1);
338 lowest_available_quality = 1;
339 while ((num_pixels/lowest_available_quality/lowest_available_quality) > speed)
340 lowest_available_quality *= 2;
341
342 lowest_available_quality = min_c(lowest_available_quality,16)((lowest_available_quality)>(16)?(16):(lowest_available_quality
))
;
343 highest_available_quality = max_c(lowest_available_quality/2,1)((lowest_available_quality/2)>(1)?(lowest_available_quality
/2):(1))
;
344 }
345 else {
346 lowest_available_quality = 1;
347 highest_available_quality = 1;
348 }
349 last_calculated_resolution = lowest_available_quality;
350
351 if (config_view != NULL__null)
352 config_view->SetBitmap(copy_of_the_preview_bitmap);
353}
354
355
356void ThresholdManipulator::Reset(Selection*)
357{
358 if (copy_of_the_preview_bitmap != NULL__null) {
359 // memcpy seems to be about 10-15% faster that copying with a loop.
360 uint32 *source = (uint32*)copy_of_the_preview_bitmap->Bits();
361 uint32 *target = (uint32*)preview_bitmap->Bits();
362 uint32 bits_length = preview_bitmap->BitsLength();
363
364 memcpy(target,source,bits_length);
365 }
366}
367
368BView* ThresholdManipulator::MakeConfigurationView(const BMessenger& target)
369{
370 if (config_view == NULL__null) {
371 config_view = new ThresholdManipulatorView(this,target);
372 config_view->ChangeSettings(&settings);
373 config_view->SetBitmap(copy_of_the_preview_bitmap);
374 }
375
376 return config_view;
377}
378
379
380ManipulatorSettings* ThresholdManipulator::ReturnSettings()
381{
382 return new ThresholdManipulatorSettings(settings);
383}
384
385void ThresholdManipulator::ChangeSettings(ManipulatorSettings *s)
386{
387 ThresholdManipulatorSettings *new_settings;
388 new_settings = dynamic_cast<ThresholdManipulatorSettings*>(s);
389 if (new_settings != NULL__null) {
390 settings = *new_settings;
391 }
392}
393
394const char* ThresholdManipulator::ReturnName()
395{
396 return B_TRANSLATE("Threshold")BLocaleRoster::Default()->GetCatalog()->GetString(("Threshold"
), "AddOns_Threshold")
;
397}
398
399const char* ThresholdManipulator::ReturnHelpString()
400{
401 return B_TRANSLATE("Shows only pixels of a specified threshold.")BLocaleRoster::Default()->GetCatalog()->GetString(("Shows only pixels of a specified threshold."
), "AddOns_Threshold")
;
402}
403
404
405status_t ThresholdManipulator::WriteSettings(BNode *node)
406{
407 ssize_t written = node->WriteAttr("threshold", B_INT32_TYPE, 0,
408 &(settings.threshold), sizeof(int32));
409
410 if (written == ssize_t(sizeof(int32)))
411 return B_OK((int)0);
412 return B_ERROR(-1);
413}
414
415status_t ThresholdManipulator::ReadSettings(BNode *node)
416{
417 ssize_t read = node->ReadAttr("threshold", B_INT32_TYPE, 0,
418 &(settings.threshold), sizeof(int32));
419
420 if (read == ssize_t(sizeof(int32)))
421 return B_OK((int)0);
422 return B_ERROR(-1);
423}
424
425
426// -------------------------------------
427ThresholdManipulatorView::ThresholdManipulatorView(ThresholdManipulator *manip,
428 const BMessenger& t)
429 : WindowGUIManipulatorView()
430{
431 target = t;
432 manipulator = manip;
433 started_adjusting = FALSE0;
434
435 threshold_control = new ThresholdView(new BMessage(THRESHOLD_ADJUSTING_FINISHED'Thaf'));
436
437 BLayoutBuilder::Group<>(this, B_VERTICAL)
438 .Add(threshold_control)
439 .SetInsets(B_USE_SMALL_INSETS)
440 .End();
441}
442
443
444ThresholdManipulatorView::~ThresholdManipulatorView()
445{
446}
447
448
449void ThresholdManipulatorView::AttachedToWindow()
450{
451 WindowGUIManipulatorView::AttachedToWindow();
452 threshold_control->SetTarget(BMessenger(this));
453}
454
455
456void ThresholdManipulatorView::MessageReceived(BMessage *message)
457{
458 switch (message->what) {
459 case THRESHOLD_ADJUSTED'Thad':
460 settings.threshold = threshold_control->Value();
461 manipulator->ChangeSettings(&settings);
462 if (!started_adjusting) {
463 target.SendMessage(HS_MANIPULATOR_ADJUSTING_STARTED'Mast');
464 started_adjusting = TRUE1;
465 }
466 break;
467
468 case THRESHOLD_ADJUSTING_FINISHED'Thaf': {
469 started_adjusting = false;
470 int32 threshold = 0;
471 int32 mode = 0;
472 message->FindInt32("threshold",&threshold);
473 message->FindInt32("mode",&mode);
474
475 settings.threshold = threshold;
476 settings.mode = mode;
477 manipulator->ChangeSettings(&settings);
478 target.SendMessage(HS_MANIPULATOR_ADJUSTING_FINISHED'Mafi');
479 }
480 break;
481
482 default:
483 WindowGUIManipulatorView::MessageReceived(message);
484 break;
485 }
486}
487
488
489void ThresholdManipulatorView::ChangeSettings(ManipulatorSettings *newSettings)
490{
491 ThresholdManipulatorSettings *s = dynamic_cast<ThresholdManipulatorSettings*>(newSettings);
492
493 if (s != NULL__null) {
494 settings.threshold = s->threshold;
495 if (threshold_control != NULL__null) {
496 if (threshold_control->LockLooper()) {
497 threshold_control->SetValue(settings.threshold);
498 threshold_control->UnlockLooper();
499 }
500 else {
501 threshold_control->SetValue(settings.threshold);
502 }
503 }
504 }
505}
506
507void ThresholdManipulatorView::SetBitmap(BBitmap *bitmap)
508{
509 threshold_control->SetBitmap(bitmap);
510}

../../../artpaint/application/Selection.h

1/*
2 * Copyright 2003, Heikki Suhonen
3 * Copyright 2009, Karsten Heimrich
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 * Heikki Suhonen <heikki.suhonen@gmail.com>
8 * Karsten Heimrich <host.haiku@gmx.de>
9 *
10 */
11#ifndef SELECTION_H
12#define SELECTION_H
13
14#include <Bitmap.h>
15#include <View.h>
16
17/*
18 Selection-class offers a mechanism for specifying an arbitrarily-shaped,
19 possibly disjoint, area from an image. In constructor it gets the size of
20 the image. After constructing selections can be added to it or removed
21 from it. It can return the selection's pixels sequentially as BPoint's or
22 coordinate pairs. It also calculates and returns the bounding rectangle of the
23 selected area. It can also return whether a given point belongs to the
24 selection or not.
25
26 Other major function of selection is drawing the selection to the view.
27 The drawing is done with the Draw-function that gets magnifying-scale
28 and bounding rectangle as a parameter. If everything is selected, the drawing
29 function should do nothing.
30
31 The selection works in reverse. It records what is NOT selected. If everything
32 is selected, like is the normal case, this will not store any information about
33 selection.
34
35 If selection is empty when adding the first selection, we make the selection
36 first full.
37
38*/
39
40class HSPolygon;
41class SelectionIterator;
42class SelectionData;
43
44
45class Selection {
46 // This list holds pointers to HSPolygons. The polygons make up the selections.
47// BList *selections;
48 SelectionData *selection_data;
49
50 // This is used when rotating the selections to store the original polygons.
51 HSPolygon **original_selections;
52
53
54 // This is a binary-bitmap that has one bit for each pixel in the image.
55 // If a bit is 1 then the corresponding pixel belongs to the selection.
56 // Otherwise it doesn't belong to the selection.
57 BBitmap *selection_map;
58 BView *selection_view;
59
60 uint8 *selection_bits;
61 uint32 selection_bpr;
62
63 // This attribute keeps track of the selection's bounds. If it is
64 // not valid it should be calculated again with the calculateBoundingRect
65 // function.
66 BRect selection_bounds;
67
68 // This attribute records the image's bounding rectangle.
69 BRect image_bounds;
70
71 // This points to the view that we want to draw to.
72 BView *image_view;
73
74// // If this is true, the selection is inverted.
75// bool inverted;
76
77 bool needs_recalculating;
78
79 float view_magnifying_scale;
80
81 // This is used to animate the lines that bound the selected area.
82 int32 animation_offset;
83
84 thread_id drawer_thread;
85 bool continue_drawing;
86 sem_id selection_mutex;
87
88// This function calculates the smallest rectangle that contains all the points
89// that are selected. It records this fact in the bounding_rect attribute.
90// Bounding rectangle is calcultated when it is needed the first time.
91void calculateBoundingRect();
92
93// This function deselects everything.
94void deSelect();
95
96static int32 thread_entry_func(void*);
97 int32 thread_func();
98
99 void SimplifySelection();
100
101public:
102 Selection(BRect);
103 ~Selection();
104
105
106void SetSelectionData(const SelectionData*);
107
108
109void StartDrawing(BView*,float);
110// This function adds a polygon to the selection. The point list describes polygons vertices.
111// The polygon is stored as a point list instead of BPolygon so that we can translate and rotate it.
112// The parameter point-list is not copied and thus should not be deleted in the calling function.
113void AddSelection(HSPolygon*,bool add_to_selection=TRUE1);
114
115
116// This function adds a binary bitmap to the selection.
117void AddSelection(BBitmap*,bool add_to_selection);
118
119// This function clears the selection.
120void Clear();
121
122// This dilates the selection map so that the size of the selection will increase
123void Dilatate();
124
125// This erodes the selection so that the size of the selection will decrease
126void Erode();
127
128// This will draw the selection. This function does not care about clipping region.
129void Draw();
130
131
132// This function returns the bounding rectangle of the selection.
133BRect GetBoundingRect();
134
135
136// This function inverts the whole selection. If everything is selected, invert does
137// nothing.
138void Invert();
139
140
141// This function returns true, if the selection is empty (i.e. everything is
142// selected).
143bool IsEmpty();
144
145// This function rotates the selection. The parameter is in degrees with positive degrees
146// clockwise. This only rotates the selection, not the actual image.
147void RotateTo(BPoint,float);
148
149// This function translates the selection by the amount given in the parameters.
150void Translate(int32,int32);
151
152
153// This recalculates the actual contents of the selection. It can be used for example after
154// rotation or translation.
155void Recalculate();
156
157
158void ChangeMagnifyingScale(float);
159
160void ImageSizeChanged(BRect);
161
162
163const SelectionData* ReturnSelectionData() { return selection_data; }
164
165// These functions return true if the point in parameter belongs to the selection (i.e.
166// is not DEselected). The BPoint version will also check the bounds rectangle while the
167// int,int version will not check bounds. The latter function can be used in combination
168// with the GetBoundingRect-function.
169inline bool ContainsPoint(BPoint);
170inline bool ContainsPoint(int32,int32);
171};
172
173
174bool Selection::ContainsPoint(BPoint p)
175{
176 int32 y = (int32)p.y;
177 int32 x = (int32)p.x;
178
179 return ((selection_bits == NULL__null) || (image_bounds.Contains(p) &&
180 ((*(selection_bits + y * selection_bpr + x)) & 0x01)));
181}
182
183
184bool Selection::ContainsPoint(int32 x, int32 y)
185{
186 return ((selection_bits == NULL__null)
14
Assuming field 'selection_bits' is equal to NULL
15
Returning the value 1, which participates in a condition later
187 || ((*(selection_bits + y * selection_bpr + x)) & 0x01));
188}
189
190
191class PointContainer {
192 BPoint **hash_table;
193 int32 *list_length_table;
194
195 int32 hash_value(int32 x, int32 y);
196const int32 hash_table_size;
197public:
198 PointContainer();
199 ~PointContainer();
200
201void InsertPoint(int32 x, int32 y);
202bool HasPoint(int32 x, int32 y);
203};
204
205
206// This class contains the vital data that describe selection. A selection
207// can be archived with such data and selection can also be modified to represent
208// the same selection as the SelectionData represents.
209class SelectionData {
210HSPolygon **selections;
211int32 selections_array_size;
212int32 number_of_selections;
213public:
214 SelectionData();
215 SelectionData(const SelectionData*);
216 ~SelectionData();
217
218bool operator==(const SelectionData&);
219
220void AddSelection(HSPolygon*);
221void EmptySelectionData();
222int32 SelectionCount() { return number_of_selections; }
223HSPolygon* ReturnSelectionAt(int32 i) { return selections[i]; }
224};
225
226#endif