picrate 2.1.2-java → 2.4.2-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }