/* * Copyright (c) 2009-2011, IETR/INSA of Rennes * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the IETR/INSA of Rennes nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ package net.sf.orcc.simulators.runtime.std.video.impl; import java.awt.Canvas; import java.awt.Graphics; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferStrategy; import java.awt.image.BufferedImage; import java.math.BigInteger; import javax.swing.JFrame; import net.sf.orcc.simulators.AbstractSimulator; import net.sf.orcc.util.OrccLogger; /** * This class defines native functions for the DisplayYUV actor. * * @author Matthieu Wipliez * */ public class DisplayYUVWithCrop { private static BufferStrategy buffer; private static Canvas canvas; /** * display is disabled. */ public static final int DISPLAY_DISABLE = 0; /** * display is enabled. */ public static final int DISPLAY_ENABLE = 2; /** * display is ready. */ public static final int DISPLAY_READY = 1; private static JFrame frame; private static BufferedImage image; private static int lastHeight; private static int lastWidth; private static long t1; private static long t2; private static int clip(int n) { if (n < 0) { return 0; } else if (n > 255) { return 255; } else { return n; } } /** * Compares the contents in the given buffers with a golden reference. * * @param pictureBufferY * Y buffer * @param pictureBufferU * U buffer * @param pictureBufferV * V buffer * @param pictureWidth * width * @param pictureHeight * height */ public static void compareYUV_comparePicture(byte[] pictureBufferY, byte[] pictureBufferU, byte[] pictureBufferV, BigInteger pictureWidth, BigInteger pictureHeight) { } /** * Init the YUV comparison. */ public static void compareYUV_init() { } private static int convertYCbCrtoRGB(int y, int cb, int cr) { int C = y - 16; int D = cb - 128; int E = cr - 128; int r = clip((298 * C + 409 * E + 128) >> 8); int g = clip((298 * C - 100 * D - 208 * E + 128) >> 8); int b = clip((298 * C + 516 * D + 128) >> 8); return (r << 16) | (g << 8) | b; } public static void displayYUV_displayPicture(byte[] pictureBufferY, byte[] pictureBufferU, byte[] pictureBufferV, BigInteger biPictureWidth, BigInteger biPictureHeight) { int pictureWidth = biPictureWidth.intValue(); int pictureHeight = biPictureHeight.intValue(); if (pictureWidth != lastWidth || pictureHeight != lastHeight) { setVideoSize(pictureWidth, pictureHeight); } if (image == null) { return; } for (int i = 0; i < pictureWidth / 2; i++) { for (int j = 0; j < pictureHeight / 2; j++) { int u = pictureBufferU[i + j * pictureWidth / 2] & 0xFF; int v = pictureBufferV[i + j * pictureWidth / 2] & 0xFF; int y0 = pictureBufferY[i * 2 + j * 2 * pictureWidth] & 0xFF; int y1 = pictureBufferY[i * 2 + 1 + j * 2 * pictureWidth] & 0xFF; int y2 = pictureBufferY[i * 2 + (j * 2 + 1) * pictureWidth] & 0xFF; int y3 = pictureBufferY[i * 2 + 1 + (j * 2 + 1) * pictureWidth] & 0xFF; int rgb0 = convertYCbCrtoRGB(y0, u, v); int rgb1 = convertYCbCrtoRGB(y1, u, v); int rgb2 = convertYCbCrtoRGB(y2, u, v); int rgb3 = convertYCbCrtoRGB(y3, u, v); image.setRGB(i * 2, j * 2, rgb0); image.setRGB(i * 2 + 1, j * 2, rgb1); image.setRGB(i * 2, j * 2 + 1, rgb2); image.setRGB(i * 2 + 1, j * 2 + 1, rgb3); } } if (buffer != null) { Graphics graphics = buffer.getDrawGraphics(); graphics.drawImage(image, 0, 0, null); buffer.show(); graphics.dispose(); } } /** * Returns the flags of the display. This implementation returns a display * always enabled and ready. * * @return the flags of the display */ public static BigInteger displayYUV_getFlags() { return BigInteger.valueOf(DISPLAY_ENABLE | DISPLAY_READY); } /** * Initializes the display. */ public static void displayYUV_init() { frame = new JFrame("display"); frame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { if (buffer != null) { buffer.dispose(); } canvas = null; image = null; lastHeight = 0; lastWidth = 0; AbstractSimulator.stop(BigInteger.ZERO); } }); canvas = new Canvas(); frame.add(canvas); frame.setVisible(true); } private static void setVideoSize(int newWidth, int newHeight) { lastWidth = newWidth; lastHeight = newHeight; if (canvas != null) { canvas.setSize(lastWidth, lastHeight); frame.pack(); canvas.createBufferStrategy(2); buffer = canvas.getBufferStrategy(); image = new BufferedImage(lastWidth, lastHeight, BufferedImage.TYPE_INT_RGB); } } public static void fpsPrintInit() { t1 = System.currentTimeMillis(); } public static void fpsPrintNewPicDecoded() { t2 = System.currentTimeMillis(); OrccLogger.noticeRaw("Image displayed in " + (t2 - t1) + " ms\n"); t1 = t2; } }