1 /*
   2  * Copyright (c) 2012, 2018, 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>{@code
  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>{@code
 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>{@code
 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>{@code
 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>{@code
 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>{@code
 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>{@code
 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 &gt;&gt; 24) &amp; 0xff);
 338      *     int red   = ((retval &gt;&gt; 16) &amp; 0xff);
 339      *     int green = ((retval &gt;&gt;  8) &amp; 0xff);
 340      *     int blue  = ((retval      ) &amp; 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 }