package de.danielsenff.dropps; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.DefaultListModel; import javax.swing.JOptionPane; import org.jdesktop.application.Application; import util.FileUtil; import util.ImageIOUtils; import ddsutil.DDSUtil; import ddsutil.MipMapsUtil; import de.danielsenff.dropps.models.ExportOptions; import de.danielsenff.dropps.models.IConvertListener; import de.danielsenff.dropps.models.IProgressListener; import de.danielsenff.dropps.models.IProgressObserverable; import de.danielsenff.dropps.models.ProgressStatus; import de.danielsenff.dropps.models.TextureImageFormatLoaderTGA; /** * Controller for the conversion process. This actually does the work. * @author dahie * */ public class ConvertController implements IProgressObserverable { private static final Logger logger = Logger.getLogger(ConvertController.class.getName()); protected final List<IConvertListener> convertListeners = new ArrayList<IConvertListener>(1); protected final List<IProgressListener> progressListeners = new ArrayList<IProgressListener>(1); //constants for messages regarding the conversion process public static final String ERROR_FILE_IO = "errorFileIOMessage"; public static final String ERROR_THREAD_INTERUPTION = "errorGeneralMessage"; public static final String ERROR_ORIGINAL_FILE_PATH_NULL = "errorOriginalFilePathNull"; public static final String ERROR_ORIGINAL_FILE_NOT_EXISTS = "errorOriginalFileNotExists"; public static final String ERROR_CANT_CREATE_CONVERTED_FILE = "errorCantCreateConvertedFile"; private final ExportOptions options; /** * @param options */ public ConvertController(final ExportOptions options) { this.options = options; } /** * Convert a bunch of files * @param files * @param options */ public void convertFiles(final Collection<File> files) { int i = 0; for (final File file : files) { convertFile(file, i, files.size()); i++; } } /** * Process a single file * @param file * @param options * @param i * @param filesCount */ private void convertFile(final File file, final int i, final int filesCount) { System.out.println("Process: "+file); notifyConversionBegin(file); notifyProgressListeners(new ProgressStatus(i, filesCount, "progress")); BufferedImage imageToConvert = null; final DefaultListModel dlm = (DefaultListModel) ((DroppsView)((Dropps)Application.getInstance()).getMainView()).getDropPanel().getModel(); try { System.out.println("Read BufferedImage ..."); //check if is folder if(file.isDirectory()) { dlm.removeElement(file); notifyError(new ProgressStatus(i, filesCount, "unsupportedFolder_"+file.getName(), true)); return; } // check supported fileformats if(!isFiletypeSupported(file)) { dlm.removeElement(file); notifyError(new ProgressStatus(i, filesCount, "unsupportedFileformat_"+file.getName(), true)); return; } InputStream fis = new FileInputStream(file); if(ImageIOUtils.isImageIOSupported(file)) { imageToConvert = ImageIO.read(fis); fis.close(); System.out.println(imageToConvert.getType()); } else if (FileUtil.getFileSuffix(file).contains("tex")) { imageToConvert = DDSUtil.decompressTexture(file); } else if (FileUtil.getFileSuffix(file).contains("tga")) { try { final TextureImageFormatLoaderTGA loader = new TextureImageFormatLoaderTGA(); final BufferedInputStream in = new BufferedInputStream(fis); imageToConvert = loader.loadTextureImage(in , true, false); fis.close(); } catch (final Exception ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(Dropps.getApplication().getMainFrame(), "<html>Error: The TGA-file could not be loaded. Only 32bit TGA are supported." + "<br>The operation is aborted. </html>", "Error", JOptionPane.ERROR_MESSAGE); fis.close(); } } if(imageToConvert != null) { final String convertedFile = file.getAbsolutePath().substring(0,file.getAbsolutePath().lastIndexOf('.')); final File newFile = new File(convertedFile+".dds"); // check image dimensions if (!MipMapsUtil.isPowerOfTwo(imageToConvert.getWidth()) && !MipMapsUtil.isPowerOfTwo(imageToConvert.getHeight()) && options.hasGeneratedMipMaps()) { dlm.removeElement(file); notifyError(new ProgressStatus(i, filesCount, "notPowerOf2_"+file.getName(), true)); return; } System.out.println("Begin conversion ..."); // exclude this into an Converter with appropriate listeners DDSUtil.write(newFile, imageToConvert, options.getNewPixelformat(), options.hasGeneratedMipMaps()); } } catch (final IOException e) { e.printStackTrace(); // showErrorDialog(e.getMessage()); } catch (final OutOfMemoryError e) { e.printStackTrace(); final long mem0 = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory(); JOptionPane.showMessageDialog(null, "<html>Error: Out of memory: " + mem0 + "<br>The operation is aborted. </html>", "Error", JOptionPane.ERROR_MESSAGE); } dlm.removeElement(file); notifyConversionEnd(file); } private boolean isFiletypeSupported(final File file) { if(ImageIOUtils.isImageIOSupported(file) || FileUtil.getFileSuffix(file).contains("tex") || FileUtil.getFileSuffix(file).contains("tga") ) return true; return false; } protected void notifyProgressListeners(final ProgressStatus status) { for (final IProgressListener iProgressListener : progressListeners) { iProgressListener.update(status); } } protected void notifyConversionBegin(final File originalFile) { for (final IConvertListener iConvertListener : convertListeners) { iConvertListener.convertBegin(originalFile); } } protected void notifyConversionEnd(final File originalFile) { for (final IConvertListener iConvertListener : convertListeners) { iConvertListener.convertEnd(originalFile); } } protected void notifyError(final ProgressStatus status) { for (final IProgressListener iProgressListener : progressListeners) { iProgressListener.error(status); } } protected boolean checkConvertFileExists(final File originalFile) { if (!originalFile.exists()) { notifyError(new ProgressStatus(0, 0, ERROR_ORIGINAL_FILE_NOT_EXISTS, true)); logger.log(Level.SEVERE, ERROR_ORIGINAL_FILE_NOT_EXISTS); return false; } return true; } public void addListener(final IConvertListener listener) { convertListeners.add(listener); } public void removeListener(final IConvertListener listener) { convertListeners.remove(listener); } @Override public void addListener(final IProgressListener listener) { progressListeners.add(listener); } @Override public void removeListener(final IProgressListener listener) { progressListeners.remove(listener); } }