1 | // TODO: different sorting methods, e.g. "widest SSIs" |
2 | sclass G22DataWrangler > Stages2 is IHasChangeListeners { |
3 | replace Stage with Runnable. |
4 | |
5 | event change; |
6 | |
7 | settable BufferedImage inputImage; |
8 | |
9 | // try to re-use anything that is identical |
10 | settable G22DataWrangler stealingFrom; |
11 | |
12 | settable bool withDiagonals = true; |
13 | settableWithVar int blur = 1; // in pixels |
14 | |
15 | // kilobytes per compressed image (pessimistic estimate |
16 | // counting 2 bytes for each int) |
17 | settable TargetAndActual<Double> kilobytes = new(250.0); |
18 | settable new TargetAndActual<Double> coveredPixelsPercentage; |
19 | settable new TargetAndActual<Double> detailLevel; |
20 | |
21 | settable bool vectorize = true; |
22 | settable bool allowPartialSSIs = true; |
23 | |
24 | settable SortMode sortMode = SortMode.compressibility; |
25 | |
26 | enum SortMode { compressibility, pixels } |
27 | |
28 | settable IPosterizer posterizer = new SinglePixelPosterizer(4); |
29 | |
30 | BufferedImage blurredImage; |
31 | int maxLines, maxInts; |
32 | L<? extends AbstractSSI> currentSSIs; // ssis at current stage |
33 | L<SSI> initialSSIs; |
34 | AbstractSSIList sortedSSIs, cutSSIs, |
35 | vectorizedSSIs, cutVectorizedSSIs; |
36 | CutListToBudget<AbstractSSI> cutter; |
37 | |
38 | // We store the posterized image as Hi15 |
39 | Hi15Image posterizedImage; |
40 | |
41 | // Region maker + regions |
42 | |
43 | FastRegions_Hi15Image regionMaker; |
44 | L<IImageRegion<Hi15Image>> regions; |
45 | |
46 | // Constructors |
47 | |
48 | *() {} |
49 | *(BufferedImage *inputImage) {} |
50 | |
51 | // Methods |
52 | |
53 | selfType kb(TargetAndActual<Double> kb) { ret kilobytes(kb); } |
54 | TargetAndActual<Double> kb() { ret kilobytes; } |
55 | |
56 | WidthAndHeight resolution() { |
57 | ret imageSize(inputImage); |
58 | } |
59 | |
60 | double detailDivisor() { |
61 | ret areaRoot(inputImage); |
62 | } |
63 | |
64 | selfType colorsPerChannel(int perChannel) { |
65 | ret posterizer(new SinglePixelPosterizer(perChannel)); |
66 | } |
67 | |
68 | int colorsPerChannel() { |
69 | ret posterizer/SinglePixelPosterizer.brightnessLevels; |
70 | } |
71 | |
72 | int colors() { |
73 | ret cubed(colorsPerChannel()); |
74 | } |
75 | |
76 | transient simplyCached FieldVar<Int> varColorsPerChannel() { |
77 | ret new FieldVar<Int>(this, "colorsPerChannel", l0 colorsPerChannel, l1 colorsPerChannel); |
78 | } |
79 | |
80 | transient simplyCached FieldVar<Int> varColors() { |
81 | ret new FieldVar<Int>(this, "colors", l0 colors, l1 colors); |
82 | } |
83 | |
84 | // choose number of colors for posterized image |
85 | selfType colors(int colors) { |
86 | int perChannel = iceil(cbrt(colors)); |
87 | ret colorsPerChannel(perChannel); |
88 | } |
89 | |
90 | stage "Stop Stealing" { |
91 | if (stealingFrom != null && stealingFrom.inputImage != inputImage) |
92 | stealingFrom = null; |
93 | } |
94 | |
95 | stage "Blur" { |
96 | if (stealingFrom != null) |
97 | if (stealingFrom.blur == blur) |
98 | ret with blurredImage = stealingFrom.blurredImage; |
99 | else |
100 | stealingFrom = null; |
101 | blurredImage = blurBufferedImage(blur, inputImage); |
102 | } |
103 | |
104 | stage "Posterize" { |
105 | if (stealingFrom != null) |
106 | if (eq(stealingFrom.posterizer, posterizer)) |
107 | ret with posterizedImage = stealingFrom.posterizedImage; |
108 | else |
109 | stealingFrom = null; |
110 | posterizedImage = posterizeBufferedImageToHi15(blurredImage, posterizer); |
111 | } |
112 | |
113 | stage regionsStage "Regions" { |
114 | if (stealingFrom != null) |
115 | if (stealingFrom.withDiagonals == withDiagonals) { |
116 | regionMaker = stealingFrom.regionMaker; |
117 | regions = stealingFrom.regions; |
118 | ret; |
119 | } else |
120 | stealingFrom = null; |
121 | |
122 | regionMaker = new FastRegions_Hi15Image(posterizedImage); |
123 | regionMaker.withDiagonals(withDiagonals); |
124 | regions = regionMaker!; |
125 | } |
126 | |
127 | stage "Sort regions" { |
128 | regions = biggestRegionsFirst(regions); |
129 | } |
130 | |
131 | stage "SSIs" { |
132 | initialSSIs = new L; |
133 | for (region : regions) |
134 | initialSSIs.addAll(new G22_RegionToSSIs_v2(region).withDiagonals (withDiagonals)!); |
135 | currentSSIs = initialSSIs; |
136 | } |
137 | |
138 | int initialSSILines() { |
139 | ret totalSSILines(initialSSIs); |
140 | } |
141 | |
142 | stage "Vector-Optimize" { |
143 | currentSSIs = vectorizedSSIs = vectorize |
144 | ? new VectorOptimizedSSIList(currentSSIs) |
145 | : new GeneralSSIList(currentSSIs); |
146 | } |
147 | |
148 | stage "Sort SSIs" { |
149 | if (sortMode == SortMode.compressibility) |
150 | sortedSSIs = new GeneralSSIList(sortedDesc(currentSSIs, (a, b) -> { |
151 | int x = cmp(a.compressibility(), b.compressibility()); |
152 | if (x != 0) ret x; |
153 | ret cmp(a.numberOfPixels(), b.numberOfPixels()); |
154 | })); |
155 | else if (sortMode == SortMode.pixels) |
156 | sortedSSIs = new GeneralSSIList(biggestSSIsFirst(currentSSIs)); |
157 | else |
158 | fail("Unknown sort mode"); |
159 | currentSSIs = sortedSSIs; |
160 | } |
161 | |
162 | stage "Cut SSI List by detail level" { |
163 | maxLines = !detailLevel.hasTarget() ? Int.MAX_VALUE |
164 | : iround(detailDivisor()*detailLevel.target()); |
165 | currentSSIs = cutSSIs = new GeneralSSIList(takeFirstNSSILines(maxLines, currentSSIs)); |
166 | detailLevel.set(l(cutSSIs)/detailDivisor()); |
167 | } |
168 | |
169 | stage "Cut Vector-Optimized SSIs by file size" { |
170 | maxInts = !kilobytes.hasTarget() ? Int.MAX_VALUE |
171 | : iround(kilobytes.target()*512); // assuming 16 bit ints |
172 | cutter = new CutListToBudget<AbstractSSI>(ssi -> (double) ssi.sizeInInts(), maxInts, (L) currentSSIs); |
173 | |
174 | if (allowPartialSSIs) |
175 | cutter.allowPartial((ssi, budget) -> ssi.reduceToInts(iround(budget))); |
176 | |
177 | currentSSIs = cutVectorizedSSIs = new GeneralSSIList(cutter!); |
178 | kilobytes.set(totalSizeInInts(cutVectorizedSSIs)/512.0); |
179 | } |
180 | |
181 | L<IImageRegion<Hi15Image>> regions() { |
182 | stepUntilStage(regionsStage); |
183 | ret regions; |
184 | } |
185 | |
186 | L<IBinaryImage> regionsAsIBinaryImages() { |
187 | ret map regionToIBinaryImage(regions()); |
188 | } |
189 | |
190 | BlurAndPosterizeSettings bnpSettings() { |
191 | ret new BlurAndPosterizeSettings() |
192 | .blur(blur) |
193 | .colors(colors()); |
194 | } |
195 | |
196 | void importSettings(BlurAndPosterizeSettings bnp) { |
197 | blur(bnp.blur); |
198 | colors(bnp.colors); |
199 | } |
200 | |
201 | FastRegions_Hi15Image regionMaker() { |
202 | stepUntilStage(regionsStage); |
203 | ret regionMaker; |
204 | } |
205 | } |
Began life as a copy of #1035748
download show line numbers debug dex old transpilations
Travelled to 2 computer(s): mqqgnosmbjvj, wnsclhtenguj
No comments. add comment
Snippet ID: | #1035995 |
Snippet name: | G22DataWrangler backup before color drift |
Eternal ID of this version: | #1035995/1 |
Text MD5: | ab71c24b28021ba205a0bb2ece6eff99 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-08-21 08:13:42 |
Source code size: | 6056 bytes / 205 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 120 / 132 |
Referenced in: | [show references] |