propane 3.4.0-java → 3.4.1-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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/.mvn/extensions.xml +1 -2
  3. data/.travis.yml +2 -2
  4. data/CHANGELOG.md +2 -0
  5. data/README.md +12 -7
  6. data/Rakefile +2 -2
  7. data/lib/propane.rb +2 -2
  8. data/lib/propane/app.rb +18 -9
  9. data/lib/propane/helper_methods.rb +1 -1
  10. data/lib/propane/runner.rb +1 -1
  11. data/lib/propane/version.rb +1 -1
  12. data/library/color_group/color_group.rb +26 -0
  13. data/library/dxf/dxf.rb +4 -0
  14. data/library/net/net.rb +5 -0
  15. data/library/video_event/video_event.rb +2 -1
  16. data/pom.rb +3 -3
  17. data/pom.xml +3 -3
  18. data/propane.gemspec +1 -1
  19. data/src/main/java/japplemenubar/JAppleMenuBar.java +3 -3
  20. data/src/main/java/monkstone/ColorUtil.java +14 -0
  21. data/src/main/java/monkstone/MathToolModule.java +243 -194
  22. data/src/main/java/monkstone/filechooser/Chooser.java +1 -0
  23. data/src/main/java/monkstone/slider/WheelHandler.java +6 -5
  24. data/src/main/java/monkstone/vecmath/vec3/Vec3.java +3 -2
  25. data/src/main/java/monkstone/videoevent/CaptureEvent.java +27 -0
  26. data/src/main/java/monkstone/videoevent/{VideoInterface.java → MovieEvent.java} +10 -26
  27. data/src/main/java/processing/awt/PSurfaceAWT.java +1 -1
  28. data/src/main/java/processing/core/PApplet.java +1236 -599
  29. data/src/main/java/processing/core/PGraphics.java +59 -59
  30. data/src/main/java/processing/core/PImage.java +528 -129
  31. data/src/main/java/processing/core/PShape.java +10 -10
  32. data/src/main/java/processing/core/PVector.java +2 -2
  33. data/src/main/java/processing/core/ThinkDifferent.java +5 -7
  34. data/src/main/java/processing/dxf/RawDXF.java +404 -0
  35. data/src/main/java/processing/net/Client.java +744 -0
  36. data/src/main/java/processing/net/Server.java +388 -0
  37. data/src/main/java/processing/opengl/FontTexture.java +19 -20
  38. data/src/main/java/processing/opengl/FrameBuffer.java +27 -17
  39. data/src/main/java/processing/opengl/LinePath.java +512 -508
  40. data/src/main/java/processing/opengl/PGL.java +3106 -3066
  41. data/src/main/java/processing/opengl/PGraphicsOpenGL.java +4 -4
  42. data/src/main/java/processing/opengl/PShader.java +1442 -1341
  43. data/vendors/Rakefile +3 -27
  44. metadata +12 -25
  45. data/src/main/java/processing/core/util/image/ImageLoadFacade.java +0 -161
  46. data/src/main/java/processing/core/util/image/ImageSaveFacade.java +0 -169
  47. data/src/main/java/processing/core/util/image/constants/TifConstants.java +0 -45
  48. data/src/main/java/processing/core/util/image/load/AwtImageLoadStrategy.java +0 -80
  49. data/src/main/java/processing/core/util/image/load/Base64StringImageLoadStrategy.java +0 -73
  50. data/src/main/java/processing/core/util/image/load/FallbackImageLoadStrategy.java +0 -70
  51. data/src/main/java/processing/core/util/image/load/ImageIoImageLoadStrategy.java +0 -132
  52. data/src/main/java/processing/core/util/image/load/ImageLoadStrategy.java +0 -48
  53. data/src/main/java/processing/core/util/image/load/ImageLoadUtil.java +0 -45
  54. data/src/main/java/processing/core/util/image/load/TgaImageLoadStrategy.java +0 -255
  55. data/src/main/java/processing/core/util/image/load/TiffImageLoadStrategy.java +0 -98
  56. data/src/main/java/processing/core/util/image/save/ImageSaveStrategy.java +0 -49
  57. data/src/main/java/processing/core/util/image/save/ImageSaveUtil.java +0 -48
  58. data/src/main/java/processing/core/util/image/save/ImageWriterImageSaveStrategy.java +0 -179
  59. data/src/main/java/processing/core/util/image/save/SaveImageException.java +0 -41
  60. data/src/main/java/processing/core/util/image/save/TgaImageSaveStrategy.java +0 -198
  61. data/src/main/java/processing/core/util/image/save/TiffImageSaveStrategy.java +0 -91
  62. data/src/main/java/processing/core/util/image/save/TiffNakedFilenameImageSaveStrategy.java +0 -57
  63. data/src/main/java/processing/core/util/io/InputFactory.java +0 -285
  64. data/src/main/java/processing/core/util/io/PathUtil.java +0 -109
@@ -207,12 +207,12 @@ public class PGraphics extends PImage implements PConstants {
207
207
  /**
208
208
  * Array of hint[] items. These are hacks to get around various
209
209
  * temporary workarounds inside the environment.
210
- * <p/>
210
+ *
211
211
  * Note that this array cannot be static, as a hint() may result in a
212
212
  * runtime change specific to a renderer. For instance, calling
213
213
  * hint(DISABLE_DEPTH_TEST) has to call glDisable() right away on an
214
214
  * instance of PGraphicsOpenGL.
215
- * <p/>
215
+ *
216
216
  * The hints[] array is allocated early on because it might
217
217
  * be used inside beginDraw(), allocate(), etc.
218
218
  */
@@ -910,7 +910,7 @@ public class PGraphics extends PImage implements PConstants {
910
910
  *
911
911
  * ( end auto-generated )
912
912
  * <h3>Advanced</h3>
913
- * <p/>
913
+ *
914
914
  * When creating your own PGraphics, you should call this when
915
915
  * you're finished drawing.
916
916
  *
@@ -1605,11 +1605,11 @@ public class PGraphics extends PImage implements PConstants {
1605
1605
  * All shapes are constructed by connecting a series of vertices.
1606
1606
  * <b>vertex()</b> is used to specify the vertex coordinates for points,
1607
1607
  * lines, triangles, quads, and polygons and is used exclusively within the
1608
- * <b>beginShape()</b> and <b>endShape()</b> function.<br />
1609
- * <br />
1608
+ * <b>beginShape()</b> and <b>endShape()</b> function.
1609
+ *
1610
1610
  * Drawing a vertex in 3D using the <b>z</b> parameter requires the P3D
1611
- * parameter in combination with size as shown in the above example.<br />
1612
- * <br />
1611
+ * parameter in combination with size as shown in the above example.
1612
+ *
1613
1613
  * This function is also used to map a texture onto the geometry. The
1614
1614
  * <b>texture()</b> function declares the texture to apply to the geometry
1615
1615
  * and the <b>u</b> and <b>v</b> coordinates set define the mapping of this
@@ -1652,12 +1652,12 @@ public class PGraphics extends PImage implements PConstants {
1652
1652
  * coincident with a call to vertex. As of beta, this was moved to
1653
1653
  * the protected method you see here, and called from an optional
1654
1654
  * param of and overloaded vertex().
1655
- * <p/>
1655
+ *
1656
1656
  * The parameters depend on the current textureMode. When using
1657
1657
  * textureMode(IMAGE), the coordinates will be relative to the size
1658
1658
  * of the image texture, when used with textureMode(NORMAL),
1659
1659
  * they'll be in the range 0..1.
1660
- * <p/>
1660
+ *
1661
1661
  * Used by both PGraphics2D (for images) and PGraphics3D.
1662
1662
  */
1663
1663
  protected void vertexTexture(float u, float v) {
@@ -3746,8 +3746,8 @@ public class PGraphics extends PImage implements PConstants {
3746
3746
  * <b>image()</b> to set the location of one corner of the image and uses
3747
3747
  * the fourth and fifth parameters to set the opposite corner. Use
3748
3748
  * <b>imageMode(CENTER)</b> to draw images centered at the given x and y
3749
- * position.<br />
3750
- * <br />
3749
+ * position.
3750
+ *
3751
3751
  * The parameter to <b>imageMode()</b> must be written in ALL CAPS because
3752
3752
  * Processing is a case-sensitive language.
3753
3753
  *
@@ -3781,13 +3781,13 @@ public class PGraphics extends PImage implements PConstants {
3781
3781
  * <b>x</b> and <b>y</b> parameters define the location of the image from
3782
3782
  * its upper-left corner. The image is displayed at its original size
3783
3783
  * unless the <b>width</b> and <b>height</b> parameters specify a different
3784
- * size.<br />
3785
- * <br />
3784
+ * size.
3785
+ *
3786
3786
  * The <b>imageMode()</b> function changes the way the parameters work. For
3787
3787
  * example, a call to <b>imageMode(CORNERS)</b> will change the
3788
3788
  * <b>width</b> and <b>height</b> parameters to define the x and y values
3789
- * of the opposite corner of the image.<br />
3790
- * <br />
3789
+ * of the opposite corner of the image.
3790
+ *
3791
3791
  * The color of an image may be modified with the <b>tint()</b> function.
3792
3792
  * This function will maintain transparency for GIF and PNG images.
3793
3793
  *
@@ -3891,7 +3891,7 @@ public class PGraphics extends PImage implements PConstants {
3891
3891
  /**
3892
3892
  * Expects x1, y1, x2, y2 coordinates where (x2 >= x1) and (y2 >= y1).
3893
3893
  * If tint() has been called, the image will be colored.
3894
- * <p/>
3894
+ *
3895
3895
  * The default implementation draws an image as a textured quad.
3896
3896
  * The (u, v) coordinates are in image space (they're ints, after all..)
3897
3897
  */
@@ -4016,7 +4016,7 @@ public class PGraphics extends PImage implements PConstants {
4016
4016
  * to <b>shapeMode(CORNERS)</b>, for example, will change the width and
4017
4017
  * height parameters to define the x and y values of the opposite corner of
4018
4018
  * the shape.
4019
- * <br /><br />
4019
+
4020
4020
  * Note complex shapes may draw awkwardly with P3D. This renderer does not
4021
4021
  * yet support shapes that have holes or complicated breaks.
4022
4022
  *
@@ -4255,10 +4255,10 @@ public class PGraphics extends PImage implements PConstants {
4255
4255
  * <b>text()</b> function. If no <b>size</b> parameter is input, the font
4256
4256
  * will appear at its original size (the size it was created at with the
4257
4257
  * "Create Font..." tool) until it is changed with <b>textSize()</b>. <br
4258
- * /> <br /> Because fonts are usually bitmaped, you should create fonts at
4258
+ * /> Because fonts are usually bitmaped, you should create fonts at
4259
4259
  * the sizes that will be used most commonly. Using <b>textFont()</b>
4260
4260
  * without the size parameter will result in the cleanest-looking text. <br
4261
- * /><br /> With the default (JAVA2D) and PDF renderers, it's also possible
4261
+ * /> With the default (JAVA2D) and PDF renderers, it's also possible
4262
4262
  * to enable the use of native fonts via the command
4263
4263
  * <b>hint(ENABLE_NATIVE_FONTS)</b>. This will produce vector text in
4264
4264
  * JAVA2D sketches and PDF output in cases where the vector data is
@@ -4372,16 +4372,16 @@ public class PGraphics extends PImage implements PConstants {
4372
4372
  *
4373
4373
  * Sets the way text draws to the screen. In the default configuration, the
4374
4374
  * <b>MODEL</b> mode, it's possible to rotate, scale, and place letters in
4375
- * two and three dimensional space.<br />
4376
- * <br />
4375
+ * two and three dimensional space.
4376
+ *
4377
4377
  * The <b>SHAPE</b> mode draws text using the the glyph outlines of
4378
4378
  * individual characters rather than as textures. This mode is only
4379
4379
  * supported with the <b>PDF</b> and <b>P3D</b> renderer settings. With the
4380
4380
  * <b>PDF</b> renderer, you must call <b>textMode(SHAPE)</b> before any
4381
4381
  * other drawing occurs. If the outlines are not available, then
4382
4382
  * <b>textMode(SHAPE)</b> will be ignored and <b>textMode(MODEL)</b> will
4383
- * be used instead.<br />
4384
- * <br />
4383
+ * be used instead.
4384
+ *
4385
4385
  * The <b>textMode(SHAPE)</b> option in <b>P3D</b> can be combined with
4386
4386
  * <b>beginRaw()</b> to write vector-accurate text to 2D and 3D output
4387
4387
  * files, for instance <b>DXF</b> or <b>PDF</b>. The <b>SHAPE</b> mode is
@@ -4575,7 +4575,7 @@ public class PGraphics extends PImage implements PConstants {
4575
4575
  * with the <b>fill()</b> function. The text displays in relation to the
4576
4576
  * <b>textAlign()</b> function, which gives the option to draw to the left,
4577
4577
  * right, and center of the coordinates.
4578
- * <br /><br />
4578
+
4579
4579
  * The <b>x2</b> and <b>y2</b> parameters define a rectangular area to
4580
4580
  * display within and may only be used with string data. For text drawn
4581
4581
  * inside a rectangle, the coordinates are interpreted based on the current
@@ -4745,11 +4745,11 @@ public class PGraphics extends PImage implements PConstants {
4745
4745
  * Draw text in a box that is constrained to a particular size.
4746
4746
  * The current rectMode() determines what the coordinates mean
4747
4747
  * (whether x1/y1/x2/y2 or x/y/w/h).
4748
- * <P/>
4748
+ *
4749
4749
  * Note that the x,y coords of the start of the box
4750
4750
  * will align with the *ascent* of the text, not the baseline,
4751
4751
  * as is the case for the other text() functions.
4752
- * <P/>
4752
+ *
4753
4753
  * Newlines that are \n (Unix newline or linefeed char, ascii 10)
4754
4754
  * are honored, and \r (carriage return, Windows and Mac OS) are
4755
4755
  * ignored.
@@ -5173,8 +5173,8 @@ public class PGraphics extends PImage implements PConstants {
5173
5173
  * They allow you to change the style and transformation settings
5174
5174
  * and later return to what you had. When a new state is started
5175
5175
  * with push(), it builds on the current style and transform
5176
- * information.<br />
5177
- * <br />
5176
+ * information.
5177
+ *
5178
5178
  * <b>push()</b> stores information related to the current
5179
5179
  * transformation state and style settings controlled by the
5180
5180
  * following functions: <b>rotate()</b>, <b>translate()</b>,
@@ -5182,8 +5182,8 @@ public class PGraphics extends PImage implements PConstants {
5182
5182
  * <b>strokeWeight()</b>, <b>strokeCap()</b>, <b>strokeJoin()</b>,
5183
5183
  * <b>imageMode()</b>, <b>rectMode()</b>, <b>ellipseMode()</b>,
5184
5184
  * <b>colorMode()</b>, <b>textAlign()</b>, <b>textFont()</b>,
5185
- * <b>textMode()</b>, <b>textSize()</b>, <b>textLeading()</b>.<br />
5186
- * <br />
5185
+ * <b>textMode()</b>, <b>textSize()</b>, <b>textLeading()</b>.
5186
+ *
5187
5187
  * The <b>push()</b> and <b>pop()</b> functions were added with
5188
5188
  * Processing 3.5. They can be used in place of <b>pushMatrix()</b>,
5189
5189
  * <b>popMatrix()</b>, <b>pushStyles()</b>, and <b>popStyles()</b>.
@@ -5209,9 +5209,9 @@ public class PGraphics extends PImage implements PConstants {
5209
5209
  * Note that these functions are always used together. They allow
5210
5210
  * you to change the style and transformation settings and later
5211
5211
  * return to what you had. When a new state is started with push(),
5212
- * it builds on the current style and transform information.<br />
5213
- * <br />
5214
- * <br />
5212
+ * it builds on the current style and transform information.
5213
+ *
5214
+ *
5215
5215
  * <b>push()</b> stores information related to the current
5216
5216
  * transformation state and style settings controlled by the
5217
5217
  * following functions: <b>rotate()</b>, <b>translate()</b>,
@@ -5219,8 +5219,8 @@ public class PGraphics extends PImage implements PConstants {
5219
5219
  * <b>strokeWeight()</b>, <b>strokeCap()</b>, <b>strokeJoin()</b>,
5220
5220
  * <b>imageMode()</b>, <b>rectMode()</b>, <b>ellipseMode()</b>,
5221
5221
  * <b>colorMode()</b>, <b>textAlign()</b>, <b>textFont()</b>,
5222
- * <b>textMode()</b>, <b>textSize()</b>, <b>textLeading()</b>.<br />
5223
- * <br />
5222
+ * <b>textMode()</b>, <b>textSize()</b>, <b>textLeading()</b>.
5223
+ *
5224
5224
  * The <b>push()</b> and <b>pop()</b> functions were added with
5225
5225
  * Processing 3.5. They can be used in place of <b>pushMatrix()</b>,
5226
5226
  * <b>popMatrix()</b>, <b>pushStyles()</b>, and <b>popStyles()</b>.
@@ -5799,14 +5799,14 @@ public class PGraphics extends PImage implements PConstants {
5799
5799
  * The <b>beginCamera()</b> and <b>endCamera()</b> functions enable
5800
5800
  * advanced customization of the camera space. The functions are useful if
5801
5801
  * you want to more control over camera movement, however for most users,
5802
- * the <b>camera()</b> function will be sufficient.<br /><br />The camera
5802
+ * the <b>camera()</b> function will be sufficient..containsThe camera
5803
5803
  * functions will replace any transformations (such as <b>rotate()</b> or
5804
5804
  * <b>translate()</b>) that occur before them in <b>draw()</b>, but they
5805
5805
  * will not automatically replace the camera transform itself. For this
5806
5806
  * reason, camera functions should be placed at the beginning of
5807
5807
  * <b>draw()</b> (so that transformations happen afterwards), and the
5808
5808
  * <b>camera()</b> function can be used after <b>beginCamera()</b> if you
5809
- * want to reset the camera before applying transformations.<br /><br
5809
+ * want to reset the camera before applying transformations.<br
5810
5810
  * />This function sets the matrix mode to the camera matrix so calls such
5811
5811
  * as <b>translate()</b>, <b>rotate()</b>, applyMatrix() and resetMatrix()
5812
5812
  * affect the camera. <b>beginCamera()</b> should always be used with a
@@ -6145,8 +6145,8 @@ public class PGraphics extends PImage implements PConstants {
6145
6145
  * returns the Y value for a given coordinate based on the current set of
6146
6146
  * transformations (scale, rotate, translate, etc.) The Y value can be used
6147
6147
  * to place an object in space relative to the location of the original
6148
- * point once the transformations are no longer in use.<br />
6149
- * <br />
6148
+ * point once the transformations are no longer in use.
6149
+ *
6150
6150
  * In the example, the <b>modelX()</b>, <b>modelY()</b>, and
6151
6151
  * <b>modelZ()</b> functions record the location of a box in space after
6152
6152
  * being placed using a series of translate and rotate commands. After
@@ -6176,8 +6176,8 @@ public class PGraphics extends PImage implements PConstants {
6176
6176
  * returns the Z value for a given coordinate based on the current set of
6177
6177
  * transformations (scale, rotate, translate, etc.) The Z value can be used
6178
6178
  * to place an object in space relative to the location of the original
6179
- * point once the transformations are no longer in use.<br />
6180
- * <br />
6179
+ * point once the transformations are no longer in use.
6180
+ *
6181
6181
  * In the example, the <b>modelX()</b>, <b>modelY()</b>, and
6182
6182
  * <b>modelZ()</b> functions record the location of a box in space after
6183
6183
  * being placed using a series of translate and rotate commands. After
@@ -6215,7 +6215,7 @@ public class PGraphics extends PImage implements PConstants {
6215
6215
  * <b>pushStyle()</b>, it builds on the current style information. The
6216
6216
  * <b>pushStyle()</b> and <b>popStyle()</b> functions can be embedded to
6217
6217
  * provide more control (see the second example above for a demonstration.)
6218
- * <br /><br />
6218
+
6219
6219
  * The style information controlled by the following functions are included
6220
6220
  * in the style:
6221
6221
  * fill(), stroke(), tint(), strokeWeight(), strokeCap(), strokeJoin(),
@@ -6629,25 +6629,25 @@ public class PGraphics extends PImage implements PConstants {
6629
6629
  * ( begin auto-generated from tint.xml )
6630
6630
  *
6631
6631
  * Sets the fill value for displaying images. Images can be tinted to
6632
- * specified colors or made transparent by setting the alpha.<br />
6633
- * <br />
6632
+ * specified colors or made transparent by setting the alpha.
6633
+ *
6634
6634
  * To make an image transparent, but not change it's color, use white as
6635
6635
  * the tint color and specify an alpha value. For instance, tint(255, 128)
6636
6636
  * will make an image 50% transparent (unless <b>colorMode()</b> has been
6637
- * used).<br />
6638
- * <br />
6637
+ * used).
6638
+ *
6639
6639
  * When using hexadecimal notation to specify a color, use "#" or "0x"
6640
6640
  * before the values (e.g. #CCFFAA, 0xFFCCFFAA). The # syntax uses six
6641
6641
  * digits to specify a color (the way colors are specified in HTML and
6642
6642
  * CSS). When using the hexadecimal notation starting with "0x", the
6643
6643
  * hexadecimal value must be specified with eight characters; the first two
6644
6644
  * characters define the alpha component and the remainder the red, green,
6645
- * and blue components.<br />
6646
- * <br />
6645
+ * and blue components.
6646
+ *
6647
6647
  * The value for the parameter "gray" must be less than or equal to the
6648
6648
  * current maximum value as specified by <b>colorMode()</b>. The default
6649
- * maximum value is 255.<br />
6650
- * <br />
6649
+ * maximum value is 255.
6650
+ *
6651
6651
  * The <b>tint()</b> function is also used to control the coloring of
6652
6652
  * textures in 3D.
6653
6653
  *
@@ -7243,9 +7243,9 @@ public class PGraphics extends PImage implements PConstants {
7243
7243
  *
7244
7244
  * Sets the falloff rates for point lights, spot lights, and ambient
7245
7245
  * lights. The parameters are used to determine the falloff with the
7246
- * following equation:<br /><br />d = distance from light position to
7247
- * vertex position<br />falloff = 1 / (CONSTANT + d * LINEAR + (d*d) *
7248
- * QUADRATIC)<br /><br />Like <b>fill()</b>, it affects only the elements
7246
+ * following equation:.containsd = distance from light position to
7247
+ * vertex positionfalloff = 1 / (CONSTANT + d * LINEAR + (d*d) *
7248
+ * QUADRATIC).containsLike <b>fill()</b>, it affects only the elements
7249
7249
  * which are created after it in the code. The default value if
7250
7250
  * <b>LightFalloff(1.0, 0.0, 0.0)</b>. Thinking about an ambient light with
7251
7251
  * a falloff can be tricky. It is used, for example, if you wanted a region
@@ -7904,12 +7904,12 @@ public class PGraphics extends PImage implements PConstants {
7904
7904
  *
7905
7905
  * Extracts the red value from a color, scaled to match current
7906
7906
  * <b>colorMode()</b>. This value is always returned as a float so be
7907
- * careful not to assign it to an int value.<br /><br />The red() function
7907
+ * careful not to assign it to an int value..containsThe red() function
7908
7908
  * is easy to use and undestand, but is slower than another technique. To
7909
7909
  * achieve the same results when working in <b>colorMode(RGB, 255)</b>, but
7910
7910
  * with greater speed, use the &gt;&gt; (right shift) operator with a bit
7911
7911
  * mask. For example, the following two lines of code are equivalent:<br
7912
- * /><pre>float r1 = red(myColor);<br />float r2 = myColor &gt;&gt; 16
7912
+ * /><pre>float r1 = red(myColor);float r2 = myColor &gt;&gt; 16
7913
7913
  * &amp; 0xFF;</pre>
7914
7914
  *
7915
7915
  * ( end auto-generated )
@@ -7937,12 +7937,12 @@ public class PGraphics extends PImage implements PConstants {
7937
7937
  *
7938
7938
  * Extracts the green value from a color, scaled to match current
7939
7939
  * <b>colorMode()</b>. This value is always returned as a float so be
7940
- * careful not to assign it to an int value.<br /><br />The <b>green()</b>
7940
+ * careful not to assign it to an int value..containsThe <b>green()</b>
7941
7941
  * function is easy to use and undestand, but is slower than another
7942
7942
  * technique. To achieve the same results when working in <b>colorMode(RGB,
7943
7943
  * 255)</b>, but with greater speed, use the &gt;&gt; (right shift)
7944
7944
  * operator with a bit mask. For example, the following two lines of code
7945
- * are equivalent:<br /><pre>float r1 = green(myColor);<br />float r2 =
7945
+ * are equivalent:<pre>float r1 = green(myColor);float r2 =
7946
7946
  * myColor &gt;&gt; 8 &amp; 0xFF;</pre>
7947
7947
  *
7948
7948
  * ( end auto-generated )
@@ -7970,12 +7970,12 @@ public class PGraphics extends PImage implements PConstants {
7970
7970
  *
7971
7971
  * Extracts the blue value from a color, scaled to match current
7972
7972
  * <b>colorMode()</b>. This value is always returned as a float so be
7973
- * careful not to assign it to an int value.<br /><br />The <b>blue()</b>
7973
+ * careful not to assign it to an int value..containsThe <b>blue()</b>
7974
7974
  * function is easy to use and undestand, but is slower than another
7975
7975
  * technique. To achieve the same results when working in <b>colorMode(RGB,
7976
7976
  * 255)</b>, but with greater speed, use a bit mask to remove the other
7977
7977
  * color components. For example, the following two lines of code are
7978
- * equivalent:<br /><pre>float r1 = blue(myColor);<br />float r2 = myColor
7978
+ * equivalent:<pre>float r1 = blue(myColor);float r2 = myColor
7979
7979
  * &amp; 0xFF;</pre>
7980
7980
  *
7981
7981
  * ( end auto-generated )
@@ -24,10 +24,13 @@
24
24
 
25
25
  package processing.core;
26
26
 
27
- import processing.core.util.image.ImageSaveFacade;
28
-
29
27
  import java.awt.*;
30
28
  import java.awt.image.*;
29
+ import java.io.*;
30
+ import java.util.Iterator;
31
+
32
+ import javax.imageio.*;
33
+ import javax.imageio.metadata.*;
31
34
 
32
35
 
33
36
  /**
@@ -40,11 +43,11 @@ import java.awt.image.*;
40
43
  * fields for the <b>width</b> and <b>height</b> of the image, as well as
41
44
  * an array called <b>pixels[]</b> that contains the values for every pixel
42
45
  * in the image. The methods described below allow easy access to the
43
- * image's pixels and alpha channel and simplify the process of compositing.
44
- * using the <b>pixels[]</b> array, be sure to use the
46
+ * image's pixels and alpha channel and simplify the process of compositing.<br/>
47
+ * <br/> using the <b>pixels[]</b> array, be sure to use the
45
48
  * <b>loadPixels()</b> method on the image to make sure that the pixel data
46
- * is properly loaded.
47
- * create a new image, use the <b>createImage()</b> function. Do not
49
+ * is properly loaded.<br/>
50
+ * <br/> create a new image, use the <b>createImage()</b> function. Do not
48
51
  * use the syntax <b>new PImage()</b>.
49
52
  *
50
53
  * ( end auto-generated )
@@ -58,6 +61,17 @@ import java.awt.image.*;
58
61
  */
59
62
  public class PImage implements PConstants, Cloneable {
60
63
 
64
+ private static final byte TIFF_HEADER[] = {
65
+ 77, 77, 0, 42, 0, 0, 0, 8, 0, 9, 0, -2, 0, 4, 0, 0, 0, 1, 0, 0,
66
+ 0, 0, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 3, 0, 0, 0, 1,
67
+ 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 3, 0, 0, 0, 122, 1, 6, 0, 3, 0,
68
+ 0, 0, 1, 0, 2, 0, 0, 1, 17, 0, 4, 0, 0, 0, 1, 0, 0, 3, 0, 1, 21,
69
+ 0, 3, 0, 0, 0, 1, 0, 3, 0, 0, 1, 22, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0,
70
+ 1, 23, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 8, 0, 8
71
+ };
72
+
73
+ private static final String TIFF_ERROR = "Error: Processing can only read its own TIFF files.";
74
+
61
75
  /**
62
76
  * Format for this image, one of RGB, ARGB or ALPHA.
63
77
  * note that RGB images still require 0xff in the high byte
@@ -75,8 +89,8 @@ public class PImage implements PConstants, Cloneable {
75
89
  * values. The <b>index</b> value defines the position of a value within
76
90
  * the array. For example, the statement <b>color b = pixels[230]</b> will
77
91
  * set the variable <b>b</b> to be equal to the value at that location in
78
- * the array.<br />
79
- * <br />
92
+ * the array.
93
+ *
80
94
  * Before accessing this array, the data must loaded with the
81
95
  * <b>loadPixels()</b> function. After the array data has been modified,
82
96
  * the <b>updatePixels()</b> function must be run to update the changes.
@@ -184,11 +198,11 @@ public class PImage implements PConstants, Cloneable {
184
198
  * pixel in the image. A group of methods, described below, allow easy
185
199
  * access to the image's pixels and alpha channel and simplify the process
186
200
  * of compositing.
187
- *
201
+ *
188
202
  * Before using the <b>pixels[]</b> array, be sure to use the
189
203
  * <b>loadPixels()</b> method on the image to make sure that the pixel data
190
204
  * is properly loaded.
191
- *
205
+ *
192
206
  * To create a new image, use the <b>createImage()</b> function (do not use
193
207
  * <b>new PImage()</b>).
194
208
  * ( end auto-generated )
@@ -236,6 +250,7 @@ public class PImage implements PConstants, Cloneable {
236
250
  init(width, height, format, factor);
237
251
  }
238
252
 
253
+
239
254
  /**
240
255
  * Do not remove, see notes in the other variant.
241
256
  */
@@ -266,7 +281,7 @@ public class PImage implements PConstants, Cloneable {
266
281
  /**
267
282
  * Check the alpha on an image, using a really primitive loop.
268
283
  */
269
- private void checkAlpha() {
284
+ protected void checkAlpha() {
270
285
  if (pixels == null) return;
271
286
 
272
287
  for (int i = 0; i < pixels.length; i++) {
@@ -315,8 +330,6 @@ public class PImage implements PConstants, Cloneable {
315
330
  this.format = format;
316
331
  this.pixelDensity = factor;
317
332
  this.pixels = pixels;
318
- this.pixelWidth = width * pixelDensity;
319
- this.pixelHeight = height * pixelDensity;
320
333
  }
321
334
 
322
335
  /**
@@ -329,38 +342,6 @@ public class PImage implements PConstants, Cloneable {
329
342
  * the data and the img is valid
330
343
  */
331
344
  public PImage(Image img) {
332
- initFromImage(img);
333
- }
334
-
335
- /**
336
- * @nowebref
337
- *
338
- * @param requiresCheckAlpha
339
- */
340
- public PImage(Image img, boolean requiresCheckAlpha) {
341
- initFromImage(img);
342
-
343
- if (requiresCheckAlpha) {
344
- checkAlpha();
345
- }
346
- }
347
-
348
- /**
349
- * @nowebref
350
- *
351
- * @param requiresCheckAlpha
352
- */
353
- public PImage(Image img, boolean requiresCheckAlpha, PApplet parent) {
354
- initFromImage(img);
355
-
356
- this.parent = parent;
357
-
358
- if (requiresCheckAlpha) {
359
- checkAlpha();
360
- }
361
- }
362
-
363
- private void initFromImage(Image img) {
364
345
  format = RGB;
365
346
  if (img instanceof BufferedImage) {
366
347
  BufferedImage bi = (BufferedImage) img;
@@ -395,7 +376,7 @@ public class PImage implements PConstants, Cloneable {
395
376
  height = img.getHeight(null);
396
377
  pixels = new int[width * height];
397
378
  PixelGrabber pg =
398
- new PixelGrabber(img, 0, 0, width, height, pixels, 0, width);
379
+ new PixelGrabber(img, 0, 0, width, height, pixels, 0, width);
399
380
  try {
400
381
  pg.grabPixels();
401
382
  } catch (InterruptedException e) { }
@@ -405,6 +386,7 @@ public class PImage implements PConstants, Cloneable {
405
386
  pixelHeight = height;
406
387
  }
407
388
 
389
+
408
390
  /**
409
391
  * Use the getNative() method instead, which allows library interfaces to be
410
392
  * written in a cross-platform fashion for desktop, Android, and others.
@@ -490,7 +472,7 @@ public class PImage implements PConstants, Cloneable {
490
472
  *
491
473
  * <h3>Advanced</h3>
492
474
  * Call this when you want to mess with the pixels[] array.
493
- * <p/>
475
+ *
494
476
  * For subclasses where the pixels[] buffer isn't set by default,
495
477
  * this should copy all data into the pixels[] array
496
478
  *
@@ -524,7 +506,7 @@ public class PImage implements PConstants, Cloneable {
524
506
  * <b>updatePixels()</b>. Even if the renderer may not seem to use this
525
507
  * function in the current Processing release, this will always be subject
526
508
  * to change.
527
- *
509
+ *
528
510
  * Currently, none of the renderers use the additional parameters to
529
511
  * <b>updatePixels()</b>, however this may be implemented in the future.
530
512
  *
@@ -592,8 +574,8 @@ public class PImage implements PConstants, Cloneable {
592
574
  * Resize the image to a new width and height. To make the image scale
593
575
  * proportionally, use 0 as the value for the <b>wide</b> or <b>high</b>
594
576
  * parameter. For instance, to make the width of an image 150 pixels, and
595
- * change the height using the same proportion, use resize(150, 0).<br />
596
- * <br />
577
+ * change the height using the same proportion, use resize(150, 0).
578
+ *
597
579
  * Even though a PGraphics is technically a PImage, it is not possible to
598
580
  * rescale the image data found in a PGraphics. (It's simply not possible
599
581
  * to do this consistently across renderers: technically infeasible with
@@ -745,14 +727,14 @@ public class PImage implements PConstants, Cloneable {
745
727
  * the display window by specifying an additional <b>width</b> and
746
728
  * <b>height</b> parameter. When getting an image, the <b>x</b> and
747
729
  * <b>y</b> parameters define the coordinates for the upper-left corner of
748
- * the image, regardless of the current <b>imageMode()</b>.<br />
749
- * <br />
730
+ * the image, regardless of the current <b>imageMode()</b>.
731
+ *
750
732
  * If the pixel requested is outside of the image window, black is
751
733
  * returned. The numbers returned are scaled according to the current color
752
734
  * ranges, but only RGB values are returned by this function. For example,
753
735
  * even though you may have drawn a shape with <b>colorMode(HSB)</b>, the
754
- * numbers returned will be in RGB format.<br />
755
- * <br />
736
+ * numbers returned will be in RGB format.
737
+ *
756
738
  * Getting the color of a single pixel with <b>get(x, y)</b> is easy, but
757
739
  * not as fast as grabbing the data directly from <b>pixels[]</b>. The
758
740
  * equivalent statement to <b>get(x, y)</b> using <b>pixels[]</b> is
@@ -899,15 +881,15 @@ public class PImage implements PConstants, Cloneable {
899
881
  * ( begin auto-generated from PImage_set.xml )
900
882
  *
901
883
  * Changes the color of any pixel or writes an image directly into the
902
- * display window.<br />
903
- * <br />
884
+ * display window.
885
+ *
904
886
  * The <b>x</b> and <b>y</b> parameters specify the pixel to change and the
905
887
  * <b>color</b> parameter specifies the color value. The color parameter is
906
888
  * affected by the current color mode (the default is RGB values from 0 to
907
889
  * 255). When setting an image, the <b>x</b> and <b>y</b> parameters define
908
890
  * the coordinates for the upper-left corner of the image, regardless of
909
891
  * the current <b>imageMode()</b>.
910
- * <br /><br />
892
+
911
893
  * Setting the color of a single pixel with <b>set(x, y)</b> is easy, but
912
894
  * not as fast as putting the data directly into <b>pixels[]</b>. The
913
895
  * equivalent statement to <b>set(x, y, #000000)</b> using <b>pixels[]</b>
@@ -1023,8 +1005,8 @@ public class PImage implements PConstants, Cloneable {
1023
1005
  * Masks part of an image from displaying by loading another image and
1024
1006
  * using it as an alpha channel. This mask image should only contain
1025
1007
  * grayscale data, but only the blue color channel is used. The mask image
1026
- * needs to be the same size as the image to which it is applied.<br />
1027
- * <br />
1008
+ * needs to be the same size as the image to which it is applied.
1009
+ *
1028
1010
  * In addition to using a mask image, an integer array containing the alpha
1029
1011
  * channel data can be specified directly. This method is useful for
1030
1012
  * creating dynamically generated alpha masks. This array must be of the
@@ -1138,28 +1120,28 @@ public class PImage implements PConstants, Cloneable {
1138
1120
  /**
1139
1121
  * ( begin auto-generated from PImage_filter.xml )
1140
1122
  *
1141
- * Filters an image as defined by one of the following modes:<br /><br
1123
+ * Filters an image as defined by one of the following modes:<br
1142
1124
  * />THRESHOLD - converts the image to black and white pixels depending if
1143
1125
  * they are above or below the threshold defined by the level parameter.
1144
1126
  * The level must be between 0.0 (black) and 1.0(white). If no level is
1145
- * specified, 0.5 is used.<br />
1146
- * <br />
1147
- * GRAY - converts any colors in the image to grayscale equivalents<br />
1148
- * <br />
1149
- * INVERT - sets each pixel to its inverse value<br />
1150
- * <br />
1127
+ * specified, 0.5 is used.
1128
+ *
1129
+ * GRAY - converts any colors in the image to grayscale equivalents
1130
+ *
1131
+ * INVERT - sets each pixel to its inverse value
1132
+ *
1151
1133
  * POSTERIZE - limits each channel of the image to the number of colors
1152
- * specified as the level parameter<br />
1153
- * <br />
1134
+ * specified as the level parameter
1135
+ *
1154
1136
  * BLUR - executes a Guassian blur with the level parameter specifying the
1155
1137
  * extent of the blurring. If no level parameter is used, the blur is
1156
- * equivalent to Guassian blur of radius 1<br />
1157
- * <br />
1158
- * OPAQUE - sets the alpha channel to entirely opaque<br />
1159
- * <br />
1138
+ * equivalent to Guassian blur of radius 1
1139
+ *
1140
+ * OPAQUE - sets the alpha channel to entirely opaque
1141
+ *
1160
1142
  * ERODE - reduces the light areas with the amount defined by the level
1161
- * parameter<br />
1162
- * <br />
1143
+ * parameter
1144
+ *
1163
1145
  * DILATE - increases the light areas with the amount defined by the level parameter
1164
1146
  *
1165
1147
  * ( end auto-generated )
@@ -1178,7 +1160,7 @@ public class PImage implements PConstants, Cloneable {
1178
1160
  * </UL>
1179
1161
  * Luminance conversion code contributed by
1180
1162
  * <A HREF="http://www.toxi.co.uk">toxi</A>
1181
- * <P/>
1163
+ *
1182
1164
  * Gaussian blur code contributed by
1183
1165
  * <A HREF="http://incubator.quasimondo.com">Mario Klingemann</A>
1184
1166
  *
@@ -1695,7 +1677,7 @@ public class PImage implements PConstants, Cloneable {
1695
1677
  * source pixels to fit the specified target region. No alpha information
1696
1678
  * is used in the process, however if the source image has an alpha channel
1697
1679
  * set, it will be copied as well.
1698
- * <br /><br />
1680
+
1699
1681
  * As of release 0149, this function ignores <b>imageMode()</b>.
1700
1682
  *
1701
1683
  * ( end auto-generated )
@@ -1855,47 +1837,47 @@ public class PImage implements PConstants, Cloneable {
1855
1837
  * Blends a region of pixels into the image specified by the <b>img</b>
1856
1838
  * parameter. These copies utilize full alpha channel support and a choice
1857
1839
  * of the following modes to blend the colors of source pixels (A) with the
1858
- * ones of pixels in the destination image (B):<br />
1859
- * <br />
1860
- * BLEND - linear interpolation of colours: C = A*factor + B<br />
1861
- * <br />
1862
- * ADD - additive blending with white clip: C = min(A*factor + B, 255)<br />
1863
- * <br />
1840
+ * ones of pixels in the destination image (B):
1841
+ *
1842
+ * BLEND - linear interpolation of colours: C = A*factor + B
1843
+ *
1844
+ * ADD - additive blending with white clip: C = min(A*factor + B, 255)
1845
+ *
1864
1846
  * SUBTRACT - subtractive blending with black clip: C = max(B - A*factor,
1865
- * 0)<br />
1866
- * <br />
1867
- * DARKEST - only the darkest colour succeeds: C = min(A*factor, B)<br />
1868
- * <br />
1869
- * LIGHTEST - only the lightest colour succeeds: C = max(A*factor, B)<br />
1870
- * <br />
1871
- * DIFFERENCE - subtract colors from underlying image.<br />
1872
- * <br />
1873
- * EXCLUSION - similar to DIFFERENCE, but less extreme.<br />
1874
- * <br />
1875
- * MULTIPLY - Multiply the colors, result will always be darker.<br />
1876
- * <br />
1877
- * SCREEN - Opposite multiply, uses inverse values of the colors.<br />
1878
- * <br />
1847
+ * 0)
1848
+ *
1849
+ * DARKEST - only the darkest colour succeeds: C = min(A*factor, B)
1850
+ *
1851
+ * LIGHTEST - only the lightest colour succeeds: C = max(A*factor, B)
1852
+ *
1853
+ * DIFFERENCE - subtract colors from underlying image.
1854
+ *
1855
+ * EXCLUSION - similar to DIFFERENCE, but less extreme.
1856
+ *
1857
+ * MULTIPLY - Multiply the colors, result will always be darker.
1858
+ *
1859
+ * SCREEN - Opposite multiply, uses inverse values of the colors.
1860
+ *
1879
1861
  * OVERLAY - A mix of MULTIPLY and SCREEN. Multiplies dark values,
1880
- * and screens light values.<br />
1881
- * <br />
1882
- * HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower.<br />
1883
- * <br />
1862
+ * and screens light values.
1863
+ *
1864
+ * HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower.
1865
+ *
1884
1866
  * SOFT_LIGHT - Mix of DARKEST and LIGHTEST.
1885
- * Works like OVERLAY, but not as harsh.<br />
1886
- * <br />
1867
+ * Works like OVERLAY, but not as harsh.
1868
+ *
1887
1869
  * DODGE - Lightens light tones and increases contrast, ignores darks.
1888
- * Called "Color Dodge" in Illustrator and Photoshop.<br />
1889
- * <br />
1870
+ * Called "Color Dodge" in Illustrator and Photoshop.
1871
+ *
1890
1872
  * BURN - Darker areas are applied, increasing contrast, ignores lights.
1891
- * Called "Color Burn" in Illustrator and Photoshop.<br />
1892
- * <br />
1873
+ * Called "Color Burn" in Illustrator and Photoshop.
1874
+ *
1893
1875
  * All modes use the alpha information (highest byte) of source image
1894
1876
  * pixels as the blending factor. If the source and destination regions are
1895
1877
  * different sizes, the image will be automatically resized to match the
1896
1878
  * destination size. If the <b>srcImg</b> parameter is not used, the
1897
- * display window is used as the source image.<br />
1898
- * <br />
1879
+ * display window is used as the source image.
1880
+ *
1899
1881
  * As of release 0149, this function ignores <b>imageMode()</b>.
1900
1882
  *
1901
1883
  * ( end auto-generated )
@@ -3010,18 +2992,385 @@ int testFunction(int dst, int src) {
3010
2992
 
3011
2993
  // FILE I/O
3012
2994
 
2995
+ static protected PImage loadTIFF(byte tiff[]) {
2996
+ if ((tiff[42] != tiff[102]) || // width/height in both places
2997
+ (tiff[43] != tiff[103])) {
2998
+ System.err.println(TIFF_ERROR);
2999
+ return null;
3000
+ }
3001
+
3002
+ int width =
3003
+ ((tiff[30] & 0xff) << 8) | (tiff[31] & 0xff);
3004
+ int height =
3005
+ ((tiff[42] & 0xff) << 8) | (tiff[43] & 0xff);
3006
+
3007
+ int count =
3008
+ ((tiff[114] & 0xff) << 24) |
3009
+ ((tiff[115] & 0xff) << 16) |
3010
+ ((tiff[116] & 0xff) << 8) |
3011
+ (tiff[117] & 0xff);
3012
+ if (count != width * height * 3) {
3013
+ System.err.println(TIFF_ERROR + " (" + width + ", " + height +")");
3014
+ return null;
3015
+ }
3016
+
3017
+ // check the rest of the header
3018
+ for (int i = 0; i < TIFF_HEADER.length; i++) {
3019
+ if ((i == 30) || (i == 31) || (i == 42) || (i == 43) ||
3020
+ (i == 102) || (i == 103) ||
3021
+ (i == 114) || (i == 115) || (i == 116) || (i == 117)) continue;
3022
+
3023
+ if (tiff[i] != TIFF_HEADER[i]) {
3024
+ System.err.println(TIFF_ERROR + " (" + i + ")");
3025
+ return null;
3026
+ }
3027
+ }
3028
+
3029
+ PImage outgoing = new PImage(width, height, RGB);
3030
+ int index = 768;
3031
+ count /= 3;
3032
+ for (int i = 0; i < count; i++) {
3033
+ outgoing.pixels[i] =
3034
+ 0xFF000000 |
3035
+ (tiff[index++] & 0xff) << 16 |
3036
+ (tiff[index++] & 0xff) << 8 |
3037
+ (tiff[index++] & 0xff);
3038
+ }
3039
+ return outgoing;
3040
+ }
3041
+
3042
+ protected boolean saveTIFF(OutputStream output) {
3043
+ // shutting off the warning, people can figure this out themselves
3044
+ /*
3045
+ if (format != RGB) {
3046
+ System.err.println("Warning: only RGB information is saved with " +
3047
+ ".tif files. Use .tga or .png for ARGB images and others.");
3048
+ }
3049
+ */
3050
+ try {
3051
+ byte tiff[] = new byte[768];
3052
+ System.arraycopy(
3053
+ TIFF_HEADER,
3054
+ 0,
3055
+ tiff,
3056
+ 0,
3057
+ TIFF_HEADER.length
3058
+ );
3059
+
3060
+ tiff[30] = (byte) ((pixelWidth >> 8) & 0xff);
3061
+ tiff[31] = (byte) ((pixelWidth) & 0xff);
3062
+ tiff[42] = tiff[102] = (byte) ((pixelHeight >> 8) & 0xff);
3063
+ tiff[43] = tiff[103] = (byte) ((pixelHeight) & 0xff);
3064
+
3065
+ int count = pixelWidth*pixelHeight*3;
3066
+ tiff[114] = (byte) ((count >> 24) & 0xff);
3067
+ tiff[115] = (byte) ((count >> 16) & 0xff);
3068
+ tiff[116] = (byte) ((count >> 8) & 0xff);
3069
+ tiff[117] = (byte) ((count) & 0xff);
3070
+
3071
+ // spew the header to the disk
3072
+ output.write(tiff);
3073
+
3074
+ for (int i = 0; i < pixels.length; i++) {
3075
+ output.write((pixels[i] >> 16) & 0xff);
3076
+ output.write((pixels[i] >> 8) & 0xff);
3077
+ output.write(pixels[i] & 0xff);
3078
+ }
3079
+ output.flush();
3080
+ return true;
3081
+
3082
+ } catch (IOException e) {
3083
+ e.printStackTrace();
3084
+ }
3085
+ return false;
3086
+ }
3087
+
3088
+
3089
+ /**
3090
+ * Creates a Targa32 formatted byte sequence of specified
3091
+ * pixel buffer using RLE compression.
3092
+ * </p>
3093
+ * Also figured out how to avoid parsing the image upside-down
3094
+ * (there's a header flag to set the image origin to top-left)
3095
+ * </p>
3096
+ * Starting with revision 0092, the format setting is taken into account:
3097
+ * <UL>
3098
+ * <LI><TT>ALPHA</TT> images written as 8bit grayscale (uses lowest byte)
3099
+ * <LI><TT>RGB</TT> &rarr; 24 bits
3100
+ * <LI><TT>ARGB</TT> &rarr; 32 bits
3101
+ * </UL>
3102
+ * All versions are RLE compressed.
3103
+ * </p>
3104
+ * Contributed by toxi 8-10 May 2005, based on this RLE
3105
+ * <A HREF="http://www.wotsit.org/download.asp?f=tga">specification</A>
3106
+ */
3107
+ protected boolean saveTGA(OutputStream output) {
3108
+ byte header[] = new byte[18];
3109
+
3110
+ if (format == ALPHA) { // save ALPHA images as 8bit grayscale
3111
+ header[2] = 0x0B;
3112
+ header[16] = 0x08;
3113
+ header[17] = 0x28;
3114
+
3115
+ } else if (format == RGB) {
3116
+ header[2] = 0x0A;
3117
+ header[16] = 24;
3118
+ header[17] = 0x20;
3119
+
3120
+ } else if (format == ARGB) {
3121
+ header[2] = 0x0A;
3122
+ header[16] = 32;
3123
+ header[17] = 0x28;
3124
+
3125
+ } else {
3126
+ throw new RuntimeException("Image format not recognized inside save()");
3127
+ }
3128
+ // set image dimensions lo-hi byte order
3129
+ header[12] = (byte) (pixelWidth & 0xff);
3130
+ header[13] = (byte) (pixelWidth >> 8);
3131
+ header[14] = (byte) (pixelHeight & 0xff);
3132
+ header[15] = (byte) (pixelHeight >> 8);
3133
+
3134
+ try {
3135
+ output.write(header);
3136
+
3137
+ int maxLen = pixelHeight * pixelWidth;
3138
+ int index = 0;
3139
+ int col; //, prevCol;
3140
+ int[] currChunk = new int[128];
3141
+
3142
+ // 8bit image exporter is in separate loop
3143
+ // to avoid excessive conditionals...
3144
+ if (format == ALPHA) {
3145
+ while (index < maxLen) {
3146
+ boolean isRLE = false;
3147
+ int rle = 1;
3148
+ currChunk[0] = col = pixels[index] & 0xff;
3149
+ while (index + rle < maxLen) {
3150
+ if (col != (pixels[index + rle]&0xff) || rle == 128) {
3151
+ isRLE = (rle > 1);
3152
+ break;
3153
+ }
3154
+ rle++;
3155
+ }
3156
+ if (isRLE) {
3157
+ output.write(0x80 | (rle - 1));
3158
+ output.write(col);
3159
+
3160
+ } else {
3161
+ rle = 1;
3162
+ while (index + rle < maxLen) {
3163
+ int cscan = pixels[index + rle] & 0xff;
3164
+ if ((col != cscan && rle < 128) || rle < 3) {
3165
+ currChunk[rle] = col = cscan;
3166
+ } else {
3167
+ if (col == cscan) rle -= 2;
3168
+ break;
3169
+ }
3170
+ rle++;
3171
+ }
3172
+ output.write(rle - 1);
3173
+ for (int i = 0; i < rle; i++) output.write(currChunk[i]);
3174
+ }
3175
+ index += rle;
3176
+ }
3177
+ } else { // export 24/32 bit TARGA
3178
+ while (index < maxLen) {
3179
+ boolean isRLE = false;
3180
+ currChunk[0] = col = pixels[index];
3181
+ int rle = 1;
3182
+ // try to find repeating bytes (min. len = 2 pixels)
3183
+ // maximum chunk size is 128 pixels
3184
+ while (index + rle < maxLen) {
3185
+ if (col != pixels[index + rle] || rle == 128) {
3186
+ isRLE = (rle > 1); // set flag for RLE chunk
3187
+ break;
3188
+ }
3189
+ rle++;
3190
+ }
3191
+ if (isRLE) {
3192
+ output.write(128 | (rle - 1));
3193
+ output.write(col & 0xff);
3194
+ output.write(col >> 8 & 0xff);
3195
+ output.write(col >> 16 & 0xff);
3196
+ if (format == ARGB) output.write(col >>> 24 & 0xff);
3197
+
3198
+ } else { // not RLE
3199
+ rle = 1;
3200
+ while (index + rle < maxLen) {
3201
+ if ((col != pixels[index + rle] && rle < 128) || rle < 3) {
3202
+ currChunk[rle] = col = pixels[index + rle];
3203
+ } else {
3204
+ // check if the exit condition was the start of
3205
+ // a repeating colour
3206
+ if (col == pixels[index + rle]) rle -= 2;
3207
+ break;
3208
+ }
3209
+ rle++;
3210
+ }
3211
+ // write uncompressed chunk
3212
+ output.write(rle - 1);
3213
+ if (format == ARGB) {
3214
+ for (int i = 0; i < rle; i++) {
3215
+ col = currChunk[i];
3216
+ output.write(col & 0xff);
3217
+ output.write(col >> 8 & 0xff);
3218
+ output.write(col >> 16 & 0xff);
3219
+ output.write(col >>> 24 & 0xff);
3220
+ }
3221
+ } else {
3222
+ for (int i = 0; i < rle; i++) {
3223
+ col = currChunk[i];
3224
+ output.write(col & 0xff);
3225
+ output.write(col >> 8 & 0xff);
3226
+ output.write(col >> 16 & 0xff);
3227
+ }
3228
+ }
3229
+ }
3230
+ index += rle;
3231
+ }
3232
+ }
3233
+ output.flush();
3234
+ return true;
3235
+
3236
+ } catch (IOException e) {
3237
+ e.printStackTrace();
3238
+ return false;
3239
+ }
3240
+ }
3241
+
3242
+
3243
+ /**
3244
+ * Use ImageIO functions from Java 1.4 and later to handle image save.
3245
+ * Various formats are supported, typically jpeg, png, bmp, and wbmp.
3246
+ * To get a list of the supported formats for writing, use: <BR>
3247
+ * <TT>println(javax.imageio.ImageIO.getReaderFormatNames())</TT>
3248
+ */
3249
+ protected boolean saveImageIO(String path) throws IOException {
3250
+ try {
3251
+ int outputFormat = (format == ARGB) ?
3252
+ BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB;
3253
+
3254
+ String extension =
3255
+ path.substring(path.lastIndexOf('.') + 1).toLowerCase();
3256
+
3257
+ // JPEG and BMP images that have an alpha channel set get pretty unhappy.
3258
+ // BMP just doesn't write, and JPEG writes it as a CMYK image.
3259
+ // http://code.google.com/p/processing/issues/detail?id=415
3260
+ if (extension.equals("bmp") || extension.equals("jpg") || extension.equals("jpeg")) {
3261
+ outputFormat = BufferedImage.TYPE_INT_RGB;
3262
+ }
3263
+
3264
+ BufferedImage bimage = new BufferedImage(pixelWidth, pixelHeight, outputFormat);
3265
+ bimage.setRGB(0, 0, pixelWidth, pixelHeight, pixels, 0, pixelWidth);
3266
+
3267
+ File file = new File(path);
3268
+
3269
+ ImageWriter writer = null;
3270
+ ImageWriteParam param = null;
3271
+ IIOMetadata metadata = null;
3272
+
3273
+ if (extension.equals("jpg") || extension.equals("jpeg")) {
3274
+ if ((writer = imageioWriter("jpeg")) != null) {
3275
+ // Set JPEG quality to 90% with baseline optimization. Setting this
3276
+ // to 1 was a huge jump (about triple the size), so this seems good.
3277
+ // Oddly, a smaller file size than Photoshop at 90%, but I suppose
3278
+ // it's a completely different algorithm.
3279
+ param = writer.getDefaultWriteParam();
3280
+ param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
3281
+ param.setCompressionQuality(0.9f);
3282
+ }
3283
+ }
3284
+
3285
+ if (extension.equals("png")) {
3286
+ if ((writer = imageioWriter("png")) != null) {
3287
+ param = writer.getDefaultWriteParam();
3288
+ if (false) {
3289
+ metadata = imageioDPI(writer, param, 100);
3290
+ }
3291
+ }
3292
+ }
3293
+
3294
+ if (writer != null) {
3295
+ BufferedOutputStream output =
3296
+ new BufferedOutputStream(PApplet.createOutput(file));
3297
+ writer.setOutput(ImageIO.createImageOutputStream(output));
3298
+ // writer.write(null, new IIOImage(bimage, null, null), param);
3299
+ writer.write(metadata, new IIOImage(bimage, null, metadata), param);
3300
+ writer.dispose();
3301
+
3302
+ output.flush();
3303
+ output.close();
3304
+ return true;
3305
+ }
3306
+ // If iter.hasNext() somehow fails up top, it falls through to here
3307
+ return javax.imageio.ImageIO.write(bimage, extension, file);
3308
+
3309
+ } catch (Exception e) {
3310
+ e.printStackTrace();
3311
+ throw new IOException("image save failed.");
3312
+ }
3313
+ }
3314
+
3315
+
3316
+ private ImageWriter imageioWriter(String extension) {
3317
+ Iterator<ImageWriter> iter = ImageIO.getImageWritersByFormatName(extension);
3318
+ if (iter.hasNext()) {
3319
+ return iter.next();
3320
+ }
3321
+ return null;
3322
+ }
3323
+
3324
+
3325
+ private IIOMetadata imageioDPI(ImageWriter writer, ImageWriteParam param, double dpi) {
3326
+ // http://stackoverflow.com/questions/321736/how-to-set-dpi-information-in-an-image
3327
+ ImageTypeSpecifier typeSpecifier =
3328
+ ImageTypeSpecifier.createFromBufferedImageType(BufferedImage.TYPE_INT_RGB);
3329
+ IIOMetadata metadata =
3330
+ writer.getDefaultImageMetadata(typeSpecifier, param);
3331
+
3332
+ if (!metadata.isReadOnly() && metadata.isStandardMetadataFormatSupported()) {
3333
+ // for PNG, it's dots per millimeter
3334
+ double dotsPerMilli = dpi / 25.4;
3335
+
3336
+ IIOMetadataNode horiz = new IIOMetadataNode("HorizontalPixelSize");
3337
+ horiz.setAttribute("value", Double.toString(dotsPerMilli));
3338
+
3339
+ IIOMetadataNode vert = new IIOMetadataNode("VerticalPixelSize");
3340
+ vert.setAttribute("value", Double.toString(dotsPerMilli));
3341
+
3342
+ IIOMetadataNode dim = new IIOMetadataNode("Dimension");
3343
+ dim.appendChild(horiz);
3344
+ dim.appendChild(vert);
3345
+
3346
+ IIOMetadataNode root = new IIOMetadataNode("javax_imageio_1.0");
3347
+ root.appendChild(dim);
3348
+
3349
+ try {
3350
+ metadata.mergeTree("javax_imageio_1.0", root);
3351
+ return metadata;
3352
+
3353
+ } catch (IIOInvalidTreeException e) {
3354
+ System.err.println("Could not set the DPI of the output image");
3355
+ e.printStackTrace();
3356
+ }
3357
+ }
3358
+ return null;
3359
+ }
3360
+
3361
+
3013
3362
  protected String[] saveImageFormats;
3014
3363
 
3015
3364
  /**
3016
3365
  * ( begin auto-generated from PImage_save.xml )
3017
3366
  *
3018
- * Saves the image into a file.Append a file extension to the name of
3019
- the file, to indicate the file format to be used: either TIFF (.tif),
3020
- TARGA (.tga), JPEG (.jpg), or PNG (.png). If no extension is included
3021
- in the filename, the image will save in TIFF format and .tif will be
3022
- added to the name. These files are saved to the sketch's folder, which
3023
- may be opened by selecting "Show sketch folder" from the "Sketch" menu.
3024
- <br /><br />To save an image created within the code, rather
3367
+ * Saves the image into a file. Append a file extension to the name of
3368
+ * the file, to indicate the file format to be used: either TIFF (.tif),
3369
+ * TARGA (.tga), JPEG (.jpg), or PNG (.png). If no extension is included
3370
+ * in the filename, the image will save in TIFF format and .tif will be
3371
+ * added to the name. These files are saved to the sketch's folder, which
3372
+ * may be opened by selecting "Show sketch folder" from the "Sketch" menu.
3373
+ To save an image created within the code, rather
3025
3374
  * than through loading, it's necessary to make the image with the
3026
3375
  * <b>createImage()</b> function so it is aware of the location of the
3027
3376
  * program and can therefore save the file to the right place. See the
@@ -3053,23 +3402,73 @@ int testFunction(int dst, int src) {
3053
3402
  * require a black and white image. Basic testing produced a zero-length
3054
3403
  * file with no error.
3055
3404
  *
3056
- * @return
3057
3405
  * @webref pimage:method
3058
3406
  * @brief Saves the image to a TIFF, TARGA, PNG, or JPEG file
3059
3407
  * @usage application
3060
3408
  * @param filename a sequence of letters and numbers
3061
3409
  */
3062
- public boolean save(String filename) { // ignore
3063
- // Make sure the pixel data is ready to go
3064
- loadPixels();
3065
-
3066
- return ImageSaveFacade.get().save(
3067
- pixels,
3068
- pixelWidth,
3069
- pixelHeight,
3070
- format,
3071
- filename,
3072
- parent
3073
- );
3074
- }
3410
+ public boolean save(String filename) { // ignore
3411
+ boolean success = false;
3412
+
3413
+ if (parent != null) {
3414
+ // use savePath(), so that the intermediate directories are created
3415
+ filename = parent.savePath(filename);
3416
+
3417
+ } else {
3418
+ File file = new File(filename);
3419
+ if (file.isAbsolute()) {
3420
+ // make sure that the intermediate folders have been created
3421
+ PApplet.createPath(file);
3422
+ } else {
3423
+ String msg =
3424
+ "PImage.save() requires an absolute path. " +
3425
+ "Use createImage(), or pass savePath() to save().";
3426
+ PGraphics.showException(msg);
3427
+ }
3428
+ }
3429
+
3430
+ // Make sure the pixel data is ready to go
3431
+ loadPixels();
3432
+
3433
+ try {
3434
+ OutputStream os = null;
3435
+
3436
+ if (saveImageFormats == null) {
3437
+ saveImageFormats = javax.imageio.ImageIO.getWriterFormatNames();
3438
+ }
3439
+ if (saveImageFormats != null) {
3440
+ for (int i = 0; i < saveImageFormats.length; i++) {
3441
+ if (filename.endsWith("." + saveImageFormats[i])) {
3442
+ if (!saveImageIO(filename)) {
3443
+ System.err.println("Error while saving image.");
3444
+ return false;
3445
+ }
3446
+ return true;
3447
+ }
3448
+ }
3449
+ }
3450
+
3451
+ if (filename.toLowerCase().endsWith(".tga")) {
3452
+ os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
3453
+ success = saveTGA(os); //, pixels, width, height, format);
3454
+
3455
+ } else {
3456
+ if (!filename.toLowerCase().endsWith(".tif") &&
3457
+ !filename.toLowerCase().endsWith(".tiff")) {
3458
+ // if no .tif extension, add it..
3459
+ filename += ".tif";
3460
+ }
3461
+ os = new BufferedOutputStream(new FileOutputStream(filename), 32768);
3462
+ success = saveTIFF(os); //, pixels, width, height);
3463
+ }
3464
+ os.flush();
3465
+ os.close();
3466
+
3467
+ } catch (IOException e) {
3468
+ System.err.println("Error while saving image.");
3469
+ e.printStackTrace();
3470
+ success = false;
3471
+ }
3472
+ return success;
3473
+ }
3075
3474
  }