1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.test.silkfx.hdr
18 
19 import android.content.Context
20 import android.graphics.Bitmap
21 import android.graphics.Canvas
22 import android.graphics.ColorMatrixColorFilter
23 import android.graphics.Gainmap
24 import android.graphics.ImageDecoder
25 import android.graphics.Paint
26 import android.graphics.Rect
27 import android.util.AttributeSet
28 import android.widget.Button
29 import android.widget.ImageView
30 import android.widget.LinearLayout
31 import android.widget.TextView
32 import com.android.test.silkfx.R
33 
34 enum class DecodeMode {
35     Full,
36     Subsampled4,
37     Scaled66,
38     CropedSquared,
39     CropedSquaredScaled33
40 }
41 
42 fun gainmapVisualizer(gainmap: Gainmap): Bitmap {
43     val map = gainmap.gainmapContents
44     val gainmapVisualizer = Bitmap.createBitmap(map.width, map.height,
45             Bitmap.Config.ARGB_8888)
46     val canvas = Canvas(gainmapVisualizer!!)
47     val paint = Paint()
48     paint.colorFilter = ColorMatrixColorFilter(
49             floatArrayOf(
50                     0f, 0f, 0f, 1f, 0f,
51                     0f, 0f, 0f, 1f, 0f,
52                     0f, 0f, 0f, 1f, 0f,
53                     0f, 0f, 0f, 0f, 255f
54             )
55     )
56     canvas.drawBitmap(map, 0f, 0f, paint)
57     canvas.setBitmap(null)
58     return gainmapVisualizer
59 }
60 
61 class GainmapDecodeTest(context: Context, attrs: AttributeSet?) : LinearLayout(context, attrs) {
62 
63     private fun decode(mode: DecodeMode) {
64         val source = ImageDecoder.createSource(resources.assets,
65                 "gainmaps/${context.assets.list("gainmaps")!![0]}")
66 
67         val sourceInfo = findViewById<TextView>(R.id.source_info)!!
68 
69         val gainmapImage = ImageDecoder.decodeBitmap(source) { decoder, info, source ->
70             decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE
71             sourceInfo.text =
72                 "Original size ${info.size.width}x${info.size.height}; mime-type = ${info.mimeType}"
73 
74             when (mode) {
75                 DecodeMode.Full -> {}
76                 DecodeMode.Subsampled4 -> {
77                     decoder.setTargetSampleSize(4)
78                 }
79                 DecodeMode.Scaled66 -> {
80                     val size = info.size
81                     decoder.setTargetSize((size.width * .66).toInt(), (size.height * .66).toInt())
82                 }
83                 DecodeMode.CropedSquared -> {
84                     val dimen = minOf(info.size.width, info.size.height)
85                     decoder.crop = Rect(50, 50, dimen - 100, dimen - 100)
86                 }
87                 DecodeMode.CropedSquaredScaled33 -> {
88                     val size = info.size
89                     val targetWidth = (size.width * .33).toInt()
90                     val targetHeight = (size.height * .33).toInt()
91                     decoder.setTargetSize(targetWidth, targetHeight)
92                     val dimen = minOf(targetWidth, targetHeight)
93                     decoder.crop = Rect(50, 50, dimen - 100, dimen - 100)
94                 }
95             }
96         }
97 
98         val gainmapContents = gainmapImage.gainmap?.let { gainmapVisualizer(it) }
99         val sdrBitmap = gainmapImage.also { it.gainmap = null }
100 
101         findViewById<ImageView>(R.id.sdr_source)!!.setImageBitmap(sdrBitmap)
102         findViewById<TextView>(R.id.sdr_label)!!.text =
103             "SDR Size: ${sdrBitmap.width}x${sdrBitmap.height}"
104 
105         findViewById<ImageView>(R.id.gainmap)!!.setImageBitmap(gainmapContents)
106         findViewById<TextView>(R.id.gainmap_label)!!.text =
107             "Gainmap Size: ${gainmapContents?.width ?: 0}x${gainmapContents?.height ?: 0}"
108     }
109 
110     override fun onFinishInflate() {
111         super.onFinishInflate()
112         decode(DecodeMode.Full)
113 
114         findViewById<Button>(R.id.decode_full)!!.setOnClickListener {
115             decode(DecodeMode.Full)
116         }
117         findViewById<Button>(R.id.decode_subsampled4)!!.setOnClickListener {
118             decode(DecodeMode.Subsampled4)
119         }
120         findViewById<Button>(R.id.decode_scaled66)!!.setOnClickListener {
121             decode(DecodeMode.Scaled66)
122         }
123         findViewById<Button>(R.id.decode_crop)!!.setOnClickListener {
124             decode(DecodeMode.CropedSquared)
125         }
126         findViewById<Button>(R.id.decode_cropScaled33)!!.setOnClickListener {
127             decode(DecodeMode.CropedSquaredScaled33)
128         }
129     }
130 }