Beatmup
tools.cpp
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 #include "tools.h"
20 #include "bitmap_access.h"
21 #include "converter.h"
22 #include "processing.h"
23 #include <cstdlib>
24 
25 
26 using namespace Beatmup;
27 
28 
29 namespace Kernels {
30  template<class in_t> class ScanlineSearch {
31  public:
32  static void process(AbstractBitmap& bitmap, const typename in_t::pixtype& target, const IntPoint& start, IntPoint& result) {
33  in_t in(bitmap, start.x, start.y);
34 
35  typename in_t::pixtype convTarget;
36  convTarget = target;
37  int x = start.x, y = start.y;
38  const int W = in.getWidth(), H = in.getHeight();
39  in.goTo(x,y);
40  do {
41  if (in() == convTarget) {
42  result.x = x;
43  result.y = y;
44  return;
45  }
46  x++;
47  if (x >= W) {
48  x = 0;
49  y++;
50  }
51  in++;
52  } while (y < H);
53  result.x = result.y = -1;
54  }
55  };
56 
57 
58  template<class out_t> class ChessboardRendering {
59  public:
60  static void process(AbstractBitmap& bitmap, int width, int height, int cellSize) {
61  out_t out(bitmap);
62  for (int y = 0; y < height; y++)
63  for (int x = 0; x < width; x++) {
64  out = pixint1{ 255 * ((x / cellSize + y / cellSize) % 2) };
65  out++;
66  }
67  }
68  };
69 }
70 
71 
73  return makeCopy(source, source.getPixelFormat());
74 }
75 
76 
78  return makeCopy(source, source.getContext(), newPixelFormat);
79 }
80 
81 
83  InternalBitmap* copy = new Beatmup::InternalBitmap(context, newPixelFormat, source.getWidth(), source.getHeight());
84  FormatConverter converter;
85  converter.setBitmaps(&source, copy);
86  source.getContext().performTask(converter);
87  return copy;
88 }
89 
90 
92  RuntimeError::check(cellSize > 0, "Chessboard cell size must be positive");
95  BitmapProcessing::write<Kernels::ChessboardRendering>(*chess, width, height, cellSize);
96  return chess;
97 }
98 
99 
102  const int n = bitmap.getNumberOfChannels();
103 
104  if (bitmap.isMask())
105  throw ImplementationUnsupported("Noise is not implemented for mask bitmaps");
106  // floating-point bitmap
107  else if (bitmap.isFloat())
108  for (int y = area.a.y; y <= area.b.y; ++y) {
109  pixfloat* p = (pixfloat*)bitmap.getData(area.a.x, y);
110  for (int x = area.a.x; x <= area.b.x; ++x)
111  for (int i = 0; i < n; ++i, ++p)
112  *p = (float)std::rand() / RAND_MAX;
113  }
114  // integer bitmap
115  else if (bitmap.isInteger()) {
116  for (int y = area.a.y; y <= area.b.y; ++y) {
117  pixbyte* p = bitmap.getData(area.a.x, y);
118  for (int x = area.a.x; x <= area.b.x; ++x)
119  for (int i = 0; i < n; ++i, ++p)
120  *p = std::rand() % 256;
121  }
122  }
123 }
124 
125 
127  noise(bitmap, IntRectangle(0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1));
128 }
129 
130 
133 
134  // floating-point bitmap
136  for (int y = area.a.y; y <= area.b.y; ++y) {
137  pixfloat* p = (pixfloat*)bitmap.getData(area.a.x, y);
138  p += CHANNELS_4.A;
139  *p = 1.0f;
140  for (int x = area.a.x + 1; x <= area.b.x; ++x)
141  *(p += 4) = 1.0f;
142  }
143  // integer bitmap
144  else if (bitmap.getPixelFormat() == QuadByte)
145  for (int y = area.a.y; y <= area.b.y; ++y) {
146  pixbyte* p = bitmap.getData(area.a.x, y);
147  p += CHANNELS_4.A;
148  *p = 255;
149  for (int x = area.a.x + 1; x <= area.b.x; ++x)
150  *(p += 4) = 255;
151  }
152 }
153 
154 
156  RuntimeError::check(input.getWidth() == output.getWidth() && input.getHeight() <= output.getHeight(),
157  "Input size does not fit output size");
159  "Input/output pixel formats mismatch");
160 
162  AbstractBitmap::ReadLock* readLock = (&input == &output) ? nullptr : new AbstractBitmap::ReadLock(input);
163 
164 
165  const size_t NPIX = input.getSize().numPixels();
166  if (input.isFloat()) {
167  pixfloat
168  *pi = (pixfloat*)input.getData(0, 0),
169  *po = (pixfloat*)output.getData(0, 0);
170  const pixfloat* STOP = pi + NPIX * AbstractBitmap::CHANNELS_PER_PIXEL[input.getPixelFormat()];
171  while (pi < STOP)
172  *(po++) = 1 - *(pi++);
173  }
174  else {
175  const size_t N = NPIX * AbstractBitmap::BITS_PER_PIXEL[input.getPixelFormat()] / 8;
176  // fast integer inverse
178  *pi = (pixint_platform*)input.getData(0, 0),
179  *po = (pixint_platform*)output.getData(0, 0);
180  const pixint_platform* STOP = pi + N / sizeof(pixint_platform);
181  while (pi < STOP)
182  *(po++) = ~*(pi++);
183  // process remaining bytes
184  pixbyte
185  *ri = (pixbyte*)pi,
186  *ro = (pixbyte*)po;
187  for (int r = 0; r < N % sizeof(pixint_platform); ++r)
188  *(ro++) = ~*(ri++);
189  }
190 
191  delete readLock;
192 }
193 
194 
197  AbstractBitmap::ReadLock lock(source);
198  BitmapProcessing::read<Kernels::ScanlineSearch>(source, val, startFrom, result);
199  return result;
200 }
201 
202 
205  AbstractBitmap::ReadLock lock(source);
206  BitmapProcessing::read<Kernels::ScanlineSearch>(source, val, startFrom, result);
207  return result;
208 }
Locks a bitmap for reading on CPU.
Makes a bitmap writable for a specific target device.
A very basic class for any image.
static const unsigned char BITS_PER_PIXEL[NUM_PIXEL_FORMATS]
number of bits per pixel for each pixel format
const unsigned char getNumberOfChannels() const
Returns number of bytes per pixel stored in each bitmap.
Context & getContext() const
virtual const PixelFormat getPixelFormat() const =0
Pixel format of the bitmap.
const ImageResolution getSize() const
Returns the bitmap resolution within ImageResolution object.
bool isInteger() const
Returns true if the bitmap contains integer values, false otherwise.
bool isMask() const
Returns true if the bitmap is a mask, false otherwise.
bool isFloat() const
Returns true if the bitmap contains floating point values, false otherwise.
virtual const pixbyte * getData(int x, int y) const =0
Returns a pointer to given pixel.
static const unsigned char CHANNELS_PER_PIXEL[NUM_PIXEL_FORMATS]
number of channels for each pixel format
Basic class: task and memory management, any kind of static data.
Definition: context.h:59
float performTask(AbstractTask &task, const PoolIndex pool=DEFAULT_POOL)
Performs a given task.
Definition: context.cpp:240
CustomPoint< numeric > b
Definition: geometry.h:131
CustomPoint< numeric > a
Definition: geometry.h:131
Converts bitmap content from one pixel format to another one.
Definition: converter.h:28
void setBitmaps(AbstractBitmap *input, AbstractBitmap *output)
Definition: converter.cpp:43
virtual const int getHeight() const =0
Height of the texture in pixels.
virtual const int getWidth() const =0
Width of the texture in pixels.
Exception thrown when an implementation restriction is encountered.
Definition: exception.h:124
Bitmap whose memory is managed by the Beatmup engine.
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.
const PixelFormat getPixelFormat() const
Pixel format of the bitmap.
static void check(const bool condition, const std::string &message)
Definition: exception.h:64
static void process(AbstractBitmap &bitmap, int width, int height, int cellSize)
Definition: tools.cpp:60
static void process(AbstractBitmap &bitmap, const typename in_t::pixtype &target, const IntPoint &start, IntPoint &result)
Definition: tools.cpp:32
IntPoint scanlineSearch(AbstractBitmap &source, pixint4 val, const IntPoint &startFrom)
Goes through a bitmap in scanline order (left to right, top to bottom) until a pixel of a given color...
Definition: tools.cpp:195
void invert(AbstractBitmap &input, AbstractBitmap &output)
Inverses colors of an image in a pixelwise fashion.
Definition: tools.cpp:155
InternalBitmap * makeCopy(AbstractBitmap &bitmap)
Makes a copy of a bitmap.
Definition: tools.cpp:72
void noise(AbstractBitmap &bitmap, IntRectangle area)
Replaces a rectangular area in a bitmap by random noise.
Definition: tools.cpp:100
InternalBitmap * chessboard(Context &context, int width, int height, int cellSize, PixelFormat pixelFormat=BinaryMask)
Renders a chessboard image.
Definition: tools.cpp:91
void makeOpaque(AbstractBitmap &bitmap, IntRectangle area)
Makes a bitmap area opaque.
Definition: tools.cpp:131
uint8_t pixbyte
Definition: basic_types.h:34
const float pi
Definition: basic_types.h:29
CustomRectangle< int > IntRectangle
Definition: geometry.h:630
uint32_t pixint_platform
Definition: basic_types.h:31
float pixfloat
Definition: basic_types.h:35
@ QuadFloat
4 channels of 32 bits per pixel, single precision floating point values,
@ QuadByte
4 channels of 8 bits per pixel (like RGBA), unsigned integer values
static const struct Beatmup::@1 CHANNELS_4
Operations kernels.
Definition: basic_types.h:85
4-channel floating point arithmetic
Monochromatic integer arithmetic.
4-channel integer arithmetic
Beatmup::AbstractBitmap * copy
jlong jint jint jint jint pixelFormat
jobject jlong jint jint y
Beatmup::Context * ctx
jobject jlong jint jint jint r
jlong jint width
Beatmup::IntPoint result
jlong jint jint height
jlong jint start
jobject jlong jint x
return(jlong) new Beatmup jlong jstring jint val
JNIEnv jlong jint out
Beatmup::InternalBitmap * bitmap
Beatmup::IntPoint p((int) x,(int) y)
int n