/*
 *  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.sanselan.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() + ")";
    }
}
