/* * Copyright (c) 2009-2012 jMonkeyEngine * 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 'jMonkeyEngine' 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 com.jme3.texture.image; import com.jme3.texture.Image; import com.jme3.texture.Image.Format; import java.nio.ByteBuffer; import java.util.EnumMap; abstract class ImageCodec { public static final int FLAG_F16 = 1, FLAG_F32 = 2, FLAG_GRAY = 4; //, FLAG_ALPHAONLY = 8, FLAG_SHAREDEXP = 16; private static final EnumMap<Image.Format, ImageCodec> params = new EnumMap<Image.Format, ImageCodec>(Image.Format.class); protected final int bpp, type, maxAlpha, maxRed, maxGreen, maxBlue; protected final boolean isGray; public ImageCodec(int bpp, int flags, int maxAlpha, int maxRed, int maxGreen, int maxBlue) { this.bpp = bpp; this.isGray = (flags & FLAG_GRAY) != 0; this.type = flags & ~FLAG_GRAY; this.maxAlpha = maxAlpha; this.maxRed = maxRed; this.maxGreen = maxGreen; this.maxBlue = maxBlue; } static { // == ALPHA == // params.put(Format.Alpha8, new BitMaskImageCodec(1, 0, 8, 0, 0, 0, // 0, 0, 0, 0)); params.put(Format.Alpha8, new ByteOffsetImageCodec(1, 0, 0, -1, -1, -1)); // == LUMINANCE == // params.put(Format.Luminance8, new BitMaskImageCodec(1, FLAG_GRAY, 0, 8, 0, 0, // 0, 0, 0, 0)); params.put(Format.Luminance8, new ByteOffsetImageCodec(1, FLAG_GRAY, -1, 0, -1, -1)); params.put(Format.Luminance16F, new BitMaskImageCodec(2, FLAG_GRAY | FLAG_F16, 0, 16, 0, 0, 0, 0, 0, 0)); params.put(Format.Luminance32F, new BitMaskImageCodec(4, FLAG_GRAY | FLAG_F32, 0, 32, 0, 0, 0, 0, 0, 0)); // == INTENSITY == // ?? // == LUMINANCA ALPHA == // params.put(Format.Luminance8Alpha8, new BitMaskImageCodec(2, FLAG_GRAY, // 8, 8, 0, 0, // 8, 0, 0, 0)); params.put(Format.Luminance8Alpha8, new ByteOffsetImageCodec(2, FLAG_GRAY, 1, 0, -1, -1)); params.put(Format.Luminance16FAlpha16F, new BitMaskImageCodec(4, FLAG_GRAY | FLAG_F16, 16, 16, 0, 0, 16, 0, 0, 0)); // == RGB == // params.put(Format.BGR8, new BitMaskImageCodec(3, 0, // 0, 8, 8, 8, // 0, 16, 8, 0)); // params.put(Format.BGR8, new ByteOffsetImageCodec(3, 0, -1, 2, 1, 0)); params.put(Format.RGB565, new BitMaskImageCodec(2, 0, 0, 5, 6, 5, 0, 11, 5, 0)); // // params.put(Format.RGB8, new BitMaskImageCodec(3, 0, // 0, 8, 8, 8, // 0, 0, 8, 16)); params.put(Format.RGB8, new ByteOffsetImageCodec(3, 0, -1, 0, 1, 2)); params.put(Format.RGB32F, new ByteAlignedImageCodec(12, FLAG_F32, 0, 4, 4, 4, 0, 0, 4, 8)); ByteAlignedImageCodec rgb16f = new ByteAlignedImageCodec(6, FLAG_F16, 0, 2, 2, 2, 0, 0, 2, 4); params.put(Format.RGB16F, rgb16f); params.put(Format.RGB16F_to_RGB111110F, rgb16f); params.put(Format.RGB16F_to_RGB9E5, rgb16f); // == RGBA == // params.put(Format.ABGR8, new BitMaskImageCodec(4, 0, // 0, 8, 8, 8, // 0, 24, 16, 8)); params.put(Format.ABGR8, new ByteOffsetImageCodec(4, 0, 0, 3, 2, 1)); params.put(Format.ARGB8, new ByteOffsetImageCodec(4, 0, 0, 1, 2, 3)); params.put(Format.BGRA8, new ByteOffsetImageCodec(4, 0, 3, 2, 1, 0)); params.put(Format.RGB5A1, new BitMaskImageCodec(2, 0, 1, 5, 5, 5, 0, 11, 6, 1)); ((BitMaskImageCodec)params.get(Format.RGB5A1)).be = true; // params.put(Format.RGBA8, new ByteAlignedImageCodec(4, 0, // 0, 1, 1, 1, // 0, 0, 1, 2)); //new BitMaskImageCodec(4, 0, // 8, 8, 8, 8, // 24, 0, 8, 16)); params.put(Format.RGBA8, new ByteOffsetImageCodec(4, 0, 3, 0, 1, 2)); params.put(Format.RGBA16F, new ByteAlignedImageCodec(8, FLAG_F16, 2, 2, 2, 2, 6, 0, 2, 4)); params.put(Format.RGBA32F, new ByteAlignedImageCodec(16, FLAG_F32, 4, 4, 4, 4, 12, 0, 4, 8)); } public abstract void readComponents(ByteBuffer buf, int x, int y, int width, int offset, int[] components, byte[] tmp); public abstract void writeComponents(ByteBuffer buf, int x, int y, int width, int offset, int[] components, byte[] tmp); /** * Looks up the format in the codec registry. * The codec will be able to decode the given format. * * @param format The format to lookup. * @return The codec capable of decoding it, or null if not found. */ public static ImageCodec lookup(Format format) { ImageCodec codec = params.get(format); if (codec == null) { throw new UnsupportedOperationException("The format " + format + " is not supported"); } return codec; } }