GCC Code Coverage Report


Directory: ./
File: lib/geogram/image/image.h
Date: 2026-09-07 02:37:58
Exec Total Coverage
Lines: 0 44 0.0%
Functions: 0 19 0.0%
Branches: 0 14 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #ifndef H_OGF_IMAGE_TYPES_IMAGE_H
41 #define H_OGF_IMAGE_TYPES_IMAGE_H
42
43 #include <geogram/basic/common.h>
44 #include <geogram/image/colormap.h>
45
46 /**
47 * \file geogram/image/image.h
48 * \details Types for images.
49 */
50
51 namespace GEO {
52
53 //_________________________________________________________
54
55
56 /**
57 * \brief An image.
58 */
59 class GEOGRAM_API Image : public Counted {
60 public:
61
62 /**
63 * \brief Indicates how colors are encoded
64 * within the image.
65 */
66 enum ColorEncoding {
67 GRAY, INDEXED, RGB, BGR, RGBA, YUV
68 };
69
70 /**
71 * \brief Indicates the datatype used to
72 * encode each component of the colors.
73 */
74 enum ComponentEncoding {
75 BYTE, INT16, INT32, FLOAT32, FLOAT64
76 };
77
78
79 /**
80 * \brief Image constructor.
81 * \details Constructs an uninitialized Image.
82 */
83 Image();
84
85 /**
86 * \brief Image constructor.
87 * \param[in] color_rep the ColorEncoding
88 * \param[in] component_rep the ComponentEncoding
89 * \param[in] width the width of the image
90 * \param[in] height the height of the image, or 1 for 1D images
91 * \param[in] depth the depth of the image for 3D images, or 1
92 * for 1D and 2D images
93 */
94 Image(
95 ColorEncoding color_rep, ComponentEncoding component_rep,
96 index_t width, index_t height=1, index_t depth=1
97 ) {
98 base_mem_ = nullptr;
99 initialize(color_rep, component_rep, width, height, depth);
100 }
101
102 /**
103 * \brief Image destructor.
104 */
105 ~Image() override;
106
107 /**
108 * \brief Some implementations get the image from some sources.
109 * Default implementation does nothing.
110 * \details There is a derived class to access the webcam for
111 * instance.
112 */
113 virtual void acquire();
114
115 /**
116 * \brief Gets the dimension of the image.
117 * \retval 1 for 1D images
118 * \retval 2 for 2D images
119 * \retval 3 for 3D images
120 */
121 index_t dimension() const {
122 return dimension_;
123 }
124
125 /**
126 * \brief Gets the size of the image along one of the axes.
127 * \param[in] axis the axis, one of (0,1,2)
128 * \return the number of pixels along axis
129 */
130 index_t size(index_t axis) const {
131 geo_assert(axis < 3);
132 return size_[axis];
133 }
134
135 /**
136 * \brief Gets the width of the image.
137 * \return the width of the image, in pixels
138 */
139 index_t width() const {
140 return size_[0];
141 }
142
143 /**
144 * \brief Gets the height of the image.
145 * \return the height of the image, in pixels, or 1
146 * for 1D images
147 */
148 index_t height() const {
149 return size_[1];
150 }
151
152 /**
153 * \brief Gets the depth of the image.
154 * \return for 3D images, the depth of the image in pixels,
155 * or 1 for 1D and 2D images.
156 */
157 index_t depth() const {
158 return size_[2];
159 }
160
161 /**
162 * \brief Gets the number of bytes per pixel.
163 * \return the number of bytes used to store the color of one pixel.
164 */
165 size_t bytes_per_pixel() const {
166 return bytes_per_pixel_;
167 }
168
169 /**
170 * \brief Gets the number of components per pixel.
171 * \return the number of color components in each pixel.
172 */
173 size_t components_per_pixel() const {
174 return nb_components(color_encoding());
175 }
176
177 /**
178 * \brief Gets the number of pixels.
179 * \return the total number of pixels in this image
180 */
181 size_t nb_pixels() const {
182 return size_t(size_[0]) * size_t(size_[1]) * size_t(size_[2]);
183 }
184
185 /**
186 * \brief Gets the number of bytes.
187 * \return the total number of bytes used to store the color
188 * data of this image
189 */
190 size_t bytes() const {
191 return nb_pixels() * bytes_per_pixel();
192 }
193
194 /**
195 * \brief Gets the ComponentEncoding.
196 * \return the ComponentEncoding
197 */
198 ComponentEncoding component_encoding() const {
199 return component_encoding_;
200 }
201
202 /**
203 * \brief Gets the ColorEncoding.
204 * \return the ColorEncoding
205 */
206 ColorEncoding color_encoding() const {
207 return color_encoding_;
208 }
209
210 /**
211 * \brief Gets the Colormap
212 * \return a const pointer to the Colormap.
213 */
214 const Colormap* colormap() const {
215 return colormap_;
216 }
217
218 /**
219 * \brief Gets the Colormap
220 * \return a pointer to the Colormap.
221 */
222 Colormap* colormap() {
223 return colormap_;
224 }
225
226 /**
227 * \brief Sets the Colormap
228 * \param[in] colormap a pointer to the Colormap,
229 * ownership is transfered to this Image
230 */
231 void set_colormap(Colormap* colormap) {
232 colormap_ = colormap;
233 }
234
235 /**
236 * \brief Gets the base memory.
237 * \return a pointer to the color data associated
238 * with this image.
239 */
240 Memory::pointer base_mem() const {
241 return base_mem_;
242 }
243
244 /**
245 * \brief Gets the base memory as a byte pointer.
246 * \return a byte pointer to the color data associated
247 * with this image.
248 * \pre ComponentEncoding == BYTE
249 */
250 Memory::byte* base_mem_byte_ptr() const {
251 return byte_ptr(base_mem_);
252 }
253
254 /**
255 * \brief Gets the base memory as a 16 bits integer pointer.
256 * \return a 16 bits integer pointer to the color data associated
257 * with this image.
258 * \pre ComponentEncoding == INT16
259 */
260 Numeric::int16* base_mem_int16_ptr() const {
261 return int16_ptr(base_mem_);
262 }
263
264 /**
265 * \brief Gets the base memory as a 32 bits integer pointer.
266 * \return a 32 bits integer pointer to the color data associated
267 * with this image.
268 * \pre ComponentEncoding == FLOAT32
269 */
270 Numeric::int32* base_mem_int32_ptr() const {
271 return int32_ptr(base_mem_);
272 }
273
274 /**
275 * \brief Gets the base memory as a 32 bits floating point pointer.
276 * \return a 32 bits floating point pointer to the color data associated
277 * with this image.
278 * \pre ComponentEncoding == FLOAT32
279 */
280 Numeric::float32* base_mem_float32_ptr() const {
281 return float32_ptr(base_mem_);
282 }
283
284 /**
285 * \brief Gets the base memory as a 64 bits floating point pointer.
286 * \return a 64 bits floating point pointer to the color data associated
287 * with this image.
288 * \pre ComponentEncoding == FLOAT64
289 */
290 Numeric::float64* base_mem_float64_ptr() const {
291 return float64_ptr(base_mem_);
292 }
293
294 /**
295 * \brief Gets the address of a pixel in a 1D image.
296 * \param[in] x the x coordinate of the pixel
297 * \return a pointer to the color data associated with the pixel
298 * \pre x < width()
299 */
300 Memory::pointer pixel_base(index_t x) {
301 return base_mem() + x * factor_[0];
302 }
303
304
305 /**
306 * \brief Gets the address of a pixel in a 1D image as a byte pointer.
307 * \param[in] x the x coordinate of the pixel
308 * \return a pointer to the color data associated with the pixel
309 * \pre x < width() && COMPONENT_ENCODING == BYTE
310 */
311 Memory::byte* pixel_base_byte_ptr(index_t x) {
312 return byte_ptr(base_mem() + x * factor_[0]);
313 }
314
315 /**
316 * \brief Gets the address of a pixel in a 1D image as a int16 pointer.
317 * \param[in] x the x coordinate of the pixel
318 * \return a pointer to the color data associated with the pixel
319 * \pre x < width() && COMPONENT_ENCODING == INT16
320 */
321 Numeric::int16* pixel_base_int16_ptr(index_t x) {
322 return int16_ptr(base_mem() + x * factor_[0]);
323 }
324
325 /**
326 * \brief Gets the address of a pixel in a 1D image as a int32 pointer.
327 * \param[in] x the x coordinate of the pixel
328 * \return a pointer to the color data associated with the pixel
329 * \pre x < width() && COMPONENT_ENCODING == INT32
330 */
331 Numeric::int32* pixel_base_int32_ptr(index_t x) {
332 return int32_ptr(base_mem() + x * factor_[0]);
333 }
334
335 /**
336 * \brief Gets the address of a pixel in a 1D image as a float32 pointer.
337 * \param[in] x the x coordinate of the pixel
338 * \return a pointer to the color data associated with the pixel
339 * \pre x < width() && COMPONENT_ENCODING == FLOAT32
340 */
341 Numeric::float32* pixel_base_float32_ptr(index_t x) {
342 return float32_ptr(base_mem() + x * factor_[0]);
343 }
344
345 /**
346 * \brief Gets the address of a pixel in a 1D image as a float64 pointer.
347 * \param[in] x the x coordinate of the pixel
348 * \return a pointer to the color data associated with the pixel
349 * \pre x < width() && COMPONENT_ENCODING == FLOAT64
350 */
351 Numeric::float64* pixel_base_float64_ptr(index_t x) {
352 return float64_ptr(base_mem() + x * factor_[0]);
353 }
354
355
356 /**
357 * \brief Gets the address of a pixel in a 2D image.
358 * \param[in] x , y the coordinates of the pixel
359 * \return a pointer to the color data associated with the pixel
360 * \pre x < width() && y < height()
361 */
362 Memory::pointer pixel_base(index_t x, index_t y) {
363 return base_mem() + x * factor_[0] + y * factor_[1];
364 }
365
366 /**
367 * \brief Gets the address of a pixel in a 2D image as a byte pointer.
368 * \param[in] x , y the coordinates of the pixel
369 * \return a pointer to the color data associated with the pixel
370 * \pre x < width() && y < height() && component_encoding() && BYTE
371 */
372 Memory::byte* pixel_base_byte_ptr(index_t x, index_t y) {
373 return byte_ptr(base_mem() + x * factor_[0] + y * factor_[1]);
374 }
375
376 /**
377 * \brief Gets the address of a pixel in a 2D image as an int16 pointer.
378 * \param[in] x , y the coordinates of the pixel
379 * \return a pointer to the color data associated with the pixel
380 * \pre x < width() && y < height() && component_encoding() && INT16
381 */
382 Numeric::int16* pixel_base_int16_ptr(index_t x, index_t y) {
383 return int16_ptr(base_mem() + x * factor_[0] + y * factor_[1]);
384 }
385
386 /**
387 * \brief Gets the address of a pixel in a 2D image as an int32 pointer.
388 * \param[in] x , y the coordinates of the pixel
389 * \return a pointer to the color data associated with the pixel
390 * \pre x < width() && y < height() && component_encoding() && INT32
391 */
392 Numeric::int32* pixel_base_int32_ptr(index_t x, index_t y) {
393 return int32_ptr(base_mem() + x * factor_[0] + y * factor_[1]);
394 }
395
396 /**
397 * \brief Gets the address of a pixel in a 2D image as a float32 pointer.
398 * \param[in] x , y the coordinates of the pixel
399 * \return a pointer to the color data associated with the pixel
400 * \pre x < width() && y < height() && component_encoding() && FLOAT32
401 */
402 Numeric::float32* pixel_base_float32_ptr(index_t x, index_t y) {
403 return float32_ptr(base_mem() + x * factor_[0] + y * factor_[1]);
404 }
405
406 /**
407 * \brief Gets the address of a pixel in a 2D image as a float64 pointer.
408 * \param[in] x , y the coordinates of the pixel
409 * \return a pointer to the color data associated with the pixel
410 * \pre x < width() && y < height() && component_encoding() && FLOAT64
411 */
412 Numeric::float64* pixel_base_float64_ptr(index_t x, index_t y) {
413 return float64_ptr(base_mem() + x * factor_[0] + y * factor_[1]);
414 }
415
416 /**
417 * \brief Gets the address of a pixel in a 3D image.
418 * \param[in] x , y , z the coordinates of the pixel
419 * \return a pointer to the color data associated with the pixel
420 * \pre x < width() && y < height() && z < depth()
421 */
422 Memory::pointer pixel_base(index_t x, index_t y, index_t z) {
423 return base_mem() +
424 x * factor_[0] + y * factor_[1] + z * factor_[2];
425 }
426
427 /**
428 * \brief Gets the address of a pixel in a 3D image as a byte pointer.
429 * \param[in] x , y , z the coordinates of the pixel
430 * \return a pointer to the color data associated with the pixel
431 * \pre x < width() && y < height() && z < depth() &&
432 * component_encoding() && BYTE
433 */
434 Memory::byte* pixel_base_byte_ptr(index_t x, index_t y, index_t z) {
435 return byte_ptr(base_mem() +
436 x * factor_[0] + y * factor_[1] + z * factor_[2]
437 );
438 }
439
440 /**
441 * \brief Gets the address of a pixel in a 3D image as an int16 pointer.
442 * \param[in] x , y , z the coordinates of the pixel
443 * \return a pointer to the color data associated with the pixel
444 * \pre x < width() && y < height() && z < depth() &&
445 * component_encoding() && INT16
446 */
447 Numeric::int16* pixel_base_int16_ptr(index_t x, index_t y, index_t z) {
448 return int16_ptr(base_mem() +
449 x * factor_[0] + y * factor_[1] + z * factor_[2]
450 );
451 }
452
453 /**
454 * \brief Gets the address of a pixel in a 3D image as an int32 pointer.
455 * \param[in] x , y , z the coordinates of the pixel
456 * \return a pointer to the color data associated with the pixel
457 * \pre x < width() && y < height() && z < depth() &&
458 * component_encoding() && INT32
459 */
460 Numeric::int32* pixel_base_int32_ptr(index_t x, index_t y, index_t z) {
461 return int32_ptr(base_mem() +
462 x * factor_[0] + y * factor_[1] + z * factor_[2]
463 );
464 }
465
466 /**
467 * \brief Gets the address of a pixel in a 3D image as a float32
468 * pointer.
469 * \param[in] x , y , z the coordinates of the pixel
470 * \return a pointer to the color data associated with the pixel
471 * \pre x < width() && y < height() && z < depth() &&
472 * component_encoding() && FLOAT32
473 */
474 Numeric::float32* pixel_base_float32_ptr(
475 index_t x, index_t y, index_t z
476 ) {
477 return float32_ptr(base_mem() +
478 x * factor_[0] + y * factor_[1] + z * factor_[2]
479 );
480 }
481
482 /**
483 * \brief Gets the address of a pixel in a 3D image as a float64
484 * pointer.
485 * \param[in] x , y , z the coordinates of the pixel
486 * \return a pointer to the color data associated with the pixel
487 * \pre x < width() && y < height() && z < depth() &&
488 * component_encoding() && FLOAT64
489 */
490 Numeric::float64* pixel_base_float64_ptr(
491 index_t x, index_t y, index_t z
492 ) {
493 return float64_ptr(base_mem() +
494 x * factor_[0] + y * factor_[1] + z * factor_[2]
495 );
496 }
497
498 /**
499 * \brief Gets the number of components associated with
500 * a ColorEncoding.
501 * \param[in] color_rep the ColorEncoding
502 * \return the number of components used by \p color_rep
503 */
504 static size_t nb_components(ColorEncoding color_rep);
505
506 /**
507 * \brief Gets the number of bytes used by a ComponentEncoding.
508 * \param[in] component_rep the ComponentEncoding
509 * \return the number of bytes used to represent a color component
510 * encoded with \p component_rep
511 */
512 static size_t bytes_per_component(ComponentEncoding component_rep);
513
514 /**
515 * \brief Converts an untyped pointer into a byte pointer.
516 * \param[in] ptr the pointer to be converted
517 * \return pointer \p ptr converted to a byte pointer
518 * \pre component_encoding_ == BYTE
519 * \note This function does nothing else than casting the pointer. In
520 * addition, in debug mode, it tests that the color encoding is the
521 * right one (and throws an assertion failure if it is not the case).
522 */
523 Memory::byte* byte_ptr(Memory::pointer ptr) const {
524 geo_debug_assert(component_encoding_ == BYTE);
525 return ptr;
526 }
527
528 /**
529 * \brief Converts an untyped pointer into a 16 bits integer pointer.
530 * \param[in] ptr the pointer to be converted
531 * \return pointer \p ptr converted to a 16 bits integer pointer
532 * \pre component_encoding_ == INT16
533 * \note This function does nothing else than casting the pointer. In
534 * addition, in debug mode, it tests that the color encoding is the
535 * right one (and throws an assertion failure if it is not the case).
536 */
537 Numeric::int16* int16_ptr(Memory::pointer ptr) const {
538 geo_debug_assert(component_encoding_ == INT16);
539 return (Numeric::int16*)(void*)(ptr);
540 }
541
542 /**
543 * \brief Converts an untyped pointer into a 32 bits integer pointer.
544 * \param[in] ptr the pointer to be converted
545 * \return pointer \p ptr converted to a 32 bits integer pointer
546 * \pre component_encoding_ == INT32
547 * \note This function does nothing else than casting the pointer. In
548 * addition, in debug mode, it tests that the color encoding is the
549 * right one (and throws an assertion failure if it is not the case).
550 */
551 Numeric::int32* int32_ptr(Memory::pointer ptr) const {
552 geo_debug_assert(
553 component_encoding_ == INT32 ||
554 (component_encoding_ == BYTE && bytes_per_pixel_ == 4)
555 );
556 return (Numeric::int32*)(void*)(ptr);
557 }
558
559 /**
560 * \brief Converts an untyped pointer into a 32 bits floating point
561 * pointer.
562 * \param[in] ptr the pointer to be converted
563 * \return pointer \p ptr converted to a 32 bits floating point pointer
564 * \pre component_encoding_ == FLOAT32
565 * \note This function does nothing else than casting the pointer. In
566 * addition, in debug mode, it tests that the color encoding is the
567 * right one (and throws an assertion failure if it is not the case).
568 */
569 Numeric::float32* float32_ptr(Memory::pointer ptr) const {
570 geo_debug_assert(component_encoding_ == FLOAT32);
571 return (Numeric::float32*)(void*)(ptr);
572 }
573
574 /**
575 * \brief Converts an untyped pointer into a 64 bits floating point
576 * pointer.
577 * \param[in] ptr the pointer to be converted
578 * \return pointer \p ptr converted to a 64 bits floating point pointer
579 * \pre component_encoding_ == FLOAT64
580 * \note This function does nothing else than casting the pointer. In
581 * addition, in debug mode, it tests that the color encoding is the
582 * right one (and throws an assertion failure if it is not the case).
583 */
584 Numeric::float64* float64_ptr(Memory::pointer ptr) const {
585 geo_debug_assert(component_encoding_ == FLOAT64);
586 return (Numeric::float64*)(void*)(ptr);
587 }
588
589 /**
590 * \brief Flips this image along the y axis.
591 */
592 void flip_vertically();
593
594 /**
595 * \brief Swaps two color components of this image.
596 * \param[in] channel1 , channel2 the two channels to
597 * be swapped
598 * \pre channel1 < nb_components(color_encoding()) &&
599 * channel2 < nb_components(color_encoding())
600 */
601 void swap_components(index_t channel1, index_t channel2);
602
603 /**
604 * \brief Creates storage for the specified encoding
605 * and image dimensions.
606 * \param[in] color_rep the ColorEncoding
607 * \param[in] component_rep the ComponentEncoding
608 * \param[in] size_x the image width
609 * \param[in] size_y the image height, or 1 for 1D images
610 * \param[in] size_z the image depth for 3D images, or 1 for 1D and
611 * 2D images
612 */
613 void initialize(
614 ColorEncoding color_rep, ComponentEncoding component_rep,
615 index_t size_x, index_t size_y=1, index_t size_z=1
616 );
617
618 protected:
619 ColorEncoding color_encoding_;
620 ComponentEncoding component_encoding_;
621 Colormap_var colormap_;
622 size_t factor_[3];
623 Memory::pointer base_mem_;
624 index_t dimension_;
625 index_t size_[3];
626 size_t bytes_per_pixel_;
627
628 private:
629 /**
630 * \brief Forbids copy-construction.
631 */
632 Image(const Image& rhs);
633
634 /**
635 * \brief Forbids assignment operator.
636 */
637 Image& operator=(const Image& rhs);
638 };
639
640 typedef SmartPointer<Image> Image_var;
641
642 //_________________________________________________________
643
644 }
645 #endif
646