001/**
002 * Copyright (C) 2014  Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/
003 *
004 * This file is part of Dicoogle/dicoogle.
005 *
006 * Dicoogle/dicoogle is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * Dicoogle/dicoogle is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with Dicoogle.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package pt.ua.dicoogle.server.web.utils;
020
021import java.awt.image.BufferedImage;
022import java.io.IOException;
023import java.io.InputStream;
024import java.util.Iterator;
025import javax.imageio.ImageIO;
026import javax.imageio.ImageReader;
027import javax.imageio.stream.ImageInputStream;
028import org.dcm4che2.imageio.plugins.dcm.DicomImageReadParam;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031import pt.ua.dicoogle.sdk.StorageInputStream;
032
033/**
034 * A utility library for loading images.
035 *
036 * @author Eduardo Pinho <eduardopinho@ua.pt>
037 */
038public class ImageLoader {
039    
040    private ImageLoader() {
041    }
042    
043    static {
044        ImageIO.scanForPlugins();
045    }
046    
047    /**
048     * Obtain an image from an ordinary input stream. This method will attempt to automatically use the
049     * appropriate image reader for the image's format, including DICOM.
050     *
051     * @param inputStream the input stream to retrieve the image from
052     * @return a buffered image
053     * @throws IOException if the image format is not supported or another IO issue occurred
054     */
055    public static BufferedImage loadImage(InputStream inputStream) throws IOException {
056        BufferedImage image;
057        try (ImageInputStream imageInputStream
058                = ImageIO.createImageInputStream(inputStream)) {
059
060            Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream);
061            if (!readers.hasNext()) {
062                throw new IOException("Unsupported image format");
063            }
064            ImageReader reader = readers.next();
065            reader.setInput(imageInputStream, false);
066            if (reader.getFormatName().equalsIgnoreCase("DICOM")) {
067                DicomImageReadParam param = (DicomImageReadParam) reader.getDefaultReadParam();
068                image = reader.read(0, param);
069            } else {
070                image = reader.read(0);
071            }
072        } catch (org.dcm4che2.data.ConfigurationError | IOException ex) {
073            LoggerFactory.getLogger(ImageLoader.class).debug("Failed to load image reader, attempting special DICOM reading mechanism", ex);
074            image = loadDICOMImage(inputStream);
075        }
076        return image;
077    }
078    
079    /**
080     * Obtain an image from a Dicoogle storage input stream. This method will attempt to automatically use the
081     * appropriate image reader for the image's format, including DICOM.
082     *
083     * @param imageFromStorage the storage input stream to retrieve the image from
084     * @return a buffered image
085     * @throws IOException if the image format is not supported or another IO issue occurred
086     */
087    public static BufferedImage loadImage(StorageInputStream imageFromStorage) throws IOException {
088        return loadImage(imageFromStorage.getInputStream());
089    }
090
091    /**
092     * Obtain a DICOM image from an orginary input stream. This method will attempt to read the file in
093     * storage as a DICOM file only.
094     *
095     * @param inputStream the input stream to retrieve the DICOM image from
096     * @return a buffered image
097     * @throws IOException if the image format is not DICOM or another IO issue occurred
098     */
099    public static BufferedImage loadDICOMImage(InputStream inputStream) throws IOException {
100        try (ImageInputStream imageInputStream
101                = ImageIO.createImageInputStream(inputStream)) {
102            Iterator<ImageReader> iter = ImageIO.getImageReadersByFormatName("DICOM");
103            ImageReader reader = iter.next();
104            DicomImageReadParam param = (DicomImageReadParam) reader.getDefaultReadParam();
105            reader.setInput(imageInputStream, false);
106            BufferedImage img = reader.read(0, param);
107            return img;
108        }
109    }
110    
111    /**
112     * Obtain a DICOM from a Dicoogle storage input stream. This method will attempt to read the file in
113     * storage as a DICOM file only.
114     *
115     * @param imageFromStorage the storage input stream to retrieve the DICOM image from
116     * @return a buffered image
117     * @throws IOException if the image format is not DICOM or another IO issue occurred
118     */
119    public static BufferedImage loadDICOMImage(StorageInputStream imageFromStorage) throws IOException {
120        return loadDICOMImage(imageFromStorage.getInputStream());
121    }
122}