/* * @(#)GDIRenderer.java 1.28 03/04/23 * * Copyright (c) 1996-2002 Sun Microsystems, Inc. All rights reserved. */ package com.sun.media.renderer.video; import javax.media.*; import javax.media.Format; import javax.media.format.*; import javax.media.renderer.VideoRenderer; import java.awt.*; import java.util.Vector; import com.sun.media.*; public class GDIRenderer extends BasicVideoRenderer { private static boolean available = false; static { try { JMFSecurityManager.loadLibrary("jmgdi"); available = true; } catch (Exception e) { } catch (UnsatisfiedLinkError ule) { } } private int blitter = 0; protected Object data = null; //private int blitterAvailable = 0; private int defbitsPerPixel; private int defrMask; private int defgMask; private int defbMask; private int offsetX = 0; private int offsetY = 0; private int bytesPerPixel = 4; private int bitsPerPixel; private int rMask; private int gMask; private int bMask; private int pixelStride; private int lineStride; private boolean flipped; private int handle = 0; private synchronized native boolean gdiInitialize(); private synchronized native boolean gdiSetComponent(int windowHandle); private synchronized native boolean gdiSetOutputSize(int width, int height); private synchronized native boolean gdiDraw(Object data, long dataBytes, int elSize, // 1 for byte[], 2 for short[] // 4 for int[] int bytesPerPixel, int srcWidth, int srcHeight, int srcStride, int dstWidth, int dstHeight, int rm, int gm, int bm, boolean flipped, int windowHandle); private synchronized native boolean gdiFree(); protected VideoFormat defaultFormat; public GDIRenderer() { super("Windows GDI Renderer"); if (available) { if (gdiInitialize()) { Class arrayType; if (defbitsPerPixel <= 8) arrayType = Format.byteArray; else if (defbitsPerPixel <= 16) arrayType = Format.shortArray; else if (defbitsPerPixel <= 24) arrayType = Format.byteArray; else arrayType = Format.intArray; defaultFormat = new RGBFormat(null, Format.NOT_SPECIFIED, arrayType, Format.NOT_SPECIFIED, // frame rate defbitsPerPixel, defrMask, defgMask, defbMask, (defbitsPerPixel == 24)? 3:1, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED); supportedFormats = new VideoFormat[8]; supportedFormats[0] = defaultFormat; // The remaining are general formats supported by GDI // 15 bit supportedFormats[1] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.shortArray, Format.NOT_SPECIFIED, // frame rate 16, 0x7C00, 0x03E0, 0x001F, 1, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED); // 15 bit supportedFormats[2] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, // frame rate 16, 0x7C00, 0x03E0, 0x001F, 2, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, RGBFormat.LITTLE_ENDIAN); // 16 bit supportedFormats[3] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.shortArray, Format.NOT_SPECIFIED, // frame rate 16, 0xF800, 0x07E0, 0x001F, 1, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED); // 16 bit supportedFormats[4] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, // frame rate 16, 0xF800, 0x07E0, 0x001F, 2, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, RGBFormat.LITTLE_ENDIAN); // 24 bit supportedFormats[5] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, // frame rate 24, 3, 2, 1, 3, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED); // 32 bit xRGB supportedFormats[6] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.intArray, Format.NOT_SPECIFIED, // frame rate 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 1, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED); // 32 bit xRGB supportedFormats[7] = new RGBFormat(null, Format.NOT_SPECIFIED, Format.byteArray, Format.NOT_SPECIFIED, // frame rate 32, 3, 2, 1, 4, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED, Format.NOT_SPECIFIED); } else { System.err.println("GDIRenderer. gdiInitialize() failed"); available = false; } } } public void open() throws ResourceUnavailableException { if (!available) throw new ResourceUnavailableException("GDI not available !!!"); handle = 0; if (blitter == 0) gdiInitialize(); if (blitter == 0) throw new ResourceUnavailableException("GDIRenderer couldn't open"); } public synchronized void reset() { handle = 0; } public void close() { if (available) gdiFree(); } /** * Set the data input format. * @return false if the format is not supported. */ public Format setInputFormat(Format format) { if (!available) return null; if (super.setInputFormat(format) != null) { if (inputFormat instanceof RGBFormat) { RGBFormat rgbf = (RGBFormat) inputFormat; bitsPerPixel = rgbf.getBitsPerPixel(); rMask = rgbf.getRedMask(); gMask = rgbf.getGreenMask(); bMask = rgbf.getBlueMask(); lineStride = rgbf.getLineStride(); pixelStride = rgbf.getPixelStride(); flipped = (rgbf.getFlipped() == Format.TRUE); if (inputFormat.getDataType() == Format.byteArray && bitsPerPixel > 16) { int bypp = bitsPerPixel / 8; rMask = 0xFF << ((rMask - 1) * 8); gMask = 0xFF << ((gMask - 1) * 8); bMask = 0xFF << ((bMask - 1) * 8); } } else if (inputFormat instanceof IndexedColorFormat) { bitsPerPixel = 8; lineStride = ((IndexedColorFormat)format).getLineStride(); } else return null; // Inform the native code of the input format change if (outWidth == -1 || outHeight == -1) { outWidth = inWidth; outHeight = inHeight; } if (component != null) component.setSize(outWidth, outHeight); // All's well return format; } else { // Unsupported format return null; } } protected int doProcess(Buffer buffer) { return doProcess(buffer, false); } protected synchronized int doProcess(Buffer buffer, boolean repainting) { if (!available || component == null) return BUFFER_PROCESSED_OK; if (handle == 0) handle = com.sun.media.util.WindowUtil.getWindowHandle(component); if (handle == 0) return BUFFER_PROCESSED_OK; if (!repainting) { if (!buffer.getFormat().equals(inputFormat)) { if (setInputFormat(buffer.getFormat()) == null) return BUFFER_PROCESSED_FAILED; } } if (!repainting) data = getInputData(buffer); int elSize = 1; if (data instanceof short[]) elSize = 2; else if (data instanceof int[]) elSize = 4; bytesPerPixel = bitsPerPixel / 8; long dataBytes = 0; if (data instanceof NBA) { dataBytes = ((NBA)data).getNativeData(); } if (data == null) return BUFFER_PROCESSED_OK; if (outWidth > 0 && outHeight > 0) { int returned = (gdiDraw(data, dataBytes, elSize, bytesPerPixel, inWidth, inHeight, lineStride / pixelStride, outWidth, outHeight, rMask, gMask, bMask, flipped, handle))? BUFFER_PROCESSED_OK : BUFFER_PROCESSED_FAILED; return returned; } else return BUFFER_PROCESSED_OK; } protected synchronized void repaint() { if (!isStarted() && data != null) doProcess(null, true); } protected synchronized void setAvailable(boolean available) { super.setAvailable(available); handle = 0; } }