EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.comic]

COVERAGE SUMMARY FOR SOURCE FILE [CreateCbzComicTask.java]

nameclass, %method, %block, %line, %
CreateCbzComicTask.java100% (1/1)100% (7/7)81%  (320/394)93%  (68.5/74)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CreateCbzComicTask100% (1/1)100% (7/7)81%  (320/394)93%  (68.5/74)
CreateCbzComicTask (File, String [], Map, File, Conversion): void 100% (1/1)66%  (40/61)81%  (8.1/10)
cleanUpComic (): void 100% (1/1)78%  (21/27)96%  (6.7/7)
<static initializer> 100% (1/1)80%  (12/15)80%  (0.8/1)
createInputStream (RenderedImage, String): InputStream 100% (1/1)81%  (22/27)97%  (6.8/7)
addImageFile (String, File): void 100% (1/1)85%  (186/220)93%  (35.2/38)
addZipEntry (String, File, InputStream): void 100% (1/1)85%  (28/33)98%  (8.8/9)
setUpComic (): void 100% (1/1)100% (11/11)100% (2/2)

1// Jomic - a viewer for comic book archives.
2// Copyright (C) 2004-2008 Thomas Aglassinger
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program.  If not, see <http://www.gnu.org/licenses/>.
16package net.sf.jomic.comic;
17 
18import java.awt.image.RenderedImage;
19import java.io.ByteArrayInputStream;
20import java.io.ByteArrayOutputStream;
21import java.io.File;
22import java.io.FileInputStream;
23import java.io.FileOutputStream;
24import java.io.IOException;
25import java.io.InputStream;
26import java.util.Map;
27import java.util.zip.Deflater;
28import java.util.zip.ZipEntry;
29import java.util.zip.ZipException;
30import java.util.zip.ZipOutputStream;
31 
32import javax.imageio.ImageIO;
33import javax.imageio.stream.ImageInputStream;
34 
35import net.sf.jomic.tools.FileTools;
36import net.sf.jomic.tools.ImageInfo;
37import net.sf.jomic.tools.ImageTools;
38import net.sf.jomic.tools.StringTools;
39import net.sf.wraplog.Logger;
40 
41/**
42 *  Task to create a CBZ comic from a set of image files.
43 *
44 * @author    Thomas Aglassinger
45 */
46// TODO: Use antzip to encode zipped filenames using ISO-Latin1.
47public class CreateCbzComicTask extends AbstractCreateComicTask
48{
49    private static final double STEP_WEIGHT_READ_IMAGE = 0.333;
50    private static final double STEP_WEIGHT_TRIM_IMAGE = 0.667;
51 
52    private FileTools fileTools;
53    private ImageTools imageTools;
54    private Logger logger;
55    private ZipOutputStream out;
56    private StringTools stringTools;
57 
58    /**
59     *  Create a new task to create a CBZ comic.
60     *
61     * @param  newSourceBaseDir    the base directory where the source files are located
62     * @param  newSourceFileNames  the names of the files relative to <code>newSourceBaseDir</code>
63     *      that should be included in the archive
64     * @param  newComicInfoMap     Description of the parameter
65     * @param  newTargetZipFile    the ZIP file to create
66     * @param  newConversion       a conversion specifying the format and image manipulations of the
67     *      new comic; if null, the default will be a conversion creating a CBZ including all the
68     *      images specified.
69     */
70    public CreateCbzComicTask(File newSourceBaseDir, String[] newSourceFileNames,
71            Map newComicInfoMap, File newTargetZipFile, Conversion newConversion) {
72        super(newSourceBaseDir, newSourceFileNames, newComicInfoMap, newTargetZipFile, newConversion);
73        assert newTargetZipFile != null;
74        assert newSourceBaseDir != null;
75        assert newSourceFileNames != null;
76        assert newSourceFileNames.length > 0;
77        logger = Logger.getLogger(CreateCbzComicTask.class);
78        fileTools = FileTools.instance();
79        imageTools = ImageTools.instance();
80        stringTools = StringTools.instance();
81    }
82 
83    protected void setUpComic()
84        throws Exception {
85        out = new ZipOutputStream(new FileOutputStream(getTargetComicFile()));
86    }
87 
88    protected void addImageFile(String outImageName, File sourceImageFile)
89        throws Exception {
90        assert out != null;
91        assert outImageName != null;
92        assert sourceImageFile != null;
93        ImageInputStream sourceImageStream = ImageIO.createImageInputStream(sourceImageFile);
94        int compressionLevel = Deflater.DEFAULT_COMPRESSION;
95 
96        if (sourceImageStream != null) {
97            try {
98                ImageInfo imageInfo = getImageInfo(sourceImageFile);
99                long baseProgress = getProgress();
100 
101                if (getConversion().isAddable(imageInfo)) {
102                    String sourceImageFormat = imageInfo.getFormat();
103                    String targetImageFormat = getConversion().getImageFormatName(sourceImageFormat);
104                    boolean needsNewFormat = !sourceImageFormat.equals(targetImageFormat);
105                    boolean needsTrim = getConversion().needsTrim(sourceImageFile);
106                    long inFileLength = sourceImageFile.length();
107 
108                    if (logger.isInfoEnabled()) {
109                        logger.info("add " + stringTools.sourced(sourceImageFile) + " as "
110                                + stringTools.sourced(outImageName));
111                    }
112 
113                    InputStream in;
114 
115                    if (needsTrim || needsNewFormat) {
116                        RenderedImage image = imageTools.readImage(sourceImageFile);
117 
118                        setProgress(baseProgress + Math.round(STEP_WEIGHT_READ_IMAGE * inFileLength));
119                        if (needsTrim) {
120                            image = getConversion().getTrimmed(image);
121                        }
122                        in = createInputStream(image, targetImageFormat);
123                        setProgress(baseProgress + Math.round(STEP_WEIGHT_TRIM_IMAGE * inFileLength));
124                    } else {
125                        in = new FileInputStream(sourceImageFile);
126                    }
127                    if (imageTools.isCompressedImageFormat(targetImageFormat)) {
128                        compressionLevel = Deflater.NO_COMPRESSION;
129                    }
130                    out.setLevel(compressionLevel);
131                    addZipEntry(outImageName, sourceImageFile, in);
132                } else {
133                    if (logger.isInfoEnabled()) {
134                        if (imageInfo.hasError()) {
135                            logger.info("ignoring broken image: " + stringTools.sourced(sourceImageFile),
136                                    imageInfo.getError());
137                        } else {
138                            logger.info("skipping non-image: " + stringTools.sourced(sourceImageFile)
139                                    + "; format=" + imageInfo.getFormat() + ", size=" + imageInfo.getSize());
140                        }
141                    }
142                }
143                setProgress(baseProgress + sourceImageFile.length() + 1);
144            } finally {
145                sourceImageStream.close();
146            }
147        }
148    }
149 
150    protected void cleanUpComic()
151        throws Exception {
152        if (out != null) {
153            try {
154                out.close();
155            } catch (ZipException error) {
156                logger.warn("ignoring attempt to close zip file without entries", error);
157            } finally {
158                out = null;
159            }
160        }
161    }
162 
163    private void addZipEntry(String outName, File sourceImageFile, InputStream in)
164        throws IOException {
165        try {
166            ZipEntry zipEntry = new ZipEntry(outName);
167 
168            zipEntry.setTime(sourceImageFile.lastModified());
169            out.putNextEntry(zipEntry);
170            fileTools.copy(in, out);
171            enableAddedAtLeastOneImage();
172        } finally {
173            in.close();
174        }
175        out.closeEntry();
176    }
177 
178    private InputStream createInputStream(RenderedImage image, String imageFormat)
179        throws IOException {
180        InputStream result;
181        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
182 
183        try {
184            ImageIO.write(image, imageFormat, byteStream);
185 
186            byte[] imageData = byteStream.toByteArray();
187 
188            result = new ByteArrayInputStream(imageData);
189        } finally {
190            byteStream.close();
191        }
192        return result;
193    }
194}

[all classes][net.sf.jomic.comic]
EMMA 2.0.4217 (C) Vladimir Roubtsov