001: /*
002: * Apollo - Motion capture and animation system
003: * Copyright (c) 2005 Apollo
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * as published by the Free Software Foundation; either version 2
008: * of the License, or (at your option) any later version.
009: *
010: * This program is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013: * GNU General Public License for more details.
014: *
015: * You should have received a copy of the GNU General Public License
016: * along with this program; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
018: *
019: * http://www.gnu.org/copyleft/gpl.html
020: *
021: * @author Giovane.Kuhn - brain@netuno.com.br
022: *
023: */
024: package org.apollo;
025:
026: import java.awt.image.BufferedImage;
027: import java.io.File;
028: import java.io.FileNotFoundException;
029: import java.io.FileOutputStream;
030: import java.io.IOException;
031: import java.lang.reflect.InvocationTargetException;
032: import java.util.Map;
033:
034: import javax.media.Buffer;
035: import javax.media.Effect;
036: import javax.media.Format;
037: import javax.media.Processor;
038: import javax.media.control.TrackControl;
039: import javax.media.format.VideoFormat;
040:
041: import org.apollo.datamodel.VideoEffect;
042: import org.apollo.effect.IVideoEffect;
043:
044: import com.sun.image.codec.jpeg.ImageFormatException;
045: import com.sun.image.codec.jpeg.JPEGCodec;
046: import com.sun.image.codec.jpeg.JPEGEncodeParam;
047: import com.sun.image.codec.jpeg.JPEGImageEncoder;
048:
049: /**
050: * Class provides utilities for apollo aplication
051: *
052: * @author Giovane.Kuhn on 06/04/2005
053: */
054: public final class MediaUtil {
055:
056: /** Constant to convert red to gray */
057: private static final float R_GRAY = 0.299f;
058:
059: /** Constant to convert green to gray */
060: private static final float G_GRAY = 0.587f;
061:
062: /** Constant to convert blue to gray */
063: private static final float B_GRAY = 0.114f;
064:
065: private MediaUtil() {
066: // nop
067: }
068:
069: /**
070: * Verifiy if someone format from array matches with parameter <code>in</code>
071: * @param in Format that all formats from array will be matched
072: * @param outs Array of Format
073: * @return Format at <code>outs</code> that matches <code>in</code>, otherwise <code>null</code>
074: */
075: public static Format matches(Format in, Format outs[]) {
076: for (int i = 0; i < outs.length; i++) {
077: if (in.matches(outs[i]))
078: return outs[i];
079: }
080: return null;
081: }
082:
083: /**
084: * Validate if buffer data has correct size and datatype
085: * Credit: example at java.sun.com
086: * @param buffer Buffer that should be validated
087: * @param newSize Size that buffer data should have
088: */
089: public static void validateIntArraySize(Buffer buffer, int newSize) {
090: Object bufferArray = buffer.getData();
091: int[] typedArray;
092:
093: // has correct type and is not null
094: if (bufferArray instanceof int[]) {
095: typedArray = (int[]) bufferArray;
096: // has sufficient capacity
097: if (typedArray.length >= newSize) {
098: return;
099: }
100:
101: // reallocate array
102: int[] tempArray = new int[newSize];
103: System.arraycopy(typedArray, 0, tempArray, 0,
104: typedArray.length);
105: typedArray = tempArray;
106: } else {
107: typedArray = new int[newSize];
108: }
109:
110: buffer.setData(typedArray);
111: return;
112: }
113:
114: /**
115: * Convert a RGB color to gray scale
116: * @param rgb Array of components RBG
117: * @return Gray scale
118: */
119: public static int toGray(int[] rgb) {
120: return (int) (R_GRAY * rgb[0] + G_GRAY * rgb[1] + B_GRAY
121: * rgb[2]);
122: }
123:
124: /**
125: * Create a JPEG image
126: * @param fileName Output file name
127: * @param in Array data
128: * @param inOffset Array offset
129: * @param maxX Image width
130: * @param maxY Image height
131: * @param imageType Use BufferedImage.TYPE_XXX to define image type
132: * @throws ImageFormatException
133: * @throws IOException
134: */
135: public static void generateImage(File fileName, int[] in,
136: int inOffset, int maxX, int maxY, int imageType)
137: throws ImageFormatException, IOException {
138: // Intilizing the File OutPut Stream Right Now the file name is hardcoded but is will as per transactions
139: FileOutputStream fos;
140: try {
141: fos = new java.io.FileOutputStream(fileName);
142: } catch (FileNotFoundException e) {
143: throw new RuntimeException(e);
144: }
145: // Making the object of the Buffered Image which will use to set the pixels horizontally
146: BufferedImage bi = new BufferedImage(maxX, maxY, imageType);
147: // Setting the Pixel Horizontally
148: bi.setRGB(0, 0, maxX, maxY, in, inOffset, maxX);
149: // Taking the object of the encoder which will use to make the jpg image it will match the colorid with the jpg specifications
150: JPEGEncodeParam param = JPEGCodec.getDefaultJPEGEncodeParam(bi);
151: /* Setting the quality of the same <br>
152: * This creates new Quantization tables that replace the currently installed <br>
153: * Quantization tables. It also updates the Component QTable mapping to the default <br>
154: * for the current encoded COLOR_ID. The Created Quantization table varies from very high compression, very low quality, (0.0) to low compression, very high quality (1.0) based on the quality parameter.
155: */
156: param.setQuality(1.0f, true);
157: // This vreates the object of the encoder and encode image data as JPEG Data streams
158: JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(fos);
159: //Encode a BufferedImage as a JPEG data stream
160: encoder.encode(bi, param);
161: }
162:
163: /**
164: * Get video track from processor
165: * @param processor Processor to get video track
166: * @return Video track or <code>null</code> if not exists
167: */
168: public static TrackControl getVideoTrack(Processor processor) {
169: TrackControl[] tc = processor.getTrackControls();
170: for (int i = 0; i < tc.length; i++) {
171: if (tc[i].getFormat() instanceof VideoFormat) {
172: return tc[i];
173: }
174: }
175: return null;
176: }
177:
178: /**
179: * Set user properties to a JMF effect
180: * @param ve Apollo video effect
181: * @param e JMF effect
182: */
183: public static void setEffectProperties(VideoEffect ve, Effect e) {
184: try {
185: for (Map.Entry<String, Object> entry : ve.getProperties()
186: .entrySet()) {
187: // set instance properties
188: String methodName = "set"
189: + String.valueOf(entry.getKey().charAt(0))
190: .toUpperCase()
191: + (entry.getKey().length() == 1 ? "" : entry
192: .getKey().substring(1));
193: ApolloUtil.invokeMethod(methodName, e,
194: new Object[] { entry.getValue() });
195: }
196: } catch (SecurityException e1) {
197: throw new RuntimeException(e1);
198: } catch (IllegalArgumentException e1) {
199: throw new RuntimeException(e1);
200: } catch (NoSuchMethodException e1) {
201: throw new RuntimeException(e1);
202: } catch (IllegalAccessException e1) {
203: throw new RuntimeException(e1);
204: } catch (InvocationTargetException e1) {
205: throw new RuntimeException(e1);
206: }
207:
208: }
209:
210: /**
211: * Get JMF property to user properties
212: * @param ve Apollo video effect
213: * @param e JMF effect
214: */
215: public static void getEffectProperties(VideoEffect ve,
216: IVideoEffect e) {
217: try {
218: for (String name : e.getProperties()) {
219: // get instance properties
220: String methodName = "get"
221: + String.valueOf(name.charAt(0)).toUpperCase()
222: + (name.length() == 1 ? "" : name.substring(1));
223: ve.setProperty(name, ApolloUtil.invokeMethod(
224: methodName, e, null));
225: }
226: } catch (SecurityException e1) {
227: throw new RuntimeException(e1);
228: } catch (IllegalArgumentException e1) {
229: throw new RuntimeException(e1);
230: } catch (NoSuchMethodException e1) {
231: throw new RuntimeException(e1);
232: } catch (IllegalAccessException e1) {
233: throw new RuntimeException(e1);
234: } catch (InvocationTargetException e1) {
235: throw new RuntimeException(e1);
236: }
237:
238: }
239:
240: }
|