Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.scene.image; 027 028import java.nio.Buffer; 029import java.nio.ByteBuffer; 030import java.nio.IntBuffer; 031 032/** 033 * A {@link PixelFormat} object representing a pixel format that can store 034 * full colors and so can be used as a destination format to write pixel 035 * data from an arbitrary image. 036 * @since 2.2 037 */ 038public abstract class WritablePixelFormat<T extends Buffer> 039 extends PixelFormat<T> 040{ 041 WritablePixelFormat(Type type) { 042 super(type); 043 } 044 045 @Override 046 public boolean isWritable() { 047 return true; 048 } 049 050 /** 051 * Stores a 32-bit integer representation of the color in the buffer 052 * at the specified coordinates. 053 * The 32-bit integer will contain the 4 color components in separate 054 * 8-bit fields in ARGB order from the most significant byte to the least 055 * significant byte. 056 * The buffer should be positioned to the start of the pixel data such 057 * that {@code buf.get(0)} would return the pixel information for the 058 * pixel at coordinates {@code (0, 0)}. 059 * The {@code scanlineStride} parameter defines the distance from the pixel 060 * data at the start of one row to the pixel data at the start of the 061 * immediately following row at the next higher Y coordinate. Usually, 062 * {@code scanlineStride} is the same as the width of the image multiplied 063 * by the number of data elements per pixel (1 for the case of the 064 * integer and indexed formats, or 3 or 4 in the case of the byte 065 * formats), but some images may have further padding between rows for 066 * alignment or other purposes. 067 * 068 * @param buf the buffer of pixel data 069 * @param x the X coordinate of the pixel to be read 070 * @param y the Y coordinate of the pixel to be read 071 * @param scanlineStride the number of buffer elements between the 072 * start of adjacent pixel rows in the buffer 073 * @param argb a 32-bit value with the color to be stored in the pixel 074 * in a format similar to the {@code Type.INT_ARGB} pixel format 075 */ 076 public abstract void setArgb(T buf, int x, int y, int scanlineStride, 077 int argb); 078 079 static class IntArgb extends WritablePixelFormat<IntBuffer> { 080 static final IntArgb INSTANCE = new IntArgb(); 081 082 private IntArgb() { 083 super(Type.INT_ARGB); 084 } 085 086 @Override 087 public boolean isPremultiplied() { 088 return false; 089 } 090 091 @Override 092 public int getArgb(IntBuffer buf, int x, int y, int scanlineStride) { 093 return buf.get(y * scanlineStride + x); 094 } 095 096 @Override 097 public void setArgb(IntBuffer buf, int x, int y, int scanlineStride, 098 int argb) 099 { 100 buf.put(y * scanlineStride + x, argb); 101 } 102 } 103 104 static class IntArgbPre extends WritablePixelFormat<IntBuffer> { 105 static final IntArgbPre INSTANCE = new IntArgbPre(); 106 107 private IntArgbPre() { 108 super(Type.INT_ARGB_PRE); 109 } 110 111 @Override 112 public boolean isPremultiplied() { 113 return true; 114 } 115 116 @Override 117 public int getArgb(IntBuffer buf, int x, int y, int scanlineStride) { 118 return PretoNonPre(buf.get(y * scanlineStride + x)); 119 } 120 121 @Override 122 public void setArgb(IntBuffer buf, int x, int y, int scanlineStride, 123 int argb) 124 { 125 buf.put(y * scanlineStride + x, NonPretoPre(argb)); 126 } 127 } 128 129 static class ByteBgra extends WritablePixelFormat<ByteBuffer> { 130 static final ByteBgra INSTANCE = new ByteBgra(); 131 132 private ByteBgra() { 133 super(Type.BYTE_BGRA); 134 } 135 136 @Override 137 public boolean isPremultiplied() { 138 return false; 139 } 140 141 @Override 142 public int getArgb(ByteBuffer buf, int x, int y, int scanlineStride) { 143 int index = y * scanlineStride + x * 4; 144 int b = buf.get(index ) & 0xff; 145 int g = buf.get(index + 1) & 0xff; 146 int r = buf.get(index + 2) & 0xff; 147 int a = buf.get(index + 3) & 0xff; 148 return (a << 24) | (r << 16) | (g << 8) | b; 149 } 150 151 @Override 152 public void setArgb(ByteBuffer buf, int x, int y, int scanlineStride, 153 int argb) 154 { 155 int index = y * scanlineStride + x * 4; 156 buf.put(index, (byte) (argb )); 157 buf.put(index + 1, (byte) (argb >> 8)); 158 buf.put(index + 2, (byte) (argb >> 16)); 159 buf.put(index + 3, (byte) (argb >> 24)); 160 } 161 } 162 163 static class ByteBgraPre extends WritablePixelFormat<ByteBuffer> { 164 static final ByteBgraPre INSTANCE = new ByteBgraPre(); 165 166 private ByteBgraPre() { 167 super(Type.BYTE_BGRA_PRE); 168 } 169 170 @Override 171 public boolean isPremultiplied() { 172 return true; 173 } 174 175 @Override 176 public int getArgb(ByteBuffer buf, int x, int y, int scanlineStride) { 177 int index = y * scanlineStride + x * 4; 178 int b = buf.get(index ) & 0xff; 179 int g = buf.get(index + 1) & 0xff; 180 int r = buf.get(index + 2) & 0xff; 181 int a = buf.get(index + 3) & 0xff; 182 if (a > 0x00 && a < 0xff) { 183 int halfa = a >> 1; 184 r = (r >= a) ? 0xff : (r * 0xff + halfa) / a; 185 g = (g >= a) ? 0xff : (g * 0xff + halfa) / a; 186 b = (b >= a) ? 0xff : (b * 0xff + halfa) / a; 187 } 188 return (a << 24) | (r << 16) | (g << 8) | b; 189 } 190 191 @Override 192 public void setArgb(ByteBuffer buf, int x, int y, int scanlineStride, 193 int argb) 194 { 195 int index = y * scanlineStride + x * 4; 196 int a = (argb >>> 24); 197 int r, g, b; 198 if (a > 0x00) { 199 r = (argb >> 16) & 0xff; 200 g = (argb >> 8) & 0xff; 201 b = (argb ) & 0xff; 202 if (a < 0xff) { 203 r = (r * a + 127) / 0xff; 204 g = (g * a + 127) / 0xff; 205 b = (b * a + 127) / 0xff; 206 } 207 } else { 208 a = r = g = b = 0; 209 } 210 buf.put(index, (byte) b); 211 buf.put(index + 1, (byte) g); 212 buf.put(index + 2, (byte) r); 213 buf.put(index + 3, (byte) a); 214 } 215 } 216}