/*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.apache.commons.imaging.formats.jpeg.segments;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class DhtSegment extends Segment
{
    public final List<HuffmanTable> huffmanTables = new ArrayList<HuffmanTable>();

    public static class HuffmanTable
    {
        // some arrays are better off one-based
        // to avoid subtractions by one later when indexing them
        public final int tableClass;
        public final int destinationIdentifier;
        public final int[] bits; // 1-based
        public final int[] huffVal; // 0-based

        // derived properties:
        public final int[] huffSize = new int[16 * 256]; // 0-based
        public final int[] huffCode; // 0-based
        public final int[] minCode = new int[1 + 16]; // 1-based
        public final int[] maxCode = new int[1 + 16]; // 1-based
        public final int[] valPtr = new int[1 + 16]; // 1-based

        public HuffmanTable(int tableClass, int destinationIdentifier,
                int[] bits, int[] huffVal)
        {
            this.tableClass = tableClass;
            this.destinationIdentifier = destinationIdentifier;
            this.bits = bits;
            this.huffVal = huffVal;

            // "generate_size_table", section C.2, figure C.1, page 51 of ITU-T T.81:
            int k = 0;
            int i = 1;
            int j = 1;
            int lastK = -1;
            while (true)
            {
                if (j > bits[i])
                {
                    i++;
                    j = 1;
                    if (i > 16)
                    {
                        huffSize[k] = 0;
                        lastK = k;
                        break;
                    }
                }
                else
                {
                    huffSize[k] = i;
                    k++;
                    j++;
                }
            }

            // "generate_code_table", section C.2, figure C.2, page 52 of ITU-T T.81:
            k = 0;
            int code = 0;
            int si = huffSize[0];
            huffCode = new int[lastK];
            while (true)
            {
                huffCode[k] = code;
                code++;
                k++;

                if (huffSize[k] == si)
                    continue;
                if (huffSize[k] == 0)
                    break;
                do
                {
                    code <<= 1;
                    si++;
                } while (huffSize[k] != si);
            }

            // "Decoder_tables", section F.2.2.3, figure F.15, page 108 of T.81:
            i = 0;
            j = 0;
            while (true)
            {
                i++;
                if (i > 16)
                    break;
                if (bits[i] == 0)
                    maxCode[i] = -1;
                else
                {
                    valPtr[i] = j;
                    minCode[i] = huffCode[j];
                    j += bits[i] - 1;
                    maxCode[i] = huffCode[j];
                    j++;
                }
            }

        }
    }


    public DhtSegment(int marker, byte[] segmentData)
            throws IOException
    {
        this(marker, segmentData.length, new ByteArrayInputStream(segmentData));
    }

    public DhtSegment(int marker, int length, InputStream is)
            throws IOException
    {
        super(marker, length);

        while (length > 0)
        {
            int tableClassAndDestinationId =
                    0xff & readByte("TableClassAndDestinationId",
                    is, "Not a Valid JPEG File");
            length--;
            int tableClass = (tableClassAndDestinationId >> 4) & 0xf;
            int destinationIdentifier = tableClassAndDestinationId & 0xf;
            int[] bits = new int[1 + 16];
            int bitsSum = 0;
            for (int i = 1; i < bits.length; i++)
            {
                bits[i] = 0xff & readByte("Li", is, "Not a Valid JPEG File");
                length--;
                bitsSum += bits[i];
            }
            int[] huffVal = new int[bitsSum];
            for (int i = 0; i < bitsSum; i++)
            {
                huffVal[i] = 0xff & readByte("Vij", is, "Not a Valid JPEG File");
                length--;
            }

            huffmanTables.add(new HuffmanTable(tableClass,
                    destinationIdentifier, bits, huffVal));
        }
    }

    @Override
    public String getDescription()
    {
        return "DHT (" + getSegmentType() + ")";
    }
}
