1/*
2 * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.imageio.plugins.jpeg;
27
28import javax.imageio.metadata.IIOMetadataNode;
29import javax.imageio.stream.ImageOutputStream;
30import javax.imageio.metadata.IIOInvalidTreeException;
31
32import java.io.IOException;
33import java.io.UnsupportedEncodingException;
34
35import org.w3c.dom.Node;
36
37/**
38 * A Comment marker segment.  Retains an array of bytes representing the
39 * comment data as it is read from the stream.  If the marker segment is
40 * constructed from a String, then local default encoding is assumed
41 * when creating the byte array.  If the marker segment is created from
42 * an {@code IIOMetadataNode}, the user object, if present is
43 * assumed to be a byte array containing the comment data.  If there is
44 * no user object then the comment attribute is used to create the
45 * byte array, again assuming the default local encoding.
46 */
47class COMMarkerSegment extends MarkerSegment {
48    private static final String ENCODING = "ISO-8859-1";
49
50    /**
51     * Constructs a marker segment from the given buffer, which contains
52     * data from an {@code ImageInputStream}.  This is used when
53     * reading metadata from a stream.
54     */
55    COMMarkerSegment(JPEGBuffer buffer) throws IOException {
56        super(buffer);
57        loadData(buffer);
58    }
59
60    /**
61     * Constructs a marker segment from a String.  This is used when
62     * modifying metadata from a non-native tree and when transcoding.
63     * The default encoding is used to construct the byte array.
64     */
65    COMMarkerSegment(String comment) {
66        super(JPEG.COM);
67        data = comment.getBytes(); // Default encoding
68    }
69
70    /**
71     * Constructs a marker segment from a native tree node.  If the node
72     * is an {@code IIOMetadataNode} and contains a user object,
73     * that object is used rather than the string attribute.  If the
74     * string attribute is used, the default encoding is used.
75     */
76    COMMarkerSegment(Node node) throws IIOInvalidTreeException{
77        super(JPEG.COM);
78        if (node instanceof IIOMetadataNode) {
79            IIOMetadataNode ourNode = (IIOMetadataNode) node;
80            data = (byte []) ourNode.getUserObject();
81        }
82        if (data == null) {
83            String comment =
84                node.getAttributes().getNamedItem("comment").getNodeValue();
85            if (comment != null) {
86                data = comment.getBytes(); // Default encoding
87            } else {
88                throw new IIOInvalidTreeException("Empty comment node!", node);
89            }
90        }
91    }
92
93    /**
94     * Returns the array encoded as a String, using ISO-Latin-1 encoding.
95     * If an application needs another encoding, the data array must be
96     * consulted directly.
97     */
98    String getComment() {
99        try {
100            return new String (data, ENCODING);
101        } catch (UnsupportedEncodingException e) {}  // Won't happen
102        return null;
103    }
104
105    /**
106     * Returns an {@code IIOMetadataNode} containing the data array
107     * as a user object and a string encoded using ISO-8895-1, as an
108     * attribute.
109     */
110    IIOMetadataNode getNativeNode() {
111        IIOMetadataNode node = new IIOMetadataNode("com");
112        node.setAttribute("comment", getComment());
113        if (data != null) {
114            node.setUserObject(data.clone());
115        }
116        return node;
117    }
118
119    /**
120     * Writes the data for this segment to the stream in
121     * valid JPEG format, directly from the data array.
122     */
123    void write(ImageOutputStream ios) throws IOException {
124        length = 2 + data.length;
125        writeTag(ios);
126        ios.write(data);
127    }
128
129    void print() {
130        printTag("COM");
131        System.out.println("<" + getComment() + ">");
132    }
133}
134