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 public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) { 052 tiles = new BufferedImage[width][height]; 053 054 try { 055 056 socket = new DatagramSocket(localPort); 057 localHost = socket.getLocalAddress(); 058 this.remoteHost = remoteHost; 059 this.remotePort = remotePort; 060 this.localPort = localPort; 061 this.decoder = new DefaultDecoder(); 062 063 new Thread(new Runnable() { 064 @Override 065 public void run() { 066 byte[] buf = new byte[1024]; 067 DatagramPacket p = new DatagramPacket(buf, 1024); 068 try { 069 while (on) { 070 socket.receive(p); 071 072 int length = p.getLength(); 073 074 BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2)); 075 076 if (bufferedImage != null) { 077 078 int x = p.getData()[length - 2]; 079 int y = p.getData()[length - 1]; 080 081 drawTile(x, y, bufferedImage); 082 083 } 084 085 } 086 } 087 catch (IOException e) { 088 LOGGER.log(Level.WARNING, "exception", e); 089 } 090 } 091 }).start(); 092 093 new Thread(new Runnable() { 094 @Override 095 public void run() { 096 byte[] buf = new byte[1024]; 097 DatagramPacket p = new DatagramPacket(buf, 1024); 098 try { 099 while (on) { 100 101 p.setAddress(remoteHost); 102 p.setPort(remotePort); 103 socket.send(p); 104 105 try { 106 Thread.sleep(1000); 107 } 108 catch (InterruptedException e) { 109 LOGGER.log(Level.WARNING, "exception", e); 110 } 111 112 } 113 } 114 catch (IOException e) { 115 LOGGER.log(Level.WARNING, "exception", e); 116 } 117 } 118 }).start(); 119 120 } 121 catch (SocketException e) { 122 LOGGER.log(Level.WARNING, "exception", e); 123 } 124 this.setSize(width, height); 125 } 126 127 public InetAddress getLocalHost() { 128 return localHost; 129 } 130 131 public InetAddress getRemoteHost() { 132 return remoteHost; 133 } 134 135 public int getLocalPort() { 136 return localPort; 137 } 138 139 public int getRemotePort() { 140 return remotePort; 141 } 142 143 public DatagramSocket getDatagramSocket() { 144 return socket; 145 } 146 147 public void drawTile(int x, int y, BufferedImage bufferedImage) { 148 tiles[x][y] = bufferedImage; 149 // repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth); 150 this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this); 151 } 152 153 @Override 154 public void paint(Graphics g) { 155 for (int i = 0; i < tiles.length; i++) { 156 for (int j = 0; j < tiles[0].length; j++) { 157 g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this); 158 } 159 } 160 } 161 162 public ImageDecoder getDecoder() { 163 return decoder; 164 } 165 166 public void setDecoder(ImageDecoder decoder) { 167 this.decoder = decoder; 168 } 169 170 public void stop() { 171 this.on = false; 172 socket.close(); 173 } 174}