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;
028
029/**
030 * UDP Image Receiver.
031 * It uses PNG Tiles into UDP packets.
032 *
033 * @author Thiago Rocha Camargo
034 */
035public class ImageReceiver extends Canvas {
036
037        private static final long serialVersionUID = -7000112305305269025L;
038        private boolean on = true;
039    private DatagramSocket socket;
040    private BufferedImage[][] tiles;
041    private static final int tileWidth = ImageTransmitter.tileWidth;
042    private InetAddress localHost;
043    private InetAddress remoteHost;
044    private int localPort;
045    private int remotePort;
046    private ImageDecoder decoder;
047
048    public ImageReceiver(final InetAddress remoteHost, final int remotePort, final int localPort, int width, int height) {
049        tiles = new BufferedImage[width][height];
050
051        try {
052
053            socket = new DatagramSocket(localPort);
054            localHost = socket.getLocalAddress();
055            this.remoteHost = remoteHost;
056            this.remotePort = remotePort;
057            this.localPort = localPort;
058            this.decoder = new DefaultDecoder();
059
060            new Thread(new Runnable() {
061                public void run() {
062                    byte[] buf = new byte[1024];
063                    DatagramPacket p = new DatagramPacket(buf, 1024);
064                    try {
065                        while (on) {
066                            socket.receive(p);
067
068                            int length = p.getLength();
069
070                            BufferedImage bufferedImage = decoder.decode(new ByteArrayInputStream(p.getData(), 0, length - 2));
071
072                            if (bufferedImage != null) {
073
074                                int x = p.getData()[length - 2];
075                                int y = p.getData()[length - 1];
076
077                                drawTile(x, y, bufferedImage);
078
079                            }
080
081                        }
082                    }
083                    catch (IOException e) {
084                        e.printStackTrace();
085                    }
086                }
087            }).start();
088
089            new Thread(new Runnable() {
090                public void run() {
091                    byte[] buf = new byte[1024];
092                    DatagramPacket p = new DatagramPacket(buf, 1024);
093                    try {
094                        while (on) {
095
096                            p.setAddress(remoteHost);
097                            p.setPort(remotePort);
098                            socket.send(p);
099
100                            try {
101                                Thread.sleep(1000);
102                            }
103                            catch (InterruptedException e) {
104                                e.printStackTrace();
105                            }
106
107                        }
108                    }
109                    catch (IOException e) {
110                        e.printStackTrace();
111                    }
112                }
113            }).start();
114
115        }
116        catch (SocketException e) {
117            e.printStackTrace();
118        }
119        this.setSize(width, height);
120    }
121
122    public InetAddress getLocalHost() {
123        return localHost;
124    }
125
126    public InetAddress getRemoteHost() {
127        return remoteHost;
128    }
129
130    public int getLocalPort() {
131        return localPort;
132    }
133
134    public int getRemotePort() {
135        return remotePort;
136    }
137
138    public DatagramSocket getDatagramSocket() {
139        return socket;
140    }
141
142    public void drawTile(int x, int y, BufferedImage bufferedImage) {
143        tiles[x][y] = bufferedImage;
144        //repaint(x * tileWidth, y * tileWidth, tileWidth, tileWidth);
145        this.getGraphics().drawImage(bufferedImage, tileWidth * x, tileWidth * y, this);
146    }
147
148    public void paint(Graphics g) {
149        for (int i = 0; i < tiles.length; i++) {
150            for (int j = 0; j < tiles[0].length; j++) {
151                g.drawImage(tiles[i][j], tileWidth * i, tileWidth * j, this);
152            }
153        }
154    }
155
156    public ImageDecoder getDecoder() {
157        return decoder;
158    }
159
160    public void setDecoder(ImageDecoder decoder) {
161        this.decoder = decoder;
162    }
163
164    public void stop(){
165        this.on=false;
166        socket.close();
167    }
168}