/* * 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 java.nio.ByteBuffer; class BitMaskImageCodec extends ImageCodec { // Shifts final int as, rs, gs, bs; boolean be = false; public BitMaskImageCodec(int bpp, int flags, int ac, int rc, int gc, int bc, int as, int rs, int gs, int bs) { super(bpp, flags, (int) (((long) 1 << ac) - 1), (int) (((long) 1 << rc) - 1), (int) (((long) 1 << gc) - 1), (int) (((long) 1 << bc) - 1)); if (bpp > 4) { throw new UnsupportedOperationException("Use ByteAlignedImageCodec for codecs with pixel sizes larger than 4 bytes"); } this.as = as; this.rs = rs; this.gs = gs; this.bs = bs; } private static int readPixelRaw(ByteBuffer buf, int idx, int bpp) { //idx += bpp; //int original = buf.get(--idx) & 0xff; //while ((--bpp) > 0) { // original = (original << 8) | (buf.get(--idx) & 0xff); //} //return original; //return buf.getInt(idx) & (0xFFFFFFFF >>> (32 - bpp)); int pixel = 0; buf.position(idx); for (int i = 0; i < bpp; i++) { pixel = pixel | (buf.get() & 0xff) << (i * 8); } return pixel; } private void writePixelRaw(ByteBuffer buf, int idx, int pixel, int bpp){ // buf.position(idx); // if (!be){ // This works: // while ((--bpp) >= 0){ // byte bt = (byte) ((pixel >> (bpp * 8)) & 0xff); // buf.put(idx + bpp, bt); // } // == // } else { // for (int i = bpp - 1; i >= 0; i--) { // byte bt = (byte) ((pixel >> (i * 8)) & 0xff); // buf.put(idx + i, bt); // } // } buf.position(idx); for (int i = 0; i < bpp; i++) { buf.put( (byte)((pixel >> (8 * i)) & 0xff) ); } } @Override public void readComponents(ByteBuffer buf, int x, int y, int width, int offset, int[] components, byte[] tmp) { int inputPixel = readPixelRaw(buf, (x + y * width) * bpp + offset, bpp); components[0] = (inputPixel >> as) & maxAlpha; components[1] = (inputPixel >> rs) & maxRed; components[2] = (inputPixel >> gs) & maxGreen; components[3] = (inputPixel >> bs) & maxBlue; } public void writeComponents(ByteBuffer buf, int x, int y, int width, int offset, int[] components, byte[] tmp) { // Shift components then mask them // Map all components into a single bitspace int outputPixel = ((components[0] & maxAlpha) << as) | ((components[1] & maxRed) << rs) | ((components[2] & maxGreen) << gs) | ((components[3] & maxBlue) << bs); // Find index in image where to write pixel. // Write the resultant bitspace into the pixel. writePixelRaw(buf, (x + y * width) * bpp + offset, outputPixel, bpp); } }