Skip to content

Commit

Permalink
Use awt coerceData instead of own implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
weisJ committed Mar 16, 2024
1 parent c410398 commit c880f2c
Showing 1 changed file with 1 addition and 122 deletions.
123 changes: 1 addition & 122 deletions jsvg/src/main/java/com/github/weisj/jsvg/util/ImageUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,131 +132,10 @@ public static int getINT_RGBA_ScanlineStride(@NotNull Raster raster) {
return bufferedImage;
}

private static @NotNull ColorModel coerceColorModel(@NotNull ColorModel cm, boolean newAlphaPreMultiplied) {
if (cm.isAlphaPremultiplied() == newAlphaPreMultiplied) return cm;

// Easiest way to build proper color-model for new Alpha state...
// Eventually this should switch on known ColorModel types and
// only fall back on this hack when the CM type is unknown.
WritableRaster wr = cm.createCompatibleWritableRaster(1, 1);
return cm.coerceData(wr, newAlphaPreMultiplied);
}

public static @NotNull ColorModel coerceData(@NotNull WritableRaster wr, @NotNull ColorModel cm,
boolean newAlphaPreMultiplied) {
if (!cm.hasAlpha()) return cm;
if (cm.isAlphaPremultiplied() == newAlphaPreMultiplied) return cm;

if (newAlphaPreMultiplied) {
multiplyAlpha(wr);
} else {
divideAlpha(wr);
}

return coerceColorModel(cm, newAlphaPreMultiplied);
}

public static void multiplyAlpha(@NotNull WritableRaster wr) {
if (is_INT_PACK_Data(wr.getSampleModel(), true)) {
multiply_INT_PACK_Data(wr);
} else {
int[] pixel = null;
int bands = wr.getNumBands();
float norm = 1.0f / 255f;
int x0 = wr.getMinX();
int x1 = x0 + wr.getWidth();
int y0 = wr.getMinY();
int y1 = y0 + wr.getHeight();
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
pixel = wr.getPixel(x, y, pixel);
int a = pixel[bands - 1];
if ((a >= 0) && (a < 255)) {
float alpha = a * norm;
for (int b = 0; b < bands - 1; b++) {
pixel[b] = (int) (pixel[b] * alpha + 0.5f);
}
wr.setPixel(x, y, pixel);
}
}
}
}
}

public static void divideAlpha(@NotNull WritableRaster wr) {
if (is_INT_PACK_Data(wr.getSampleModel(), true)) {
divide_INT_PACK_Data(wr);
} else {
int bands = wr.getNumBands();
int[] pixel = null;

int x0 = wr.getMinX();
int x1 = x0 + wr.getWidth();
int y0 = wr.getMinY();
int y1 = y0 + wr.getHeight();
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
pixel = wr.getPixel(x, y, pixel);
int a = pixel[bands - 1];
if ((a > 0) && (a < 255)) {
float alpha = 255 / (float) a;
for (int b = 0; b < bands - 1; b++) {
pixel[b] = (int) (pixel[b] * alpha + 0.5f);
}
wr.setPixel(x, y, pixel);
}
}
}
}
}

private static void divide_INT_PACK_Data(@NotNull WritableRaster wr) {
final int width = wr.getWidth();
final int scanStride = getINT_RGBA_DataAdjust(wr);
final int base = getINT_RGBA_DataOffset(wr);
final int[] pixels = getINT_RGBA_DataBank(wr);

for (int y = 0; y < wr.getHeight(); y++) {
int sp = base + y * scanStride;
final int end = sp + width;
while (sp < end) {
int pixel = pixels[sp];
int a = pixel >>> 24;
if (a == 0) {
pixels[sp] = 0x00FFFFFF;
} else if (a < 255) {
int aFP = (0x00FF0000 / a);
pixels[sp] = ((a << 24) |
((((pixel & 0xFF0000) >> 16) * aFP) & 0xFF0000) |
(((((pixel & 0x00FF00) >> 8) * aFP) & 0xFF0000) >> 8) |
(((pixel & 0x0000FF) * aFP) & 0xFF0000) >> 16);
}
sp++;
}
}
}

private static void multiply_INT_PACK_Data(@NotNull WritableRaster wr) {
final int width = wr.getWidth();
final int scanStride = getINT_RGBA_DataAdjust(wr);
final int base = getINT_RGBA_DataOffset(wr);
final int[] pixels = getINT_RGBA_DataBank(wr);

for (int y = 0; y < wr.getHeight(); y++) {
int sp = base + y * scanStride;
final int end = sp + width;
while (sp < end) {
int pixel = pixels[sp];
int a = pixel >>> 24;
if (a < 255) { // this does NOT include a == 255 (0xff) !
pixels[sp] = ((a << 24) |
((((pixel & 0xFF0000) * a) >> 8) & 0xFF0000) |
((((pixel & 0x00FF00) * a) >> 8) & 0x00FF00) |
((((pixel & 0x0000FF) * a) >> 8) & 0x0000FF));
}
sp++;
}
}
return cm.coerceData(wr, newAlphaPreMultiplied);
}

}

0 comments on commit c880f2c

Please sign in to comment.