View Javadoc

1   package de.desy.video.sw;
2   
3   // big memory for testing:
4   // 	-Xms512m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m
5   
6   
7   import java.awt.Frame;
8   import java.awt.Graphics;
9   import java.awt.Canvas;
10  import java.awt.Image;
11  import java.awt.Toolkit;
12  import java.awt.Color;
13  import java.awt.event.ComponentEvent;
14  import java.awt.event.WindowEvent;
15  import java.awt.event.WindowAdapter;
16  import java.awt.event.ComponentAdapter;
17  import java.awt.event.MouseMotionAdapter;
18  import java.awt.event.MouseAdapter;
19  import java.awt.event.MouseEvent;
20  import javax.swing.JPanel;
21  import java.awt.GridBagLayout;
22  import java.awt.BorderLayout;
23  import java.awt.Dimension;
24  import javax.swing.JRadioButton;
25  import java.awt.GridBagConstraints;
26  import javax.swing.SwingConstants;
27  import javax.swing.JTextField;
28  import javax.swing.JCheckBox;
29  import java.awt.event.KeyEvent;
30  import java.awt.image.MemoryImageSource;
31  import java.awt.HeadlessException;
32  import java.awt.Point;
33  
34  import javax.swing.JLabel;
35  import javax.swing.JButton;
36  import java.awt.ComponentOrientation;
37  import javax.swing.BorderFactory;
38  import javax.swing.border.BevelBorder;
39  
40  import de.desy.tine.client.TLink;
41  import de.desy.tine.dataUtils.TDataType;
42  import de.desy.tine.definitions.TAccess;
43  import de.desy.tine.definitions.TMode;
44  import de.desy.tine.client.*;
45  //import de.desy.tine.dataUtils.*;
46  //import de.desy.tine.definitions.*;
47  import de.desy.tine.types.*;
48  
49  import java.awt.Insets;
50  import java.awt.AlphaComposite;
51  import java.awt.Composite;
52  import javax.swing.JOptionPane;
53  
54  //import java.awt.FileDialog;
55  import javax.swing.JFileChooser;
56  import javax.swing.filechooser.FileNameExtensionFilter;
57  
58  import java.io.File;
59  import java.text.DateFormat;
60  import java.text.SimpleDateFormat;
61  
62  
63  /**
64   * @deprecated 
65   */
66  public final class CFastImageDisplayer extends Frame implements TLinkCallback {
67  
68  	private static final long serialVersionUID = 1L;
69  	private java.awt.image.BufferStrategy m_FlipStrategy=null;
70  	private JPanel jControlPanel = null;
71  	private JRadioButton jRBColorGreyscale = null;
72  	private JRadioButton jRBColorPITZ = null;
73  	private JRadioButton jRBColorJet = null;
74  	private JPanel jControlSubPanel = null;
75  	private JCheckBox jCBOverlay = null;
76  	private JCheckBox jCBAOIZoom = null;
77  	private JCheckBox jCBKeepAspectRatio = null;
78  	private JPanel jControlSubPanel2 = null;
79  	private JLabel jLabelAddress = null;
80  	private JTextField jTFAddress = null;
81  	private JPanel jControlPanel3 = null;
82  	private JButton jBStart = null;
83  	private JButton jBStop = null;
84  	private JButton jBSaveAsPNG = null;
85  	private JButton jBQuit = null;
86  	private Canvas m_VideoCanvas = null;
87  
88  	private boolean m_bOverlayEnabled;
89  	private boolean m_bVideoCanvasMouseInOverlay;
90  	private boolean m_bVideoCanvasMouseInCanvas;
91  	private boolean m_bVideoCanvasMouseLeftButtonDown;
92  	private boolean m_bAOIZoom;
93  	private boolean m_bKeepAspectRatioEnabled;
94  	private boolean m_bTransferRunning=false;
95  	private boolean m_bFalsecolorEnabled=true;
96  	private CFastImageDisplayer m_selfRef=null;
97  	//TINE
98  	private TLink m_vidLink = null;  //  @jve:decl-index=0:
99  
100 	private final int minx = 592;
101 	private final int miny = 211; // 127 + 2x42 OSD;
102 	
103 	// buffers to work with
104 	IMAGE m_srcImgHdr = null;  //  @jve:decl-index=0:
105 	byte[] m_dstBuf = null;
106 	byte[] m_srcBuf = null;
107 
108 	int[] m_DisplayImageBuffer = null;// = new int[hdr.width*hdr.height];
109 	int[] m_ColorLookupTableArray = null; //mapping from
110 	CColorLookupTable m_CColorLookupTable = null;
111 
112 	private long m_lastframenumber=-1;
113 	private long m_droppedframes=0;
114 	private long m_receivedframes=0;
115 	private double m_ratio = -0.001;
116 	
117 	Image m_img=null;  //  @jve:decl-index=0:
118 	MemoryImageSource m_mis=null;  //  @jve:decl-index=0:
119 	
120 	int m_iColorMode = CColorLookupTable.FALSEPITZ;
121 	boolean m_bDoUpdateColorLookupTable = true;
122 	CVideoHeader3 m_Hdr = null;  //  @jve:decl-index=0:
123 	
124 	/**
125 	 * This is the default constructor
126 	 */
127 
128 	// SW!  String aDefaultStartupServer 
129 	public CFastImageDisplayer() {
130 		super();
131 
132 		m_selfRef = this;
133 		
134 		initialize();
135 		
136 		//pack();
137 		this.setVisible(true);
138 		m_VideoCanvas.createBufferStrategy(2);
139 		m_FlipStrategy = m_VideoCanvas.getBufferStrategy();
140 		
141 		m_CColorLookupTable = new CColorLookupTable();
142 		
143 	}
144 
145 	private void QuitCleanupApplication()
146 	{
147 		System.out.println("Cleaning up TINE transfer (if necessary)...");
148 		doStopTransfer();
149 		System.out.println("TINE transfer cleaned up.");
150 		
151 		System.exit(0);
152 	}
153 	
154 	/**
155 	 * This method initializes this
156 	 * 
157 	 * @return void
158 	 */
159 	private void initialize() {
160 		this.setSize(559, 387);
161 		this.setMinimumSize(new Dimension(minx, miny));
162 		this.setTitle("jtDVD - java tine Digital Video Display");
163 
164 		m_VideoCanvas = new Canvas();
165 		m_VideoCanvas.setBackground(new Color(80,80,80));
166 		m_VideoCanvas.setBounds(5, 5, 200, 200);
167 		m_VideoCanvas.setIgnoreRepaint(true);
168 		m_VideoCanvas.addMouseListener( new MouseAdapter() {
169 			public void mouseExited(MouseEvent e)
170 			{
171 				boolean old = m_bVideoCanvasMouseInOverlay; 
172 				m_bVideoCanvasMouseInOverlay = false;
173 				m_bVideoCanvasMouseInCanvas = false;
174 				//m_bVideoCanvasMouseLeftButtonDown = false;
175 				//System.out.println("Mouse exited.");
176 				if (old == true) repaintAnything();
177 			}
178 			
179 			public void mouseEntered(MouseEvent e)
180 			{
181 				boolean old = m_bVideoCanvasMouseInOverlay; 
182 				//m_bVideoCanvasMouseInOverlay = true;
183 				m_bVideoCanvasMouseInCanvas = true;
184 				//m_bVideoCanvasMouseLeftButtonDown = false;
185 				//System.out.println("Mouse exited.");
186 				if (old == true) repaintAnything();
187 			}
188 			
189 			public void mousePressed(MouseEvent e)
190 			{
191 				//if (e.getModifiers() == MouseEvent.BUTTON1_DOWN_MASK)
192 					m_bVideoCanvasMouseLeftButtonDown = true;
193 			
194 			}
195 	          
196 			public void mouseReleased(MouseEvent e)
197 			{
198 				//if (e.getModifiers() == MouseEvent.BUTTON1_DOWN_MASK)
199 					m_bVideoCanvasMouseLeftButtonDown = false;
200 		
201 			}
202 			
203 		});
204 		
205 		
206 		m_VideoCanvas.addMouseMotionListener( new MouseMotionAdapter() {
207 			public void mouseMoved(MouseEvent e) 
208 			{
209 				//int xpos = e.getX();
210 				int ypos = e.getY();
211 				
212 				//boolean old = m_bVideoCanvasMouseInOverlay; 
213 								
214 				if (((ypos>0) && (ypos<50)) ||((ypos > m_VideoCanvas.getHeight()-50) && (ypos < m_VideoCanvas.getHeight())))
215 					m_bVideoCanvasMouseInOverlay = true;
216 				
217 				if (((ypos<=0) || (ypos >= m_VideoCanvas.getHeight())))				
218 					m_bVideoCanvasMouseInOverlay = false;
219 
220 				m_bVideoCanvasMouseInCanvas = true;
221 
222 				if (m_bTransferRunning == false) repaintAnything();
223 				
224 				//if (old != m_bMouseInOverlay) repaintAnything();
225 				
226 			}
227 		});
228 		
229 		this.add(m_VideoCanvas, BorderLayout.CENTER);
230 		this.add(getJControlPanel(), BorderLayout.SOUTH);
231 
232 		jRBColorGreyscale.setSelected(false);
233 		jRBColorPITZ.setSelected(true);
234 		jRBColorJet.setSelected(false);
235 		
236 		m_iColorMode = CColorLookupTable.FALSEPITZ;
237 		m_bDoUpdateColorLookupTable = true;
238 		
239 		jCBOverlay.setSelected(false);
240 		m_bOverlayEnabled = false;
241 		m_bVideoCanvasMouseInOverlay = false;
242 		m_bVideoCanvasMouseInCanvas = false;
243 		m_bVideoCanvasMouseLeftButtonDown = false;
244 		
245 		jCBAOIZoom.setSelected(false);
246 		m_bAOIZoom = false;
247 		jCBKeepAspectRatio.setSelected(true);
248 		
249 		jBStop.setEnabled(false);
250 		jBSaveAsPNG.setEnabled(false);
251 		
252 		this.addWindowListener(new WindowAdapter(){
253 			public void windowClosed(WindowEvent arg0) {
254 				// super.windowClosed(arg0);
255 				//System.out.println("windowClosed");
256 			}
257 			
258 			public void windowClosing(WindowEvent arg0) {
259 				//System.out.println("windowClosing");
260 				super.windowClosing(arg0);
261 				QuitCleanupApplication();
262 				
263 			}
264 		});
265 		
266 		this.addComponentListener(new ComponentAdapter(){
267 			public void componentResized(ComponentEvent arg0) 
268 			{
269 				repaint();
270 			}
271 
272 			public void componentMoved(ComponentEvent arg0) 
273 			{
274 				repaint();
275 			}
276 
277 			public void componentShown(ComponentEvent arg0)
278 			{
279 				repaint();
280 			}
281 		});
282 	}
283 
284 	private AlphaComposite makeComposite(float alpha) 
285 	{
286 		int type = AlphaComposite.SRC_OVER;
287 		return(AlphaComposite.getInstance(type, alpha));
288 	}
289 
290 	
291 	//public synchronized void updateImage( Image img, long aFrameNumber )
292 	public void updateImage()
293 	{
294 	
295 		if (m_Hdr == null) return;
296 		
297 		
298 	    Graphics g=null;
299 	    do 
300 	    {
301 	    	// The following loop ensures that the contents of the drawing buffer
302 	        // are consistent in case the underlying surface was recreated
303 	        do 
304 	        {
305 	        	try 
306 	        	{
307 	    	    	g = (java.awt.Graphics2D) m_FlipStrategy.getDrawGraphics();
308 	    			java.awt.Graphics2D g2d= (java.awt.Graphics2D)g;
309 	    			
310     				m_VideoCanvas.paint(g);
311 	    			
312 	    			if (m_img != null)
313 	    			{
314     					java.awt.Rectangle imgR = new java.awt.Rectangle();
315     					java.awt.Rectangle srcR = new java.awt.Rectangle();
316     					java.awt.Rectangle dstR = new java.awt.Rectangle();;
317     					java.awt.Rectangle dstROrig = new java.awt.Rectangle();;
318 
319     					imgR.x = 0;
320     					imgR.y = 0;
321     					imgR.width = m_Hdr.frameHeader.sourceWidth;
322     					imgR.height = m_Hdr.frameHeader.sourceHeight;
323     						
324     					srcR.x = m_Hdr.frameHeader.xStart;
325     					srcR.y = m_Hdr.frameHeader.yStart;
326     					srcR.width = m_Hdr.frameHeader.aoiWidth;
327     					srcR.height = m_Hdr.frameHeader.aoiHeight;
328     					if (srcR.width == -1) srcR.width = imgR.width;
329     					if (srcR.height == -1) srcR.height = imgR.height;
330     					    					
331     					dstROrig.x = 2;
332     					dstROrig.y = 2;
333     					dstROrig.width = m_VideoCanvas.getWidth()-4;
334     					dstROrig.height = m_VideoCanvas.getHeight()-4;
335 
336     					dstR.x = 2;
337     					dstR.y = 2;
338     					dstR.width = m_VideoCanvas.getWidth()-4;
339     					dstR.height = m_VideoCanvas.getHeight()-4;
340     					
341     					//dstR = dstROrig;
342     					
343 						if (m_bKeepAspectRatioEnabled == true)
344 	    				{
345     					    double whratiovideo = 1.0;
346     						if (imgR.height > 0) whratiovideo = ((double)imgR.width)/((double)imgR.height);
347 
348 	    					for (;;)
349 	    					{
350 	    						dstR.height = (int) Math.round(((double)dstR.width)/whratiovideo);
351 	    						if (dstR.height > dstROrig.height) 
352 	    						{ 
353 	    							dstR.width--; 
354 	    							continue; 
355 	    						}
356 	    						else 
357 									if (dstR.width <= dstROrig.width) break; else dstR.width = dstROrig.width-1;
358 	    					}
359 
360 	    					dstR.x=dstROrig.x+((dstROrig.width-dstR.width)/2);
361 	    					dstR.y=dstROrig.y+((dstROrig.height-dstR.height)/2);
362 	    				}
363 	    				
364 
365     					
366 	    				// after: now width and height are adjusted properly to canvas for whole big image
367     					if ((m_bAOIZoom == false) && ((srcR.width != imgR.width) || (srcR.height != imgR.height)))
368 	    				{
369     	       				g2d.setColor(new Color(0,0,0)); // DARK_
370     	       				g2d.fillRect(dstR.x, dstR.y, dstR.width, dstR.height);
371 	    				}
372 
373     					if (m_bAOIZoom == true)
374     					{
375     						
376     						if (m_bKeepAspectRatioEnabled == true)
377     						{
378     							int widthaoi = srcR.width;
379     							int heightaoi = srcR.height;
380         						
381         						
382     							double whratioaoi = 1.0;
383     							if (heightaoi > 0) whratioaoi = ((double)widthaoi)/((double)heightaoi);
384 
385     							//heightaoi = height;
386     							widthaoi = dstROrig.width;
387     							
388     							for (;;)
389     							{
390     								heightaoi = (int) Math.round(((double)widthaoi)/whratioaoi);
391     								if (heightaoi > dstROrig.height) 
392     								{ 
393     									widthaoi--; 
394     									continue;
395     								}
396     								else
397     									if (widthaoi <= dstROrig.width) break; 
398     									else 
399     									{
400     										widthaoi = dstROrig.width;
401     									}
402     							}
403 
404     							dstR.width = widthaoi;
405     	    					dstR.height = heightaoi;
406    							
407     						}
408 
409 	    					dstR.x=dstROrig.x+((dstROrig.width-dstR.width)/2);
410 	    					dstR.y=dstROrig.y+((dstROrig.height-dstR.height)/2);
411     					}
412     					else
413     					{
414    							double wscale_full = (dstR.width*1.0/imgR.width*1.0);
415    							double hscale_full = (dstR.height*1.0/imgR.height*1.0);
416 
417    							dstR.width = (int) Math.round(srcR.width*wscale_full); 
418    							dstR.height = (int) Math.round(srcR.height*hscale_full);
419    							
420    							dstR.x+=((int) (srcR.x*wscale_full));
421    							dstR.y+=((int) (srcR.y*hscale_full));
422     					}
423 	    				
424     					g2d.drawImage(m_img, dstR.x, dstR.y, dstR.width, dstR.height, null);
425 	    				
426     	    			String sAddPixelValue = "";
427     	    			
428     	    			if ((m_bOverlayEnabled == true) || (m_bVideoCanvasMouseInOverlay == true))
429     	    			{
430     	    				if ((m_bVideoCanvasMouseInCanvas == true) && (m_bVideoCanvasMouseLeftButtonDown == true))
431     	    				{
432     	    					sAddPixelValue = "";
433     	    					try{
434     	    						Point p = m_VideoCanvas.getMousePosition();
435     	    						if (p != null)
436     	    						{
437     	    	    					int pixelindex = 0; 
438 
439     	    	    					sAddPixelValue += "  (out of dimension)";
440 
441     	    	    					if (((p.x>=dstR.x) && (p.x<=(dstR.x+dstR.width))) && ((p.y>=dstR.y) && (p.y<=(dstR.y+dstR.height))))
442     	    	    					{
443         	    	    					// do coordinate transform, src, dst
444     	    	    						
445     	    	    						double dst2srcWidthRelation = 1.0*srcR.width / dstR.width;
446     	    	    						double dst2srcHeightRelation =  1.0*srcR.height / dstR.height;
447     	    	    						    	    	    						
448     	    	    						int pixelx = (int) ((1.0*(p.x-dstR.x))*dst2srcWidthRelation);
449     	    	    						int pixely = (int) ((1.0*(p.y-dstR.y))*dst2srcHeightRelation);
450     	    	    						if (pixelx >= srcR.width) pixelx = srcR.width-1; 
451     	    	    						if (pixely >= srcR.height) pixely = srcR.height-1;
452     	    	    							    	    						
453     	    	    						pixelindex = (srcR.width*pixely+pixelx)*m_Hdr.frameHeader.bytesPerPixel;
454     	    	    						
455     		    	    					sAddPixelValue = "  px("+(pixelx+1+srcR.x)+","+(pixely+1+srcR.y)+") = ";
456     		    	    					// debug:
457     		    	    					//sAddPixelValue = "  ("+p.x+"/"+p.y+")   px("+(pixelx+1+srcR.x)+","+(pixely+1+srcR.y)+") = ";
458     	    	    						
459     	    	    						if (m_Hdr.frameHeader.imageFormat == CVideoHeader3.CF_IMAGE_FORMAT_GRAY)
460     	    	    						{
461     	    	    							long pxvalue = ((long)m_dstBuf[pixelindex])&0xff;
462     	    	    							if (m_Hdr.frameHeader.bytesPerPixel > 1) pxvalue |= (((long)m_dstBuf[pixelindex+1])&0xff)<<8;
463     	    	    							if (m_Hdr.frameHeader.bytesPerPixel > 2) pxvalue |= (((long)m_dstBuf[pixelindex+2])&0xff)<<16;
464     	    	    							if (m_Hdr.frameHeader.bytesPerPixel > 3) pxvalue |= (((long)m_dstBuf[pixelindex+3])&0xff)<<24;
465 
466     	    	    							int maxpxvalue = (1 << m_Hdr.frameHeader.effectiveBitsPerPixel)-1;
467     	    	    								
468     	    	    							sAddPixelValue += pxvalue+" (out of "+maxpxvalue+")";
469     	    	    						}
470     	    	    						else if (m_Hdr.frameHeader.imageFormat == CVideoHeader3.CF_IMAGE_FORMAT_RGB)
471     	    	    						{
472     	    	    							long redvalue = ((long)m_dstBuf[pixelindex])&0xff;
473     	    	    							long greenvalue = ((long)m_dstBuf[pixelindex+1])&0xff;
474     	    	    							long bluevalue = ((long)m_dstBuf[pixelindex+2])&0xff;
475       	    							
476     	    	    							sAddPixelValue += "("+redvalue+"/"+greenvalue+"/"+bluevalue+")";
477     	    	    						}
478     	    	    						else
479     	    	    						{
480     	    	    							sAddPixelValue += "(unknown)";
481     	    	    						}
482     	    	    					}
483     	    							
484     	    						}
485     	    					}
486     	    					catch( HeadlessException ex1 )
487     	    					{
488     	    					}
489     	    					
490     	    					
491     	    				}
492     	    				
493     	    			}
494     	    			
495     	    			if ((m_bOverlayEnabled == true) || (m_bVideoCanvasMouseInOverlay == true))
496     	    			{
497     	       				Composite originalComposite = g2d.getComposite();	       				
498     	       				g2d.setColor(new Color(190,190,190)); // DARK_
499     	       				g2d.setComposite(makeComposite(0.85F));
500     	       				g2d.fillRect(2, 2, m_VideoCanvas.getWidth()-4, 40 );
501     	       				g2d.fillRect(2, m_VideoCanvas.getHeight()-42, m_VideoCanvas.getWidth()-4, 40 );	       				
502     	       				g2d.setComposite(originalComposite);
503     	       					       				
504     	       				g2d.setColor(new Color(0,0,0));
505     	       				
506     	       				String s = "Source: "+m_Hdr.sourceHeader.cameraPortName+" ("+CVideoHeader3.formatToString(m_Hdr.frameHeader.sourceFormat)+")";
507     	       				g2d.drawString(s, 10, 16);
508     	       				
509     	       				s = "Size: "+m_Hdr.frameHeader.sourceWidth+" px * "+m_Hdr.frameHeader.sourceHeight+" px";
510     	       				
511     	       				if ((m_Hdr.frameHeader.aoiWidth != -1) || (m_Hdr.frameHeader.aoiHeight != -1))
512     	       				{
513     	       					s+="  (AOI: L "+m_Hdr.frameHeader.xStart+", T "+m_Hdr.frameHeader.yStart+
514     	       								", W "+m_Hdr.frameHeader.aoiWidth+", H "+m_Hdr.frameHeader.aoiHeight+" )";
515     	       				}
516     	       				else
517     	       					s+="  (AOI: none)";
518     	       				g2d.drawString(s,10,34);
519     	       				
520     	       				DateFormat dfmt = new SimpleDateFormat("HH:mm:ss.SSS");
521     	       				
522     	       				s = "# "+m_Hdr.frameHeader.frameNumber+" - "+dfmt.format(m_Hdr.getTimestampAsDate());
523     	       				g2d.drawString(s, m_VideoCanvas.getWidth()-g2d.getFontMetrics().stringWidth(s)-10, 16);
524     	       				
525     	       				s = "Drop: "+m_droppedframes+" ("+String.format("%4.3f", 
526     	       						new java.lang.Object[]{Double.valueOf(m_ratio*100.0)})+"%)";
527     	       				g2d.drawString(s, m_VideoCanvas.getWidth()-g2d.getFontMetrics().stringWidth(s)-10, 34);
528     	       				
529     	       				s = "Format: "+CVideoHeader3.formatToString(m_Hdr.frameHeader.imageFormat);
530     	       				s += sAddPixelValue;
531     	       				g2d.drawString(s, 10, m_VideoCanvas.getHeight()-26 );
532     	       				
533     	       				s = "Flags: "+CVideoHeader3.flagsToString(m_Hdr.frameHeader.imageFlags);
534     	       				g2d.drawString(s, 10, m_VideoCanvas.getHeight()-8 );
535     	       				
536     	       				double rot = m_Hdr.frameHeader.imageRotation; 
537     	       				
538            					double rotAbs = Math.abs(rot);
539     	       				
540            					s = "Rotation: "+String.format("%4.2f", 
541     	       						new java.lang.Object[]{Double.valueOf(rotAbs)})+"%";
542            					
543            					if (rot > 0.0) s += " cw";
544            					else if (rot < 0.0) s += " ccw";
545 
546            					g2d.drawString(s, m_VideoCanvas.getWidth()-g2d.getFontMetrics().stringWidth(s)-10, m_VideoCanvas.getHeight()-8 );
547     	       				
548     	       				
549     	    			}
550 	    			
551 	    			}
552 	    			
553        				
554 	    	    } 
555 	        	catch( Exception ex )
556 	        	{
557 	        		ex.printStackTrace();
558 	        	}
559 	    	    finally 
560 	    	    {
561 	    	        g.dispose();
562 	    	    }
563 	        }
564 	        while (m_FlipStrategy.contentsRestored());
565 
566 	        // Display the buffer
567 	        m_FlipStrategy.show();
568 
569 	        // Repeat the rendering if the drawing buffer was lost
570 	    } 
571 	    while (m_FlipStrategy.contentsLost());
572 	}
573 	
574 	public void update(Graphics g)
575 	{
576 		paint(g);		
577 	}
578 	
579 	public void repaintAnything()
580 	{
581 		updateImage();
582 		repaint();
583 	}
584 	
585 	public void paint(Graphics g)
586 	{
587 		if (m_bTransferRunning == false) 
588 		{
589 			updateImage();
590 			repaint();
591 		}
592 		super.paint(g);
593 	}
594 
595 	/*
596 	private void RepaintCanvas()
597 	{
598 		Graphics g = null;
599 		try {
600 			if (m_FlipStrategy != null)
601 			{
602 				g = (java.awt.Graphics2D) m_FlipStrategy.getDrawGraphics();
603 				m_VideoCanvas.paint(g);
604 			}
605 		}
606 		catch( Exception ex )
607 		{
608 			ex.printStackTrace();
609 		}
610 		finally
611 		{
612 			if (g != null) g.dispose();
613 		}
614 	}
615 	*/
616 	/**
617 	 * This method initializes jControlPanel	
618 	 * 	
619 	 * @return javax.swing.JPanel	
620 	 */
621 	private JPanel getJControlPanel() {
622 		if (jControlPanel == null) {
623 			GridBagConstraints gridBagConstraints21 = new GridBagConstraints();
624 			gridBagConstraints21.gridx = 3;
625 			gridBagConstraints21.insets = new Insets(2, 0, 2, 0);
626 			gridBagConstraints21.gridheight = 1;
627 			gridBagConstraints21.gridwidth = 0;
628 			gridBagConstraints21.ipadx = 0;
629 			gridBagConstraints21.anchor = GridBagConstraints.EAST;
630 			gridBagConstraints21.weighty = 1.0;
631 			gridBagConstraints21.gridy = 2;
632 			GridBagConstraints gridBagConstraints13 = new GridBagConstraints();
633 			gridBagConstraints13.gridx = 3;
634 			gridBagConstraints13.insets = new Insets(0, 0, 0, 0);
635 			gridBagConstraints13.ipadx = 0;
636 			gridBagConstraints13.ipady = 0;
637 			gridBagConstraints13.weighty = 1.0;
638 			gridBagConstraints13.anchor = GridBagConstraints.EAST;
639 			gridBagConstraints13.gridwidth = 1;
640 			gridBagConstraints13.gridy = 1;
641 			GridBagConstraints gridBagConstraints10 = new GridBagConstraints();
642 			gridBagConstraints10.gridx = 3;
643 			gridBagConstraints10.anchor = GridBagConstraints.EAST;
644 			gridBagConstraints10.gridy = 0;
645 			GridBagConstraints gridBagConstraints3 = new GridBagConstraints();
646 			gridBagConstraints3.gridx = 2;
647 			gridBagConstraints3.gridy = 0;
648 			GridBagConstraints gridBagConstraints7 = new GridBagConstraints();
649 			gridBagConstraints7.gridx = 2;
650 			gridBagConstraints7.ipadx = 0;
651 			gridBagConstraints7.gridy = 2;
652 			GridBagConstraints gridBagConstraints4 = new GridBagConstraints();
653 			gridBagConstraints4.gridx = 2;
654 			gridBagConstraints4.gridy = 1;
655 			GridBagConstraints gridBagConstraints2 = new GridBagConstraints();
656 			gridBagConstraints2.gridx = 0;
657 			gridBagConstraints2.ipadx = 13;
658 			gridBagConstraints2.gridy = 2;
659 			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
660 			gridBagConstraints1.gridx = 0;
661 			gridBagConstraints1.ipadx = 10;
662 			gridBagConstraints1.insets = new Insets(0, 0, 6, 0);
663 			gridBagConstraints1.gridy = 1;
664 			GridBagConstraints gridBagConstraints = new GridBagConstraints();
665 			gridBagConstraints.gridx = 0;
666 			gridBagConstraints.gridwidth = 1;
667 			gridBagConstraints.ipadx = 43;
668 			gridBagConstraints.insets = new Insets(0, 0, 7, 0);
669 			gridBagConstraints.gridy = 0;
670 			jControlPanel = new JPanel();
671 			jControlPanel.setLayout(new GridBagLayout());
672 			jControlPanel.setPreferredSize(new Dimension(290, 100));
673 			jControlPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
674 			jControlPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
675 			jControlPanel.add(getJRBColorGreyscale(), gridBagConstraints);
676 			jControlPanel.add(getJRBColorPITZ(), gridBagConstraints1);
677 			jControlPanel.add(getJRBColorJet(), gridBagConstraints2);
678 			jControlPanel.add(getJControlSubPanel(), gridBagConstraints4);
679 			jControlPanel.add(getJCBKeepAspectRatio(), gridBagConstraints7);
680 			jControlPanel.add(getJControlSubPanel2(), gridBagConstraints3);
681 			jControlPanel.add(getJControlPanel3(), gridBagConstraints10);
682 			jControlPanel.add(getJBSaveAsPNG(), gridBagConstraints13);
683 			jControlPanel.add(getJBQuit(), gridBagConstraints21);
684 		}
685 		return jControlPanel;
686 	}
687 
688 	/**
689 	 * This method initializes jRBColorGreyscale	
690 	 * 	
691 	 * @return javax.swing.JRadioButton	
692 	 */
693 	private JRadioButton getJRBColorGreyscale() {
694 		if (jRBColorGreyscale == null) {
695 			jRBColorGreyscale = new JRadioButton();
696 			jRBColorGreyscale.setText("Grayscale");
697 			jRBColorGreyscale.setHorizontalTextPosition(SwingConstants.TRAILING);
698 			jRBColorGreyscale.setMnemonic(KeyEvent.VK_UNDEFINED);
699 			jRBColorGreyscale.setHorizontalAlignment(SwingConstants.LEFT);
700 			jRBColorGreyscale.addActionListener(new java.awt.event.ActionListener() {
701 				public void actionPerformed(java.awt.event.ActionEvent e) {
702 					jRBColorPITZ.setSelected(false);
703 					jRBColorJet.setSelected(false);
704 					if (jRBColorGreyscale.isSelected() == false) jRBColorGreyscale.setSelected(true);
705 					m_iColorMode = CColorLookupTable.GRAYSCALE;
706 					m_bDoUpdateColorLookupTable = true;
707 
708 					repaint();
709 				}
710 			});
711 		}
712 		return jRBColorGreyscale;
713 	}
714 
715 	/**
716 	 * This method initializes jRBColorPITZ	
717 	 * 	
718 	 * @return javax.swing.JRadioButton	
719 	 */
720 	private JRadioButton getJRBColorPITZ() {
721 		if (jRBColorPITZ == null) {
722 			jRBColorPITZ = new JRadioButton();
723 			jRBColorPITZ.setText("PITZ False Color");
724 			jRBColorPITZ.setMnemonic(KeyEvent.VK_UNDEFINED);
725 			jRBColorPITZ.addActionListener(new java.awt.event.ActionListener() {
726 				public void actionPerformed(java.awt.event.ActionEvent e) {
727 					jRBColorJet.setSelected(false);
728 					jRBColorGreyscale.setSelected(false);
729 					if (jRBColorPITZ.isSelected() == false) jRBColorPITZ.setSelected(true);
730 					m_iColorMode = CColorLookupTable.FALSEPITZ;
731 					m_bDoUpdateColorLookupTable = true;
732 
733 					repaint();
734 				}
735 			});
736 		}
737 		return jRBColorPITZ;
738 	}
739 
740 	/**
741 	 * This method initializes jRBColorJet	
742 	 * 	
743 	 * @return javax.swing.JRadioButton	
744 	 */
745 	private JRadioButton getJRBColorJet() {
746 		if (jRBColorJet == null) {
747 			jRBColorJet = new JRadioButton();
748 			jRBColorJet.setName("");
749 			jRBColorJet.setText("JET False Color");
750 			jRBColorJet.addActionListener(new java.awt.event.ActionListener() {
751 				public void actionPerformed(java.awt.event.ActionEvent e) {
752 					
753 					jRBColorPITZ.setSelected(false);
754 					jRBColorGreyscale.setSelected(false);
755 					if (jRBColorJet.isSelected() == false) jRBColorJet.setSelected(true);
756 					m_iColorMode = CColorLookupTable.FALSEJET;
757 					m_bDoUpdateColorLookupTable = true;
758 
759 					repaint();
760 				}
761 			});
762 		}
763 		return jRBColorJet;
764 	}
765 
766 	/**
767 	 * This method initializes jControlSubPanel	
768 	 * 	
769 	 * @return javax.swing.JPanel	
770 	 */
771 	private JPanel getJControlSubPanel() {
772 		if (jControlSubPanel == null) {
773 			GridBagConstraints gridBagConstraints6 = new GridBagConstraints();
774 			gridBagConstraints6.gridx = 1;
775 			gridBagConstraints6.gridwidth = 0;
776 			gridBagConstraints6.gridheight = 0;
777 			gridBagConstraints6.gridy = 0;
778 			GridBagConstraints gridBagConstraints5 = new GridBagConstraints();
779 			gridBagConstraints5.gridx = 0;
780 			gridBagConstraints5.ipadx = 57;
781 			gridBagConstraints5.gridy = 0;
782 			jControlSubPanel = new JPanel();
783 			jControlSubPanel.setLayout(new GridBagLayout());
784 			jControlSubPanel.setPreferredSize(new Dimension(270, 20));
785 			jControlSubPanel.add(getJCBOverlay(), gridBagConstraints5);
786 			jControlSubPanel.add(getJCBAOIZoom(), gridBagConstraints6);
787 		}
788 		return jControlSubPanel;
789 	}
790 
791 	/**
792 	 * This method initializes jCBOverlay	
793 	 * 	
794 	 * @return javax.swing.JCheckBox	
795 	 */
796 	private JCheckBox getJCBOverlay() {
797 		if (jCBOverlay == null) {
798 			jCBOverlay = new JCheckBox();
799 			jCBOverlay.setMnemonic(KeyEvent.VK_UNDEFINED);
800 			jCBOverlay.setText("Overlay always on");
801 			jCBOverlay.addItemListener(new java.awt.event.ItemListener() {
802 				public void itemStateChanged(java.awt.event.ItemEvent e) {
803 					if (m_bOverlayEnabled == true) 
804 						m_bOverlayEnabled = false; 
805 					else
806 						m_bOverlayEnabled = true;
807 
808 					repaint();
809 				}
810 				
811 			});
812 		}
813 		return jCBOverlay;
814 	}
815 
816 	/**
817 	 * This method initializes jCBAOIZoom	
818 	 * 	
819 	 * @return javax.swing.JCheckBox	
820 	 */
821 	private JCheckBox getJCBAOIZoom() {
822 		if (jCBAOIZoom == null) {
823 			jCBAOIZoom = new JCheckBox();
824 			jCBAOIZoom.setText("AOI Zoom");
825 			jCBAOIZoom.setMnemonic(KeyEvent.VK_UNDEFINED);
826 			jCBAOIZoom.addItemListener(new java.awt.event.ItemListener() {
827 				public void itemStateChanged(java.awt.event.ItemEvent e) {
828 					if (m_bAOIZoom == true) 
829 						m_bAOIZoom = false; 
830 					else
831 						m_bAOIZoom = true;
832 
833 					repaint();
834 				}
835 				
836 			});
837 			
838 			
839 		}
840 		return jCBAOIZoom;
841 	}
842 
843 	/**
844 	 * This method initializes jCBKeepAspectRatio	
845 	 * 	
846 	 * @return javax.swing.JCheckBox	
847 	 */
848 	private JCheckBox getJCBKeepAspectRatio() {
849 		if (jCBKeepAspectRatio == null) {
850 			jCBKeepAspectRatio = new JCheckBox();
851 			jCBKeepAspectRatio.setMnemonic(KeyEvent.VK_UNDEFINED);
852 			jCBKeepAspectRatio.setPreferredSize(new Dimension(265, 24));
853 			jCBKeepAspectRatio.setText("Keep Aspect Ratio");
854 			jCBKeepAspectRatio.addItemListener(new java.awt.event.ItemListener() {
855 				public void itemStateChanged(java.awt.event.ItemEvent e) {
856 					if (m_bKeepAspectRatioEnabled == true) 
857 						m_bKeepAspectRatioEnabled = false; 
858 					else
859 						m_bKeepAspectRatioEnabled = true;
860 					
861 					repaint();
862 				}
863 			});
864 
865 		}
866 		return jCBKeepAspectRatio;
867 	}
868 
869 	/**
870 	 * This method initializes jControlSubPanel2	
871 	 * 	
872 	 * @return javax.swing.JPanel	
873 	 */
874 	private JPanel getJControlSubPanel2() {
875 		if (jControlSubPanel2 == null) {
876 			GridBagConstraints gridBagConstraints9 = new GridBagConstraints();
877 			gridBagConstraints9.fill = GridBagConstraints.VERTICAL;
878 			gridBagConstraints9.gridy = 0;
879 			gridBagConstraints9.weightx = 1.0;
880 			gridBagConstraints9.gridx = 1;
881 			GridBagConstraints gridBagConstraints8 = new GridBagConstraints();
882 			gridBagConstraints8.gridx = 0;
883 			gridBagConstraints8.anchor = GridBagConstraints.WEST;
884 			gridBagConstraints8.ipadx = 5;
885 			gridBagConstraints8.gridy = 0;
886 			jLabelAddress = new JLabel();
887 			jLabelAddress.setText("    Address:");
888 			jControlSubPanel2 = new JPanel();
889 			jControlSubPanel2.setLayout(new GridBagLayout());
890 			jControlSubPanel2.setPreferredSize(new Dimension(280, 20));
891 			jControlSubPanel2.add(jLabelAddress, gridBagConstraints8);
892 			jControlSubPanel2.add(getJTFAddress(), gridBagConstraints9);
893 		}
894 		return jControlSubPanel2;
895 	}
896 
897 	/**
898 	 * This method initializes jTFAddress	
899 	 * 	
900 	 * @return javax.swing.JTextField	
901 	 */
902 	private JTextField getJTFAddress() {
903 		if (jTFAddress == null) {
904 			jTFAddress = new JTextField();
905 			jTFAddress.setPreferredSize(new Dimension(200, 20));
906 			jTFAddress.addActionListener(new java.awt.event.ActionListener() {
907 			public void actionPerformed(java.awt.event.ActionEvent e) 
908 			{
909 				jBStart.doClick();
910 			}
911 			});
912 			
913 		}
914 		return jTFAddress;
915 	}
916 
917 	/**
918 	 * This method initializes jControlPanel3	
919 	 * 	
920 	 * @return javax.swing.JPanel	
921 	 */
922 	private JPanel getJControlPanel3() {
923 		if (jControlPanel3 == null) {
924 			GridBagConstraints gridBagConstraints12 = new GridBagConstraints();
925 			gridBagConstraints12.gridx = 1;
926 			gridBagConstraints12.gridheight = 1;
927 			gridBagConstraints12.ipadx = 0;
928 			gridBagConstraints12.gridwidth = 1;
929 			gridBagConstraints12.insets = new Insets(2, 0, 2, 0);
930 			gridBagConstraints12.anchor = GridBagConstraints.EAST;
931 			gridBagConstraints12.fill = GridBagConstraints.NONE;
932 			gridBagConstraints12.weightx = 1.0;
933 			gridBagConstraints12.weighty = 1.0;
934 			gridBagConstraints12.gridy = 0;
935 			GridBagConstraints gridBagConstraints11 = new GridBagConstraints();
936 			gridBagConstraints11.gridx = 0;
937 			gridBagConstraints11.weightx = 1.0;
938 			gridBagConstraints11.weighty = 1.0;
939 			gridBagConstraints11.gridwidth = 1;
940 			gridBagConstraints11.insets = new Insets(2, 0, 2, 0);
941 			gridBagConstraints11.gridy = 0;
942 			jControlPanel3 = new JPanel();
943 			jControlPanel3.setLayout(new GridBagLayout());
944 			jControlPanel3.setPreferredSize(new Dimension(160, 26));
945 			jControlPanel3.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
946 			jControlPanel3.add(getJBStart(), gridBagConstraints11);
947 			jControlPanel3.add(getJBStop(), gridBagConstraints12);
948 		}
949 		return jControlPanel3;
950 	}
951 
952 	public void setAlreadyStarted(String aAddress)
953 	{
954 		jTFAddress.setText(aAddress);
955 		jBStop.setEnabled(true);
956 		jBStart.setEnabled(false);
957 		jBSaveAsPNG.setEnabled(false);
958 		jTFAddress.setEditable(false);
959 	}
960 	
961 	/**
962 	 * This method initializes jBStart	
963 	 * 	
964 	 * @return javax.swing.JButton	
965 	 */
966 	private JButton getJBStart() {
967 		if (jBStart == null) {
968 			jBStart = new JButton();
969 			jBStart.setMnemonic(KeyEvent.VK_UNDEFINED);
970 			jBStart.setText("Start");
971 			jBStart.addActionListener(new java.awt.event.ActionListener() {
972 				public void actionPerformed(java.awt.event.ActionEvent e) {
973 					String s = jTFAddress.getText();
974 					if (doStartTransfer(s, false)==true)
975 					{
976 						jBStop.setEnabled(true);
977 						jBStart.setEnabled(false);
978 						jBSaveAsPNG.setEnabled(false);
979 						jTFAddress.setEditable(false);
980 					}
981 				}
982 			});
983 		}
984 		return jBStart;
985 	}
986 
987 	/**
988 	 * This method initializes jBStop	
989 	 * 	
990 	 * @return javax.swing.JButton	
991 	 */
992 	private JButton getJBStop() {
993 		if (jBStop == null) {
994 			jBStop = new JButton();
995 			jBStop.setMnemonic(KeyEvent.VK_UNDEFINED);
996 			jBStop.setPreferredSize(new Dimension(62, 26));
997 			jBStop.setText("Stop");
998 			jBStop.addActionListener(new java.awt.event.ActionListener() {
999 				public void actionPerformed(java.awt.event.ActionEvent e) 
1000 				{
1001 					doStopTransfer();
1002 					jBStop.setEnabled(false);
1003 					jBStart.setEnabled(true);
1004 					jBSaveAsPNG.setEnabled(true);
1005 					jTFAddress.setEditable(true);
1006 					
1007 				}
1008 			});
1009 		}
1010 		return jBStop;
1011 	}
1012 
1013 	/**
1014 	 * This method initializes jBSaveAsPNG	
1015 	 * 	
1016 	 * @return javax.swing.JButton	
1017 	 */
1018 	private JButton getJBSaveAsPNG() {
1019 		if (jBSaveAsPNG == null) {
1020 			jBSaveAsPNG = new JButton();
1021 			jBSaveAsPNG.setMnemonic(KeyEvent.VK_UNDEFINED);
1022 			jBSaveAsPNG.setText("Save As PNG...");
1023 			jBSaveAsPNG.addActionListener(new java.awt.event.ActionListener() {
1024 				public void actionPerformed(java.awt.event.ActionEvent e) 
1025 				{
1026 				
1027 					JFileChooser chooser = new JFileChooser(new File("."));
1028 				    
1029 					String[] fileType= {"png"};
1030 					
1031 					FileNameExtensionFilter PNGfilter = new FileNameExtensionFilter(
1032 				        "PNG files", fileType);
1033 				    
1034 				    chooser.addChoosableFileFilter(PNGfilter);
1035 				    
1036 				    int returnVal = chooser.showSaveDialog(m_selfRef);
1037 				    
1038 				    if (returnVal == JFileChooser.APPROVE_OPTION) 
1039 				    {
1040 						String fileNamePath = chooser.getSelectedFile().getAbsolutePath();
1041 
1042 						boolean ret = CBasicPNGWriterV3.write(fileNamePath, m_img, m_Hdr);
1043 						if (ret == false)
1044 						{
1045 							JOptionPane.showMessageDialog(m_selfRef, 
1046 									new String("Error saving image."),"", JOptionPane.ERROR_MESSAGE );
1047 						}
1048 					}
1049 
1050 					repaint();
1051 
1052 				}
1053 			});
1054 		}
1055 		return jBSaveAsPNG;
1056 	}
1057 
1058 	/**
1059 	 * This method initializes jBQuit	
1060 	 * 	
1061 	 * @return javax.swing.JButton	
1062 	 */
1063 	private JButton getJBQuit() {
1064 		if (jBQuit == null) {
1065 			jBQuit = new JButton();
1066 			jBQuit.setMnemonic(KeyEvent.VK_UNDEFINED);
1067 			jBQuit.setText("Quit");
1068 			jBQuit.addActionListener(new java.awt.event.ActionListener() {
1069 				public void actionPerformed(java.awt.event.ActionEvent e) {
1070 					QuitCleanupApplication();
1071 				}
1072 			});
1073 		}
1074 		return jBQuit;
1075 	}
1076 
1077 	////////////////////////////////////////////////////////////////////////////
1078 	//TINE handling
1079 	////////////////////////////////////////////////////////////////////////////
1080 	public boolean ProbeTine(String aDevName, String aDevProp)
1081 	{
1082 		boolean retval = true;
1083 		int cc;
1084 				
1085 		byte[] framebits = new byte[CVideoHeader3.HDRSIZE]; 
1086 		//	1 meg max frame size, e.g. 800x624 x 2 bypp + header
1087 		// if bigger than server max work area size, then error 30 
1088 		// (invalid transport)
1089 		
1090 		TDataType dout = new TDataType(framebits);
1091 		
1092 	    // get a reference array : synchronous call ...
1093 	    TLink ref = new TLink(aDevName,aDevProp,dout,null,TAccess.CA_READ);
1094 	    cc=ref.execute();
1095 	    if (cc != 0) 
1096 	    {
1097 	    	//System.out.println("Error: get reference : " + ref.getLinkStatus());
1098 	    	// 517==RETCODE_NOFRAMEYET
1099 	    	JOptionPane.showMessageDialog(this, 
1100 	    			new String("Probing Address did not succeed.\n\n"+
1101 	    						"Transfer was cancelled."),"Checking connection...", JOptionPane.ERROR_MESSAGE );
1102 	    	retval = false;
1103 	    }
1104 	    else
1105 	    {
1106 	    	ref.cancel();
1107 	    	//System.out.println("Got "+dout.dCompletionLength+" bytes back.");
1108 	    	if (dout.dCompletionLength != CVideoHeader3.HDRSIZE)
1109 	    	{
1110 		    	JOptionPane.showMessageDialog(this, 
1111 		    			new String("CF_IMAGE header is not 172 bytes in size.\n\n"+
1112 		    						"Transfer was cancelled."),"Checking connection...", JOptionPane.ERROR_MESSAGE );
1113 	    	}
1114 	    }
1115 	    
1116 	    framebits = null;
1117 	    				
1118 		return retval;
1119 	}
1120 
1121 	
1122 	public boolean doStartTransfer(String aCmdLine, boolean aCommandLine)
1123 	{
1124 		String devName = aCmdLine;  // /context/server/device;
1125 		String devProp = "Frame.Sched";
1126 		
1127 		if (aCommandLine == true) jTFAddress.setText(devName);
1128 		
1129 		if (devName.endsWith("/") == true) devName += "Output";
1130 		
1131 		if (ProbeTine(devName, "Header") == false) return false;
1132 		
1133 		//buffer must be dividable by four
1134 		// 192 = 188 headerbytes + (dividable by 8)
1135 		if (m_srcBuf == null)
1136 			m_srcBuf = new byte[1024*1024*6+192];
1137    
1138 		m_srcImgHdr = new IMAGE();
1139 	    m_srcImgHdr.setImageFrameBuffer(m_srcBuf);
1140 	    
1141 	    TDataType img_dout = new TDataType(m_srcImgHdr);
1142 		
1143 		m_vidLink = new TLink(devName,devProp,img_dout,null,TAccess.CA_READ);
1144 	    if (m_vidLink.attach(TMode.CM_POLL, this, 1000) < 0)
1145 	    {
1146 	      m_vidLink.cancel();
1147 	      m_vidLink = null;
1148     	  
1149 	      JOptionPane.showMessageDialog(this, 
1150 	    			new String("No permanent connection to server (\""+m_vidLink.getLastError()+"\".\n\n"+
1151 	    						"Transfer was cancelled."),"Establishing connection...", JOptionPane.ERROR_MESSAGE );
1152 	      
1153 	      return false;
1154 	    }
1155 
1156 	    m_img=null;
1157 		m_mis=null;
1158 		
1159 		m_DisplayImageBuffer = null;
1160 		m_ColorLookupTableArray = null;
1161 		m_bDoUpdateColorLookupTable = true;
1162 		m_lastframenumber=-1;
1163 		m_droppedframes=0;
1164 		m_receivedframes=0;
1165 		m_ratio = -0.001;
1166 				
1167 	    m_bTransferRunning = true;
1168 			
1169 		return true;
1170 	}
1171 	
1172 	public boolean doStopTransfer()
1173 	{
1174 		if (m_vidLink != null)
1175 		{
1176 			m_vidLink.cancel();
1177 			m_vidLink = null;
1178 		}
1179 
1180 		//m_srcBuf = null;
1181 		//m_dstBuf = null;
1182 
1183 		m_bTransferRunning = false;		
1184 	
1185 		return true;
1186 	}
1187 	
1188 	public synchronized void updateHeader(CVideoHeader3 aHdr)
1189 	{
1190 		m_Hdr = aHdr;
1191 	}
1192 	
1193     public synchronized void callback(TLink lnk)
1194     {
1195     	if (m_bTransferRunning == false) return;
1196 
1197     	if (lnk.getLinkStatus() == 516) return;
1198 	   	
1199     	if (lnk.getLinkStatus() != 0 )
1200 	    {
1201 	        System.out.println("Link Error : code="+lnk.getLinkStatus()+ " msg="+ lnk.getLastError());
1202 	        return;
1203 	    }
1204     	
1205     	CVideoHeader3 hdr = new CVideoHeader3(m_srcImgHdr);
1206     	//adjust into raw bits
1207       	
1208    		int pixellength = hdr.getAppendedWidth()*hdr.getAppendedHeight();
1209    		int uncompressed_byte_length = pixellength * hdr.frameHeader.bytesPerPixel;
1210 
1211    		if (m_DisplayImageBuffer == null)
1212 		{
1213 			m_DisplayImageBuffer = new int[pixellength];
1214 		}
1215 		else if (m_DisplayImageBuffer.length < pixellength)
1216 		{
1217 			m_DisplayImageBuffer = null;
1218 			m_DisplayImageBuffer = new int[pixellength];
1219 		}
1220     		
1221    		if (hdr.frameHeader.imageFormat == CVideoHeader3.CF_IMAGE_FORMAT_GRAY)
1222    		{
1223    			if ((m_dstBuf == null) || (m_dstBuf.length < uncompressed_byte_length)) m_dstBuf = new byte[uncompressed_byte_length];
1224 
1225    			if (convertImage(m_srcBuf, hdr, m_dstBuf) == false) 
1226    			{
1227    				System.out.println("convertImage false");
1228    				return;
1229    			}
1230 
1231    			if (m_bFalsecolorEnabled == false)
1232    			{
1233    				// enable false color switching in gui
1234    				jRBColorPITZ.setEnabled(true);
1235    				jRBColorJet.setEnabled(true);
1236    				jRBColorGreyscale.setEnabled(true);
1237     				
1238    				m_bFalsecolorEnabled = true;
1239    			}
1240     			
1241    			//System.out.println("Image #"+hdr.framenumber+" received.");
1242 
1243 			if ((m_ColorLookupTableArray == null) || (m_ColorLookupTableArray.length < (hdr.frameHeader.bytesPerPixel << 8)) )
1244 			{
1245 				m_bDoUpdateColorLookupTable = true;
1246   			}
1247    			
1248    			if (m_bDoUpdateColorLookupTable == true)
1249    			{
1250    				boolean ret = m_CColorLookupTable.AdjustTable(m_iColorMode, hdr.frameHeader.bytesPerPixel, hdr.frameHeader.effectiveBitsPerPixel);
1251    				if ((ret == true) || (m_ColorLookupTableArray == null)) m_ColorLookupTableArray = m_CColorLookupTable.getColorLookupTable(); 
1252    				m_bDoUpdateColorLookupTable = false;
1253    			}
1254     			
1255    			int maxcol = (1<<hdr.frameHeader.effectiveBitsPerPixel)-1;
1256    			int index=0;
1257    			try {
1258    				// not only 8bpp by now (but not "perfect")
1259    				// todo	make faster
1260    				while( index < pixellength )
1261    				{
1262    					if (hdr.frameHeader.bytesPerPixel == 1)
1263    						m_DisplayImageBuffer[index] = m_ColorLookupTableArray[((int)m_dstBuf[index])&maxcol];
1264 
1265    					if (hdr.frameHeader.bytesPerPixel == 2)
1266    					{
1267    						int tmp;
1268    						int clutindex=0;
1269 										
1270    						clutindex = (((int)m_dstBuf[2*index])&0xff);
1271    						tmp = ((((int)m_dstBuf[2*index+1]))&0xff)<<8;
1272 						
1273    						// &maxcol
1274    						m_DisplayImageBuffer[index] = m_ColorLookupTableArray[tmp+clutindex];
1275    					}
1276 										
1277    					index++;
1278    				}
1279    			} catch( ArrayIndexOutOfBoundsException ex) {}
1280     			
1281    		}
1282    		else // can only be RGB now
1283    		{
1284    			if (m_bFalsecolorEnabled == true)
1285    			{
1286    				// disable false color switching in gui
1287    				jRBColorPITZ.setEnabled(false);
1288    				jRBColorJet.setEnabled(false);
1289    				jRBColorGreyscale.setEnabled(false);
1290 
1291    				m_bFalsecolorEnabled = false;
1292    			}
1293 
1294    			if ((m_dstBuf == null) || (m_dstBuf.length < uncompressed_byte_length)) m_dstBuf = new byte[uncompressed_byte_length];
1295     			
1296    			// rgb24
1297    			if (convertImageColor(m_srcBuf, m_dstBuf, hdr, m_DisplayImageBuffer) == false) 
1298    			{
1299    				System.out.println("convertImageColor false");
1300    				return;
1301    			}
1302    		}
1303 
1304 		if (m_mis == null)
1305 		{
1306 			m_mis = new MemoryImageSource(hdr.getAppendedWidth(), hdr.getAppendedHeight(), m_DisplayImageBuffer, 0, hdr.getAppendedWidth());
1307 			m_mis.setAnimated(true);
1308 			m_mis.setFullBufferUpdates(true);
1309 		}
1310 			
1311 		if (m_img == null)
1312 		{
1313 			m_img = Toolkit.getDefaultToolkit().createImage(m_mis);
1314 		}
1315 			
1316 		m_mis.newPixels();
1317 			
1318 		// calculate variables
1319 			
1320 		if (m_lastframenumber == -1)
1321 		{
1322 			m_lastframenumber = hdr.frameHeader.frameNumber;
1323 			m_droppedframes = 0;
1324 			m_receivedframes++;
1325 		}
1326 		else
1327 		{
1328 			if (hdr.frameHeader.frameNumber == m_lastframenumber)
1329 			{
1330 				System.out.println("Theyre same: "+hdr.frameHeader.frameNumber+"  "+m_lastframenumber+" !");
1331 			}
1332 			else if( hdr.frameHeader.frameNumber < m_lastframenumber)
1333 			{
1334 				m_receivedframes++;
1335 			}
1336 			else
1337 			{
1338 				m_droppedframes += (hdr.frameHeader.frameNumber-m_lastframenumber-1);
1339 				m_receivedframes++;
1340 			}
1341 			m_lastframenumber = hdr.frameHeader.frameNumber;
1342 				
1343 		}
1344 
1345 		if (m_receivedframes != 0)
1346 			m_ratio = ((1.0*m_droppedframes) / (1.0*(m_receivedframes)));
1347 			
1348 		if (m_img != null) 
1349 		{
1350 			updateHeader(hdr);
1351 			updateImage();
1352 		}
1353    	}
1354 	
1355 	
1356 	////////////////////////////////////////////////////////////////////////////////
1357 	// frame decode handling
1358 	////////////////////////////////////////////////////////////////////////////////
1359     
1360 	public boolean convertImage(byte[] aSrc, CVideoHeader3 aHdr, byte[] aDst)
1361 	{
1362 		int uncompressed_size = aHdr.getAppendedWidth()*aHdr.getAppendedHeight()*aHdr.frameHeader.bytesPerPixel;
1363 			
1364 		if ((aSrc == null) || (aDst == null) || (aDst.length < uncompressed_size)) return false;
1365 
1366 		if (aHdr.frameHeader.sourceFormat == CVideoHeader3.CF_IMAGE_FORMAT_GRAY)
1367 		{
1368 			if (aHdr.frameHeader.imageFormat != aHdr.frameHeader.sourceFormat)
1369 			{
1370 				// only HuffYUV is supported here as decompression
1371 				if (aHdr.frameHeader.imageFormat != CVideoHeader3.CF_IMAGE_FORMAT_HUFFYUV) return false;
1372 
1373 				CHuffmanDecompression.DecompressHuffYUV(aSrc, CVideoHeader3.HDRSIZE, aDst, 0, uncompressed_size);
1374 					
1375 				// adjust header after compression
1376 				aHdr.frameHeader.imageFormat = aHdr.frameHeader.sourceFormat;
1377 				aHdr.sourceHeader.totalLength = uncompressed_size+CVideoHeader3.HDRSIZE;
1378 				aHdr.frameHeader.appendedFrameSize = uncompressed_size;
1379 			}
1380 			else
1381 			{
1382 				//System.arraycopy(aSrc, CVideoHeader3.HDRSIZE, aDst, 0, (int) aHdr.frameHeader.appendedFrameSize);
1383 				System.arraycopy(aSrc, 0, aDst, 0, (int) aHdr.frameHeader.appendedFrameSize);
1384 			}			
1385 		}
1386 		else
1387 		{
1388 			 return false;
1389 		}
1390 			
1391 		return true;
1392 	}
1393 
1394 	public boolean convertImageColor(byte[] aSrc, byte[] aDstRaw, CVideoHeader3 aHdr, int[] aDst)
1395 	{
1396 		int uncompressed_pixel_size = aHdr.getAppendedWidth()*aHdr.getAppendedHeight();
1397 			
1398 		if ((aSrc == null) || (aDst == null) || (aDst.length < uncompressed_pixel_size)) return false;
1399 		if ((aDstRaw == null) || (aDstRaw.length < uncompressed_pixel_size*aHdr.frameHeader.bytesPerPixel)) return false;
1400 
1401 		if (aHdr.frameHeader.imageFormat != CVideoHeader3.CF_IMAGE_FORMAT_RGB)
1402 		{
1403 			return false;
1404 		}
1405 		int index=0;
1406 		int index1=0;
1407 
1408 		try {
1409 		while( index < uncompressed_pixel_size)
1410 		{
1411 			int red16 = (((int) aSrc[index1++])&0xFF);
1412 			int green8 = (((int) aSrc[index1++])&0xFF);
1413 			int blue = (((int) aSrc[index1++])&0xFF);
1414 			
1415 			aDst[index++] = 0xFF000000 | (red16 << 16) | (green8 << 8) | (blue);
1416 			//  
1417 		}
1418 		} catch( ArrayIndexOutOfBoundsException ex) {}
1419 
1420 		System.arraycopy(aSrc, 0, aDstRaw, 0, aHdr.frameHeader.appendedFrameSize);
1421 		//System.arraycopy(aSrc, CVideoHeader3.HDRSIZE, aDstRaw, 0, (int) aHdr.imH_length);
1422 		
1423 		return true;
1424 	}
1425 	
1426 	
1427 }  //  @jve:decl-index=0:visual-constraint="21,28"