001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.imaging.icc;
018
019import java.io.ByteArrayInputStream;
020import java.io.IOException;
021import java.io.InputStream;
022import java.io.PrintWriter;
023import java.io.StringWriter;
024import java.nio.ByteOrder;
025import java.nio.charset.StandardCharsets;
026import java.util.Arrays;
027import java.util.logging.Logger;
028
029import org.apache.commons.imaging.ImageReadException;
030import org.apache.commons.imaging.common.BinaryFunctions;
031
032public class IccTag {
033
034    private static final Logger LOGGER = Logger.getLogger(IccTag.class.getName());
035
036    public final int signature;
037    public final int offset;
038    public final int length;
039    public final IccTagType fIccTagType;
040    private byte[] data;
041    private IccTagDataType itdt;
042    private int dataTypeSignature;
043
044    // public final byte[] data;
045
046    public IccTag(final int signature, final int offset, final int length, final IccTagType fIccTagType) {
047        this.signature = signature;
048        this.offset = offset;
049        this.length = length;
050        this.fIccTagType = fIccTagType;
051    }
052
053    public void setData(final byte[] bytes) throws IOException {
054        data = bytes;
055
056        try (InputStream bis = new ByteArrayInputStream(bytes)) {
057            dataTypeSignature = BinaryFunctions.read4Bytes("data type signature", bis,
058                    "ICC: corrupt tag data", ByteOrder.BIG_ENDIAN);
059
060            itdt = getIccTagDataType(dataTypeSignature);
061            // if (itdt != null)
062            // {
063            // System.out.println("\t\t\t" + "itdt: " + itdt.name);
064            // }
065        }
066    }
067
068    private IccTagDataType getIccTagDataType(final int quad) {
069        for (final IccTagDataType iccTagDataType : IccTagDataTypes.values()) {
070            if (iccTagDataType.getSignature() == quad) {
071                return iccTagDataType;
072            }
073        }
074
075        return null;
076    }
077
078    public void dump(final String prefix) throws ImageReadException, IOException {
079        try (StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw)) {
080            dump(pw, prefix);
081            pw.flush();
082            sw.flush();
083            LOGGER.fine(sw.toString());
084        }
085    }
086
087    public void dump(final PrintWriter pw, final String prefix) throws ImageReadException,
088            IOException {
089        pw.println(prefix
090                + "tag signature: "
091                + Integer.toHexString(signature)
092                + " ("
093                + new String(new byte[] {
094                        (byte) (0xff & (signature >> 24)),
095                        (byte) (0xff & (signature >> 16)),
096                        (byte) (0xff & (signature >> 8)),
097                        (byte) (0xff & (signature >> 0)), }, StandardCharsets.US_ASCII)
098                + ")");
099
100        if (data == null) {
101            pw.println(prefix + "data: " + Arrays.toString(data));
102        } else {
103            pw.println(prefix + "data: " + data.length);
104
105            pw.println(prefix
106                    + "data type signature: "
107                    + Integer.toHexString(dataTypeSignature)
108                    + " ("
109                    + new String(new byte[] {
110                            (byte) (0xff & (dataTypeSignature >> 24)),
111                            (byte) (0xff & (dataTypeSignature >> 16)),
112                            (byte) (0xff & (dataTypeSignature >> 8)),
113                            (byte) (0xff & (dataTypeSignature >> 0)), }, StandardCharsets.US_ASCII)
114                    + ")");
115
116            if (itdt == null) {
117                pw.println(prefix + "IccTagType : " + "unknown");
118            } else {
119                pw.println(prefix + "IccTagType : " + itdt.getName());
120                itdt.dump(prefix, data);
121            }
122
123        }
124
125        pw.println("");
126        pw.flush();
127
128    }
129}