picrate 2.1.2-java → 2.4.2-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -1
  3. data/CHANGELOG.md +8 -0
  4. data/README.md +3 -2
  5. data/Rakefile +2 -1
  6. data/docs/_includes/footer.html +1 -1
  7. data/docs/_layouts/post.html +1 -1
  8. data/docs/_methods/noise_mode.md +88 -0
  9. data/docs/_posts/2018-05-06-install_jruby.md +1 -1
  10. data/docs/_posts/2018-11-18-building-gem.md +3 -1
  11. data/docs/classes.md +2 -2
  12. data/docs/editors.md +2 -2
  13. data/docs/gems.md +3 -3
  14. data/docs/index.html +1 -1
  15. data/docs/libraries.md +2 -2
  16. data/docs/live.md +2 -2
  17. data/docs/magic.md +2 -2
  18. data/docs/methods.md +2 -2
  19. data/docs/modules.md +3 -3
  20. data/docs/objects.md +2 -2
  21. data/lib/picrate/app.rb +7 -6
  22. data/lib/picrate/native_folder.rb +1 -3
  23. data/lib/picrate/version.rb +1 -1
  24. data/library/pdf/pdf.rb +7 -0
  25. data/library/svg/svg.rb +7 -0
  26. data/picrate.gemspec +5 -3
  27. data/pom.rb +25 -4
  28. data/pom.xml +39 -4
  29. data/src/main/java/monkstone/FastNoiseModuleJava.java +127 -0
  30. data/src/main/java/monkstone/PicrateLibrary.java +3 -1
  31. data/src/main/java/monkstone/SmoothNoiseModuleJava.java +127 -0
  32. data/src/main/java/monkstone/fastmath/DegLutTables.java +111 -0
  33. data/src/main/java/monkstone/fastmath/Deglut.java +41 -93
  34. data/src/main/java/monkstone/noise/OpenSimplex2F.java +914 -0
  35. data/src/main/java/monkstone/noise/OpenSimplex2S.java +1138 -0
  36. data/src/main/java/monkstone/vecmath/package-info.java +1 -1
  37. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +1 -1
  38. data/src/main/java/monkstone/videoevent/package-info.java +1 -1
  39. data/src/main/java/processing/awt/ShimAWT.java +260 -94
  40. data/src/main/java/processing/core/PApplet.java +14664 -13450
  41. data/src/main/java/processing/core/PConstants.java +5 -5
  42. data/src/main/java/processing/core/PFont.java +1 -1
  43. data/src/main/java/processing/core/PGraphics.java +200 -201
  44. data/src/main/java/processing/core/PImage.java +539 -549
  45. data/src/main/java/processing/core/PShape.java +18 -18
  46. data/src/main/java/processing/core/PVector.java +23 -23
  47. data/src/main/java/processing/data/Table.java +4 -4
  48. data/src/main/java/processing/net/Client.java +13 -13
  49. data/src/main/java/processing/net/Server.java +5 -5
  50. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +4 -4
  51. data/src/main/java/processing/pdf/PGraphicsPDF.java +529 -0
  52. data/src/main/java/processing/svg/PGraphicsSVG.java +378 -0
  53. data/test/deglut_spec_test.rb +2 -2
  54. data/test/respond_to_test.rb +0 -2
  55. data/test/test_helper.rb +1 -1
  56. data/vendors/Rakefile +1 -1
  57. metadata +26 -15
  58. data/src/main/java/monkstone/noise/SimplexNoise.java +0 -465
@@ -31,27 +31,30 @@ import java.io.IOException;
31
31
  import java.io.InputStream;
32
32
  import java.io.OutputStream;
33
33
 
34
+ import processing.awt.ShimAWT;
35
+
34
36
 
35
37
  /**
36
- * ( begin auto-generated from PImage.xml )
37
- *
38
- * Datatype for storing images. Processing can display <b>.gif</b>,
39
- * <b>.jpg</b>, <b>.tga</b>, and <b>.png</b> images. Images may be
40
- * displayed in 2D and 3D space. Before an image is used, it must be loaded
41
- * with the <b>loadImage()</b> function. The <b>PImage</b> class contains
42
- * fields for the <b>width</b> and <b>height</b> of the image, as well as
43
- * an array called <b>pixels[]</b> that contains the values for every pixel
44
- * in the image. The methods described below allow easy access to the
45
- * image's pixels and alpha channel and simplify the process of compositing.
46
- * using the <b>pixels[]</b> array, be sure to use the
47
- * <b>loadPixels()</b> method on the image to make sure that the pixel data
48
- * is properly loaded.
49
- * create a new image, use the <b>createImage()</b> function. Do not
50
- * use the syntax <b>new PImage()</b>.
51
- *
52
- * ( end auto-generated )
53
- *
38
+ *
39
+ * Datatype for storing images. Processing can display <b>.gif</b>, <b>.jpg</b>,
40
+ * <b>.tga</b>, and <b>.png</b> images. Images may be displayed in 2D and 3D
41
+ * space. Before an image is used, it must be loaded with the <b>loadImage()</b>
42
+ * function. The <b>PImage</b> class contains fields for the <b>width</b> and
43
+ * <b>height</b> of the image, as well as an array called <b>pixels[]</b> that
44
+ * contains the values for every pixel in the image. The methods described below
45
+ * allow easy access to the image's pixels and alpha channel and simplify the
46
+ * process of compositing.<br />
47
+ * <br />
48
+ * Before using the <b>pixels[]</b> array, be sure to use the
49
+ * <b>loadPixels()</b> method on the image to make sure that the pixel data is
50
+ * properly loaded.<br />
51
+ * <br />
52
+ * To create a new image, use the <b>createImage()</b> function. Do not use the
53
+ * syntax <b>new PImage()</b>.
54
+ *
55
+ *
54
56
  * @webref image
57
+ * @webBrief Datatype for storing images.
55
58
  * @usage Web &amp; Application
56
59
  * @instanceName pimg any object of type PImage
57
60
  * @see PApplet#loadImage(String)
@@ -60,7 +63,7 @@ import java.io.OutputStream;
60
63
  */
61
64
  public class PImage implements PConstants, Cloneable {
62
65
 
63
- private static final byte TIFF_HEADER[] = {
66
+ private static final byte[] TIFF_HEADER = {
64
67
  77, 77, 0, 42, 0, 0, 0, 8, 0, 9, 0, -2, 0, 4, 0, 0, 0, 1, 0, 0,
65
68
  0, 0, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 3, 0, 0, 0, 1,
66
69
  0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 3, 0, 0, 0, 122, 1, 6, 0, 3, 0,
@@ -79,28 +82,22 @@ public class PImage implements PConstants, Cloneable {
79
82
  public int format;
80
83
 
81
84
  /**
82
- * ( begin auto-generated from pixels.xml )
83
- *
84
- * Array containing the values for all the pixels in the display window.
85
- * These values are of the color datatype. This array is the size of the
86
- * display window. For example, if the image is 100x100 pixels, there will
87
- * be 10000 values and if the window is 200x300 pixels, there will be 60000
88
- * values. The <b>index</b> value defines the position of a value within
89
- * the array. For example, the statement <b>color b = pixels[230]</b> will
90
- * set the variable <b>b</b> to be equal to the value at that location in
91
- * the array.
92
85
  *
86
+ * The pixels[] array contains the values for all the pixels in the image. These
87
+ * values are of the color datatype. This array is the size of the image,
88
+ * meaning if the image is 100 x 100 pixels, there will be 10,000 values and if
89
+ * the window is 200 x 300 pixels, there will be 60,000 values. <br />
90
+ * <br />
93
91
  * Before accessing this array, the data must loaded with the
94
- * <b>loadPixels()</b> function. After the array data has been modified,
95
- * the <b>updatePixels()</b> function must be run to update the changes.
96
- * Without <b>loadPixels()</b>, running the code may (or will in future
97
- * releases) result in a NullPointerException.
92
+ * <b>loadPixels()</b> method. Failure to do so may result in a
93
+ * NullPointerException. After the array data has been modified, the
94
+ * <b>updatePixels()</b> method must be run to update the content of the display
95
+ * window.
98
96
  *
99
- * ( end auto-generated )
100
97
  *
101
98
  * @webref image:pixels
99
+ * @webBrief Array containing the color of every pixel in the image.
102
100
  * @usage web_application
103
- * @brief Array containing the color of every pixel in the image
104
101
  */
105
102
  public int[] pixels;
106
103
 
@@ -112,26 +109,22 @@ public class PImage implements PConstants, Cloneable {
112
109
  public int pixelHeight;
113
110
 
114
111
  /**
115
- * ( begin auto-generated from PImage_width.xml )
116
112
  *
117
113
  * The width of the image in units of pixels.
118
114
  *
119
- * ( end auto-generated )
120
115
  * @webref pimage:field
116
+ * @webBrief The width of the image in units of pixels.
121
117
  * @usage web_application
122
- * @brief Image width
123
118
  */
124
119
  public int width;
125
120
 
126
121
  /**
127
- * ( begin auto-generated from PImage_height.xml )
128
122
  *
129
123
  * The height of the image in units of pixels.
130
124
  *
131
- * ( end auto-generated )
132
125
  * @webref pimage:field
126
+ * @webBrief The height of the image in units of pixels.
133
127
  * @usage web_application
134
- * @brief Image height
135
128
  */
136
129
  public int height;
137
130
 
@@ -155,14 +148,11 @@ public class PImage implements PConstants, Cloneable {
155
148
  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
156
149
 
157
150
 
158
- // private fields
159
- private int fracU, ifU, fracV, ifV, u1, u2, v1, v2, sX, sY, iw, iw1, ih1;
160
- private int ul, ll, ur, lr, cUL, cLL, cUR, cLR;
151
+ private int ifV, sX, v1, v2, iw, iw1, ih1;
161
152
  private int srcXOffset, srcYOffset;
162
- private int r, g, b, a;
163
153
  private int[] srcBuffer;
164
154
 
165
- // fixed point precision is limited to 15 bits!!
155
+ // fixed point precision is limited to 15 bits
166
156
  static final int PRECISIONB = 15;
167
157
  static final int PRECISIONF = 1 << PRECISIONB;
168
158
  static final int PREC_MAXVAL = PRECISIONF-1;
@@ -197,14 +187,13 @@ public class PImage implements PConstants, Cloneable {
197
187
  * pixel in the image. A group of methods, described below, allow easy
198
188
  * access to the image's pixels and alpha channel and simplify the process
199
189
  * of compositing.
200
- *
190
+ * <br/> <br/>
201
191
  * Before using the <b>pixels[]</b> array, be sure to use the
202
192
  * <b>loadPixels()</b> method on the image to make sure that the pixel data
203
193
  * is properly loaded.
204
- *
194
+ * <br/> <br/>
205
195
  * To create a new image, use the <b>createImage()</b> function (do not use
206
196
  * <b>new PImage()</b>).
207
- * ( end auto-generated )
208
197
  * @nowebref
209
198
  * @usage web_application
210
199
  * @see PApplet#loadImage(String, String)
@@ -213,7 +202,6 @@ public class PImage implements PConstants, Cloneable {
213
202
  */
214
203
  public PImage() {
215
204
  format = ARGB; // default to ARGB images for release 0116
216
- pixelDensity = 1;
217
205
  }
218
206
 
219
207
 
@@ -228,7 +216,7 @@ public class PImage implements PConstants, Cloneable {
228
216
  // toxi: is it maybe better to init the image with max alpha enabled?
229
217
  //for(int i=0; i<pixels.length; i++) pixels[i]=0xffffffff;
230
218
  // fry: i'm opting for the full transparent image, which is how
231
- // photoshop works, and our audience oughta be familiar with.
219
+ // photoshop works, and our audience will likely be familiar with.
232
220
  // also, i want to avoid having to set all those pixels since
233
221
  // in java it's super slow, and most using this fxn will be
234
222
  // setting all the pixels anyway.
@@ -296,15 +284,10 @@ public class PImage implements PConstants, Cloneable {
296
284
 
297
285
  //////////////////////////////////////////////////////////////
298
286
 
299
- public PImage(int width, int height, int[] pixels, boolean requiresCheckAlpha, PApplet parent) {
300
- initFromPixels(
301
- width,
302
- height,
303
- pixels,
304
- RGB,
305
- 1
306
- );
307
287
 
288
+ public PImage(int width, int height, int[] pixels,
289
+ boolean requiresCheckAlpha, PApplet parent) {
290
+ initFromPixels(width, height, pixels, RGB,1);
308
291
  this.parent = parent;
309
292
 
310
293
  if (requiresCheckAlpha) {
@@ -312,7 +295,8 @@ public class PImage implements PConstants, Cloneable {
312
295
  }
313
296
  }
314
297
 
315
- public PImage(int width, int height, int[] pixels, boolean requiresCheckAlpha, PApplet parent,
298
+ public PImage(int width, int height, int[] pixels,
299
+ boolean requiresCheckAlpha, PApplet parent,
316
300
  int format, int factor) {
317
301
 
318
302
  initFromPixels(width, height, pixels, format, factor);
@@ -382,28 +366,20 @@ public class PImage implements PConstants, Cloneable {
382
366
 
383
367
 
384
368
  /**
385
- * ( begin auto-generated from PImage_loadPixels.xml )
386
- *
387
- * Loads the pixel data for the image into its <b>pixels[]</b> array. This
388
- * function must always be called before reading from or writing to <b>pixels[]</b>.
389
- * renderers may or may not seem to require <b>loadPixels()</b>
390
- * or <b>updatePixels()</b>. However, the rule is that any time you want to
391
- * manipulate the <b>pixels[]</b> array, you must first call
392
- * <b>loadPixels()</b>, and after changes have been made, call
393
- * <b>updatePixels()</b>. Even if the renderer may not seem to use this
394
- * function in the current Processing release, this will always be subject
395
- * to change.
396
369
  *
397
- * ( end auto-generated )
370
+ * Loads the pixel data of the current display window into the <b>pixels[]</b>
371
+ * array. This function must always be called before reading from or writing to
372
+ * <b>pixels[]</b>. Subsequent changes to the display window will not be
373
+ * reflected in <b>pixels</b> until <b>loadPixels()</b> is called again.
398
374
  *
399
- * <h3>Advanced</h3>
400
- * Call this when you want to mess with the pixels[] array.
401
375
  *
402
- * For subclasses where the pixels[] buffer isn't set by default,
403
- * this should copy all data into the pixels[] array
376
+ * <h3>Advanced</h3> Call this when you want to mess with the pixels[] array.
377
+ * <p/>
378
+ * For subclasses where the pixels[] buffer isn't set by default, this should
379
+ * copy all data into the pixels[] array
404
380
  *
405
381
  * @webref pimage:pixels
406
- * @brief Loads the pixel data for the image into its pixels[] array
382
+ * @webBrief Loads the pixel data for the image into its <b>pixels[]</b> array.
407
383
  * @usage web_application
408
384
  */
409
385
  public void loadPixels() { // ignore
@@ -420,30 +396,19 @@ public class PImage implements PConstants, Cloneable {
420
396
 
421
397
 
422
398
  /**
423
- * ( begin auto-generated from PImage_updatePixels.xml )
424
- *
425
- * Updates the image with the data in its <b>pixels[]</b> array. Use in
426
- * conjunction with <b>loadPixels()</b>. If you're only reading pixels from
427
- * the array, there's no need to call <b>updatePixels()</b>.
428
- * renderers may or may not seem to require <b>loadPixels()</b>
429
- * or <b>updatePixels()</b>. However, the rule is that any time you want to
430
- * manipulate the <b>pixels[]</b> array, you must first call
431
- * <b>loadPixels()</b>, and after changes have been made, call
432
- * <b>updatePixels()</b>. Even if the renderer may not seem to use this
433
- * function in the current Processing release, this will always be subject
434
- * to change.
435
- *
436
- * Currently, none of the renderers use the additional parameters to
437
- * <b>updatePixels()</b>, however this may be implemented in the future.
438
- *
439
- * ( end auto-generated )
440
- * <h3>Advanced</h3>
441
- * Mark the pixels in this region as needing an update.
442
- * This is not currently used by any of the renderers, however the api
443
- * is structured this way in the hope of being able to use this to
444
- * speed things up in the future.
399
+ *
400
+ * Updates the display window with the data in the <b>pixels[]</b> array. Use in
401
+ * conjunction with <b>loadPixels()</b>. If you're only reading pixels from the
402
+ * array, there's no need to call <b>updatePixels()</b> &mdash; updating is only
403
+ * necessary to apply changes.
404
+ *
405
+ * <h3>Advanced</h3> Mark the pixels in this region as needing an update. This
406
+ * is not currently used by any of the renderers, however the api is structured
407
+ * this way in the hope of being able to use this to speed things up in the
408
+ * future.
409
+ *
445
410
  * @webref pimage:pixels
446
- * @brief Updates the image with the data in its pixels[] array
411
+ * @webBrief Updates the image with the data in its <b>pixels[]</b> array.
447
412
  * @usage web_application
448
413
  * @param x x-coordinate of the upper-left corner
449
414
  * @param y y-coordinate of the upper-left corner
@@ -495,13 +460,12 @@ public class PImage implements PConstants, Cloneable {
495
460
 
496
461
 
497
462
  /**
498
- * ( begin auto-generated from PImage_resize.xml )
499
463
  *
500
464
  * Resize the image to a new width and height. To make the image scale
501
465
  * proportionally, use 0 as the value for the <b>wide</b> or <b>high</b>
502
466
  * parameter. For instance, to make the width of an image 150 pixels, and
503
- * change the height using the same proportion, use resize(150, 0).
504
- *
467
+ * change the height using the same proportion, use resize(150, 0).<br />
468
+ * <br />
505
469
  * Even though a PGraphics is technically a PImage, it is not possible to
506
470
  * rescale the image data found in a PGraphics. (It's simply not possible
507
471
  * to do this consistently across renderers: technically infeasible with
@@ -509,9 +473,8 @@ public class PImage implements PConstants, Cloneable {
509
473
  * content, first get a copy of its image data using the <b>get()</b>
510
474
  * method, and call <b>resize()</b> on the PImage that is returned.
511
475
  *
512
- * ( end auto-generated )
513
476
  * @webref pimage:method
514
- * @brief Changes the size of an image to a new width and height
477
+ * @webBrief Resize the image to a new width and height.
515
478
  * @usage web_application
516
479
  * @param w the resized image width
517
480
  * @param h the resized image height
@@ -548,7 +511,6 @@ public class PImage implements PConstants, Cloneable {
548
511
 
549
512
 
550
513
  /**
551
- * ( begin auto-generated from PImage_get.xml )
552
514
  *
553
515
  * Reads the color of any pixel or grabs a section of an image. If no
554
516
  * parameters are specified, the entire image is returned. Use the <b>x</b>
@@ -556,20 +518,19 @@ public class PImage implements PConstants, Cloneable {
556
518
  * the display window by specifying an additional <b>width</b> and
557
519
  * <b>height</b> parameter. When getting an image, the <b>x</b> and
558
520
  * <b>y</b> parameters define the coordinates for the upper-left corner of
559
- * the image, regardless of the current <b>imageMode()</b>.
560
- *
521
+ * the image, regardless of the current <b>imageMode()</b>.<br />
522
+ * <br />
561
523
  * If the pixel requested is outside of the image window, black is
562
524
  * returned. The numbers returned are scaled according to the current color
563
525
  * ranges, but only RGB values are returned by this function. For example,
564
526
  * even though you may have drawn a shape with <b>colorMode(HSB)</b>, the
565
- * numbers returned will be in RGB format.
566
- *
527
+ * numbers returned will be in RGB format.<br />
528
+ * <br />
567
529
  * Getting the color of a single pixel with <b>get(x, y)</b> is easy, but
568
530
  * not as fast as grabbing the data directly from <b>pixels[]</b>. The
569
531
  * equivalent statement to <b>get(x, y)</b> using <b>pixels[]</b> is
570
532
  * <b>pixels[y*width+x]</b>. See the reference for <b>pixels[]</b> for more information.
571
533
  *
572
- * ( end auto-generated )
573
534
  *
574
535
  * <h3>Advanced</h3>
575
536
  * Returns an ARGB "color" type (a packed 32 bit int with the color.
@@ -590,7 +551,7 @@ public class PImage implements PConstants, Cloneable {
590
551
  * pixels[] array directly.
591
552
  *
592
553
  * @webref image:pixels
593
- * @brief Reads the color of any pixel or grabs a rectangle of pixels
554
+ * @webBrief Reads the color of any pixel or grabs a rectangle of pixels.
594
555
  * @usage web_application
595
556
  * @param x x-coordinate of the pixel
596
557
  * @param y y-coordinate of the pixel
@@ -707,28 +668,26 @@ public class PImage implements PConstants, Cloneable {
707
668
 
708
669
 
709
670
  /**
710
- * ( begin auto-generated from PImage_set.xml )
711
671
  *
712
672
  * Changes the color of any pixel or writes an image directly into the
713
- * display window.
714
- *
673
+ * display window.<br />
674
+ * <br />
715
675
  * The <b>x</b> and <b>y</b> parameters specify the pixel to change and the
716
676
  * <b>color</b> parameter specifies the color value. The color parameter is
717
677
  * affected by the current color mode (the default is RGB values from 0 to
718
678
  * 255). When setting an image, the <b>x</b> and <b>y</b> parameters define
719
679
  * the coordinates for the upper-left corner of the image, regardless of
720
680
  * the current <b>imageMode()</b>.
721
- *
681
+ * <br /><br />
722
682
  * Setting the color of a single pixel with <b>set(x, y)</b> is easy, but
723
683
  * not as fast as putting the data directly into <b>pixels[]</b>. The
724
684
  * equivalent statement to <b>set(x, y, #000000)</b> using <b>pixels[]</b>
725
685
  * is <b>pixels[y*width+x] = #000000</b>. See the reference for
726
686
  * <b>pixels[]</b> for more information.
727
687
  *
728
- * ( end auto-generated )
729
688
  *
730
689
  * @webref image:pixels
731
- * @brief writes a color to any pixel or writes an image into another
690
+ * @webBrief Writes a color to any pixel or writes an image into another
732
691
  * @usage web_application
733
692
  * @param x x-coordinate of the pixel
734
693
  * @param y y-coordinate of the pixel
@@ -829,20 +788,18 @@ public class PImage implements PConstants, Cloneable {
829
788
 
830
789
 
831
790
  /**
832
- * ( begin auto-generated from PImage_mask.xml )
833
791
  *
834
792
  * Masks part of an image from displaying by loading another image and
835
793
  * using it as an alpha channel. This mask image should only contain
836
794
  * grayscale data, but only the blue color channel is used. The mask image
837
- * needs to be the same size as the image to which it is applied.
838
- *
795
+ * needs to be the same size as the image to which it is applied.<br />
796
+ * <br />
839
797
  * In addition to using a mask image, an integer array containing the alpha
840
798
  * channel data can be specified directly. This method is useful for
841
799
  * creating dynamically generated alpha masks. This array must be of the
842
800
  * same length as the target image's pixels array and should contain only
843
801
  * grayscale data of values between 0-255.
844
802
  *
845
- * ( end auto-generated )
846
803
  *
847
804
  * <h3>Advanced</h3>
848
805
  *
@@ -859,9 +816,9 @@ public class PImage implements PConstants, Cloneable {
859
816
  * performing a proper luminance-based conversion.
860
817
  *
861
818
  * @webref pimage:method
819
+ * @webBrief Masks part of an image with another image as an alpha channel
862
820
  * @usage web_application
863
821
  * @param img image to use as the mask
864
- * @brief Masks part of an image with another image as an alpha channel
865
822
  */
866
823
  public void mask(PImage img) {
867
824
  img.loadPixels();
@@ -947,36 +904,43 @@ public class PImage implements PConstants, Cloneable {
947
904
 
948
905
 
949
906
  /**
950
- * ( begin auto-generated from PImage_filter.xml )
951
- *
952
- * Filters an image as defined by one of the following modes:
953
- * THRESHOLD - converts the image to black and white pixels depending if
954
- * they are above or below the threshold defined by the level parameter.
955
- * The level must be between 0.0 (black) and 1.0(white). If no level is
956
- * specified, 0.5 is used.
957
- *
958
- * GRAY - converts any colors in the image to grayscale equivalents
959
- *
960
- * INVERT - sets each pixel to its inverse value
961
- *
962
- * POSTERIZE - limits each channel of the image to the number of colors
963
- * specified as the level parameter
964
907
  *
965
- * BLUR - executes a Guassian blur with the level parameter specifying the
966
- * extent of the blurring. If no level parameter is used, the blur is
967
- * equivalent to Guassian blur of radius 1
968
- *
969
- * OPAQUE - sets the alpha channel to entirely opaque
970
- *
971
- * ERODE - reduces the light areas with the amount defined by the level
972
- * parameter
973
- *
974
- * DILATE - increases the light areas with the amount defined by the level parameter
975
- *
976
- * ( end auto-generated )
977
- *
978
- * <h3>Advanced</h3>
979
- * Method to apply a variety of basic filters to this image.
908
+ * Filters the image as defined by one of the following modes:<br />
909
+ * <br />
910
+ * THRESHOLD<br />
911
+ * Converts the image to black and white pixels depending if they are above or
912
+ * below the threshold defined by the level parameter. The parameter must be
913
+ * between 0.0 (black) and 1.0 (white). If no level is specified, 0.5 is
914
+ * used.<br />
915
+ * <br />
916
+ * GRAY<br />
917
+ * Converts any colors in the image to grayscale equivalents. No parameter is
918
+ * used.<br />
919
+ * <br />
920
+ * OPAQUE<br />
921
+ * Sets the alpha channel to entirely opaque. No parameter is used.<br />
922
+ * <br />
923
+ * INVERT<br />
924
+ * Sets each pixel to its inverse value. No parameter is used.<br />
925
+ * <br />
926
+ * POSTERIZE<br />
927
+ * Limits each channel of the image to the number of colors specified as the
928
+ * parameter. The parameter can be set to values between 2 and 255, but results
929
+ * are most noticeable in the lower ranges.<br />
930
+ * <br />
931
+ * BLUR<br />
932
+ * Executes a Gaussian blur with the level parameter specifying the extent of
933
+ * the blurring. If no parameter is used, the blur is equivalent to Gaussian
934
+ * blur of radius 1. Larger values increase the blur.<br />
935
+ * <br />
936
+ * ERODE<br />
937
+ * Reduces the light areas. No parameter is used.<br />
938
+ * <br />
939
+ * DILATE<br />
940
+ * Increases the light areas. No parameter is used.
941
+ *
942
+ *
943
+ * <h3>Advanced</h3> Method to apply a variety of basic filters to this image.
980
944
  * <P>
981
945
  * <UL>
982
946
  * <LI>filter(BLUR) provides a basic blur.
@@ -989,14 +953,15 @@ public class PImage implements PConstants, Cloneable {
989
953
  * </UL>
990
954
  * Luminance conversion code contributed by
991
955
  * <A HREF="http://www.toxi.co.uk">toxi</A>
992
- *
956
+ * <P/>
993
957
  * Gaussian blur code contributed by
994
958
  * <A HREF="http://incubator.quasimondo.com">Mario Klingemann</A>
995
959
  *
996
960
  * @webref image:pixels
997
- * @brief Converts the image to grayscale or black and white
961
+ * @webBrief Converts the image to grayscale or black and white
998
962
  * @usage web_application
999
- * @param kind Either THRESHOLD, GRAY, OPAQUE, INVERT, POSTERIZE, BLUR, ERODE, or DILATE
963
+ * @param kind Either THRESHOLD, GRAY, OPAQUE, INVERT, POSTERIZE, BLUR, ERODE,
964
+ * or DILATE
1000
965
  * @param param unique for each, see above
1001
966
  */
1002
967
  public void filter(int kind, float param) {
@@ -1004,20 +969,14 @@ public class PImage implements PConstants, Cloneable {
1004
969
 
1005
970
  switch (kind) {
1006
971
  case BLUR:
1007
- switch (format) {
1008
- case ALPHA:
972
+ if (format == ALPHA)
1009
973
  blurAlpha(param);
1010
- break;
1011
- case ARGB:
974
+ else if (format == ARGB)
1012
975
  blurARGB(param);
1013
- break;
1014
- default:
976
+ else
1015
977
  blurRGB(param);
1016
- break;
1017
- }
1018
978
  break;
1019
979
 
1020
-
1021
980
  case GRAY:
1022
981
  throw new RuntimeException("Use filter(GRAY) instead of " +
1023
982
  "filter(GRAY, param)");
@@ -1091,7 +1050,8 @@ public class PImage implements PConstants, Cloneable {
1091
1050
  */
1092
1051
  protected void buildBlurKernel(float r) {
1093
1052
  int radius = (int) (r * 3.5f);
1094
- radius = (radius < 1) ? 1 : ((radius < 248) ? radius : 248);
1053
+ if (radius < 1) radius = 1;
1054
+ if (radius > 248) radius = 248;
1095
1055
  if (blurRadius != radius) {
1096
1056
  blurRadius = radius;
1097
1057
  blurKernelSize = 1 + blurRadius<<1;
@@ -1188,8 +1148,8 @@ public class PImage implements PConstants, Cloneable {
1188
1148
 
1189
1149
 
1190
1150
  protected void blurRGB(float r) {
1191
- int sum, cr, cg, cb; //, k;
1192
- int /*pixel,*/ read, ri, /*roff,*/ ym, ymi, /*riw,*/ bk0;
1151
+ int sum, cr, cg, cb;
1152
+ int read, ri, ym, ymi, bk0;
1193
1153
  int[] r2 = new int[pixels.length];
1194
1154
  int[] g2 = new int[pixels.length];
1195
1155
  int[] b2 = new int[pixels.length];
@@ -1420,7 +1380,7 @@ public class PImage implements PConstants, Cloneable {
1420
1380
  }
1421
1381
  if (lumDown > currLum) {
1422
1382
  result = colDown;
1423
- currLum = lumDown;
1383
+ // currLum = lumDown; // removed, unused assignment
1424
1384
  }
1425
1385
  outgoing[index++] = result;
1426
1386
  }
@@ -1489,7 +1449,7 @@ public class PImage implements PConstants, Cloneable {
1489
1449
  }
1490
1450
  if (lumDown < currLum) {
1491
1451
  result = colDown;
1492
- currLum = lumDown;
1452
+ // currLum = lumDown; // removed, unused assignment
1493
1453
  }
1494
1454
  outgoing[index++] = result;
1495
1455
  }
@@ -1505,20 +1465,18 @@ public class PImage implements PConstants, Cloneable {
1505
1465
 
1506
1466
 
1507
1467
  /**
1508
- * ( begin auto-generated from PImage_copy.xml )
1509
1468
  *
1510
1469
  * Copies a region of pixels from one image into another. If the source and
1511
1470
  * destination regions aren't the same size, it will automatically resize
1512
1471
  * source pixels to fit the specified target region. No alpha information
1513
1472
  * is used in the process, however if the source image has an alpha channel
1514
1473
  * set, it will be copied as well.
1515
- *
1474
+ * <br /><br />
1516
1475
  * As of release 0149, this function ignores <b>imageMode()</b>.
1517
1476
  *
1518
- * ( end auto-generated )
1519
1477
  *
1520
1478
  * @webref image:pixels
1521
- * @brief Copies the entire image
1479
+ * @webBrief Copies the entire image
1522
1480
  * @usage web_application
1523
1481
  * @param sx X coordinate of the source's upper left corner
1524
1482
  * @param sy Y coordinate of the source's upper left corner
@@ -1554,13 +1512,11 @@ public class PImage implements PConstants, Cloneable {
1554
1512
 
1555
1513
 
1556
1514
  /**
1557
- * ( begin auto-generated from blendColor.xml )
1558
1515
  *
1559
1516
  * Blends two color values together based on the blending mode given as the
1560
1517
  * <b>MODE</b> parameter. The possible modes are described in the reference
1561
1518
  * for the <b>blend()</b> function.
1562
1519
  *
1563
- * ( end auto-generated )
1564
1520
  * <h3>Advanced</h3>
1565
1521
  * <UL>
1566
1522
  * <LI>REPLACE - destination colour equals colour of source pixel: C = A.
@@ -1574,7 +1530,7 @@ public class PImage implements PConstants, Cloneable {
1574
1530
  * Clipped to 0..255, Photoshop calls this "Linear Burn",
1575
1531
  * and Director calls it "Add Pin".
1576
1532
  *
1577
- * <LI>SUBTRACT - substractive blend with black clip:
1533
+ * <LI>SUBTRACT - subtractive blend with black clip:
1578
1534
  * <TT>C = max(B - A*factor, 0)</TT>.
1579
1535
  * Clipped to 0..255, Photoshop calls this "Linear Dodge",
1580
1536
  * and Director calls it "Subtract Pin".
@@ -1616,15 +1572,17 @@ public class PImage implements PConstants, Cloneable {
1616
1572
  * necessarily "correct" code. No biggie, most software does. A nitpicker
1617
1573
  * can find numerous "off by 1 division" problems in the blend code where
1618
1574
  * <TT>&gt;&gt;8</TT> or <TT>&gt;&gt;7</TT> is used when strictly speaking
1619
- * <TT>/255.0</TT> or <TT>/127.0</TT> should have been used.</P>
1575
+ * <TT>/255.0</T> or <TT>/127.0</TT> should have been used.</P>
1620
1576
  * <P>For instance, exclusion (not intended for real-time use) reads
1621
1577
  * <TT>r1 + r2 - ((2 * r1 * r2) / 255)</TT> because <TT>255 == 1.0</TT>
1622
1578
  * not <TT>256 == 1.0</TT>. In other words, <TT>(255*255)>>8</TT> is not
1623
1579
  * the same as <TT>(255*255)/255</TT>. But for real-time use the shifts
1624
- * are preferrable, and the difference is insignificant for applications
1580
+ * are preferable, and the difference is insignificant for applications
1625
1581
  * built with Processing.</P>
1626
1582
  *
1627
1583
  * @webref color:creating_reading
1584
+ * @webBrief Blends two color values together based on the blending mode given as the
1585
+ * <b>MODE</b> parameter.
1628
1586
  * @usage web_application
1629
1587
  * @param c1 the first color to blend
1630
1588
  * @param c2 the second color to blend
@@ -1667,65 +1625,63 @@ public class PImage implements PConstants, Cloneable {
1667
1625
 
1668
1626
 
1669
1627
  /**
1670
- * ( begin auto-generated from PImage_blend.xml )
1671
1628
  *
1672
1629
  * Blends a region of pixels into the image specified by the <b>img</b>
1673
1630
  * parameter. These copies utilize full alpha channel support and a choice
1674
1631
  * of the following modes to blend the colors of source pixels (A) with the
1675
- * ones of pixels in the destination image (B):
1676
- *
1677
- * BLEND - linear interpolation of colours: C = A*factor + B
1678
- *
1679
- * ADD - additive blending with white clip: C = min(A*factor + B, 255)
1680
- *
1632
+ * ones of pixels in the destination image (B):<br />
1633
+ * <br />
1634
+ * BLEND - linear interpolation of colours: C = A*factor + B<br />
1635
+ * <br />
1636
+ * ADD - additive blending with white clip: C = min(A*factor + B, 255)<br />
1637
+ * <br />
1681
1638
  * SUBTRACT - subtractive blending with black clip: C = max(B - A*factor,
1682
- * 0)
1683
- *
1684
- * DARKEST - only the darkest colour succeeds: C = min(A*factor, B)
1685
- *
1686
- * LIGHTEST - only the lightest colour succeeds: C = max(A*factor, B)
1687
- *
1688
- * DIFFERENCE - subtract colors from underlying image.
1689
- *
1690
- * EXCLUSION - similar to DIFFERENCE, but less extreme.
1691
- *
1692
- * MULTIPLY - Multiply the colors, result will always be darker.
1693
- *
1694
- * SCREEN - Opposite multiply, uses inverse values of the colors.
1695
- *
1639
+ * 0)<br />
1640
+ * <br />
1641
+ * DARKEST - only the darkest colour succeeds: C = min(A*factor, B)<br />
1642
+ * <br />
1643
+ * LIGHTEST - only the lightest colour succeeds: C = max(A*factor, B)<br />
1644
+ * <br />
1645
+ * DIFFERENCE - subtract colors from underlying image.<br />
1646
+ * <br />
1647
+ * EXCLUSION - similar to DIFFERENCE, but less extreme.<br />
1648
+ * <br />
1649
+ * MULTIPLY - Multiply the colors, result will always be darker.<br />
1650
+ * <br />
1651
+ * SCREEN - Opposite multiply, uses inverse values of the colors.<br />
1652
+ * <br />
1696
1653
  * OVERLAY - A mix of MULTIPLY and SCREEN. Multiplies dark values,
1697
- * and screens light values.
1698
- *
1699
- * HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower.
1700
- *
1654
+ * and screens light values.<br />
1655
+ * <br />
1656
+ * HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower.<br />
1657
+ * <br />
1701
1658
  * SOFT_LIGHT - Mix of DARKEST and LIGHTEST.
1702
- * Works like OVERLAY, but not as harsh.
1703
- *
1659
+ * Works like OVERLAY, but not as harsh.<br />
1660
+ * <br />
1704
1661
  * DODGE - Lightens light tones and increases contrast, ignores darks.
1705
- * Called "Color Dodge" in Illustrator and Photoshop.
1706
- *
1662
+ * Called "Color Dodge" in Illustrator and Photoshop.<br />
1663
+ * <br />
1707
1664
  * BURN - Darker areas are applied, increasing contrast, ignores lights.
1708
- * Called "Color Burn" in Illustrator and Photoshop.
1709
- *
1665
+ * Called "Color Burn" in Illustrator and Photoshop.<br />
1666
+ * <br />
1710
1667
  * All modes use the alpha information (highest byte) of source image
1711
1668
  * pixels as the blending factor. If the source and destination regions are
1712
1669
  * different sizes, the image will be automatically resized to match the
1713
1670
  * destination size. If the <b>srcImg</b> parameter is not used, the
1714
- * display window is used as the source image.
1715
- *
1671
+ * display window is used as the source image.<br />
1672
+ * <br />
1716
1673
  * As of release 0149, this function ignores <b>imageMode()</b>.
1717
1674
  *
1718
- * ( end auto-generated )
1719
1675
  *
1720
1676
  * @webref image:pixels
1721
- * @brief Copies a pixel or rectangle of pixels using different blending modes
1677
+ * @webBrief Copies a pixel or rectangle of pixels using different blending modes.
1722
1678
  * @param src an image variable referring to the source image
1723
1679
  * @param sx X coordinate of the source's upper left corner
1724
1680
  * @param sy Y coordinate of the source's upper left corner
1725
1681
  * @param sw source image width
1726
1682
  * @param sh source image height
1727
- * @param dx X coordinate of the destinations's upper left corner
1728
- * @param dy Y coordinate of the destinations's upper left corner
1683
+ * @param dx X coordinate of the destination's upper left corner
1684
+ * @param dy Y coordinate of the destination's upper left corner
1729
1685
  * @param dw destination image width
1730
1686
  * @param dh destination image height
1731
1687
  * @param mode Either BLEND, ADD, SUBTRACT, LIGHTEST, DARKEST, DIFFERENCE, EXCLUSION, MULTIPLY, SCREEN, OVERLAY, HARD_LIGHT, SOFT_LIGHT, DODGE, BURN
@@ -1745,18 +1701,18 @@ public class PImage implements PConstants, Cloneable {
1745
1701
  loadPixels();
1746
1702
  if (src == this) {
1747
1703
  if (intersect(sx, sy, sx2, sy2, dx, dy, dx2, dy2)) {
1748
- blit_resize(get(sx, sy, sw, sh),
1704
+ blitResize(get(sx, sy, sw, sh),
1749
1705
  0, 0, sw, sh,
1750
- pixels, pixelWidth, pixelHeight, dx, dy, dx2, dy2, mode);
1706
+ pixels, pixelWidth, pixelHeight, dx, dy, dx2, dy2, mode, true);
1751
1707
  } else {
1752
1708
  // same as below, except skip the loadPixels() because it'd be redundant
1753
- blit_resize(src, sx, sy, sx2, sy2,
1754
- pixels, pixelWidth, pixelHeight, dx, dy, dx2, dy2, mode);
1709
+ blitResize(src, sx, sy, sx2, sy2,
1710
+ pixels, pixelWidth, pixelHeight, dx, dy, dx2, dy2, mode, true);
1755
1711
  }
1756
1712
  } else {
1757
1713
  src.loadPixels();
1758
- blit_resize(src, sx, sy, sx2, sy2,
1759
- pixels, pixelWidth, pixelHeight, dx, dy, dx2, dy2, mode);
1714
+ blitResize(src, sx, sy, sx2, sy2,
1715
+ pixels, pixelWidth, pixelHeight, dx, dy, dx2, dy2, mode, true);
1760
1716
  //src.updatePixels();
1761
1717
  }
1762
1718
  updatePixels();
@@ -1807,11 +1763,11 @@ public class PImage implements PConstants, Cloneable {
1807
1763
  * Uses bilinear filtering if smooth() has been enabled
1808
1764
  * 'mode' determines the blending mode used in the process.
1809
1765
  */
1810
- private void blit_resize(PImage img,
1811
- int srcX1, int srcY1, int srcX2, int srcY2,
1812
- int[] destPixels, int screenW, int screenH,
1813
- int destX1, int destY1, int destX2, int destY2,
1814
- int mode) {
1766
+ private void blitResize(PImage img,
1767
+ int srcX1, int srcY1, int srcX2, int srcY2,
1768
+ int[] destPixels, int screenW, int screenH,
1769
+ int destX1, int destY1, int destX2, int destY2,
1770
+ int mode, boolean smooth) {
1815
1771
  if (srcX1 < 0) srcX1 = 0;
1816
1772
  if (srcY1 < 0) srcY1 = 0;
1817
1773
  if (srcX2 > img.pixelWidth) srcX2 = img.pixelWidth;
@@ -1822,10 +1778,9 @@ public class PImage implements PConstants, Cloneable {
1822
1778
  int destW = destX2 - destX1;
1823
1779
  int destH = destY2 - destY1;
1824
1780
 
1825
- boolean smooth = true; // may as well go with the smoothing these days
1826
-
1827
1781
  if (!smooth) {
1828
- srcW++; srcH++;
1782
+ srcW++;
1783
+ srcH++;
1829
1784
  }
1830
1785
 
1831
1786
  if (destW <= 0 || destH <= 0 ||
@@ -1857,12 +1812,23 @@ public class PImage implements PConstants, Cloneable {
1857
1812
  srcBuffer = img.pixels;
1858
1813
 
1859
1814
  if (smooth) {
1860
- // use bilinear filtering
1861
- iw = img.pixelWidth;
1862
- iw1 = img.pixelWidth - 1;
1863
- ih1 = img.pixelHeight - 1;
1815
+ blitResizeBilinear(img, destPixels, destOffset, screenW, destW, destH, dx, dy, mode);
1816
+ } else {
1817
+ blitResizeNearest(img, destPixels, destOffset, screenW, destW, destH, dx, dy, mode);
1818
+ }
1819
+ }
1864
1820
 
1865
- switch (mode) {
1821
+ private void blitResizeBilinear(PImage img,
1822
+ int[] destPixels, int destOffset, int screenW,
1823
+ int destW, int destH,
1824
+ int dx, int dy,
1825
+ int mode) {
1826
+ // use bilinear filtering
1827
+ iw = img.pixelWidth;
1828
+ iw1 = img.pixelWidth - 1;
1829
+ ih1 = img.pixelHeight - 1;
1830
+
1831
+ switch (mode) {
1866
1832
 
1867
1833
  case BLEND:
1868
1834
  for (int y = 0; y < destH; y++) {
@@ -1870,7 +1836,7 @@ public class PImage implements PConstants, Cloneable {
1870
1836
  for (int x = 0; x < destW; x++) {
1871
1837
  // davbol - renamed old blend_multiply to blend_blend
1872
1838
  destPixels[destOffset + x] =
1873
- blend_blend(destPixels[destOffset + x], filter_bilinear());
1839
+ blend_blend(destPixels[destOffset + x], filter_bilinear());
1874
1840
  sX += dx;
1875
1841
  }
1876
1842
  destOffset += screenW;
@@ -1883,7 +1849,7 @@ public class PImage implements PConstants, Cloneable {
1883
1849
  filter_new_scanline();
1884
1850
  for (int x = 0; x < destW; x++) {
1885
1851
  destPixels[destOffset + x] =
1886
- blend_add_pin(destPixels[destOffset + x], filter_bilinear());
1852
+ blend_add_pin(destPixels[destOffset + x], filter_bilinear());
1887
1853
  sX += dx;
1888
1854
  }
1889
1855
  destOffset += screenW;
@@ -1896,7 +1862,7 @@ public class PImage implements PConstants, Cloneable {
1896
1862
  filter_new_scanline();
1897
1863
  for (int x = 0; x < destW; x++) {
1898
1864
  destPixels[destOffset + x] =
1899
- blend_sub_pin(destPixels[destOffset + x], filter_bilinear());
1865
+ blend_sub_pin(destPixels[destOffset + x], filter_bilinear());
1900
1866
  sX += dx;
1901
1867
  }
1902
1868
  destOffset += screenW;
@@ -1909,7 +1875,7 @@ public class PImage implements PConstants, Cloneable {
1909
1875
  filter_new_scanline();
1910
1876
  for (int x = 0; x < destW; x++) {
1911
1877
  destPixels[destOffset + x] =
1912
- blend_lightest(destPixels[destOffset + x], filter_bilinear());
1878
+ blend_lightest(destPixels[destOffset + x], filter_bilinear());
1913
1879
  sX += dx;
1914
1880
  }
1915
1881
  destOffset += screenW;
@@ -1922,7 +1888,7 @@ public class PImage implements PConstants, Cloneable {
1922
1888
  filter_new_scanline();
1923
1889
  for (int x = 0; x < destW; x++) {
1924
1890
  destPixels[destOffset + x] =
1925
- blend_darkest(destPixels[destOffset + x], filter_bilinear());
1891
+ blend_darkest(destPixels[destOffset + x], filter_bilinear());
1926
1892
  sX += dx;
1927
1893
  }
1928
1894
  destOffset += screenW;
@@ -1947,7 +1913,7 @@ public class PImage implements PConstants, Cloneable {
1947
1913
  filter_new_scanline();
1948
1914
  for (int x = 0; x < destW; x++) {
1949
1915
  destPixels[destOffset + x] =
1950
- blend_difference(destPixels[destOffset + x], filter_bilinear());
1916
+ blend_difference(destPixels[destOffset + x], filter_bilinear());
1951
1917
  sX += dx;
1952
1918
  }
1953
1919
  destOffset += screenW;
@@ -1960,7 +1926,7 @@ public class PImage implements PConstants, Cloneable {
1960
1926
  filter_new_scanline();
1961
1927
  for (int x = 0; x < destW; x++) {
1962
1928
  destPixels[destOffset + x] =
1963
- blend_exclusion(destPixels[destOffset + x], filter_bilinear());
1929
+ blend_exclusion(destPixels[destOffset + x], filter_bilinear());
1964
1930
  sX += dx;
1965
1931
  }
1966
1932
  destOffset += screenW;
@@ -1973,7 +1939,7 @@ public class PImage implements PConstants, Cloneable {
1973
1939
  filter_new_scanline();
1974
1940
  for (int x = 0; x < destW; x++) {
1975
1941
  destPixels[destOffset + x] =
1976
- blend_multiply(destPixels[destOffset + x], filter_bilinear());
1942
+ blend_multiply(destPixels[destOffset + x], filter_bilinear());
1977
1943
  sX += dx;
1978
1944
  }
1979
1945
  destOffset += screenW;
@@ -1986,7 +1952,7 @@ public class PImage implements PConstants, Cloneable {
1986
1952
  filter_new_scanline();
1987
1953
  for (int x = 0; x < destW; x++) {
1988
1954
  destPixels[destOffset + x] =
1989
- blend_screen(destPixels[destOffset + x], filter_bilinear());
1955
+ blend_screen(destPixels[destOffset + x], filter_bilinear());
1990
1956
  sX += dx;
1991
1957
  }
1992
1958
  destOffset += screenW;
@@ -1999,7 +1965,7 @@ public class PImage implements PConstants, Cloneable {
1999
1965
  filter_new_scanline();
2000
1966
  for (int x = 0; x < destW; x++) {
2001
1967
  destPixels[destOffset + x] =
2002
- blend_overlay(destPixels[destOffset + x], filter_bilinear());
1968
+ blend_overlay(destPixels[destOffset + x], filter_bilinear());
2003
1969
  sX += dx;
2004
1970
  }
2005
1971
  destOffset += screenW;
@@ -2012,7 +1978,7 @@ public class PImage implements PConstants, Cloneable {
2012
1978
  filter_new_scanline();
2013
1979
  for (int x = 0; x < destW; x++) {
2014
1980
  destPixels[destOffset + x] =
2015
- blend_hard_light(destPixels[destOffset + x], filter_bilinear());
1981
+ blend_hard_light(destPixels[destOffset + x], filter_bilinear());
2016
1982
  sX += dx;
2017
1983
  }
2018
1984
  destOffset += screenW;
@@ -2025,7 +1991,7 @@ public class PImage implements PConstants, Cloneable {
2025
1991
  filter_new_scanline();
2026
1992
  for (int x = 0; x < destW; x++) {
2027
1993
  destPixels[destOffset + x] =
2028
- blend_soft_light(destPixels[destOffset + x], filter_bilinear());
1994
+ blend_soft_light(destPixels[destOffset + x], filter_bilinear());
2029
1995
  sX += dx;
2030
1996
  }
2031
1997
  destOffset += screenW;
@@ -2039,7 +2005,7 @@ public class PImage implements PConstants, Cloneable {
2039
2005
  filter_new_scanline();
2040
2006
  for (int x = 0; x < destW; x++) {
2041
2007
  destPixels[destOffset + x] =
2042
- blend_dodge(destPixels[destOffset + x], filter_bilinear());
2008
+ blend_dodge(destPixels[destOffset + x], filter_bilinear());
2043
2009
  sX += dx;
2044
2010
  }
2045
2011
  destOffset += screenW;
@@ -2052,7 +2018,7 @@ public class PImage implements PConstants, Cloneable {
2052
2018
  filter_new_scanline();
2053
2019
  for (int x = 0; x < destW; x++) {
2054
2020
  destPixels[destOffset + x] =
2055
- blend_burn(destPixels[destOffset + x], filter_bilinear());
2021
+ blend_burn(destPixels[destOffset + x], filter_bilinear());
2056
2022
  sX += dx;
2057
2023
  }
2058
2024
  destOffset += screenW;
@@ -2060,245 +2026,249 @@ public class PImage implements PConstants, Cloneable {
2060
2026
  }
2061
2027
  break;
2062
2028
 
2063
- }
2029
+ }
2030
+ }
2064
2031
 
2065
- } else {
2066
- // nearest neighbour scaling (++fast!)
2067
- switch (mode) {
2032
+ private void blitResizeNearest(PImage img,
2033
+ int[] destPixels, int destOffset, int screenW,
2034
+ int destW, int destH,
2035
+ int dx, int dy,
2036
+ int mode) {
2037
+ // nearest neighbour scaling (++fast!)
2038
+ int sY;
2039
+ switch (mode) {
2068
2040
 
2069
- case BLEND:
2070
- for (int y = 0; y < destH; y++) {
2071
- sX = srcXOffset;
2072
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2073
- for (int x = 0; x < destW; x++) {
2074
- // davbol - renamed old blend_multiply to blend_blend
2075
- destPixels[destOffset + x] =
2076
- blend_blend(destPixels[destOffset + x],
2041
+ case BLEND:
2042
+ for (int y = 0; y < destH; y++) {
2043
+ sX = srcXOffset;
2044
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2045
+ for (int x = 0; x < destW; x++) {
2046
+ // davbol - renamed old blend_multiply to blend_blend
2047
+ destPixels[destOffset + x] =
2048
+ blend_blend(destPixels[destOffset + x],
2049
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2050
+ sX += dx;
2051
+ }
2052
+ destOffset += screenW;
2053
+ srcYOffset += dy;
2054
+ }
2055
+ break;
2056
+
2057
+ case ADD:
2058
+ for (int y = 0; y < destH; y++) {
2059
+ sX = srcXOffset;
2060
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2061
+ for (int x = 0; x < destW; x++) {
2062
+ destPixels[destOffset + x] =
2063
+ blend_add_pin(destPixels[destOffset + x],
2077
2064
  srcBuffer[sY + (sX >> PRECISIONB)]);
2078
- sX += dx;
2079
- }
2080
- destOffset += screenW;
2081
- srcYOffset += dy;
2065
+ sX += dx;
2082
2066
  }
2083
- break;
2084
-
2085
- case ADD:
2086
- for (int y = 0; y < destH; y++) {
2087
- sX = srcXOffset;
2088
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2089
- for (int x = 0; x < destW; x++) {
2090
- destPixels[destOffset + x] =
2091
- blend_add_pin(destPixels[destOffset + x],
2092
- srcBuffer[sY + (sX >> PRECISIONB)]);
2093
- sX += dx;
2094
- }
2095
- destOffset += screenW;
2096
- srcYOffset += dy;
2067
+ destOffset += screenW;
2068
+ srcYOffset += dy;
2069
+ }
2070
+ break;
2071
+
2072
+ case SUBTRACT:
2073
+ for (int y = 0; y < destH; y++) {
2074
+ sX = srcXOffset;
2075
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2076
+ for (int x = 0; x < destW; x++) {
2077
+ destPixels[destOffset + x] =
2078
+ blend_sub_pin(destPixels[destOffset + x],
2079
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2080
+ sX += dx;
2097
2081
  }
2098
- break;
2099
-
2100
- case SUBTRACT:
2101
- for (int y = 0; y < destH; y++) {
2102
- sX = srcXOffset;
2103
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2104
- for (int x = 0; x < destW; x++) {
2105
- destPixels[destOffset + x] =
2106
- blend_sub_pin(destPixels[destOffset + x],
2107
- srcBuffer[sY + (sX >> PRECISIONB)]);
2108
- sX += dx;
2109
- }
2110
- destOffset += screenW;
2111
- srcYOffset += dy;
2082
+ destOffset += screenW;
2083
+ srcYOffset += dy;
2084
+ }
2085
+ break;
2086
+
2087
+ case LIGHTEST:
2088
+ for (int y = 0; y < destH; y++) {
2089
+ sX = srcXOffset;
2090
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2091
+ for (int x = 0; x < destW; x++) {
2092
+ destPixels[destOffset + x] =
2093
+ blend_lightest(destPixels[destOffset + x],
2094
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2095
+ sX += dx;
2096
+ }
2097
+ destOffset += screenW;
2098
+ srcYOffset += dy;
2099
+ }
2100
+ break;
2101
+
2102
+ case DARKEST:
2103
+ for (int y = 0; y < destH; y++) {
2104
+ sX = srcXOffset;
2105
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2106
+ for (int x = 0; x < destW; x++) {
2107
+ destPixels[destOffset + x] =
2108
+ blend_darkest(destPixels[destOffset + x],
2109
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2110
+ sX += dx;
2112
2111
  }
2113
- break;
2114
-
2115
- case LIGHTEST:
2116
- for (int y = 0; y < destH; y++) {
2117
- sX = srcXOffset;
2118
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2119
- for (int x = 0; x < destW; x++) {
2120
- destPixels[destOffset + x] =
2121
- blend_lightest(destPixels[destOffset + x],
2112
+ destOffset += screenW;
2113
+ srcYOffset += dy;
2114
+ }
2115
+ break;
2116
+
2117
+ case REPLACE:
2118
+ for (int y = 0; y < destH; y++) {
2119
+ sX = srcXOffset;
2120
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2121
+ for (int x = 0; x < destW; x++) {
2122
+ destPixels[destOffset + x] = srcBuffer[sY + (sX >> PRECISIONB)];
2123
+ sX += dx;
2124
+ }
2125
+ destOffset += screenW;
2126
+ srcYOffset += dy;
2127
+ }
2128
+ break;
2129
+
2130
+ case DIFFERENCE:
2131
+ for (int y = 0; y < destH; y++) {
2132
+ sX = srcXOffset;
2133
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2134
+ for (int x = 0; x < destW; x++) {
2135
+ destPixels[destOffset + x] =
2136
+ blend_difference(destPixels[destOffset + x],
2122
2137
  srcBuffer[sY + (sX >> PRECISIONB)]);
2123
- sX += dx;
2124
- }
2125
- destOffset += screenW;
2126
- srcYOffset += dy;
2138
+ sX += dx;
2127
2139
  }
2128
- break;
2129
-
2130
- case DARKEST:
2131
- for (int y = 0; y < destH; y++) {
2132
- sX = srcXOffset;
2133
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2134
- for (int x = 0; x < destW; x++) {
2135
- destPixels[destOffset + x] =
2136
- blend_darkest(destPixels[destOffset + x],
2140
+ destOffset += screenW;
2141
+ srcYOffset += dy;
2142
+ }
2143
+ break;
2144
+
2145
+ case EXCLUSION:
2146
+ for (int y = 0; y < destH; y++) {
2147
+ sX = srcXOffset;
2148
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2149
+ for (int x = 0; x < destW; x++) {
2150
+ destPixels[destOffset + x] =
2151
+ blend_exclusion(destPixels[destOffset + x],
2137
2152
  srcBuffer[sY + (sX >> PRECISIONB)]);
2138
- sX += dx;
2139
- }
2140
- destOffset += screenW;
2141
- srcYOffset += dy;
2142
- }
2143
- break;
2144
-
2145
- case REPLACE:
2146
- for (int y = 0; y < destH; y++) {
2147
- sX = srcXOffset;
2148
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2149
- for (int x = 0; x < destW; x++) {
2150
- destPixels[destOffset + x] = srcBuffer[sY + (sX >> PRECISIONB)];
2151
- sX += dx;
2152
- }
2153
- destOffset += screenW;
2154
- srcYOffset += dy;
2155
- }
2156
- break;
2157
-
2158
- case DIFFERENCE:
2159
- for (int y = 0; y < destH; y++) {
2160
- sX = srcXOffset;
2161
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2162
- for (int x = 0; x < destW; x++) {
2163
- destPixels[destOffset + x] =
2164
- blend_difference(destPixels[destOffset + x],
2165
- srcBuffer[sY + (sX >> PRECISIONB)]);
2166
- sX += dx;
2167
- }
2168
- destOffset += screenW;
2169
- srcYOffset += dy;
2153
+ sX += dx;
2170
2154
  }
2171
- break;
2172
-
2173
- case EXCLUSION:
2174
- for (int y = 0; y < destH; y++) {
2175
- sX = srcXOffset;
2176
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2177
- for (int x = 0; x < destW; x++) {
2178
- destPixels[destOffset + x] =
2179
- blend_exclusion(destPixels[destOffset + x],
2180
- srcBuffer[sY + (sX >> PRECISIONB)]);
2181
- sX += dx;
2182
- }
2183
- destOffset += screenW;
2184
- srcYOffset += dy;
2185
- }
2186
- break;
2187
-
2188
- case MULTIPLY:
2189
- for (int y = 0; y < destH; y++) {
2190
- sX = srcXOffset;
2191
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2192
- for (int x = 0; x < destW; x++) {
2193
- destPixels[destOffset + x] =
2194
- blend_multiply(destPixels[destOffset + x],
2195
- srcBuffer[sY + (sX >> PRECISIONB)]);
2196
- sX += dx;
2197
- }
2198
- destOffset += screenW;
2199
- srcYOffset += dy;
2155
+ destOffset += screenW;
2156
+ srcYOffset += dy;
2157
+ }
2158
+ break;
2159
+
2160
+ case MULTIPLY:
2161
+ for (int y = 0; y < destH; y++) {
2162
+ sX = srcXOffset;
2163
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2164
+ for (int x = 0; x < destW; x++) {
2165
+ destPixels[destOffset + x] =
2166
+ blend_multiply(destPixels[destOffset + x],
2167
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2168
+ sX += dx;
2200
2169
  }
2201
- break;
2202
-
2203
- case SCREEN:
2204
- for (int y = 0; y < destH; y++) {
2205
- sX = srcXOffset;
2206
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2207
- for (int x = 0; x < destW; x++) {
2208
- destPixels[destOffset + x] =
2209
- blend_screen(destPixels[destOffset + x],
2210
- srcBuffer[sY + (sX >> PRECISIONB)]);
2211
- sX += dx;
2212
- }
2213
- destOffset += screenW;
2214
- srcYOffset += dy;
2170
+ destOffset += screenW;
2171
+ srcYOffset += dy;
2172
+ }
2173
+ break;
2174
+
2175
+ case SCREEN:
2176
+ for (int y = 0; y < destH; y++) {
2177
+ sX = srcXOffset;
2178
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2179
+ for (int x = 0; x < destW; x++) {
2180
+ destPixels[destOffset + x] =
2181
+ blend_screen(destPixels[destOffset + x],
2182
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2183
+ sX += dx;
2215
2184
  }
2216
- break;
2217
-
2218
- case OVERLAY:
2219
- for (int y = 0; y < destH; y++) {
2220
- sX = srcXOffset;
2221
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2222
- for (int x = 0; x < destW; x++) {
2223
- destPixels[destOffset + x] =
2224
- blend_overlay(destPixels[destOffset + x],
2225
- srcBuffer[sY + (sX >> PRECISIONB)]);
2226
- sX += dx;
2227
- }
2228
- destOffset += screenW;
2229
- srcYOffset += dy;
2185
+ destOffset += screenW;
2186
+ srcYOffset += dy;
2187
+ }
2188
+ break;
2189
+
2190
+ case OVERLAY:
2191
+ for (int y = 0; y < destH; y++) {
2192
+ sX = srcXOffset;
2193
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2194
+ for (int x = 0; x < destW; x++) {
2195
+ destPixels[destOffset + x] =
2196
+ blend_overlay(destPixels[destOffset + x],
2197
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2198
+ sX += dx;
2230
2199
  }
2231
- break;
2232
-
2233
- case HARD_LIGHT:
2234
- for (int y = 0; y < destH; y++) {
2235
- sX = srcXOffset;
2236
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2237
- for (int x = 0; x < destW; x++) {
2238
- destPixels[destOffset + x] =
2239
- blend_hard_light(destPixels[destOffset + x],
2240
- srcBuffer[sY + (sX >> PRECISIONB)]);
2241
- sX += dx;
2242
- }
2243
- destOffset += screenW;
2244
- srcYOffset += dy;
2200
+ destOffset += screenW;
2201
+ srcYOffset += dy;
2202
+ }
2203
+ break;
2204
+
2205
+ case HARD_LIGHT:
2206
+ for (int y = 0; y < destH; y++) {
2207
+ sX = srcXOffset;
2208
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2209
+ for (int x = 0; x < destW; x++) {
2210
+ destPixels[destOffset + x] =
2211
+ blend_hard_light(destPixels[destOffset + x],
2212
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2213
+ sX += dx;
2245
2214
  }
2246
- break;
2247
-
2248
- case SOFT_LIGHT:
2249
- for (int y = 0; y < destH; y++) {
2250
- sX = srcXOffset;
2251
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2252
- for (int x = 0; x < destW; x++) {
2253
- destPixels[destOffset + x] =
2254
- blend_soft_light(destPixels[destOffset + x],
2255
- srcBuffer[sY + (sX >> PRECISIONB)]);
2256
- sX += dx;
2257
- }
2258
- destOffset += screenW;
2259
- srcYOffset += dy;
2215
+ destOffset += screenW;
2216
+ srcYOffset += dy;
2217
+ }
2218
+ break;
2219
+
2220
+ case SOFT_LIGHT:
2221
+ for (int y = 0; y < destH; y++) {
2222
+ sX = srcXOffset;
2223
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2224
+ for (int x = 0; x < destW; x++) {
2225
+ destPixels[destOffset + x] =
2226
+ blend_soft_light(destPixels[destOffset + x],
2227
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2228
+ sX += dx;
2260
2229
  }
2261
- break;
2262
-
2263
- // davbol - proposed 2007-01-09
2264
- case DODGE:
2265
- for (int y = 0; y < destH; y++) {
2266
- sX = srcXOffset;
2267
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2268
- for (int x = 0; x < destW; x++) {
2269
- destPixels[destOffset + x] =
2270
- blend_dodge(destPixels[destOffset + x],
2271
- srcBuffer[sY + (sX >> PRECISIONB)]);
2272
- sX += dx;
2273
- }
2274
- destOffset += screenW;
2275
- srcYOffset += dy;
2230
+ destOffset += screenW;
2231
+ srcYOffset += dy;
2232
+ }
2233
+ break;
2234
+
2235
+ // davbol - proposed 2007-01-09
2236
+ case DODGE:
2237
+ for (int y = 0; y < destH; y++) {
2238
+ sX = srcXOffset;
2239
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2240
+ for (int x = 0; x < destW; x++) {
2241
+ destPixels[destOffset + x] =
2242
+ blend_dodge(destPixels[destOffset + x],
2243
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2244
+ sX += dx;
2276
2245
  }
2277
- break;
2278
-
2279
- case BURN:
2280
- for (int y = 0; y < destH; y++) {
2281
- sX = srcXOffset;
2282
- sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2283
- for (int x = 0; x < destW; x++) {
2284
- destPixels[destOffset + x] =
2285
- blend_burn(destPixels[destOffset + x],
2286
- srcBuffer[sY + (sX >> PRECISIONB)]);
2287
- sX += dx;
2288
- }
2289
- destOffset += screenW;
2290
- srcYOffset += dy;
2246
+ destOffset += screenW;
2247
+ srcYOffset += dy;
2248
+ }
2249
+ break;
2250
+
2251
+ case BURN:
2252
+ for (int y = 0; y < destH; y++) {
2253
+ sX = srcXOffset;
2254
+ sY = (srcYOffset >> PRECISIONB) * img.pixelWidth;
2255
+ for (int x = 0; x < destW; x++) {
2256
+ destPixels[destOffset + x] =
2257
+ blend_burn(destPixels[destOffset + x],
2258
+ srcBuffer[sY + (sX >> PRECISIONB)]);
2259
+ sX += dx;
2291
2260
  }
2292
- break;
2293
-
2261
+ destOffset += screenW;
2262
+ srcYOffset += dy;
2294
2263
  }
2264
+ break;
2295
2265
  }
2296
2266
  }
2297
2267
 
2298
2268
 
2299
2269
  private void filter_new_scanline() {
2300
2270
  sX = srcXOffset;
2301
- fracV = srcYOffset & PREC_MAXVAL;
2271
+ int fracV = srcYOffset & PREC_MAXVAL;
2302
2272
  ifV = PREC_MAXVAL - fracV + 1;
2303
2273
  v1 = (srcYOffset >> PRECISIONB) * iw;
2304
2274
  v2 = min((srcYOffset >> PRECISIONB) + 1, ih1) * iw;
@@ -2306,14 +2276,18 @@ public class PImage implements PConstants, Cloneable {
2306
2276
 
2307
2277
 
2308
2278
  private int filter_bilinear() {
2309
- fracU = sX & PREC_MAXVAL;
2310
- ifU = PREC_MAXVAL - fracU + 1;
2311
- ul = (ifU * ifV) >> PRECISIONB;
2312
- ll = ifU - ul;
2313
- ur = ifV - ul;
2314
- lr = PREC_MAXVAL + 1 - ul - ll - ur;
2315
- u1 = (sX >> PRECISIONB);
2316
- u2 = min(u1 + 1, iw1);
2279
+ int cUL, cLL, cUR, cLR;
2280
+ int r, g, b, a;
2281
+
2282
+ // private fields
2283
+ int fracU = sX & PREC_MAXVAL;
2284
+ int ifU = PREC_MAXVAL - fracU + 1;
2285
+ int ul = (ifU * ifV) >> PRECISIONB;
2286
+ int ll = ifU - ul;
2287
+ int ur = ifV - ul;
2288
+ int lr = PREC_MAXVAL + 1 - ul - ll - ur;
2289
+ int u1 = (sX >> PRECISIONB);
2290
+ int u2 = min(u1 + 1, iw1);
2317
2291
 
2318
2292
  // get color values of the 4 neighbouring texels
2319
2293
  cUL = srcBuffer[v1 + u1];
@@ -2735,7 +2709,7 @@ int testFunction(int dst, int src) {
2735
2709
 
2736
2710
 
2737
2711
  /**
2738
- * Soft Light (Pegtop)
2712
+ * Soft Light (peg top)
2739
2713
  * O = (1 - D) * MULTIPLY(D, S) + D * SCREEN(D, S)
2740
2714
  * O = (1 - D) * DS + D * (1 - (1 - D)(1 - S))
2741
2715
  * O = 2DS + DD - 2DDS
@@ -2823,18 +2797,17 @@ int testFunction(int dst, int src) {
2823
2797
  }
2824
2798
 
2825
2799
 
2800
+
2826
2801
  //////////////////////////////////////////////////////////////
2827
2802
 
2828
2803
  // FILE I/O
2829
2804
 
2830
2805
 
2831
- protected boolean saveImpl(String filename) {
2832
- return false;
2833
- }
2834
-
2835
-
2836
2806
  static public PImage loadTIFF(InputStream input) { // ignore
2837
- byte tiff[] = PApplet.loadBytes(input);
2807
+ byte[] tiff = PApplet.loadBytes(input);
2808
+ if (tiff == null) {
2809
+ return null;
2810
+ }
2838
2811
 
2839
2812
  if ((tiff[42] != tiff[102]) || // width/height in both places
2840
2813
  (tiff[43] != tiff[103])) {
@@ -2883,8 +2856,8 @@ int testFunction(int dst, int src) {
2883
2856
  }
2884
2857
 
2885
2858
  protected boolean saveTIFF(OutputStream output) {
2886
- // shutting off the warning, people can figure this out themselves
2887
2859
  /*
2860
+ // shutting off this warning, people can figure this out themselves
2888
2861
  if (format != RGB) {
2889
2862
  System.err.println("Warning: only RGB information is saved with " +
2890
2863
  ".tif files. Use .tga or .png for ARGB images and others.");
@@ -2917,6 +2890,7 @@ int testFunction(int dst, int src) {
2917
2890
  return true;
2918
2891
 
2919
2892
  } catch (IOException e) {
2893
+ e.printStackTrace();
2920
2894
  }
2921
2895
  return false;
2922
2896
  }
@@ -3124,7 +3098,7 @@ int testFunction(int dst, int src) {
3124
3098
  /**
3125
3099
  * Creates a Targa32 formatted byte sequence of specified
3126
3100
  * pixel buffer using RLE compression.
3127
- * <p>
3101
+ * </p>
3128
3102
  * Also figured out how to avoid parsing the image upside-down
3129
3103
  * (there's a header flag to set the image origin to top-left)
3130
3104
  * </p>
@@ -3135,33 +3109,31 @@ int testFunction(int dst, int src) {
3135
3109
  * <LI><TT>ARGB</TT> &rarr; 32 bits
3136
3110
  * </UL>
3137
3111
  * All versions are RLE compressed.
3138
- *
3112
+ * </p>
3139
3113
  * Contributed by toxi 8-10 May 2005, based on this RLE
3140
3114
  * <A HREF="http://www.wotsit.org/download.asp?f=tga">specification</A>
3141
3115
  */
3142
3116
  protected boolean saveTGA(OutputStream output) {
3143
3117
  byte[] header = new byte[18];
3144
3118
 
3145
- switch (format) {
3146
- case ALPHA:
3147
- // save ALPHA images as 8bit grayscale
3148
- header[2] = 0x0B;
3149
- header[16] = 0x08;
3150
- header[17] = 0x28;
3151
- break;
3152
- case RGB:
3153
- header[2] = 0x0A;
3154
- header[16] = 24;
3155
- header[17] = 0x20;
3156
- break;
3157
- case ARGB:
3158
- header[2] = 0x0A;
3159
- header[16] = 32;
3160
- header[17] = 0x28;
3161
- break;
3162
- default:
3163
- throw new RuntimeException("Image format not recognized inside save()");
3164
- }
3119
+ if (format == ALPHA) { // save ALPHA images as 8bit grayscale
3120
+ header[2] = 0x0B;
3121
+ header[16] = 0x08;
3122
+ header[17] = 0x28;
3123
+
3124
+ } else if (format == RGB) {
3125
+ header[2] = 0x0A;
3126
+ header[16] = 24;
3127
+ header[17] = 0x20;
3128
+
3129
+ } else if (format == ARGB) {
3130
+ header[2] = 0x0A;
3131
+ header[16] = 32;
3132
+ header[17] = 0x28;
3133
+
3134
+ } else {
3135
+ throw new RuntimeException("Image format not recognized inside save()");
3136
+ }
3165
3137
  // set image dimensions lo-hi byte order
3166
3138
  header[12] = (byte) (pixelWidth & 0xff);
3167
3139
  header[13] = (byte) (pixelWidth >> 8);
@@ -3271,13 +3243,13 @@ int testFunction(int dst, int src) {
3271
3243
  return true;
3272
3244
 
3273
3245
  } catch (IOException e) {
3246
+ e.printStackTrace();
3274
3247
  return false;
3275
3248
  }
3276
3249
  }
3277
3250
 
3278
3251
 
3279
3252
  /**
3280
- * ( begin auto-generated from PImage_save.xml )
3281
3253
  *
3282
3254
  * Saves the image into a file. Append a file extension to the name of
3283
3255
  * the file, to indicate the file format to be used: either TIFF (.tif),
@@ -3285,13 +3257,12 @@ int testFunction(int dst, int src) {
3285
3257
  * in the filename, the image will save in TIFF format and .tif will be
3286
3258
  * added to the name. These files are saved to the sketch's folder, which
3287
3259
  * may be opened by selecting "Show sketch folder" from the "Sketch" menu.
3288
- * To save an image created within the code, rather
3260
+ * <br /><br />To save an image created within the code, rather
3289
3261
  * than through loading, it's necessary to make the image with the
3290
3262
  * <b>createImage()</b> function so it is aware of the location of the
3291
3263
  * program and can therefore save the file to the right place. See the
3292
3264
  * <b>createImage()</b> reference for more information.
3293
3265
  *
3294
- * ( end auto-generated )
3295
3266
  * <h3>Advanced</h3>
3296
3267
  * Save this image to disk.
3297
3268
  * <p>
@@ -3318,60 +3289,79 @@ int testFunction(int dst, int src) {
3318
3289
  * file with no error.
3319
3290
  *
3320
3291
  * @webref pimage:method
3321
- * @brief Saves the image to a TIFF, TARGA, PNG, or JPEG file
3292
+ * @webBrief Saves the image to a TIFF, TARGA, PNG, or JPEG file.
3322
3293
  * @usage application
3323
3294
  * @param filename a sequence of letters and numbers
3324
3295
  */
3325
- public boolean save(String filename) { // ignore
3326
- boolean success = false;
3296
+ public boolean save(String filename) { // ignore
3297
+ boolean success;
3327
3298
 
3328
- if (parent != null) {
3329
- // use savePath(), so that the intermediate directories are created
3330
- filename = parent.savePath(filename);
3299
+ if (parent != null) {
3300
+ // use savePath(), so that the intermediate directories are created
3301
+ filename = parent.savePath(filename);
3331
3302
 
3332
- } else {
3333
- File file = new File(filename);
3334
- if (file.isAbsolute()) {
3335
- // make sure that the intermediate folders have been created
3336
- PApplet.createPath(file);
3337
- } else {
3338
- String msg =
3339
- "PImage.save() requires an absolute path. " +
3340
- "Use createImage(), or pass savePath() to save().";
3341
- PGraphics.showException(msg);
3342
- }
3343
- }
3303
+ } else {
3304
+ File file = new File(filename);
3305
+ if (file.isAbsolute()) {
3306
+ // make sure that the intermediate folders have been created
3307
+ PApplet.createPath(file);
3308
+ } else {
3309
+ String msg =
3310
+ "PImage.save() requires an absolute path. " +
3311
+ "Use createImage(), or pass savePath() to save().";
3312
+ PGraphics.showException(msg);
3313
+ }
3314
+ }
3344
3315
 
3345
- // Make sure the pixel data is ready to go
3346
- loadPixels();
3316
+ // Make sure the pixel data is ready to go
3317
+ loadPixels();
3347
3318
 
3348
- try {
3349
- OutputStream os = null;
3319
+ try {
3320
+ final String lower = filename.toLowerCase();
3350
3321
 
3351
- if (saveImpl(filename)) {
3352
- return true;
3353
- }
3322
+ if (saveImpl(filename)) {
3323
+ return true;
3324
+ }
3354
3325
 
3355
- if (filename.toLowerCase().endsWith(".tga")) {
3356
- os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
3357
- success = saveTGA(os); //, pixels, width, height, format);
3326
+ if (lower.endsWith(".tga")) {
3327
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
3328
+ success = saveTGA(os); //, pixels, width, height, format);
3329
+ os.close();
3330
+
3331
+ } else { // fall-through case is TIFF
3332
+ // add a default extension and save uncompressed
3333
+ // TODO this is the only place in the api that we mess w/ file names,
3334
+ // and while arguably useful, seems like a weird precedent [fry 200816]
3335
+ if (!lower.endsWith(".tif") && !lower.endsWith(".tiff")) {
3336
+ filename += ".tif";
3337
+ }
3338
+ OutputStream os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
3339
+ success = saveTIFF(os); //, pixels, width, height);
3340
+ os.close();
3341
+ }
3358
3342
 
3359
- } else {
3360
- if (!filename.toLowerCase().endsWith(".tif") &&
3361
- !filename.toLowerCase().endsWith(".tiff")) {
3362
- // if no .tif extension, add it..
3363
- filename += ".tif";
3364
- }
3365
- os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
3366
- success = saveTIFF(os); //, pixels, width, height);
3367
- }
3368
- os.flush();
3369
- os.close();
3343
+ } catch (IOException e) {
3344
+ System.err.println("Error while saving image.");
3345
+ e.printStackTrace();
3346
+ success = false;
3347
+ }
3348
+ return success;
3349
+ }
3370
3350
 
3371
- } catch (IOException e) {
3372
- System.err.println("Error while saving image.");
3373
- success = false;
3374
- }
3375
- return success;
3376
- }
3351
+
3352
+ /**
3353
+ * Override this in subclasses to intercept save calls for other formats
3354
+ * or higher-performance implementations. When reaching this code, pixels
3355
+ * must be loaded and that path should be absolute.
3356
+ *
3357
+ * @param path must be a full path (not relative or simply a filename)
3358
+ */
3359
+ protected boolean saveImpl(String path) {
3360
+ // TODO Imperfect/temporary solution for alpha 2.
3361
+ // https://github.com/processing/processing4/wiki/Exorcising-AWT
3362
+ if (!PApplet.disableAWT) {
3363
+ return ShimAWT.saveImage(this, path);
3364
+ }
3365
+ return false;
3366
+ }
3377
3367
  }