App
NBitmap.java
Go to the documentation of this file.
1 package mhr.appcore.bitmap;
2 
3 import mhr.appcore.bitmap.exceptions.BitmapAllocationException;
4 import mhr.appcore.bitmap.exceptions.UnsupportedBitmapException;
5 import mhr.appcore.exceptions.AlreadyDisposedException;
6 import mhr.appcore.interfaces.PDBitmap;
7 import mhr.appcore.utils.Rect;
8 
13 public class NBitmap {
14 
15 //----- Nativní metody ----------------------------------------------------------------------------------------------------------------------//
17  protected native long createTBitmap(int nativeType, int width, int height, int colorMode, boolean premultiplied);
19  protected native long createTBitmap(int nativeType, long adress);
21  protected native long wrapAsTBitmap(int nativeType, long adress, int width, int height, int colorMode, boolean premultiplied);
23  protected native int premultiply(int nativeType, long adress);
25  protected native int demultiply(int nativeType, long adress);
27  protected native long getChannel(int nativeType, long adress, int index);
29  protected native int fill(int nativeType, long adress, int tlx, int tly, int brx, int bry, int color);
31  protected native int copyTo(int nativeType, long adress, long dstAdress, int tlx, int tly, int brx, int bry, int srcOrigX, int srcOrigY);
33  protected native int dispose(int nativeType, long adress);
35  protected native int setPremultiplied(int nativeType, long adresss, boolean premultiplied);
36 
37 //----- Java pole ---------------------------------------------------------------------------------------------------------------------------//
38  protected BitmapInfo info = null;
39  protected NativeType nativeType = NativeType.INVALID_TYPE;
40  protected long adress = 0;
41  protected PDBitmap wrapped = null;
42 
46  protected NBitmap() {
47  }
48 
49 //----- Accessory a primitivní metody -------------------------------------------------------------------------------------------------------//
56  if (info == null) {
57  throw new AlreadyDisposedException("Bitmap is already disposed.");
58  }
59  return new BitmapInfo(info);
60  }
61 
68  if (info == null) {
69  throw new AlreadyDisposedException("Bitmap is already disposed.");
70  }
71  return info.getRect();
72  }
73 
79  public int getWidth() throws AlreadyDisposedException{
80  if (info == null) {
81  throw new AlreadyDisposedException("Bitmap is already disposed.");
82  }
83  return info.width;
84  }
85 
91  public int getHeight() throws AlreadyDisposedException{
92  if (info == null) {
93  throw new AlreadyDisposedException("Bitmap is already disposed.");
94  }
95  return info.height;
96  }
97 
102  public long getAdress() {
103  return adress;
104  }
105 
111  return nativeType;
112  }
113 
118  public void setPremultiplied(boolean premultiplied) throws AlreadyDisposedException {
119  if (info == null || adress == 0) {
120  throw new AlreadyDisposedException("Bitmap is already disposed.");
121  }
122  if (setPremultiplied(nativeType.getValue(), adress, premultiplied) != 0) {
123  throw new RuntimeException("Something went wrong.");
124  }
125  info.premultiplied = premultiplied;
126  }
127 //----- Konstruktory ------------------------------------------------------------------------------------------------------------------------//
135  nativeType = info.getNativeType();
136  if (nativeType == NativeType.INVALID_TYPE) {
137  throw new UnsupportedBitmapException("Specified parameters doesn't map to supported native type.");
138  }
139  adress = createTBitmap(nativeType.getValue(), info.width, info.height, info.colorMode.getValue(), info.premultiplied);
140  if (adress == 0) {
141  throw new BitmapAllocationException("Failed to allocate requested bitmap.");
142  }
143  this.info = new BitmapInfo(info); // Chceme vlastní kopii, pro všechny případy
144  }
145 
155  BitmapInfo info = wrap.getInfo();
156  NativeType tmpType = info.getNativeType();
157  if (tmpType == NativeType.INVALID_TYPE) {
158  throw new UnsupportedBitmapException("Supplied bitmap doesn't map to native type");
159  }
160  long wrapAdress = wrap.getAndLockData();
161  if (wrapAdress == 0) {
162  wrap.unlockData();
163  throw new BitmapAllocationException("Failed to get data adress from PDBitmap.");
164  }
165  adress = wrapAsTBitmap(tmpType.getValue(), wrapAdress, info.width, info.height, info.colorMode.getValue(), info.premultiplied);
166  if (adress == 0) {
167  wrap.unlockData();
168  throw new BitmapAllocationException("Failed to allocate requested bitmap.");
169  }
170  this.nativeType = tmpType;
171  this.wrapped = wrap;
172  this.info = new BitmapInfo(info);
173  }
174 
182  if (other.adress != 0) { // Platná bitmapa, protože šla alokovat a není disposed
183  adress = createTBitmap(other.nativeType.getValue(), other.adress);
184  if (adress == 0) {
185  throw new BitmapAllocationException("Failed to get data adress from PDBitmap.");
186  } else {
187  this.info = new BitmapInfo(other.info);
188  this.nativeType = other.nativeType;
189  }
190  } else {
191  throw new AlreadyDisposedException("Bitmap is already disposed.");
192  }
193  }
194 
202  public NBitmap(long adress, BitmapInfo info) throws NullPointerException, UnsupportedBitmapException{
203  if (adress == 0) {
204  throw new NullPointerException("Native adress could not be NULL");
205  }
206  nativeType = info.getNativeType();
207  if (nativeType == NativeType.INVALID_TYPE) {
208  throw new UnsupportedBitmapException("Supplied bitmap doesn't map to native type");
209  }
210  this.adress = adress;
211  this.info = new BitmapInfo(info);
212  }
213 
214 //----- Destruktory -------------------------------------------------------------------------------------------------------------------------//
221  public synchronized void dispose() {
222  if (wrapped != null) {
224  wrapped = null;
225  }
226  if (adress != 0) {
227  dispose(nativeType.getValue(), adress); // Neni problem s double free, C++ ví o tom, že je jen wrapper
228  adress = 0;
229  info = null;
230  }
231  nativeType = NativeType.INVALID_TYPE;
232  }
233 
235  @Override
236  protected void finalize() throws Throwable {
237  dispose();
238  super.finalize();
239  }
240 
241 //----- Metody ------------------------------------------------------------------------------------------------------------------------------//
242  public int cropTo(Rect r) throws AlreadyDisposedException {
243  Rect crop = r.cropBy(getRect()); // aby nepřesahoval, hodí výjimku alreadyDisposed
244  if (wrapped != null) {
245  throw new IllegalStateException("Cannot crop wrapped bitmap");
246  }
247  long newAdress = createTBitmap(nativeType.getValue(), crop.getWidth(), crop.getHeight(), info.colorMode.getValue(), info.premultiplied);
248  if (newAdress == 0) {
249  throw new BitmapAllocationException("Failed to allocate requested bitmap.");
250  }
251  int retVal = copyTo(nativeType.getValue(), adress, newAdress, crop.tlx, crop.tly, crop.brx, crop.bry, 0, 0);
252  dispose(nativeType.getValue(), adress);
253  adress = newAdress;
254  info.width = crop.getWidth();
255  info.height = crop.getHeight();
256  return retVal;
257  }
258 
264  public int premultiply() throws AlreadyDisposedException {
265  if (this.adress != 0) {
266  int retVal = premultiply(nativeType.getValue(), adress);
267  if (retVal == 0) {
268  this.info.premultiplied = true;
269  }
270  return retVal;
271  } else {
272  throw new AlreadyDisposedException("Bitmap is already disposed.");
273  }
274  }
275 
281  public int demultiply() throws AlreadyDisposedException {
282  if (this.adress != 0) {
283  int retVal = demultiply(nativeType.getValue(), adress);
284  if (retVal == 0) {
285  this.info.premultiplied = false;
286  }
287  return retVal;
288  } else {
289  throw new AlreadyDisposedException("Bitmap is already disposed.");
290  }
291  }
292 
301  public NBitmap getChannel(int index) throws BitmapAllocationException, IllegalArgumentException, AlreadyDisposedException{
302  NBitmap retVal = null;
303  if (this.adress != 0) {
305  long tmpAdress = getChannel(nativeType.getValue(), adress, index);
306  if (tmpAdress != 0) {
307  retVal = new NBitmap();
308  retVal.info = new BitmapInfo(info);
310  retVal.info.colorMode = ColorMode.MONO;
312  retVal.adress = tmpAdress;
313  retVal.wrapped = null;
314  } else {
315  throw new BitmapAllocationException("Could nod allocate bitmap.");
316  }
317  } else {
318  throw new IllegalArgumentException("Operation not applicable to single channel bitmap, make copy instead.");
319  }
320  } else {
321  throw new AlreadyDisposedException("Bitmap is already disposed.");
322  }
323  return retVal;
324  }
325 
336  public int copyTo(NBitmap dst, Rect srcRect, int srcOrigX, int srcOrigY) throws AlreadyDisposedException, IllegalArgumentException{
337  if (this.adress == 0 || dst.adress == 0) {
338  throw new AlreadyDisposedException("Bitmap is already disposed.");
339  }
340  if (this.nativeType != dst.nativeType) {
341  throw new IllegalArgumentException("Incompatible bitmaps.");
342  }
343  return copyTo(nativeType.getValue(), adress, dst.adress, srcRect.tlx, srcRect.tly, srcRect.brx, srcRect.bry, srcOrigX, srcOrigY);
344  }
345 
353  public int fill(Rect srcRect, int color) throws AlreadyDisposedException {
354  if (this.adress != 0) {
355  return fill(nativeType.getValue(), adress, srcRect.tlx, srcRect.tly, srcRect.brx, srcRect.bry, color);
356  } else {
357  throw new AlreadyDisposedException("Bitmap is already disposed.");
358  }
359  }
360 }