1 /* 2 * Copyright (c) 2012, 2014, 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 test.com.sun.javafx.image; 27 28 import com.sun.javafx.image.AlphaType; 29 import com.sun.javafx.image.BytePixelGetter; 30 import com.sun.javafx.image.BytePixelSetter; 31 import com.sun.javafx.image.ByteToBytePixelConverter; 32 import com.sun.javafx.image.ByteToIntPixelConverter; 33 import com.sun.javafx.image.IntPixelGetter; 34 import com.sun.javafx.image.IntPixelSetter; 35 import com.sun.javafx.image.IntToBytePixelConverter; 36 import com.sun.javafx.image.IntToIntPixelConverter; 37 import com.sun.javafx.image.PixelConverter; 38 import com.sun.javafx.image.PixelGetter; 39 import com.sun.javafx.image.PixelSetter; 40 import com.sun.javafx.image.PixelUtils; 41 import com.sun.javafx.image.impl.ByteArgb; 42 import com.sun.javafx.image.impl.ByteBgr; 43 import com.sun.javafx.image.impl.ByteBgra; 44 import com.sun.javafx.image.impl.ByteBgraPre; 45 import com.sun.javafx.image.impl.ByteGray; 46 import com.sun.javafx.image.impl.ByteGrayAlpha; 47 import com.sun.javafx.image.impl.ByteGrayAlphaPre; 48 import com.sun.javafx.image.impl.ByteRgb; 49 import com.sun.javafx.image.impl.ByteRgba; 50 import com.sun.javafx.image.impl.IntArgb; 51 import com.sun.javafx.image.impl.IntArgbPre; 52 import static junit.framework.Assert.*; 53 54 import java.nio.ByteBuffer; 55 import java.nio.IntBuffer; 56 import javafx.scene.image.PixelFormat; 57 import javafx.scene.image.WritablePixelFormat; 58 import javafx.scene.paint.Color; 59 import org.junit.Test; 60 61 /** 62 */ 63 public class ConverterTest { 64 static ByteBuffer heapByteBuffer(int off, int len) { 65 ByteBuffer bbuf = ByteBuffer.allocate(off + len); 66 if (off > 0) { 67 bbuf.position(off); 68 bbuf = bbuf.slice(); 69 } 70 return bbuf; 71 } 72 73 static ByteBuffer directByteBuffer(int off, int len) { 74 ByteBuffer bbuf = ByteBuffer.allocateDirect(off + len); 75 if (off > 0) { 76 bbuf.position(off); 77 bbuf = bbuf.slice(); 78 } 79 return bbuf; 80 } 81 82 static IntBuffer heapIntBuffer(int off, int len) { 83 IntBuffer ibuf = IntBuffer.allocate(off + len); 84 if (off > 0) { 85 ibuf.position(off); 86 ibuf = ibuf.slice(); 87 } 88 return ibuf; 89 } 90 91 static IntBuffer directIntBuffer(int off, int len) { 92 IntBuffer ibuf = ByteBuffer.allocateDirect((off + len) * 4).asIntBuffer(); 93 if (off > 0) { 94 ibuf.position(off); 95 ibuf = ibuf.slice(); 96 } 97 return ibuf; 98 } 99 100 static Color derive(Color c, double opacity) { 101 return new Color(c.getRed(), c.getGreen(), c.getBlue(), c.getOpacity() * opacity); 102 } 103 104 static int RgbToGray(int red, int green, int blue) { 105 return (int) (red * .3 + green * .59 + blue * .11); 106 } 107 108 static int grayify(int argb) { 109 int alpha = (argb >> 24) & 0xff; 110 int red = (argb >> 16) & 0xff; 111 int green = (argb >> 8) & 0xff; 112 int blue = (argb ) & 0xff; 113 int gray = RgbToGray(red, green, blue); 114 return (alpha << 24) | (gray << 16) | (gray << 8) | gray; 115 } 116 117 static int getArgb(Color c) { 118 int alpha = (int) (c.getOpacity() * 255f); 119 int red = (int) (c.getRed() * 255f); 120 int green = (int) (c.getGreen() * 255f); 121 int blue = (int) (c.getBlue() * 255f); 122 return (alpha << 24) | (red << 16) | (green << 8) | blue; 123 } 124 125 static int getArgbPre(Color c) { 126 double a = c.getOpacity(); 127 int alpha = (int) (a * 255f); 128 int red = (int) (a * c.getRed() * 255f); 129 int green = (int) (a * c.getGreen() * 255f); 130 int blue = (int) (a * c.getBlue() * 255f); 131 return (alpha << 24) | (red << 16) | (green << 8) | blue; 132 } 133 134 static class ByteFormat { 135 private final BytePixelGetter getter; 136 private final BytePixelSetter setter; 137 private final int aoff, roff, goff, boff, grayoff; 138 private final int ncomp; 139 140 public ByteFormat(BytePixelGetter getter, 141 int aoff, int roff, int goff, int boff) 142 { 143 if (getter == null) throw new NullPointerException("getter must not be null"); 144 145 this.getter = getter; 146 this.setter = null; 147 this.grayoff = -1; 148 this.aoff = aoff; 149 this.roff = roff; 150 this.goff = goff; 151 this.boff = boff; 152 this.ncomp = (aoff < 0) ? 3 : 4; 153 } 154 155 public ByteFormat(BytePixelGetter getter, BytePixelSetter setter, 156 int aoff, int roff, int goff, int boff) 157 { 158 if (getter == null) throw new NullPointerException("getter must not be null"); 159 if (setter == null) throw new NullPointerException("setter must not be null"); 160 161 this.getter = getter; 162 this.setter = setter; 163 this.grayoff = -1; 164 this.aoff = aoff; 165 this.roff = roff; 166 this.goff = goff; 167 this.boff = boff; 168 this.ncomp = (aoff < 0) ? 3 : 4; 169 } 170 171 public ByteFormat(BytePixelGetter getter, 172 int aoff, int grayoff) 173 { 174 if (getter == null) throw new NullPointerException("getter must not be null"); 175 176 this.getter = getter; 177 this.setter = null; 178 this.grayoff = grayoff; 179 this.aoff = aoff; 180 this.roff = -1; 181 this.goff = -1; 182 this.boff = -1; 183 this.ncomp = (aoff < 0) ? 1 : 2; 184 } 185 186 public ByteFormat(BytePixelGetter getter, BytePixelSetter setter, 187 int aoff, int grayoff) 188 { 189 if (getter == null) throw new NullPointerException("getter must not be null"); 190 if (setter == null) throw new NullPointerException("setter must not be null"); 191 192 this.getter = getter; 193 this.setter = setter; 194 this.grayoff = grayoff; 195 this.aoff = aoff; 196 this.roff = -1; 197 this.goff = -1; 198 this.boff = -1; 199 this.ncomp = (aoff < 0) ? 1 : 2; 200 } 201 202 public int getNcomp() { 203 return ncomp; 204 } 205 206 public int getArgb(byte barr[], int off) { 207 int alpha = (aoff < 0) ? 255 : (barr[off + aoff] & 0xff); 208 int red, green, blue; 209 if (isGray()) { 210 red = green = blue = barr[off + grayoff] & 0xff; 211 } else { 212 red = barr[off + roff] & 0xff; 213 green = barr[off + goff] & 0xff; 214 blue = barr[off + boff] & 0xff; 215 } 216 if (alpha < 255 && alpha > 0 && getter.getAlphaType() == AlphaType.PREMULTIPLIED) { 217 int halfa = alpha >> 1; 218 red = (red >= alpha) ? 255 : (red * 255 + halfa) / alpha; 219 green = (green >= alpha) ? 255 : (green * 255 + halfa) / alpha; 220 blue = (blue >= alpha) ? 255 : (blue * 255 + halfa) / alpha; 221 } 222 return (alpha << 24) | (red << 16) | (green << 8) | blue; 223 } 224 225 public int getArgb(ByteBuffer bbuf, int off) { 226 int alpha = (aoff < 0) ? 255 : (bbuf.get(off + aoff) & 0xff); 227 int red, green, blue; 228 if (isGray()) { 229 red = green = blue = bbuf.get(off + grayoff) & 0xff; 230 } else { 231 red = bbuf.get(off + roff) & 0xff; 232 green = bbuf.get(off + goff) & 0xff; 233 blue = bbuf.get(off + boff) & 0xff; 234 } 235 if (alpha < 255 && alpha > 0 && getter.getAlphaType() == AlphaType.PREMULTIPLIED) { 236 int halfa = alpha >> 1; 237 red = (red >= alpha) ? 255 : (red * 255 + halfa) / alpha; 238 green = (green >= alpha) ? 255 : (green * 255 + halfa) / alpha; 239 blue = (blue >= alpha) ? 255 : (blue * 255 + halfa) / alpha; 240 } 241 return (alpha << 24) | (red << 16) | (green << 8) | blue; 242 } 243 244 public void setArgb(byte barr[], int off, int argb) { 245 int alpha = (argb >> 24) & 0xff; 246 int red = (argb >> 16) & 0xff; 247 int green = (argb >> 8) & 0xff; 248 int blue = (argb ) & 0xff; 249 if (getter.getAlphaType() == AlphaType.PREMULTIPLIED) { 250 red = (red * alpha + 127) / 255; 251 green = (green * alpha + 127) / 255; 252 blue = (blue * alpha + 127) / 255; 253 } 254 if (aoff >= 0) { 255 barr[off + aoff] = (byte) alpha; 256 } 257 if (isGray()) { 258 int gray = RgbToGray(red, green, blue); 259 barr[off + grayoff] = (byte) gray; 260 } else { 261 barr[off + roff] = (byte) red; 262 barr[off + goff] = (byte) green; 263 barr[off + boff] = (byte) blue; 264 } 265 } 266 267 public void setArgb(ByteBuffer bbuf, int off, int argb) { 268 int alpha = (argb >> 24) & 0xff; 269 int red = (argb >> 16) & 0xff; 270 int green = (argb >> 8) & 0xff; 271 int blue = (argb ) & 0xff; 272 if (getter.getAlphaType() == AlphaType.PREMULTIPLIED) { 273 red = (red * alpha + 127) / 255; 274 green = (green * alpha + 127) / 255; 275 blue = (blue * alpha + 127) / 255; 276 } 277 if (aoff >= 0) { 278 bbuf.put(off + aoff, (byte) alpha); 279 } 280 if (isGray()) { 281 int gray = RgbToGray(red, green, blue); 282 bbuf.put(off + grayoff, (byte) gray); 283 } else { 284 bbuf.put(off + roff, (byte) red); 285 bbuf.put(off + goff, (byte) green); 286 bbuf.put(off + boff, (byte) blue); 287 } 288 } 289 290 public BytePixelGetter getGetter() { 291 return getter; 292 } 293 294 public BytePixelSetter getSetter() { 295 return setter; 296 } 297 298 public boolean isGray() { 299 return grayoff >= 0; 300 } 301 302 public int getGrayOff() { 303 return grayoff; 304 } 305 306 public int getAoff() { 307 return aoff; 308 } 309 310 public int getRoff() { 311 return roff; 312 } 313 314 public int getGoff() { 315 return goff; 316 } 317 318 public int getBoff() { 319 return boff; 320 } 321 322 @Override 323 public String toString() { 324 if (getter == null) { 325 return "ByteFormat{" + "setter=" + setter + '}'; 326 } else if (setter == null) { 327 return "ByteFormat{" + "getter=" + getter + '}'; 328 } else if (getter == setter) { 329 return "ByteFormat{" + "accessor=" + getter + '}'; 330 } else { 331 return "ByteFormat{" + "getter=" + getter + ", setter=" + setter + '}'; 332 } 333 } 334 } 335 336 static class IntFormat { 337 private final IntPixelGetter getter; 338 private final IntPixelSetter setter; 339 private final int ashift, rshift, gshift, bshift; 340 341 public IntFormat(IntPixelGetter getter, IntPixelSetter setter, 342 int ashift, int rshift, int gshift, int bshift) 343 { 344 if (getter == null) throw new NullPointerException("getter must not be null"); 345 if (setter == null) throw new NullPointerException("setter must not be null"); 346 347 this.getter = getter; 348 this.setter = setter; 349 this.ashift = ashift; 350 this.rshift = rshift; 351 this.gshift = gshift; 352 this.bshift = bshift; 353 } 354 355 private int convertPixel(int pixel) { 356 int alpha = (pixel >> ashift) & 0xff; 357 int red = (pixel >> rshift) & 0xff; 358 int green = (pixel >> gshift) & 0xff; 359 int blue = (pixel >> bshift) & 0xff; 360 if (alpha > 0 && alpha < 255 && getter.getAlphaType() == AlphaType.PREMULTIPLIED) { 361 int halfa = alpha >> 1; 362 red = (red >= alpha) ? 255 : (red * 255 + halfa) / alpha; 363 green = (green >= alpha) ? 255 : (green * 255 + halfa) / alpha; 364 blue = (blue >= alpha) ? 255 : (blue * 255 + halfa) / alpha; 365 } 366 return (alpha << 24) | (red << 16) | (green << 8) | blue; 367 } 368 369 private int convertArgb(int argb) { 370 int alpha = (argb >> 24) & 0xff; 371 int red = (argb >> 16) & 0xff; 372 int green = (argb >> 8) & 0xff; 373 int blue = (argb ) & 0xff; 374 if (alpha < 255 && getter.getAlphaType() == AlphaType.PREMULTIPLIED) { 375 red = (red * alpha + 127) / 255; 376 green = (green * alpha + 127) / 255; 377 blue = (blue * alpha + 127) / 255; 378 } 379 return (alpha << ashift) | (red << rshift) | (green << gshift) | (blue << bshift); 380 } 381 382 public int getArgb(int iarr[], int off) { 383 return convertPixel(iarr[off]); 384 } 385 386 public int getArgb(IntBuffer ibuf, int off) { 387 return convertPixel(ibuf.get(off)); 388 } 389 390 public void setArgb(int iarr[], int off, int argb) { 391 iarr[off] = convertArgb(argb); 392 } 393 394 public void setArgb(IntBuffer ibuf, int off, int argb) { 395 ibuf.put(off, convertArgb(argb)); 396 } 397 398 public IntPixelGetter getGetter() { 399 return getter; 400 } 401 402 public IntPixelSetter getSetter() { 403 return setter; 404 } 405 406 public int getAshift() { 407 return ashift; 408 } 409 410 public int getRshift() { 411 return rshift; 412 } 413 414 public int getGshift() { 415 return gshift; 416 } 417 418 public int getBshift() { 419 return bshift; 420 } 421 422 @Override 423 public String toString() { 424 if (getter == null) { 425 return "IntFormat{" + "setter=" + setter + '}'; 426 } else if (setter == null) { 427 return "IntFormat{" + "getter=" + getter + '}'; 428 } else if (getter == setter) { 429 return "IntFormat{" + "accessor=" + getter + '}'; 430 } else { 431 return "IntFormat{" + "getter=" + getter + ", setter=" + setter + '}'; 432 } 433 } 434 } 435 436 437 static ByteFormat ByteFormats[] = { 438 new ByteFormat(ByteArgb.getter, ByteArgb.setter, 0, 1, 2, 3), 439 new ByteFormat(ByteBgra.getter, ByteBgra.setter, 3, 2, 1, 0), 440 new ByteFormat(ByteBgraPre.getter, ByteBgraPre.setter, 3, 2, 1, 0), 441 new ByteFormat(ByteRgba.getter, ByteRgba.setter, 3, 0, 1, 2), 442 new ByteFormat(ByteRgb.getter, -1, 0, 1, 2), 443 new ByteFormat(ByteBgr.getter, ByteBgr.setter, -1, 2, 1, 0), 444 445 new ByteFormat(ByteGray.getter, ByteGray.setter, -1, 0), 446 new ByteFormat(ByteGrayAlpha.getter, ByteGrayAlpha.setter, 1, 0), 447 new ByteFormat(ByteGrayAlphaPre.getter, ByteGrayAlphaPre.setter, 1, 0), 448 }; 449 450 static IntFormat IntFormats[] = { 451 new IntFormat(IntArgb.getter, IntArgb.setter, 24, 16, 8, 0), 452 new IntFormat(IntArgbPre.getter, IntArgbPre.setter, 24, 16, 8, 0), 453 }; 454 455 static Color TestColors[] = { 456 Color.WHITE, 457 Color.BLACK, 458 Color.RED, 459 Color.GREEN, 460 Color.BLUE, 461 Color.TRANSPARENT, 462 derive(Color.WHITE, 0.5), 463 derive(Color.BLACK, 0.5), 464 derive(Color.RED, 0.5), 465 derive(Color.GREEN, 0.5), 466 derive(Color.BLUE, 0.5), 467 }; 468 469 static Color OpaqueTestColors[] = { 470 Color.WHITE, 471 Color.BLACK, 472 Color.RED, 473 Color.GREEN, 474 Color.BLUE, 475 Color.CYAN, 476 Color.MAGENTA, 477 Color.YELLOW, 478 }; 479 480 static void checkArgb(int argb1, int argb2, double delta) { 481 assertEquals("alpha", (argb1 >> 24) & 0xff, (argb2 >> 24) & 0xff); 482 assertEquals("red", (argb1 >> 16) & 0xff, (argb2 >> 16) & 0xff, delta); 483 assertEquals("green", (argb1 >> 8) & 0xff, (argb2 >> 8) & 0xff, delta); 484 assertEquals("blue", (argb1 ) & 0xff, (argb2 ) & 0xff, delta); 485 } 486 487 void testget(ByteFormat bfmt, ByteBuffer bbuf, byte barr[], Color c) { 488 int refnon = getArgb(c); 489 int refpre = getArgbPre(c); 490 bfmt.setArgb(bbuf, 0, refnon); 491 bfmt.setArgb(barr, 0, refnon); 492 BytePixelGetter bpg = bfmt.getGetter(); 493 boolean premult = (bpg.getAlphaType() == AlphaType.PREMULTIPLIED); 494 double delta = 0.0; 495 if (bfmt.isGray()) { 496 refnon = grayify(refnon); 497 refpre = grayify(refpre); 498 delta += 1.0; 499 } 500 checkArgb(refnon, bpg.getArgb (bbuf, 0), delta + (premult ? 1.0 : 0.0)); 501 checkArgb(refpre, bpg.getArgbPre(bbuf, 0), delta + (premult ? 0.0 : 1.0)); 502 checkArgb(refnon, bpg.getArgb (barr, 0), delta + (premult ? 1.0 : 0.0)); 503 checkArgb(refpre, bpg.getArgbPre(barr, 0), delta + (premult ? 0.0 : 1.0)); 504 } 505 506 void testget(IntFormat ifmt, IntBuffer ibuf, int iarr[], Color c) { 507 int refnon = getArgb(c); 508 int refpre = getArgbPre(c); 509 ifmt.setArgb(ibuf, 0, refnon); 510 ifmt.setArgb(iarr, 0, refnon); 511 IntPixelGetter bpg = ifmt.getGetter(); 512 boolean premult = (bpg.getAlphaType() == AlphaType.PREMULTIPLIED); 513 checkArgb(refnon, bpg.getArgb (ibuf, 0), premult ? 1.0 : 0.0); 514 checkArgb(refpre, bpg.getArgbPre(ibuf, 0), premult ? 0.0 : 1.0); 515 checkArgb(refnon, bpg.getArgb (iarr, 0), premult ? 1.0 : 0.0); 516 checkArgb(refpre, bpg.getArgbPre(iarr, 0), premult ? 0.0 : 1.0); 517 } 518 519 void testset(ByteFormat bfmt, ByteBuffer bbuf, byte barr[], Color c) { 520 int refnon = getArgb(c); 521 int refpre = getArgbPre(c); 522 BytePixelSetter bps = bfmt.getSetter(); 523 bps.setArgb (bbuf, 0, refnon); 524 bps.setArgbPre(bbuf, 4, refpre); 525 bps.setArgb (barr, 0, refnon); 526 bps.setArgbPre(barr, 4, refpre); 527 boolean premult = (bps.getAlphaType() == AlphaType.PREMULTIPLIED); 528 double delta = 0.0; 529 if (bfmt.isGray()) { 530 refnon = grayify(refnon); 531 delta += 1.0; 532 } 533 checkArgb(refnon, bfmt.getArgb(bbuf, 0), delta + (premult ? 1.0 : 0.0)); 534 checkArgb(refnon, bfmt.getArgb(bbuf, 4), delta + (premult ? 1.0 : 1.0)); 535 checkArgb(refnon, bfmt.getArgb(barr, 0), delta + (premult ? 1.0 : 0.0)); 536 checkArgb(refnon, bfmt.getArgb(barr, 4), delta + (premult ? 1.0 : 1.0)); 537 } 538 539 void testset(IntFormat ifmt, IntBuffer ibuf, int iarr[], Color c) { 540 int refnon = getArgb(c); 541 int refpre = getArgbPre(c); 542 IntPixelSetter ips = ifmt.getSetter(); 543 ips.setArgb (ibuf, 0, refnon); 544 ips.setArgbPre(ibuf, 1, refpre); 545 ips.setArgb (iarr, 0, refnon); 546 ips.setArgbPre(iarr, 1, refpre); 547 boolean premult = (ips.getAlphaType() == AlphaType.PREMULTIPLIED); 548 double delta = 0.0; 549 checkArgb(refnon, ifmt.getArgb(ibuf, 0), delta + (premult ? 1.0 : 0.0)); 550 checkArgb(refnon, ifmt.getArgb(ibuf, 1), delta + (premult ? 1.0 : 1.0)); 551 checkArgb(refnon, ifmt.getArgb(iarr, 0), delta + (premult ? 1.0 : 0.0)); 552 checkArgb(refnon, ifmt.getArgb(iarr, 1), delta + (premult ? 1.0 : 1.0)); 553 } 554 555 @Test 556 public void testByteAccessors() { 557 testByteAccessors(heapByteBuffer(0, 8)); 558 testByteAccessors(heapByteBuffer(1, 8)); 559 testByteAccessors(directByteBuffer(0, 8)); 560 testByteAccessors(directByteBuffer(1, 8)); 561 } 562 563 private void testByteAccessors(ByteBuffer bbuf) { 564 byte barr[] = new byte[8]; 565 for (ByteFormat bfmt : ByteFormats) { 566 BytePixelGetter getter = bfmt.getGetter(); 567 BytePixelSetter setter = bfmt.getSetter(); 568 if (getter != null && setter != null) { 569 assertEquals(getter.getAlphaType(), setter.getAlphaType()); 570 } 571 Color testColors[] = (getter.getAlphaType() == AlphaType.OPAQUE 572 ? OpaqueTestColors : TestColors); 573 for (Color c : testColors) { 574 if (getter != null) { 575 testget(bfmt, bbuf, barr, c); 576 } 577 if (setter != null) { 578 testset(bfmt, bbuf, barr, c); 579 } 580 } 581 } 582 } 583 584 static final int FxColors[] = { 585 0x00000000, 586 0xffff0000, 587 0xff00ff00, 588 0xff0000ff, 589 0xffffffff 590 }; 591 592 static final PixelFormat FxFormats[] = { 593 PixelFormat.getByteBgraInstance(), 594 PixelFormat.getByteBgraPreInstance(), 595 PixelFormat.getByteRgbInstance(), 596 PixelFormat.getIntArgbInstance(), 597 PixelFormat.getIntArgbPreInstance(), 598 PixelFormat.createByteIndexedInstance(FxColors), 599 PixelFormat.createByteIndexedPremultipliedInstance(FxColors) 600 }; 601 602 static final WritablePixelFormat FxWritableFormats[] = { 603 WritablePixelFormat.getByteBgraInstance(), 604 WritablePixelFormat.getByteBgraPreInstance(), 605 WritablePixelFormat.getIntArgbInstance(), 606 WritablePixelFormat.getIntArgbPreInstance() 607 }; 608 609 static void checkAllTypesTested(PixelFormat<?> formats[], boolean writable) { 610 if (writable) { 611 for (PixelFormat<?> pf : formats) { 612 assertTrue(pf.isWritable()); 613 } 614 } 615 for (PixelFormat.Type type : PixelFormat.Type.values()) { 616 if (type == PixelFormat.Type.BYTE_INDEXED || 617 type == PixelFormat.Type.BYTE_RGB) 618 { 619 // Non-writable type 620 if (writable) continue; 621 } 622 boolean found = false; 623 for (PixelFormat<?> pf : formats) { 624 if (pf.getType() == type) { 625 found = true; 626 break; 627 } 628 } 629 assertTrue(found); 630 } 631 } 632 633 @Test 634 public void ensureFXConverters() { 635 checkAllTypesTested(FxFormats, false); 636 checkAllTypesTested(FxWritableFormats, true); 637 for (PixelFormat<?> pf : FxFormats) { 638 PixelGetter<?> getter = PixelUtils.getGetter(pf); 639 assertNotNull(getter); 640 for (WritablePixelFormat<?> wpf : FxWritableFormats) { 641 PixelSetter<?> setter = PixelUtils.getSetter(wpf); 642 assertNotNull(setter); 643 PixelConverter<?, ?> converter = PixelUtils.getConverter(getter, setter); 644 assertNotNull(converter); 645 } 646 } 647 } 648 649 @Test 650 public void ensureJ2DConverters() { 651 assertNotNull(PixelUtils.getConverter(ByteGray.getter, ByteGray.setter)); 652 assertNotNull(PixelUtils.getConverter(ByteBgr.getter, ByteBgr.setter)); 653 assertNotNull(PixelUtils.getConverter(IntArgbPre.getter, IntArgbPre.setter)); 654 assertNotNull(PixelUtils.getConverter(ByteBgraPre.getter, IntArgbPre.setter)); 655 } 656 657 @Test 658 public void testIntAccessors() { 659 testIntAccessors(heapIntBuffer(0, 2)); 660 testIntAccessors(heapIntBuffer(1, 2)); 661 testIntAccessors(directIntBuffer(0, 2)); 662 testIntAccessors(directIntBuffer(1, 2)); 663 } 664 665 private void testIntAccessors(IntBuffer ibuf) { 666 int iarr[] = new int[2]; 667 for (IntFormat ifmt : IntFormats) { 668 IntPixelGetter getter = ifmt.getGetter(); 669 IntPixelSetter setter = ifmt.getSetter(); 670 if (getter != null && setter != null) { 671 assertEquals(getter.getAlphaType(), setter.getAlphaType()); 672 } 673 Color testColors[] = (getter.getAlphaType() == AlphaType.OPAQUE 674 ? OpaqueTestColors : TestColors); 675 for (Color c : testColors) { 676 if (getter != null) { 677 testget(ifmt, ibuf, iarr, c); 678 } 679 if (setter != null) { 680 testset(ifmt, ibuf, iarr, c); 681 } 682 } 683 } 684 } 685 686 static boolean isGeneral(PixelConverter pc) { 687 Class enclosing = pc.getClass().getEnclosingClass(); 688 return (enclosing != null && 689 enclosing.getName().equals("com.sun.javafx.image.impl.General")); 690 } 691 692 static void clear(ByteBuffer hbuf, ByteBuffer dbuf, byte arr[]) { 693 assertEquals(hbuf.capacity(), dbuf.capacity()); 694 assertEquals(hbuf.capacity(), arr.length); 695 byte bv = (byte) (Math.random() * 255); 696 for (int i = 0; i < arr.length; i++) { 697 hbuf.put(i, (byte) bv); 698 dbuf.put(i, (byte) bv); 699 arr[i] = bv; 700 } 701 } 702 703 static void clear(IntBuffer hbuf, IntBuffer dbuf, int arr[]) { 704 assertEquals(hbuf.capacity(), dbuf.capacity()); 705 assertEquals(hbuf.capacity(), arr.length); 706 int iv = (int) (Math.random() * 0xffffffff); 707 for (int i = 0; i < arr.length; i++) { 708 hbuf.put(i, iv); 709 dbuf.put(i, iv); 710 arr[i] = iv; 711 } 712 } 713 714 @Test 715 public void testB2BConverterTypes() { 716 testB2BConverterTypes(0); 717 testB2BConverterTypes(1); 718 } 719 720 private void testB2BConverterTypes(int off) { 721 ByteBuffer srchbuf = heapByteBuffer(off, 4 * TestColors.length); 722 ByteBuffer srcdbuf = directByteBuffer(off, 4 * TestColors.length); 723 byte srcarr[] = new byte[4 * TestColors.length]; 724 ByteBuffer dsthbuf = heapByteBuffer(off, 4 * TestColors.length); 725 ByteBuffer dstdbuf = directByteBuffer(off, 4 * TestColors.length); 726 byte dstarr[] = new byte[4 * TestColors.length]; 727 for (ByteFormat bfmtgetter : ByteFormats) { 728 BytePixelGetter bpg = bfmtgetter.getGetter(); 729 for (ByteFormat bfmtsetter : ByteFormats) { 730 BytePixelSetter bps = bfmtsetter.getSetter(); 731 if (bps == null) continue; 732 ByteToBytePixelConverter b2bpc = 733 PixelUtils.getB2BConverter(bpg, bps); 734 if (bfmtsetter.getNcomp() < 4 && b2bpc == null) continue; 735 if (!isGeneral(b2bpc)) { 736 PixelConverter pc = PixelUtils.getConverter(bpg, bps); 737 assertEquals(b2bpc, pc); 738 } 739 assertEquals(b2bpc.getGetter(), bpg); 740 assertEquals(b2bpc.getSetter(), bps); 741 Color testColors[] = ((bpg.getAlphaType() == AlphaType.OPAQUE || 742 bps.getAlphaType() == AlphaType.OPAQUE) 743 ? OpaqueTestColors : TestColors); 744 int srcncomp = bfmtgetter.getNcomp(); 745 for (int i = 0; i < testColors.length; i++) { 746 bfmtgetter.setArgb(srchbuf, i * srcncomp, getArgb(testColors[i])); 747 bfmtgetter.setArgb(srcdbuf, i * srcncomp, getArgb(testColors[i])); 748 bfmtgetter.setArgb(srcarr, i * srcncomp, getArgb(testColors[i])); 749 } 750 int dstncomp = bfmtsetter.getNcomp(); 751 double delta = 0.0; 752 if (bpg.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 753 if (bps.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 754 boolean isgray = bfmtgetter.isGray() || bfmtsetter.isGray(); 755 if (isgray) { 756 delta += 1.0; 757 } 758 b2bpc.convert(srchbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 759 b2bpc.convert(srchbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 760 b2bpc.convert(srchbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 761 for (int i = 0; i < testColors.length; i++) { 762 int refargb = getArgb(testColors[i]); 763 if (isgray) refargb = grayify(refargb); 764 checkArgb(refargb, bfmtsetter.getArgb(dsthbuf, i * dstncomp), delta); 765 checkArgb(refargb, bfmtsetter.getArgb(dstdbuf, i * dstncomp), delta); 766 checkArgb(refargb, bfmtsetter.getArgb(dstarr, i * dstncomp), delta); 767 } 768 clear(dsthbuf, dstdbuf, dstarr); 769 b2bpc.convert(srcdbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 770 b2bpc.convert(srcdbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 771 b2bpc.convert(srcdbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 772 for (int i = 0; i < testColors.length; i++) { 773 int refargb = getArgb(testColors[i]); 774 if (isgray) refargb = grayify(refargb); 775 checkArgb(refargb, bfmtsetter.getArgb(dsthbuf, i * dstncomp), delta); 776 checkArgb(refargb, bfmtsetter.getArgb(dstdbuf, i * dstncomp), delta); 777 checkArgb(refargb, bfmtsetter.getArgb(dstarr, i * dstncomp), delta); 778 } 779 clear(dsthbuf, dstdbuf, dstarr); 780 b2bpc.convert(srcarr, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 781 b2bpc.convert(srcarr, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 782 b2bpc.convert(srcarr, 0, 0, dstarr, 0, 0, testColors.length, 1); 783 for (int i = 0; i < testColors.length; i++) { 784 int refargb = getArgb(testColors[i]); 785 if (isgray) refargb = grayify(refargb); 786 checkArgb(refargb, bfmtsetter.getArgb(dsthbuf, i * dstncomp), delta); 787 checkArgb(refargb, bfmtsetter.getArgb(dstdbuf, i * dstncomp), delta); 788 checkArgb(refargb, bfmtsetter.getArgb(dstarr, i * dstncomp), delta); 789 } 790 } 791 } 792 } 793 794 @Test 795 public void testB2IConverterTypes() { 796 testB2IConverterTypes(0); 797 testB2IConverterTypes(1); 798 } 799 800 private void testB2IConverterTypes(int off) { 801 ByteBuffer srchbuf = heapByteBuffer(off, 4 * TestColors.length); 802 ByteBuffer srcdbuf = directByteBuffer(off, 4 * TestColors.length); 803 byte srcarr[] = new byte[4 * TestColors.length]; 804 IntBuffer dsthbuf = heapIntBuffer(off, TestColors.length); 805 IntBuffer dstdbuf = directIntBuffer(off,TestColors.length); 806 int dstarr[] = new int[TestColors.length]; 807 for (ByteFormat bfmtgetter : ByteFormats) { 808 BytePixelGetter bpg = bfmtgetter.getGetter(); 809 for (IntFormat ifmtsetter : IntFormats) { 810 IntPixelSetter ips = ifmtsetter.getSetter(); 811 if (ips == null) continue; 812 ByteToIntPixelConverter b2ipc = 813 PixelUtils.getB2IConverter(bpg, ips); 814 // Should not be null - so far all int formats are full color+alpha 815 if (!isGeneral(b2ipc)) { 816 PixelConverter pc = PixelUtils.getConverter(bpg, ips); 817 assertEquals(b2ipc, pc); 818 } 819 assertEquals(b2ipc.getGetter(), bpg); 820 assertEquals(b2ipc.getSetter(), ips); 821 Color testColors[] = ((bpg.getAlphaType() == AlphaType.OPAQUE || 822 ips.getAlphaType() == AlphaType.OPAQUE) 823 ? OpaqueTestColors : TestColors); 824 int srcncomp = bfmtgetter.getNcomp(); 825 for (int i = 0; i < testColors.length; i++) { 826 bfmtgetter.setArgb(srchbuf, i * srcncomp, getArgb(testColors[i])); 827 bfmtgetter.setArgb(srcdbuf, i * srcncomp, getArgb(testColors[i])); 828 bfmtgetter.setArgb(srcarr, i * srcncomp, getArgb(testColors[i])); 829 } 830 double delta = 0.0; 831 if (bpg.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 832 if (ips.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 833 boolean isgray = bfmtgetter.isGray(); 834 if (isgray) { 835 delta += 1.0; 836 } 837 b2ipc.convert(srchbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 838 b2ipc.convert(srchbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 839 b2ipc.convert(srchbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 840 for (int i = 0; i < testColors.length; i++) { 841 int refargb = getArgb(testColors[i]); 842 if (isgray) refargb = grayify(refargb); 843 checkArgb(refargb, ifmtsetter.getArgb(dsthbuf, i), delta); 844 checkArgb(refargb, ifmtsetter.getArgb(dstdbuf, i), delta); 845 checkArgb(refargb, ifmtsetter.getArgb(dstarr, i), delta); 846 } 847 clear(dsthbuf, dstdbuf, dstarr); 848 b2ipc.convert(srcdbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 849 b2ipc.convert(srcdbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 850 b2ipc.convert(srcdbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 851 for (int i = 0; i < testColors.length; i++) { 852 int refargb = getArgb(testColors[i]); 853 if (isgray) refargb = grayify(refargb); 854 checkArgb(refargb, ifmtsetter.getArgb(dsthbuf, i), delta); 855 checkArgb(refargb, ifmtsetter.getArgb(dstdbuf, i), delta); 856 checkArgb(refargb, ifmtsetter.getArgb(dstarr, i), delta); 857 } 858 clear(dsthbuf, dstdbuf, dstarr); 859 b2ipc.convert(srcarr, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 860 b2ipc.convert(srcarr, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 861 b2ipc.convert(srcarr, 0, 0, dstarr, 0, 0, testColors.length, 1); 862 for (int i = 0; i < testColors.length; i++) { 863 int refargb = getArgb(testColors[i]); 864 if (isgray) refargb = grayify(refargb); 865 checkArgb(refargb, ifmtsetter.getArgb(dsthbuf, i), delta); 866 checkArgb(refargb, ifmtsetter.getArgb(dstdbuf, i), delta); 867 checkArgb(refargb, ifmtsetter.getArgb(dstarr, i), delta); 868 } 869 } 870 } 871 } 872 873 @Test 874 public void testI2BConverterTypes() { 875 testI2BConverterTypes(0); 876 testI2BConverterTypes(1); 877 } 878 879 private void testI2BConverterTypes(int off) { 880 IntBuffer srchbuf = heapIntBuffer(off, TestColors.length); 881 IntBuffer srcdbuf = directIntBuffer(off, TestColors.length); 882 int srcarr[] = new int[TestColors.length]; 883 ByteBuffer dsthbuf = heapByteBuffer(off, 4 * TestColors.length); 884 ByteBuffer dstdbuf = directByteBuffer(off, 4 * TestColors.length); 885 byte dstarr[] = new byte[4 * TestColors.length]; 886 for (IntFormat ifmtgetter : IntFormats) { 887 IntPixelGetter ipg = ifmtgetter.getGetter(); 888 for (ByteFormat bfmtsetter : ByteFormats) { 889 BytePixelSetter bps = bfmtsetter.getSetter(); 890 if (bps == null) continue; 891 IntToBytePixelConverter i2bpc = 892 PixelUtils.getI2BConverter(ipg, bps); 893 if (bfmtsetter.getNcomp() < 4 && i2bpc == null) continue; 894 if (!isGeneral(i2bpc)) { 895 PixelConverter pc = PixelUtils.getConverter(ipg, bps); 896 assertEquals(i2bpc, pc); 897 } 898 assertEquals(i2bpc.getGetter(), ipg); 899 assertEquals(i2bpc.getSetter(), bps); 900 Color testColors[] = ((ipg.getAlphaType() == AlphaType.OPAQUE || 901 bps.getAlphaType() == AlphaType.OPAQUE) 902 ? OpaqueTestColors : TestColors); 903 for (int i = 0; i < testColors.length; i++) { 904 ifmtgetter.setArgb(srchbuf, i, getArgb(testColors[i])); 905 ifmtgetter.setArgb(srcdbuf, i, getArgb(testColors[i])); 906 ifmtgetter.setArgb(srcarr, i, getArgb(testColors[i])); 907 } 908 int dstncomp = bfmtsetter.getNcomp(); 909 double delta = 0.0; 910 if (ipg.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 911 if (bps.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 912 boolean isgray = bfmtsetter.isGray(); 913 if (isgray) { 914 delta += 1.0; 915 } 916 i2bpc.convert(srchbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 917 i2bpc.convert(srchbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 918 i2bpc.convert(srchbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 919 for (int i = 0; i < testColors.length; i++) { 920 int refargb = getArgb(testColors[i]); 921 if (isgray) refargb = grayify(refargb); 922 checkArgb(refargb, bfmtsetter.getArgb(dsthbuf, i * dstncomp), delta); 923 checkArgb(refargb, bfmtsetter.getArgb(dstdbuf, i * dstncomp), delta); 924 checkArgb(refargb, bfmtsetter.getArgb(dstarr, i * dstncomp), delta); 925 } 926 clear(dsthbuf, dstdbuf, dstarr); 927 i2bpc.convert(srcdbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 928 i2bpc.convert(srcdbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 929 i2bpc.convert(srcdbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 930 for (int i = 0; i < testColors.length; i++) { 931 int refargb = getArgb(testColors[i]); 932 if (isgray) refargb = grayify(refargb); 933 checkArgb(refargb, bfmtsetter.getArgb(dsthbuf, i * dstncomp), delta); 934 checkArgb(refargb, bfmtsetter.getArgb(dstdbuf, i * dstncomp), delta); 935 checkArgb(refargb, bfmtsetter.getArgb(dstarr, i * dstncomp), delta); 936 } 937 clear(dsthbuf, dstdbuf, dstarr); 938 i2bpc.convert(srcarr, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 939 i2bpc.convert(srcarr, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 940 i2bpc.convert(srcarr, 0, 0, dstarr, 0, 0, testColors.length, 1); 941 for (int i = 0; i < testColors.length; i++) { 942 int refargb = getArgb(testColors[i]); 943 if (isgray) refargb = grayify(refargb); 944 checkArgb(refargb, bfmtsetter.getArgb(dsthbuf, i * dstncomp), delta); 945 checkArgb(refargb, bfmtsetter.getArgb(dstdbuf, i * dstncomp), delta); 946 checkArgb(refargb, bfmtsetter.getArgb(dstarr, i * dstncomp), delta); 947 } 948 } 949 } 950 } 951 952 @Test 953 public void testI2IConverterTypes() { 954 testI2IConverterTypes(0); 955 testI2IConverterTypes(1); 956 } 957 958 private void testI2IConverterTypes(int off) { 959 IntBuffer srchbuf = heapIntBuffer(off, TestColors.length); 960 IntBuffer srcdbuf = directIntBuffer(off, TestColors.length); 961 int srcarr[] = new int[TestColors.length]; 962 IntBuffer dsthbuf = heapIntBuffer(off, TestColors.length); 963 IntBuffer dstdbuf = directIntBuffer(off, TestColors.length); 964 int dstarr[] = new int[TestColors.length]; 965 for (IntFormat ifmtgetter : IntFormats) { 966 IntPixelGetter ipg = ifmtgetter.getGetter(); 967 for (IntFormat ifmtsetter : IntFormats) { 968 IntPixelSetter ips = ifmtsetter.getSetter(); 969 if (ips == null) continue; 970 IntToIntPixelConverter i2ipc = 971 PixelUtils.getI2IConverter(ipg, ips); 972 // Should not be null - so far all int formats are full color+alpha 973 if (!isGeneral(i2ipc)) { 974 PixelConverter pc = PixelUtils.getConverter(ipg, ips); 975 assertEquals(i2ipc, pc); 976 } 977 assertEquals(i2ipc.getGetter(), ipg); 978 assertEquals(i2ipc.getSetter(), ips); 979 Color testColors[] = ((ipg.getAlphaType() == AlphaType.OPAQUE || 980 ips.getAlphaType() == AlphaType.OPAQUE) 981 ? OpaqueTestColors : TestColors); 982 for (int i = 0; i < testColors.length; i++) { 983 ifmtgetter.setArgb(srchbuf, i, getArgb(testColors[i])); 984 ifmtgetter.setArgb(srcdbuf, i, getArgb(testColors[i])); 985 ifmtgetter.setArgb(srcarr, i, getArgb(testColors[i])); 986 } 987 double delta = 0.0; 988 if (ipg.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 989 if (ips.getAlphaType() == AlphaType.PREMULTIPLIED) delta += 1.0; 990 i2ipc.convert(srchbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 991 i2ipc.convert(srchbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 992 i2ipc.convert(srchbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 993 for (int i = 0; i < testColors.length; i++) { 994 int refargb = getArgb(testColors[i]); 995 checkArgb(refargb, ifmtsetter.getArgb(dsthbuf, i), delta); 996 checkArgb(refargb, ifmtsetter.getArgb(dstdbuf, i), delta); 997 checkArgb(refargb, ifmtsetter.getArgb(dstarr, i), delta); 998 } 999 clear(dsthbuf, dstdbuf, dstarr); 1000 i2ipc.convert(srcdbuf, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 1001 i2ipc.convert(srcdbuf, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 1002 i2ipc.convert(srcdbuf, 0, 0, dstarr, 0, 0, testColors.length, 1); 1003 for (int i = 0; i < testColors.length; i++) { 1004 int refargb = getArgb(testColors[i]); 1005 checkArgb(refargb, ifmtsetter.getArgb(dsthbuf, i), delta); 1006 checkArgb(refargb, ifmtsetter.getArgb(dstdbuf, i), delta); 1007 checkArgb(refargb, ifmtsetter.getArgb(dstarr, i), delta); 1008 } 1009 clear(dsthbuf, dstdbuf, dstarr); 1010 i2ipc.convert(srcarr, 0, 0, dsthbuf, 0, 0, testColors.length, 1); 1011 i2ipc.convert(srcarr, 0, 0, dstdbuf, 0, 0, testColors.length, 1); 1012 i2ipc.convert(srcarr, 0, 0, dstarr, 0, 0, testColors.length, 1); 1013 for (int i = 0; i < testColors.length; i++) { 1014 int refargb = getArgb(testColors[i]); 1015 checkArgb(refargb, ifmtsetter.getArgb(dsthbuf, i), delta); 1016 checkArgb(refargb, ifmtsetter.getArgb(dstdbuf, i), delta); 1017 checkArgb(refargb, ifmtsetter.getArgb(dstarr, i), delta); 1018 } 1019 } 1020 } 1021 } 1022 }