View Javadoc
1   package org.newdawn.slick;
2   
3   import java.nio.ByteBuffer;
4   import java.nio.ByteOrder;
5   
6   import org.lwjgl.BufferUtils;
7   import org.newdawn.slick.opengl.ImageData;
8   
9   import javax.annotation.Nonnull;
10  
11  /**
12   * A utility for creating images from pixel operations
13   *
14   * Expected usage is:
15   * <code>
16   * ImageBuffer buffer = new ImageBuffer(320,200);
17   * buffer.setRGBA(100,100,50,50,20,255);
18   * ..
19   * Image image = buffer.getImage();
20   * </code>
21   * 
22   * @author kevin
23   */
24  public class ImageBuffer implements ImageData {
25      /** The width of the image */
26      private final int width;
27      /** The height of the image */
28      private final int height;
29      /** The width of the texture */
30      private final int texWidth;
31      /** The height of the texture */
32      private final int texHeight;
33      /** The raw data generated for the image */
34      private final byte[] rawData;
35  
36      /**
37       *
38       * @param width width
39       * @param height height
40       */
41      public ImageBuffer(int width, int height) {
42          this.width = width;
43          this.height = height;
44  
45          texWidth = get2Fold(width);
46          texHeight = get2Fold(height);
47  
48          rawData = new byte[texWidth * texHeight * 4];
49      }
50  
51      /**
52       * Retrieve the raw data stored within the image buffer
53       *
54       * @return The raw data in RGBA packed format from within the image buffer
55       */
56      public byte[] getRGBA() {
57          return rawData;
58      }
59  
60      /**
61       * @see org.newdawn.slick.opengl.ImageData#getFormat()
62       */
63      @Nonnull
64      public Format getFormat() {
65          return Format.RGBA;
66      }
67  
68      /**
69       * @see org.newdawn.slick.opengl.ImageData#getHeight()
70       */
71      public int getHeight() {
72          return height;
73      }
74  
75      /**
76       * @see org.newdawn.slick.opengl.ImageData#getTexHeight()
77       */
78      public int getTexHeight() {
79          return texHeight;
80      }
81  
82      /**
83       * @see org.newdawn.slick.opengl.ImageData#getTexWidth()
84       */
85      public int getTexWidth() {
86          return texWidth;
87      }
88  
89      /**
90       * @see org.newdawn.slick.opengl.ImageData#getWidth()
91       */
92      public int getWidth() {
93          return width;
94      }
95  
96      /**
97       * @see org.newdawn.slick.opengl.ImageData#getImageBufferData()
98       */
99      public ByteBuffer getImageBufferData() {
100         ByteBuffer scratch = BufferUtils.createByteBuffer(rawData.length);
101         scratch.put(rawData);
102         scratch.flip();
103 
104         return scratch;
105     }
106 
107     /**
108      * Set a pixel in the image buffer
109      *
110      * @param x The x position of the pixel to set
111      * @param y The y position of the pixel to set
112      * @param r The red component to set (0->255)
113      * @param g The green component to set (0->255)
114      * @param b The blue component to set (0->255)
115      * @param a The alpha component to set (0->255)
116      */
117     public void setRGBA(int x, int y, int r, int g, int b, int a) {
118         if ((x < 0) || (x >= width) || (y < 0) || (y >= height)) {
119             throw new RuntimeException("Specified location: "+x+","+y+" outside of image");
120         }
121 
122         int ofs = ((x + (y * texWidth)) * 4);
123 
124         if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
125             rawData[ofs] = (byte) b;
126             rawData[ofs + 1] = (byte) g;
127             rawData[ofs + 2] = (byte) r;
128             rawData[ofs + 3] = (byte) a;
129         } else {
130             rawData[ofs] = (byte) r;
131             rawData[ofs + 1] = (byte) g;
132             rawData[ofs + 2] = (byte) b;
133             rawData[ofs + 3] = (byte) a;
134         }
135     }
136 
137     /**
138      * Get an image generated based on this buffer
139      *
140      * @return The image generated from this buffer
141      */
142     @Nonnull
143     public Image getImage() {
144         return new Image(this);
145     }
146 
147     /**
148      * Get an image generated based on this buffer
149      *
150      * @param filter The filtering method to use when scaling this image
151      * @return The image generated from this buffer
152      */
153     @Nonnull
154     public Image getImage(int filter) {
155         return new Image(this, filter);
156     }
157 
158     /**
159      * Get the closest greater power of 2 to the fold number
160      * 
161      * @param fold The target number
162      * @return The power of 2
163      */
164     private int get2Fold(int fold) {
165         int ret = 2;
166         while (ret < fold) {
167             ret *= 2;
168         }
169         return ret;
170     }
171 
172 }