annotate app/src/main/java/com/bartsent/simpleresizer/lib/Resizer.kt @ 7:9374d044a132 concur

Concurrency attempt, NOT WORKING.
author David Barts <n5jrn@me.com>
date Wed, 17 Feb 2021 07:24:26 -0800
parents
children 884092efe31a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
1 package com.bartsent.simpleresizer.lib
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
2
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
3 import android.graphics.Bitmap
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
4 import android.graphics.Color
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
5 import java.io.Closeable
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
6 import kotlin.math.ceil
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
7 import kotlin.math.floor
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
8
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
9 class Resizer: Closeable {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
10 private val NWORKERS = maxOf(1, Runtime.getRuntime().availableProcessors() - 2)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
11 private val workers = Channel<Worker>(NWORKERS)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
12 init {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
13 for (i in 0 until NWORKERS)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
14 workers.write(Worker(workers))
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
15 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
16
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
17 override fun close() {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
18 for (i in 0 until NWORKERS)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
19 workers.read().run {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
20 interrupt()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
21 join()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
22 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
23 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
24
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
25 private fun drain(): Unit {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
26 val saved = Array<Worker>(NWORKERS) { workers.read() }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
27 saved.forEach { workers.write(it) }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
28 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
29
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
30 private data class IndexWeight(var index: Int, var weight: Double)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
31
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
32 private fun precomputeWeights(dstSize: Int, srcSize: Int, filter: ScalingKernel): Array<Array<IndexWeight>> {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
33 val du = srcSize.toDouble() / dstSize.toDouble()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
34 val scale = maxOf(1.0, du)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
35 val ru = ceil(scale * filter.size)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
36 val TEMPLATE = arrayOf<IndexWeight>()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
37 val out = Array<Array<IndexWeight>>(dstSize) { TEMPLATE }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
38 val tmp = ArrayList<IndexWeight>((ru.toInt()+2)*2)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
39 val emax = srcSize - 1
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
40
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
41 for (v in 0 until dstSize) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
42 val fu = (v.toDouble()+0.5)*du - 0.5
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
43 val begin = maxOf(0, ceil(fu - ru).toInt())
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
44 val end = minOf(emax, floor(fu + ru).toInt())
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
45 var sum: Double = 0.0
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
46 for (u in begin..end) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
47 val w = filter.weight((u.toDouble() - fu) / scale)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
48 if (w != 0.0) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
49 sum += w
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
50 tmp.add(IndexWeight(u, w))
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
51 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
52 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
53 if (sum != 0.0) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
54 tmp.forEach {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
55 it.weight /= sum
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
56 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
57 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
58 out[v] = tmp.toArray(TEMPLATE)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
59 tmp.clear()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
60 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
61 return out
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
62 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
63
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
64 private data class WorkUnit(val target: Bitmap, val x: Int, val y: Int,
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
65 val weights: Array<IndexWeight>, val scanLine: IntArray)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
66
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
67 private class Worker(private val workers: Channel<Worker>): Thread() {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
68 private val _input = Channel<WorkUnit>(1)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
69
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
70 override fun run() {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
71 while (true) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
72 val data = _input.read()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
73 if (isInterrupted)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
74 return
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
75 resample(data.target, data.x, data.y, data.weights, data.scanLine)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
76 workers.write(this)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
77 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
78 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
79
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
80 fun send(data: WorkUnit) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
81 _input.write(data)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
82 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
83
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
84 private fun clamp(v: Double): Int = minOf(255, maxOf(0, (v + 0.5).toInt()))
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
85
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
86 private fun resample(target: Bitmap, x: Int, y: Int, weights: Array<IndexWeight>, scanLine: IntArray): Unit {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
87 var r = 0.0; var g = 0.0; var b = 0.0; var a = 0.0
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
88 weights.forEach {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
89 val c = scanLine[it.index]
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
90 val aw = Color.alpha(c).toDouble() * it.weight
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
91 r += Color.red(c).toDouble() * aw
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
92 g += Color.green(c).toDouble() * aw
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
93 b += Color.blue(c).toDouble() * aw
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
94 a += aw
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
95 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
96 if (a == 0.0)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
97 return
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
98 val argb = Color.argb(clamp(a), clamp(r/a), clamp(g/a), clamp(b/a))
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
99 synchronized(target) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
100 target.setPixel(x, y, argb)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
101 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
102 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
103 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
104
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
105 private fun resample(target: Bitmap, x: Int, y: Int, weights: Array<IndexWeight>, scanLine: IntArray): Unit {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
106 workers.read().send(WorkUnit(target, x, y, weights, scanLine))
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
107 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
108
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
109 fun horizontal(image: Bitmap, newWidth: Int, kernel: ScalingKernel): Bitmap {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
110 val dst = Bitmap.createBitmap(newWidth, image.height, Bitmap.Config.ARGB_8888)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
111 val weights = precomputeWeights(newWidth, image.width, kernel)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
112 val scanLine = IntArray(image.width)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
113 for (y in 0 until image.height) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
114 for (x in 0 until image.width) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
115 scanLine[x] = image.getPixel(x, y)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
116 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
117 for (x in weights.indices) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
118 resample(dst, x, y, weights[x], scanLine)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
119 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
120 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
121 drain()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
122 return dst
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
123 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
124
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
125 fun vertical(image: Bitmap, newHeight: Int, kernel: ScalingKernel): Bitmap {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
126 val dst = Bitmap.createBitmap(image.width, newHeight, Bitmap.Config.ARGB_8888)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
127 val weights = precomputeWeights(newHeight, image.height, kernel)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
128 val scanLine = IntArray(image.height)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
129 for (x in 0 until image.width) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
130 for (y in 0 until image.height) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
131 scanLine[y] = image.getPixel(x, y)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
132 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
133 for (y in weights.indices) {
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
134 resample(dst, x, y, weights[y], scanLine)
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
135 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
136 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
137 drain()
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
138 return dst
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
139 }
9374d044a132 Concurrency attempt, NOT WORKING.
David Barts <n5jrn@me.com>
parents:
diff changeset
140 }