alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (DQTMarkerSegment.java)

This example Java source code file (DQTMarkerSegment.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

arraylist, cloneable, clonenotsupportedexception, could, dom, dqtmarkersegment, iioexception, iioinvalidtreeexception, iiometadatanode, image, imageio, iterator, jpegqtable, nodelist, object, qtable, qtable_size, util

The DQTMarkerSegment.java Java example source code

/*
 * 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();
            */
        }
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java DQTMarkerSegment.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.