1
2
3
4
5
6
7
8 package com.buckosoft.PicMan.business.mosaic.engine;
9
10 import java.awt.Graphics2D;
11 import java.awt.image.BufferedImage;
12 import java.util.Iterator;
13 import java.util.List;
14
15 import org.apache.commons.logging.Log;
16 import org.apache.commons.logging.LogFactory;
17
18 import com.buckosoft.PicMan.business.mosaic.MosaicEngine;
19 import com.buckosoft.PicMan.domain.MosaicTile;
20 import com.buckosoft.PicMan.domain.Pic;
21
22
23
24
25
26
27
28
29
30 public class SecondRibbon extends MosaicEngine {
31 private static final boolean DEBUG = false;
32 private final Log logger = LogFactory.getLog(getClass());
33
34 private int curRow = 0;
35 private int[] curCols;
36 private int curCol;
37 private int maxRow;
38 private int maxCol;
39 private int p;
40 private List<Pic> picList;
41 private String info = "N/A";
42 private int[] used;
43 private int tileRows;
44 private String buildStep = "Idle";
45 private int pass = -1;
46
47
48
49
50 public String getStatus() {
51 StringBuilder sb = new StringBuilder();
52 sb.append(buildStep);
53 sb.append(": pass=");
54 sb.append(pass);
55 if (!buildStep.equals("Calc")) {
56 sb.append(" curRow = ");
57 sb.append(curRow);
58 sb.append(" curCol = ");
59 sb.append(curCol);
60 }
61 sb.append(" p=");
62 sb.append(p);
63 return(sb.toString());
64 }
65
66
67
68
69 public String getInfo() {
70 return(info);
71 }
72
73 protected boolean _build() {
74 Graphics2D gd = bi.createGraphics();
75
76
77 picList = dbf.getPics(this.mosaicSet, tileHeight);
78 if (DEBUG)
79 logger.info("Working from " + picList.size() + " pics");
80 maxRow = this.masterPic.getHeight();
81 maxCol = this.masterPic.getWidth();
82 tileRows = maxRow / tileHeight;
83 if (tileRows * tileHeight < maxRow)
84 tileRows++;
85 curCols = new int[tileRows];
86
87 long[][] rate = new long[tileRows][picList.size()];
88 used = new int[picList.size()];
89 info = "tileRows=" + tileRows + " maxCol=" + maxCol + " pics=" + picList.size();
90 if (DEBUG)
91 logger.info("tileRows=" + tileRows + " rowHeight=" + tileHeight);
92 if (!mosaic.isBatch())
93 restoreBuild(gd);
94 boolean workDone = true;
95 while (workDone) {
96 pass++;
97 workDone = false;
98 BufferedImage mbi;
99 int x,y;
100 buildStep = "Calc";
101 for (p=0; p<picList.size(); p++) {
102 mbi = pmf.getMosaicThumbNail(picList.get(p), tileHeight).getImage();
103 for (curRow=0; curRow<tileRows; curRow++) {
104 curCol = curCols[curRow];
105 int cr = curRow * tileHeight;
106
107
108
109
110 if (curCol < maxCol) {
111 workDone = true;
112
113 rate[curRow][p] = used[p]*0;
114 for (x=0; x<mbi.getWidth(); x++) {
115 for (y=0; y<mbi.getHeight(); y++) {
116 int mpx = mbi.getRGB(x, y);
117 int ppx;
118 if (x+curCol >= bi.getWidth() || y+cr >= bi.getHeight())
119 ppx = mpx;
120 else
121 ppx = bi.getRGB(x+curCol, y+cr);
122
123
124
125 rate[curRow][p] += Math.abs(((mpx)&0xFF) - ((ppx)&0xFF)) * 1;
126 rate[curRow][p] += Math.abs(((mpx>>8)&0xFF) - ((ppx>>8)&0xFF)) * 1;
127 rate[curRow][p] += Math.abs(((mpx>>16)&0xFF) - ((ppx>>16)&0xFF)) * 1;
128 }
129 }
130
131
132 rate[curRow][p] /= mbi.getWidth();
133
134 }
135 }
136 if (!workDone)
137 break;
138 if (!pmf.isEngineOn())
139 return(true);
140 }
141 buildStep = "Draw";
142 for (curRow=0; curRow<tileRows; curRow++) {
143 curCol = curCols[curRow];
144 int cr = curRow * tileHeight;
145 if (curCol >= maxCol)
146 continue;
147 long best = Long.MAX_VALUE;
148 int besti = 0;
149 int besti2 = 0;
150 for (x=0; x<rate[curRow].length; x++) {
151 if (rate[curRow][x] < best) {
152 besti2 = besti;
153 best = rate[curRow][x];
154 besti = x;
155 }
156 }
157
158 if (DEBUG) {
159 if (besti == -1)
160 logger.info("row=" + curRow + " besti == -1");
161 else
162 logger.info("besti = " + besti + " (" + picList.get(besti).getName() + ") = " + rate[curRow][besti]);
163 if (besti2 == -1)
164 logger.info("row=" + curRow + " besti2 == -1");
165 else
166 logger.info("besti2 = " + besti2 + " (" + picList.get(besti2).getName() + ") = " + rate[curRow][besti2]);
167 }
168 used[besti]++;
169 mbi = pmf.getMosaicThumbNail(picList.get(besti), tileHeight).getImage();
170 if (!mosaic.isBatch()) {
171 MosaicTile tile = new MosaicTile(this.mid, picList.get(besti).getPid(), curCol, cr, mbi.getWidth(), mbi.getHeight());
172 dbf.storeMosaicTile(tile);
173 }
174 gd.drawImage(mbi, null, curCol, cr);
175 curCols[curRow] += mbi.getWidth();
176 setLastMosaicUpdate();
177 }
178 if (!mosaic.isBatch())
179 dbf.storeMosaic(mosaic);
180 }
181 buildStep = "Done";
182 return(false);
183 }
184
185 private void restoreBuild(Graphics2D gd) {
186 List<MosaicTile> lmt = dbf.getMosaicTiles(this.mid);
187 if (DEBUG)
188 logger.info("Restoring " + lmt.size() + " tiles");
189 boolean workDone = true;
190 buildStep = "Restore";
191 while (workDone) {
192 workDone = false;
193 pass++;
194 updateRestoreStatus();
195 for (curRow=0; curRow<tileRows; curRow++) {
196 curCol = curCols[curRow];
197 int cr = curRow * tileHeight;
198 Iterator<MosaicTile> iter = lmt.iterator();
199 while (iter.hasNext()) {
200 MosaicTile mt = iter.next();
201 if (mt.getX() == curCol && mt.getY() == cr) {
202 int besti = getPicListIndex(mt.getPid());
203 if (DEBUG)
204 logger.info("restore: besti = " + besti + " (" + picList.get(besti).getName() + ")");
205 used[besti]++;
206 BufferedImage mbi = pmf.getThumbNail(picList.get(besti), tileHeight).getImage();
207 gd.drawImage(mbi, null, curCol, cr);
208 curCols[curRow] += mbi.getWidth();
209 setLastMosaicUpdate();
210 workDone = true;
211 break;
212 }
213 }
214 }
215 }
216 }
217
218 private void updateRestoreStatus() {
219 buildStep = "Restore";
220 }
221
222 private int getPicListIndex(int pid) {
223 for (int i=0; i<picList.size(); i++) {
224 Pic p = picList.get(i);
225 if (p.getPid() == pid)
226 return(i);
227 }
228 return(-1);
229 }
230 }