Main Page | Class Hierarchy | Class List | File List | Class Members | Related Pages

JPEGScaler.java

00001 package org.nees.buffalo.video;
00002 
00003 import java.awt.geom.AffineTransform;
00004 import java.awt.image.AffineTransformOp;
00005 import java.awt.image.BufferedImage;
00006 import java.io.ByteArrayInputStream;
00007 import java.io.ByteArrayOutputStream;
00008 import java.io.IOException;
00009 
00010 import com.rbnb.sapi.ChannelMap;
00011 import com.rbnb.sapi.SAPIException;
00012 import com.rbnb.sapi.Sink;
00013 import com.rbnb.sapi.PlugIn;
00014 import com.rbnb.sapi.PlugInChannelMap;
00015 
00016 import com.sun.image.codec.jpeg.JPEGCodec;
00017 import com.sun.image.codec.jpeg.JPEGEncodeParam;
00018 import com.sun.image.codec.jpeg.JPEGImageDecoder;
00019 import com.sun.image.codec.jpeg.JPEGImageEncoder;
00020 
00021 public class JPEGScaler {
00022     
00023     private final String rbnbHostName = "neesub4.eng.buffalo.edu";
00024     private final String rbnbSinkName = "JPEGScalerSink";
00025     private final String rbnbPluginName = "JPEGScaler";
00026     
00027     private final String inputChannelName;
00028     private final String outputChannelName;
00029     
00030     private final int width;
00031     private final int height;
00032 
00033     public JPEGScaler(String inputChannelName, String outputChannelName, int width, int height) {
00034         this.inputChannelName = inputChannelName;
00035         this.outputChannelName = outputChannelName;
00036         this.width = width;
00037         this.height = height;
00038         
00039         execute();      
00040     }
00041     
00042     private void execute() {
00043         // open connection to RBNB server as a sink
00044         Sink sink = new Sink();
00045         try {
00046             sink.OpenRBNBConnection(rbnbHostName, rbnbSinkName);
00047         } catch (SAPIException e) {
00048             System.err.println("Failed to connect to RBNB server for sink.");
00049             return;             
00050         }
00051                 
00052         // select input channel to monitor
00053         ChannelMap sinkRequestMap = new ChannelMap();
00054         int inputChannelIndex = -1;
00055         try {
00056             inputChannelIndex = sinkRequestMap.Add(inputChannelName);
00057         } catch (SAPIException e) {
00058             System.err.println("Failed to add input channel to channel map.");
00059             return;             
00060         }
00061             
00062         PlugIn plugin = new PlugIn();
00063         try {
00064             plugin.OpenRBNBConnection(rbnbHostName, rbnbPluginName);
00065         } catch (SAPIException e) {
00066             System.err.println("Failed to connect to RBNB server for plugin.");
00067             return;             
00068         }
00069         
00070         // select channel to output data to
00071         ChannelMap pluginRegisterMap = new ChannelMap();
00072         int outputChannelIndex = -1;
00073         try {
00074             outputChannelIndex = pluginRegisterMap.Add(outputChannelName);
00075         } catch (SAPIException e) {
00076             System.err.println("Failed to add output channel to channel map.");
00077             return;             
00078         }           
00079         pluginRegisterMap.PutMime(outputChannelIndex, "image/jpeg");
00080         
00081         try {
00082             plugin.Register(pluginRegisterMap);
00083         } catch (SAPIException e) {
00084             System.err.println("Failed to register output channel map.");
00085             return;             
00086         }
00087         
00088         byte[] imageData;
00089         double startTime;
00090         double durationTime;
00091         String timeReference;
00092         int imageIndex = 0;
00093         while (true) {
00094             
00095             PlugInChannelMap pluginFetchMap = null;
00096             try {
00097                 pluginFetchMap = plugin.Fetch(1000);
00098             } catch (SAPIException e) {
00099                 System.err.println("Failed to fetch input data, retrying.");
00100                 continue;
00101             }                   
00102                 
00103             // no data received, try again
00104             if (pluginFetchMap.GetIfFetchTimedOut()) {
00105                 System.err.println("Data request timed out, retrying.");        
00106                 continue;
00107             }
00108 
00109             startTime = pluginFetchMap.GetRequestStart();
00110             durationTime = pluginFetchMap.GetRequestDuration();
00111             timeReference = pluginFetchMap.GetRequestReference();
00112             
00113             try {
00114                 sink.Request(sinkRequestMap, startTime, durationTime, timeReference);
00115             } catch (SAPIException e) {
00116                 System.err.println("Failed to monitor input channel.");
00117                 continue;               
00118             }
00119             
00120             // see if any data is available from source
00121             ChannelMap sinkFetchMap = null;
00122             try {
00123                 sinkFetchMap = sink.Fetch(1000);
00124             } catch (SAPIException e) {
00125                 System.err.println("Failed to fetch input data, retrying.");
00126                 continue;
00127             }       
00128             
00129             // no data received, try again
00130             if (sinkFetchMap.GetIfFetchTimedOut()) {
00131                 System.err.println("Data request timed out, retrying.");        
00132                 continue;
00133             }           
00134 
00135             imageData = sinkFetchMap.GetData(inputChannelIndex);
00136             imageData = scaleImage(imageData, width, height, 0.75f);
00137             if (imageData == null) {
00138                 continue;
00139             }
00140             
00141             // put data in channel map, preserving original time stamp
00142             try {
00143                 pluginFetchMap.PutTime(startTime, durationTime);
00144                 pluginFetchMap.PutDataAsByteArray(outputChannelIndex, imageData);
00145             } catch (SAPIException e) {
00146                 System.err.println("Failed to put output data to channel map, skipping.");
00147                 continue;               
00148             }   
00149                 
00150             // send data to RBNB server
00151             try {
00152                 plugin.Flush(pluginFetchMap);
00153             } catch (SAPIException e) {
00154                 System.err.println("Failed to flush output data to server, skipping.");
00155                 continue;               
00156             }   
00157             
00158         }
00159         
00160     }
00161     
00162     private byte[] scaleImage(byte[] imageData, int width, int height, float quality) {
00163         JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(new ByteArrayInputStream(imageData));
00164     
00165         // decode JPEG image to raw image
00166         BufferedImage bi;
00167         try {
00168             bi = decoder.decodeAsBufferedImage();
00169         } catch (IOException e){
00170             System.err.println("Failed to decode input JPEG image, skipping.");
00171             return null;
00172         }
00173     
00174         // scale both width and height
00175         float widthScale = width/bi.getWidth();
00176         float heightScale = height/bi.getHeight();
00177         AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(widthScale, heightScale), null);
00178         bi = op.filter(bi, null);
00179                 
00180         // encode scaled image as JPEG image                
00181         ByteArrayOutputStream out = new ByteArrayOutputStream();
00182         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
00183         JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
00184         param.setQuality(quality, false);           
00185         try {
00186             encoder.encode(bi, param);
00187         } catch (IOException e) {
00188             System.err.println("Failed to encode output JPEG image, skipping.");
00189             return null;
00190         }               
00191 
00192         // get JPEG image data as byte array
00193         return out.toByteArray();
00194     }
00195 
00196     public static void main(String[] args) {
00197         String inputChannelName = args[0];
00198         String outputChannelName = args[1];
00199         int width = Integer.parseInt(args[2]);
00200         int height = Integer.parseInt(args[2]);
00201         new JPEGScaler(inputChannelName, outputChannelName, width, height);     
00202     }
00203 }

Generated on Tue Mar 23 11:54:24 2004 for Data turbine for NEESGrid by doxygen 1.3.6