001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2008
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.shared.media;
034:
035: import com.flexive.shared.exceptions.FxApplicationException;
036: import com.flexive.shared.media.impl.FxMediaImageMagickEngine;
037: import com.flexive.shared.media.impl.FxMediaNativeEngine;
038: import com.flexive.shared.media.impl.FxUnknownMetadataImpl;
039: import org.apache.commons.lang.StringUtils;
040: import org.apache.commons.logging.Log;
041: import org.apache.commons.logging.LogFactory;
042: import org.apache.sanselan.ImageFormat;
043: import org.apache.sanselan.Sanselan;
044:
045: import java.io.File;
046: import java.io.FileInputStream;
047: import java.io.IOException;
048:
049: /**
050: * Media engine
051: *
052: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
053: * @version $Rev
054: */
055: public class FxMediaEngine {
056: private static final transient Log LOG = LogFactory
057: .getLog(FxMediaEngine.class);
058:
059: /**
060: * Is ImageMagick installed?
061: *
062: * @return if ImageMagick is installed
063: */
064: public static boolean hasImageMagickInstalled() {
065: return FxMediaImageMagickEngine.IM_AVAILABLE;
066: }
067:
068: /**
069: * Get the ImageMagick version as String
070: *
071: * @return ImageMagick version as String
072: */
073: public static String getImageMagickVersion() {
074: return FxMediaImageMagickEngine.IM_VERSION;
075: }
076:
077: /**
078: * We need at least version 6.3.x of ImageMagick to be able to parse identify output
079: *
080: * @return can ImageMagick's identify be used?
081: */
082: public static boolean isImageMagickIdentifySupported() {
083: return FxMediaImageMagickEngine.IM_IDENTIFY_POSSIBLE;
084: }
085:
086: /**
087: * Identify a file, returning metadata
088: *
089: * @param mimeType if not null it will be used to call the correct identify routine
090: * @param file the file to identify
091: * @return metadata
092: */
093: public static FxMetadata identify(String mimeType, File file) {
094: if (mimeType == null) {
095: byte[] header = new byte[5];
096: //read the first 5 bytes
097: if (file.length() > 5) {
098: FileInputStream fis = null;
099: try {
100: fis = new FileInputStream(file);
101: if (fis.read(header, 0, 5) != 5)
102: header = null;
103: } catch (IOException e) {
104: LOG.error(e);
105: } finally {
106: try {
107: if (fis != null)
108: fis.close();
109: } catch (IOException e) {
110: LOG.error(e);
111: }
112: }
113: }
114: mimeType = detectMimeType(header, file.getName());
115: }
116: try {
117: if (mimeType.startsWith("image")) {
118: if (FxMediaImageMagickEngine.IM_IDENTIFY_POSSIBLE) {
119:
120: }
121: //native
122: return FxMediaNativeEngine.identify(mimeType, file);
123: }
124: } catch (FxApplicationException e) {
125: LOG.error(e);
126: }
127: //last resort: unknown
128: return new FxUnknownMetadataImpl(mimeType, file.getName());
129: }
130:
131: /**
132: * Scale an image and return the dimensions (width and height) as int array
133: *
134: * @param original original file
135: * @param scaled scaled file
136: * @param extension extension
137: * @param width desired width
138: * @param height desired height
139: * @return actual width ([0]) and height ([1]) of scaled image
140: * @throws FxApplicationException on errors
141: */
142: public static int[] scale(File original, File scaled,
143: String extension, int width, int height)
144: throws FxApplicationException {
145: if (FxMediaImageMagickEngine.IM_AVAILABLE)
146: return FxMediaImageMagickEngine.scale(original, scaled,
147: extension, width, height);
148: return FxMediaNativeEngine.scale(original, scaled, extension,
149: width, height);
150: }
151:
152: /**
153: * Detect the mimetype of a file based on the first n bytes and the filename
154: *
155: * @param header first n bytes of the file to examine
156: * @return detected mimetype
157: */
158: public static String detectMimeType(byte[] header) {
159: return detectMimeType(header, null);
160: }
161:
162: /**
163: * Detect the mimetype of a file based on the first n bytes and the filename
164: *
165: * @param header first n bytes of the file to examine
166: * @param fileName filename
167: * @return detected mimetype
168: */
169: public static String detectMimeType(byte[] header, String fileName) {
170: if (header != null && header.length > 5) {
171: try {
172: ImageFormat iformat = Sanselan.guessFormat(header);
173: if (iformat.actual) {
174: return "image/" + iformat.extension.toLowerCase();
175: }
176: } catch (Exception e) {
177: LOG.error(e);
178: }
179: }
180: if (!StringUtils.isEmpty(fileName) && fileName.indexOf('.') > 0) {
181: //extension based detection
182: fileName = fileName.trim().toUpperCase();
183: if (fileName.endsWith(".JPG"))
184: return "image/jpeg";
185: if (fileName.endsWith(".GIF"))
186: return "image/gif";
187: if (fileName.endsWith(".PNG"))
188: return "image/png";
189: if (fileName.endsWith(".BMP"))
190: return "image/bmp";
191: if (fileName.endsWith(".DOC") || fileName.endsWith(".DOCX"))
192: return "application/msword";
193: if (fileName.endsWith(".XLS") || fileName.endsWith(".XLSX"))
194: return "application/msexcel";
195: if (fileName.endsWith(".PPT") || fileName.endsWith(".PPTX"))
196: return "application/mspowerpoint";
197: if (fileName.endsWith(".PDF"))
198: return "application/pdf";
199: if (fileName.endsWith(".HTM"))
200: return "text/html";
201: if (fileName.endsWith(".HTML"))
202: return "text/html";
203: if (fileName.endsWith(".TXT"))
204: return "text/plain";
205: if (fileName.endsWith(".ICO"))
206: return "image/vnd.microsoft.icon";
207: }
208: //byte signature based detection
209: if (header != null && header.length > 5 && header[1] == 0x50
210: && header[2] == 0x4E && header[3] == 0x47) { //PNG
211: return "image/png";
212: }
213: return "application/unknown";
214: }
215: }
|