/*
TI16MapColor.java
(c) 2011-2016 Edward Swartz
All rights reserved. This program and the accompanying materials
are made available under the terms of the Eclipse Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html
*/
package v9t9.video.imageimport;
import java.util.TreeMap;
import org.ejs.gui.images.BasePaletteMapper;
import org.ejs.gui.images.ColorMapUtils;
import org.ejs.gui.images.V99ColorMapUtils;
import ejs.base.utils.Pair;
class TI16MapColor extends BasePaletteMapper {
final int white = 15;
final int black = 1;
final int grey = 14;
private boolean isGreyscale;
//final int darkGreen = 12;
public TI16MapColor(byte[][] thePalette, boolean useColorMappedGreyScale, boolean isGreyScale) {
super(thePalette, 1, 16, false, useColorMappedGreyScale);
this.isGreyscale = isGreyScale;
}
/* (non-Javadoc)
* @see v9t9.emulator.clients.builtin.video.ImageDataCanvas.IMapColor#mapColor(int, int[])
*/
@Override
public int mapColor(int pixel, int[] distA) {
Pair<Integer, Integer> info = getCloseColor(pixel);
distA[0] = info.second;
return info.first;
}
/**
* Get the closest color by sheer brute force -- we don't
* want dark green to emerge as a "close" color for dark or
* desaturated colors!
*
* 0 clear
*
* 1 black
*
* 2 medium green
*
* 3 light green
*
* 4 dark blue
*
* 5 light blue
*
* 6 dark red
*
* 7 cyan
*
* 8 medium red
*
* 9 orange/skin
*
* 10 yellow
*
* 11 light yellow
*
* 12 dark green
*
* 13 purple
*
* 14 grey
*
* 15 white
*
* @param prgb
* @return pair of index and distance
*/
private Pair<Integer, Integer> getCloseColor(int pixel) {
int closest = -1;
int mindiff = -1;
if (isGreyscale) {
int lum = ColorMapUtils.getPixelLum(pixel);
if (lum >= 192) {
closest = white;
} else if (lum >= 96) {
// dithering will take care of the rest
closest = grey;
} else {
closest = black;
}
mindiff = ColorMapUtils.getRGBDistance(palette[closest], pixel);
return new Pair<Integer, Integer>(closest, mindiff);
}
float[] phsv = { 0, 0, 0 };
ColorMapUtils.rgbToHsv((pixel & 0xff0000) >> 16, (pixel & 0x00ff00) >> 8, (pixel & 0xff), phsv);
float hue = phsv[0];
float val = phsv[2] * 100 / 256;
if (phsv[1] < (hue >= 30 && hue < 75 ? 0.4f : 0.2f)) {
if (val >= 80) {
closest = white;
} else if (val >= 50) {
// dithering will take care of the rest
closest = grey;
} else {
closest = black;
}
mindiff = ColorMapUtils.getRGBDistance(palette[closest], pixel);
}
else {
Pair<Integer, Integer> info = ColorMapUtils.getClosestColorByDistanceAndHSV(
palette, firstColor, 16, pixel, -1);
// Pair<Integer, Integer> info = ColorMapUtils.getClosestColorByDistance(
// palette, firstColor, 16, pixel, -1);
closest = info.first; mindiff = info.second;
// if (!isGreyscale) {
// if (false && closest == darkGreen) {
// if (phsv[1] < 0.5f) {
// closest = black;
// mindiff = ColorMapUtils.getRGBDistance(palette[closest], pixel);
// }
// }
// // see how the color matches
// else if (false && closest == black) {
// if (phsv[1] > 0.9f && val >= 25) {
// if ((hue >= 90 && hue < 140) && (val >= 5 && val <= 33)) {
// closest = 12;
// mindiff = ColorMapUtils.getRGBDistance(palette[closest], pixel);
// }
// }
// }
// /*else {
// int rigid = rigidMatch(phsv, hue, val);
// if (phsv[1] < 0.5f && (rigid == 1 || rigid == 14 || rigid == 15)) {
// closest = rigid;
// }
// }*/
// }
}
//closest = rigidMatch(phsv, hue, val);
return new Pair<Integer, Integer>(closest, mindiff);
}
/* (non-Javadoc)
* @see v9t9.emulator.clients.builtin.video.ImageImport.IMapColor#getClosestColor(int[])
*/
@Override
public int getClosestPaletteEntry(int pixel) {
Pair<Integer, Integer> info = getCloseColor(pixel);
return info.first;
}
@Override
public int getMinimalPaletteDistance() {
//return super.getMinimalPaletteDistance();
return 0x10 * 0x20 * 3;
}
/* (non-Javadoc)
* @see org.ejs.gui.images.IPaletteMapper#getGreyToRgbMap()
*/
@Override
public TreeMap<Integer, byte[]> getGreyToRgbMap() {
return V99ColorMapUtils.getGreyToRgbMap332();
}
}