Beatmup
bitmap.cpp
Go to the documentation of this file.
1 /*
2  Beatmup image and signal processing library
3  Copyright (C) 2020, 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 "bitmap.h"
20 #include <stdexcept>
21 
22 using namespace Beatmup;
23 
24 
25 Python::Bitmap::Bitmap(Beatmup::Context& context, pybind11::buffer& buffer):
26  AbstractBitmap(context)
27 {
28  auto info = buffer.request();
29 
30  // check if empty
31  if (info.size == 0)
32  throw std::invalid_argument("A bitmap cannot be empty");
33 
34  // check dimensions
35  if (info.ndim < 3)
36  throw std::invalid_argument("A bitmap is expected to have at least 3 dimensions");
37  else
38  for (int i = 0; i + 3 < info.ndim; ++i)
39  if (info.shape[i] != 1)
40  throw std::invalid_argument("A bitmap is expected to have at most 3 inner non-singleton dimensions.");
41 
42  // check pixel format
43  static const char* FORMAT_UINT8 = "B";
44  static const char* FORMAT_FLOAT = "f";
45  const auto numChannels = info.shape[info.ndim - 1];
46 
47  if (info.format == FORMAT_UINT8)
48  switch (numChannels) {
49  case 1: format = PixelFormat::SingleByte; break;
50  case 3: format = PixelFormat::TripleByte; break;
51  case 4: format = PixelFormat::QuadByte; break;
52  default:
53  throw std::invalid_argument("A bitmap may have 1, 3 of 4 channels, but got " + std::to_string(numChannels));
54  }
55  else if (info.format == FORMAT_FLOAT)
56  switch (numChannels) {
57  case 1: format = PixelFormat::SingleFloat; break;
58  case 3: format = PixelFormat::TripleFloat; break;
59  case 4: format = PixelFormat::QuadFloat; break;
60  default:
61  throw std::invalid_argument("A bitmap may have 1, 3 of 4 channels, but got " + std::to_string(numChannels));
62  }
63  else
64  throw std::invalid_argument("Unsupported data format. Expected bitmap values of type float32 or uint8.");
65 
66  // check stride
67  const int bps = getBitsPerPixel() / 8;
68  strideBytes = info.shape[info.ndim - 2] * bps;
69  if (info.strides[info.ndim - 1] * numChannels != bps || info.strides[info.ndim - 2] != bps || info.strides[info.ndim - 3] != strideBytes)
70  throw std::invalid_argument("Strided bitmaps are not supported.");
71 
72  // GOOOD.
73  data = std::move(info);
74 }
75 
76 
77 const pixbyte* Python::Bitmap::getData(int x, int y) const {
78  return static_cast<const pixbyte*>(data.ptr) + y * strideBytes + x;
79 }
80 
81 
83  return static_cast<pixbyte*>(data.ptr) + y * strideBytes + x;
84 }
85 
86 
88  return data.itemsize * data.size;
89 }
A very basic class for any image.
const unsigned char getBitsPerPixel() const
Returns number of bits per pixel stored in each bitmap.
Basic class: task and memory management, any kind of static data.
Definition: context.h:59
const msize getMemorySize() const
Bitmap size in bytes.
Definition: bitmap.cpp:87
pybind11::buffer_info data
Definition: bitmap.h:37
Bitmap(Beatmup::Context &context, pybind11::buffer &buffer)
Creates the bitmap from Android Bitmap java object.
Definition: bitmap.cpp:25
PixelFormat format
Definition: bitmap.h:38
const pixbyte * getData(int x, int y) const
Returns a pointer to given pixel.
Definition: bitmap.cpp:77
uint32_t msize
memory size
Definition: basic_types.h:30
uint8_t pixbyte
Definition: basic_types.h:34
@ SingleByte
single channel of 8 bits per pixel (like grayscale), unsigned integer values
@ SingleFloat
single channel of 32 bits per pixel (like grayscale), single precision floating point values
@ QuadFloat
4 channels of 32 bits per pixel, single precision floating point values,
@ TripleFloat
3 channels of 32 bits per pixel, single precision floating point values
@ QuadByte
4 channels of 8 bits per pixel (like RGBA), unsigned integer values
@ TripleByte
3 channels of 8 bits per pixel (like RGB), unsigned integer values
std::string to_string(Beatmup::NNets::ActivationFunction function)
jobject jlong jint jint y
jobject jlong jint x