Skip to content

Commit

Permalink
Refactor for ImageRaster classes
Browse files Browse the repository at this point in the history
Refactored DefaultImageRaster and MipMapImageRaster, common code moved to superclass ImageRaster
  • Loading branch information
kristinfjola authored and JoopAue committed Mar 24, 2016
1 parent cfcf6a1 commit dd7b7e6
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 204 deletions.
104 changes: 12 additions & 92 deletions jme3-core/src/main/java/com/jme3/texture/image/DefaultImageRaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,14 @@
import java.nio.ByteBuffer;

public class DefaultImageRaster extends ImageRaster {

private final int[] components = new int[4];

@VisibleForTesting
protected final int[] components = new int[4];
private ByteBuffer buffer;
private final Image image;
private final ImageCodec codec;
@VisibleForTesting
protected final Image image;
@VisibleForTesting
protected final ImageCodec codec;
private final int width;
private final int height;
private final int offset;
Expand Down Expand Up @@ -120,10 +123,10 @@ public int getHeight() {
public void setPixel(int x, int y, ColorRGBA color) {
rangeCheck(x, y);
getSRGB(color);
grayscaleCheck(color);
setComponents(color);
grayscaleCheck(color, codec);
setComponents(color, codec, components);
writeComponents(x, y);
image.setUpdateNeeded();
setImageUpdateNeeded(image);
}

/**
Expand All @@ -137,43 +140,6 @@ protected void getSRGB(ColorRGBA color) {
}
}

/**
* Check flags for grayscale
* @param color
*/
@VisibleForTesting
protected void grayscaleCheck(ColorRGBA color) {
if (codec.isGray) {
float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
color = new ColorRGBA(gray, gray, gray, color.a);
}
}

@VisibleForTesting
protected void setComponents(ColorRGBA color) {
switch (codec.type) {
case ImageCodec.FLAG_F16:
components[0] = (int) FastMath.convertFloatToHalf(color.a);
components[1] = (int) FastMath.convertFloatToHalf(color.r);
components[2] = (int) FastMath.convertFloatToHalf(color.g);
components[3] = (int) FastMath.convertFloatToHalf(color.b);
break;
case ImageCodec.FLAG_F32:
components[0] = (int) Float.floatToIntBits(color.a);
components[1] = (int) Float.floatToIntBits(color.r);
components[2] = (int) Float.floatToIntBits(color.g);
components[3] = (int) Float.floatToIntBits(color.b);
break;
case 0:
// Convert color to bits by multiplying by size
components[0] = Math.min( (int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
components[1] = Math.min( (int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
components[2] = Math.min( (int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
components[3] = Math.min( (int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
break;
}
}

@VisibleForTesting
protected void writeComponents(int x, int y) {
codec.writeComponents(getBuffer(), x, y, width, offset, components, temp);
Expand All @@ -198,59 +164,13 @@ public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
if (store == null) {
store = new ColorRGBA();
}
setStoreComponents(store);
setStoreRGBA(store);
setStoreComponents(store, codec, components);
setStoreRGBA(store, codec);
setSRGB(store);

return store;
}


@VisibleForTesting
protected void setStoreComponents(ColorRGBA store) {
switch (codec.type) {
case ImageCodec.FLAG_F16:
store.set(FastMath.convertHalfToFloat((short)components[1]),
FastMath.convertHalfToFloat((short)components[2]),
FastMath.convertHalfToFloat((short)components[3]),
FastMath.convertHalfToFloat((short)components[0]));
break;
case ImageCodec.FLAG_F32:
store.set(Float.intBitsToFloat((int)components[1]),
Float.intBitsToFloat((int)components[2]),
Float.intBitsToFloat((int)components[3]),
Float.intBitsToFloat((int)components[0]));
break;
case 0:
// Convert to float and divide by bitsize to get into range 0.0 - 1.0.
store.set((float)components[1] / codec.maxRed,
(float)components[2] / codec.maxGreen,
(float)components[3] / codec.maxBlue,
(float)components[0] / codec.maxAlpha);
break;
}
}

@VisibleForTesting
protected void setStoreRGBA(ColorRGBA store) {
if (codec.isGray) {
store.g = store.b = store.r;
} else {
if (codec.maxRed == 0) {
store.r = 1;
}
if (codec.maxGreen == 0) {
store.g = 1;
}
if (codec.maxBlue == 0) {
store.b = 1;
}
if (codec.maxAlpha == 0) {
store.a = 1;
}
}
}

@VisibleForTesting
protected void setSRGB(ColorRGBA store) {
if (convertToLinear) {
Expand Down
91 changes: 91 additions & 0 deletions jme3-core/src/main/java/com/jme3/texture/image/ImageRaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@
package com.jme3.texture.image;

import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.system.JmeSystem;
import com.jme3.texture.Image;
import org.fest.util.VisibleForTesting;

/**
* Utility class for reading and writing from jME3 {@link Image images}.
Expand Down Expand Up @@ -65,6 +67,8 @@
*/
public abstract class ImageRaster {



/**
* Create new image reader / writer.
*
Expand Down Expand Up @@ -201,4 +205,91 @@ public ImageRaster() {
public ColorRGBA getPixel(int x, int y) {
return getPixel(x, y, null);
}

/**
* Check flags for grayscale
* @param color
*/
@VisibleForTesting
protected void grayscaleCheck(ColorRGBA color, ImageCodec codec) {
if (codec.isGray) {
float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
color = new ColorRGBA(gray, gray, gray, color.a);
}
}

@VisibleForTesting
protected void setComponents(ColorRGBA color, ImageCodec codec, int[] components) {
switch (codec.type) {
case ImageCodec.FLAG_F16:
components[0] = (int) FastMath.convertFloatToHalf(color.a);
components[1] = (int) FastMath.convertFloatToHalf(color.r);
components[2] = (int) FastMath.convertFloatToHalf(color.g);
components[3] = (int) FastMath.convertFloatToHalf(color.b);
break;
case ImageCodec.FLAG_F32:
components[0] = (int) Float.floatToIntBits(color.a);
components[1] = (int) Float.floatToIntBits(color.r);
components[2] = (int) Float.floatToIntBits(color.g);
components[3] = (int) Float.floatToIntBits(color.b);
break;
case 0:
// Convert color to bits by multiplying by size
components[0] = Math.min((int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
components[1] = Math.min((int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
components[2] = Math.min((int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
components[3] = Math.min((int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
break;
}
}

protected void setImageUpdateNeeded(Image image) {
image.setUpdateNeeded();
}

@VisibleForTesting
protected void setStoreComponents(ColorRGBA store, ImageCodec codec, int[] components) {
switch (codec.type) {
case ImageCodec.FLAG_F16:
store.set(FastMath.convertHalfToFloat((short)components[1]),
FastMath.convertHalfToFloat((short)components[2]),
FastMath.convertHalfToFloat((short)components[3]),
FastMath.convertHalfToFloat((short)components[0]));
break;
case ImageCodec.FLAG_F32:
store.set(Float.intBitsToFloat((int)components[1]),
Float.intBitsToFloat((int)components[2]),
Float.intBitsToFloat((int)components[3]),
Float.intBitsToFloat((int)components[0]));
break;
case 0:
// Convert to float and divide by bitsize to get into range 0.0 - 1.0.
store.set((float)components[1] / codec.maxRed,
(float)components[2] / codec.maxGreen,
(float)components[3] / codec.maxBlue,
(float)components[0] / codec.maxAlpha);
break;
}
}

@VisibleForTesting
protected void setStoreRGBA(ColorRGBA store, ImageCodec codec) {
if (codec.isGray) {
store.g = store.b = store.r;
} else {
if (codec.maxRed == 0) {
store.r = 1;
}
if (codec.maxGreen == 0) {
store.g = 1;
}
if (codec.maxBlue == 0) {
store.b = 1;
}
if (codec.maxAlpha == 0) {
store.a = 1;
}
}
}

}
101 changes: 11 additions & 90 deletions jme3-core/src/main/java/com/jme3/texture/image/MipMapImageRaster.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,13 @@

public class MipMapImageRaster extends ImageRaster {

private final int[] components = new int[4];
@VisibleForTesting
protected final int[] components = new int[4];
private ByteBuffer buffer;
private final Image image;
private final ImageCodec codec;
@VisibleForTesting
protected final Image image;
@VisibleForTesting
protected final ImageCodec codec;
private int width[];
private int height[];
private final byte[] temp;
Expand Down Expand Up @@ -102,47 +105,10 @@ public void setMipLevel(int mipLevel) {
@Override
public void setPixel(int x, int y, ColorRGBA color) {
rangeCheck(x, y);
grayscaleCheck(color);
setComponents(color);
grayscaleCheck(color, codec);
setComponents(color, codec, components);
writeComponents(x, y);
image.setUpdateNeeded();
}

/**
* Check flags for grayscale
* @param color
*/
@VisibleForTesting
protected void grayscaleCheck(ColorRGBA color) {
if (codec.isGray) {
float gray = color.r * 0.27f + color.g * 0.67f + color.b * 0.06f;
color = new ColorRGBA(gray, gray, gray, color.a);
}
}

@VisibleForTesting
protected void setComponents(ColorRGBA color) {
switch (codec.type) {
case ImageCodec.FLAG_F16:
components[0] = (int) FastMath.convertFloatToHalf(color.a);
components[1] = (int) FastMath.convertFloatToHalf(color.r);
components[2] = (int) FastMath.convertFloatToHalf(color.g);
components[3] = (int) FastMath.convertFloatToHalf(color.b);
break;
case ImageCodec.FLAG_F32:
components[0] = (int) Float.floatToIntBits(color.a);
components[1] = (int) Float.floatToIntBits(color.r);
components[2] = (int) Float.floatToIntBits(color.g);
components[3] = (int) Float.floatToIntBits(color.b);
break;
case 0:
// Convert color to bits by multiplying by size
components[0] = Math.min((int) (color.a * codec.maxAlpha + 0.5f), codec.maxAlpha);
components[1] = Math.min((int) (color.r * codec.maxRed + 0.5f), codec.maxRed);
components[2] = Math.min((int) (color.g * codec.maxGreen + 0.5f), codec.maxGreen);
components[3] = Math.min((int) (color.b * codec.maxBlue + 0.5f), codec.maxBlue);
break;
}
setImageUpdateNeeded(image);
}

@VisibleForTesting
Expand All @@ -169,56 +135,11 @@ public ColorRGBA getPixel(int x, int y, ColorRGBA store) {
if (store == null) {
store = new ColorRGBA();
}
setStoreComponents(store);
setStoreRGBA(store);
setStoreComponents(store, codec, components);
setStoreRGBA(store, codec);
return store;
}

@VisibleForTesting
protected void setStoreComponents(ColorRGBA store) {
switch (codec.type) {
case ImageCodec.FLAG_F16:
store.set(FastMath.convertHalfToFloat((short) components[1]),
FastMath.convertHalfToFloat((short) components[2]),
FastMath.convertHalfToFloat((short) components[3]),
FastMath.convertHalfToFloat((short) components[0]));
break;
case ImageCodec.FLAG_F32:
store.set(Float.intBitsToFloat((int) components[1]),
Float.intBitsToFloat((int) components[2]),
Float.intBitsToFloat((int) components[3]),
Float.intBitsToFloat((int) components[0]));
break;
case 0:
// Convert to float and divide by bitsize to get into range 0.0 - 1.0.
store.set((float) components[1] / codec.maxRed,
(float) components[2] / codec.maxGreen,
(float) components[3] / codec.maxBlue,
(float) components[0] / codec.maxAlpha);
break;
}
}

@VisibleForTesting
protected void setStoreRGBA(ColorRGBA store) {
if (codec.isGray) {
store.g = store.b = store.r;
} else {
if (codec.maxRed == 0) {
store.r = 1;
}
if (codec.maxGreen == 0) {
store.g = 1;
}
if (codec.maxBlue == 0) {
store.b = 1;
}
if (codec.maxAlpha == 0) {
store.a = 1;
}
}
}

@Override
public int getWidth() {
return width[mipLevel];
Expand Down
Loading

0 comments on commit dd7b7e6

Please sign in to comment.