001/*
002 * (C) Copyright 2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 * $Id$
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 * <p>
030 * See {@link http ://www.leadtools.com/help/leadtools/v15/Main/API/Dllaux/ExifComments.htm}.
031 *
032 * @author btatar
033 */
034public class ExifHelper {
035
036    public static final Log log = LogFactory.getLog(ExifHelper.class);
037
038    // the ASCII data format
039    public static final byte[] ASCII = { 65, 83, 67, 73, 73, 0, 0, 0 };
040
041    // the JIS data format
042    public static final byte[] JIS = { 74, 73, 83, 0, 0, 0, 0, 0 };
043
044    // the UNDEFINED data format
045    public static final byte[] UNDEFINED = { 0, 0, 0, 0, 0, 0, 0, 0 };
046
047    private ExifHelper() {
048    }
049
050    /**
051     * Method used to perform the decode of the <b>Exif User comment</b> data type. The first eight bytes specify the
052     * data format, and the remainder of the comment is in the specified format.The first eight bytes can be any of the
053     * 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 =
054     * UNDEFINED
055     *
056     * @param rawBytes the user comment represented as a byte array
057     * @return the user comment as a String on the format retrieved from the data type.
058     */
059    public static String decodeUndefined(byte[] rawBytes) {
060
061        byte[] dataType = extractBytes(rawBytes, 0, 8);
062        if (Arrays.equals(ASCII, dataType)) {
063            if (rawBytes.length <= 8) {
064                return "";
065            }
066            return new String(extractBytes(rawBytes, 8, rawBytes.length - 1));
067        } else if (Arrays.equals(JIS, dataType)) {
068            log.warn("The Japanese data type encoding is not supported yet");
069            return "";
070        } else if (Arrays.equals(UNDEFINED, dataType)) {
071            log.debug("Undefined data type encoding");
072            return "";
073        } else {
074            log.debug("Unknown data type encoding");
075            return "";
076        }
077    }
078
079    /**
080     * Extracts the bytes from the received byte array. The first argument represents the starting location (zero-based)
081     * and the second argument represent the ending location which is not zero based.
082     *
083     * @param bytes the byte array
084     * @param beginIndex the begin index which is zero based
085     * @param endIndex the end index which is not zero based
086     */
087    public static byte[] extractBytes(byte[] bytes, int beginIndex, int endIndex) {
088        byte[] result = new byte[endIndex - beginIndex];
089        int count = 0;
090        for (int i = beginIndex; i < endIndex; i++) {
091            result[count++] = bytes[i];
092        }
093        return result;
094    }
095
096}