Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4192756

MemoryImageSource creates wrong shape in 16 bit color

XMLWordPrintable

    • 2d
    • kestrel
    • x86
    • windows_95



      Name: gsC80088 Date: 11/24/98


      I have a program that is supposed to use MemoryImageSource to draw random
      rectangles. It will compile OK on either jdk1.1.6 or jdk1.2 rc1, but, in
      either case, it renders incorrectly on jdk1.2 rc1. Instead, it just produces
      horizontal bands with the same width as the drawing area (rectangles yes,
      but not the right ones). Disabling the jit does not help. This program
      runs OK on jdk1.1.6 and a similar one ran OK on jdk1.2 beta4. If the program
      is modified to use the default color model, it runs OK, but too slow.
      The program code follows:

      /**
       * Test.java
       *
       * A program that uses MemoryImageSource to draw random rectangles.
       * This Program will compile either on jdk1.1.6 or jdk1.2 rc1.
       * In either case it will run correctly on jdk1.1.6, but not on
       * jdk1.2 rc1. In jdk1.2 rc1 it only produces horizontal bands
       * which all have the same width as the drawable window area.
       * Disabling the jit does not help.
       *
       * copyright 1998 Gregory P. Bauer
       */



      import java.awt.*;
      import java.awt.image.*;
      import java.awt.event.*;

      public class Test extends Frame implements Runnable {
      int width = 200;
      int height = 200;

      DirectColorModel dcm;
      int amask;
      int rmask;
      int gmask;
      int bmask;
      int rrot;
      int grot;
      int brot;

      int[] pixel;
      MemoryImageSource source;
      Image img;
      Thread renth = null;

      public Test() {
      setBackground(Color.black);

      /* WindowListener to exit when window is closed. */
      addWindowListener(
      new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
      stop();
      dispose();
      System.exit(0);
      }
      }
      );

      /* Get the system ColorModel. */
      ColorModel cm = getColorModel();

      /* If ColorModel is compatible with drawing routines
      use it. Otherwise create one that is compatible. */
      if ((cm instanceof DirectColorModel) && (cm.getPixelSize() <= 16)) {
      dcm = (DirectColorModel) cm;
      } else {
      dcm = new DirectColorModel(16, 0x1f, 0x7e0, 0xf800);
      }

      /* Fetch the component masks. */
      amask = dcm.getAlphaMask();
      rmask = dcm.getRedMask();
      gmask = dcm.getGreenMask();
      bmask = dcm.getBlueMask();

      /* Compute the shift values for the components by
      finding the highest order nonzero bit in each mask.
      The normalized components are 16-bit numbers so
      the test mask must use the 16th bit (0x8000). */
      rrot = 0;
      while ((rmask&(0x8000>>rrot)) == 0 && rrot < 16) {
      rrot++;
      }

      grot = 0;
      while ((gmask&(0x8000>>grot)) == 0 && grot < 16) {
      grot++;
      }

      brot = 0;
      while ((bmask&(0x8000>>brot)) == 0 && brot < 16) {
      brot++;
      }

      /* Initialize the buffer, MemoryImageSource, and Image. */
      pixel = new int[width * height];
      source = new MemoryImageSource(width, height, dcm, pixel, 0, width);
      source.setAnimated(true);
      img = createImage(source);

      /* Start the rendering thread. */
      renth = new Thread(this);
      renth.setPriority(Thread.MIN_PRIORITY);
      renth.start();
      }

      /* Method to stop the rendering thread. */
      public void stop() {
      renth = null;
      }

      /* This method generates and renders rectangles in batches
      of 1000 and then updates the screen. */
      public void run() {

      /* Run while current thread is valid. */
      while(Thread.currentThread() == renth) {
      int x, y, w, h;
      int r, g, b;

      /* Use render to draw a black rectangle covering
      the entire drawing area to clear it. */
      render(0, 0, width, height, 0, 0, 0);

      /* Generate 1000 rectangles. */
      for(int i = 0; i < 1000; i++) {

      /* Compute coordinates and colors for one rectangle. */
      x = (int) (((double) (width - 1)) * Math.random());
      y = (int) (((double) (height - 1)) * Math.random());
      w = (int) (((double) (width - 1)) * Math.random());
      h = (int) (((double) (height - 1)) * Math.random());
      r = (int) (65535d * Math.random());
      g = (int) (65535d * Math.random());
      b = (int) (65535d * Math.random());

      /* Render it. */
      render(x, y, w, h, r, g, b);
      }

      /* Update the screen and pause. */
      source.newPixels();
      try {
      Thread.sleep(10);
      } catch(InterruptedException e) {}
      }
      }

      /* This method draws a rectangle with the upper left corner
      at (x, y) and width w and height h and color (r, g, b). The
      color components are scaled from 0 to 65535. The coordinates
      are first validated because some of the values generated in
      the run method are invalid. Rectangles that are invalid or
      cannot be seen are discarded. */
      void render(int x, int y, int w, int h, int r, int g, int b) {

      /* Validate the coordinates. */
      if(x>width||y>height||x+w<0||y+h<0||w<0||h<0)
      return;

      /* Clip the rectangle to the drawing area. */
      if(x < 0) {
      w = x + w;
      x = 0;
      }
      if(y < 0) {
      h = y + h;
      y = 0;
      }
      if(x + w > width)
      w = width - x;
      if(y + h > height)
      h = height - y;

      /* Compute the initial offset into the buffer and the
      increment to get from one scanline to the next. */
      int k = y * width + x;
      int dw = width - w;

      /* For each scanline in the rectangle fill each pixel
      with the color given. The *rot values are used to
      place the leading bit in the correct place and the
      *mask values mask off the unused trailing bits. */
      for(int j = 0; j < h; j++) {
      for(int i = 0; i < w; i++) {
      pixel[k++] = amask|((r>>rrot)&rmask)|((g>>grot)&gmask)|((b>>brot)&bmask);
      }
      k += dw;
      }
      }

      public Dimension getPreferredSize() {
      return getMinimumSize();
      }

      public Dimension getMinimumSize() {
      return new Dimension(width, height);
      }

      public void update(Graphics g) {
      g.drawImage(img, 0, 0, this);
      }

      public void paint(Graphics g) {
      update(g);
      }

      public static void main(String[] args) {
      Test t = new Test();
      t.setTitle("Test");
      t.pack();
      t.setVisible(true);
      }
      }
      (Review ID: 41797)
      ======================================================================

            flar Jim Graham
            gstone Greg Stone
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: