propane 3.8.0-java → 4.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -1
  3. data/.mvn/wrapper/maven-wrapper.properties +1 -1
  4. data/.travis.yml +1 -1
  5. data/CHANGELOG.md +7 -1
  6. data/README.md +7 -7
  7. data/Rakefile +6 -5
  8. data/lib/propane/app.rb +10 -17
  9. data/lib/propane/helper_methods.rb +6 -6
  10. data/lib/propane/version.rb +1 -1
  11. data/lib/propane-4.0.0.jar +0 -0
  12. data/library/pdf/itextpdf-5.5.13.2.jar +0 -0
  13. data/library/pdf/pdf.rb +7 -0
  14. data/library/slider/slider.rb +1 -1
  15. data/library/svg/batik-all-1.14.jar +0 -0
  16. data/library/svg/svg.rb +7 -0
  17. data/mvnw +3 -3
  18. data/mvnw.cmd +2 -2
  19. data/pom.rb +35 -8
  20. data/pom.xml +60 -9
  21. data/propane.gemspec +9 -7
  22. data/src/main/java/monkstone/ColorUtil.java +1 -1
  23. data/src/main/java/monkstone/FastNoiseModuleJava.java +127 -0
  24. data/src/main/java/monkstone/MathToolModule.java +31 -31
  25. data/src/main/java/monkstone/PropaneLibrary.java +3 -1
  26. data/src/main/java/monkstone/SmoothNoiseModuleJava.java +127 -0
  27. data/src/main/java/monkstone/fastmath/DegLutTables.java +25 -26
  28. data/src/main/java/monkstone/fastmath/Deglut.java +1 -1
  29. data/src/main/java/monkstone/filechooser/Chooser.java +2 -2
  30. data/src/main/java/monkstone/noise/LICENSE +121 -0
  31. data/src/main/java/monkstone/noise/OpenSimplex2F.java +914 -0
  32. data/src/main/java/monkstone/noise/OpenSimplex2S.java +1138 -0
  33. data/src/main/java/monkstone/slider/CustomHorizontalSlider.java +1 -1
  34. data/src/main/java/monkstone/slider/CustomVerticalSlider.java +1 -1
  35. data/src/main/java/monkstone/slider/SimpleHorizontalSlider.java +1 -1
  36. data/src/main/java/monkstone/slider/SimpleVerticalSlider.java +1 -1
  37. data/src/main/java/monkstone/slider/SliderBar.java +1 -1
  38. data/src/main/java/monkstone/slider/SliderGroup.java +1 -1
  39. data/src/main/java/monkstone/slider/WheelHandler.java +2 -2
  40. data/src/main/java/monkstone/vecmath/JRender.java +6 -6
  41. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  42. data/src/main/java/monkstone/vecmath/vec2/Vec2.java +103 -83
  43. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +27 -41
  44. data/src/main/java/monkstone/videoevent/CaptureEvent.java +1 -1
  45. data/src/main/java/monkstone/videoevent/MovieEvent.java +1 -1
  46. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  47. data/src/main/java/processing/awt/PGraphicsJava2D.java +11 -4
  48. data/src/main/java/processing/awt/PImageAWT.java +8 -8
  49. data/src/main/java/processing/core/PApplet.java +245 -254
  50. data/src/main/java/processing/core/PConstants.java +155 -163
  51. data/src/main/java/processing/core/PGraphics.java +116 -109
  52. data/src/main/java/processing/core/PImage.java +3025 -3047
  53. data/src/main/java/processing/core/PMatrix.java +5 -2
  54. data/src/main/java/processing/data/DoubleDict.java +72 -43
  55. data/src/main/java/processing/data/DoubleList.java +6 -2
  56. data/src/main/java/processing/data/FloatDict.java +744 -756
  57. data/src/main/java/processing/data/FloatList.java +68 -26
  58. data/src/main/java/processing/data/IntDict.java +72 -45
  59. data/src/main/java/processing/data/IntList.java +63 -26
  60. data/src/main/java/processing/data/JSONArray.java +892 -931
  61. data/src/main/java/processing/data/JSONObject.java +1169 -1262
  62. data/src/main/java/processing/data/JSONTokener.java +30 -49
  63. data/src/main/java/processing/data/LongDict.java +699 -712
  64. data/src/main/java/processing/data/LongList.java +676 -700
  65. data/src/main/java/processing/data/Sort.java +1 -0
  66. data/src/main/java/processing/data/Table.java +4040 -3661
  67. data/src/main/java/processing/data/TableRow.java +16 -0
  68. data/src/main/java/processing/data/XML.java +1041 -956
  69. data/src/main/java/processing/event/TouchEvent.java +1 -1
  70. data/src/main/java/processing/opengl/FontTexture.java +2 -2
  71. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +28 -31
  72. data/src/main/java/processing/opengl/PJOGL.java +8 -7
  73. data/src/main/java/processing/opengl/PShader.java +1 -6
  74. data/src/main/java/processing/opengl/PShapeOpenGL.java +23 -24
  75. data/src/main/java/processing/opengl/PSurfaceJOGL.java +6 -6
  76. data/src/main/java/processing/pdf/PGraphicsPDF.java +581 -0
  77. data/src/main/java/processing/svg/PGraphicsSVG.java +378 -0
  78. data/src/main/{java/processing/opengl → resources}/cursors/arrow.png +0 -0
  79. data/src/main/{java/processing/opengl → resources}/cursors/cross.png +0 -0
  80. data/src/main/{java/processing/opengl → resources}/cursors/hand.png +0 -0
  81. data/src/main/{java/processing/opengl → resources}/cursors/license.txt +0 -0
  82. data/src/main/{java/processing/opengl → resources}/cursors/move.png +0 -0
  83. data/src/main/{java/processing/opengl → resources}/cursors/text.png +0 -0
  84. data/src/main/{java/processing/opengl → resources}/cursors/wait.png +0 -0
  85. data/src/main/{java/processing/opengl → resources}/shaders/ColorFrag.glsl +0 -0
  86. data/src/main/{java/processing/opengl → resources}/shaders/ColorVert.glsl +0 -0
  87. data/src/main/{java/processing/opengl → resources}/shaders/LightFrag.glsl +0 -0
  88. data/src/main/{java/processing/opengl → resources}/shaders/LightVert.glsl +0 -0
  89. data/src/main/{java/processing/opengl → resources}/shaders/LineFrag.glsl +0 -0
  90. data/src/main/{java/processing/opengl → resources}/shaders/LineVert.glsl +0 -0
  91. data/src/main/{java/processing/opengl → resources}/shaders/MaskFrag.glsl +0 -0
  92. data/src/main/{java/processing/opengl → resources}/shaders/PointFrag.glsl +0 -0
  93. data/src/main/{java/processing/opengl → resources}/shaders/PointVert.glsl +0 -0
  94. data/src/main/{java/processing/opengl → resources}/shaders/TexFrag.glsl +0 -0
  95. data/src/main/{java/processing/opengl → resources}/shaders/TexLightFrag.glsl +0 -0
  96. data/src/main/{java/processing/opengl → resources}/shaders/TexLightVert.glsl +0 -0
  97. data/src/main/{java/processing/opengl → resources}/shaders/TexVert.glsl +0 -0
  98. data/test/test_helper.rb +1 -0
  99. data/test/vecmath_spec_test.rb +14 -3
  100. data/vendors/Rakefile +1 -1
  101. metadata +53 -53
  102. data/lib/propane-3.8.0.jar +0 -0
  103. data/src/main/java/monkstone/noise/Noise.java +0 -116
  104. data/src/main/java/monkstone/noise/NoiseGenerator.java +0 -63
  105. data/src/main/java/monkstone/noise/NoiseMode.java +0 -15
  106. data/src/main/java/monkstone/noise/SimplexNoise.java +0 -470
  107. data/src/main/java/monkstone/noise/ValueNoise.java +0 -170
@@ -1,7 +1,7 @@
1
1
  package monkstone.vecmath.vec3;
2
2
 
3
3
  /*
4
- * Copyright (c) 2015-20 Martin Prout
4
+ * Copyright (c) 2015-22 Martin Prout
5
5
  *
6
6
  * This library is free software; you can redistribute it and/or
7
7
  * modify it under the terms of the GNU Lesser General Public
@@ -65,7 +65,7 @@ public final class Vec3 extends RubyObject {
65
65
  * @return new Vec3 object (ruby)
66
66
  */
67
67
  @JRubyMethod(name = "new", meta = true, rest = true)
68
- public final static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject... args) {
68
+ public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject... args) {
69
69
  Vec3 vec = (Vec3) ((RubyClass) klazz).allocate();
70
70
  vec.init(context, args);
71
71
  return vec;
@@ -83,27 +83,27 @@ public final class Vec3 extends RubyObject {
83
83
  void init(ThreadContext context, IRubyObject... args) {
84
84
  int count = args.length;
85
85
  if (count >= 2) {
86
- jx = (args[0] instanceof RubyFloat)
86
+ jx = args[0] instanceof RubyFloat
87
87
  ? ((RubyFloat) args[0]).getValue() : ((RubyFixnum) args[0]).getDoubleValue();
88
- jy = (args[1] instanceof RubyFloat)
88
+ jy = args[1] instanceof RubyFloat
89
89
  ? ((RubyFloat) args[1]).getValue() : ((RubyFixnum) args[1]).getDoubleValue();
90
90
  }
91
91
  if (count == 3) {
92
- jz = (args[2] instanceof RubyFloat)
92
+ jz = args[2] instanceof RubyFloat
93
93
  ? ((RubyFloat) args[2]).getValue() : ((RubyFixnum) args[2]).getDoubleValue();
94
94
  } // allow ruby ducktyping in constructor
95
95
  if (count == 1) {
96
96
  if (!(args[0].respondsTo("x"))) {
97
97
  throw context.runtime.newTypeError(args[0].getType() + " doesn't respond_to :x & :y");
98
98
  }
99
- jx = ((args[0].callMethod(context, "x")) instanceof RubyFloat)
99
+ jx = (args[0].callMethod(context, "x")) instanceof RubyFloat
100
100
  ? ((RubyFloat) args[0].callMethod(context, "x")).getValue() : ((RubyFixnum) args[0].callMethod(context, "x")).getDoubleValue();
101
- jy = ((args[0].callMethod(context, "y")) instanceof RubyFloat)
101
+ jy = (args[0].callMethod(context, "y")) instanceof RubyFloat
102
102
  ? ((RubyFloat) args[0].callMethod(context, "y")).getValue() : ((RubyFixnum) args[0].callMethod(context, "y")).getDoubleValue();
103
103
  if (!(args[0].respondsTo("z"))) {
104
104
  return;
105
105
  } // allow promotion from 2D to 3D, sets jz = 0
106
- jz = ((args[0].callMethod(context, "z")) instanceof RubyFloat) ? ((RubyFloat) args[0].callMethod(context, "z")).getValue() : ((RubyFixnum) args[0].callMethod(context, "z")).getDoubleValue();
106
+ jz = (args[0].callMethod(context, "z")) instanceof RubyFloat ? ((RubyFloat) args[0].callMethod(context, "z")).getValue() : ((RubyFixnum) args[0].callMethod(context, "z")).getDoubleValue();
107
107
  }
108
108
  }
109
109
 
@@ -147,11 +147,7 @@ public final class Vec3 extends RubyObject {
147
147
  */
148
148
  @JRubyMethod(name = "x=")
149
149
  public IRubyObject setX(ThreadContext context, IRubyObject other) {
150
- if (other instanceof RubyFloat) {
151
- jx = ((RubyFloat) other).getValue();
152
- } else {
153
- jx = ((RubyFixnum) other).getDoubleValue();
154
- }
150
+ jx = other instanceof RubyFloat ? ((RubyFloat) other).getValue() : ((RubyFixnum) other).getDoubleValue();
155
151
  return other;
156
152
  }
157
153
 
@@ -163,11 +159,7 @@ public final class Vec3 extends RubyObject {
163
159
  */
164
160
  @JRubyMethod(name = "y=")
165
161
  public IRubyObject setY(ThreadContext context, IRubyObject other) {
166
- if (other instanceof RubyFloat) {
167
- jy = ((RubyFloat) other).getValue();
168
- } else {
169
- jy = ((RubyFixnum) other).getDoubleValue();
170
- }
162
+ jy = other instanceof RubyFloat ? ((RubyFloat) other).getValue() : ((RubyFixnum) other).getDoubleValue();
171
163
  return other;
172
164
  }
173
165
 
@@ -179,11 +171,7 @@ public final class Vec3 extends RubyObject {
179
171
  */
180
172
  @JRubyMethod(name = "z=")
181
173
  public IRubyObject setZ(ThreadContext context, IRubyObject other) {
182
- if (other instanceof RubyFloat) {
183
- jz = ((RubyFloat) other).getValue();
184
- } else {
185
- jz = ((RubyFixnum) other).getDoubleValue();
186
- }
174
+ jz = other instanceof RubyFloat ? ((RubyFloat) other).getValue() : ((RubyFixnum) other).getDoubleValue();
187
175
  return other;
188
176
  }
189
177
 
@@ -222,13 +210,13 @@ public final class Vec3 extends RubyObject {
222
210
  Ruby runtime = context.runtime;
223
211
  if (key instanceof RubySymbol) {
224
212
  if (key == RubySymbol.newSymbol(runtime, "x")) {
225
- jx = (value instanceof RubyFloat)
213
+ jx = value instanceof RubyFloat
226
214
  ? ((RubyFloat) value).getValue() : ((RubyFixnum) value).getDoubleValue();
227
215
  } else if (key == RubySymbol.newSymbol(runtime, "y")) {
228
- jy = (value instanceof RubyFloat)
216
+ jy = value instanceof RubyFloat
229
217
  ? ((RubyFloat) value).getValue() : ((RubyFixnum) value).getDoubleValue();
230
218
  } else if (key == RubySymbol.newSymbol(runtime, "z")) {
231
- jz = (value instanceof RubyFloat)
219
+ jz = value instanceof RubyFloat
232
220
  ? ((RubyFloat) value).getValue() : ((RubyFixnum) value).getDoubleValue();
233
221
  } else {
234
222
  throw runtime.newIndexError("invalid key");
@@ -368,7 +356,7 @@ public final class Vec3 extends RubyObject {
368
356
  @JRubyMethod(name = "*", required = 1)
369
357
  public IRubyObject op_mul(ThreadContext context, IRubyObject scalar) {
370
358
  Ruby runtime = context.runtime;
371
- double multi = (scalar instanceof RubyFloat)
359
+ double multi = scalar instanceof RubyFloat
372
360
  ? ((RubyFloat) scalar).getValue() : ((RubyFixnum) scalar).getDoubleValue();
373
361
  return Vec3.rbNew(context, this.getMetaClass(), new IRubyObject[]{
374
362
  runtime.newFloat(jx * multi),
@@ -385,7 +373,7 @@ public final class Vec3 extends RubyObject {
385
373
  @JRubyMethod(name = "/", required = 1)
386
374
  public IRubyObject op_div(ThreadContext context, IRubyObject scalar) {
387
375
  Ruby runtime = context.runtime;
388
- double divisor = (scalar instanceof RubyFloat)
376
+ double divisor = scalar instanceof RubyFloat
389
377
  ? ((RubyFloat) scalar).getValue() : ((RubyFixnum) scalar).getDoubleValue();
390
378
  if (Math.abs(divisor) < Vec3.EPSILON) {
391
379
  return this;
@@ -427,12 +415,10 @@ public final class Vec3 extends RubyObject {
427
415
  */
428
416
  @JRubyMethod(name = "set_mag")
429
417
  public IRubyObject set_mag(ThreadContext context, IRubyObject scalar, Block block) {
430
- if (block.isGiven()) {
431
- if (!(boolean) block.yield(context, scalar).toJava(Boolean.class)) {
432
- return this;
433
- }
418
+ if (block.isGiven() && !block.yield(context, scalar).toJava(Boolean.class)) {
419
+ return this;
434
420
  }
435
- double new_mag = (scalar instanceof RubyFloat)
421
+ double new_mag = scalar instanceof RubyFloat
436
422
  ? ((RubyFloat) scalar).getValue() : ((RubyFixnum) scalar).getDoubleValue();
437
423
  double current = Math.sqrt(jx * jx + jy * jy + jz * jz);
438
424
  if (current > EPSILON) {
@@ -598,9 +584,9 @@ public final class Vec3 extends RubyObject {
598
584
  double u = 0;
599
585
  double v = 0;
600
586
  if (count == 3) {
601
- u = (args[1] instanceof RubyFloat)
587
+ u = args[1] instanceof RubyFloat
602
588
  ? ((RubyFloat) args[1]).getValue() : ((RubyFixnum) args[1]).getDoubleValue();
603
- v = (args[2] instanceof RubyFloat)
589
+ v = args[2] instanceof RubyFloat
604
590
  ? ((RubyFloat) args[2]).getValue() : ((RubyFixnum) args[2]).getDoubleValue();
605
591
  }
606
592
  if (count == 2) {
@@ -662,9 +648,9 @@ public final class Vec3 extends RubyObject {
662
648
  }
663
649
  if (obj instanceof Vec3) {
664
650
  final Vec3 other = (Vec3) obj;
665
- if ((Double.compare(jx, (Double) other.jx) == 0)
666
- && (Double.compare(jy, (Double) other.jy) == 0)
667
- && (Double.compare(jz, (Double) other.jz) == 0)) {
651
+ if (Double.compare(jx, (Double) other.jx) == 0
652
+ && Double.compare(jy, (Double) other.jy) == 0
653
+ && Double.compare(jz, (Double) other.jz) == 0) {
668
654
  return true;
669
655
  }
670
656
 
@@ -686,9 +672,9 @@ public final class Vec3 extends RubyObject {
686
672
  }
687
673
  if (other instanceof Vec3) {
688
674
  Vec3 v = (Vec3) other.toJava(Vec3.class);
689
- if ((Double.compare(jx, (Double) v.jx) == 0)
690
- && (Double.compare(jy, (Double) v.jy) == 0)
691
- && (Double.compare(jz, (Double) v.jz) == 0)) {
675
+ if (Double.compare(jx, (Double) v.jx) == 0
676
+ && Double.compare(jy, (Double) v.jy) == 0
677
+ && Double.compare(jz, (Double) v.jz) == 0) {
692
678
  return runtime.newBoolean(true);
693
679
  }
694
680
 
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2015-20 Martin Prout
2
+ * Copyright (c) 2015-22 Martin Prout
3
3
  *
4
4
  * This library is free software; you can redistribute it and/or
5
5
  * modify it under the terms of the GNU Lesser General Public
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2015-20 Martin Prout
2
+ * Copyright (c) 2015-22 Martin Prout
3
3
  *
4
4
  * This library is free software; you can redistribute it and/or
5
5
  * modify it under the terms of the GNU Lesser General Public
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2015-20 Martin Prout
2
+ * Copyright (c) 2015-22 Martin Prout
3
3
  *
4
4
  * This library is free software; you can redistribute it and/or
5
5
  * modify it under the terms of the GNU Lesser General Public
@@ -31,7 +31,6 @@ import java.awt.image.*;
31
31
  import java.util.Arrays;
32
32
  import java.util.HashMap;
33
33
  import java.util.Map;
34
-
35
34
  import processing.core.*;
36
35
 
37
36
 
@@ -1564,6 +1563,15 @@ public class PGraphicsJava2D extends PGraphics {
1564
1563
 
1565
1564
  /**
1566
1565
  * Handle renderer-specific image drawing.
1566
+ * @param who
1567
+ * @param x1
1568
+ * @param y1
1569
+ * @param x2
1570
+ * @param y2
1571
+ * @param u1
1572
+ * @param v1
1573
+ * @param u2
1574
+ * @param v2
1567
1575
  */
1568
1576
  @Override
1569
1577
  protected void imageImpl(PImage who,
@@ -2575,7 +2583,7 @@ public class PGraphicsJava2D extends PGraphics {
2575
2583
  // WritableRaster raster = ((BufferedImage) image).getRaster();
2576
2584
  // WritableRaster raster = image.getRaster();
2577
2585
  WritableRaster raster = getRaster();
2578
- if ((clearPixels == null) || (clearPixels.length < imageWidth)) {
2586
+ if (clearPixels == null || clearPixels.length < imageWidth) {
2579
2587
  clearPixels = new int[imageWidth];
2580
2588
  }
2581
2589
  Arrays.fill(clearPixels, 0, imageWidth, backgroundColor);
@@ -2595,7 +2603,6 @@ public class PGraphicsJava2D extends PGraphics {
2595
2603
  public void backgroundImpl() {
2596
2604
  if (backgroundAlpha) {
2597
2605
  clearPixels(backgroundColor);
2598
-
2599
2606
  } else {
2600
2607
  Color bgColor = new Color(backgroundColor);
2601
2608
  // seems to fire an additional event that causes flickering,
@@ -2798,7 +2805,7 @@ public class PGraphicsJava2D extends PGraphics {
2798
2805
  public void updatePixels(int x, int y, int c, int d) {
2799
2806
  //if ((x == 0) && (y == 0) && (c == width) && (d == height)) {
2800
2807
  // System.err.format("%d %d %d %d .. w/h = %d %d .. pw/ph = %d %d %n", x, y, c, d, width, height, pixelWidth, pixelHeight);
2801
- if ((x != 0) || (y != 0) || (c != pixelWidth) || (d != pixelHeight)) {
2808
+ if (x != 0 || y != 0 || c != pixelWidth || d != pixelHeight) {
2802
2809
  // Show a warning message, but continue anyway.
2803
2810
  showVariationWarning("updatePixels(x, y, w, h)");
2804
2811
  // new Exception().printStackTrace(System.out);
@@ -35,7 +35,6 @@ import java.io.BufferedOutputStream;
35
35
  import java.io.File;
36
36
  import java.io.IOException;
37
37
  import java.util.Iterator;
38
-
39
38
  import javax.imageio.IIOImage;
40
39
  import javax.imageio.ImageIO;
41
40
  import javax.imageio.ImageTypeSpecifier;
@@ -44,7 +43,6 @@ import javax.imageio.ImageWriter;
44
43
  import javax.imageio.metadata.IIOInvalidTreeException;
45
44
  import javax.imageio.metadata.IIOMetadata;
46
45
  import javax.imageio.metadata.IIOMetadataNode;
47
-
48
46
  import processing.core.PApplet;
49
47
  import processing.core.PImage;
50
48
 
@@ -108,8 +106,8 @@ public class PImageAWT extends PImage {
108
106
 
109
107
  /**
110
108
  * Use the getNative() method instead, which allows library interfaces to be
111
- * written in a cross-platform fashion for desktop, Android, and others.
112
- * This is still included for PGraphics objects, which may need the image.
109
+ * written in a cross-platform fashion for desktop, Android, and others.This is still included for PGraphics objects, which may need the image.
110
+ * @return
113
111
  */
114
112
  public Image getImage() { // ignore
115
113
  return (Image) getNative();
@@ -118,6 +116,7 @@ public class PImageAWT extends PImage {
118
116
 
119
117
  /**
120
118
  * Returns a native BufferedImage from this PImage.
119
+ * @return
121
120
  */
122
121
  @Override
123
122
  public Object getNative() { // ignore
@@ -259,11 +258,12 @@ public class PImageAWT extends PImage {
259
258
 
260
259
 
261
260
  /**
262
- * Use ImageIO functions from Java 1.4 and later to handle image save.
263
- * Various formats are supported, typically jpeg, png, bmp, and wbmp.
264
- * To get a list of the supported formats for writing, use: <BR>
265
- * <TT>println(javax.imageio.ImageIO.getReaderFormatNames())</TT>
261
+ * Use ImageIO functions from Java 1.4 and later to handle image save.Various formats are supported, typically jpeg, png, bmp, and wbmp.To get a list of the supported formats for writing, use: <BR>
262
+ <code>println(javax.imageio.ImageIO.getReaderFormatNames())</code>
266
263
  *
264
+ * @param path
265
+ * @return
266
+ * @throws java.io.IOException
267
267
  * @path The path to which the file should be written.
268
268
  */
269
269
  protected boolean saveImageIO(String path) throws IOException {