2006-04-03 00:59:53 +02:00
// ViewImage.java
// -----------------------
// part of YaCy
2008-07-20 19:14:51 +02:00
// (C) by Michael Peter Christen; mc@yacy.net
2006-04-03 00:59:53 +02:00
// first published on http://www.anomic.de
// Frankfurt, Germany, 2006
// created 03.04.2006
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import java.awt.Container ;
import java.awt.Image ;
import java.awt.MediaTracker ;
2011-05-07 09:45:02 +02:00
import java.awt.image.BufferedImage ;
import java.awt.image.Raster ;
2009-11-19 11:17:26 +01:00
import java.io.ByteArrayInputStream ;
2007-07-15 03:34:01 +02:00
import java.io.File ;
2006-10-03 13:05:48 +02:00
import java.io.IOException ;
import java.io.InputStream ;
2006-04-03 00:59:53 +02:00
import java.net.MalformedURLException ;
2011-03-22 12:00:55 +01:00
import java.util.Map ;
2006-04-03 00:59:53 +02:00
2010-08-23 14:32:02 +02:00
import net.yacy.cora.protocol.HeaderFramework ;
import net.yacy.cora.protocol.RequestHeader ;
2011-06-13 23:44:03 +02:00
import net.yacy.cora.services.federated.yacy.CacheStrategy ;
2011-03-22 12:00:55 +01:00
import net.yacy.cora.storage.ConcurrentARC ;
2009-10-20 00:34:44 +02:00
import net.yacy.document.ImageParser ;
2009-10-11 02:12:19 +02:00
import net.yacy.kelondro.data.meta.DigestURI ;
2009-10-10 01:13:30 +02:00
import net.yacy.kelondro.logging.Log ;
2009-10-10 03:14:19 +02:00
import net.yacy.kelondro.util.FileUtils ;
2011-03-22 12:00:55 +01:00
import net.yacy.kelondro.util.MemoryControl ;
2011-09-25 18:59:06 +02:00
import net.yacy.search.Switchboard ;
2006-04-03 00:59:53 +02:00
import de.anomic.server.serverObjects ;
import de.anomic.server.serverSwitch ;
public class ViewImage {
2011-03-22 12:00:55 +01:00
private static Map < String , Image > iconcache = new ConcurrentARC < String , Image > ( 1000 , Math . max ( 10 , Math . min ( 32 , Runtime . getRuntime ( ) . availableProcessors ( ) * 2 ) ) ) ;
2007-09-06 03:28:35 +02:00
private static String defaulticon = " htroot/env/grafics/dfltfvcn.ico " ;
2009-03-06 16:39:02 +01:00
private static byte [ ] defaulticonb ;
static {
try {
defaulticonb = FileUtils . read ( new File ( defaulticon ) ) ;
} catch ( final IOException e ) {
}
}
2011-06-13 23:44:03 +02:00
2009-07-19 22:37:44 +02:00
public static Image respond ( final RequestHeader header , final serverObjects post , final serverSwitch env ) {
2011-06-13 23:44:03 +02:00
2009-07-19 22:37:44 +02:00
final Switchboard sb = ( Switchboard ) env ;
2011-06-13 23:44:03 +02:00
2007-08-04 01:06:53 +02:00
// the url to the image can be either submitted with an url in clear text, or using a license key
// if the url is given as clear text, the user must be authorized as admin
// the license can be used also from non-authorized users
2011-06-13 23:44:03 +02:00
2007-08-04 01:06:53 +02:00
String urlString = post . get ( " url " , " " ) ;
2008-08-02 14:12:04 +02:00
final String urlLicense = post . get ( " code " , " " ) ;
2011-11-25 15:09:25 +01:00
final boolean auth = ( header . get ( HeaderFramework . CONNECTION_PROP_CLIENTIP , " " ) ) . equals ( " localhost " ) | | sb . verifyAuthentication ( header ) ; // handle access rights
2011-06-13 23:44:03 +02:00
2009-10-11 02:12:19 +02:00
DigestURI url = null ;
2007-08-04 01:06:53 +02:00
if ( ( urlString . length ( ) > 0 ) & & ( auth ) ) try {
2010-10-26 18:10:20 +02:00
url = new DigestURI ( urlString ) ;
2008-08-02 14:12:04 +02:00
} catch ( final MalformedURLException e1 ) {
2007-08-04 01:06:53 +02:00
url = null ;
}
2011-06-13 23:44:03 +02:00
2007-08-04 01:06:53 +02:00
if ( ( url = = null ) & & ( urlLicense . length ( ) > 0 ) ) {
url = sb . licensedURLs . releaseLicense ( urlLicense ) ;
2007-08-28 14:15:46 +02:00
urlString = ( url = = null ) ? null : url . toNormalform ( true , true ) ;
2006-04-03 00:59:53 +02:00
}
2011-06-13 23:44:03 +02:00
2009-07-25 23:38:57 +02:00
if ( urlString = = null ) return null ;
2011-06-13 23:44:03 +02:00
2006-04-03 00:59:53 +02:00
int width = post . getInt ( " width " , 0 ) ;
int height = post . getInt ( " height " , 0 ) ;
2006-04-07 15:38:09 +02:00
int maxwidth = post . getInt ( " maxwidth " , 0 ) ;
int maxheight = post . getInt ( " maxheight " , 0 ) ;
2011-06-13 23:44:03 +02:00
2009-11-19 11:17:26 +01:00
// get the image as stream
2011-03-22 12:00:55 +01:00
if ( MemoryControl . shortStatus ( ) ) iconcache . clear ( ) ;
2011-05-07 09:45:02 +02:00
Image image = iconcache . get ( urlString ) ;
2011-05-07 09:37:46 +02:00
if ( image = = null ) {
byte [ ] resourceb = null ;
if ( url ! = null ) try {
2011-06-13 23:44:03 +02:00
resourceb = sb . loader . loadContent ( sb . loader . request ( url , false , true ) , CacheStrategy . IFEXIST ) ;
} catch ( final IOException e ) {
2011-05-07 09:37:46 +02:00
Log . logFine ( " ViewImage " , " cannot load: " + e . getMessage ( ) ) ;
}
byte [ ] imgb = null ;
if ( resourceb = = null ) {
if ( urlString . endsWith ( " .ico " ) ) {
// load default favicon dfltfvcn.ico
if ( defaulticonb = = null ) try {
imgb = FileUtils . read ( new File ( sb . getAppPath ( ) , defaulticon ) ) ;
} catch ( final IOException e ) {
return null ;
} else {
imgb = defaulticonb ;
}
} else {
return null ;
}
} else {
final InputStream imgStream = new ByteArrayInputStream ( resourceb ) ;
// read image data
try {
imgb = FileUtils . read ( imgStream ) ;
} catch ( final IOException e ) {
return null ;
} finally {
try {
imgStream . close ( ) ;
} catch ( final Exception e ) { }
}
}
// read image
image = ImageParser . parse ( urlString , imgb ) ;
if ( image = = null | | ( auth & & ( width = = 0 | | height = = 0 ) & & maxwidth = = 0 & & maxheight = = 0 ) ) return image ;
// find original size
2011-05-07 09:45:02 +02:00
final int h = image . getHeight ( null ) ;
final int w = image . getWidth ( null ) ;
2011-06-13 23:44:03 +02:00
2011-05-07 09:37:46 +02:00
// in case of not-authorized access shrink the image to prevent
// copyright problems, so that images are not larger than thumbnails
if ( auth ) {
maxwidth = ( maxwidth = = 0 ) ? w : maxwidth ;
maxheight = ( maxheight = = 0 ) ? h : maxheight ;
} else if ( ( w > 16 ) | | ( h > 16 ) ) {
maxwidth = Math . min ( 96 , w ) ;
maxheight = Math . min ( 96 , h ) ;
} else {
maxwidth = 16 ;
maxheight = 16 ;
}
// calculate width & height from maxwidth & maxheight
if ( maxwidth < w | | maxheight < h ) {
// scale image
final double hs = ( w < = maxwidth ) ? 1 . 0 : ( ( double ) maxwidth ) / ( ( double ) w ) ;
final double vs = ( h < = maxheight ) ? 1 . 0 : ( ( double ) maxheight ) / ( ( double ) h ) ;
2011-06-13 23:44:03 +02:00
final double scale = Math . min ( hs , vs ) ;
2011-05-07 09:37:46 +02:00
//if (!auth) scale = Math.min(scale, 0.6); // this is for copyright purpose
if ( scale < 1 . 0 ) {
width = Math . max ( 1 , ( int ) ( w * scale ) ) ;
height = Math . max ( 1 , ( int ) ( h * scale ) ) ;
} else {
width = Math . max ( 1 , w ) ;
height = Math . max ( 1 , h ) ;
}
2011-06-13 23:44:03 +02:00
2011-05-07 09:37:46 +02:00
if ( w ! = width & & h ! = height ) {
// compute scaled image
2011-06-13 23:44:03 +02:00
final Image scaled = image . getScaledInstance ( width , height , Image . SCALE_AREA_AVERAGING ) ;
2011-05-07 09:37:46 +02:00
final MediaTracker mediaTracker = new MediaTracker ( new Container ( ) ) ;
mediaTracker . addImage ( scaled , 0 ) ;
try { mediaTracker . waitForID ( 0 ) ; } catch ( final InterruptedException e ) { }
2011-06-13 23:44:03 +02:00
2011-05-07 09:37:46 +02:00
// make a BufferedImage out of that
2011-06-13 23:44:03 +02:00
final BufferedImage i = new BufferedImage ( width , height , BufferedImage . TYPE_INT_RGB ) ;
2011-05-07 09:37:46 +02:00
try {
2011-06-13 23:44:03 +02:00
i . createGraphics ( ) . drawImage ( scaled , 0 , 0 , width , height , null ) ;
2011-05-07 09:37:46 +02:00
image = i ;
// check outcome
2011-06-13 23:44:03 +02:00
final Raster raster = i . getData ( ) ;
2011-05-07 09:45:02 +02:00
int [ ] pixel = new int [ 3 ] ;
pixel = raster . getPixel ( 0 , 0 , pixel ) ;
if ( pixel [ 0 ] ! = 0 | | pixel [ 1 ] ! = 0 | | pixel [ 2 ] ! = 0 ) image = i ;
2011-06-13 23:44:03 +02:00
} catch ( final Exception e ) {
2011-05-07 09:37:46 +02:00
//java.lang.ClassCastException: [I cannot be cast to [B
}
2011-06-13 23:44:03 +02:00
2011-05-07 09:37:46 +02:00
}
} else {
// do not scale
width = w ;
height = h ;
}
if ( ( height = = 16 ) & & ( width = = 16 ) & & ( resourceb ! = null ) ) {
// this might be a favicon, store image to cache for faster re-load later on
iconcache . put ( urlString , image ) ;
}
}
2011-06-13 23:44:03 +02:00
2011-05-07 09:37:46 +02:00
return image ;
}
2011-06-13 23:44:03 +02:00
2006-04-03 00:59:53 +02:00
}