1 /* 2 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javafx.scene.image; 27 28 import java.nio.Buffer; 29 import java.nio.ByteBuffer; 30 import java.nio.IntBuffer; 31 import java.util.Arrays; 32 33 /** 34 * A {@code PixelFormat} object defines the layout of data for a pixel of 35 * a given format. 36 * @since JavaFX 2.2 37 */ 38 public abstract class PixelFormat<T extends Buffer> { 39 /** 40 * An enum describing the in-array storage format of a single pixel 41 * managed by a {@link PixelFormat}. 42 * 43 * @since JavaFX 2.2 44 */ 45 public enum Type { 46 /** 47 * The pixels are stored in 32-bit integers with the premultiplied 48 * components stored in order, from MSb to LSb: 49 * alpha, red, green, blue. 50 */ 51 INT_ARGB_PRE, 52 /** 53 * The pixels are stored in 32-bit integers with the non-premultiplied 54 * components stored in order, from MSb to LSb: 55 * alpha, red, green, blue. 56 */ 57 INT_ARGB, 58 /** 59 * The pixels are stored in adjacent bytes with the premultiplied 60 * components stored in order of increasing index: 61 * blue, green, red, alpha. 62 */ 63 BYTE_BGRA_PRE, 64 /** 65 * The pixels are stored in adjacent bytes with the non-premultiplied 66 * components stored in order of increasing index: 67 * blue, green, red, alpha. 68 */ 69 BYTE_BGRA, 70 /** 71 * The opaque pixels are stored in adjacent bytes with the color 72 * components stored in order of increasing index: 73 * red, green, blue. 74 */ 75 BYTE_RGB, 76 /** 77 * The pixel colors are referenced by byte indices stored in the 78 * pixel array, with the byte interpreted as an unsigned index into 79 * a list of colors provided by the {@code PixelFormat} object. 80 */ 81 BYTE_INDEXED, 82 } 83 84 private Type type; 85 86 PixelFormat(Type type) { 87 this.type = type; 88 } 89 90 /** 91 * Returns a {@code WritablePixelFormat} instance describing a pixel 92 * layout with the pixels stored in 32-bit integers with the 93 * <b>non-premultiplied</b> components stored in order, from MSb to LSb: 94 * alpha, red, green, blue. 95 * <p> 96 * Pixels in this format can be decoded using the following sample code: 97 * <pre> 98 * int pixel = array[rowstart + x]; 99 * 100 * int alpha = ((pixel >> 24) & 0xff); 101 * int red = ((pixel >> 16) & 0xff); 102 * int green = ((pixel >> 8) & 0xff); 103 * int blue = ((pixel >> ) & 0xff); 104 * </pre> 105 * 106 * @return a {@code WritabelPixelFormat<IntBuffer>} describing the 107 * indicated pixel format 108 */ 109 public static WritablePixelFormat<IntBuffer> getIntArgbInstance() { 110 return WritablePixelFormat.IntArgb.INSTANCE; 111 } 112 113 /** 114 * Returns a {@code WritablePixelFormat} instance describing a pixel 115 * layout with the pixels stored in 32-bit integers with the 116 * <b>premultiplied</b> components stored in order, from MSb to LSb: 117 * alpha, red, green, blue. 118 * <p> 119 * Pixels in this format can be decoded using the following sample code: 120 * <pre> 121 * int pixel = array[rowstart + x]; 122 * 123 * int alpha = ((pixel >> 24) & 0xff); 124 * int red = ((pixel >> 16) & 0xff); 125 * int green = ((pixel >> 8) & 0xff); 126 * int blue = ((pixel ) & 0xff); 127 * </pre> 128 * 129 * @return a {@code WritabelPixelFormat<IntBuffer>} describing the 130 * indicated pixel format 131 */ 132 public static WritablePixelFormat<IntBuffer> getIntArgbPreInstance() { 133 return WritablePixelFormat.IntArgbPre.INSTANCE; 134 } 135 136 /** 137 * Returns a {@code WritablePixelFormat} instance describing a pixel 138 * layout with the pixels stored in adjacent bytes with the 139 * <b>non-premultiplied</b> components stored in order of increasing index: 140 * blue, green, red, alpha. 141 * <p> 142 * Pixels in this format can be decoded using the following sample code: 143 * <pre> 144 * int i = rowstart + x * 4; 145 * 146 * int blue = (array[i+0] & 0xff); 147 * int green = (array[i+1] & 0xff); 148 * int red = (array[i+2] & 0xff); 149 * int alpha = (array[i+3] & 0xff); 150 * </pre> 151 * 152 * @return a {@code WritablePixelFormat<ByteBuffer>} describing the 153 * indicated pixel format 154 */ 155 public static WritablePixelFormat<ByteBuffer> getByteBgraInstance() { 156 return WritablePixelFormat.ByteBgra.INSTANCE; 157 } 158 159 /** 160 * Returns a {@code WritablePixelFormat} instance describing a pixel 161 * layout with the pixels stored in adjacent bytes with the 162 * <b>premultiplied</b> components stored in order of increasing index: 163 * blue, green, red, alpha. 164 * <p> 165 * Pixels in this format can be decoded using the following sample code: 166 * <pre> 167 * int i = rowstart + x * 4; 168 * 169 * int blue = (array[i+0] & 0xff); 170 * int green = (array[i+1] & 0xff); 171 * int red = (array[i+2] & 0xff); 172 * int alpha = (array[i+3] & 0xff); 173 * </pre> 174 * 175 * @return a {@code WritablePixelFormat<ByteBuffer>} describing the 176 * indicated pixel format 177 */ 178 public static WritablePixelFormat<ByteBuffer> getByteBgraPreInstance() { 179 return WritablePixelFormat.ByteBgraPre.INSTANCE; 180 } 181 182 /** 183 * Returns a {@code PixelFormat} instance describing a pixel 184 * layout with the pixels stored in adjacent bytes with the 185 * color components stored in order of increasing index: 186 * red, green, blue. 187 * <p> 188 * Pixels in this format can be decoded using the following sample code: 189 * <pre> 190 * int i = rowstart + x * 3; 191 * 192 * int red = (array[i+0] & 0xff); 193 * int green = (array[i+1] & 0xff); 194 * int blue = (array[i+2] & 0xff); 195 * </pre> 196 * 197 * @return a {@code PixelFormat<ByteBuffer>} describing the 198 * indicated pixel format 199 */ 200 public static PixelFormat<ByteBuffer> getByteRgbInstance() { 201 return ByteRgb.instance; 202 } 203 204 /** 205 * Creates a {@code PixelFormat} instance describing a pixel layout 206 * with the pixels stored as single bytes representing an index 207 * into the specified lookup table of <b>premultiplied</b> color 208 * values in the {@link Type#INT_ARGB_PRE INT_ARGB_PRE} format. 209 * <p> 210 * Pixels in this format can be decoded using the following sample code: 211 * <pre> 212 * int pixel = array[rowstart + x] & 0xff; 213 * int argb = colors[pixel]; 214 * 215 * int alpha = ((argb >> 24) & 0xff); 216 * int red = ((argb >> 16) & 0xff); 217 * int green = ((argb >> 8) & 0xff); 218 * int blue = ((argb ) & 0xff); 219 * </pre> 220 * 221 * @param colors an {@code int[]} array of 32-bit color values in 222 * the {@link Type#INT_ARGB_PRE INT_ARGB_PRE} format 223 * @return a {@code PixelFormat<ByteBuffer>} describing the indicated 224 * pixel format with the specified list of premultiplied colors 225 */ 226 public static PixelFormat<ByteBuffer> 227 createByteIndexedPremultipliedInstance(int colors[]) 228 { 229 return IndexedPixelFormat.createByte(colors, true); 230 } 231 232 /** 233 * Creates a {@code PixelFormat} instance describing a pixel layout 234 * with the pixels stored as single bytes representing an index 235 * into the specified lookup table of <b>non-premultiplied</b> color 236 * values in the {@link Type#INT_ARGB INT_ARGB} format. 237 * <p> 238 * Pixels in this format can be decoded using the following sample code: 239 * <pre> 240 * int pixel = array[rowstart + x] & 0xff; 241 * int argb = colors[pixel]; 242 * 243 * int alpha = ((argb >> 24) & 0xff); 244 * int red = ((argb >> 16) & 0xff); 245 * int green = ((argb >> 8) & 0xff); 246 * int blue = ((argb ) & 0xff); 247 * </pre> 248 * 249 * @param colors an {@code int[]} array of 32-bit color values in 250 * the {@link Type#INT_ARGB INT_ARGB} format 251 * @return a {@code PixelFormat<ByteBuffer>} describing the indicated 252 * pixel format with the specified list of non-premultiplied colors 253 */ 254 public static PixelFormat<ByteBuffer> 255 createByteIndexedInstance(int colors[]) 256 { 257 return IndexedPixelFormat.createByte(colors, false); 258 } 259 260 /** 261 * Returns the enum representing the storage format of the pixels 262 * managed by this {@code PixelFormat} object. 263 * 264 * @return the {@code Type} enum of the pixels 265 */ 266 public Type getType() { 267 return type; 268 } 269 270 /** 271 * Returns true iff this {@code PixelFormat} object can convert 272 * color information into a pixel representation. 273 * 274 * @return true iff this {@code PixelFormat} can convert colors to 275 * pixel data 276 */ 277 public abstract boolean isWritable(); 278 279 /** 280 * Returns true iff the color components decoded (or encoded) by this 281 * format are pre-multiplied by the alpha component for more efficient 282 * blending calculations. 283 * 284 * @return true iff the managed color components are premultiplied 285 * by alpha 286 */ 287 public abstract boolean isPremultiplied(); 288 289 static int NonPretoPre(int nonpre) { 290 int a = nonpre >>> 24; 291 if (a == 0xff) return nonpre; 292 if (a == 0x00) return 0; 293 int r = (nonpre >> 16) & 0xff; 294 int g = (nonpre >> 8) & 0xff; 295 int b = (nonpre ) & 0xff; 296 r = (r * a + 127) / 0xff; 297 g = (g * a + 127) / 0xff; 298 b = (b * a + 127) / 0xff; 299 return (a << 24) | (r << 16) | (g << 8) | b; 300 } 301 302 static int PretoNonPre(int pre) { 303 int a = pre >>> 24; 304 if (a == 0xff || a == 0x00) return pre; 305 int r = (pre >> 16) & 0xff; 306 int g = (pre >> 8) & 0xff; 307 int b = (pre ) & 0xff; 308 int halfa = a >> 1; 309 r = (r >= a) ? 0xff : (r * 0xff + halfa) / a; 310 g = (g >= a) ? 0xff : (g * 0xff + halfa) / a; 311 b = (b >= a) ? 0xff : (b * 0xff + halfa) / a; 312 return (a << 24) | (r << 16) | (g << 8) | b; 313 } 314 315 /** 316 * Reads pixel data from the buffer at the specified coordinates and 317 * converts it to a 32-bit integer representation of the color in the 318 * {@link Type#INT_ARGB INT_ARGB} format. 319 * The 32-bit integer will contain the 4 color components in separate 320 * 8-bit fields in ARGB order from the most significant byte to the least 321 * significant byte. 322 * The buffer should be positioned to the start of the pixel data such 323 * that {@code buf.get(0)} would return the pixel information for the 324 * pixel at coordinates {@code (0, 0)}. 325 * The {@code scanlineStride} parameter defines the distance from the pixel 326 * data at the start of one row to the pixel data at the start of the 327 * immediately following row at the next higher Y coordinate. Usually, 328 * {@code scanlineStride} is the same as the width of the image multiplied 329 * by the number of data elements per pixel (1 for the case of the 330 * integer and indexed formats, or 3 or 4 in the case of the byte 331 * formats), but some images may have further padding between rows for 332 * alignment or other purposes. 333 * <p> 334 * The color components can be extracted from the returned integer using 335 * the following sample code: 336 * <pre> 337 * int alpha = ((retval >> 24) & 0xff); 338 * int red = ((retval >> 16) & 0xff); 339 * int green = ((retval >> 8) & 0xff); 340 * int blue = ((retval ) & 0xff); 341 * </pre> 342 * 343 * @param buf the buffer of pixel data 344 * @param x the X coordinate of the pixel to be read 345 * @param y the Y coordinate of the pixel to be read 346 * @param scanlineStride the number of buffer elements between the 347 * start of adjacent pixel rows in the buffer 348 * @return a 32-bit value with the color of the pixel in a format 349 * similar to the {@link Type#INT_ARGB INT_ARGB} pixel format 350 */ 351 public abstract int getArgb(T buf, int x, int y, int scanlineStride); 352 353 static class ByteRgb extends PixelFormat<ByteBuffer> { 354 static final ByteRgb instance = new ByteRgb(); 355 356 private ByteRgb() { 357 super(Type.BYTE_RGB); 358 } 359 360 @Override 361 public boolean isWritable() { 362 return true; 363 } 364 365 @Override 366 public boolean isPremultiplied() { 367 return false; 368 } 369 370 @Override 371 public int getArgb(ByteBuffer buf, int x, int y, int scanlineStride) { 372 int index = y * scanlineStride + x * 3; 373 int r = buf.get(index ) & 0xff; 374 int g = buf.get(index + 1) & 0xff; 375 int b = buf.get(index + 2) & 0xff; 376 return (0xff << 24) | (r << 16) | (g << 8) | b; 377 } 378 } 379 380 static class IndexedPixelFormat extends PixelFormat<ByteBuffer> { 381 int precolors[]; 382 int nonprecolors[]; 383 boolean premult; 384 385 static PixelFormat createByte(int colors[], boolean premult) { 386 return new IndexedPixelFormat(Type.BYTE_INDEXED, premult, 387 Arrays.copyOf(colors, 256)); 388 } 389 390 private IndexedPixelFormat(Type type, boolean premult, int colors[]) { 391 super(type); 392 if (premult) { 393 this.precolors = colors; 394 } else { 395 this.nonprecolors = colors; 396 } 397 this.premult = premult; 398 } 399 400 @Override 401 public boolean isWritable() { 402 return false; 403 } 404 405 @Override 406 public boolean isPremultiplied() { 407 return premult; 408 } 409 410 int[] getPreColors() { 411 if (precolors == null) { 412 int colors[] = new int[nonprecolors.length]; 413 for (int i = 0; i < colors.length; i++) { 414 colors[i] = NonPretoPre(nonprecolors[i]); 415 } 416 this.precolors = colors; 417 } 418 return precolors; 419 } 420 421 int[] getNonPreColors() { 422 if (nonprecolors == null) { 423 int colors[] = new int[precolors.length]; 424 for (int i = 0; i < colors.length; i++) { 425 colors[i] = PretoNonPre(precolors[i]); 426 } 427 this.nonprecolors = colors; 428 } 429 return nonprecolors; 430 } 431 432 @Override 433 public int getArgb(ByteBuffer buf, int x, int y, int scanlineStride) { 434 return getNonPreColors()[buf.get(y * scanlineStride + x) & 0xff]; 435 } 436 } 437 }