Package com.ardor3d.image.util.jogl

Source Code of com.ardor3d.image.util.jogl.JoglImageLoader

/**
* Copyright (c) 2008-2010 Ardor Labs, Inc.
*
* This file is part of Ardor3D.
*
* Ardor3D is free software: you can redistribute it and/or modify it
* under the terms of its license which may be found in the accompanying
* LICENSE file or at <http://www.ardor3d.com/LICENSE>.
*/

package com.ardor3d.image.util.jogl;

import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;

import com.ardor3d.framework.jogl.CapsUtil;
import com.ardor3d.image.Image;
import com.ardor3d.image.PixelDataType;
import com.ardor3d.image.util.ImageLoader;
import com.ardor3d.image.util.ImageLoaderUtil;
import com.ardor3d.scene.state.jogl.util.JoglTextureUtil;
import com.ardor3d.util.geom.BufferUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;

public class JoglImageLoader implements ImageLoader {

    public static boolean createOnHeap = false;

    protected CapsUtil _capsUtil;

    private enum TYPE {
        BYTE(ByteBuffer.class), SHORT(ShortBuffer.class), CHAR(CharBuffer.class), INT(IntBuffer.class), FLOAT(
                FloatBuffer.class), LONG(LongBuffer.class), DOUBLE(DoubleBuffer.class);

        private final Class<? extends Buffer> bufferClass;

        private TYPE(final Class<? extends Buffer> bufferClass) {
            this.bufferClass = bufferClass;
        }
    };

    private static final String[] supportedFormats = new String[] { "." + TextureIO.DDS.toUpperCase(),
            "." + TextureIO.GIF.toUpperCase(), "." + TextureIO.JPG.toUpperCase(), "." + TextureIO.PAM.toUpperCase(),
            "." + TextureIO.PNG.toUpperCase(), "." + TextureIO.PPM.toUpperCase(), "." + TextureIO.SGI.toUpperCase(),
            "." + TextureIO.TGA.toUpperCase(), "." + TextureIO.TIFF.toUpperCase() };

    public static String[] getSupportedFormats() {
        return supportedFormats;
    }

    public static void registerLoader() {
        ImageLoaderUtil.registerHandler(new JoglImageLoader(), supportedFormats);
    }

    public JoglImageLoader() {
        _capsUtil = new CapsUtil();
    }

    @Override
    public Image load(final InputStream is, final boolean flipped) throws IOException {
        final TextureData textureData = TextureIO.newTextureData(_capsUtil.getProfile(), is, true, null);
        final Buffer textureDataBuffer = textureData.getBuffer();
        final Image ardorImage = new Image();
        final TYPE bufferDataType = getBufferDataType(textureDataBuffer);
        if (bufferDataType == null) {
            throw new UnsupportedOperationException("Unknown buffer type " + textureDataBuffer.getClass().getName());
        } else {
            final int dataSizeInBytes = textureDataBuffer.capacity() * Buffers.sizeOfBufferElem(textureDataBuffer);
            final ByteBuffer scratch = createOnHeap ? BufferUtils.createByteBufferOnHeap(dataSizeInBytes) : Buffers
                    .newDirectByteBuffer(dataSizeInBytes);
            if (flipped) {
                flipImageData(textureDataBuffer, scratch, dataSizeInBytes, bufferDataType, textureData.getWidth(),
                        textureData.getHeight());
            } else {
                copyImageData(textureDataBuffer, scratch, bufferDataType);
            }
            ardorImage.setWidth(textureData.getWidth());
            ardorImage.setHeight(textureData.getHeight());
            ardorImage.setData(scratch);
            ardorImage.setDataFormat(JoglTextureUtil.getImageDataFormat(textureData.getPixelFormat()));
            // ardorImage.setDataType(JoglTextureUtil.getPixelDataType(textureData.getPixelType()));
            ardorImage.setDataType(PixelDataType.UnsignedByte);
            return ardorImage;
        }
    }

    private TYPE getBufferDataType(final Buffer buffer) {
        TYPE bufferDataType = null;
        for (final TYPE type : TYPE.values()) {
            if (type.bufferClass.isAssignableFrom(buffer.getClass())) {
                bufferDataType = type;
                break;
            }
        }
        return bufferDataType;
    }

    protected void copyImageData(final Buffer src, final ByteBuffer dest, final TYPE bufferDataType) {
        final int srcPos = src.position();
        final int destPos = dest.position();
        switch (bufferDataType) {
            case BYTE:
                dest.put((ByteBuffer) src);
                break;
            case SHORT:
                dest.asShortBuffer().put((ShortBuffer) src);
                break;
            case CHAR:
                dest.asCharBuffer().put((CharBuffer) src);
                break;
            case INT:
                dest.asIntBuffer().put((IntBuffer) src);
                break;
            case FLOAT:
                dest.asFloatBuffer().put((FloatBuffer) src);
            case LONG:
                dest.asLongBuffer().put((LongBuffer) src);
                break;
            case DOUBLE:
                dest.asDoubleBuffer().put((DoubleBuffer) src);
                break;
            default:
                // it should never happen
        }
        src.position(srcPos);
        dest.position(destPos);
    }

    protected void flipImageData(final Buffer src, final ByteBuffer dest, final int dataSizeInBytes,
            final TYPE bufferDataType, final int width, final int height) {
        final int srcPos = src.position();
        final int destPos = dest.position();
        final int bytesPerPixel = dataSizeInBytes / (width * height);
        final int bytesPerElement = Buffers.sizeOfBufferElem(src);
        final int elementsPerPixel = bytesPerPixel / bytesPerElement;
        final int elementsPerLine = width * elementsPerPixel;
        final int bytesPerLine = bytesPerPixel * width;// width = pixels per line
        byte[] byteBuf = null;
        short[] shortBuf = null;
        char[] charBuf = null;
        int[] intBuf = null;
        float[] floatBuf = null;
        long[] longBuf = null;
        double[] doubleBuf = null;
        switch (bufferDataType) {
            case BYTE:
                byteBuf = new byte[elementsPerLine];
                break;
            case SHORT:
                shortBuf = new short[elementsPerLine];
                break;
            case CHAR:
                charBuf = new char[elementsPerLine];
                break;
            case INT:
                intBuf = new int[elementsPerLine];
                break;
            case FLOAT:
                floatBuf = new float[elementsPerLine];
                break;
            case LONG:
                longBuf = new long[elementsPerLine];
                break;
            case DOUBLE:
                doubleBuf = new double[elementsPerLine];
                break;
            default:
                // it should never happen
        }
        while (dest.hasRemaining()) {
            final int srcFirstPixelIndex = dest.position() / bytesPerPixel;
            final int srcFirstPixelComponentOffset = dest.position() - (srcFirstPixelIndex * bytesPerPixel);
            final int srcFirstColumnIndex = srcFirstPixelIndex % width;
            final int scrFirstRowIndex = (srcFirstPixelIndex - srcFirstColumnIndex) / height;
            final int dstFirstColumnIndex = srcFirstColumnIndex;
            final int dstFirstRowIndex = (height - 1) - scrFirstRowIndex;
            final int dstFirstPixelIndex = dstFirstRowIndex * width + dstFirstColumnIndex;
            final int dstFirstPixelComponentOffset = srcFirstPixelComponentOffset;
            final int dstFirstElementIndex = dstFirstPixelIndex * bytesPerPixel + dstFirstPixelComponentOffset;
            switch (bufferDataType) {
                case BYTE:
                    ((ByteBuffer) src).position(dstFirstElementIndex);
                    ((ByteBuffer) src).get(byteBuf);
                    dest.put(byteBuf);
                    break;
                case SHORT:
                    ((ShortBuffer) src).position(dstFirstElementIndex);
                    ((ShortBuffer) src).get(shortBuf);
                    dest.asShortBuffer().put(shortBuf);
                    dest.position(dest.position() + bytesPerLine);
                    break;
                case CHAR:
                    ((CharBuffer) src).position(dstFirstElementIndex);
                    ((CharBuffer) src).get(charBuf);
                    dest.asCharBuffer().put(charBuf);
                    dest.position(dest.position() + bytesPerLine);
                    break;
                case INT:
                    ((IntBuffer) src).position(dstFirstElementIndex);
                    ((IntBuffer) src).get(intBuf);
                    dest.asIntBuffer().put(intBuf);
                    dest.position(dest.position() + bytesPerLine);
                    break;
                case FLOAT:
                    ((FloatBuffer) src).position(dstFirstElementIndex);
                    ((FloatBuffer) src).get(floatBuf);
                    dest.asFloatBuffer().put(floatBuf);
                    dest.position(dest.position() + bytesPerLine);
                    break;
                case LONG:
                    ((LongBuffer) src).position(dstFirstElementIndex);
                    ((LongBuffer) src).get(longBuf);
                    dest.asLongBuffer().put(longBuf);
                    dest.position(dest.position() + bytesPerLine);
                    break;
                case DOUBLE:
                    ((DoubleBuffer) src).position(dstFirstElementIndex);
                    ((DoubleBuffer) src).get(doubleBuf);
                    dest.asDoubleBuffer().put(doubleBuf);
                    dest.position(dest.position() + bytesPerLine);
                    break;
                default:
                    // it should never happen
            }
        }
        src.position(srcPos);
        dest.position(destPos);
    }
}
TOP

Related Classes of com.ardor3d.image.util.jogl.JoglImageLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.