1 /*
   2  * Copyright (c) 2009, 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 com.sun.javafx.robot;
  27 
  28 import java.nio.Buffer;
  29 import java.nio.IntBuffer;
  30 
  31 /**
  32  * This class encapsulates a bucket of pixels stored in IntArgbPre format.
  33  *
  34  */
  35 public class FXRobotImage {
  36     private final IntBuffer pixelBuffer;
  37     private final int width;
  38     private final int height;
  39     private final int scanlineStride;
  40 
  41     public static FXRobotImage create(Buffer pixelBuffer,
  42                                       int width, int height, int scanlineStride)
  43     {
  44         return new FXRobotImage(pixelBuffer, width, height, scanlineStride);
  45     }
  46 
  47     private FXRobotImage(Buffer pixelBuffer,
  48                          int width, int height, int scanlineStride)
  49     {
  50         if (pixelBuffer == null) {
  51             throw new IllegalArgumentException("Pixel buffer must be non-null");
  52         }
  53         if (width <= 0 || height <= 0) {
  54             throw new IllegalArgumentException("Image dimensions must be > 0");
  55         }
  56         this.pixelBuffer = (IntBuffer)pixelBuffer;
  57         this.width = width;
  58         this.height = height;
  59         this.scanlineStride = scanlineStride;
  60     }
  61 
  62     /**
  63      * Returns {@link java.nio.Buffer} which holds the data.
  64      *
  65      * @return {@code Buffer} holding the data for this image
  66      */
  67     public Buffer getPixelBuffer() {
  68         return pixelBuffer;
  69     }
  70 
  71     /**
  72      * Width of the image.
  73      * @return width
  74      */
  75     public int getWidth() {
  76         return width;
  77     }
  78 
  79     /**
  80      * Height of the image
  81      * @return height
  82      */
  83     public int getHeight() {
  84         return height;
  85     }
  86 
  87     /**
  88      * Returns scanline stride of this image in bytes
  89      *
  90      * @return scan line stride in bytes
  91      */
  92     public int getScanlineStride() {
  93         return scanlineStride;
  94     }
  95 
  96     /**
  97      * Returns pixel stride of this image in bytes.
  98      *
  99      * @return pixel stride in bytes
 100      */
 101     public int getPixelStride() {
 102         return 4;
 103     }
 104 
 105     /**
 106      * Returns pixel (in IntArgbPre) format (Argb premultiplied).
 107      *
 108      * @param x coordinate
 109      * @param y coordinate
 110      * @return pixel in IntArgbPre format
 111      */
 112     public int getArgbPre(int x, int y) {
 113         if (x < 0 || x >= width || y < 0 || y >= height) {
 114             throw new IllegalArgumentException("x,y must be >0, <width, height");
 115         }
 116         return pixelBuffer.get(x + y*scanlineStride/4);
 117     }
 118 
 119     /**
 120      * Returns pixel in IntArgb format (non-premultiplied).
 121      *
 122      * @param x coordinate
 123      * @param y coordinate
 124      * @return pixel in IntArgb format
 125      */
 126     public int getArgb(int x, int y) {
 127         if (x < 0 || x >= width || y < 0 || y >= height) {
 128             throw new IllegalArgumentException("x,y must be >0, <width, height");
 129         }
 130         int argb = pixelBuffer.get(x + y*scanlineStride/4);
 131         if ((argb >> 24) == -1) {
 132             return argb;
 133         }
 134         int a = argb >>> 24;
 135         int r = (argb >> 16) & 0xff;
 136         int g = (argb >>  8) & 0xff;
 137         int b = (argb      ) & 0xff;
 138         int a2 = a + (a >> 7);
 139         r = (r * a2) >> 8;
 140         g = (g * a2) >> 8;
 141         b = (b * a2) >> 8;
 142         return ((a << 24) | (r << 16) | (g << 8) | (b));
 143     }
 144 
 145     @Override
 146     public String toString() {
 147         return super.toString() +
 148             " [format=INT_ARGB_PRE width=" + width + " height=" + height +
 149             " scanlineStride=" + scanlineStride  +" pixelStride=" + getPixelStride()+
 150             " pixelBuffer=" + pixelBuffer + "]";
 151     }
 152 }