001/*
002 * Copyright 2010-2015 Institut Pasteur.
003 * 
004 * This file is part of Icy.
005 * 
006 * Icy is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 * 
011 * Icy is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 * 
016 * You should have received a copy of the GNU General Public License
017 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
018 */
019package icy.image.colormodel;
020
021import icy.image.lut.LUT;
022import icy.type.DataType;
023
024/**
025 * @author stephane
026 */
027public class UShortColorModel extends IcyColorModel
028{
029    /**
030     * Create a new UShortColorModel
031     * 
032     * @param numComponents
033     * @param bits
034     */
035    public UShortColorModel(int numComponents, int[] bits)
036    {
037        super(numComponents, DataType.USHORT, bits);
038    }
039
040    @Override
041    public int getRGB(Object pixel)
042    {
043        final short[] pix = (short[]) pixel;
044        final int[] scaledData = new int[numComponents];
045
046        for (int comp = 0; comp < numComponents; comp++)
047            scaledData[comp] = (int) colormapScalers[comp].scale(pix[comp] & 0xFFFF);
048
049        return getIcyColorSpace().toRGBUnnorm(scaledData);
050    }
051
052    /**
053     * Same as getRGB but by using the specified LUT instead of internal one
054     * 
055     * @see java.awt.image.ColorModel#getRGB(java.lang.Object)
056     */
057    @Override
058    public int getRGB(Object pixel, LUT lut)
059    {
060        final short[] pix = (short[]) pixel;
061        final int[] scaledData = new int[numComponents];
062
063        for (int comp = 0; comp < numComponents; comp++)
064            scaledData[comp] = (int) lut.getLutChannel(comp).getScaler().scale(pix[comp] & 0xFFFF);
065
066        return lut.getColorSpace().toRGBUnnorm(scaledData);
067    }
068
069    @Override
070    public int[] getComponents(Object pixel, int[] components, int offset)
071    {
072        final int[] result;
073
074        if (components == null)
075            result = new int[offset + numComponents];
076        else
077        {
078            if ((components.length - offset) < numComponents)
079                throw new IllegalArgumentException("Length of components array < number of components in model");
080
081            result = components;
082        }
083
084        final short data[] = (short[]) pixel;
085        final int len = data.length;
086
087        for (int i = 0; i < len; i++)
088            result[offset + i] = data[i] & 0xFFFF;
089
090        return result;
091    }
092
093    @Override
094    public Object getDataElements(int[] components, int offset, Object obj)
095    {
096        if ((components.length - offset) < numComponents)
097            throw new IllegalArgumentException("Component array too small" + " (should be " + numComponents);
098
099        final short[] pixel;
100        final int len = components.length;
101
102        if (obj == null)
103            pixel = new short[numComponents];
104        else
105            pixel = (short[]) obj;
106
107        for (int i = 0; i < len; i++)
108            pixel[i] = (short) components[offset + i];
109
110        return pixel;
111    }
112
113    @Override
114    public Object getDataElements(float[] normComponents, int offset, Object obj)
115    {
116        final short[] pixel;
117
118        if (obj == null)
119            pixel = new short[numComponents];
120        else
121            pixel = (short[]) obj;
122
123        for (int c = 0, nc = offset; c < numComponents; c++, nc++)
124            pixel[c] = (short) normalScalers[c].unscale(normComponents[nc]);
125
126        return pixel;
127    }
128
129    @Override
130    public float[] getNormalizedComponents(Object pixel, float[] normComponents, int normOffset)
131    {
132        final float[] result;
133
134        if (normComponents == null)
135            result = new float[numComponents + normOffset];
136        else
137            result = normComponents;
138
139        final short[] data = (short[]) pixel;
140
141        for (int c = 0, nc = normOffset; c < numComponents; c++, nc++)
142            result[nc] = (float) normalScalers[c].scale(data[c] & 0xFFFF);
143
144        return result;
145    }
146}