/*
 * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package net.java.sip.communicator.util;

import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;

import javax.imageio.*;
import javax.swing.*;

import net.java.sip.communicator.util.swing.*;

/**
 * Utility methods for image manipulation.
 *
 * @author Sebastien Mazy
 * @author Yana Stamcheva
 * @author Lubomir Marinov
 */
public class ImageUtils
{
    private static final Logger logger = Logger.getLogger(ImageUtils.class);

    /**
     * Returns a scaled image fitting within the given bounds while keeping the
     * aspect ratio.
     * 
     * @param image the image to scale
     * @param width maximum width of the scaled image
     * @param height maximum height of the scaled image
     * @return the scaled image
     */
    public static Image scaleImageWithinBounds(Image image, int width,
        int height)
    {
        Image scaledImage;
        int scaleHint = Image.SCALE_SMOOTH;
        double originalRatio =
            (double) image.getWidth(null) / image.getHeight(null);
        double areaRatio = (double) width / height;

        if(originalRatio > areaRatio)
        {
            scaledImage = image.getScaledInstance(width, -1,scaleHint);
        }
        else
        {
            scaledImage = image.getScaledInstance(-1, height, scaleHint);
        }
        return scaledImage;
    }

    public static ImageIcon scaleIconWithinBounds(Image image, int width,
        int height)
    {
        return new ImageIcon(scaleImageWithinBounds(image, width, height));
    }

    /**
     * Creates a rounded avatar image.
     * 
     * @param avatarBytes The bytes of the initial avatar image.
     * 
     * @return The rounded corner image.
     */
    public static Image getScaledRoundedImage(Image image, int width, int height)
    {
        ImageIcon scaledImage =
            ImageUtils.scaleIconWithinBounds(image, width, height);
        int scaledImageWidth = scaledImage.getIconWidth();
        int scaledImageHeight = scaledImage.getIconHeight();

        if(scaledImageHeight <= 0 ||
           scaledImageWidth <= 0)
            return null;

        BufferedImage destImage =
            new BufferedImage(scaledImageWidth, scaledImageHeight,
                BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = destImage.createGraphics();

        try
        {
            AntialiasingManager.activateAntialiasing(g);

            g.setColor(Color.WHITE);
            g.fillRoundRect(0, 0, scaledImageWidth, scaledImageHeight, 10, 10);
            g.setComposite(AlphaComposite.SrcIn);

            g.drawImage(scaledImage.getImage(), 0, 0, null);
        }
        finally
        {
            g.dispose();
        }
        return destImage;
    }

    public static ImageIcon getScaledRoundedIcon(Image image, int width,
        int height)
    {
        return new ImageIcon(getScaledRoundedImage(image, width, height));
    }

    /**
     * Creates a rounded corner scaled image.
     * 
     * @param imageBytes The bytes of the image to be scaled.
     * @param width The maximum width of the scaled image.
     * @param height The maximum height of the scaled image.
     * 
     * @return The rounded corner scaled image.
     */
    public static ImageIcon getScaledRoundedIcon(  byte[] imageBytes,
                                                    int width,
                                                    int height)
    {
        if (imageBytes == null || !(imageBytes.length > 0))
            return null;

        ImageIcon imageIcon = null;

        try
        {
            InputStream in = new ByteArrayInputStream(imageBytes);
            BufferedImage image = ImageIO.read(in);

            if(image != null)
                imageIcon = getScaledRoundedIcon(image, width, height);
            else
                logger.trace("Unknown image format or error reading image");
        }
        catch (Exception e)
        {
            logger.debug("Could not create image.", e);
        }

        return imageIcon;
    }

    /**
     * Returns the buffered image corresponding to the given url image path.
     * 
     * @param imagePath the path indicating, where we can find the image.
     * 
     * @return the buffered image corresponding to the given url image path.
     */
    public static BufferedImage getBufferedImage(URL imagePath)
    {
        BufferedImage image = null;

        if (imagePath == null)
        {
            return null;
        }

        try
        {
            image = ImageIO.read(imagePath);
        }
        catch (Exception exc)
        {
            logger.debug("Failed to load image:" + imagePath, exc);
        }

        return image;
    }
}

@@ -714,33 +714,32 @@
 ct ratio.%0A     *
- 
 %0A     * @param i
@@ -1731,33 +1731,32 @@
 ar image.%0A     *
- 
 %0A     * @param a
@@ -1803,33 +1803,32 @@
 ar image.%0A     *
- 
 %0A     * @return 
@@ -3113,33 +3113,32 @@
 ed image.%0A     *
- 
 %0A     * @param i
@@ -3302,33 +3302,32 @@
 ed image.%0A     *
- 
 %0A     * @return 
@@ -3732,24 +3732,165 @@
    I
-nputStream in = 
+mage image = null;%0A%0A            // sometimes ImageIO fails, will fall back to awt Toolkit%0A            try%0A            %7B%0A                image = ImageIO.read(
 new 
@@ -3921,16 +3921,17 @@
 geBytes)
+)
 ;%0A      
@@ -3940,48 +3940,344 @@
     
-BufferedImage image = ImageIO.read(in);%0A
+%7D catch (Exception e)%0A            %7B%0A                try%0A                %7B%0A                    image = Toolkit.getDefaultToolkit().createImage(imageBytes);%0A                %7D catch (Exception e1)%0A                %7B%0A                    // if it fails throw the original exception%0A                    throw e;%0A                %7D%0A            %7D
 %0A   
@@ -4700,33 +4700,32 @@
 age path.%0A     *
- 
 %0A     * @param i
@@ -4789,17 +4789,16 @@
 .%0A     *
- 
 %0A     * 

Fix issue #648. Some gif files fail to be created as images from javax.imageio.ImageIO, if in such case fall back to java.awt.Toolkit.