ptimage._java


// Image loading and manipulating

	int im_maxarray 					=		0x80000;// Max size of linear arrays in Netscape
    // Background Grid
    int  grid_bgcolor					= 0xffffff; // white
    int  grid_fgcolor					= 0;		// black


	/**
	*  Load an image with name <CODE>name</CODE>. This
	* method extends the default <CODE>getImage()</CODE> of
	* Java, and searches the Resources (archive) also.
	* The image is loaded in memory when the function returns,
	* or <CODE>null</CODE> is returned.
	*/
	public Image loadImage( String name ){    		
   		Image image = null;
   		
   		byte[] b = file_read( name, null );
   		
   		if( b != null ){
   			image = bufferToImage( b );
			b = null;
			if(image != null)
				return image;
		}
 
        try{
         	URL url = new URL(getDocumentBase(), name);
          	image = getImage(url);
 			MediaTracker tracker = new MediaTracker(this);
 			tracker.addImage(image, 0);
 			tracker.waitForAll();
 			if( image == null || image.getWidth(null) <= 0 )	// No image
 				return null;
 			else
 				return( image );
        }catch(Exception e){
        	return null; 
        }
	}


    
	// Load an image with download feedback
	Image loadImageProgress( String name ){
   		Image image = null;
   		percent[0] = 0;
   		
   		byte[] b = file_read( name, percent );
   		
   		if( b != null ){
   			image = bufferToImage( b );
			percent[0] = 100; repaint();	// Show 100% when decompressed
			b = null;
			if( image != null )
				return image;
		}
		
		return loadImage( name );
	}
  


	Image bufferToImage( byte[] buf ){
		if(buf==null) return null;
		Image image = Toolkit.getDefaultToolkit().createImage(buf);
		
		MediaTracker tracker = new MediaTracker(this);
		tracker.addImage(image, 0);
		try {
    		tracker.waitForAll();
   		} catch (InterruptedException e) {return null;}
   		return image;
   	}



// Allocate new array only if existing array doesn't fit

int[][] im_allocate_pano(int[][] pd, int pwidth, int pheight){
	if( pd == null ||
	   (pd.length != pheight || pd[0].length != pwidth) ){
		try{
        	int[][]p = new int[pheight][pwidth];
        	return p;
        }catch(Exception e){
 			return null;
 		}
 	}
 	return pd;
}
	   
				
		   	    	

void im_drawGrid( int [][] p, int g_bgcolor, int g_fgcolor ){
	int x,y,i,cy;
	int bg 		= g_bgcolor | 0xff000000;
	int fg 		= g_fgcolor | 0xff000000;
	
	if(p==null) return;
	int height 	= p.length;
	int width 	= p[0].length;
 		
    for(y = 0; y < height; y++)
    	for( x = 0; x < width; x++ ) 
     		p[y][x] = bg;
          	
 	// Horizontal lines
 	for(y = 0,i=18*2*height/width ; i >= 0; i--){
 		cy = y+1;
        for( x = 0; x < width; x++ ){ 
        	p[y] [x] = fg;
        	p[cy][x] = fg;
        }
        if( i!= 0)
        	y += (height-2-y)/i;
   	}
      	
 	// Vertical lines
	for(x = 0,i=36 ; i >= 0; i--){
 		if( x== 0)
         	for( y = 0; y < height; y++ ) 
         		p[y][x] = fg;
        else if( x >= width-1 ){
         	x = width-1; i=0;
          	for( y = 0; y < height; y++ ) 
         		p[y][x] = fg;
        }else{
        	cy = x+1;
        	for( y = 0; y < height; y++ ){ 
         		p[y][x]  = fg;
        		p[y][cy] = fg;
        	}
        }
        if( i!= 0)
        	x += (width-1-x)/i;
	}
}


	// Set alpha channel in rectangular region of
	// two dimensional array p  to 'alpha'
	
	void SetPAlpha( int x0, int y0, int x1, int y1, int alpha, int[][] p){
		int x,y, hmask = (alpha<<24) + 0x00ffffff;
		
		int h = p.length, w = p[0].length;
		
		int ymin = Math.min( y0, y1 ); if(ymin<0)	ymin=0;
		int ymax = Math.max( y0, y1 ); if(ymax>=h) 	ymax=h-1;
		
		if(x0<0)  x0=0;
		if(x0>=w) x0=w-1;
		
		if(x1<0)  x1=0;
		if(x1>=w) x1=w-1;

				
		if(x1 >= x0){
			for(y=ymin; y<=ymax; y++)
				for(x=x0; x<=x1; x++)
					p[y][x] &= hmask;
		}else{
			for(y=ymin; y<=ymax; y++){
				for(x=0; x<=x1; x++)
					p[y][x] &= hmask;
				for(x=x0; x<w; x++)
					p[y][x] &= hmask;
			}
		}
	}
	
// Scale pixel area to pwidth/pheight
// Use same procedure as Panorama Tools

void  scaleImage(int[][] pd, int width, int height){
	if( pd == null ) return;
  	int ph = pd.length, pw = pd[0].length;

	int x,y,xs,ys,xd,yd;
	int dx,dy,xs0, xs1, ys0, ys1;
	int scale = 256 * width / pw;
	int w2  = pw  * 128 - 128;
	int h2  = ph * 128 - 128;
	int sw2 = width   * 128 - 128;
	int sh2 = height  * 128 - 128;
		
	int w3 = - w2 * width / pw + sw2; 
	int w1 = width-1;
		

	for(y=ph-1; y>=0; y--){
		yd = y * 256 - h2;
		ys = yd * width / pw + sh2;
		dy = ys & 0xff; ys = (ys >> 8);
		if(ys<0){
			ys0=ys1=0;
		}else if(ys>=height-1){
			ys0=ys1=height-1;
		}else{
			ys0=ys++;ys1=ys;
		}

		for(x=pw-1; x>=0; x--){
			xs = x * scale + w3; 
			dx = xs & 0xff; xs = (xs >> 8);
			if(xs<0){
				xs0=xs1=0;
			}else if(xs>=w1){
				xs0=xs1=w1;
			}else{
				xs0=xs++;xs1=xs;
			}

			pd[y][x] = bil(pd[ys0][xs0], pd[ys0][xs1], 
						   pd[ys1][xs0], pd[ys1][xs1], dx, dy);
		}
	}
}


	// Load image into 2D-array
	// array must be allocated to hold enough data
	// Uses variable im_maxarray
	void ptImageTo2DArray( int[][]data, Image im ){
		if( im == null || data == null ) return;
		
        int grabHeight = im.getHeight(null);
        if(grabHeight*im.getWidth (null) > im_maxarray) 
        	grabHeight= im_maxarray/im.getWidth(null);
        
        int[] tdata = new int[grabHeight * im.getWidth(null)];

       	// Grab pixels in chunks of im_maxarray size
       	int cy,dy,x,y;
       	PixelGrabber pg;
       	
       	for(cy=0; cy < im.getHeight(null); cy += grabHeight ){
        	int sheight = (grabHeight < im.getHeight(null) - cy ? 
        				   grabHeight : im.getHeight(null) - cy );
        	
        	pg = new PixelGrabber( im, 0, cy,im.getWidth (null), sheight, tdata, 0, im.getWidth (null) );
        	try { pg.grabPixels(); } 
        	catch (InterruptedException e){
            	return;
        	}
        	
        	// Store pixels in 2 dimensional array
        	
        	for(y=0; y<sheight; y++){
        		dy = y*im.getWidth(null);
         		for(x=0; x<im.getWidth(null); x++)
        			data[y+cy][x] = tdata[dy + x] | 0xff000000;
        	}
        }	
  	    tdata = null;
 	    System.gc();
	}
	
		// Set alpha channel of pixel data to image im
	void ptImageToAlpha( int[][]data, Image im){
		if( im==null || data==null ) return;

       	int grabHeight = im.getHeight(null);
        if(grabHeight*im.getWidth (null) > im_maxarray) 
        	grabHeight= im_maxarray/im.getWidth(null);
        
        int[] tdata = new int[grabHeight * im.getWidth(null)];
		
	    int hmask, cy,dy,x,y;
	    PixelGrabber pg;
			
       	for(cy=0; cy < im.getHeight(null); cy += grabHeight ){
        	int sheight = (grabHeight < im.getHeight(null) - cy ? 
        				   grabHeight : im.getHeight(null) - cy );
        	
        	pg = new PixelGrabber( im, 0, cy,im.getWidth (null), sheight, tdata, 0, im.getWidth (null) );
        	try { pg.grabPixels(); } 
        	catch (InterruptedException e){
            	return;
        	}
        	
         	for(y=0; y<sheight; y++){
         		dy = y*im.getWidth(null);
         		for(x=0; x<im.getWidth(null); x++){
         				hmask = ((tdata[dy + x] & 0xff) << 24) + 0x00ffffff;
        				data[y+cy][x] &= hmask;
 	    		}
 	    	}
 	    }
 	    tdata = null;
 	    System.gc();
	}


// Insert a rectangular image into panorama	
// preserve alpha channel in panorama, insert only if alpha channel set
// in insert

void im_insertRect( int[][] pd, int xd, int yd, int[] id, int iwidth, 
					int xs, int ys, int width, int height ){
	int x,y,xp,yp,idx,px;
	
	try{
		for(y = 0, yp = yd; y < height; y++, yp++){
			for(x = 0, idx = (ys + y) * iwidth + xs; x < width; x++, idx++){
				px = id[idx];
				if((px & 0xff000000) != 0 ){ //Non transparent
					xp = x + xd;
					pd[yp][xp] = px & (pd[yp][xp]  | 0x00ffffff);
				}
			}
		}
	}catch(Exception e){
		System.out.println("Insert can't be fit into panorama");
	}
}


				

// Extract a rectangular image from panorama
// Remove alpha channel	

final void im_extractRect( int[][] pd, int xd, int yd, int[] id, int iwidth, 
					int xs, int ys, int width, int height ){
	int x,y,yp,idx,px;
	
	try{
		for(y = 0, yp = yd; y < height; y++, yp++){
			for(x = 0, idx = (ys + y) * iwidth + xs; x < width; x++, idx++){
				id[idx] = pdata[yp][x+xd] | 0xff000000; // remove possible mask
			}
		}
	}catch(Exception e){
		System.out.println("Invalid rectangle");
	}
}
				
// load the panoramic image
final int[][] im_loadPano(String fname, int[][] pd, int pw, int ph){
	int [][] p;
 

	if(fname == null || fname.equals("_PT_Grid")){
		if( pw == 0 ) pw = 100; // Dummy background 

		// Create grid panorama	
		p = im_allocate_pano( pd, pw, (ph == 0 ? pw/2 : ph) );
		im_drawGrid( p, grid_bgcolor, grid_fgcolor );
 		return p;
    }
    	
    Image pano = loadImageProgress( fname );
			
 	if( pano == null ){
		return null;
	}
 
 	// At this point we have a valid panorama image
 	// Check size:
 		
 	if(pw > pano.getWidth (null)){
 		if(ph == 0) ph = pw/2;
 	}else{
 		pw 	= pano.getWidth (null);
		ph 	= pano.getHeight(null);
	}
		
	// Set up data array for panorama pixels
		
	p = im_allocate_pano( pd, pw, ph);
	if( p == null ) return null;
  
  	ptImageTo2DArray( p, pano );     	
       
        
  	if(pw != pano.getWidth (null)){
        scaleImage( p, pano.getWidth(null), pano.getHeight(null));
	}
	pano = null;
	return p;
}
	

Back