33 import java.awt.image.DirectColorModel; 34 import java.awt.image.IndexColorModel; 35 import java.awt.image.Raster; 36 import java.awt.image.BufferedImage; 37 import java.awt.image.DataBuffer; 38 39 import sun.java2d.SurfaceData; 40 import sun.java2d.SunGraphics2D; 41 import sun.java2d.StateTrackable; 42 import sun.java2d.StateTrackable.*; 43 import sun.java2d.StateTracker; 44 import sun.java2d.loops.SurfaceType; 45 import sun.java2d.loops.CompositeType; 46 import sun.java2d.loops.RenderLoops; 47 48 49 public class BufImgSurfaceData extends SurfaceData { 50 BufferedImage bufImg; 51 private BufferedImageGraphicsConfig graphicsConfig; 52 RenderLoops solidloops; 53 54 private static native void initIDs(Class<?> ICM, Class<?> ICMColorData); 55 56 private static final int DCM_RGBX_RED_MASK = 0xff000000; 57 private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000; 58 private static final int DCM_RGBX_BLUE_MASK = 0x0000ff00; 59 private static final int DCM_555X_RED_MASK = 0xF800; 60 private static final int DCM_555X_GREEN_MASK = 0x07C0; 61 private static final int DCM_555X_BLUE_MASK = 0x003E; 62 private static final int DCM_4444_RED_MASK = 0x0f00; 63 private static final int DCM_4444_GREEN_MASK = 0x00f0; 64 private static final int DCM_4444_BLUE_MASK = 0x000f; 65 private static final int DCM_4444_ALPHA_MASK = 0xf000; 66 private static final int DCM_ARGBBM_ALPHA_MASK = 0x01000000; 67 private static final int DCM_ARGBBM_RED_MASK = 0x00ff0000; 68 private static final int DCM_ARGBBM_GREEN_MASK = 0x0000ff00; 69 private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff; 70 71 static { 72 initIDs(IndexColorModel.class, ICMColorData.class); 73 } 74 75 public static SurfaceData createData(BufferedImage bufImg) { 76 if (bufImg == null) { 77 throw new NullPointerException("BufferedImage cannot be null"); 78 } 79 SurfaceData sData; 80 ColorModel cm = bufImg.getColorModel(); 81 int type = bufImg.getType(); 82 // REMIND: Check the image type and pick an appropriate subclass 83 switch (type) { 84 case BufferedImage.TYPE_INT_BGR: 85 sData = createDataIC(bufImg, SurfaceType.IntBgr); 86 break; 87 case BufferedImage.TYPE_INT_RGB: 88 sData = createDataIC(bufImg, SurfaceType.IntRgb); 89 break; 90 case BufferedImage.TYPE_INT_ARGB: 91 sData = createDataIC(bufImg, SurfaceType.IntArgb); 92 break; 93 case BufferedImage.TYPE_INT_ARGB_PRE: 94 sData = createDataIC(bufImg, SurfaceType.IntArgbPre); 95 break; 96 case BufferedImage.TYPE_3BYTE_BGR: 97 sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2); 98 break; 99 case BufferedImage.TYPE_4BYTE_ABGR: 100 sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3); 101 break; 102 case BufferedImage.TYPE_4BYTE_ABGR_PRE: 103 sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3); 104 break; 105 case BufferedImage.TYPE_USHORT_565_RGB: 106 sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null); 107 break; 108 case BufferedImage.TYPE_USHORT_555_RGB: 109 sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null); 110 break; 111 case BufferedImage.TYPE_BYTE_INDEXED: 112 { 113 SurfaceType sType; 114 switch (cm.getTransparency()) { 115 case OPAQUE: 116 if (isOpaqueGray((IndexColorModel)cm)) { 117 sType = SurfaceType.Index8Gray; 118 } else { 119 sType = SurfaceType.ByteIndexedOpaque; 120 } 121 break; 122 case BITMASK: 123 sType = SurfaceType.ByteIndexedBm; 124 break; 125 case TRANSLUCENT: 126 sType = SurfaceType.ByteIndexed; 127 break; 128 default: 129 throw new InternalError("Unrecognized transparency"); 130 } 131 sData = createDataBC(bufImg, sType, 0); 132 } 133 break; 134 case BufferedImage.TYPE_BYTE_GRAY: 135 sData = createDataBC(bufImg, SurfaceType.ByteGray, 0); 136 break; 137 case BufferedImage.TYPE_USHORT_GRAY: 138 sData = createDataSC(bufImg, SurfaceType.UshortGray, null); 139 break; 140 case BufferedImage.TYPE_BYTE_BINARY: 141 { 142 SurfaceType sType; 143 SampleModel sm = bufImg.getRaster().getSampleModel(); 144 switch (sm.getSampleSize(0)) { 145 case 1: 146 sType = SurfaceType.ByteBinary1Bit; 147 break; 148 case 2: 149 sType = SurfaceType.ByteBinary2Bit; 150 break; 151 case 4: 152 sType = SurfaceType.ByteBinary4Bit; 153 break; 154 default: 155 throw new InternalError("Unrecognized pixel size"); 156 } 157 sData = createDataBP(bufImg, sType); 158 } 159 break; 160 case BufferedImage.TYPE_CUSTOM: 161 default: 162 { 163 Raster raster = bufImg.getRaster(); 164 int numBands = raster.getNumBands(); 165 if (raster instanceof IntegerComponentRaster && 166 raster.getNumDataElements() == 1 && 167 ((IntegerComponentRaster)raster).getPixelStride() == 1) 168 { 169 SurfaceType sType = SurfaceType.AnyInt; 170 if (cm instanceof DirectColorModel) { 171 DirectColorModel dcm = (DirectColorModel) cm; 172 int aMask = dcm.getAlphaMask(); 173 int rMask = dcm.getRedMask(); 174 int gMask = dcm.getGreenMask(); 175 int bMask = dcm.getBlueMask(); 176 if (numBands == 3 && 177 aMask == 0 && 178 rMask == DCM_RGBX_RED_MASK && 179 gMask == DCM_RGBX_GREEN_MASK && 180 bMask == DCM_RGBX_BLUE_MASK) 181 { 182 sType = SurfaceType.IntRgbx; 183 } else if (numBands == 4 && 184 aMask == DCM_ARGBBM_ALPHA_MASK && 185 rMask == DCM_ARGBBM_RED_MASK && 186 gMask == DCM_ARGBBM_GREEN_MASK && 187 bMask == DCM_ARGBBM_BLUE_MASK) 188 { 189 sType = SurfaceType.IntArgbBm; 190 } else { 191 sType = SurfaceType.AnyDcm; 192 } 193 } 194 sData = createDataIC(bufImg, sType); 195 break; 196 } else if (raster instanceof ShortComponentRaster && 197 raster.getNumDataElements() == 1 && 198 ((ShortComponentRaster)raster).getPixelStride() == 1) 199 { 200 SurfaceType sType = SurfaceType.AnyShort; 201 IndexColorModel icm = null; 202 if (cm instanceof DirectColorModel) { 203 DirectColorModel dcm = (DirectColorModel) cm; 204 int aMask = dcm.getAlphaMask(); 205 int rMask = dcm.getRedMask(); 206 int gMask = dcm.getGreenMask(); 207 int bMask = dcm.getBlueMask(); 208 if (numBands == 3 && 209 aMask == 0 && 210 rMask == DCM_555X_RED_MASK && 211 gMask == DCM_555X_GREEN_MASK && 212 bMask == DCM_555X_BLUE_MASK) 213 { 214 sType = SurfaceType.Ushort555Rgbx; 216 if (numBands == 4 && 217 aMask == DCM_4444_ALPHA_MASK && 218 rMask == DCM_4444_RED_MASK && 219 gMask == DCM_4444_GREEN_MASK && 220 bMask == DCM_4444_BLUE_MASK) 221 { 222 sType = SurfaceType.Ushort4444Argb; 223 } 224 } else if (cm instanceof IndexColorModel) { 225 icm = (IndexColorModel)cm; 226 if (icm.getPixelSize() == 12) { 227 if (isOpaqueGray(icm)) { 228 sType = SurfaceType.Index12Gray; 229 } else { 230 sType = SurfaceType.UshortIndexed; 231 } 232 } else { 233 icm = null; 234 } 235 } 236 sData = createDataSC(bufImg, sType, icm); 237 break; 238 } 239 sData = new BufImgSurfaceData(raster.getDataBuffer(), 240 bufImg, SurfaceType.Custom); 241 } 242 break; 243 } 244 ((BufImgSurfaceData) sData).initSolidLoops(); 245 return sData; 246 } 247 248 public static SurfaceData createData(Raster ras, ColorModel cm) { 249 throw new InternalError("SurfaceData not implemented for Raster/CM"); 250 } 251 252 public static SurfaceData createDataIC(BufferedImage bImg, 253 SurfaceType sType) { 254 IntegerComponentRaster icRaster = 255 (IntegerComponentRaster)bImg.getRaster(); 256 BufImgSurfaceData bisd = 257 new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType); 258 bisd.initRaster(icRaster.getDataStorage(), 259 icRaster.getDataOffset(0) * 4, 0, 260 icRaster.getWidth(), 261 icRaster.getHeight(), 262 icRaster.getPixelStride() * 4, 263 icRaster.getScanlineStride() * 4, 264 null); 265 return bisd; 266 } 267 268 public static SurfaceData createDataSC(BufferedImage bImg, 269 SurfaceType sType, 270 IndexColorModel icm) { 271 ShortComponentRaster scRaster = 272 (ShortComponentRaster)bImg.getRaster(); 273 BufImgSurfaceData bisd = 274 new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType); 275 bisd.initRaster(scRaster.getDataStorage(), 276 scRaster.getDataOffset(0) * 2, 0, 277 scRaster.getWidth(), 278 scRaster.getHeight(), 279 scRaster.getPixelStride() * 2, 280 scRaster.getScanlineStride() * 2, 281 icm); 282 return bisd; 283 } 284 285 public static SurfaceData createDataBC(BufferedImage bImg, 286 SurfaceType sType, 287 int primaryBank) { 288 ByteComponentRaster bcRaster = 289 (ByteComponentRaster)bImg.getRaster(); 290 BufImgSurfaceData bisd = 291 new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType); 292 ColorModel cm = bImg.getColorModel(); 293 IndexColorModel icm = ((cm instanceof IndexColorModel) 294 ? (IndexColorModel) cm 295 : null); 296 bisd.initRaster(bcRaster.getDataStorage(), 297 bcRaster.getDataOffset(primaryBank), 0, 298 bcRaster.getWidth(), 299 bcRaster.getHeight(), 300 bcRaster.getPixelStride(), 301 bcRaster.getScanlineStride(), 302 icm); 303 return bisd; 304 } 305 306 public static SurfaceData createDataBP(BufferedImage bImg, 307 SurfaceType sType) { 308 BytePackedRaster bpRaster = 309 (BytePackedRaster)bImg.getRaster(); 310 BufImgSurfaceData bisd = 311 new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType); 312 ColorModel cm = bImg.getColorModel(); 313 IndexColorModel icm = ((cm instanceof IndexColorModel) 314 ? (IndexColorModel) cm 315 : null); 316 bisd.initRaster(bpRaster.getDataStorage(), 317 bpRaster.getDataBitOffset() / 8, 318 bpRaster.getDataBitOffset() & 7, 319 bpRaster.getWidth(), 320 bpRaster.getHeight(), 321 0, 322 bpRaster.getScanlineStride(), 323 icm); 324 return bisd; 325 } 326 327 public RenderLoops getRenderLoops(SunGraphics2D sg2d) { 328 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && 329 sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY) 330 { 331 return solidloops; 333 return super.getRenderLoops(sg2d); 334 } 335 336 public java.awt.image.Raster getRaster(int x, int y, int w, int h) { 337 return bufImg.getRaster(); 338 } 339 340 /** 341 * Initializes the native Ops pointer. 342 */ 343 protected native void initRaster(Object theArray, 344 int offset, 345 int bitoffset, 346 int width, 347 int height, 348 int pixStr, 349 int scanStr, 350 IndexColorModel icm); 351 352 public BufImgSurfaceData(DataBuffer db, 353 BufferedImage bufImg, SurfaceType sType) 354 { 355 super(SunWritableRaster.stealTrackable(db), 356 sType, bufImg.getColorModel()); 357 this.bufImg = bufImg; 358 } 359 360 protected BufImgSurfaceData(SurfaceType surfaceType, ColorModel cm) { 361 super(surfaceType, cm); 362 } 363 364 public void initSolidLoops() { 365 this.solidloops = getSolidLoops(getSurfaceType()); 366 } 367 368 private static final int CACHE_SIZE = 5; 369 private static RenderLoops loopcache[] = new RenderLoops[CACHE_SIZE]; 370 private static SurfaceType typecache[] = new SurfaceType[CACHE_SIZE]; 371 public static synchronized RenderLoops getSolidLoops(SurfaceType type) { 372 for (int i = CACHE_SIZE - 1; i >= 0; i--) { 373 SurfaceType t = typecache[i]; 374 if (t == type) { 375 return loopcache[i]; 376 } else if (t == null) { 377 break; 378 } 379 } 380 RenderLoops l = makeRenderLoops(SurfaceType.OpaqueColor, 381 CompositeType.SrcNoEa, 382 type); 383 System.arraycopy(loopcache, 1, loopcache, 0, CACHE_SIZE-1); 384 System.arraycopy(typecache, 1, typecache, 0, CACHE_SIZE-1); 385 loopcache[CACHE_SIZE - 1] = l; 386 typecache[CACHE_SIZE - 1] = type; 387 return l; 388 } 389 390 public SurfaceData getReplacement() { 391 // BufImgSurfaceData objects should never lose their contents, 392 // so this method should never be called. 393 return restoreContents(bufImg); 394 } 395 396 public synchronized GraphicsConfiguration getDeviceConfiguration() { 397 if (graphicsConfig == null) { 398 graphicsConfig = BufferedImageGraphicsConfig.getConfig(bufImg); 399 } 400 return graphicsConfig; 401 } 402 403 public java.awt.Rectangle getBounds() { 404 return new Rectangle(bufImg.getWidth(), bufImg.getHeight()); 405 } 406 407 protected void checkCustomComposite() { 408 // BufferedImages always allow Custom Composite objects since 409 // their pixels are immediately retrievable anyway. 410 } 411 412 private static native void freeNativeICMData(long pData); 413 414 /** 415 * Returns destination Image associated with this SurfaceData. 416 */ 417 public Object getDestination() { 418 return bufImg; 419 } 420 421 public static final class ICMColorData { 422 private long pData = 0L; 423 424 private ICMColorData(long pData) { 425 this.pData = pData; 426 } 427 428 public void finalize() { 429 if (pData != 0L) { 430 BufImgSurfaceData.freeNativeICMData(pData); 431 pData = 0L; 432 } 433 } 434 } 435 } | 33 import java.awt.image.DirectColorModel; 34 import java.awt.image.IndexColorModel; 35 import java.awt.image.Raster; 36 import java.awt.image.BufferedImage; 37 import java.awt.image.DataBuffer; 38 39 import sun.java2d.SurfaceData; 40 import sun.java2d.SunGraphics2D; 41 import sun.java2d.StateTrackable; 42 import sun.java2d.StateTrackable.*; 43 import sun.java2d.StateTracker; 44 import sun.java2d.loops.SurfaceType; 45 import sun.java2d.loops.CompositeType; 46 import sun.java2d.loops.RenderLoops; 47 48 49 public class BufImgSurfaceData extends SurfaceData { 50 BufferedImage bufImg; 51 private BufferedImageGraphicsConfig graphicsConfig; 52 RenderLoops solidloops; 53 private final double scaleX; 54 private final double scaleY; 55 56 private static native void initIDs(Class<?> ICM, Class<?> ICMColorData); 57 58 private static final int DCM_RGBX_RED_MASK = 0xff000000; 59 private static final int DCM_RGBX_GREEN_MASK = 0x00ff0000; 60 private static final int DCM_RGBX_BLUE_MASK = 0x0000ff00; 61 private static final int DCM_555X_RED_MASK = 0xF800; 62 private static final int DCM_555X_GREEN_MASK = 0x07C0; 63 private static final int DCM_555X_BLUE_MASK = 0x003E; 64 private static final int DCM_4444_RED_MASK = 0x0f00; 65 private static final int DCM_4444_GREEN_MASK = 0x00f0; 66 private static final int DCM_4444_BLUE_MASK = 0x000f; 67 private static final int DCM_4444_ALPHA_MASK = 0xf000; 68 private static final int DCM_ARGBBM_ALPHA_MASK = 0x01000000; 69 private static final int DCM_ARGBBM_RED_MASK = 0x00ff0000; 70 private static final int DCM_ARGBBM_GREEN_MASK = 0x0000ff00; 71 private static final int DCM_ARGBBM_BLUE_MASK = 0x000000ff; 72 73 static { 74 initIDs(IndexColorModel.class, ICMColorData.class); 75 } 76 77 public static SurfaceData createData(BufferedImage bufImg) { 78 return createData(bufImg, 1, 1); 79 } 80 81 public static SurfaceData createData(BufferedImage bufImg, 82 double scaleX, double scaleY) 83 { 84 if (bufImg == null) { 85 throw new NullPointerException("BufferedImage cannot be null"); 86 } 87 SurfaceData sData; 88 ColorModel cm = bufImg.getColorModel(); 89 int type = bufImg.getType(); 90 // REMIND: Check the image type and pick an appropriate subclass 91 switch (type) { 92 case BufferedImage.TYPE_INT_BGR: 93 sData = createDataIC(bufImg, SurfaceType.IntBgr, scaleX, scaleY); 94 break; 95 case BufferedImage.TYPE_INT_RGB: 96 sData = createDataIC(bufImg, SurfaceType.IntRgb, scaleX, scaleY); 97 break; 98 case BufferedImage.TYPE_INT_ARGB: 99 sData = createDataIC(bufImg, SurfaceType.IntArgb, scaleX, scaleY); 100 break; 101 case BufferedImage.TYPE_INT_ARGB_PRE: 102 sData = createDataIC(bufImg, SurfaceType.IntArgbPre, scaleX, scaleY); 103 break; 104 case BufferedImage.TYPE_3BYTE_BGR: 105 sData = createDataBC(bufImg, SurfaceType.ThreeByteBgr, 2, 106 scaleX, scaleY); 107 break; 108 case BufferedImage.TYPE_4BYTE_ABGR: 109 sData = createDataBC(bufImg, SurfaceType.FourByteAbgr, 3, 110 scaleX, scaleY); 111 break; 112 case BufferedImage.TYPE_4BYTE_ABGR_PRE: 113 sData = createDataBC(bufImg, SurfaceType.FourByteAbgrPre, 3, 114 scaleX, scaleY); 115 break; 116 case BufferedImage.TYPE_USHORT_565_RGB: 117 sData = createDataSC(bufImg, SurfaceType.Ushort565Rgb, null, 118 scaleX, scaleY); 119 break; 120 case BufferedImage.TYPE_USHORT_555_RGB: 121 sData = createDataSC(bufImg, SurfaceType.Ushort555Rgb, null, 122 scaleX, scaleY); 123 break; 124 case BufferedImage.TYPE_BYTE_INDEXED: 125 { 126 SurfaceType sType; 127 switch (cm.getTransparency()) { 128 case OPAQUE: 129 if (isOpaqueGray((IndexColorModel)cm)) { 130 sType = SurfaceType.Index8Gray; 131 } else { 132 sType = SurfaceType.ByteIndexedOpaque; 133 } 134 break; 135 case BITMASK: 136 sType = SurfaceType.ByteIndexedBm; 137 break; 138 case TRANSLUCENT: 139 sType = SurfaceType.ByteIndexed; 140 break; 141 default: 142 throw new InternalError("Unrecognized transparency"); 143 } 144 sData = createDataBC(bufImg, sType, 0, scaleX, scaleY); 145 } 146 break; 147 case BufferedImage.TYPE_BYTE_GRAY: 148 sData = createDataBC(bufImg, SurfaceType.ByteGray, 0, 149 scaleX, scaleY); 150 break; 151 case BufferedImage.TYPE_USHORT_GRAY: 152 sData = createDataSC(bufImg, SurfaceType.UshortGray, null, 153 scaleX, scaleY); 154 break; 155 case BufferedImage.TYPE_BYTE_BINARY: 156 { 157 SurfaceType sType; 158 SampleModel sm = bufImg.getRaster().getSampleModel(); 159 switch (sm.getSampleSize(0)) { 160 case 1: 161 sType = SurfaceType.ByteBinary1Bit; 162 break; 163 case 2: 164 sType = SurfaceType.ByteBinary2Bit; 165 break; 166 case 4: 167 sType = SurfaceType.ByteBinary4Bit; 168 break; 169 default: 170 throw new InternalError("Unrecognized pixel size"); 171 } 172 sData = createDataBP(bufImg, sType, scaleX, scaleY); 173 } 174 break; 175 case BufferedImage.TYPE_CUSTOM: 176 default: 177 { 178 Raster raster = bufImg.getRaster(); 179 int numBands = raster.getNumBands(); 180 if (raster instanceof IntegerComponentRaster && 181 raster.getNumDataElements() == 1 && 182 ((IntegerComponentRaster)raster).getPixelStride() == 1) 183 { 184 SurfaceType sType = SurfaceType.AnyInt; 185 if (cm instanceof DirectColorModel) { 186 DirectColorModel dcm = (DirectColorModel) cm; 187 int aMask = dcm.getAlphaMask(); 188 int rMask = dcm.getRedMask(); 189 int gMask = dcm.getGreenMask(); 190 int bMask = dcm.getBlueMask(); 191 if (numBands == 3 && 192 aMask == 0 && 193 rMask == DCM_RGBX_RED_MASK && 194 gMask == DCM_RGBX_GREEN_MASK && 195 bMask == DCM_RGBX_BLUE_MASK) 196 { 197 sType = SurfaceType.IntRgbx; 198 } else if (numBands == 4 && 199 aMask == DCM_ARGBBM_ALPHA_MASK && 200 rMask == DCM_ARGBBM_RED_MASK && 201 gMask == DCM_ARGBBM_GREEN_MASK && 202 bMask == DCM_ARGBBM_BLUE_MASK) 203 { 204 sType = SurfaceType.IntArgbBm; 205 } else { 206 sType = SurfaceType.AnyDcm; 207 } 208 } 209 sData = createDataIC(bufImg, sType, scaleX, scaleY); 210 break; 211 } else if (raster instanceof ShortComponentRaster && 212 raster.getNumDataElements() == 1 && 213 ((ShortComponentRaster)raster).getPixelStride() == 1) 214 { 215 SurfaceType sType = SurfaceType.AnyShort; 216 IndexColorModel icm = null; 217 if (cm instanceof DirectColorModel) { 218 DirectColorModel dcm = (DirectColorModel) cm; 219 int aMask = dcm.getAlphaMask(); 220 int rMask = dcm.getRedMask(); 221 int gMask = dcm.getGreenMask(); 222 int bMask = dcm.getBlueMask(); 223 if (numBands == 3 && 224 aMask == 0 && 225 rMask == DCM_555X_RED_MASK && 226 gMask == DCM_555X_GREEN_MASK && 227 bMask == DCM_555X_BLUE_MASK) 228 { 229 sType = SurfaceType.Ushort555Rgbx; 231 if (numBands == 4 && 232 aMask == DCM_4444_ALPHA_MASK && 233 rMask == DCM_4444_RED_MASK && 234 gMask == DCM_4444_GREEN_MASK && 235 bMask == DCM_4444_BLUE_MASK) 236 { 237 sType = SurfaceType.Ushort4444Argb; 238 } 239 } else if (cm instanceof IndexColorModel) { 240 icm = (IndexColorModel)cm; 241 if (icm.getPixelSize() == 12) { 242 if (isOpaqueGray(icm)) { 243 sType = SurfaceType.Index12Gray; 244 } else { 245 sType = SurfaceType.UshortIndexed; 246 } 247 } else { 248 icm = null; 249 } 250 } 251 sData = createDataSC(bufImg, sType, icm, scaleX, scaleY); 252 break; 253 } 254 sData = new BufImgSurfaceData(raster.getDataBuffer(), bufImg, 255 SurfaceType.Custom, 256 scaleX, scaleY); 257 } 258 break; 259 } 260 ((BufImgSurfaceData) sData).initSolidLoops(); 261 return sData; 262 } 263 264 public static SurfaceData createData(Raster ras, ColorModel cm) { 265 throw new InternalError("SurfaceData not implemented for Raster/CM"); 266 } 267 268 public static SurfaceData createDataIC(BufferedImage bImg, 269 SurfaceType sType, 270 double scaleX, 271 double scaleY) 272 { 273 IntegerComponentRaster icRaster = 274 (IntegerComponentRaster)bImg.getRaster(); 275 BufImgSurfaceData bisd = 276 new BufImgSurfaceData(icRaster.getDataBuffer(), bImg, sType, 277 scaleX, scaleY); 278 bisd.initRaster(icRaster.getDataStorage(), 279 icRaster.getDataOffset(0) * 4, 0, 280 icRaster.getWidth(), 281 icRaster.getHeight(), 282 icRaster.getPixelStride() * 4, 283 icRaster.getScanlineStride() * 4, 284 null); 285 return bisd; 286 } 287 288 public static SurfaceData createDataSC(BufferedImage bImg, 289 SurfaceType sType, 290 IndexColorModel icm, 291 double scaleX, double scaleY) 292 { 293 ShortComponentRaster scRaster = 294 (ShortComponentRaster)bImg.getRaster(); 295 BufImgSurfaceData bisd = 296 new BufImgSurfaceData(scRaster.getDataBuffer(), bImg, sType, 297 scaleX, scaleY); 298 bisd.initRaster(scRaster.getDataStorage(), 299 scRaster.getDataOffset(0) * 2, 0, 300 scRaster.getWidth(), 301 scRaster.getHeight(), 302 scRaster.getPixelStride() * 2, 303 scRaster.getScanlineStride() * 2, 304 icm); 305 return bisd; 306 } 307 308 public static SurfaceData createDataBC(BufferedImage bImg, 309 SurfaceType sType, 310 int primaryBank, 311 double scaleX, double scaleY) 312 { 313 ByteComponentRaster bcRaster = 314 (ByteComponentRaster)bImg.getRaster(); 315 BufImgSurfaceData bisd = 316 new BufImgSurfaceData(bcRaster.getDataBuffer(), bImg, sType, 317 scaleX, scaleY); 318 ColorModel cm = bImg.getColorModel(); 319 IndexColorModel icm = ((cm instanceof IndexColorModel) 320 ? (IndexColorModel) cm 321 : null); 322 bisd.initRaster(bcRaster.getDataStorage(), 323 bcRaster.getDataOffset(primaryBank), 0, 324 bcRaster.getWidth(), 325 bcRaster.getHeight(), 326 bcRaster.getPixelStride(), 327 bcRaster.getScanlineStride(), 328 icm); 329 return bisd; 330 } 331 332 public static SurfaceData createDataBP(BufferedImage bImg, 333 SurfaceType sType, 334 double scaleX, double scaleY) 335 { 336 BytePackedRaster bpRaster = 337 (BytePackedRaster)bImg.getRaster(); 338 BufImgSurfaceData bisd = 339 new BufImgSurfaceData(bpRaster.getDataBuffer(), bImg, sType, 340 scaleX, scaleY); 341 ColorModel cm = bImg.getColorModel(); 342 IndexColorModel icm = ((cm instanceof IndexColorModel) 343 ? (IndexColorModel) cm 344 : null); 345 bisd.initRaster(bpRaster.getDataStorage(), 346 bpRaster.getDataBitOffset() / 8, 347 bpRaster.getDataBitOffset() & 7, 348 bpRaster.getWidth(), 349 bpRaster.getHeight(), 350 0, 351 bpRaster.getScanlineStride(), 352 icm); 353 return bisd; 354 } 355 356 public RenderLoops getRenderLoops(SunGraphics2D sg2d) { 357 if (sg2d.paintState <= SunGraphics2D.PAINT_ALPHACOLOR && 358 sg2d.compositeState <= SunGraphics2D.COMP_ISCOPY) 359 { 360 return solidloops; 362 return super.getRenderLoops(sg2d); 363 } 364 365 public java.awt.image.Raster getRaster(int x, int y, int w, int h) { 366 return bufImg.getRaster(); 367 } 368 369 /** 370 * Initializes the native Ops pointer. 371 */ 372 protected native void initRaster(Object theArray, 373 int offset, 374 int bitoffset, 375 int width, 376 int height, 377 int pixStr, 378 int scanStr, 379 IndexColorModel icm); 380 381 public BufImgSurfaceData(DataBuffer db, 382 BufferedImage bufImg, 383 SurfaceType sType, 384 double scaleX, 385 double scaleY) 386 { 387 super(SunWritableRaster.stealTrackable(db), 388 sType, bufImg.getColorModel()); 389 this.bufImg = bufImg; 390 this.scaleX = scaleX; 391 this.scaleY = scaleY; 392 } 393 394 protected BufImgSurfaceData(SurfaceType surfaceType, ColorModel cm) { 395 super(surfaceType, cm); 396 this.scaleX = 1; 397 this.scaleY = 1; 398 } 399 400 public void initSolidLoops() { 401 this.solidloops = getSolidLoops(getSurfaceType()); 402 } 403 404 private static final int CACHE_SIZE = 5; 405 private static RenderLoops loopcache[] = new RenderLoops[CACHE_SIZE]; 406 private static SurfaceType typecache[] = new SurfaceType[CACHE_SIZE]; 407 public static synchronized RenderLoops getSolidLoops(SurfaceType type) { 408 for (int i = CACHE_SIZE - 1; i >= 0; i--) { 409 SurfaceType t = typecache[i]; 410 if (t == type) { 411 return loopcache[i]; 412 } else if (t == null) { 413 break; 414 } 415 } 416 RenderLoops l = makeRenderLoops(SurfaceType.OpaqueColor, 417 CompositeType.SrcNoEa, 418 type); 419 System.arraycopy(loopcache, 1, loopcache, 0, CACHE_SIZE-1); 420 System.arraycopy(typecache, 1, typecache, 0, CACHE_SIZE-1); 421 loopcache[CACHE_SIZE - 1] = l; 422 typecache[CACHE_SIZE - 1] = type; 423 return l; 424 } 425 426 public SurfaceData getReplacement() { 427 // BufImgSurfaceData objects should never lose their contents, 428 // so this method should never be called. 429 return restoreContents(bufImg); 430 } 431 432 public synchronized GraphicsConfiguration getDeviceConfiguration() { 433 if (graphicsConfig == null) { 434 graphicsConfig = BufferedImageGraphicsConfig 435 .getConfig(bufImg, scaleX, scaleY); 436 } 437 return graphicsConfig; 438 } 439 440 public java.awt.Rectangle getBounds() { 441 return new Rectangle(bufImg.getWidth(), bufImg.getHeight()); 442 } 443 444 protected void checkCustomComposite() { 445 // BufferedImages always allow Custom Composite objects since 446 // their pixels are immediately retrievable anyway. 447 } 448 449 private static native void freeNativeICMData(long pData); 450 451 /** 452 * Returns destination Image associated with this SurfaceData. 453 */ 454 public Object getDestination() { 455 return bufImg; 456 } 457 458 @Override 459 public double getDefaultScaleX() { 460 return scaleX; 461 } 462 463 @Override 464 public double getDefaultScaleY() { 465 return scaleY; 466 } 467 468 public static final class ICMColorData { 469 private long pData = 0L; 470 471 private ICMColorData(long pData) { 472 this.pData = pData; 473 } 474 475 public void finalize() { 476 if (pData != 0L) { 477 BufImgSurfaceData.freeNativeICMData(pData); 478 pData = 0L; 479 } 480 } 481 } 482 } |