fast Grayscale->RGB

I am trying to display a 12-bit unsigned grayscale image as fast as I can and since I am new to the graphics end I would appreciate any help I can get.

Currently, I am doing this using:

    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsConfiguration gc = env.getScreenDevices()[0].getDefaultConfiguration();
    image = gc.createCompatibleImage(width, height);


    pixels = new short[height*width];
    dataBuffer = new DataBufferShort(pixels, pixels.length);

    sampleModel = RasterFactory.createBandedSampleModel(DataBuffer.TYPE_SHORT, width, height, 1);
    raster = RasterFactory.createWritableRaster(sampleModel, dataBuffer, null);

    cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);

    cm = new ComponentColorModel(cs, new int[]{16},
                                                         false, false,
                                                         Transparency.OPAQUE,
                                                         DataBuffer.TYPE_SHORT);

    bi = new BufferedImage(cm, raster, true, null);

    short[] newData = getImageData();
    System.arraycopy(newData, 0, pixels, 0, pixels.length);

    // draw image into buffer and refresh display
    Graphics2D g2 = (Graphics2D)image.getGraphics();
    g2.drawRenderedImage(bi, AffineTransform.getTranslateInstance(0, 0));
    paintImmediately(0, 0, width, height);

but it is very slow. I have timed this and most of the time is spent in the g2.drawRenderImage() call. I am assuming that this time is spent in the gray->rgb conversion, although it could be in the scaling of the data to fit on the monitor. I have looked at the image components and it is a DirectColorModel and the SampleModel is a SinglePixelPackedSampleModel.
I have also unsuccessfully tried to do the Grayscale->RGB conversion myself and put the converted data directly into the image.getData().getDataBuffer().getData() area. This didn’t seem to do anything. There must be a better way of doing this.

Instead of creating a custom bufferedImage, try using predefined TYPE_USHORT_GRAY image type:
bi = new BufferedImage(w,h,BufferedImage.TYPE_USHORT_GRAY);

We have some optimized loops written for this image type
(as well as for the most of the predefined image types).,
so copies to the screen or backbuffer should be reasonably fast.

Also, avoid using raster and databuffer operations, as they tend to be slow. Also, by holding to the DataBuffer you’re cutting yourself off any possibility of hardware acceleration we may have in the future: we can’t accelerate images for which you have direct pixel access.