package org.jwildfire.create.tina.variation.iflames;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jwildfire.base.Tools;
import org.jwildfire.create.GradientCreator;
import org.jwildfire.create.tina.palette.RenderColor;
import org.jwildfire.create.tina.random.AbstractRandomGenerator;
import org.jwildfire.create.tina.random.JavaInternalRandomGenerator;
import org.jwildfire.create.tina.variation.FlameTransformationContext;
import org.jwildfire.create.tina.variation.RessourceManager;
import org.jwildfire.create.tina.variation.RessourceType;
import org.jwildfire.create.tina.variation.VariationFunc;
import org.jwildfire.image.SimpleImage;
import org.jwildfire.image.WFImage;
public class ImageParams implements Params, Serializable {
private static final long serialVersionUID = 1L;
private static final String RESSOURCE_INLINED_IMAGE = "inlined_image";
public static final String RESSOURCE_IMAGE_FILENAME = "image_filename";
private static final String PARAM_STRUCTURE_THRESHOLD = "structure_threshold";
private static final String PARAM_STRUCTURE_DENSITY = "structure_density";
private static final String PARAM_IFLAME_DENSITY = "iflame_density";
private static final String PARAM_IFLAME_BRIGHTNESS = "iflame_brightness";
private static final String PARAM_IMAGE_BRIGHTNESS = "image_brightness";
private static final String PARAM_SHAPE_DISTRIBUTION = "shape_distribution";
private static final String PARAM_SCALEX = "scale_x";
private static final String PARAM_SCALEY = "scale_y";
private static final String PARAM_SCALEZ = "scale_z";
private static final String PARAM_OFFSETX = "offset_x";
private static final String PARAM_OFFSETY = "offset_y";
private static final String PARAM_OFFSETZ = "offset_z";
private static final String PARAM_ERODE = "erode";
private static final String PARAM_ERODE_SIZE = "erode_size";
private static final String PARAM_CONV_NORTH = "conv_north";
private static final String PARAM_CONV_EAST = "conv_east";
private static final String PARAM_CONV_SOUTH = "conv_south";
private static final String PARAM_CONV_WEST = "conv_west";
private static final String PARAM_MAX_IMG_WIDTH = "max_img_width";
private static final String PARAM_ID = "id";
private static final String PARAM_RENDER_ID = "render_id";
private static final String PARAM_SEED = "seed";
private static final String PARAM_COLOR_CHG_RED = "color_chg_red";
private static final String PARAM_COLOR_CHG_GREEN = "color_chg_green";
private static final String PARAM_COLOR_CHG_BLUE = "color_chg_blue";
private static final String PARAM_COLOR_CHG_HUE = "color_chg_hue";
private static final String PARAM_COLOR_CHG_SATURATION = "color_chg_saturation";
private static final String PARAM_COLOR_CHG_LIGHTNESS = "color_chg_lightness";
private static final String CACHE_KEY_PREFIX_PREPROCESSED_IMAGE = "iflames_preprocessed_image";
public static final String CACHE_KEY_PREFIX_STATISTICS = "iflames_statistics";
public static final String CACHE_KEY_PREFIX_PROGRESS_UPDATER = "iflames_progress_updater";
private double structure_threshold = 0.12;
private double structure_density = 0.03;
private double iflame_density = 0.666;
private double iflame_brightness = 1.24;
private double image_brightness = 0.42;
private ShapeDistribution shape_distribution = ShapeDistribution.HUE;
private int erode = 0;
private int erodeSize = 5;
private int conv_north = 1;
private int conv_east = 1;
private int conv_south = 0;
private int conv_west = 0;
private double scaleX = 19.20;
private double scaleY = 10.80;
private double scaleZ = 0.3;
private double offsetX = -9.6;
private double offsetY = -5.7;
private double offsetZ = 0.0;
private String imageFilename = null;
private byte[] inlinedImage = null;
private int inlinedImageHash = 0;
private int maxImgWidth = 800;
private int id = 1;
private int renderId = 0;
private int seed = 666;
private double color_change_red;
private double color_change_green;
private double color_change_blue;
private double color_change_hue;
private double color_change_saturation;
private double color_change_lightness;
// derived params
private WFImage colorMap;
private String cachedPreprocessedImageKey;
private transient Map<RenderColor, Double> colorIdxMap = new HashMap<RenderColor, Double>();
private int imgWidth, imgHeight;
private double scaleColorMap;
private transient AbstractRandomGenerator randGen;
@Override
public String[] appendParamNames(String[] pParamNames) {
List<String> res = new ArrayList<String>(Arrays.asList(pParamNames));
res.add(PARAM_STRUCTURE_THRESHOLD);
res.add(PARAM_STRUCTURE_DENSITY);
res.add(PARAM_IFLAME_DENSITY);
res.add(PARAM_IFLAME_BRIGHTNESS);
res.add(PARAM_IMAGE_BRIGHTNESS);
res.add(PARAM_SHAPE_DISTRIBUTION);
res.add(PARAM_ERODE);
res.add(PARAM_ERODE_SIZE);
res.add(PARAM_CONV_NORTH);
res.add(PARAM_CONV_EAST);
res.add(PARAM_CONV_SOUTH);
res.add(PARAM_CONV_WEST);
res.add(PARAM_SCALEX);
res.add(PARAM_SCALEY);
res.add(PARAM_SCALEZ);
res.add(PARAM_OFFSETX);
res.add(PARAM_OFFSETY);
res.add(PARAM_OFFSETZ);
res.add(PARAM_MAX_IMG_WIDTH);
res.add(PARAM_ID);
res.add(PARAM_RENDER_ID);
res.add(PARAM_SEED);
res.add(PARAM_COLOR_CHG_RED);
res.add(PARAM_COLOR_CHG_GREEN);
res.add(PARAM_COLOR_CHG_BLUE);
res.add(PARAM_COLOR_CHG_HUE);
res.add(PARAM_COLOR_CHG_SATURATION);
res.add(PARAM_COLOR_CHG_LIGHTNESS);
return res.toArray(pParamNames);
}
@Override
public String[] appendRessourceNames(String[] pRessourceNames) {
List<String> res = new ArrayList<String>(Arrays.asList(pRessourceNames));
res.add(RESSOURCE_IMAGE_FILENAME);
res.add(RESSOURCE_INLINED_IMAGE);
return res.toArray(pRessourceNames);
}
@Override
public Object[] appendParamValues(Object[] pParamValues) {
List<Object> res = new ArrayList<Object>(Arrays.asList(pParamValues));
res.add(structure_threshold);
res.add(structure_density);
res.add(iflame_density);
res.add(iflame_brightness);
res.add(image_brightness);
res.add(shape_distribution.getId());
res.add(erode);
res.add(erodeSize);
res.add(conv_north);
res.add(conv_east);
res.add(conv_south);
res.add(conv_west);
res.add(scaleX);
res.add(scaleY);
res.add(scaleZ);
res.add(offsetX);
res.add(offsetY);
res.add(offsetZ);
res.add(maxImgWidth);
res.add(id);
res.add(renderId);
res.add(seed);
res.add(color_change_red);
res.add(color_change_green);
res.add(color_change_blue);
res.add(color_change_hue);
res.add(color_change_saturation);
res.add(color_change_lightness);
return res.toArray(pParamValues);
}
@Override
public boolean setParameter(String pName, double pValue) {
if (PARAM_STRUCTURE_THRESHOLD.equalsIgnoreCase(pName)) {
structure_threshold = VariationFunc.limitVal(pValue, 0.0, 0.99999);
return true;
}
else if (PARAM_STRUCTURE_DENSITY.equalsIgnoreCase(pName)) {
structure_density = VariationFunc.limitVal(pValue, 0.0, 1.0);
return true;
}
else if (PARAM_IFLAME_DENSITY.equalsIgnoreCase(pName)) {
iflame_density = VariationFunc.limitVal(pValue, 0.0, 1.0);
return true;
}
else if (PARAM_IFLAME_BRIGHTNESS.equalsIgnoreCase(pName)) {
iflame_brightness = pValue;
return true;
}
else if (PARAM_IMAGE_BRIGHTNESS.equalsIgnoreCase(pName)) {
image_brightness = pValue;
return true;
}
else if (PARAM_SHAPE_DISTRIBUTION.equalsIgnoreCase(pName)) {
shape_distribution = ShapeDistribution.valueOf(Tools.FTOI(pValue));
if (shape_distribution == null) {
shape_distribution = ShapeDistribution.HUE;
}
return true;
}
else if (PARAM_ERODE.equalsIgnoreCase(pName)) {
erode = VariationFunc.limitIntVal(Tools.FTOI(pValue), 0, 1);
return true;
}
else if (PARAM_ERODE_SIZE.equalsIgnoreCase(pName)) {
erodeSize = Tools.FTOI(pValue);
if (erodeSize < 3) {
erodeSize = 3;
}
if (erodeSize % 2 == 0) {
erodeSize--;
}
if (erodeSize > 9) {
erodeSize = 9;
}
return true;
}
else if (PARAM_CONV_NORTH.equalsIgnoreCase(pName)) {
conv_north = VariationFunc.limitIntVal(Tools.FTOI(pValue), 0, 1);
return true;
}
else if (PARAM_CONV_EAST.equalsIgnoreCase(pName)) {
conv_east = VariationFunc.limitIntVal(Tools.FTOI(pValue), 0, 1);
return true;
}
else if (PARAM_CONV_SOUTH.equalsIgnoreCase(pName)) {
conv_south = VariationFunc.limitIntVal(Tools.FTOI(pValue), 0, 1);
return true;
}
else if (PARAM_CONV_WEST.equalsIgnoreCase(pName)) {
conv_west = VariationFunc.limitIntVal(Tools.FTOI(pValue), 0, 1);
return true;
}
else if (PARAM_SCALEX.equalsIgnoreCase(pName)) {
scaleX = pValue;
return true;
}
else if (PARAM_SCALEY.equalsIgnoreCase(pName)) {
scaleY = pValue;
return true;
}
else if (PARAM_SCALEZ.equalsIgnoreCase(pName)) {
scaleZ = pValue;
return true;
}
else if (PARAM_OFFSETX.equalsIgnoreCase(pName)) {
offsetX = pValue;
return true;
}
else if (PARAM_OFFSETY.equalsIgnoreCase(pName)) {
offsetY = pValue;
return true;
}
else if (PARAM_OFFSETZ.equalsIgnoreCase(pName)) {
offsetZ = pValue;
return true;
}
else if (PARAM_MAX_IMG_WIDTH.equalsIgnoreCase(pName)) {
maxImgWidth = VariationFunc.limitIntVal(Tools.FTOI(pValue), 16, 64000);
return true;
}
else if (PARAM_ID.equalsIgnoreCase(pName)) {
id = Tools.FTOI(pValue);
return true;
}
else if (PARAM_RENDER_ID.equalsIgnoreCase(pName)) {
renderId = Tools.FTOI(pValue);
return true;
}
else if (PARAM_SEED.equalsIgnoreCase(pName)) {
seed = Tools.FTOI(pValue);
return true;
}
else if (PARAM_COLOR_CHG_RED.equalsIgnoreCase(pName)) {
color_change_red = VariationFunc.limitVal(pValue, -1.0, 1.0);
return true;
}
else if (PARAM_COLOR_CHG_GREEN.equalsIgnoreCase(pName)) {
color_change_green = VariationFunc.limitVal(pValue, -1.0, 1.0);
return true;
}
else if (PARAM_COLOR_CHG_BLUE.equalsIgnoreCase(pName)) {
color_change_blue = VariationFunc.limitVal(pValue, -1.0, 1.0);
return true;
}
else if (PARAM_COLOR_CHG_HUE.equalsIgnoreCase(pName)) {
color_change_hue = VariationFunc.limitVal(pValue, -1.0, 1.0);
return true;
}
else if (PARAM_COLOR_CHG_SATURATION.equalsIgnoreCase(pName)) {
color_change_saturation = VariationFunc.limitVal(pValue, -1.0, 1.0);
return true;
}
else if (PARAM_COLOR_CHG_LIGHTNESS.equalsIgnoreCase(pName)) {
color_change_lightness = VariationFunc.limitVal(pValue, -1.0, 1.0);
return true;
}
else {
return false;
}
}
@Override
public boolean setRessource(String pName, byte[] pValue) {
if (RESSOURCE_IMAGE_FILENAME.equalsIgnoreCase(pName)) {
imageFilename = pValue != null ? new String(pValue) : "";
colorMap = null;
colorIdxMap.clear();
return true;
}
else if (RESSOURCE_INLINED_IMAGE.equalsIgnoreCase(pName)) {
inlinedImage = pValue;
inlinedImageHash = RessourceManager.calcHashCode(inlinedImage);
colorMap = null;
colorIdxMap.clear();
return true;
}
else {
return false;
}
}
@Override
public RessourceType getRessourceType(String pName) {
if (RESSOURCE_IMAGE_FILENAME.equalsIgnoreCase(pName)) {
return RessourceType.IMAGE_FILENAME;
}
else if (RESSOURCE_INLINED_IMAGE.equalsIgnoreCase(pName)) {
return RessourceType.IMAGE_FILE;
}
else {
return null;
}
}
@Override
public byte[][] appendRessourceValues(byte[][] pRessourceValues) {
List<byte[]> res = new ArrayList<byte[]>(Arrays.asList(pRessourceValues));
res.add((imageFilename != null ? imageFilename.getBytes() : null));
res.add(inlinedImage);
return res.toArray(pRessourceValues);
}
@Override
public String completeImageKey(String key) {
return key + "#" + id + "#" + Tools.doubleToString(structure_threshold) + "#" + Tools.doubleToString(structure_density) + "#"
+ erode + "#" + erodeSize + "#" + conv_north + "#" + conv_east + "#" + conv_south + "#" + conv_west + "#"
+ maxImgWidth + "#" + shape_distribution + "#" + colorMap.hashCode() + "#" + seed + "#" + color_change_red + "#"
+ color_change_green + "#" + color_change_blue + "#" + color_change_hue + "#" + color_change_saturation + "#" + color_change_lightness;
}
@Override
public String completeParticleKey(String pKey) {
return completeImageKey(pKey);
}
public int getMaxImgWidth() {
return maxImgWidth;
}
public double getStructure_threshold() {
return structure_threshold;
}
public int getErode() {
return erode;
}
public int getErodeSize() {
return erodeSize;
}
public int getConv_north() {
return conv_north;
}
public int getConv_east() {
return conv_east;
}
public int getConv_south() {
return conv_south;
}
public int getConv_west() {
return conv_west;
}
public double getStructure_density() {
return structure_density;
}
public void init(FlameTransformationContext pContext) {
randGen = new JavaInternalRandomGenerator();
randGen.randomize(seed);
colorMap = null;
if (inlinedImage != null) {
try {
colorMap = RessourceManager.getImage(inlinedImageHash, inlinedImage);
cachedPreprocessedImageKey = CACHE_KEY_PREFIX_PREPROCESSED_IMAGE + "#" + inlinedImageHash;
}
catch (Exception e) {
e.printStackTrace();
}
}
else if (imageFilename != null && imageFilename.length() > 0) {
try {
colorMap = RessourceManager.getImage(imageFilename);
cachedPreprocessedImageKey = CACHE_KEY_PREFIX_PREPROCESSED_IMAGE + "#" + imageFilename;
}
catch (Exception e) {
e.printStackTrace();
}
}
if (colorMap == null) {
colorMap = getDfltImage();
}
imgWidth = colorMap.getImageWidth();
imgHeight = colorMap.getImageHeight();
scaleColorMap = 1.0;
if (colorMap.getImageWidth() > maxImgWidth) {
scaleColorMap = (double) colorMap.getImageWidth() / (double) maxImgWidth;
}
cachedPreprocessedImageKey += "#" + conv_north + "#" + conv_east + "#" + conv_south + "#" + conv_west + "#" + erode + "#" + erodeSize + "#" + maxImgWidth;
}
private static SimpleImage dfltImage = null;
private synchronized SimpleImage getDfltImage() {
if (dfltImage == null) {
GradientCreator creator = new GradientCreator();
dfltImage = creator.createImage(128, 128);
}
return dfltImage;
}
public int getImgWidth() {
return imgWidth;
}
public int getImgHeight() {
return imgHeight;
}
public double getScaleColorMap() {
return scaleColorMap;
}
public WFImage getColorMap() {
return colorMap;
}
public double getImage_brightness() {
return image_brightness;
}
public double getScaleX() {
return scaleX;
}
public double getScaleY() {
return scaleY;
}
public double getScaleZ() {
return scaleZ;
}
public double getOffsetX() {
return offsetX;
}
public double getOffsetY() {
return offsetY;
}
public double getOffsetZ() {
return offsetZ;
}
public double getIFlame_brightness() {
return iflame_brightness;
}
public double getIFlame_density() {
return iflame_density;
}
public int getId() {
return id;
}
public void setImageFilename(String pImageFilename) {
imageFilename = pImageFilename;
}
public void setErode(int pErode) {
erode = pErode;
}
public void setConv_north(int pConv_north) {
conv_north = pConv_north;
}
public void setConv_east(int pConv_east) {
conv_east = pConv_east;
}
public void setConv_south(int pConv_south) {
conv_south = pConv_south;
}
public void setConv_west(int pConv_west) {
conv_west = pConv_west;
}
public void setErodeSize(int pErodeSize) {
erodeSize = pErodeSize;
}
public void setMaxImgWidth(int pMaxImgWidth) {
maxImgWidth = pMaxImgWidth;
}
public ShapeDistribution getShape_distribution() {
return shape_distribution;
}
public void setShape_distribution(ShapeDistribution pShape_distribution) {
shape_distribution = pShape_distribution;
}
public void setStructure_threshold(double pStructure_threshold) {
structure_threshold = pStructure_threshold;
}
public void setStructure_density(double pStructure_density) {
structure_density = pStructure_density;
}
public void setScaleX(double pScaleX) {
scaleX = pScaleX;
}
public void setScaleY(double pScaleY) {
scaleY = pScaleY;
}
public void setScaleZ(double pScaleZ) {
scaleZ = pScaleZ;
}
public void setOffsetX(double pOffsetX) {
offsetX = pOffsetX;
}
public void setOffsetY(double pOffsetY) {
offsetY = pOffsetY;
}
public void setOffsetZ(double pOffsetZ) {
offsetZ = pOffsetZ;
}
public double getIflame_density() {
return iflame_density;
}
public void setIflame_density(double pIflame_density) {
iflame_density = pIflame_density;
}
public double getIflame_brightness() {
return iflame_brightness;
}
public void setIflame_brightness(double pIflame_brightness) {
iflame_brightness = pIflame_brightness;
}
public void setImage_brightness(double pImage_brightness) {
image_brightness = pImage_brightness;
}
public String getCachedPreprocessedImageKey() {
return cachedPreprocessedImageKey;
}
public void setCachedPreprocessedImageKey(String cachedPreprocessedImageKey) {
this.cachedPreprocessedImageKey = cachedPreprocessedImageKey;
}
public int getRenderId() {
return renderId;
}
public void setRenderId(int pRenderId) {
renderId = pRenderId;
}
public AbstractRandomGenerator getRandGen() {
return randGen;
}
public double getColorChangeRed() {
return color_change_red;
}
public void setColorChangeRed(double pColorChangeRed) {
color_change_red = pColorChangeRed;
}
public double getColorChangeGreen() {
return color_change_green;
}
public void setColorChangeGreen(double pColorChangeGreen) {
color_change_green = pColorChangeGreen;
}
public double getColorChangeBlue() {
return color_change_blue;
}
public void setColorChangeBlue(double pColorChangeBlue) {
color_change_blue = pColorChangeBlue;
}
public double getColorChangeHue() {
return color_change_hue;
}
public void setColorChangeHue(double pColorChangeHue) {
color_change_hue = pColorChangeHue;
}
public double getColorChangeSaturation() {
return color_change_saturation;
}
public void setColorChangeSaturation(double pColorChangeSaturation) {
color_change_saturation = pColorChangeSaturation;
}
public double getColorChangeLightness() {
return color_change_lightness;
}
public void setColorChangeLightness(double pColorChangeLightness) {
color_change_lightness = pColorChangeLightness;
}
}