Beatmup
mask_bitmap_access.h
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2019, lnstadrum
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #pragma once
20 #include "abstract_bitmap.h"
21 #include "../exception.h"
22 #include "pixel_arithmetic.h"
23 
24 namespace Beatmup {
25  /**
26  A generic to access mask bitmap data
27  */
28  template<const int num_bits> class MaskScanner {
29  protected:
30  unsigned char
31  *data, //!< all bitmap data
32  *ptr, //!< pointer to current pixel
33  bit; //!< current position bit
34  int width, height; //!< bitmap size in pixels
35 
37 #ifdef BEATMUP_DEBUG
38  DebugAssertion::check(bitmap.getBitsPerPixel() == num_bits,
39  "Invalid mask bitmap scanner");
40 #endif
41  width = bitmap.getWidth();
43  data = (unsigned char*)bitmap.getData(0, 0);
44  }
45 
46  public:
47  typedef unsigned char pixvaltype;
48  typedef pixint1 pixtype;
49 
50  const int
51  NUMBER_OF_CHANNELS = 1, // a mask always has one channel
52  NUMBER_OF_BITS = num_bits,
53  MAX_VALUE = 255,
54  MAX_UNNORM_VALUE = (1 << num_bits) - 1;
55 
56  bool operator < (const MaskScanner& another) const {
57  return (ptr < another.ptr) || (ptr == another.ptr && bit < another.bit);
58  }
59 
60  pixtype* operator*() const {
61  return (pixtype*)ptr;
62  }
63 
64  /**
65  Returns bitmap width in pixels
66  */
67  inline int getWidth() const {
68  return width;
69  }
70 
71  /**
72  Returns bitmap height in pixels
73  */
74  inline int getHeight() const {
75  return height;
76  }
77  };
78 
79 
80  /**
81  A generic to access sub-byte mask bitmap data
82  */
83  template<const int num_bits, const int lookup[]> class LookupMaskScanner : public MaskScanner<num_bits> {
84  protected:
85  const int pointsPerByte = 8 / num_bits;
86  public:
87  /**
88  Returns 0..MAX_UNNORM_VALUE value at current position
89  */
90  inline unsigned char getValue() const {
91  return ((*this->ptr) >> this->bit) & this->MAX_UNNORM_VALUE;
92  }
93 
94  /**
95  Returns 0..MAX_UNNORM_VALUE value at (x,y) position
96  */
97  inline unsigned char getValue(int x, int y) const {
98  msize n = (this->width*y + x);
99  uint8_t
100  *p = this->data + n / pointsPerByte,
101  b = (unsigned char)(n % pointsPerByte);
102  return ((*p) >> (b*num_bits)) & this->MAX_UNNORM_VALUE;
103  }
104 
105  /**
106  Returns 0..MAX_UNNORM_VALUE value at position shifted by i pixels in scanline order with respect
107  to the current position
108  */
109  inline unsigned char getValue(int i) const {
110  int n = this->bit / num_bits + i;
111  uint8_t
112  *p = this->ptr + n / pointsPerByte,
113  b = (unsigned char)(n % pointsPerByte);
114  return ((*p) >> (b*num_bits)) & this->MAX_UNNORM_VALUE;
115  }
116 
117  /**
118  Returns 0..255 value at current position
119  */
120  inline pixint1 operator()() const {
121  return pixint1{ lookup[getValue()] };
122  }
123 
124  /**
125  Returns 0..255 value at (x,y) position
126  */
127  inline pixint1 operator()(int x, int y) const {
128  return pixint1{ lookup[getValue(x, y)] };
129  }
130 
131  /**
132  Returns 0..255 value at position shifted by i pixels in scanline order with respect to the current position
133  */
134  inline const pixint1 operator[](int i) const {
135  return pixint1{ lookup[getValue(i)] };
136  }
137 
138  /**
139  Move the current position ONE PIXEL forward
140  */
141  inline void operator++(int) {
142  // int argument here is to declare the postfix increment (a C++ convention)
143  if ((this->bit += num_bits) >= 8) {
144  this->ptr++;
145  this->bit = 0;
146  }
147  }
148 
149  /**
150  Move the current position N pixels forward
151  */
152  inline void operator+=(const int N) {
153  this->bit += N*num_bits;
154  this->ptr += this->bit / 8;
155  this->bit = this->bit % 8;
156  }
157 
158  /**
159  Changes current position
160  */
161  inline void goTo(int x, int y) {
162 #ifdef BEATMUP_DEBUG
163  DebugAssertion::check(x >= 0 && y >= 0 && x < this->width && y < this->height,
164  "Coordinates outside of image: %d %d (width=%d, height=%d)", x, y, this->width, this->height);
165 #endif
166  msize n = (this->width*y + x);
167  this->ptr = this->data + n / pointsPerByte,
168  this->bit = (unsigned char)(n % pointsPerByte) * num_bits;
169  }
170 
171  LookupMaskScanner(const AbstractBitmap& bitmap, int x = 0, int y = 0):
172  MaskScanner<num_bits>(bitmap)
173  {
174  goTo(x, y);
175  }
176  };
177 
178 
179  /**
180  A generic to write mask bitmap data
181  */
182  template<const int num_bits, const int lookup[]> class LookupMaskWriter : public LookupMaskScanner < num_bits, lookup >, BitmapContentModifier {
183  public:
184  /**
185  Puts a properly scaled (0..MAX_UNNORM_VALUE) value at the current position
186  */
187  inline void putValue(unsigned char x) {
188  *this->ptr = (*this->ptr & ~(this->MAX_UNNORM_VALUE << this->bit)) + (x << this->bit);
189  }
190 
191  /**
192  Puts an unscaled (0..255) value at the current position.
193  \return properly scaled value put into the mask.
194  */
195  inline unsigned char assign(int x) {
196  unsigned char v = x > 0 ? (x < 256 ? x * this->MAX_UNNORM_VALUE / 255 : this->MAX_UNNORM_VALUE) : 0;
197  putValue(v);
198  return v;
199  }
200 
201  inline unsigned char assign(int r, int g, int b) {
202  return assign((r + g + b) / 3);
203  }
204 
205  inline unsigned char assign(int r, int g, int b, int a) {
206  return assign(a);
207  }
208 
209  inline unsigned char assign(float x) {
210  unsigned char v = x > 0.0f ? (x < 1.0f ? (unsigned char)roundf(x * this->MAX_UNNORM_VALUE) : this->MAX_UNNORM_VALUE) : 0;
211  putValue(v);
212  return v;
213  }
214 
215  inline unsigned char assign(float r, float g, float b) {
216  return assign((r + g + b) / 3);
217  }
218 
219  inline unsigned char assign(float r, float g, float b, float a) {
220  return assign(a);
221  }
222 
223  inline void operator<<(const pixint1& P) {
224  assign(P.x);
225  }
226 
227  inline void operator<<(const pixint3& P) {
228  assign(P.r, P.g, P.b);
229  }
230 
231  inline void operator<<(const pixint4& P) {
232  *this->ptr = clipPixint(((P.r + P.g + P.b) * P.a + *this->ptr * (255 - P.a) * 3) / 765);
233  }
234 
235  inline void operator<<(const pixfloat1& P) {
236  assign(P.x);
237  }
238 
239  inline void operator<<(const pixfloat3& P) {
240  assign(P.r, P.g, P.b);
241  }
242 
243  inline void operator<<(const pixfloat4& P) {
244  *this->ptr = pixfloat2pixbyte((P.r + P.g + P.b) * P.a / 3 + *this->ptr * (1 - P.a));
245  }
246 
247  inline void operator=(const pixint1& P) {
248  assign(P.x);
249  }
250 
251  inline void operator=(const pixint3& P) {
252  assign(P.r, P.g, P.b);
253  }
254 
255  inline void operator=(const pixint4& P) {
256  assign(P.r, P.g, P.b, P.a);
257  }
258 
259  inline void operator=(const pixfloat1& P) {
260  assign(P.x);
261  }
262 
263  inline void operator=(const pixfloat3& P) {
264  assign(P.r, P.g, P.b);
265  }
266 
267  inline void operator=(const pixfloat4& P) {
268  assign(P.r, P.g, P.b, P.a);
269  }
270 
271  LookupMaskWriter(AbstractBitmap& bitmap, int x = 0, int y = 0) : LookupMaskScanner < num_bits, lookup >(bitmap, x, y), BitmapContentModifier(bitmap) {}
272  };
273 
274  //!< lookup tables for masks values
275  extern const int MASK_LUT_1_BIT[2], MASK_LUT_2_BITS[4], MASK_LUT_4_BITS[16];
276 
283 
284 
285  /**
286  Mask reqding interface to single byte bitmap
287  */
288  class SingleByteMaskReader : public MaskScanner<8> {
289  public:
290  /**
291  Returns 0..MAX_UNNORM_VALUE value at current position
292  */
293  inline unsigned char getValue() const {
294  return *ptr;
295  }
296 
297  /**
298  Returns 0..MAX_UNNORM_VALUE value at position shifted by i pixels in scanline order with respect
299  to the current position
300  */
301  inline unsigned char getValue(int i) const {
302  return ptr[i];
303  }
304 
305  /**
306  Returns 0..MAX_UNNORM_VALUE value at (x,y) position
307  */
308  inline unsigned char getValue(int x, int y) const {
309  return data[width*y + x];
310  }
311 
312  /**
313  Returns 0..255 value at current position
314  */
315  inline pixint1 operator()() const {
316  return pixint1{ getValue() };
317  }
318 
319  /**
320  Returns 0..255 value at (x,y) position
321  */
322  inline pixint1 operator()(int x, int y) const {
323  return pixint1{ getValue(x, y) };
324  }
325 
326  /**
327  Returns 0..255 value at position shifted by i pixels in scanline order with respect to the current position
328  */
329  inline const pixint1 operator[](int i) const {
330  return pixint1{ getValue(i) };
331  }
332 
333  /**
334  Move the current position ONE PIXEL forward
335  */
336  inline void operator++(int) {
337  // int argument here is to declare the postfix increment (a C++ convention)
338  ptr++;
339  }
340 
341  /**
342  Move the current position N pixels forward
343  */
344  inline void operator+=(const int N) {
345  ptr += N;
346  }
347 
348  /**
349  Changes current position
350  */
351  inline void goTo(int x, int y) {
352 #ifdef BEATMUP_DEBUG
353  DebugAssertion::check(x >= 0 && y >= 0 && x < width && y < height,
354  "Coordinates outside of image: %d %d (width=%d, height=%d)", x, y, width, height);
355 #endif
356  ptr = data + (width*y + x);
357  }
358 
359  SingleByteMaskReader(const AbstractBitmap& bitmap, int x = 0, int y = 0):
360  MaskScanner<8>(bitmap)
361  {
362  goTo(x, y);
363  }
364  };
365 
366 
368  public:
369  /**
370  Puts a properly scaled (0..MAX_UNNORM_VALUE) value at the current position
371  */
372  inline void putValue(unsigned char x) {
373  *this->ptr = x;
374  }
375 
376  /**
377  Puts an unscaled (0..255) value at the current position.
378  \return properly scaled value put into the mask.
379  */
380  inline unsigned char assign(int x) {
381  putValue(x);
382  return x;
383  }
384 
385  inline unsigned char assign(int r, int g, int b) {
386  return assign((r + g + b) / 3);
387  }
388 
389  inline unsigned char assign(int r, int g, int b, int a) {
390  return assign(a);
391  }
392 
393  inline unsigned char assign(float x) {
394  unsigned char v = x > 0.0f ? (x < 1.0f ? (unsigned char)roundf(x * this->MAX_UNNORM_VALUE) : this->MAX_UNNORM_VALUE) : 0;
395  putValue(v);
396  return v;
397  }
398 
399  inline unsigned char assign(float r, float g, float b) {
400  return assign((r + g + b) / 3);
401  }
402 
403  inline unsigned char assign(float r, float g, float b, float a) {
404  return assign(a);
405  }
406 
407  inline void operator<<(const pixint1& P) {
408  assign(P.x);
409  }
410 
411  inline void operator<<(const pixint3& P) {
412  assign(P.r, P.g, P.b);
413  }
414 
415  inline void operator<<(const pixint4& P) {
416  *this->ptr = clipPixint(((P.r + P.g + P.b) * P.a + *this->ptr * (255 - P.a) * 3) / 765);
417  }
418 
419  inline void operator<<(const pixfloat1& P) {
420  assign(P.x);
421  }
422 
423  inline void operator<<(const pixfloat3& P) {
424  assign(P.r, P.g, P.b);
425  }
426 
427  inline void operator<<(const pixfloat4& P) {
428  *this->ptr = pixfloat2pixbyte((P.r + P.g + P.b) * P.a / 3 + *this->ptr * (1 - P.a));
429  }
430 
431  inline void operator=(const pixint1& P) {
432  assign(P.x);
433  }
434 
435  inline void operator=(const pixint3& P) {
436  assign(P.r, P.g, P.b);
437  }
438 
439  inline void operator=(const pixint4& P) {
440  assign(P.r, P.g, P.b, P.a);
441  }
442 
443  inline void operator=(const pixfloat1& P) {
444  assign(P.x);
445  }
446 
447  inline void operator=(const pixfloat3& P) {
448  assign(P.r, P.g, P.b);
449  }
450 
451  inline void operator=(const pixfloat4& P) {
452  assign(P.r, P.g, P.b, P.a);
453  }
454 
456  };
457 }
A very basic class for any image.
const unsigned char getBitsPerPixel() const
Returns number of bits per pixel stored in each bitmap.
const pixbyte * getData(int x, int y) const
Returns a pointer to given pixel.
const int getHeight() const
Height of the texture in pixels.
const int getWidth() const
Width of the texture in pixels.
A generic to access sub-byte mask bitmap data.
unsigned char getValue(int i) const
Returns 0..MAX_UNNORM_VALUE value at position shifted by i pixels in scanline order with respect to t...
pixint1 operator()() const
Returns 0..255 value at current position.
unsigned char getValue() const
Returns 0..MAX_UNNORM_VALUE value at current position.
const pixint1 operator[](int i) const
Returns 0..255 value at position shifted by i pixels in scanline order with respect to the current po...
unsigned char getValue(int x, int y) const
Returns 0..MAX_UNNORM_VALUE value at (x,y) position.
void goTo(int x, int y)
Changes current position.
void operator+=(const int N)
Move the current position N pixels forward.
pixint1 operator()(int x, int y) const
Returns 0..255 value at (x,y) position.
void operator++(int)
Move the current position ONE PIXEL forward.
LookupMaskScanner(const AbstractBitmap &bitmap, int x=0, int y=0)
A generic to write mask bitmap data lookup tables for masks values.
void operator<<(const pixint4 &P)
unsigned char assign(int r, int g, int b)
void putValue(unsigned char x)
Puts a properly scaled (0..MAX_UNNORM_VALUE) value at the current position.
void operator=(const pixint3 &P)
unsigned char assign(float r, float g, float b)
void operator<<(const pixfloat3 &P)
void operator=(const pixfloat1 &P)
void operator<<(const pixfloat1 &P)
void operator<<(const pixfloat4 &P)
void operator=(const pixint1 &P)
void operator=(const pixfloat4 &P)
void operator<<(const pixint1 &P)
void operator=(const pixint4 &P)
unsigned char assign(float x)
unsigned char assign(int r, int g, int b, int a)
void operator<<(const pixint3 &P)
unsigned char assign(int x)
Puts an unscaled (0..255) value at the current position.
void operator=(const pixfloat3 &P)
LookupMaskWriter(AbstractBitmap &bitmap, int x=0, int y=0)
unsigned char assign(float r, float g, float b, float a)
A generic to access mask bitmap data.
MaskScanner(const AbstractBitmap &bitmap)
unsigned char bit
current position bit
bool operator<(const MaskScanner &another) const
unsigned char * ptr
pointer to current pixel
int getHeight() const
Returns bitmap height in pixels.
pixtype * operator*() const
int height
bitmap size in pixels
int getWidth() const
Returns bitmap width in pixels.
unsigned char * data
all bitmap data
Mask reqding interface to single byte bitmap.
unsigned char getValue(int x, int y) const
Returns 0..MAX_UNNORM_VALUE value at (x,y) position.
unsigned char getValue(int i) const
Returns 0..MAX_UNNORM_VALUE value at position shifted by i pixels in scanline order with respect to t...
void goTo(int x, int y)
Changes current position.
SingleByteMaskReader(const AbstractBitmap &bitmap, int x=0, int y=0)
unsigned char getValue() const
Returns 0..MAX_UNNORM_VALUE value at current position.
void operator++(int)
Move the current position ONE PIXEL forward.
pixint1 operator()(int x, int y) const
Returns 0..255 value at (x,y) position.
void operator+=(const int N)
Move the current position N pixels forward.
pixint1 operator()() const
Returns 0..255 value at current position.
const pixint1 operator[](int i) const
Returns 0..255 value at position shifted by i pixels in scanline order with respect to the current po...
SingleByteMaskWriter(AbstractBitmap &bitmap, int x=0, int y=0)
void putValue(unsigned char x)
Puts a properly scaled (0..MAX_UNNORM_VALUE) value at the current position.
void operator<<(const pixfloat1 &P)
unsigned char assign(float r, float g, float b)
unsigned char assign(int r, int g, int b)
void operator=(const pixfloat3 &P)
void operator=(const pixfloat1 &P)
unsigned char assign(int x)
Puts an unscaled (0..255) value at the current position.
unsigned char assign(float r, float g, float b, float a)
void operator<<(const pixfloat4 &P)
void operator=(const pixint1 &P)
void operator=(const pixint4 &P)
void operator<<(const pixint3 &P)
void operator=(const pixfloat4 &P)
void operator<<(const pixint1 &P)
unsigned char assign(int r, int g, int b, int a)
void operator=(const pixint3 &P)
unsigned char assign(float x)
void operator<<(const pixint4 &P)
void operator<<(const pixfloat3 &P)
uint32_t msize
memory size
Definition: basic_types.h:30
LookupMaskWriter< 4, MASK_LUT_4_BITS > HexMaskWriter
LookupMaskScanner< 2, MASK_LUT_2_BITS > QuaternaryMaskReader
const int MASK_LUT_4_BITS[16]
LookupMaskWriter< 1, MASK_LUT_1_BIT > BinaryMaskWriter
LookupMaskScanner< 1, MASK_LUT_1_BIT > BinaryMaskReader
pixbyte clipPixint(int x)
Clips an integer pixel value to 0..255 range.
pixbyte pixfloat2pixbyte(pixfloat x)
Converts a floating point pixel value to a 0..255 integer.
LookupMaskWriter< 2, MASK_LUT_2_BITS > QuaternaryMaskWriter
const int MASK_LUT_2_BITS[4]
LookupMaskScanner< 4, MASK_LUT_4_BITS > HexMaskReader
const int MASK_LUT_1_BIT[2]
Monochromatic floating point arithmetic.
Trichromatic floating point arithmetic.
4-channel floating point arithmetic
Monochromatic integer arithmetic.
Trichromatic integer arithmetic.
4-channel integer arithmetic
jobject jlong jint jint jint jint g
jobject jlong jint jint jint jint jint b
jobject jlong jint jint y
jobject jlong jint jint jint r
jobject jlong jint jint jint jint jint jint a
jobject jlong jint x
Beatmup::InternalBitmap * bitmap
Beatmup::IntPoint p((int) x,(int) y)
int n
JNIEnv jlong jfloat jfloat jfloat v