001/*
002 * (C) Copyright 2007-2019 Nuxeo (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 */
019
020package org.nuxeo.ecm.platform.picture;
021
022import java.util.Arrays;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026
027/**
028 * Helper to handle the UNDEFINED Exif data type.
029 *
030 * @see <a href="https://www.leadtools.com/help/leadtools/v15/main/api/dllaux/exifcomments.htm">Exif Comments</a>
031 * @author btatar
032 */
033public class ExifHelper {
034
035    public static final Log log = LogFactory.getLog(ExifHelper.class);
036
037    // the ASCII data format
038    public static final byte[] ASCII = { 65, 83, 67, 73, 73, 0, 0, 0 };
039
040    // the JIS data format
041    public static final byte[] JIS = { 74, 73, 83, 0, 0, 0, 0, 0 };
042
043    // the UNDEFINED data format
044    public static final byte[] UNDEFINED = { 0, 0, 0, 0, 0, 0, 0, 0 };
045
046    private ExifHelper() {
047    }
048
049    /**
050     * Method used to perform the decode of the <b>Exif User comment</b> data type. The first eight bytes specify the
051     * data format, and the remainder of the comment is in the specified format.The first eight bytes can be any of the
052     * following cases: 65, 83, 67, 73, 73, 0, 0, 0 = ASCII 74, 73, 83, 0, 0, 0, 0, 0 = JIS 0, 0, 0, 0, 0, 0, 0, 0 =
053     * UNDEFINED
054     *
055     * @param rawBytes the user comment represented as a byte array
056     * @return the user comment as a String on the format retrieved from the data type.
057     */
058    public static String decodeUndefined(byte[] rawBytes) {
059
060        byte[] dataType = extractBytes(rawBytes, 0, 8);
061        if (Arrays.equals(ASCII, dataType)) {
062            if (rawBytes.length <= 8) {
063                return "";
064            }
065            return new String(extractBytes(rawBytes, 8, rawBytes.length - 1));
066        } else if (Arrays.equals(JIS, dataType)) {
067            log.warn("The Japanese data type encoding is not supported yet");
068            return "";
069        } else if (Arrays.equals(UNDEFINED, dataType)) {
070            log.debug("Undefined data type encoding");
071            return "";
072        } else {
073            log.debug("Unknown data type encoding");
074            return "";
075        }
076    }
077
078    /**
079     * Extracts the bytes from the received byte array. The first argument represents the starting location (zero-based)
080     * and the second argument represent the ending location which is not zero based.
081     *
082     * @param bytes the byte array
083     * @param beginIndex the begin index which is zero based
084     * @param endIndex the end index which is not zero based
085     */
086    public static byte[] extractBytes(byte[] bytes, int beginIndex, int endIndex) {
087        byte[] result = new byte[endIndex - beginIndex];
088        int count = 0;
089        for (int i = beginIndex; i < endIndex; i++) {
090            result[count++] = bytes[i];
091        }
092        return result;
093    }
094
095}