Beatmup Java package
Bitmap.java
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 package Beatmup;
20 
21 import android.graphics.Bitmap.Config;
22 import android.util.Log;
23 
24 import Beatmup.Context;
25 import Beatmup.Geometry.IntRectangle;
26 import Beatmup.Imaging.PixelFormat;
27 
28 
29 /**
30  * Bitmap wrapper
31  */
32 public class Bitmap extends Beatmup.Object {
33  protected Context context;
34 
35  // native methods
36  private native static long newInternalBitmap(Context context, int width, int height, int pixelFormat);
37 
38  protected native static long newNativeBitmap(Context context, android.graphics.Bitmap bitmap);
39 
40  private native int getWidth(long handle);
41  private native int getHeight(long handle);
42  private native int getPixelFormat(long handle);
43 
44  private native void zero(long handle);
45  private native void crop(long handle, long outputHandle, int x1, int y1, int x2, int y2, int outLeft, int outTop);
46  private native static void invert(long handle);
47 
48  protected native static void pullPixels(long handle);
49 
50 
51  private static long createNativeBitmapEnsuringPixelFormat(Context context, android.graphics.Bitmap bitmap) throws BadPixelFormat {
52  if (bitmap.getConfig() != android.graphics.Bitmap.Config.ALPHA_8 && bitmap.getConfig() != android.graphics.Bitmap.Config.ARGB_8888)
53  throw new BadPixelFormat(bitmap.getConfig());
54  return newNativeBitmap(context, bitmap);
55  }
56 
57 
58  protected Bitmap(Context context, long handle) {
59  super(handle);
60  this.context = context;
61  context.watchBitmap(this);
62  }
63 
64 
65  /**
66  * Creates new bitmap from Android bitmap object. NO PIXEL DATA IS COPIED.
67  * @param context Beatmup context
68  * @param bitmap source bitmap
69  * @throws BadPixelFormat
70  */
71  protected Bitmap(Context context, android.graphics.Bitmap bitmap) throws BadPixelFormat {
72  super(createNativeBitmapEnsuringPixelFormat(context, bitmap));
73  this.context = context;
74  context.watchBitmap(this);
75  }
76 
77 
78  /**
79  * Creates new internally managed bitmap
80  * @param context Beatmup context
81  * @param width bitmap width in pixels
82  * @param height bitmap height in pixels
83  * @param pixelFormat bitmap pixel format
84  */
85  public Bitmap(Context context, int width, int height, PixelFormat pixelFormat) {
86  super(newInternalBitmap(context, width, height, pixelFormat.ordinal()));
87  this.context = context;
88  context.watchBitmap(this);
89  }
90 
91 
92  /**
93  * Creates a bitmap whose right bound is byte-aligned
94  * @param context Beatmup context
95  * @param minWidth minimal bitmap width in pixels; the actual one may be bigger to have the aligned right boundary
96  * @param height bitmap height in pixels
97  * @param pixelFormat bitmap pixel format
98  * @return new byte-aligned bitmap
99  */
100  static Bitmap createByteAligned(Context context, int minWidth, int height, PixelFormat pixelFormat) {
101  int pixPerByte = 8 / pixelFormat.getBitsPerPixel();
102  if (pixPerByte > 1)
103  minWidth = ((minWidth + pixPerByte - 1) / pixPerByte) * pixPerByte;
104  return new Bitmap(context, minWidth, height, pixelFormat);
105  }
106 
107 
108  /**
109  * Creates an empty bitmap of the same size and pixel format as a given bitmap
110  * @param bitmap the bitmap specifying size and pixel format
111  * @return the new bitmap
112  */
113  static public Bitmap createEmpty(Bitmap bitmap) {
114  return new Bitmap(bitmap.context, bitmap.getWidth(), bitmap.getHeight(), bitmap.getPixelFormat());
115  }
116 
117 
118  /**
119  * @return bitmap width in pixels
120  */
121  public int getWidth() {
122  return getWidth(handle);
123  }
124 
125 
126  /**
127  * @return bitmap height in pixels
128  */
129  public int getHeight() {
130  return getHeight(handle);
131  }
132 
133 
134  /**
135  * @return bitmap border rectangle in pixels
136  */
138  return new IntRectangle(0, 0, getWidth()-1, getHeight()-1);
139  }
140 
141 
142  /**
143  * @return bitmap pixel format
144  */
146  return PixelFormat.values()[ getPixelFormat(handle) ];
147  }
148 
149 
150  /**
151  * Sets all bitmap pixels to zero
152  */
153  public void zero() {
154  zero(handle);
155  }
156 
157  public static void recycle(Bitmap bitmap) {
158  if (bitmap != null)
159  bitmap.dispose();
160  }
161 
162 
163  /**
164  * @return copy of this bitmap
165  */
166  public Bitmap clone() {
167  return context.copyBitmap(this, getPixelFormat());
168  }
169 
170 
171  /**
172  * @return copy of this bitmap with a different pixel format
173  */
174  public Bitmap clone(PixelFormat pixelFormat) {
175  return context.copyBitmap(this, pixelFormat);
176  }
177 
178 
179  /**
180  * Creates a bitmap containing a copy of a rectangular region
181  * @param region the region to copy
182  * @return the new bitmap
183  */
184  public Bitmap copyRegion(IntRectangle region) {
185  Bitmap copy = Bitmap.createByteAligned(context, region.getWidth(), region.getHeight(), getPixelFormat());
186  if (copy.getWidth() != region.getWidth())
187  copy.zero();
188  crop(handle, copy.handle, region.x1, region.y1, region.x2, region.y2, 0, 0);
189  return copy;
190  }
191 
192  /**
193  * Copies a rectangular area to another bitmap. The area size is equal to the target bitmap size.
194  * @param bitmap the target bitmap
195  * @param left source area top-left corner horizontal position in pixels
196  * @param top source area top-left corner vertical position in pixels
197  */
198  public void projectOn(Bitmap bitmap, int left, int top) {
199  crop(handle, bitmap.handle, left, top, left+bitmap.getWidth(), top+bitmap.getHeight(), 0, 0);
200  }
201 
202  /**
203  * Pixelwise bitmap inversion
204  */
205  public void invert() {
206  invert(handle);
207  }
208 
209  /**
210  * Transfers pixel data from GPU to CPU
211  */
212  public void pullPixels() {
214  }
215 
216  /**
217  * CoreException thrown when a native bitmap has incompatible pixel format
218  */
219  public static class BadPixelFormat extends IllegalArgumentException {
220  public BadPixelFormat(Config config) {
221  super("Pixel format not supported: " + (config == null ? "config is null" : config.toString()));
222  // config may be null for some bitmaps
223  }
224  }
225 }
CoreException thrown when a native bitmap has incompatible pixel format.
Definition: Bitmap.java:219
Bitmap wrapper.
Definition: Bitmap.java:32
void zero()
Sets all bitmap pixels to zero.
Definition: Bitmap.java:153
PixelFormat getPixelFormat()
Definition: Bitmap.java:145
static Bitmap createEmpty(Bitmap bitmap)
Creates an empty bitmap of the same size and pixel format as a given bitmap.
Definition: Bitmap.java:113
void invert()
Pixelwise bitmap inversion.
Definition: Bitmap.java:205
IntRectangle clientRectangle()
Definition: Bitmap.java:137
void pullPixels()
Transfers pixel data from GPU to CPU.
Definition: Bitmap.java:212
Bitmap clone(PixelFormat pixelFormat)
Definition: Bitmap.java:174
void projectOn(Bitmap bitmap, int left, int top)
Copies a rectangular area to another bitmap.
Definition: Bitmap.java:198
Bitmap copyRegion(IntRectangle region)
Creates a bitmap containing a copy of a rectangular region.
Definition: Bitmap.java:184
Bitmap clone()
Definition: Bitmap.java:166
int getHeight()
Definition: Bitmap.java:129
int getWidth()
Definition: Bitmap.java:121
Bitmap(Context context, android.graphics.Bitmap bitmap)
Creates new bitmap from Android bitmap object.
Definition: Bitmap.java:71
Bitmap(Context context, int width, int height, PixelFormat pixelFormat)
Creates new internally managed bitmap.
Definition: Bitmap.java:85
Beatmup engine context.
Definition: Context.java:34
void watchBitmap(Bitmap bitmap)
Adds a bitmap to the watch list.
Definition: Context.java:230
Integer-valued rectangle.
Base class for objects natively managed by Beatmup.
Definition: Object.java:24
long handle
pointer to the native object
Definition: Object.java:25
synchronized void dispose()
Destroys the native object.
Definition: Object.java:37
Enumeration of Beatmup pixel formats.