/////////////////////////////// Image processing ////////////////////////////// // Performs the image conversion/processing/etc that you want to perform void ProcessImage(ImageDataType imageData) { byte[] pixels = imageData.pixels; int width = imageData.width; int height = imageData.height; int i; // remember that we're working in BGR color ... so the actual width is 3x int w = width * 3; byte tmp; // sanity check if ((pixels == null) || (width == 0) || (height == 0)) { return; } // you could use imageData.getName() to perform different analysis in the same // program .... // as an example ... swap red and blue values for (i = 0; i < w * height; i += 3) { // normal image format is BGR ... first byte is blue tmp = pixels[i]; // swap red and blue pixels[i] = pixels[i + 2]; pixels[i + 2] = tmp; } // note this this is an inplace filter so you don't need an additional image array // but you've now corrupted the original image ... }
/////////////////////////////// Main ////////////////////////////////////////// // This method will be called when the thread is started. public void run() { // holds the variable name being sent by RR string varName; // holds the received and prehaps processed image data byte[] varData = new byte[DATA_BUFFER]; // byte array for incoming integer number byte[] number = new byte[4]; IPAddress myIp = IPAddress.Parse("127.0.0.1"); IPEndPoint ipEnd = new IPEndPoint(myIp, SERVER_PORTNUM); Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server.Bind(ipEnd); Console.WriteLine("RoboRealm Java Socket Server v0.0.1 Listening On Port "+SERVER_PORTNUM+"....\n"); ImageDataType imageData = new ImageDataType(); while (isRunning) { Console.WriteLine("Waiting ...\n"); server.Listen(10); Socket client = server.Accept(); Console.WriteLine("Connected.\n"); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, TIMEOUT); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, TIMEOUT); NetworkStream networkStream = new NetworkStream(client); BinaryWriter binaryWriter = new BinaryWriter(networkStream); BinaryReader binaryReader = new BinaryReader(networkStream); imageData.count=0; int len=0; while (true) { imageData.count++; // *1* Comment the next line out after debugging is done!! Console.WriteLine("Processing "+imageData.count+"\r"); try { while (true) { // read in variable length binaryReader.Read(number, 0, 4); len = byteToInt(number); // if length <=0 on the variable name then we're done if (len<=0) break; // read in variable name but if the name is longer than 64 characters // then grab the first 64 chars only byte[] varNameChar = new byte[len]; binaryReader.Read(varNameChar, 0, len); varName = System.Text.Encoding.ASCII.GetString(varNameChar); // read in the variable's data length binaryReader.Read(number, 0, 4); len = byteToInt(number); // if the data is less than 1024 read it in now .. if (len<DATA_BUFFER) { binaryReader.Read(varData, 0, len); } // handle this variable if (ProcessVariable(binaryWriter, binaryReader, imageData, varName, varData, len)<0) { len=-1; break; } } //Done collecting variables. // termination signal -1 on attribute length if (len==-1) break; // process image ProcessImage(imageData); //Returning variables. // Write out the processed image back to RoboRealm using stdout. // You can also write back any other variables to use in // other parts of the program. // The format is the same as the input. ReturnBytesVariable(binaryWriter, "image", imageData.pixels, imageData.width*imageData.height*3); //Returned image; // Send back the count as an example of how to feed back variables into RoboRealm ReturnIntVariable(binaryWriter, "count", imageData.count); // write out end of message binaryWriter.Write(intToByte(0)); // flush all data back to RR binaryWriter.Flush(); // continue by waiting for next image request } catch (Exception e) { //ignore any timeout errors by closing connection and restarting //Console.WriteLine("Caught exception " + e.ToString() + "\n" + e.StackTrace); break; }; } Console.WriteLine("\nDisconnected.\n"); binaryReader.Close(); binaryWriter.Close(); client.Close(); if (len==-1) break; } }
// Parses the variables sent by RR into the appropriate structure. You can add // your own processing routines here to handle other variables that may get sent. int ProcessVariable(BinaryWriter writer, BinaryReader reader, ImageDataType imageData, string name, byte[] data, int len) { name = name.ToLower(); // determine what we've got if (name.Equals("name")) { imageData.name = name; } else // determine what we've got if (name.Equals("width")) { imageData.width = byteToInt(data); } else if (name.Equals("height")) { imageData.height = byteToInt(data); } else if (name.Equals("image")) { if ((imageData.width==0)||(imageData.height==0)) { ReturnError(writer, "Error - missing image dimensions before image data!"); Console.WriteLine("Error - missing image dimensions before image data!"); return -1; } if (len!=(imageData.width*imageData.height*3)) { ReturnError(writer, "Error - length of data and dimensions of image\n disagree! (width:"+imageData.width+" height:"+imageData.height+" len:"+len+")\n"); Console.WriteLine("Error - length of data and dimensions of image\n disagree! (width:"+imageData.width+" height:"+imageData.height+" len:"+len+")\n"); return -1; } // we only need to allocate once! The program will remain // active for as long as processing continues ... if (imageData.pixels==null) { imageData.pixels = new byte[len]; imageData.allocLen = len; } else { // but we need to check to see if the image size has changed that we have // enough room to load it in if (imageData.allocLen<len) { imageData.pixels = new byte[len]; imageData.allocLen = len; } } // we did not read in the image data yet since it is always > 1024 .. int res; if ((res=readBytes(imageData.pixels, reader, len))!=len) { Console.WriteLine("Error - read failed. Wanted "+len+" bytes but got "+res+"\n"); return -1; } } else { // skip this variable if (len>DATA_BUFFER) { while (len > 0) { reader.Read(); len--; } } } return 1; }
/////////////////////////////// Image processing ////////////////////////////// // Performs the image conversion/processing/etc that you want to perform void ProcessImage(ImageDataType imageData) { byte[] pixels = imageData.pixels; int width = imageData.width; int height = imageData.height; int i; // remember that we're working in BGR color ... so the actual width is 3x int w=width*3; byte tmp; // sanity check if ((pixels==null)||(width==0)||(height==0)) return; // you could use imageData.getName() to perform different analysis in the same // program .... // as an example ... swap red and blue values for (i=0;i<w*height;i+=3) { // normal image format is BGR ... first byte is blue tmp = pixels[i]; // swap red and blue pixels[i] = pixels[i+2]; pixels[i+2] = tmp; } // note this this is an inplace filter so you don't need an additional image array // but you've now corrupted the original image ... }
/////////////////////////////// Main ////////////////////////////////////////// // This method will be called when the thread is started. public void run() { // holds the variable name being sent by RR string varName; // holds the received and prehaps processed image data byte[] varData = new byte[DATA_BUFFER]; // byte array for incoming integer number byte[] number = new byte[4]; IPAddress myIp = IPAddress.Parse("127.0.0.1"); IPEndPoint ipEnd = new IPEndPoint(myIp, SERVER_PORTNUM); Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server.Bind(ipEnd); Console.WriteLine("RoboRealm Java Socket Server v0.0.1 Listening On Port " + SERVER_PORTNUM + "....\n"); ImageDataType imageData = new ImageDataType(); while (isRunning) { Console.WriteLine("Waiting ...\n"); server.Listen(10); Socket client = server.Accept(); Console.WriteLine("Connected.\n"); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, TIMEOUT); client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, TIMEOUT); NetworkStream networkStream = new NetworkStream(client); BinaryWriter binaryWriter = new BinaryWriter(networkStream); BinaryReader binaryReader = new BinaryReader(networkStream); imageData.count = 0; int len = 0; while (true) { imageData.count++; // *1* Comment the next line out after debugging is done!! Console.WriteLine("Processing " + imageData.count + "\r"); try { while (true) { // read in variable length binaryReader.Read(number, 0, 4); len = byteToInt(number); // if length <=0 on the variable name then we're done if (len <= 0) { break; } // read in variable name but if the name is longer than 64 characters // then grab the first 64 chars only byte[] varNameChar = new byte[len]; binaryReader.Read(varNameChar, 0, len); varName = System.Text.Encoding.ASCII.GetString(varNameChar); // read in the variable's data length binaryReader.Read(number, 0, 4); len = byteToInt(number); // if the data is less than 1024 read it in now .. if (len < DATA_BUFFER) { binaryReader.Read(varData, 0, len); } // handle this variable if (ProcessVariable(binaryWriter, binaryReader, imageData, varName, varData, len) < 0) { len = -1; break; } } //Done collecting variables. // termination signal -1 on attribute length if (len == -1) { break; } // process image ProcessImage(imageData); //Returning variables. // Write out the processed image back to RoboRealm using stdout. // You can also write back any other variables to use in // other parts of the program. // The format is the same as the input. ReturnBytesVariable(binaryWriter, "image", imageData.pixels, imageData.width * imageData.height * 3); //Returned image; // Send back the count as an example of how to feed back variables into RoboRealm ReturnIntVariable(binaryWriter, "count", imageData.count); // write out end of message binaryWriter.Write(intToByte(0)); // flush all data back to RR binaryWriter.Flush(); // continue by waiting for next image request } catch (Exception e) { //ignore any timeout errors by closing connection and restarting //Console.WriteLine("Caught exception " + e.ToString() + "\n" + e.StackTrace); break; }; } Console.WriteLine("\nDisconnected.\n"); binaryReader.Close(); binaryWriter.Close(); client.Close(); if (len == -1) { break; } } }
// Parses the variables sent by RR into the appropriate structure. You can add // your own processing routines here to handle other variables that may get sent. int ProcessVariable(BinaryWriter writer, BinaryReader reader, ImageDataType imageData, string name, byte[] data, int len) { name = name.ToLower(); // determine what we've got if (name.Equals("name")) { imageData.name = name; } else // determine what we've got if (name.Equals("width")) { imageData.width = byteToInt(data); } else if (name.Equals("height")) { imageData.height = byteToInt(data); } else if (name.Equals("image")) { if ((imageData.width == 0) || (imageData.height == 0)) { ReturnError(writer, "Error - missing image dimensions before image data!"); Console.WriteLine("Error - missing image dimensions before image data!"); return(-1); } if (len != (imageData.width * imageData.height * 3)) { ReturnError(writer, "Error - length of data and dimensions of image\n disagree! (width:" + imageData.width + " height:" + imageData.height + " len:" + len + ")\n"); Console.WriteLine("Error - length of data and dimensions of image\n disagree! (width:" + imageData.width + " height:" + imageData.height + " len:" + len + ")\n"); return(-1); } // we only need to allocate once! The program will remain // active for as long as processing continues ... if (imageData.pixels == null) { imageData.pixels = new byte[len]; imageData.allocLen = len; } else { // but we need to check to see if the image size has changed that we have // enough room to load it in if (imageData.allocLen < len) { imageData.pixels = new byte[len]; imageData.allocLen = len; } } // we did not read in the image data yet since it is always > 1024 .. int res; if ((res = readBytes(imageData.pixels, reader, len)) != len) { Console.WriteLine("Error - read failed. Wanted " + len + " bytes but got " + res + "\n"); return(-1); } } else { // skip this variable if (len > DATA_BUFFER) { while (len > 0) { reader.Read(); len--; } } } return(1); }