mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
nQuant: backport Gadgetbridge fixups
This commit is contained in:
committed by
José Rebelo
parent
c8da8b4717
commit
07b1e593b3
@@ -37,7 +37,7 @@ public class BitmapUtilities {
|
||||
return ditherPixel;
|
||||
}
|
||||
|
||||
static int[] quantize_image(final int width, final int height, final int[] pixels, final Integer[] palette, final Ditherable ditherable, final boolean hasSemiTransparency, final boolean dither)
|
||||
static int[] quantize_image(final int width, final int height, final int[] pixels, final int[] palette, final Ditherable ditherable, final boolean hasSemiTransparency, final boolean dither)
|
||||
{
|
||||
int[] qPixels = new int[pixels.length];
|
||||
int nMaxColors = palette.length;
|
||||
|
||||
@@ -196,7 +196,7 @@ public class BlueNoise {
|
||||
return Color.argb(a_pix, r_pix, g_pix, b_pix);
|
||||
}
|
||||
|
||||
static int[] processImagePixels(final Integer[] palette, final int[] qPixels) {
|
||||
static int[] processImagePixels(final int[] palette, final int[] qPixels) {
|
||||
int[] qPixel32s = new int[qPixels.length];
|
||||
for (var i = 0; i < qPixels.length; ++i)
|
||||
qPixel32s[i] = palette[qPixels[i]];
|
||||
@@ -204,7 +204,7 @@ public class BlueNoise {
|
||||
return qPixel32s;
|
||||
}
|
||||
|
||||
public static int[] dither(final int width, final int height, final int[] pixels, final Integer[] palette, final Ditherable ditherable, final int[] qPixels, final float weight)
|
||||
public static int[] dither(final int width, final int height, final int[] pixels, final int[] palette, final Ditherable ditherable, final int[] qPixels, final float weight)
|
||||
{
|
||||
final float strength = 1 / 3f;
|
||||
for (int y = 0; y < height; ++y) {
|
||||
|
||||
@@ -3,5 +3,5 @@ package com.android.nQuant;
|
||||
public interface Ditherable {
|
||||
public int getColorIndex(final int c);
|
||||
|
||||
public short nearestColorIndex(final Integer[] palette, final int c, final int pos);
|
||||
public short nearestColorIndex(final int[] palette, final int c, final int pos);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class GilbertCurve {
|
||||
private final int width, height;
|
||||
private final double weight;
|
||||
private final int[] pixels;
|
||||
private final Integer[] palette;
|
||||
private final int[] palette;
|
||||
private final int[] qPixels;
|
||||
private final Ditherable ditherable;
|
||||
private final float[] saliencies;
|
||||
@@ -47,7 +47,7 @@ public class GilbertCurve {
|
||||
private final int margin, thresold;
|
||||
private static final float BLOCK_SIZE = 343f;
|
||||
|
||||
private GilbertCurve(final int width, final int height, final int[] image, final Integer[] palette, final int[] qPixels, final Ditherable ditherable, final float[] saliencies, double weight, boolean dither)
|
||||
private GilbertCurve(final int width, final int height, final int[] image, final int[] palette, final int[] qPixels, final Ditherable ditherable, final float[] saliencies, double weight, boolean dither)
|
||||
{
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@@ -279,7 +279,7 @@ public class GilbertCurve {
|
||||
qPixels[bidx] = palette[qPixels[bidx]];
|
||||
}
|
||||
|
||||
private void generate2d(int x, int y, int ax, int ay, int bx, int by) throws Exception {
|
||||
private void generate2d(int x, int y, int ax, int ay, int bx, int by) {
|
||||
int w = Math.abs(ax + ay);
|
||||
int h = Math.abs(bx + by);
|
||||
int dax = Integer.signum(ax);
|
||||
@@ -353,7 +353,7 @@ public class GilbertCurve {
|
||||
weights[0] += 1f - weight;
|
||||
}
|
||||
|
||||
private void run() throws Exception
|
||||
private void run()
|
||||
{
|
||||
if(!sortedByYDiff)
|
||||
initWeights(DITHER_MAX);
|
||||
@@ -364,7 +364,7 @@ public class GilbertCurve {
|
||||
generate2d(0, 0, 0, height, width, 0);
|
||||
}
|
||||
|
||||
public static int[] dither(final int width, final int height, final int[] pixels, final Integer[] palette, final Ditherable ditherable, final float[] saliencies, final double weight, final boolean dither) throws Exception
|
||||
public static int[] dither(final int width, final int height, final int[] pixels, final int[] palette, final Ditherable ditherable, final float[] saliencies, final double weight, final boolean dither)
|
||||
{
|
||||
int[] qPixels = new int[pixels.length];
|
||||
new GilbertCurve(width, height, pixels, palette, qPixels, ditherable, saliencies, weight, dither).run();
|
||||
|
||||
@@ -4,6 +4,7 @@ package com.android.nQuant;
|
||||
Copyright (c) 2018-2026 Miller Cy Chan
|
||||
* error measure; time used is proportional to number of bins squared - WJ */
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
|
||||
import com.android.nQuant.CIELABConvertor.Lab;
|
||||
@@ -25,6 +26,10 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
super(fname);
|
||||
}
|
||||
|
||||
public PnnLABQuantizer(Bitmap bitmap) {
|
||||
super(bitmap);
|
||||
}
|
||||
|
||||
private static final class Pnnbin {
|
||||
float ac = 0, Lc = 0, Ac = 0, Bc = 0, err = 0;
|
||||
float cnt = 0;
|
||||
@@ -128,7 +133,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer[] pnnquan(final int[] pixels, int nMaxColors)
|
||||
protected int[] pnnquan(final int[] pixels, int nMaxColors)
|
||||
{
|
||||
short quan_rt = (short) 1;
|
||||
Pnnbin[] bins = new Pnnbin[65536];
|
||||
@@ -192,7 +197,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
|
||||
if(pixelMap.size() <= nMaxColors) {
|
||||
/* Fill palette */
|
||||
Integer[] palette = new Integer[pixelMap.size()];
|
||||
int[] palette = new int[pixelMap.size()];
|
||||
int k = 0;
|
||||
for (Integer pixel : pixelMap.keySet()) {
|
||||
palette[k++] = pixel;
|
||||
@@ -312,7 +317,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
}
|
||||
|
||||
/* Fill palette */
|
||||
Integer[] palette = new Integer[extbins > 0 ? nMaxColors : maxbins];
|
||||
int[] palette = new int[extbins > 0 ? nMaxColors : maxbins];
|
||||
short k = 0;
|
||||
for (int i = 0; k < palette.length; ++k) {
|
||||
Lab lab1 = new Lab();
|
||||
@@ -327,7 +332,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short nearestColorIndex(final Integer[] palette, int c, final int pos)
|
||||
protected short nearestColorIndex(final int[] palette, int c, final int pos)
|
||||
{
|
||||
final int offset = !isNano ? c : BitmapUtilities.getColorIndex(c, hasSemiTransparency, m_transparentPixelIndex >= 0);
|
||||
Short got = nearestMap.get(offset);
|
||||
@@ -404,7 +409,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected short closestColorIndex(final Integer[] palette, int c, final int pos)
|
||||
protected short closestColorIndex(final int[] palette, int c, final int pos)
|
||||
{
|
||||
if (Color.alpha(c) <= alphaThreshold)
|
||||
return nearestColorIndex(palette, c, pos);
|
||||
@@ -481,7 +486,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public short nearestColorIndex(Integer[] palette, int c, final int pos) {
|
||||
public short nearestColorIndex(int[] palette, int c, final int pos) {
|
||||
if (palette.length <= 4)
|
||||
return PnnLABQuantizer.this.nearestColorIndex(palette, c, pos);
|
||||
return PnnLABQuantizer.this.closestColorIndex(palette, c, pos);
|
||||
@@ -490,7 +495,7 @@ public class PnnLABQuantizer extends PnnQuantizer {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int[] dither(final int[] cPixels, Integer[] palette, int width, int height, boolean dither) throws Exception
|
||||
public int[] dither(final int[] cPixels, int[] palette, int width, int height, boolean dither)
|
||||
{
|
||||
Ditherable ditherable = getDitherFn();
|
||||
if(hasSemiTransparency)
|
||||
|
||||
@@ -7,6 +7,7 @@ Copyright (c) 2018-2026 Miller Cy Chan
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.util.Pair;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -36,6 +37,10 @@ public class PnnQuantizer {
|
||||
fromBitmap(fname);
|
||||
}
|
||||
|
||||
public PnnQuantizer(Bitmap bitmap) {
|
||||
fromBitmap(bitmap);
|
||||
}
|
||||
|
||||
private void fromBitmap(Bitmap bitmap) {
|
||||
width = bitmap.getWidth();
|
||||
height = bitmap.getHeight();
|
||||
@@ -131,7 +136,7 @@ public class PnnQuantizer {
|
||||
return cnt -> cnt;
|
||||
}
|
||||
|
||||
protected Integer[] pnnquan(final int[] pixels, int nMaxColors)
|
||||
protected int[] pnnquan(final int[] pixels, int nMaxColors)
|
||||
{
|
||||
short quan_rt = (short) 1;
|
||||
Pnnbin[] bins = new Pnnbin[65536];
|
||||
@@ -255,7 +260,7 @@ public class PnnQuantizer {
|
||||
}
|
||||
|
||||
/* Fill palette */
|
||||
Integer[] palette = new Integer[extbins > 0 ? nMaxColors : maxbins];
|
||||
int[] palette = new int[extbins > 0 ? nMaxColors : maxbins];
|
||||
short k = 0;
|
||||
for (int i = 0; k < palette.length; ++k) {
|
||||
palette[k] = Color.argb((int) bins[i].ac, (int) bins[i].rc, (int) bins[i].gc, (int) bins[i].bc);
|
||||
@@ -266,7 +271,7 @@ public class PnnQuantizer {
|
||||
return palette;
|
||||
}
|
||||
|
||||
protected short nearestColorIndex(final Integer[] palette, int c, final int pos)
|
||||
protected short nearestColorIndex(final int[] palette, int c, final int pos)
|
||||
{
|
||||
final int offset = weight > .015 ? c : BitmapUtilities.getColorIndex(c, hasSemiTransparency, m_transparentPixelIndex >= 0);
|
||||
Short got = nearestMap.get(offset);
|
||||
@@ -310,7 +315,7 @@ public class PnnQuantizer {
|
||||
return k;
|
||||
}
|
||||
|
||||
protected short closestColorIndex(final Integer[] palette, int c, final int pos)
|
||||
protected short closestColorIndex(final int[] palette, int c, final int pos)
|
||||
{
|
||||
short k = 0;
|
||||
if (Color.alpha(c) <= alphaThreshold)
|
||||
@@ -382,7 +387,7 @@ public class PnnQuantizer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public short nearestColorIndex(Integer[] palette, int c, final int pos) {
|
||||
public short nearestColorIndex(int[] palette, int c, final int pos) {
|
||||
if(dither)
|
||||
return PnnQuantizer.this.nearestColorIndex(palette, c, pos);
|
||||
return PnnQuantizer.this.closestColorIndex(palette, c, pos);
|
||||
@@ -390,7 +395,7 @@ public class PnnQuantizer {
|
||||
};
|
||||
}
|
||||
|
||||
protected int[] dither(final int[] cPixels, Integer[] palette, int width, int height, boolean dither) throws Exception
|
||||
protected int[] dither(final int[] cPixels, int[] palette, int width, int height, boolean dither)
|
||||
{
|
||||
Ditherable ditherable = getDitherFn(dither);
|
||||
if(hasSemiTransparency)
|
||||
@@ -406,7 +411,7 @@ public class PnnQuantizer {
|
||||
return qPixels;
|
||||
}
|
||||
|
||||
public Bitmap convert(int nMaxColors, boolean dither) throws Exception {
|
||||
public Pair<Bitmap, int[]> convert(int nMaxColors, boolean dither) {
|
||||
int semiTransCount = 0;
|
||||
for (int i = 0; i < pixels.length; ++i) {
|
||||
int pixel = pixels[i];
|
||||
@@ -435,11 +440,11 @@ public class PnnQuantizer {
|
||||
PR = coeffs[0][0]; PG = coeffs[0][1]; PB = coeffs[0][2];
|
||||
}
|
||||
|
||||
Integer[] palette;
|
||||
int[] palette;
|
||||
if (nMaxColors > 2)
|
||||
palette = pnnquan(pixels, nMaxColors);
|
||||
else {
|
||||
palette = new Integer[nMaxColors];
|
||||
palette = new int[nMaxColors];
|
||||
weight = 1;
|
||||
if (m_transparentPixelIndex >= 0) {
|
||||
palette[0] = m_transparentColor;
|
||||
@@ -452,7 +457,9 @@ public class PnnQuantizer {
|
||||
}
|
||||
|
||||
int[] qPixels = dither(pixels, palette, width, height, dither);
|
||||
return Bitmap.createBitmap(qPixels, width, height, Bitmap.Config.ARGB_8888);
|
||||
return new Pair<>(
|
||||
Bitmap.createBitmap(qPixels, width, height, Bitmap.Config.ARGB_8888),
|
||||
palette);
|
||||
}
|
||||
|
||||
public boolean hasAlpha() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* All files under this package were adapted from https://github.com/mcychan/nQuant.android
|
||||
* at 8f18e9d7536e71a90d0d1333968e07688b7ebf09
|
||||
* at 12822f15c92695136f1761b6b72c9bd18dc70c46
|
||||
* <p>
|
||||
* Changes done:
|
||||
* - Update PnnQuantizer to allow for access to the palette after convertion
|
||||
|
||||
Reference in New Issue
Block a user