1
6
7 import java.lang.ref.*;
8 import java.awt.geom.*;
9 import java.awt.image.*;
10 import java.awt.*;
11 import java.util.*;
12
13 public class ImageJob extends CacheRef implements java.io.Serializable{
14
15 private static final long serialVersionUID = Version.getSUID();
16
17 public static double SCALEFACT = 2;
18
19 public int index;
20 public double scale;
21 public Segment seg;
22 public AffineTransform trans;
23 AffineTransform rtrans;
24
25 transient HashSet users = new HashSet();;
26
27 public transient boolean pending = false;
28
29 public ImageJob(Segment seg,int index) {
30
31 this.seg = seg;
32 this.index = index;
33
34 scale = 1;
35 for (int i=0;i<index;i++) scale *= SCALEFACT;
36
37 rtrans = (AffineTransform)seg.map.overlaytrans.clone();
38 rtrans.scale(1/scale,1/scale);
39 }
40
41 public boolean equals(Object that) {
42 return((that instanceof ImageJob) &&
43 ((ImageJob)that).seg == seg &&
44 ((ImageJob)that).index == index);
45 }
46
47 public int hashCode() {
48 return(seg.hashCode() + index);
49 }
50
51 public boolean check() {
52 return(rtrans!=null && (trans!=null || ref==null));
53 }
54
55 public String toString() {
56 return(seg.getName()+" index = "+index+" scale = "+scale);
57 }
58
59 public void setImage(BufferedImage image) {
60 if (image!=null && getTrans()!=null) {
61 set(image);
62 }
63 }
64
65
66 public AffineTransform getTrans() {
67 if (trans != null) return(trans);
68
69 if (rtrans==null) {
70 rtrans = (AffineTransform)seg.map.overlaytrans.clone();
71 rtrans.scale(1/scale,1/scale);
72 }
73
74 Rectangle2D bounds = seg.getBounds(rtrans);
75 try {
76 trans = rtrans.createInverse();
77 } catch (Exception e) {
78 ErrorLog.exception(e,"Error reducing segment "+seg.name);
79 ref = null;
80 return(null);
81 }
82 trans.translate(bounds.getX(),bounds.getY());
83 return(trans);
84 }
85
86
87
101
102 public void addUser(Component user) {
103 if (isReady()) user.repaint();
104 else
105 if (users==null) users = new HashSet();
106 synchronized(users) {
107 users.add(new TransparentWeakReference(user));
108 }
109 }
110
111 public boolean load() {
112
113 seg.solve();
114
115 if (index!=0 && Segment.dobig)
116 seg.cookers[0].load();
117
118 if (!lock(true)) {
119
120 for (int s=index-1;s>=0;s--) {
121 BufferedImage big = (BufferedImage)seg.cookers[s].get();
122 if (big!=null) {
123 int fact = 1<<(index-s);
124 int w = big.getWidth()/fact;
125 int h = big.getHeight()/fact;
126 BufferedImage res = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
127 Raster bigrast = big.getRaster();
128 WritableRaster small = res.getRaster();
129 int[] pixel = null;
130 for (int i=0;i<w;i++)
131 for (int j=0;j<h;j++) {
132 pixel = bigrast.getPixel(i*fact,j*fact,pixel);
133 small.setPixel(i,j,pixel);
134 }
135 big=null;
136 bigrast=null;
137 small=null;
138
139 setImage(res);
140
141
142
143
144
145
146
147
148
149
150
151
152 lock(true);
153 res=null;
154
155 break;
156 }
157 }
158
159 if (!lock(true)) {
160
161 Image rawimage=seg.isource.getImage();
162
163 Rectangle2D bounds = seg.getBounds(rtrans);
164
165 if (Double.isInfinite(bounds.getWidth()) || Double.isNaN(bounds.getWidth())) {
166 System.out.println("bad width "+bounds.getWidth());
167 ErrorLog.log("bad width "+bounds.getWidth());
168 ref=null;
169 return(false);
170 }
171
172
173 BufferedImage res = null;
174 try {
175
176 res = seg.map.getImage(rawimage,rtrans,bounds,seg.boundary,
177 seg.name+" (%"+(int)(100/scale)+" size) ",seg.transparent);
178
179
180
181
182
183
184
185
186 } catch (Exception e) {
187 ErrorLog.exception(e,"Error morphing segment "+seg.name);
188 ref = null;
189 return(false);
190 } finally {
191 CartoFrame.message.setText("");
192 rawimage = null;
193 }
194 setImage(res);
195 lock(true);
196 res = null;
197 }
198 }
199
200 if (Segment.thumbs) {
201 if (index<Segment.levels-1) {
202 seg.cookers[Segment.levels-1].load();
203 seg.cookers[Segment.levels-1].lock(false);
204 }
205 else
206 seg.thumbnail = (BufferedImage)get();
207 }
208
209 if (users!=null)
210 synchronized(users) {
211 ImageThread.addUsers(users);
212 users.clear();
213 }
214
215
216 return(true);
217 }
218
219 static Color[] dbgcolors = {Color.RED,Color.GREEN,Color.BLUE,Color.YELLOW,Color.PINK};
220 static int dbgcnt = 0;
221
222 public boolean isReady() {
223 return(ref!=null);
224 }
225 }
226