/*
 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.imageio.plugins.jpeg;

import javax.imageio.IIOException;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadataNode;
import javax.imageio.stream.ImageOutputStream;
import javax.imageio.plugins.jpeg.JPEGQTable;

import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;

import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.NamedNodeMap;

/**
 * A DQT (Define Quantization Table) marker segment.
 */
class DQTMarkerSegment extends MarkerSegment {
    List tables = new ArrayList();  // Could be 1 to 4

    DQTMarkerSegment(float quality, boolean needTwo) {
        super(JPEG.DQT);
        tables.add(new Qtable(true, quality));
        if (needTwo) {
            tables.add(new Qtable(false, quality));
        }
    }

    DQTMarkerSegment(JPEGBuffer buffer) throws IOException {
        super(buffer);
        int count = length;
        while (count > 0) {
            Qtable newGuy = new Qtable(buffer);
            tables.add(newGuy);
            count -= newGuy.data.length+1;
        }
        buffer.bufAvail -= length;
    }

    DQTMarkerSegment(JPEGQTable[] qtables) {
        super(JPEG.DQT);
        for (int i = 0; i < qtables.length; i++) {
            tables.add(new Qtable(qtables[i], i));
        }
    }

    DQTMarkerSegment(Node node) throws IIOInvalidTreeException {
        super(JPEG.DQT);
        NodeList children = node.getChildNodes();
        int size = children.getLength();
        if ((size < 1) || (size > 4)) {
            throw new IIOInvalidTreeException("Invalid DQT node", node);
        }
        for (int i = 0; i < size; i++) {
            tables.add(new Qtable(children.item(i)));
        }
    }

    protected Object clone() {
        DQTMarkerSegment newGuy = (DQTMarkerSegment) super.clone();
        newGuy.tables = new ArrayList(tables.size());
        Iterator iter = tables.iterator();
        while (iter.hasNext()) {
            Qtable table = (Qtable) iter.next();
            newGuy.tables.add(table.clone());
        }
        return newGuy;
    }

    IIOMetadataNode getNativeNode() {
        IIOMetadataNode node = new IIOMetadataNode("dqt");
        for (int i= 0; i<tables.size(); i++) {
            Qtable table = (Qtable) tables.get(i);
            node.appendChild(table.getNativeNode());
        }
        return node;
    }

    /**
     * Writes the data for this segment to the stream in
     * valid JPEG format.
     */
    void write(ImageOutputStream ios) throws IOException {
        // We don't write DQT segments; the IJG library does.
    }

    void print() {
        printTag("DQT");
        System.out.println("Num tables: "
                           + Integer.toString(tables.size()));
        for (int i= 0; i<tables.size(); i++) {
            Qtable table = (Qtable) tables.get(i);
            table.print();
        }
        System.out.println();
    }

    /**
     * Assuming the given table was generated by scaling the "standard"
     * visually lossless luminance table, extract the scale factor that
     * was used.
     */
    Qtable getChromaForLuma(Qtable luma) {
        Qtable newGuy = null;
        // Determine if the table is all the same values
        // if so, use the same table
        boolean allSame = true;
        for (int i = 1; i < luma.QTABLE_SIZE; i++) {
            if (luma.data[i] != luma.data[i-1]) {
                allSame = false;
                break;
            }
        }
        if (allSame) {
            newGuy = (Qtable) luma.clone();
            newGuy.tableID = 1;
        } else {
            // Otherwise, find the largest coefficient less than 255.  This is
            // the largest value that we know did not clamp on scaling.
            int largestPos = 0;
            for (int i = 1; i < luma.QTABLE_SIZE; i++) {
                if (luma.data[i] > luma.data[largestPos]) {
                    largestPos = i;
                }
            }
            // Compute the scale factor by dividing it by the value in the
            // same position from the "standard" table.
            // If the given table was not generated by scaling the standard,
            // the resulting table will still be reasonable, as it will reflect
            // a comparable scaling of chrominance frequency response of the
            // eye.
            float scaleFactor = ((float)(luma.data[largestPos]))
                / ((float)(JPEGQTable.K1Div2Luminance.getTable()[largestPos]));
            //    generate a new table
            JPEGQTable jpegTable =
                JPEGQTable.K2Div2Chrominance.getScaledInstance(scaleFactor,
                                                               true);
            newGuy = new Qtable(jpegTable, 1);
        }
        return newGuy;
    }

    Qtable getQtableFromNode(Node node) throws IIOInvalidTreeException {
        return new Qtable(node);
    }

    /**
     * A quantization table within a DQT marker segment.
     */
    class Qtable implements Cloneable {
        int elementPrecision;
        int tableID;
        final int QTABLE_SIZE = 64;
        int [] data; // 64 elements, in natural order

        /**
         * The zigzag-order position of the i'th element
         * of a DCT block read in natural order.
         */
        private final int [] zigzag = {
            0,  1,  5,  6, 14, 15, 27, 28,
            2,  4,  7, 13, 16, 26, 29, 42,
            3,  8, 12, 17, 25, 30, 41, 43,
            9, 11, 18, 24, 31, 40, 44, 53,
            10, 19, 23, 32, 39, 45, 52, 54,
            20, 22, 33, 38, 46, 51, 55, 60,
            21, 34, 37, 47, 50, 56, 59, 61,
            35, 36, 48, 49, 57, 58, 62, 63
        };

        Qtable(boolean wantLuma, float quality) {
            elementPrecision = 0;
            JPEGQTable base = null;
            if (wantLuma) {
                tableID = 0;
                base = JPEGQTable.K1Div2Luminance;
            } else {
                tableID = 1;
                base = JPEGQTable.K2Div2Chrominance;
            }
            if (quality != JPEG.DEFAULT_QUALITY) {
                quality = JPEG.convertToLinearQuality(quality);
                if (wantLuma) {
                    base = JPEGQTable.K1Luminance.getScaledInstance
                        (quality, true);
                } else {
                    base = JPEGQTable.K2Div2Chrominance.getScaledInstance
                        (quality, true);
                }
            }
            data = base.getTable();
        }

        Qtable(JPEGBuffer buffer) throws IIOException {
            elementPrecision = buffer.buf[buffer.bufPtr] >>> 4;
            tableID = buffer.buf[buffer.bufPtr++] & 0xf;
            if (elementPrecision != 0) {
                // IJG is compiled for 8-bits, so this shouldn't happen
                throw new IIOException ("Unsupported element precision");
            }
            data = new int [QTABLE_SIZE];
            // Read from zig-zag order to natural order
            for (int i = 0; i < QTABLE_SIZE; i++) {
                data[i] = buffer.buf[buffer.bufPtr+zigzag[i]] & 0xff;
            }
            buffer.bufPtr += QTABLE_SIZE;
        }

        Qtable(JPEGQTable table, int id) {
            elementPrecision = 0;
            tableID = id;
            data = table.getTable();
        }

        Qtable(Node node) throws IIOInvalidTreeException {
            if (node.getNodeName().equals("dqtable")) {
                NamedNodeMap attrs = node.getAttributes();
                int count = attrs.getLength();
                if ((count < 1) || (count > 2)) {
                    throw new IIOInvalidTreeException
                        ("dqtable node must have 1 or 2 attributes", node);
                }
                elementPrecision = 0;
                tableID = getAttributeValue(node, attrs, "qtableId", 0, 3, true);
                if (node instanceof IIOMetadataNode) {
                    IIOMetadataNode ourNode = (IIOMetadataNode) node;
                    JPEGQTable table = (JPEGQTable) ourNode.getUserObject();
                    if (table == null) {
                        throw new IIOInvalidTreeException
                            ("dqtable node must have user object", node);
                    }
                    data = table.getTable();
                } else {
                    throw new IIOInvalidTreeException
                        ("dqtable node must have user object", node);
                }
            } else {
                throw new IIOInvalidTreeException
                    ("Invalid node, expected dqtable", node);
            }
        }

        protected Object clone() {
            Qtable newGuy = null;
            try {
                newGuy = (Qtable) super.clone();
            } catch (CloneNotSupportedException e) {} // won't happen
            if (data != null) {
                newGuy.data = (int []) data.clone();
            }
            return newGuy;
        }

        IIOMetadataNode getNativeNode() {
            IIOMetadataNode node = new IIOMetadataNode("dqtable");
            node.setAttribute("elementPrecision",
                              Integer.toString(elementPrecision));
            node.setAttribute("qtableId",
                              Integer.toString(tableID));
            node.setUserObject(new JPEGQTable(data));
            return node;
        }

        void print() {
            System.out.println("Table id: " + Integer.toString(tableID));
            System.out.println("Element precision: "
                               + Integer.toString(elementPrecision));

            (new JPEGQTable(data)).toString();
            /*
              for (int i = 0; i < 64; i++) {
              if (i % 8 == 0) {
              System.out.println();
              }
              System.out.print(" " + Integer.toString(data[i]));
              }
              System.out.println();
            */
        }
    }
}
