2022-02-11 09:07:11 +11:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
* Copyright 2012 by Nicholas Bishop. All rights reserved. */
|
2012-02-22 23:57:31 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup bli
|
2013-09-12 03:02:50 +00:00
|
|
|
*/
|
|
|
|
|
2020-05-08 18:16:39 +02:00
|
|
|
#include "BLI_utildefines.h"
|
|
|
|
|
2020-03-02 15:04:53 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2013-07-22 23:20:48 +00:00
|
|
|
typedef unsigned int BLI_bitmap;
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2022-05-13 09:24:28 +10:00
|
|
|
/* WARNING: the bitmap does not keep track of its own size or check
|
2012-03-03 20:19:11 +00:00
|
|
|
* for out-of-bounds access */
|
2012-02-22 23:57:31 +00:00
|
|
|
|
|
|
|
/* internal use */
|
|
|
|
/* 2^5 = 32 (bits) */
|
2014-06-06 16:00:53 +10:00
|
|
|
#define _BITMAP_POWER 5
|
2012-02-22 23:57:31 +00:00
|
|
|
/* 0b11111 */
|
2014-06-06 16:00:53 +10:00
|
|
|
#define _BITMAP_MASK 31
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
2022-03-30 17:26:42 +11:00
|
|
|
* Number of blocks needed to hold '_num' bits.
|
2021-12-09 20:01:44 +11:00
|
|
|
*/
|
2022-07-15 10:21:27 +03:00
|
|
|
#define _BITMAP_NUM_BLOCKS(_num) (((_num) + _BITMAP_MASK) >> _BITMAP_POWER)
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
2022-03-30 17:26:42 +11:00
|
|
|
* Size (in bytes) used to hold '_num' bits.
|
2021-12-09 20:01:44 +11:00
|
|
|
*/
|
2022-03-30 17:26:42 +11:00
|
|
|
#define BLI_BITMAP_SIZE(_num) ((size_t)(_BITMAP_NUM_BLOCKS(_num)) * sizeof(BLI_bitmap))
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
2022-03-30 17:26:42 +11:00
|
|
|
* Allocate memory for a bitmap with '_num' bits; free with MEM_freeN().
|
2021-12-09 20:01:44 +11:00
|
|
|
*/
|
2022-03-30 17:26:42 +11:00
|
|
|
#define BLI_BITMAP_NEW(_num, _alloc_string) \
|
|
|
|
((BLI_bitmap *)MEM_callocN(BLI_BITMAP_SIZE(_num), _alloc_string))
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Allocate a bitmap on the stack.
|
|
|
|
*/
|
2022-03-30 17:26:42 +11:00
|
|
|
#define BLI_BITMAP_NEW_ALLOCA(_num) \
|
|
|
|
((BLI_bitmap *)memset(alloca(BLI_BITMAP_SIZE(_num)), 0, BLI_BITMAP_SIZE(_num)))
|
2014-06-05 13:55:50 +10:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Allocate using given MemArena.
|
|
|
|
*/
|
2022-03-30 17:26:42 +11:00
|
|
|
#define BLI_BITMAP_NEW_MEMARENA(_mem, _num) \
|
2014-11-25 21:09:13 +01:00
|
|
|
(CHECK_TYPE_INLINE(_mem, MemArena *), \
|
2022-03-30 17:26:42 +11:00
|
|
|
((BLI_bitmap *)BLI_memarena_calloc(_mem, BLI_BITMAP_SIZE(_num))))
|
2014-11-25 21:09:13 +01:00
|
|
|
|
2022-07-15 10:20:04 +03:00
|
|
|
/**
|
|
|
|
* Declares a bitmap as a variable.
|
|
|
|
*/
|
|
|
|
#define BLI_BITMAP_DECLARE(_name, _num) BLI_bitmap _name[_BITMAP_NUM_BLOCKS(_num)] = {}
|
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Get the value of a single bit at '_index'.
|
|
|
|
*/
|
2014-06-06 16:05:15 +10:00
|
|
|
#define BLI_BITMAP_TEST(_bitmap, _index) \
|
2015-01-14 05:10:18 +11:00
|
|
|
(CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
|
2014-06-06 16:00:53 +10:00
|
|
|
((_bitmap)[(_index) >> _BITMAP_POWER] & (1u << ((_index)&_BITMAP_MASK))))
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2018-07-25 16:51:48 +02:00
|
|
|
#define BLI_BITMAP_TEST_AND_SET_ATOMIC(_bitmap, _index) \
|
|
|
|
(CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
|
2018-08-01 10:52:01 +02:00
|
|
|
(atomic_fetch_and_or_uint32((uint32_t *)&(_bitmap)[(_index) >> _BITMAP_POWER], \
|
|
|
|
(1u << ((_index)&_BITMAP_MASK))) & \
|
|
|
|
(1u << ((_index)&_BITMAP_MASK))))
|
2018-07-25 16:51:48 +02:00
|
|
|
|
2014-06-06 16:05:15 +10:00
|
|
|
#define BLI_BITMAP_TEST_BOOL(_bitmap, _index) \
|
2015-01-14 05:10:18 +11:00
|
|
|
(CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
|
2014-06-06 16:05:15 +10:00
|
|
|
(BLI_BITMAP_TEST(_bitmap, _index) != 0))
|
2013-10-10 22:30:16 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Set the value of a single bit at '_index'.
|
|
|
|
*/
|
2014-06-06 16:05:15 +10:00
|
|
|
#define BLI_BITMAP_ENABLE(_bitmap, _index) \
|
2015-01-14 05:10:18 +11:00
|
|
|
(CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
|
2014-06-06 16:00:53 +10:00
|
|
|
((_bitmap)[(_index) >> _BITMAP_POWER] |= (1u << ((_index)&_BITMAP_MASK))))
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Clear the value of a single bit at '_index'.
|
|
|
|
*/
|
2014-06-06 16:05:15 +10:00
|
|
|
#define BLI_BITMAP_DISABLE(_bitmap, _index) \
|
2015-01-14 05:10:18 +11:00
|
|
|
(CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
|
2014-06-06 16:00:53 +10:00
|
|
|
((_bitmap)[(_index) >> _BITMAP_POWER] &= ~(1u << ((_index)&_BITMAP_MASK))))
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Flip the value of a single bit at '_index'.
|
|
|
|
*/
|
2016-02-13 17:47:38 +11:00
|
|
|
#define BLI_BITMAP_FLIP(_bitmap, _index) \
|
|
|
|
(CHECK_TYPE_ANY(_bitmap, BLI_bitmap *, const BLI_bitmap *), \
|
|
|
|
((_bitmap)[(_index) >> _BITMAP_POWER] ^= (1u << ((_index)&_BITMAP_MASK))))
|
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Set or clear the value of a single bit at '_index'.
|
|
|
|
*/
|
2014-06-06 16:05:15 +10:00
|
|
|
#define BLI_BITMAP_SET(_bitmap, _index, _set) \
|
2014-06-06 16:00:53 +10:00
|
|
|
{ \
|
|
|
|
CHECK_TYPE(_bitmap, BLI_bitmap *); \
|
2020-09-19 16:01:32 +10:00
|
|
|
if (_set) { \
|
2014-06-06 16:05:15 +10:00
|
|
|
BLI_BITMAP_ENABLE(_bitmap, _index); \
|
2020-09-19 16:01:32 +10:00
|
|
|
} \
|
|
|
|
else { \
|
2014-06-06 16:05:15 +10:00
|
|
|
BLI_BITMAP_DISABLE(_bitmap, _index); \
|
2020-09-19 16:01:32 +10:00
|
|
|
} \
|
2014-06-06 16:00:53 +10:00
|
|
|
} \
|
|
|
|
(void)0
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
2022-03-30 17:26:42 +11:00
|
|
|
* Resize bitmap to have space for '_num' bits.
|
2021-12-09 20:01:44 +11:00
|
|
|
*/
|
2022-03-30 17:26:42 +11:00
|
|
|
#define BLI_BITMAP_RESIZE(_bitmap, _num) \
|
2014-06-06 16:00:53 +10:00
|
|
|
{ \
|
|
|
|
CHECK_TYPE(_bitmap, BLI_bitmap *); \
|
2022-03-30 17:26:42 +11:00
|
|
|
(_bitmap) = MEM_recallocN(_bitmap, BLI_BITMAP_SIZE(_num)); \
|
2014-06-06 16:00:53 +10:00
|
|
|
} \
|
|
|
|
(void)0
|
2012-02-22 23:57:31 +00:00
|
|
|
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Set or clear all bits in the bitmap.
|
|
|
|
*/
|
2018-12-15 11:47:24 +03:00
|
|
|
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits);
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Invert all bits in the bitmap.
|
|
|
|
*/
|
2018-12-15 11:47:24 +03:00
|
|
|
void BLI_bitmap_flip_all(BLI_bitmap *bitmap, size_t bits);
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Copy all bits from one bitmap to another.
|
|
|
|
*/
|
2018-12-15 11:47:24 +03:00
|
|
|
void BLI_bitmap_copy_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits);
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Combine two bitmaps with boolean AND.
|
|
|
|
*/
|
2018-12-15 11:47:24 +03:00
|
|
|
void BLI_bitmap_and_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits);
|
2021-12-09 20:01:44 +11:00
|
|
|
/**
|
|
|
|
* Combine two bitmaps with boolean OR.
|
|
|
|
*/
|
2018-12-15 11:47:24 +03:00
|
|
|
void BLI_bitmap_or_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits);
|
|
|
|
|
2022-07-15 10:20:04 +03:00
|
|
|
/**
|
|
|
|
* Find index of the lowest unset bit.
|
|
|
|
* Returns -1 if all the bits are set.
|
|
|
|
*/
|
|
|
|
int BLI_bitmap_find_first_unset(const BLI_bitmap *bitmap, size_t bits);
|
|
|
|
|
2020-03-02 15:04:53 +01:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|