package de.gaalop.visualizer.engines.lwjgl.recording; import java.awt.image.BufferedImage; import java.nio.ByteBuffer; import java.util.LinkedList; import org.lwjgl.opengl.Display; /** * Implements a thread that transforms a bytebuffer to an image. * After transforming, the storage process is started * @author Christian Steinmetz */ public class TransformationThread extends Thread { private final LinkedList<RecByteBufferAndTime> list = new LinkedList<RecByteBufferAndTime>(); private boolean terminate = false; private Recorder recorder; public TransformationThread(Recorder recorder) { this.recorder = recorder; } /** * Terminates the transformation. * This method does not stop the transformation of posted images */ public void terminate() { terminate = true; } /** * Adds a frame * @param buffer The ByteBuffer of the frame * @param delay The delay between the last frame and this frame in ms */ public void addFrame(ByteBuffer buffer, long delay) { RecByteBufferAndTime b = new RecByteBufferAndTime(buffer, delay); synchronized (list) { list.add(b); } } @Override public void run() { while (!terminate) { if (!list.isEmpty()) { RecByteBufferAndTime b = list.removeFirst(); BufferedImage image = transformPixelsRGBBuffer2ARGB_ByHand(b.getByteBuffer()); recorder._addFrame(image, b.getDelay()); } Thread.yield(); } recorder._finish(); } /** * Transforms an rgb pixel array to an argb BufferedImage * Code from pc * @param pixelsRGB The rgb pixel array * @return The created image */ private BufferedImage transformPixelsRGBBuffer2ARGB_ByHand( ByteBuffer pixelsRGB) { int width = Display.getDisplayMode().getWidth(); int height = Display.getDisplayMode().getHeight(); // Transform the ByteBuffer and get it as pixeldata. int[] pixelInts = new int[width * height]; // Convert RGB bytes to ARGB ints with no transparency. // Flip image vertically by reading the // rows of pixels in the byte buffer in reverse // - (0,0) is at bottom left in OpenGL. // // Points to first byte (red) in each row. int p = width * height * 3; int q; // Index into ByteBuffer int i = 0; // Index into target int[] int w3 = width * 3; // Number of bytes in each row for (int row = 0; row < height; row++) { p -= w3; q = p; for (int col = 0; col < width; col++) { int iR = pixelsRGB.get(q++); int iG = pixelsRGB.get(q++); int iB = pixelsRGB.get(q++); pixelInts[i++] = 0xFF000000 | ((iR & 0x000000FF) << 16) | ((iG & 0x000000FF) << 8) | (iB & 0x000000FF); } } // Create a new BufferedImage from the pixeldata. BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); bufferedImage.setRGB(0, 0, width, height, pixelInts, 0, width); return bufferedImage; } }