jdk/src/share/classes/com/sun/imageio/plugins/jpeg/JFIFMarkerSegment.java
author sherman
Tue, 30 Aug 2011 11:53:11 -0700
changeset 10419 12c063b39232
parent 5506 202f599c92aa
child 14342 8435a30053c1
permissions -rw-r--r--
7084245: Update usages of InternalError to use exception chaining Summary: to use new InternalError constructor with cause chainning Reviewed-by: alanb, ksrini, xuelei, neugens Contributed-by: sebastian.sickelmann@gmx.de
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2381
diff changeset
     2
 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2381
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2381
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2381
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2381
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2381
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.imageio.plugins.jpeg;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import javax.imageio.IIOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import javax.imageio.IIOImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import javax.imageio.ImageTypeSpecifier;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import javax.imageio.ImageReader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import javax.imageio.metadata.IIOInvalidTreeException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.imageio.metadata.IIOMetadataNode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.imageio.metadata.IIOMetadata;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.imageio.stream.ImageInputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
import javax.imageio.stream.ImageOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import javax.imageio.stream.MemoryCacheImageOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
import javax.imageio.event.IIOReadProgressListener;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
import java.awt.Graphics;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
import java.awt.color.ICC_Profile;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
import java.awt.color.ICC_ColorSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
import java.awt.color.ColorSpace;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
import java.awt.image.ColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
import java.awt.image.SampleModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
import java.awt.image.IndexColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
import java.awt.image.ComponentColorModel;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
import java.awt.image.DataBuffer;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
import java.awt.image.DataBufferByte;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
import java.awt.image.Raster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
import java.awt.image.WritableRaster;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
import java.io.ByteArrayOutputStream;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
import java.util.List;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
import java.util.ArrayList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
import java.util.Iterator;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
import org.w3c.dom.Node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
import org.w3c.dom.NodeList;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
import org.w3c.dom.NamedNodeMap;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * A JFIF (JPEG File Interchange Format) APP0 (Application-Specific)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * marker segment.  Inner classes are included for JFXX extension
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 * marker segments, for different varieties of thumbnails, and for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * ICC Profile APP2 marker segments.  Any of these secondary types
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * that occur are kept as members of a single JFIFMarkerSegment object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
class JFIFMarkerSegment extends MarkerSegment {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    int majorVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
    int minorVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
    int resUnits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    int Xdensity;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
    int Ydensity;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    int thumbWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    int thumbHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    JFIFThumbRGB thumb = null;  // If present
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    ArrayList extSegments = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    ICCMarkerSegment iccSegment = null; // optional ICC
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    private static final int THUMB_JPEG = 0x10;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    private static final int THUMB_PALETTE = 0x11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    private static final int THUMB_UNASSIGNED = 0x12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private static final int THUMB_RGB = 0x13;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    private static final int DATA_SIZE = 14;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    private static final int ID_SIZE = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    private final int MAX_THUMB_WIDTH = 255;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private final int MAX_THUMB_HEIGHT = 255;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    private final boolean debug = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
     * Set to <code>true</code> when reading the chunks of an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
     * ICC profile.  All chunks are consolidated to create a single
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * "segment" containing all the chunks.  This flag is a state
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     * variable identifying whether to construct a new segment or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
     * append to an old one.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    private boolean inICC = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
     * A placeholder for an ICC profile marker segment under
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
     * construction.  The segment is not added to the list
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
     * until all chunks have been read.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private ICCMarkerSegment tempICCSegment = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * Default constructor.  Used to create a default JFIF header
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    JFIFMarkerSegment() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
        super(JPEG.APP0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        majorVersion = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
        minorVersion = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        resUnits = JPEG.DENSITY_UNIT_ASPECT_RATIO;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
        Xdensity = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        Ydensity = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
        thumbWidth = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        thumbHeight = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * Constructs a JFIF header by reading from a stream wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * in a JPEGBuffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    JFIFMarkerSegment(JPEGBuffer buffer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        super(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
        buffer.bufPtr += ID_SIZE;  // skip the id, we already checked it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        majorVersion = buffer.buf[buffer.bufPtr++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        minorVersion = buffer.buf[buffer.bufPtr++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        resUnits = buffer.buf[buffer.bufPtr++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        Xdensity = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        Xdensity |= buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
        Ydensity = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        Ydensity |= buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
        thumbWidth = buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        thumbHeight = buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        buffer.bufAvail -= DATA_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        if (thumbWidth > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
            thumb = new JFIFThumbRGB(buffer, thumbWidth, thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * Constructs a JFIF header from a DOM Node.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
    JFIFMarkerSegment(Node node) throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        this();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        updateFromNativeNode(node, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
     * Returns a deep-copy clone of this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    protected Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        JFIFMarkerSegment newGuy = (JFIFMarkerSegment) super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        if (!extSegments.isEmpty()) { // Clone the list with a deep copy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            newGuy.extSegments = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            for (Iterator iter = extSegments.iterator(); iter.hasNext();) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
                JFIFExtensionMarkerSegment jfxx =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
                    (JFIFExtensionMarkerSegment) iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
                newGuy.extSegments.add(jfxx.clone());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        if (iccSegment != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            newGuy.iccSegment = (ICCMarkerSegment) iccSegment.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
        return newGuy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
     * Add an JFXX extension marker segment from the stream wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
     * in the JPEGBuffer to the list of extension segments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    void addJFXX(JPEGBuffer buffer, JPEGImageReader reader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        extSegments.add(new JFIFExtensionMarkerSegment(buffer, reader));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
     * Adds an ICC Profile APP2 segment from the stream wrapped
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * in the JPEGBuffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
    void addICC(JPEGBuffer buffer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
        if (inICC == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            if (iccSegment != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
                throw new IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                    ("> 1 ICC APP2 Marker Segment not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            tempICCSegment = new ICCMarkerSegment(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            if (inICC == false) { // Just one chunk
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                iccSegment = tempICCSegment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
                tempICCSegment = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
            if (tempICCSegment.addData(buffer) == true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                iccSegment = tempICCSegment;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
                tempICCSegment = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
     * Add an ICC Profile APP2 segment by constructing it from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * the given ICC_ColorSpace object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    void addICC(ICC_ColorSpace cs) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        if (iccSegment != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
            throw new IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                ("> 1 ICC APP2 Marker Segment not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
        iccSegment = new ICCMarkerSegment(cs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     * Returns a tree of DOM nodes representing this object and any
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
     * subordinate JFXX extension or ICC Profile segments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
    IIOMetadataNode getNativeNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        IIOMetadataNode node = new IIOMetadataNode("app0JFIF");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
        node.setAttribute("majorVersion", Integer.toString(majorVersion));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        node.setAttribute("minorVersion", Integer.toString(minorVersion));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
        node.setAttribute("resUnits", Integer.toString(resUnits));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        node.setAttribute("Xdensity", Integer.toString(Xdensity));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        node.setAttribute("Ydensity", Integer.toString(Ydensity));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        node.setAttribute("thumbWidth", Integer.toString(thumbWidth));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        node.setAttribute("thumbHeight", Integer.toString(thumbHeight));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        if (!extSegments.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
            IIOMetadataNode JFXXnode = new IIOMetadataNode("JFXX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
            node.appendChild(JFXXnode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
            for (Iterator iter = extSegments.iterator(); iter.hasNext();) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
                JFIFExtensionMarkerSegment seg =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
                    (JFIFExtensionMarkerSegment) iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
                JFXXnode.appendChild(seg.getNativeNode());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        if (iccSegment != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            node.appendChild(iccSegment.getNativeNode());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * Updates the data in this object from the given DOM Node tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     * If fromScratch is true, this object is being constructed.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
     * Otherwise an existing object is being modified.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
     * Throws an IIOInvalidTreeException if the tree is invalid in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * any way.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    void updateFromNativeNode(Node node, boolean fromScratch)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        // none of the attributes are required
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        NamedNodeMap attrs = node.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        if (attrs.getLength() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
            int value = getAttributeValue(node, attrs, "majorVersion",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                                          0, 255, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            majorVersion = (value != -1) ? value : majorVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            value = getAttributeValue(node, attrs, "minorVersion",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                                      0, 255, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            minorVersion = (value != -1) ? value : minorVersion;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            value = getAttributeValue(node, attrs, "resUnits", 0, 2, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            resUnits = (value != -1) ? value : resUnits;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            value = getAttributeValue(node, attrs, "Xdensity", 1, 65535, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            Xdensity = (value != -1) ? value : Xdensity;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
            value = getAttributeValue(node, attrs, "Ydensity", 1, 65535, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            Ydensity = (value != -1) ? value : Ydensity;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
            value = getAttributeValue(node, attrs, "thumbWidth", 0, 255, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            thumbWidth = (value != -1) ? value : thumbWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            value = getAttributeValue(node, attrs, "thumbHeight", 0, 255, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            thumbHeight = (value != -1) ? value : thumbHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
        if (node.hasChildNodes()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
            NodeList children = node.getChildNodes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            int count = children.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
            if (count > 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
                    ("app0JFIF node cannot have > 2 children", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            for (int i = 0; i < count; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                Node child = children.item(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                String name = child.getNodeName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
                if (name.equals("JFXX")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
                    if ((!extSegments.isEmpty()) && fromScratch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
                        throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
                            ("app0JFIF node cannot have > 1 JFXX node", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
                    NodeList exts = child.getChildNodes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
                    int extCount = exts.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
                    for (int j = 0; j < extCount; j++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
                        Node ext = exts.item(j);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
                        extSegments.add(new JFIFExtensionMarkerSegment(ext));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
                if (name.equals("app2ICC")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
                    if ((iccSegment != null) && fromScratch) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
                        throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
                            ("> 1 ICC APP2 Marker Segment not supported", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
                    iccSegment = new ICCMarkerSegment(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    int getThumbnailWidth(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        if (thumb != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            if (index == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
                return thumb.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            index--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        JFIFExtensionMarkerSegment jfxx =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            (JFIFExtensionMarkerSegment) extSegments.get(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        return jfxx.thumb.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    int getThumbnailHeight(int index) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        if (thumb != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            if (index == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
                return thumb.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            index--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
        JFIFExtensionMarkerSegment jfxx =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            (JFIFExtensionMarkerSegment) extSegments.get(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
        return jfxx.thumb.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
    BufferedImage getThumbnail(ImageInputStream iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                               int index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                               JPEGImageReader reader) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        reader.thumbnailStarted(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        BufferedImage ret = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
        if ((thumb != null) && (index == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                ret = thumb.getThumbnail(iis, reader);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            if (thumb != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                index--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            JFIFExtensionMarkerSegment jfxx =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                (JFIFExtensionMarkerSegment) extSegments.get(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            ret = jfxx.thumb.getThumbnail(iis, reader);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
        reader.thumbnailComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * Writes the data for this segment to the stream in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * valid JPEG format.  Assumes that there will be no thumbnail.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
               JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        // No thumbnail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        write(ios, null, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * Writes the data for this segment to the stream in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * valid JPEG format.  The length written takes the thumbnail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * width and height into account.  If necessary, the thumbnail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * is clipped to 255 x 255 and a warning is sent to the writer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * argument.  Progress updates are sent to the writer argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
               BufferedImage thumb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
               JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
        int thumbWidth = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
        int thumbHeight = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
        int thumbLength = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        int [] thumbData = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
        if (thumb != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
            // Clip if necessary and get the data in thumbData
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            thumbWidth = thumb.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
            thumbHeight = thumb.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
            if ((thumbWidth > MAX_THUMB_WIDTH)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
                || (thumbHeight > MAX_THUMB_HEIGHT)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
                writer.warningOccurred(JPEGImageWriter.WARNING_THUMB_CLIPPED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            thumbWidth = Math.min(thumbWidth, MAX_THUMB_WIDTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
            thumbHeight = Math.min(thumbHeight, MAX_THUMB_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            thumbData = thumb.getRaster().getPixels(0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
                                                    thumbWidth, thumbHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
                                                    (int []) null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
            thumbLength = thumbData.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
        length = DATA_SIZE + LENGTH_SIZE + thumbLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        writeTag(ios);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
        byte [] id = {0x4A, 0x46, 0x49, 0x46, 0x00};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        ios.write(id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        ios.write(majorVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        ios.write(minorVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        ios.write(resUnits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        write2bytes(ios, Xdensity);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        write2bytes(ios, Ydensity);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        ios.write(thumbWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        ios.write(thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        if (thumbData != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
            writer.thumbnailStarted(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            writeThumbnailData(ios, thumbData, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
            writer.thumbnailComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     * Write out the values in the integer array as a sequence of bytes,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     * reporting progress to the writer argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    void writeThumbnailData(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
                            int [] thumbData,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
                            JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        int progInterval = thumbData.length / 20;  // approx. every 5%
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        if (progInterval == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            progInterval = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        for (int i = 0; i < thumbData.length; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
            ios.write(thumbData[i]);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
            if ((i > progInterval) && (i % progInterval == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
                writer.thumbnailProgress
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
                    (((float) i * 100) / ((float) thumbData.length));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
     * Write out this JFIF Marker Segment, including a thumbnail or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
     * appending a series of JFXX Marker Segments, as appropriate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
     * Warnings and progress reports are sent to the writer argument.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
     * The list of thumbnails is matched to the list of JFXX extension
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
     * segments, if any, in order to determine how to encode the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
     * thumbnails.  If there are more thumbnails than metadata segments,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
     * default encoding is used for the extra thumbnails.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    void writeWithThumbs(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                         List thumbnails,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
                         JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        if (thumbnails != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            JFIFExtensionMarkerSegment jfxx = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
            if (thumbnails.size() == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                if (!extSegments.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
                    jfxx = (JFIFExtensionMarkerSegment) extSegments.get(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
                writeThumb(ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
                           (BufferedImage) thumbnails.get(0),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                           jfxx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                           0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
                           true,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
                           writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                // All others write as separate JFXX segments
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                write(ios, writer);  // Just the header without any thumbnail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
                for (int i = 0; i < thumbnails.size(); i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
                    jfxx = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                    if (i < extSegments.size()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
                        jfxx = (JFIFExtensionMarkerSegment) extSegments.get(i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
                    writeThumb(ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
                               (BufferedImage) thumbnails.get(i),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
                               jfxx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
                               i,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
                               false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
                               writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        } else {  // No thumbnails
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
            write(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
    private void writeThumb(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
                            BufferedImage thumb,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
                            JFIFExtensionMarkerSegment jfxx,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
                            int index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
                            boolean onlyOne,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                            JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
        ColorModel cm = thumb.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        ColorSpace cs = cm.getColorSpace();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        if (cm instanceof IndexColorModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
            // We never write a palette image into the header
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            // So if it's the only one, we need to write the header first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            if (onlyOne) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                write(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            if ((jfxx == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
                || (jfxx.code == THUMB_PALETTE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
                writeJFXXSegment(index, thumb, ios, writer); // default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
                // Expand to RGB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
                BufferedImage thumbRGB =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
                    ((IndexColorModel) cm).convertToIntDiscrete
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
                    (thumb.getRaster(), false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
                jfxx.setThumbnail(thumbRGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
                writer.thumbnailStarted(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
                jfxx.write(ios, writer);  // Handles clipping if needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                writer.thumbnailComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        } else if (cs.getType() == ColorSpace.TYPE_RGB) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
            if (jfxx == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
                if (onlyOne) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
                    write(ios, thumb, writer); // As part of the header
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
                    writeJFXXSegment(index, thumb, ios, writer); // default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
                // If this is the only one, write the header first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
                if (onlyOne) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
                    write(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
                if (jfxx.code == THUMB_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
                    writeJFXXSegment(index, thumb, ios, writer); // default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
                    writer.warningOccurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
                        (JPEGImageWriter.WARNING_NO_RGB_THUMB_AS_INDEXED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
                    jfxx.setThumbnail(thumb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
                    writer.thumbnailStarted(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
                    jfxx.write(ios, writer);  // Handles clipping if needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
                    writer.thumbnailComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
        } else if (cs.getType() == ColorSpace.TYPE_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
            if (jfxx == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
                if (onlyOne) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
                    BufferedImage thumbRGB = expandGrayThumb(thumb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                    write(ios, thumbRGB, writer); // As part of the header
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                    writeJFXXSegment(index, thumb, ios, writer); // default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                // If this is the only one, write the header first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                if (onlyOne) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                    write(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
                if (jfxx.code == THUMB_RGB) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
                    BufferedImage thumbRGB = expandGrayThumb(thumb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
                    writeJFXXSegment(index, thumbRGB, ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
                } else if (jfxx.code == THUMB_JPEG) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
                    jfxx.setThumbnail(thumb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
                    writer.thumbnailStarted(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
                    jfxx.write(ios, writer);  // Handles clipping if needed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
                    writer.thumbnailComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
                } else if (jfxx.code == THUMB_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
                    writeJFXXSegment(index, thumb, ios, writer); // default
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
                    writer.warningOccurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
                        (JPEGImageWriter.WARNING_NO_GRAY_THUMB_AS_INDEXED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
            writer.warningOccurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
                (JPEGImageWriter.WARNING_ILLEGAL_THUMBNAIL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
    // Could put reason codes in here to be parsed in writeJFXXSegment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
    // in order to provide more meaningful warnings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
    private class IllegalThumbException extends Exception {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     * Writes out a new JFXX extension segment, without saving it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
    private void writeJFXXSegment(int index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
                                  BufferedImage thumbnail,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
                                  ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
                                  JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        JFIFExtensionMarkerSegment jfxx = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
             jfxx = new JFIFExtensionMarkerSegment(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
        } catch (IllegalThumbException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            writer.warningOccurred
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
                (JPEGImageWriter.WARNING_ILLEGAL_THUMBNAIL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
        writer.thumbnailStarted(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        jfxx.write(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        writer.thumbnailComplete();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
     * Return an RGB image that is the expansion of the given grayscale
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
     * image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
    private static BufferedImage expandGrayThumb(BufferedImage thumb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
        BufferedImage ret = new BufferedImage(thumb.getWidth(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
                                              thumb.getHeight(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
                                              BufferedImage.TYPE_INT_RGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
        Graphics g = ret.getGraphics();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
        g.drawImage(thumb, 0, 0, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
        return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
     * Writes out a default JFIF marker segment to the given
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
     * output stream.  If <code>thumbnails</code> is not <code>null</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
     * writes out the set of thumbnail images as JFXX marker segments, or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
     * incorporated into the JFIF segment if appropriate.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
     * If <code>iccProfile</code> is not <code>null</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * writes out the profile after the JFIF segment using as many APP2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * marker segments as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    static void writeDefaultJFIF(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                                 List thumbnails,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
                                 ICC_Profile iccProfile,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
                                 JPEGImageWriter writer)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
        JFIFMarkerSegment jfif = new JFIFMarkerSegment();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
        jfif.writeWithThumbs(ios, thumbnails, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
        if (iccProfile != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
            writeICC(iccProfile, ios);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
     * Prints out the contents of this object to System.out for debugging.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
    void print() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        printTag("JFIF");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
        System.out.print("Version ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
        System.out.print(majorVersion);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
        System.out.println(".0"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                           + Integer.toString(minorVersion));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
        System.out.print("Resolution units: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        System.out.println(resUnits);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        System.out.print("X density: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        System.out.println(Xdensity);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
        System.out.print("Y density: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
        System.out.println(Ydensity);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        System.out.print("Thumbnail Width: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        System.out.println(thumbWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        System.out.print("Thumbnail Height: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
        System.out.println(thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
        if (!extSegments.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
            for (Iterator iter = extSegments.iterator(); iter.hasNext();) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
                JFIFExtensionMarkerSegment extSegment =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
                    (JFIFExtensionMarkerSegment) iter.next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
                extSegment.print();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
        if (iccSegment != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
            iccSegment.print();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * A JFIF extension APP0 marker segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    class JFIFExtensionMarkerSegment extends MarkerSegment {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
        int code;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
        JFIFThumb thumb;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
        private static final int DATA_SIZE = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
        private static final int ID_SIZE = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
        JFIFExtensionMarkerSegment(JPEGBuffer buffer, JPEGImageReader reader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
            super(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
            buffer.bufPtr += ID_SIZE;  // skip the id, we already checked it
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
            code = buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
            buffer.bufAvail -= DATA_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
            if (code == THUMB_JPEG) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
                thumb = new JFIFThumbJPEG(buffer, length, reader);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
                buffer.loadBuf(2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
                int thumbX = buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
                int thumbY = buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
                buffer.bufAvail -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
                // following constructors handle bufAvail
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
                if (code == THUMB_PALETTE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
                    thumb = new JFIFThumbPalette(buffer, thumbX, thumbY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                    thumb = new JFIFThumbRGB(buffer, thumbX, thumbY);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        JFIFExtensionMarkerSegment(Node node) throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            super(JPEG.APP0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
            NamedNodeMap attrs = node.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
            if (attrs.getLength() > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
                code = getAttributeValue(node,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
                                         attrs,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
                                         "extensionCode",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
                                         THUMB_JPEG,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
                                         THUMB_RGB,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
                                         false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
                if (code == THUMB_UNASSIGNED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
                throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
                    ("invalid extensionCode attribute value", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
                code = THUMB_UNASSIGNED;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
            // Now the child
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
            if (node.getChildNodes().getLength() != 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
                throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
                    ("app0JFXX node must have exactly 1 child", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
            Node child = node.getFirstChild();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
            String name = child.getNodeName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
            if (name.equals("JFIFthumbJPEG")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
                if (code == THUMB_UNASSIGNED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
                    code = THUMB_JPEG;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
                thumb = new JFIFThumbJPEG(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
            } else if (name.equals("JFIFthumbPalette")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
                if (code == THUMB_UNASSIGNED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
                    code = THUMB_PALETTE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
                thumb = new JFIFThumbPalette(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
            } else if (name.equals("JFIFthumbRGB")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
                if (code == THUMB_UNASSIGNED) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
                    code = THUMB_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
                thumb = new JFIFThumbRGB(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
                    ("unrecognized app0JFXX child node", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
        JFIFExtensionMarkerSegment(BufferedImage thumbnail)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
            throws IllegalThumbException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
            super(JPEG.APP0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
            ColorModel cm = thumbnail.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
            int csType = cm.getColorSpace().getType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
            if (cm.hasAlpha()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
                throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            if (cm instanceof IndexColorModel) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                code = THUMB_PALETTE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
                thumb = new JFIFThumbPalette(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
            } else if (csType == ColorSpace.TYPE_RGB) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                code = THUMB_RGB;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
                thumb = new JFIFThumbRGB(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
            } else if (csType == ColorSpace.TYPE_GRAY) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
                code = THUMB_JPEG;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
                thumb = new JFIFThumbJPEG(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
                throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
        void setThumbnail(BufferedImage thumbnail) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
                switch (code) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
                case THUMB_PALETTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                    thumb = new JFIFThumbPalette(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
                case THUMB_RGB:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
                    thumb = new JFIFThumbRGB(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
                case THUMB_JPEG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
                    thumb = new JFIFThumbJPEG(thumbnail);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
                    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
            } catch (IllegalThumbException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
                // Should never happen
10419
12c063b39232 7084245: Update usages of InternalError to use exception chaining
sherman
parents: 5506
diff changeset
   766
                throw new InternalError("Illegal thumb in setThumbnail!", e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
        protected Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
            JFIFExtensionMarkerSegment newGuy =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
                (JFIFExtensionMarkerSegment) super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
            if (thumb != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
                newGuy.thumb = (JFIFThumb) thumb.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
            return newGuy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        IIOMetadataNode getNativeNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            IIOMetadataNode node = new IIOMetadataNode("app0JFXX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
            node.setAttribute("extensionCode", Integer.toString(code));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            node.appendChild(thumb.getNativeNode());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
        void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
                   JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
            length = LENGTH_SIZE + DATA_SIZE + thumb.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
            writeTag(ios);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
            byte [] id = {0x4A, 0x46, 0x58, 0x58, 0x00};
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
            ios.write(id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
            ios.write(code);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            thumb.write(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
        void print() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            printTag("JFXX");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            thumb.print();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
     * A superclass for the varieties of thumbnails that can
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
     * be stored in a JFIF extension marker segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
    abstract class JFIFThumb implements Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
        long streamPos = -1L;  // Save the thumbnail pos when reading
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
        abstract int getLength(); // When writing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
        abstract int getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
        abstract int getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
        abstract BufferedImage getThumbnail(ImageInputStream iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                                            JPEGImageReader reader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
            throws IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
        protected JFIFThumb() {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
        protected JFIFThumb(JPEGBuffer buffer) throws IOException{
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
            // Save the stream position for reading the thumbnail later
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            streamPos = buffer.getStreamPosition();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
        abstract void print();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
        abstract IIOMetadataNode getNativeNode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        abstract void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
                            JPEGImageWriter writer) throws IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        protected Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
                return super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
            } catch (CloneNotSupportedException e) {} // won't happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
    abstract class JFIFThumbUncompressed extends JFIFThumb {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
        BufferedImage thumbnail = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
        int thumbWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        int thumbHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
        String name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
        JFIFThumbUncompressed(JPEGBuffer buffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
                              int width,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
                              int height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
                              int skip,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
                              String name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
            super(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
            thumbWidth = width;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            thumbHeight = height;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
            // Now skip the thumbnail data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
            buffer.skipData(skip);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
            this.name = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
        JFIFThumbUncompressed(Node node, String name)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
            throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
            thumbWidth = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            thumbHeight = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
            this.name = name;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
            NamedNodeMap attrs = node.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
            int count = attrs.getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
            if (count > 2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
                throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
                    (name +" node cannot have > 2 attributes", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
            if (count != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
                int value = getAttributeValue(node, attrs, "thumbWidth",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
                                              0, 255, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
                thumbWidth = (value != -1) ? value : thumbWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
                value = getAttributeValue(node, attrs, "thumbHeight",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
                                          0, 255, false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
                thumbHeight = (value != -1) ? value : thumbHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
        JFIFThumbUncompressed(BufferedImage thumb) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
            thumbnail = thumb;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
            thumbWidth = thumb.getWidth();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
            thumbHeight = thumb.getHeight();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
            name = null;  // not used when writing
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        void readByteBuffer(ImageInputStream iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
                            byte [] data,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
                            JPEGImageReader reader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
                            float workPortion,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
                            float workOffset) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
            int progInterval = Math.max((int)(data.length/20/workPortion),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
                                        1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
            for (int offset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                 offset < data.length;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                int len = Math.min(progInterval, data.length-offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
                iis.read(data, offset, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
                offset += progInterval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
                float percentDone = ((float) offset* 100)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
                    / data.length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
                    * workPortion + workOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
                if (percentDone > 100.0F) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
                    percentDone = 100.0F;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
                reader.thumbnailProgress (percentDone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
        int getWidth() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
            return thumbWidth;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
        int getHeight() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
            return thumbHeight;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
        IIOMetadataNode getNativeNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
            IIOMetadataNode node = new IIOMetadataNode(name);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
            node.setAttribute("thumbWidth", Integer.toString(thumbWidth));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
            node.setAttribute("thumbHeight", Integer.toString(thumbHeight));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
            return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
        void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
                   JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
            if ((thumbWidth > MAX_THUMB_WIDTH)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
                || (thumbHeight > MAX_THUMB_HEIGHT)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
                writer.warningOccurred(JPEGImageWriter.WARNING_THUMB_CLIPPED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
            thumbWidth = Math.min(thumbWidth, MAX_THUMB_WIDTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
            thumbHeight = Math.min(thumbHeight, MAX_THUMB_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
            ios.write(thumbWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
            ios.write(thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        void writePixels(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
                         JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
            if ((thumbWidth > MAX_THUMB_WIDTH)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
                || (thumbHeight > MAX_THUMB_HEIGHT)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
                writer.warningOccurred(JPEGImageWriter.WARNING_THUMB_CLIPPED);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
            thumbWidth = Math.min(thumbWidth, MAX_THUMB_WIDTH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
            thumbHeight = Math.min(thumbHeight, MAX_THUMB_HEIGHT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            int [] data = thumbnail.getRaster().getPixels(0, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
                                                          thumbWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
                                                          thumbHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
                                                          (int []) null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
            writeThumbnailData(ios, data, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
        void print() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
            System.out.print(name + " width: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   954
            System.out.println(thumbWidth);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
            System.out.print(name + " height: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
            System.out.println(thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   957
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   958
90ce3da70b43 Initial load
duke
parents:
diff changeset
   959
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   960
90ce3da70b43 Initial load
duke
parents:
diff changeset
   961
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   962
     * A JFIF thumbnail stored as RGB, one byte per channel,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   963
     * interleaved.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   964
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   965
    class JFIFThumbRGB extends JFIFThumbUncompressed {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
90ce3da70b43 Initial load
duke
parents:
diff changeset
   967
        JFIFThumbRGB(JPEGBuffer buffer, int width, int height)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   968
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   969
90ce3da70b43 Initial load
duke
parents:
diff changeset
   970
            super(buffer, width, height, width*height*3, "JFIFthumbRGB");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   971
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   972
90ce3da70b43 Initial load
duke
parents:
diff changeset
   973
        JFIFThumbRGB(Node node) throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   974
            super(node, "JFIFthumbRGB");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   975
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   976
90ce3da70b43 Initial load
duke
parents:
diff changeset
   977
        JFIFThumbRGB(BufferedImage thumb) throws IllegalThumbException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   978
            super(thumb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   979
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   980
90ce3da70b43 Initial load
duke
parents:
diff changeset
   981
        int getLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   982
            return (thumbWidth*thumbHeight*3);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   983
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   984
90ce3da70b43 Initial load
duke
parents:
diff changeset
   985
        BufferedImage getThumbnail(ImageInputStream iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   986
                                   JPEGImageReader reader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   987
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   988
            iis.mark();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   989
            iis.seek(streamPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   990
            DataBufferByte buffer = new DataBufferByte(getLength());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   991
            readByteBuffer(iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   992
                           buffer.getData(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   993
                           reader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   994
                           1.0F,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   995
                           0.0F);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   996
            iis.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   997
90ce3da70b43 Initial load
duke
parents:
diff changeset
   998
            WritableRaster raster =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   999
                Raster.createInterleavedRaster(buffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                                               thumbWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1001
                                               thumbHeight,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
                                               thumbWidth*3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                                               3,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
                                               new int [] {0, 1, 2},
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                                               null);
2381
0afc5d868c46 6631559: Registration of ImageIO plugins should not cause loading of jpeg.dlli and cmm.dll
bae
parents: 2
diff changeset
  1006
            ColorModel cm = new ComponentColorModel(JPEG.JCS.sRGB,
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
                                                    false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
                                                    false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
                                                    ColorModel.OPAQUE,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
                                                    DataBuffer.TYPE_BYTE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
            return new BufferedImage(cm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
                                     raster,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
                                     false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
                                     null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
                   JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
            super.write(ios, writer); // width and height
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
            writePixels(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1024
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
     * A JFIF thumbnail stored as an indexed palette image
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1027
     * using an RGB palette.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1028
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
    class JFIFThumbPalette extends JFIFThumbUncompressed {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        private static final int PALETTE_SIZE = 768;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
        JFIFThumbPalette(JPEGBuffer buffer, int width, int height)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
            super(buffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1035
                  width,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
                  height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1037
                  PALETTE_SIZE + width * height,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
                  "JFIFThumbPalette");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
        JFIFThumbPalette(Node node) throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
            super(node, "JFIFThumbPalette");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
        JFIFThumbPalette(BufferedImage thumb) throws IllegalThumbException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
            super(thumb);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
            IndexColorModel icm = (IndexColorModel) thumbnail.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
            if (icm.getMapSize() > 256) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
                throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
        int getLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
            return (thumbWidth*thumbHeight + PALETTE_SIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
        BufferedImage getThumbnail(ImageInputStream iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
                                   JPEGImageReader reader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
            iis.mark();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
            iis.seek(streamPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
            // read the palette
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
            byte [] palette = new byte [PALETTE_SIZE];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
            float palettePart = ((float) PALETTE_SIZE) / getLength();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
            readByteBuffer(iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
                           palette,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
                           reader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
                           palettePart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                           0.0F);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            DataBufferByte buffer = new DataBufferByte(thumbWidth*thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
            readByteBuffer(iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
                           buffer.getData(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
                           reader,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
                           1.0F-palettePart,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
                           palettePart);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
            iis.read();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
            iis.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
            IndexColorModel cm = new IndexColorModel(8,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
                                                     256,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
                                                     palette,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
                                                     0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1083
                                                     false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1084
            SampleModel sm = cm.createCompatibleSampleModel(thumbWidth,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1085
                                                            thumbHeight);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
            WritableRaster raster =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1087
                Raster.createWritableRaster(sm, buffer, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1088
            return new BufferedImage(cm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1089
                                     raster,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1090
                                     false,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1091
                                     null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1092
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1093
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1094
        void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1095
                   JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1096
            super.write(ios, writer); // width and height
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1097
            // Write the palette (must be 768 bytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
            byte [] palette = new byte[768];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1099
            IndexColorModel icm = (IndexColorModel) thumbnail.getColorModel();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
            byte [] reds = new byte [256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1101
            byte [] greens = new byte [256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1102
            byte [] blues = new byte [256];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1103
            icm.getReds(reds);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1104
            icm.getGreens(greens);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1105
            icm.getBlues(blues);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
            for (int i = 0; i < 256; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1107
                palette[i*3] = reds[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
                palette[i*3+1] = greens[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1109
                palette[i*3+2] = blues[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
            ios.write(palette);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1112
            writePixels(ios, writer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1113
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1114
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1115
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1116
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1117
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
     * A JFIF thumbnail stored as a JPEG stream.  No JFIF or
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
     * JFIF extension markers are permitted.  There is no need
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1120
     * to clip these, but the entire image must fit into a
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
     * single JFXX marker segment.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1123
    class JFIFThumbJPEG extends JFIFThumb {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
        JPEGMetadata thumbMetadata = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
        byte [] data = null;  // Compressed image data, for writing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1126
        private static final int PREAMBLE_SIZE = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1127
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
        JFIFThumbJPEG(JPEGBuffer buffer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
                      int length,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1130
                      JPEGImageReader reader) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1131
            super(buffer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1132
            // Compute the final stream position
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1133
            long finalPos = streamPos + (length - PREAMBLE_SIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1134
            // Set the stream back to the start of the thumbnail
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1135
            // and read its metadata (but don't decode the image)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1136
            buffer.iis.seek(streamPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1137
            thumbMetadata = new JPEGMetadata(false, true, buffer.iis, reader);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1138
            // Set the stream to the computed final position
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1139
            buffer.iis.seek(finalPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1140
            // Clear the now invalid buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1141
            buffer.bufAvail = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1142
            buffer.bufPtr = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1143
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1144
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
        JFIFThumbJPEG(Node node) throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
            if (node.getChildNodes().getLength() > 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1147
                throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1148
                    ("JFIFThumbJPEG node must have 0 or 1 child", node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
            Node child = node.getFirstChild();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
            if (child != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
                String name = child.getNodeName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1153
                if (!name.equals("markerSequence")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1154
                    throw new IIOInvalidTreeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1155
                        ("JFIFThumbJPEG child must be a markerSequence node",
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1156
                         node);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1157
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1158
                thumbMetadata = new JPEGMetadata(false, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1159
                thumbMetadata.setFromMarkerSequenceNode(child);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1160
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1161
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1162
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1163
        JFIFThumbJPEG(BufferedImage thumb) throws IllegalThumbException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1164
            int INITIAL_BUFSIZE = 4096;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1165
            int MAZ_BUFSIZE = 65535 - 2 - PREAMBLE_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1166
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1167
                ByteArrayOutputStream baos =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1168
                    new ByteArrayOutputStream(INITIAL_BUFSIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
                MemoryCacheImageOutputStream mos =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
                    new MemoryCacheImageOutputStream(baos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1172
                JPEGImageWriter thumbWriter = new JPEGImageWriter(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1173
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1174
                thumbWriter.setOutput(mos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1175
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1176
                // get default metadata for the thumb
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1177
                JPEGMetadata metadata =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1178
                    (JPEGMetadata) thumbWriter.getDefaultImageMetadata
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1179
                    (new ImageTypeSpecifier(thumb), null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1180
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1181
                // Remove the jfif segment, which should be there.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1182
                MarkerSegment jfif = metadata.findMarkerSegment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1183
                    (JFIFMarkerSegment.class, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1184
                if (jfif == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1185
                    throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1186
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1187
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1188
                metadata.markerSequence.remove(jfif);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1189
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1190
                /*  Use this if removing leaves a hole and causes trouble
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1191
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1192
                // Get the tree
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1193
                String format = metadata.getNativeMetadataFormatName();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1194
                IIOMetadataNode tree =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1195
                (IIOMetadataNode) metadata.getAsTree(format);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1196
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1197
                // If there is no app0jfif node, the image is bad
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1198
                NodeList jfifs = tree.getElementsByTagName("app0JFIF");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1199
                if (jfifs.getLength() == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1200
                throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1201
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1202
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1203
                // remove the app0jfif node
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1204
                Node jfif = jfifs.item(0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1205
                Node parent = jfif.getParentNode();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1206
                parent.removeChild(jfif);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1207
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1208
                metadata.setFromTree(format, tree);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1209
                */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1210
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1211
                thumbWriter.write(new IIOImage(thumb, null, metadata));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1212
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1213
                thumbWriter.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1214
                // Now check that the size is OK
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1215
                if (baos.size() > MAZ_BUFSIZE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1216
                    throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1217
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1218
                data = baos.toByteArray();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1219
            } catch (IOException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1220
                throw new IllegalThumbException();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1221
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1222
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1223
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1224
        int getWidth() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1225
            int retval = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1226
            SOFMarkerSegment sof =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1227
                (SOFMarkerSegment) thumbMetadata.findMarkerSegment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1228
                (SOFMarkerSegment.class, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1229
            if (sof != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1230
                retval = sof.samplesPerLine;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1231
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1232
            return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1233
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1234
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1235
        int getHeight() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1236
            int retval = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1237
            SOFMarkerSegment sof =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1238
                (SOFMarkerSegment) thumbMetadata.findMarkerSegment
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1239
                (SOFMarkerSegment.class, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1240
            if (sof != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1241
                retval = sof.numLines;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1242
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1243
            return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1244
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1245
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1246
        private class ThumbnailReadListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1247
            implements IIOReadProgressListener {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1248
            JPEGImageReader reader = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1249
            ThumbnailReadListener (JPEGImageReader reader) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1250
                this.reader = reader;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1251
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1252
            public void sequenceStarted(ImageReader source, int minIndex) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1253
            public void sequenceComplete(ImageReader source) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1254
            public void imageStarted(ImageReader source, int imageIndex) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1255
            public void imageProgress(ImageReader source,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1256
                                      float percentageDone) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1257
                reader.thumbnailProgress(percentageDone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1258
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1259
            public void imageComplete(ImageReader source) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1260
            public void thumbnailStarted(ImageReader source,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1261
                int imageIndex, int thumbnailIndex) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1262
            public void thumbnailProgress(ImageReader source, float percentageDone) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1263
            public void thumbnailComplete(ImageReader source) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1264
            public void readAborted(ImageReader source) {}
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1265
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1266
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1267
        BufferedImage getThumbnail(ImageInputStream iis,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1268
                                   JPEGImageReader reader)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1269
            throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1270
            iis.mark();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1271
            iis.seek(streamPos);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1272
            JPEGImageReader thumbReader = new JPEGImageReader(null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1273
            thumbReader.setInput(iis);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1274
            thumbReader.addIIOReadProgressListener
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1275
                (new ThumbnailReadListener(reader));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1276
            BufferedImage ret = thumbReader.read(0, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1277
            thumbReader.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1278
            iis.reset();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1279
            return ret;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1280
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1281
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1282
        protected Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1283
            JFIFThumbJPEG newGuy = (JFIFThumbJPEG) super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1284
            if (thumbMetadata != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1285
                newGuy.thumbMetadata = (JPEGMetadata) thumbMetadata.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1286
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1287
            return newGuy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1288
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1289
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1290
        IIOMetadataNode getNativeNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1291
            IIOMetadataNode node = new IIOMetadataNode("JFIFthumbJPEG");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1292
            if (thumbMetadata != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1293
                node.appendChild(thumbMetadata.getNativeTree());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1294
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1295
            return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1296
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1297
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1298
        int getLength() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1299
            if (data == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1300
                return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1301
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1302
                return data.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1303
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1304
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1305
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1306
        void write(ImageOutputStream ios,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1307
                   JPEGImageWriter writer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1308
            int progInterval = data.length / 20;  // approx. every 5%
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1309
            if (progInterval == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1310
                progInterval = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1311
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1312
            for (int offset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1313
                 offset < data.length;) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1314
                int len = Math.min(progInterval, data.length-offset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1315
                ios.write(data, offset, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1316
                offset += progInterval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1317
                float percentDone = ((float) offset * 100) / data.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1318
                if (percentDone > 100.0F) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1319
                    percentDone = 100.0F;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1320
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1321
                writer.thumbnailProgress (percentDone);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1322
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1323
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1324
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1325
        void print () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1326
            System.out.println("JFIF thumbnail stored as JPEG");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1327
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1328
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1329
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1330
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1331
     * Write out the given profile to the stream, embedded in
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1332
     * the necessary number of APP2 segments, per the ICC spec.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1333
     * This is the only mechanism for writing an ICC profile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1334
     * to a stream.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1335
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1336
    static void writeICC(ICC_Profile profile, ImageOutputStream ios)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1337
        throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1338
        int LENGTH_LENGTH = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1339
        final String ID = "ICC_PROFILE";
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1340
        int ID_LENGTH = ID.length()+1; // spec says it's null-terminated
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1341
        int COUNTS_LENGTH = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1342
        int MAX_ICC_CHUNK_SIZE =
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1343
            65535 - LENGTH_LENGTH - ID_LENGTH - COUNTS_LENGTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1344
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1345
        byte [] data = profile.getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1346
        int numChunks = data.length / MAX_ICC_CHUNK_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1347
        if ((data.length % MAX_ICC_CHUNK_SIZE) != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1348
            numChunks++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1349
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1350
        int chunkNum = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1351
        int offset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1352
        for (int i = 0; i < numChunks; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1353
            int dataLength = Math.min(data.length-offset, MAX_ICC_CHUNK_SIZE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1354
            int segLength = dataLength+COUNTS_LENGTH+ID_LENGTH+LENGTH_LENGTH;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1355
            ios.write(0xff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1356
            ios.write(JPEG.APP2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1357
            MarkerSegment.write2bytes(ios, segLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1358
            byte [] id = ID.getBytes("US-ASCII");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1359
            ios.write(id);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1360
            ios.write(0); // Null-terminate the string
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1361
            ios.write(chunkNum++);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1362
            ios.write(numChunks);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1363
            ios.write(data, offset, dataLength);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1364
            offset += dataLength;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1365
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1366
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1367
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1368
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1369
     * An APP2 marker segment containing an ICC profile.  In the stream
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1370
     * a profile larger than 64K is broken up into a series of chunks.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1371
     * This inner class represents the complete profile as a single objec,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1372
     * combining chunks as necessary.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1373
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1374
    class ICCMarkerSegment extends MarkerSegment {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1375
        ArrayList chunks = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1376
        byte [] profile = null; // The complete profile when it's fully read
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1377
                         // May remain null when writing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1378
        private static final int ID_SIZE = 12;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1379
        int chunksRead;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1380
        int numChunks;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1381
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1382
        ICCMarkerSegment(ICC_ColorSpace cs) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1383
            super(JPEG.APP2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1384
            chunks = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1385
            chunksRead = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1386
            numChunks = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1387
            profile = cs.getProfile().getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1388
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1389
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1390
        ICCMarkerSegment(JPEGBuffer buffer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1391
            super(buffer);  // gets whole segment or fills the buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1392
            if (debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1393
                System.out.println("Creating new ICC segment");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1394
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1395
            buffer.bufPtr += ID_SIZE; // Skip the id
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1396
            buffer.bufAvail -= ID_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1397
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1398
             * Reduce the stored length by the id size.  The stored
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1399
             * length is used to store the length of the profile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1400
             * data only.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1401
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1402
            length -= ID_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1403
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1404
            // get the chunk number
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1405
            int chunkNum = buffer.buf[buffer.bufPtr] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1406
            // get the total number of chunks
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1407
            numChunks = buffer.buf[buffer.bufPtr+1] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1408
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1409
            if (chunkNum > numChunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1410
                throw new IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1411
                    ("Image format Error; chunk num > num chunks");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1412
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1413
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1414
            // if there are no more chunks, set up the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1415
            if (numChunks == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1416
                // reduce the stored length by the two chunk numbering bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1417
                length -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1418
                profile = new byte[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1419
                buffer.bufPtr += 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1420
                buffer.bufAvail-=2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1421
                buffer.readData(profile);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1422
                inICC = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1423
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1424
                // If we store them away, include the chunk numbering bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1425
                byte [] profileData = new byte[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1426
                // Now reduce the stored length by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1427
                // two chunk numbering bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1428
                length -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1429
                buffer.readData(profileData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1430
                chunks = new ArrayList();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1431
                chunks.add(profileData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1432
                chunksRead = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1433
                inICC = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1434
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1435
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1436
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1437
        ICCMarkerSegment(Node node) throws IIOInvalidTreeException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1438
            super(JPEG.APP2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1439
            if (node instanceof IIOMetadataNode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1440
                IIOMetadataNode ourNode = (IIOMetadataNode) node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1441
                ICC_Profile prof = (ICC_Profile) ourNode.getUserObject();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1442
                if (prof != null) {  // May be null
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1443
                    profile = prof.getData();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1444
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1445
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1446
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1447
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1448
        protected Object clone () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1449
            ICCMarkerSegment newGuy = (ICCMarkerSegment) super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1450
            if (profile != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1451
                newGuy.profile = (byte[]) profile.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1452
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1453
            return newGuy;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1454
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1455
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1456
        boolean addData(JPEGBuffer buffer) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1457
            if (debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1458
                System.out.println("Adding to ICC segment");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1459
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1460
            // skip the tag
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1461
            buffer.bufPtr++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1462
            buffer.bufAvail--;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1463
            // Get the length, but not in length
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1464
            int dataLen = (buffer.buf[buffer.bufPtr++] & 0xff) << 8;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1465
            dataLen |= buffer.buf[buffer.bufPtr++] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1466
            buffer.bufAvail -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1467
            // Don't include length itself
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1468
            dataLen -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1469
            // skip the id
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1470
            buffer.bufPtr += ID_SIZE; // Skip the id
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1471
            buffer.bufAvail -= ID_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1472
            /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1473
             * Reduce the stored length by the id size.  The stored
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1474
             * length is used to store the length of the profile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1475
             * data only.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1476
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1477
            dataLen -= ID_SIZE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1478
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1479
            // get the chunk number
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1480
            int chunkNum = buffer.buf[buffer.bufPtr] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1481
            if (chunkNum > numChunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1482
                throw new IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1483
                    ("Image format Error; chunk num > num chunks");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1484
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1485
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1486
            // get the number of chunks, which should match
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1487
            int newNumChunks = buffer.buf[buffer.bufPtr+1] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1488
            if (numChunks != newNumChunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1489
                throw new IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1490
                    ("Image format Error; icc num chunks mismatch");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1491
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1492
            dataLen -= 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1493
            if (debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1494
                System.out.println("chunkNum: " + chunkNum
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1495
                                   + ", numChunks: " + numChunks
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1496
                                   + ", dataLen: " + dataLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1497
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1498
            boolean retval = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1499
            byte [] profileData = new byte[dataLen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1500
            buffer.readData(profileData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1501
            chunks.add(profileData);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1502
            length += dataLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1503
            chunksRead++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1504
            if (chunksRead < numChunks) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1505
                inICC = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1506
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1507
                if (debug) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1508
                    System.out.println("Completing profile; total length is "
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1509
                                       + length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1510
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1511
                // create an array for the whole thing
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1512
                profile = new byte[length];
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1513
                // copy the existing chunks, releasing them
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1514
                // Note that they may be out of order
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1515
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1516
                int index = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1517
                for (int i = 1; i <= numChunks; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1518
                    boolean foundIt = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1519
                    for (int chunk = 0; chunk < chunks.size(); chunk++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1520
                        byte [] chunkData = (byte []) chunks.get(chunk);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1521
                        if (chunkData[0] == i) { // Right one
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1522
                            System.arraycopy(chunkData, 2,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1523
                                             profile, index,
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1524
                                             chunkData.length-2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1525
                            index += chunkData.length-2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1526
                            foundIt = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1527
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1528
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1529
                    if (foundIt == false) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1530
                        throw new IIOException
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1531
                            ("Image Format Error: Missing ICC chunk num " + i);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1532
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1533
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1534
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1535
                chunks = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1536
                chunksRead = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1537
                numChunks = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1538
                inICC = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1539
                retval = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1540
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1541
            return retval;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1542
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1543
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1544
        IIOMetadataNode getNativeNode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1545
            IIOMetadataNode node = new IIOMetadataNode("app2ICC");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1546
            if (profile != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1547
                node.setUserObject(ICC_Profile.getInstance(profile));
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1548
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1549
            return node;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1550
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1551
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1552
        /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1553
         * No-op.  Profiles are never written from metadata.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1554
         * They are written from the ColorSpace of the image.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1555
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1556
        void write(ImageOutputStream ios) throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1557
            // No-op
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1558
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1559
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1560
        void print () {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1561
            printTag("ICC Profile APP2");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1562
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1563
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1564
}