001/** 002 * 003 * Copyright the original author or authors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.jingleold.mediaimpl.sshare.api; 018 019import java.awt.Canvas; 020import java.awt.Graphics; 021import java.awt.image.BufferedImage; 022import java.io.ByteArrayInputStream; 023import java.io.IOException; 024import java.net.DatagramPacket; 025import java.net.DatagramSocket; 026import java.net.InetAddress; 027import java.net.SocketException; 028import java.util.logging.Level; 029import java.util.logging.Logger; 030 031/** 032 * UDP Image Receiver. 033 * It uses PNG Tiles into UDP packets. 034 * 035 * @author Thiago Rocha Camargo 036 */ 037public class ImageReceiver extends Canvas { 038 private static final Logger LOGGER = Logger.getLogger(ImageReceiver.class.getName()); 039 040 private static final long serialVersionUID = -7000112305305269025L; 041 private boolean on = true; 042 private DatagramSocket socket; 043 private BufferedImage[][] tiles; 044 private static final int tileWidth = ImageTransmitter.tileWidth; 045 private InetAddress localHost; 046 private InetAddress remoteHost; 047 private int localPort; 048 private int remotePort; 049 private ImageDecoder decoder; 050 051 @SuppressWarnings("this-escape") 052 public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) { 053 tiles = new BufferedImage[width][height]; 054 055 try { 056 057 socket = new DatagramSocket(localPort); 058 localHost = socket.getLocalAddress(); 059 this.remoteHost = remoteHost; 060 this.remotePort = remotePort; 061 this.localPort = localPort; 062 this.decoder = new DefaultDecoder(); 063 064 new Thread(new Runnable() { 065 @Override 066 public void run() { 067 byte[] buf = new byte[1024]; 068 DatagramPacket p = new DatagramPacket(buf, 1024); 069 try { 070 while (on) { 071 socket.receive(p); 072 073 int length = p.getLength(); 074 075 BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2)); 076 077 if (bufferedImage != null) { 078 079 int x = p.getData()[length - 2]; 080 int y = p.getData()[length - 1]; 081 082 drawTile(x, y, bufferedImage); 083 084 } 085 086 } 087 } 088 catch (IOException e) { 089 LOGGER.log(Level.WARNING, "exception", e); 090 } 091 } 092 }).start(); 093 094 new Thread(new Runnable() { 095 @Override 096 public void run() { 097 byte[] buf = new byte[1024]; 098 DatagramPacket p = new DatagramPacket(buf, 1024); 099 try { 100 while (on) { 101 102 p.setAddress(remoteHost); 103 p.setPort(remotePort); 104 socket.send(p); 105 106 try { 107 Thread.sleep(1000); 108 } 109 catch (InterruptedException e) { 110 LOGGER.log(Level.WARNING, "exception", e); 111 } 112 113 } 114 } 115 catch (IOException e) { 116 LOGGER.log(Level.WARNING, "exception", e); 117 } 118 } 119 }).start(); 120 121 } 122 catch (SocketException e) { 123 LOGGER.log(Level.WARNING, "exception", e); 124 } 125 this.setSize(width, height); 126 } 127 128 public InetAddress getLocalHost() { 129 return localHost; 130 } 131 132 public InetAddress getRemoteHost() { 133 return remoteHost; 134 } 135 136 public int getLocalPort() { 137 return localPort; 138 } 139 140 public int getRemotePort() { 141 return remotePort; 142 } 143 144 public DatagramSocket getDatagramSocket() { 145 return socket; 146 } 147 148 public void drawTile(int x, int y, BufferedImage bufferedImage) { 149 tiles[x][y] = bufferedImage; 150 // repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth); 151 this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this); 152 } 153 154 @Override 155 public void paint(Graphics g) { 156 for (int i = 0; i < tiles.length; i++) { 157 for (int j = 0; j < tiles[0].length; j++) { 158 g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this); 159 } 160 } 161 } 162 163 public ImageDecoder getDecoder() { 164 return decoder; 165 } 166 167 public void setDecoder(ImageDecoder decoder) { 168 this.decoder = decoder; 169 } 170 171 public void stop() { 172 this.on = false; 173 socket.close(); 174 } 175}