// Path: ImagingKit_Core/src/main/java/hageldave/imagingkit/core/util/BufferedImageFactory.java
// public class BufferedImageFactory {
// 
// 	private BufferedImageFactory(){}
// 	
// 	/**
// 	 * shortcut for get(img, BufferedImage.TYPE_INT_ARGB).
// 	 * @param img to be copied to BufferedImage of type INT_ARGB
// 	 * @return a BufferedImage copy of the provided Image
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage getINT_ARGB(Image img){
// 		return get(img, BufferedImage.TYPE_INT_ARGB);
// 	}
// 	
// 	/**
// 	 * Creates a new BufferedImage of the specified imgType and same size as 
// 	 * the provided image and draws the provided Image onto the new BufferedImage.
// 	 * @param img to be copied to BufferedImage
// 	 * @param imgType of the BufferedImage. See 
// 	 * {@link BufferedImage#BufferedImage(int, int, int)} for details on the
// 	 * available imgTypes.
// 	 * @return a BufferedImage copy of the provided Image
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage get(Image img, int imgType){
// 		Function<Integer, ImageObserver> obs = flags->{
// 			return (image, infoflags, x, y, width, height)->(infoflags & flags)!=flags;
// 		};
// 		BufferedImage bimg = new BufferedImage(
// 				img.getWidth(obs.apply(ImageObserver.WIDTH)), 
// 				img.getHeight(obs.apply(ImageObserver.HEIGHT)), 
// 				imgType);
// 		Graphics2D gr2D = bimg.createGraphics();
// 		gr2D.drawImage(img, 0, 0, obs.apply(ImageObserver.ALLBITS));
// 				
// 		gr2D.dispose();
// 		
// 		return bimg;
// 	}
// 	
// 	/**
// 	 * Instancing method for BufferedImage of type {@link BufferedImage#TYPE_INT_ARGB}
// 	 * @param d dimension of the created BufferedImage
// 	 * @return a new BufferedImage of specified dimension and type TYPE_INT_ARGB
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage getINT_ARGB(Dimension d){
// 		return getINT_ARGB(d.width, d.height);
// 	}
// 	
// 	/**
// 	 * Instancing method for BufferedImage of type {@link BufferedImage#TYPE_INT_ARGB}
// 	 * @param width of the created BufferedImage
// 	 * @param height of the created BufferedImage
// 	 * @return a new BufferedImage of specified dimension and type TYPE_INT_ARGB
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage getINT_ARGB(int width, int height){
// 		return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// 	}
// }


import javax.imageio.ImageIO;
import hageldave.imagingkit.core.util.BufferedImageFactory;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/*
 * Copyright 2017 David Haegele
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to 
 * deal in the Software without restriction, including without limitation the 
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 * sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
 * IN THE SOFTWARE.
 */

package hageldave.imagingkit.core.io;




/**
 * Class providing convenience methods for saving Images to file.
 * @author hageldave
 * @since 1.0
 */
public class ImageSaver {
	
	private ImageSaver(){}
	
	/**
	 * @return {@link ImageIO#getWriterFileSuffixes()}
	 * @since 1.0
	 */
	public static String[] getSaveableImageFileFormats(){
		return ImageIO.getWriterFileSuffixes();
	}
	
	/**
	 * returns if specified image format supports rgb values only. This means
	 * argb values probably need conversion beforehand.
	 * @param imgFormat the file format e.g. jpg or png
	 * @return true if format only supports rgb values
	 * @since 1.0
	 */
	public static boolean isFormatRGBOnly(String imgFormat){
		switch (imgFormat.toLowerCase()) {
		/* fall through */
		case "jpg":
		case "jpeg":
		case "bmp":
			return true;
		default:
			return false;
		}
	}
	
	public static boolean isFormatBWOnly(String imgFormat){
		switch (imgFormat.toLowerCase()) {
		case "wbmp":
			return true;
		default:
			return false;
		}
	}
	
	/**
	 * Saves specified Image to file of specified img file format.
	 * <p>
	 * Some image file formats may require image type conversion before
	 * saving. This method converts to type INT_RGB for jpg, jpeg and bmp, 
	 * and to type BYTE_BINARY for wbmp.
	 * <p>
	 * The provided {@link OutputStream} will not be closed, this is the
	 * responsibility of the caller.
	 * @param image to be saved
	 * @param os {@link OutputStream} to write image to.
	 * @param imgFileFormat image file format. Consult {@link #getSaveableImageFileFormats()}
	 * to get the supported img file formats of your system. 
	 * @throws ImageSaverException if an IOException occurred during 
	 * the process or no appropriate writer could be found for specified format.
	 * @since 1.1
	 */
	public static void saveImage(Image image, OutputStream os, String imgFileFormat){
		final RenderedImage rImg;
		if( isFormatRGBOnly(imgFileFormat) && !isBufferedImageOfType(image, BufferedImage.TYPE_INT_RGB) ){
// Path: ImagingKit_Core/src/main/java/hageldave/imagingkit/core/util/BufferedImageFactory.java
// public class BufferedImageFactory {
// 
// 	private BufferedImageFactory(){}
// 	
// 	/**
// 	 * shortcut for get(img, BufferedImage.TYPE_INT_ARGB).
// 	 * @param img to be copied to BufferedImage of type INT_ARGB
// 	 * @return a BufferedImage copy of the provided Image
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage getINT_ARGB(Image img){
// 		return get(img, BufferedImage.TYPE_INT_ARGB);
// 	}
// 	
// 	/**
// 	 * Creates a new BufferedImage of the specified imgType and same size as 
// 	 * the provided image and draws the provided Image onto the new BufferedImage.
// 	 * @param img to be copied to BufferedImage
// 	 * @param imgType of the BufferedImage. See 
// 	 * {@link BufferedImage#BufferedImage(int, int, int)} for details on the
// 	 * available imgTypes.
// 	 * @return a BufferedImage copy of the provided Image
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage get(Image img, int imgType){
// 		Function<Integer, ImageObserver> obs = flags->{
// 			return (image, infoflags, x, y, width, height)->(infoflags & flags)!=flags;
// 		};
// 		BufferedImage bimg = new BufferedImage(
// 				img.getWidth(obs.apply(ImageObserver.WIDTH)), 
// 				img.getHeight(obs.apply(ImageObserver.HEIGHT)), 
// 				imgType);
// 		Graphics2D gr2D = bimg.createGraphics();
// 		gr2D.drawImage(img, 0, 0, obs.apply(ImageObserver.ALLBITS));
// 				
// 		gr2D.dispose();
// 		
// 		return bimg;
// 	}
// 	
// 	/**
// 	 * Instancing method for BufferedImage of type {@link BufferedImage#TYPE_INT_ARGB}
// 	 * @param d dimension of the created BufferedImage
// 	 * @return a new BufferedImage of specified dimension and type TYPE_INT_ARGB
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage getINT_ARGB(Dimension d){
// 		return getINT_ARGB(d.width, d.height);
// 	}
// 	
// 	/**
// 	 * Instancing method for BufferedImage of type {@link BufferedImage#TYPE_INT_ARGB}
// 	 * @param width of the created BufferedImage
// 	 * @param height of the created BufferedImage
// 	 * @return a new BufferedImage of specified dimension and type TYPE_INT_ARGB
// 	 * @since 1.0
// 	 */
// 	public static BufferedImage getINT_ARGB(int width, int height){
// 		return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// 	}
// }


// Path: ImagingKit_Core/src/main/java/hageldave/imagingkit/core/io/ImageSaver.java
import javax.imageio.ImageIO;
import hageldave.imagingkit.core.util.BufferedImageFactory;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

/*
 * Copyright 2017 David Haegele
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to 
 * deal in the Software without restriction, including without limitation the 
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 
 * sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
 * IN THE SOFTWARE.
 */

package hageldave.imagingkit.core.io;




/**
 * Class providing convenience methods for saving Images to file.
 * @author hageldave
 * @since 1.0
 */
public class ImageSaver {
	
	private ImageSaver(){}
	
	/**
	 * @return {@link ImageIO#getWriterFileSuffixes()}
	 * @since 1.0
	 */
	public static String[] getSaveableImageFileFormats(){
		return ImageIO.getWriterFileSuffixes();
	}
	
	/**
	 * returns if specified image format supports rgb values only. This means
	 * argb values probably need conversion beforehand.
	 * @param imgFormat the file format e.g. jpg or png
	 * @return true if format only supports rgb values
	 * @since 1.0
	 */
	public static boolean isFormatRGBOnly(String imgFormat){
		switch (imgFormat.toLowerCase()) {
		/* fall through */
		case "jpg":
		case "jpeg":
		case "bmp":
			return true;
		default:
			return false;
		}
	}
	
	public static boolean isFormatBWOnly(String imgFormat){
		switch (imgFormat.toLowerCase()) {
		case "wbmp":
			return true;
		default:
			return false;
		}
	}
	
	/**
	 * Saves specified Image to file of specified img file format.
	 * <p>
	 * Some image file formats may require image type conversion before
	 * saving. This method converts to type INT_RGB for jpg, jpeg and bmp, 
	 * and to type BYTE_BINARY for wbmp.
	 * <p>
	 * The provided {@link OutputStream} will not be closed, this is the
	 * responsibility of the caller.
	 * @param image to be saved
	 * @param os {@link OutputStream} to write image to.
	 * @param imgFileFormat image file format. Consult {@link #getSaveableImageFileFormats()}
	 * to get the supported img file formats of your system. 
	 * @throws ImageSaverException if an IOException occurred during 
	 * the process or no appropriate writer could be found for specified format.
	 * @since 1.1
	 */
	public static void saveImage(Image image, OutputStream os, String imgFileFormat){
		final RenderedImage rImg;
		if( isFormatRGBOnly(imgFileFormat) && !isBufferedImageOfType(image, BufferedImage.TYPE_INT_RGB) ){
			rImg = BufferedImageFactory.get(image, BufferedImage.TYPE_INT_RGB);