Beatmup
abstract_bitmap.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 "abstract_bitmap.h"
20 #include "../context.h"
21 #include "../gpu/pipeline.h"
22 #include "internal_bitmap.h"
23 #include "converter.h"
24 #include "../gpu/bgl.h"
25 #include "../exception.h"
26 #include "../gpu/swapper.h"
27 #include "../utils/bmp_file.h"
28 #include <cstring>
29 
30 
31 using namespace Beatmup;
32 
33 const char* AbstractBitmap::PIXEL_FORMAT_NAMES[] = {
34  "single byte", "triple byte", "quad byte",
35  "single floating point", "triple floating point", "quad floating point",
36  "binary mask", "quaternary mask", "hexadecimal mask"
37 };
38 
39 
40 const unsigned char AbstractBitmap::BITS_PER_PIXEL[] = {
41  8, 8*3, 8*4, // integer bitmaps
42  32, 32*3, 32*4, // floating point bitmaps
43  1, 2, 4 // masks
44 };
45 
46 
47 const unsigned char AbstractBitmap::CHANNELS_PER_PIXEL[] = {
48  1, 3, 4, // integer bitmaps
49  1, 3, 4, // floating point bitmaps
50  1, 1, 1 // masks
51 };
52 
53 
55  const bool handleValid = hasValidHandle();
56 
57  if (!handleValid)
58  TextureHandler::prepare(gpu);
59  glBindTexture(GL_TEXTURE_2D, textureHandle);
60 
61  // setup alignment
62  if (isMask()) {
63  // masks are stored as horizontally-stretched bitmaps
64  const int textureWidth = getWidth() / (8 / getBitsPerPixel());
65 
66 #ifdef BEATMUP_OPENGLVERSION_GLES20
67  if (!handleValid)
68  glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, textureWidth, getHeight(), 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
69 #else
70  if (!handleValid)
71  glTexStorage2D(GL_TEXTURE_2D, 1, GL_R8, textureWidth, getHeight());
72 #endif
73  GL::GLException::check("allocating texture image (mask)");
74  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
75  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
76  }
77 
78  else {
79 #ifdef BEATMUP_OPENGLVERSION_GLES20
80  if (!handleValid)
81  glTexImage2D(GL_TEXTURE_2D,
82  0,
84  getWidth(), getHeight(),
85  0,
88  nullptr);
89 
90 #else
91  if (!handleValid)
92  glTexStorage2D(GL_TEXTURE_2D, 1, GL::BITMAP_INTERNALFORMATS[getPixelFormat()], getWidth(), getHeight());
93 #endif
94  GL::GLException::check("allocating texture image");
95  }
96 }
97 
98 
100  if (isMask())
101  return TextureFormat::Rx8;
102  return (TextureFormat)getPixelFormat();
103 }
104 
105 
107  return upToDate[target];
108 }
109 
110 
113 }
114 
115 
116 int AbstractBitmap::getPixelInt(int x, int y, int cha) const {
118  if (isMask(pf)) {
119  unsigned char
120  pixPerByte = 8 / BITS_PER_PIXEL[pf],
121  offset = (x + y*getWidth()) % pixPerByte; // offset from byte-aligned bound in pixels
122  const pixbyte* p = getData(x, y);
123  return ((*p) >> (offset*BITS_PER_PIXEL[pf])) & ((1 << BITS_PER_PIXEL[pf]) - 1);
124  }
125  const pixbyte* p = getData(x, y) + cha * BITS_PER_PIXEL[pf] / 8 / CHANNELS_PER_PIXEL[pf];
126  if (isInteger(pf))
127  return *p;
128  //if (isFloat(pf))
129  return (int)(*((float*)p) * 255);
130 }
131 
132 
133 const unsigned char AbstractBitmap::getBitsPerPixel() const {
134  return BITS_PER_PIXEL[getPixelFormat()];
135 }
136 
137 
138 const unsigned char AbstractBitmap::getNumberOfChannels() const {
140 }
141 
142 
144  return isInteger(getPixelFormat());
145 }
146 
147 
149  return isFloat(getPixelFormat());
150 }
151 
152 
154  return isMask(getPixelFormat());
155 }
156 
157 
160 }
161 
162 
165 }
166 
167 
170 }
171 
172 
173 std::string AbstractBitmap::toString() const {
174  std::string desc = std::to_string(getWidth()) + "x" + std::to_string(getHeight()) + " " + PIXEL_FORMAT_NAMES[getPixelFormat()];
176  desc += " stored on CPU+GPU";
177  else
179  desc += " stored on CPU";
180  else
182  desc += " stored on GPU";
183  else
184  desc += " dirty";
185  return desc;
186 }
187 
188 
191  // Grab output bitmap from GPU memory to RAM
192  Swapper::pullPixels(*this);
193  }
194 
195  lockPixelData();
196 
198  getData(0, 0),
199  getWidth(), getHeight(),
200  getBitsPerPixel(),
201  filename
202  );
203 
204  unlockPixelData();
205 }
206 
207 
211 }
212 
213 
215  if (hasValidHandle()) {
216  TextureHandler::invalidate(*ctx.getGpuRecycleBin());
217  }
218 }
219 
220 
222  return ctx;
223 }
224 
225 
227  lockPixelData();
228  memset(getData(0, 0), 0, getMemorySize());
229  unlockPixelData();
232 }
233 
234 
236 #ifdef BEATMUP_DEBUG
237  DebugAssertion::check(!bitmap.isDirty(), "Reading a dirty bitmap");
238 #endif
242 }
243 
244 
247 }
ReadLock(AbstractBitmap &bitmap)
A very basic class for any image.
virtual const TextureFormat getTextureFormat() const
Returns the texture format specifying how the shader must interpret the data.
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 & ctx
context managing this bitmap
Context & getContext() const
virtual const PixelFormat getPixelFormat() const =0
Pixel format of the bitmap.
bool isDirty() const
Returns true if the bitmap does not contain any valid content.
static const char * PIXEL_FORMAT_NAMES[NUM_PIXEL_FORMATS]
pixel format names
bool isInteger() const
Returns true if the bitmap contains integer values, false otherwise.
int getPixelInt(int x, int y, int cha=0) const
Retrieves integer value of given channel at given pixel.
std::string toString() const
Retruns a string describing the bitmap.
virtual void prepare(GraphicPipeline &gpu)
Prepares (eventually uploads) texture data on GPU.
const unsigned char getBitsPerPixel() const
Returns number of bits per pixel stored in each bitmap.
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.
AbstractBitmap(const AbstractBitmap &that)=delete
disabling copying constructor
bool isUpToDate(ProcessingTarget) const
void saveBmp(const char *filename)
Saves the bitmap to a BMP file.
virtual void lockPixelData()=0
Locks access to the CPU memory buffer containing pixel data.
virtual const msize getMemorySize() const =0
Bitmap size in bytes.
virtual void unlockPixelData()=0
Unlocks access to the CPU memory buffer containing pixel data.
static const unsigned char CHANNELS_PER_PIXEL[NUM_PIXEL_FORMATS]
number of channels for each pixel format
void zero()
Sets all the pixels to zero.
bool upToDate[2]
bitmap up-to-date state on CPU and GPU
static void save(const void *pixels, int32_t width, int32_t height, uint8_t bpp, const char *filename)
Stores an image into a BMP file.
Definition: bmp_file.cpp:145
Basic class: task and memory management, any kind of static data.
Definition: context.h:59
GL::RecycleBin * getGpuRecycleBin() const
Definition: context.cpp:340
static void check(const std::string &info)
Definition: bgl.h:62
bool hasValidHandle() const
Returns true if the texture handle points to a valid texture.
virtual const int getHeight() const =0
Height of the texture in pixels.
TextureFormat
Texture format, specifies how the texture should be interpreted on the shader side.
virtual const int getWidth() const =0
Width of the texture in pixels.
Internal low-level GPU control API.
Definition: pipeline.h:33
void unlockPixelData()
Unlocks access to the CPU memory buffer containing pixel data.
static void pullPixels(AbstractBitmap &bitmap)
Copies bitmap from GPU memory to RAM.
Definition: swapper.cpp:48
const GLuint BITMAP_INTERNALFORMATS[]
Definition: bgl.h:147
const GLuint BITMAP_PIXELTYPES[]
Mapping of bitmap pixel formats to GL pixel types.
Definition: bgl.h:160
const GLuint BITMAP_PIXELFORMATS[]
Mapping of bitmap pixel formats to GL pixel formats.
Definition: bgl.h:80
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
@ QuaternaryMask
2 bits per pixel
@ 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
@ BinaryMask
1 bit per pixel
@ HexMask
4 bits per pixel
ProcessingTarget
Definition: basic_types.h:55
std::string to_string(Beatmup::NNets::ActivationFunction function)
jlong jint jint jint jint pixelFormat
jobject jlong jint jint y
Beatmup::Context * ctx
JNIEnv jlong jstring filename
jobject jlong jint x
Beatmup::InternalBitmap * bitmap
Beatmup::IntPoint p((int) x,(int) y)