annotate servlet/src/digilib/image/ImageLoaderDocuImage.java @ 532:6d66b4ed7f07 digilibPDF

clean up
author robcast
date Fri, 05 Feb 2010 20:59:18 +0100
parents 9cedd170b581
children 87cb3dc2aa12
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
1 /* ImageLoaderDocuImage -- Image class implementation using JDK 1.4 ImageLoader
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
2
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
3 Digital Image Library servlet components
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
4
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
5 Copyright (C) 2002, 2003 Robert Casties (robcast@mail.berlios.de)
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
6
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
7 This program is free software; you can redistribute it and/or modify it
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
8 under the terms of the GNU General Public License as published by the
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
9 Free Software Foundation; either version 2 of the License, or (at your
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
10 option) any later version.
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
11
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
12 Please read license.txt for the full details. A copy of the GPL
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
13 may be found at http://www.gnu.org/copyleft/lgpl.html
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
14
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
15 You should have received a copy of the GNU General Public License
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
16 along with this program; if not, write to the Free Software
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
18 */
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
19
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
20 package digilib.image;
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
21
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
22 import java.awt.Image;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
23 import java.awt.Rectangle;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
24 import java.awt.RenderingHints;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
25 import java.awt.geom.AffineTransform;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
26 import java.awt.geom.Rectangle2D;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
27 import java.awt.image.AffineTransformOp;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
28 import java.awt.image.BufferedImage;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
29 import java.awt.image.ConvolveOp;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
30 import java.awt.image.Kernel;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
31 import java.awt.image.RescaleOp;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
32 import java.io.File;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
33 import java.io.IOException;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
34 import java.io.OutputStream;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
35 import java.io.RandomAccessFile;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
36 import java.util.Arrays;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
37 import java.util.Iterator;
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
38
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
39 import javax.imageio.IIOImage;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
40 import javax.imageio.ImageIO;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
41 import javax.imageio.ImageReadParam;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
42 import javax.imageio.ImageReader;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
43 import javax.imageio.ImageWriteParam;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
44 import javax.imageio.ImageWriter;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
45 import javax.imageio.stream.FileImageInputStream;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
46 import javax.imageio.stream.ImageInputStream;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
47 import javax.imageio.stream.ImageOutputStream;
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
48
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
49 import digilib.io.FileOpException;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
50 import digilib.io.FileOps;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
51 import digilib.io.ImageFile;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
52 import digilib.io.ImageFileset;
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
53
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
54 /** Implementation of DocuImage using the ImageLoader API of Java 1.4 and Java2D. */
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
55 public class ImageLoaderDocuImage extends DocuImageImpl {
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
56
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
57 /** image object */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
58 protected BufferedImage img;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
59
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
60 /** interpolation type */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
61 protected RenderingHints renderHint;
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
62
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
63 /** ImageIO image reader */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
64 protected ImageReader reader;
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
65
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
66 /** File that was read */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
67 protected File imgFile;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
68
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
69 /* loadSubimage is supported. */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
70 public boolean isSubimageSupported() {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
71 return true;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
72 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
73
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
74 public void setQuality(int qual) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
75 quality = qual;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
76 renderHint = new RenderingHints(null);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
77 // hint.put(RenderingHints.KEY_ANTIALIASING,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
78 // RenderingHints.VALUE_ANTIALIAS_OFF);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
79 // setup interpolation quality
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
80 if (qual > 0) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
81 logger.debug("quality q1");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
82 renderHint.put(RenderingHints.KEY_INTERPOLATION,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
83 RenderingHints.VALUE_INTERPOLATION_BICUBIC);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
84 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
85 logger.debug("quality q0");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
86 renderHint.put(RenderingHints.KEY_INTERPOLATION,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
87 RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
88 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
89 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
90
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
91 public int getHeight() {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
92 int h = 0;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
93 try {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
94 if (img == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
95 h = reader.getHeight(0);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
96 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
97 h = img.getHeight();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
98 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
99 } catch (IOException e) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
100 logger.debug("error in getHeight", e);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
101 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
102 return h;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
103 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
104
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
105 public int getWidth() {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
106 int w = 0;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
107 try {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
108 if (img == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
109 w = reader.getWidth(0);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
110 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
111 w = img.getWidth();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
112 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
113 } catch (IOException e) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
114 logger.debug("error in getHeight", e);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
115 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
116 return w;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
117 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
118
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
119 /* returns a list of supported image formats */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
120 public Iterator<String> getSupportedFormats() {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
121 String[] formats = ImageIO.getReaderFormatNames();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
122 return Arrays.asList(formats).iterator();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
123 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
124
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
125 /** Check image size and type and store in ImageFile f */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
126 public boolean identify(ImageFile imgf) throws IOException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
127 // try parent method first
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
128 if (super.identify(imgf)) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
129 return true;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
130 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
131 // fileset to store the information
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
132 ImageFileset imgfs = imgf.getParent();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
133 File f = imgf.getFile();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
134 if (f == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
135 throw new IOException("File not found!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
136 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
137 logger.debug("identifying (ImageIO) " + f);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
138 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
139 * try ImageReader
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
140 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
141 RandomAccessFile raf = new RandomAccessFile(f, "r");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
142 ImageInputStream istream = ImageIO.createImageInputStream(raf);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
143 Iterator<ImageReader> readers = ImageIO.getImageReaders(istream);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
144 if (readers.hasNext()) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
145 ImageReader reader = readers.next();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
146 /* are there more readers? */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
147 logger.debug("ImageIO: this reader: " + reader.getClass());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
148 while (readers.hasNext()) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
149 logger.debug("ImageIO: next reader: "
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
150 + readers.next().getClass());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
151 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
152 try {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
153 reader.setInput(istream);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
154 ImageSize d = new ImageSize(reader.getWidth(0), reader.getHeight(0));
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
155 imgf.setSize(d);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
156 //String t = reader.getFormatName();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
157 String t = FileOps.mimeForFile(f);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
158 imgf.setMimetype(t);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
159 //logger.debug(" format:"+t);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
160 if (imgfs != null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
161 imgfs.setAspect(d);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
162 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
163 return true;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
164 } finally {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
165 // dispose the reader to free resources
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
166 reader.dispose();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
167 raf.close();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
168 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
169 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
170 throw new FileOpException("ERROR: unknown image file format!");
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
171 }
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
172
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
173
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
174 /* load image file */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
175 public void loadImage(ImageFile f) throws FileOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
176 logger.debug("loadImage " + f.getFile());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
177 try {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
178 img = ImageIO.read(f.getFile());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
179 if (img == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
180 throw new FileOpException("Unable to load File!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
181 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
182 } catch (IOException e) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
183 throw new FileOpException("Error reading image.");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
184 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
185 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
186
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
187 /**
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
188 * Get an ImageReader for the image file.
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
189 *
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
190 * @return
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
191 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
192 public ImageReader getReader(ImageFile f) throws IOException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
193 logger.debug("preloadImage " + f.getFile());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
194 if (reader != null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
195 logger.debug("Reader was not null!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
196 // clean up old reader
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
197 dispose();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
198 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
199 // System.gc();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
200 RandomAccessFile rf = new RandomAccessFile(f.getFile(), "r");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
201 ImageInputStream istream = new FileImageInputStream(rf);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
202 // Iterator readers = ImageIO.getImageReaders(istream);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
203 String mt = f.getMimetype();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
204 logger.debug("File type:" + mt);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
205 Iterator<ImageReader> readers = ImageIO.getImageReadersByMIMEType(mt);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
206 if (!readers.hasNext()) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
207 throw new FileOpException("Unable to load File!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
208 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
209 reader = readers.next();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
210 /* are there more readers? */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
211 logger.debug("ImageIO: this reader: " + reader.getClass());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
212 while (readers.hasNext()) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
213 logger.debug("ImageIO: next reader: " + readers.next().getClass());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
214 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
215 // */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
216 reader.setInput(istream);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
217 imgFile = f.getFile();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
218 return reader;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
219 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
220
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
221 /* Load an image file into the Object. */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
222 public void loadSubimage(ImageFile f, Rectangle region, int prescale)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
223 throws FileOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
224 logger.debug("loadSubimage");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
225 // System.gc();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
226 try {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
227 if ((reader == null) || (imgFile != f.getFile())) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
228 getReader(f);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
229 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
230 // set up reader parameters
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
231 ImageReadParam readParam = reader.getDefaultReadParam();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
232 readParam.setSourceRegion(region);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
233 if (prescale > 1) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
234 readParam.setSourceSubsampling(prescale, prescale, 0, 0);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
235 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
236 // read image
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
237 logger.debug("loading..");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
238 img = reader.read(0, readParam);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
239 logger.debug("loaded");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
240 } catch (IOException e) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
241 throw new FileOpException("Unable to load File!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
242 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
243 if (img == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
244 throw new FileOpException("Unable to load File!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
245 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
246 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
247
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
248 /* write image of type mt to Stream */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
249 public void writeImage(String mt, OutputStream ostream)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
250 throws FileOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
251 logger.debug("writeImage");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
252 // setup output
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
253 ImageWriter writer = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
254 ImageOutputStream imgout = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
255 try {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
256 imgout = ImageIO.createImageOutputStream(ostream);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
257 if (mt == "image/jpeg") {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
258 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
259 * JPEG doesn't do transparency so we have to convert any RGBA
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
260 * image to RGB :-( *Java2D BUG*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
261 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
262 if (img.getColorModel().hasAlpha()) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
263 logger.debug("BARF: JPEG with transparency!!");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
264 int w = img.getWidth();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
265 int h = img.getHeight();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
266 // BufferedImage.TYPE_INT_RGB seems to be fastest (JDK1.4.1,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
267 // OSX)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
268 int destType = BufferedImage.TYPE_INT_RGB;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
269 BufferedImage img2 = new BufferedImage(w, h, destType);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
270 img2.createGraphics().drawImage(img, null, 0, 0);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
271 img = img2;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
272 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
273 writer = (ImageWriter) ImageIO.getImageWritersByFormatName(
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
274 "jpeg").next();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
275 if (writer == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
276 throw new FileOpException("Unable to get JPEG writer");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
277 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
278 ImageWriteParam param = writer.getDefaultWriteParam();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
279 if (quality > 1) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
280 // change JPEG compression quality
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
281 param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
282 //logger.debug("JPEG qual before: "
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
283 // + Float.toString(param.getCompressionQuality()));
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
284 param.setCompressionQuality(0.9f);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
285 //logger.debug("JPEG qual now: "
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
286 // + Float.toString(param.getCompressionQuality()));
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
287 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
288 writer.setOutput(imgout);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
289 // render output
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
290 logger.debug("writing");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
291 writer.write(null, new IIOImage(img, null, null), param);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
292 } else if (mt == "image/png") {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
293 // render output
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
294 writer = (ImageWriter) ImageIO.getImageWritersByFormatName(
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
295 "png").next();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
296 if (writer == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
297 throw new FileOpException("Unable to get PNG writer");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
298 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
299 writer.setOutput(imgout);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
300 logger.debug("writing");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
301 writer.write(img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
302 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
303 // unknown mime type
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
304 throw new FileOpException("Unknown mime type: " + mt);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
305 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
306
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
307 } catch (IOException e) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
308 throw new FileOpException("Error writing image.");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
309 } finally {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
310 // clean up
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
311 if (writer != null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
312 writer.dispose();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
313 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
314 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
315 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
316
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
317 public void scale(double scale, double scaleY) throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
318 logger.debug("scale");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
319 /* for downscaling in high quality the image is blurred first */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
320 if ((scale <= 0.5) && (quality > 1)) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
321 int bl = (int) Math.floor(1 / scale);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
322 blur(bl);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
323 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
324 /* then scaled */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
325 AffineTransformOp scaleOp = new AffineTransformOp(AffineTransform
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
326 .getScaleInstance(scale, scale), renderHint);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
327 BufferedImage scaledImg = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
328 // enforce destination image type (*Java2D BUG*)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
329 int type = img.getType();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
330 // FIXME: which type would be best?
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
331 if ((quality > 0) && (type != 0)) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
332 logger.debug("creating destination image");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
333 Rectangle2D dstBounds = scaleOp.getBounds2D(img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
334 scaledImg = new BufferedImage((int) dstBounds.getWidth(),
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
335 (int) dstBounds.getHeight(), type);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
336 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
337 logger.debug("scaling...");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
338 scaledImg = scaleOp.filter(img, scaledImg);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
339 if (scaledImg == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
340 throw new ImageOpException("Unable to scale");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
341 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
342 // DEBUG
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
343 logger.debug("destination image type " + scaledImg.getType());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
344 logger.debug("SCALE: " + scale + " ->" + scaledImg.getWidth() + "x"
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
345 + scaledImg.getHeight());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
346 img = scaledImg;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
347 scaledImg = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
348 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
349
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
350 public void blur(int radius) throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
351 // DEBUG
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
352 logger.debug("blur: " + radius);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
353 // minimum radius is 2
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
354 int klen = Math.max(radius, 2);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
355 // FIXME: use constant kernels for most common sizes
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
356 int ksize = klen * klen;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
357 // kernel is constant 1/k
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
358 float f = 1f / ksize;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
359 float[] kern = new float[ksize];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
360 for (int i = 0; i < ksize; i++) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
361 kern[i] = f;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
362 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
363 Kernel blur = new Kernel(klen, klen, kern);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
364 // blur with convolve operation
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
365 ConvolveOp blurOp = new ConvolveOp(blur, ConvolveOp.EDGE_NO_OP,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
366 renderHint);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
367 // blur needs explicit destination image type for color *Java2D BUG*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
368 BufferedImage blurredImg = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
369 if (img.getType() == BufferedImage.TYPE_3BYTE_BGR) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
370 blurredImg = new BufferedImage(img.getWidth(), img.getHeight(), img
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
371 .getType());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
372 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
373 blurredImg = blurOp.filter(img, blurredImg);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
374 if (blurredImg == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
375 throw new ImageOpException("Unable to scale");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
376 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
377 img = blurredImg;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
378 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
379
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
380 public void crop(int x_off, int y_off, int width, int height)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
381 throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
382 // setup Crop
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
383 BufferedImage croppedImg = img.getSubimage(x_off, y_off, width, height);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
384 // DEBUG
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
385 // util.dprintln(2, " time
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
386 // "+(System.currentTimeMillis()-startTime)+"ms");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
387 if (croppedImg == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
388 throw new ImageOpException("Unable to crop");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
389 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
390 logger.debug("CROP:" + croppedImg.getWidth() + "x"
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
391 + croppedImg.getHeight());
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
392 img = croppedImg;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
393 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
394
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
395 public void enhance(float mult, float add) throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
396 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
397 * Only one constant should work regardless of the number of bands
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
398 * according to the JDK spec. Doesn't work on JDK 1.4 for OSX and Linux
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
399 * (at least). RescaleOp scaleOp = new RescaleOp( (float)mult,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
400 * (float)add, null); scaleOp.filter(img, img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
401 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
402
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
403 /* The number of constants must match the number of bands in the image. */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
404 int ncol = img.getColorModel().getNumComponents();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
405 float[] dm = new float[ncol];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
406 float[] da = new float[ncol];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
407 for (int i = 0; i < ncol; i++) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
408 dm[i] = (float) mult;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
409 da[i] = (float) add;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
410 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
411 RescaleOp scaleOp = new RescaleOp(dm, da, null);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
412 scaleOp.filter(img, img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
413 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
414
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
415 public void enhanceRGB(float[] rgbm, float[] rgba) throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
416
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
417 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
418 * The number of constants must match the number of bands in the image.
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
419 * We do only 3 (RGB) bands.
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
420 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
421
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
422 int ncol = img.getColorModel().getNumColorComponents();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
423 if ((ncol != 3) || (rgbm.length != 3) || (rgba.length != 3)) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
424 logger
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
425 .debug("ERROR(enhance): unknown number of color bands or coefficients ("
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
426 + ncol + ")");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
427 return;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
428 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
429 RescaleOp scaleOp = new RescaleOp(rgbOrdered(rgbm), rgbOrdered(rgba),
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
430 null);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
431 scaleOp.filter(img, img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
432 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
433
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
434 /**
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
435 * Ensures that the array f is in the right order to map the images RGB
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
436 * components. (not shure what happens
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
437 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
438 public float[] rgbOrdered(float[] fa) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
439 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
440 * TODO: this is UGLY, UGLY!!
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
441 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
442 float[] fb;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
443 int t = img.getType();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
444 if (img.getColorModel().hasAlpha()) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
445 fb = new float[4];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
446 if ((t == BufferedImage.TYPE_INT_ARGB)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
447 || (t == BufferedImage.TYPE_INT_ARGB_PRE)) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
448 // RGB Type
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
449 fb[0] = fa[0];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
450 fb[1] = fa[1];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
451 fb[2] = fa[2];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
452 fb[3] = 1f;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
453 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
454 // this isn't tested :-(
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
455 fb[0] = 1f;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
456 fb[1] = fa[0];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
457 fb[2] = fa[1];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
458 fb[3] = fa[2];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
459 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
460 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
461 fb = new float[3];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
462 if (t == BufferedImage.TYPE_3BYTE_BGR) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
463 // BGR Type (actually it looks like RBG...)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
464 fb[0] = fa[0];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
465 fb[1] = fa[2];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
466 fb[2] = fa[1];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
467 } else {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
468 fb[0] = fa[0];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
469 fb[1] = fa[1];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
470 fb[2] = fa[2];
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
471 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
472 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
473 return fb;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
474 }
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
475
531
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
476 public void rotate(double angle) throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
477 // setup rotation
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
478 double rangle = Math.toRadians(angle);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
479 // create offset to make shure the rotated image has no negative
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
480 // coordinates
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
481 double w = img.getWidth();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
482 double h = img.getHeight();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
483 AffineTransform trafo = new AffineTransform();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
484 // center of rotation
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
485 double x = (w / 2);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
486 double y = (h / 2);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
487 trafo.rotate(rangle, x, y);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
488 // try rotation to see how far we're out of bounds
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
489 AffineTransformOp rotOp = new AffineTransformOp(trafo, renderHint);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
490 Rectangle2D rotbounds = rotOp.getBounds2D(img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
491 double xoff = rotbounds.getX();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
492 double yoff = rotbounds.getY();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
493 // move image back in line
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
494 trafo
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
495 .preConcatenate(AffineTransform.getTranslateInstance(-xoff,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
496 -yoff));
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
497 // transform image
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
498 rotOp = new AffineTransformOp(trafo, renderHint);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
499 BufferedImage rotImg = rotOp.filter(img, null);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
500 // calculate new bounding box
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
501 // Rectangle2D bounds = rotOp.getBounds2D(img);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
502 if (rotImg == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
503 throw new ImageOpException("Unable to rotate");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
504 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
505 img = rotImg;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
506 // crop new image (with self-made rounding)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
507 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
508 * img = rotImg.getSubimage( (int) (bounds.getX()+0.5), (int)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
509 * (bounds.getY()+0.5), (int) (bounds.getWidth()+0.5), (int)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
510 * (bounds.getHeight()+0.5));
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
511 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
512 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
513
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
514 public void mirror(double angle) throws ImageOpException {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
515 // setup mirror
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
516 double mx = 1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
517 double my = 1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
518 double tx = 0;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
519 double ty = 0;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
520 if (Math.abs(angle - 0) < epsilon) { // 0 degree
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
521 mx = -1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
522 tx = getWidth();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
523 } else if (Math.abs(angle - 90) < epsilon) { // 90 degree
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
524 my = -1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
525 ty = getHeight();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
526 } else if (Math.abs(angle - 180) < epsilon) { // 180 degree
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
527 mx = -1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
528 tx = getWidth();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
529 } else if (Math.abs(angle - 270) < epsilon) { // 270 degree
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
530 my = -1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
531 ty = getHeight();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
532 } else if (Math.abs(angle - 360) < epsilon) { // 360 degree
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
533 mx = -1;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
534 tx = getWidth();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
535 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
536 AffineTransformOp mirOp = new AffineTransformOp(new AffineTransform(mx,
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
537 0, 0, my, tx, ty), renderHint);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
538 BufferedImage mirImg = mirOp.filter(img, null);
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
539 if (mirImg == null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
540 throw new ImageOpException("Unable to mirror");
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
541 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
542 img = mirImg;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
543 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
544
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
545 /*
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
546 * (non-Javadoc)
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
547 *
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
548 * @see java.lang.Object#finalize()
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
549 */
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
550 protected void finalize() throws Throwable {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
551 dispose();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
552 super.finalize();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
553 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
554
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
555 public void dispose() {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
556 // we must dispose the ImageReader because it keeps the filehandle
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
557 // open!
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
558 if (reader != null) {
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
559 reader.dispose();
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
560 reader = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
561 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
562 img = null;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
563 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
564
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
565 public Image getImage(){
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
566 return (Image) img;
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
567 }
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
568
9cedd170b581 * PDF generation works now even with subdirectories
robcast
parents: 1
diff changeset
569
1
0ff3ede32060 Initial revision
robcast
parents:
diff changeset
570 }