fix dithering when dest has alpha and source does not; also fix it
when dest has more alpha bits than the source (rare)
This commit is contained in:
@@ -81,6 +81,9 @@ void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst)
|
|||||||
conv[i] = MaxOutputIntensity * 65536 / MaxInputIntensity;
|
conv[i] = MaxOutputIntensity * 65536 / MaxInputIntensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Max alpha value; used when there's no alpha source. */
|
||||||
|
const Uint8 alpha_max = Uint8((1 << dst_cbits[3]) - 1);
|
||||||
|
|
||||||
/* For each row: */
|
/* For each row: */
|
||||||
for(int row = 0; row < src->h; ++row) {
|
for(int row = 0; row < src->h; ++row) {
|
||||||
const Uint8 *srcp = (const Uint8 *)src->pixels + row * src->pitch;
|
const Uint8 *srcp = (const Uint8 *)src->pixels + row * src->pitch;
|
||||||
@@ -97,10 +100,19 @@ void SM_SDL_OrderedDither(const SDL_Surface *src, SDL_Surface *dst)
|
|||||||
colors[c] = DitherPixel(col, row, colors[c], conv[c]);
|
colors[c] = DitherPixel(col, row, colors[c], conv[c]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( src_cbits[3] == 0 ) /* src doesn't have alpha */
|
/* If the source has no alpha, the conversion formula will end up
|
||||||
colors[3] = (1<<dst_cbits[3]) - 1; /* Give dst full alpha */
|
* with 0; that's fine for color channels, but for alpha we need to
|
||||||
else /* src does have alpha */
|
* be opaque. */
|
||||||
colors[3] >>= src_cbits[3] - dst_cbits[3]; /* Convert the alpha channel, which we didn't dither. */
|
if(src_cbits[3] == 0) {
|
||||||
|
colors[3] = alpha_max;
|
||||||
|
} else {
|
||||||
|
/* Same as DitherPixel, except it doesn't actually dither; dithering
|
||||||
|
* looks bad on the alpha channel. */
|
||||||
|
int out_intensity = colors[3] * conv[3];
|
||||||
|
|
||||||
|
/* Truncate, and add e to make sure a value of 14.999998 -> 15. */
|
||||||
|
colors[3] = Uint8((out_intensity + 1) >> 16);
|
||||||
|
}
|
||||||
|
|
||||||
/* Raw value -> int -> pixel */
|
/* Raw value -> int -> pixel */
|
||||||
mySDL_SetRawRGBAV(dstp, dst, colors);
|
mySDL_SetRawRGBAV(dstp, dst, colors);
|
||||||
|
|||||||
Reference in New Issue
Block a user