001package org.dcm4che3.image;
002
003public class ByteLookupTable extends LookupTable {
004
005    private final byte[] lut;
006
007    ByteLookupTable(StoredValue inBits, int outBits, int offset, byte[] lut) {
008        super(inBits, outBits, offset);
009        this.lut = lut;
010    }
011
012    ByteLookupTable(StoredValue inBits, int outBits, int offset, int size, boolean flip) {
013        this(inBits, outBits, offset, new byte[size]);
014        int maxOut = (1<<outBits)-1;
015        int maxIndex = size - 1;
016        int midIndex = maxIndex / 2;
017        if (flip)
018            for (int i = 0; i < size; i++)
019                lut[maxIndex-i] = (byte) ((i * maxOut + midIndex) / maxIndex);
020        else
021            for (int i = 0; i < size; i++)
022                lut[i] = (byte) ((i * maxOut + midIndex) / maxIndex);
023    }
024
025    @Override
026    public int length() {
027        return lut.length;
028    }
029
030    @Override
031    public void lookup(byte[] src, int srcPos, byte[] dest, int destPos, int length) {
032        for (int i = srcPos, endPos = srcPos + length, j = destPos; i < endPos;)
033            dest[j++] = lut[index(src[i++])];
034    }
035
036    private int index(int pixel) {
037        int index = inBits.valueOf(pixel) - offset;
038        return Math.min(Math.max(0, index), lut.length-1);
039    }
040
041    @Override
042    public void lookup(short[] src, int srcPos, byte[] dest, int destPos, int length) {
043        for (int i = srcPos, endPos = srcPos + length, j = destPos; i < endPos;)
044            dest[j++] = lut[index(src[i++])];
045    }
046
047    @Override
048    public void lookup(byte[] src, int srcPos, short[] dest, int destPos, int length) {
049        for (int i = srcPos, endPos = srcPos + length, j = destPos; i < endPos;)
050            dest[j++] = (short) (lut[index(src[i++])] & 0xff);
051    }
052
053    @Override
054    public void lookup(short[] src, int srcPos, short[] dest, int destPos, int length) {
055        for (int i = srcPos, endPos = srcPos + length, j = destPos; i < endPos;)
056            dest[j++] = (short) (lut[index(src[i++])] & 0xff);
057    }
058
059    @Override
060    public LookupTable adjustOutBits(int outBits) {
061        int diff = outBits - this.outBits;
062        if (diff != 0) {
063            byte[] lut = this.lut;
064            if (outBits > 8) {
065                short[] ss = new short[lut.length];
066                for (int i = 0; i < lut.length; i++)
067                    ss[i] = (short) ((lut[i] & 0xff) << diff);
068                return new ShortLookupTable(inBits, outBits, offset, ss);
069            }
070            if (diff < 0) {
071                diff = -diff;
072                for (int i = 0; i < lut.length; i++)
073                    lut[i] = (byte) ((lut[i] & 0xff) >> diff);
074            } else
075                for (int i = 0; i < lut.length; i++)
076                    lut[i] <<= diff;
077            this.outBits = outBits;
078        }
079        return this;
080    }
081
082    @Override
083    public void inverse() {
084        byte[] lut = this.lut;
085        int maxOut = (1<<outBits)-1;
086        for (int i = 0; i < lut.length; i++)
087            lut[i] = (byte) (maxOut - lut[i]); 
088     }
089
090
091    @Override
092    public LookupTable combine(LookupTable other) {
093        byte[] lut = this.lut;
094        if (other.outBits > 8) {
095            short[] ss = new short[lut.length];
096            other.lookup(lut, 0, ss, 0, lut.length);
097            return new ShortLookupTable(inBits, other.outBits, offset, ss);
098        }
099        other.lookup(lut, 0, lut, 0, lut.length);
100        this.outBits = other.outBits;
101        return this;
102    }
103
104}