Removing unused code to reveal what's left to replace, so DrawingBits.h and .cpp can be removed as per the TODO comment in these files. Mentioned GPL code is here: http://vlc.sourcearchive.com/documentation/0.9.8a/DrawingTidbits_8cpp-source.html
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32333 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,309 +21,6 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// ShiftComponent
|
||||
inline uchar
|
||||
ShiftComponent(uchar component, float percent)
|
||||
{
|
||||
// change the color by <percent>, make sure we aren't rounding
|
||||
// off significant bits
|
||||
if (percent >= 1)
|
||||
return (uchar)(component * (2 - percent));
|
||||
else
|
||||
return (uchar)(255 - percent * (255 - component));
|
||||
}
|
||||
|
||||
// ShiftColor
|
||||
rgb_color
|
||||
ShiftColor(rgb_color color, float percent)
|
||||
{
|
||||
rgb_color result = {
|
||||
ShiftComponent(color.red, percent),
|
||||
ShiftComponent(color.green, percent),
|
||||
ShiftComponent(color.blue, percent),
|
||||
0
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ReplaceColor
|
||||
void
|
||||
ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
|
||||
{
|
||||
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
|
||||
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
uint32 fromIndex = screen.IndexForColor(from);
|
||||
uint32 toIndex = screen.IndexForColor(to);
|
||||
|
||||
uchar *bits = (uchar *)bitmap->Bits();
|
||||
int32 bitsLength = bitmap->BitsLength();
|
||||
for (int32 index = 0; index < bitsLength; index++)
|
||||
if (bits[index] == fromIndex)
|
||||
bits[index] = toIndex;
|
||||
}
|
||||
|
||||
// ReplaceTransparentColor
|
||||
void
|
||||
ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
|
||||
{
|
||||
ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
|
||||
|
||||
BScreen screen(B_MAIN_SCREEN_ID);
|
||||
uint32 withIndex = screen.IndexForColor(with);
|
||||
|
||||
uchar *bits = (uchar *)bitmap->Bits();
|
||||
int32 bitsLength = bitmap->BitsLength();
|
||||
for (int32 index = 0; index < bitsLength; index++)
|
||||
if (bits[index] == B_TRANSPARENT_8_BIT)
|
||||
bits[index] = withIndex;
|
||||
}
|
||||
|
||||
// ycrcb_to_rgb
|
||||
inline void
|
||||
ycbcr_to_rgb( uint8 y, uint8 cb, uint8 cr,
|
||||
uint8& r, uint8& g, uint8& b)
|
||||
{
|
||||
r = (uint8)max_c( 0, min_c( 255, 1.164 * ( y - 16 ) + 1.596 * ( cr - 128 ) ) );
|
||||
g = (uint8)max_c( 0, min_c( 255, 1.164 * ( y - 16 ) - 0.813 * ( cr - 128 )
|
||||
- 0.391 * ( cb - 128 ) ) );
|
||||
b = (uint8)max_c( 0, min_c( 255, 1.164 * ( y - 16 ) + 2.018 * ( cb - 128 ) ) );
|
||||
}
|
||||
|
||||
// this function will not produce visually pleasing results!
|
||||
// we'd have to convert to Lab colorspace, do the mixing
|
||||
// and convert back to RGB - in an ideal world...
|
||||
//
|
||||
// mix_colors
|
||||
inline void
|
||||
mix_colors( uint8 ra, uint8 ga, uint8 ba,
|
||||
uint8 rb, uint8 gb, uint8 bb,
|
||||
uint8& r, uint8& g, uint8& b, float mixLevel )
|
||||
{
|
||||
float mixA = ( 1.0 - mixLevel );
|
||||
float mixB = mixLevel;
|
||||
r = (uint8)(mixA * ra + mixB * rb);
|
||||
g = (uint8)(mixA * ga + mixB * gb);
|
||||
b = (uint8)(mixA * ba + mixB * bb);
|
||||
}
|
||||
|
||||
// the algorithm used is probably pretty slow, but it should be easy
|
||||
// to understand what's going on...
|
||||
//
|
||||
// scale_bitmap
|
||||
status_t
|
||||
scale_bitmap( BBitmap* bitmap, uint32 fromWidth, uint32 fromHeight )
|
||||
{
|
||||
status_t status = B_BAD_VALUE;
|
||||
|
||||
if ( bitmap && bitmap->IsValid()
|
||||
&& ( bitmap->ColorSpace() == B_RGB32 || bitmap->ColorSpace() == B_RGBA32 ) )
|
||||
{
|
||||
status = B_MISMATCHED_VALUES;
|
||||
// we only support upscaling as of now
|
||||
uint32 destWidth = bitmap->Bounds().IntegerWidth() + 1;
|
||||
uint32 destHeight = bitmap->Bounds().IntegerHeight() + 1;
|
||||
if ( fromWidth <= destWidth && fromHeight <= destHeight )
|
||||
{
|
||||
status = B_OK;
|
||||
uint32 bpr = bitmap->BytesPerRow();
|
||||
if ( fromWidth < destWidth )
|
||||
{
|
||||
// scale horizontally
|
||||
uint8* src = (uint8*)bitmap->Bits();
|
||||
uint8* p = new uint8[fromWidth * 4]; // temp buffer
|
||||
for ( uint32 y = 0; y < fromHeight; y++ )
|
||||
{
|
||||
// copy valid pixels into temp buffer
|
||||
memcpy( p, src, fromWidth * 4 );
|
||||
for ( uint32 x = 0; x < destWidth; x++ )
|
||||
{
|
||||
// mix colors of left and right pixels and write it back
|
||||
// into the bitmap
|
||||
float xPos = ( (float)x / (float)destWidth ) * (float)fromWidth;
|
||||
uint32 leftIndex = (uint32)floorf( xPos ) * 4;
|
||||
uint32 rightIndex = (uint32)ceilf( xPos ) * 4;
|
||||
rgb_color left;
|
||||
left.red = p[leftIndex + 2];
|
||||
left.green = p[leftIndex + 1];
|
||||
left.blue = p[leftIndex + 0];
|
||||
rgb_color right;
|
||||
right.red = p[rightIndex + 2];
|
||||
right.green = p[rightIndex + 1];
|
||||
right.blue = p[rightIndex + 0];
|
||||
rgb_color mix;
|
||||
mix_colors( left.red, left.green, left.blue,
|
||||
right.red, right.green, right.blue,
|
||||
mix.red, mix.green, mix.blue, xPos - floorf( xPos ) );
|
||||
uint32 destIndex = x * 4;
|
||||
src[destIndex + 2] = mix.red;
|
||||
src[destIndex + 1] = mix.green;
|
||||
src[destIndex + 0] = mix.blue;
|
||||
}
|
||||
src += bpr;
|
||||
}
|
||||
delete[] p;
|
||||
}
|
||||
if ( fromHeight < destHeight )
|
||||
{
|
||||
// scale vertically
|
||||
uint8* src = (uint8*)bitmap->Bits();
|
||||
uint8* p = new uint8[fromHeight * 3]; // temp buffer
|
||||
for ( uint32 x = 0; x < destWidth; x++ )
|
||||
{
|
||||
// copy valid pixels into temp buffer
|
||||
for ( uint32 y = 0; y < fromHeight; y++ )
|
||||
{
|
||||
uint32 destIndex = y * 3;
|
||||
uint32 srcIndex = x * 4 + y * bpr;
|
||||
p[destIndex + 0] = src[srcIndex + 0];
|
||||
p[destIndex + 1] = src[srcIndex + 1];
|
||||
p[destIndex + 2] = src[srcIndex + 2];
|
||||
}
|
||||
// do the scaling
|
||||
for ( uint32 y = 0; y < destHeight; y++ )
|
||||
{
|
||||
// mix colors of upper and lower pixels and write it back
|
||||
// into the bitmap
|
||||
float yPos = ( (float)y / (float)destHeight ) * (float)fromHeight;
|
||||
uint32 upperIndex = (uint32)floorf( yPos ) * 3;
|
||||
uint32 lowerIndex = (uint32)ceilf( yPos ) * 3;
|
||||
rgb_color upper;
|
||||
upper.red = p[upperIndex + 2];
|
||||
upper.green = p[upperIndex + 1];
|
||||
upper.blue = p[upperIndex + 0];
|
||||
rgb_color lower;
|
||||
lower.red = p[lowerIndex + 2];
|
||||
lower.green = p[lowerIndex + 1];
|
||||
lower.blue = p[lowerIndex + 0];
|
||||
rgb_color mix;
|
||||
mix_colors( upper.red, upper.green, upper.blue,
|
||||
lower.red, lower.green, lower.blue,
|
||||
mix.red, mix.green, mix.blue, yPos - floorf( yPos ) );
|
||||
uint32 destIndex = x * 4 + y * bpr;
|
||||
src[destIndex + 2] = mix.red;
|
||||
src[destIndex + 1] = mix.green;
|
||||
src[destIndex + 0] = mix.blue;
|
||||
}
|
||||
}
|
||||
delete[] p;
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// convert_bitmap
|
||||
status_t
|
||||
convert_bitmap( BBitmap* inBitmap, BBitmap* outBitmap )
|
||||
{
|
||||
status_t status = B_BAD_VALUE;
|
||||
// see that we got valid bitmaps
|
||||
if ( inBitmap && inBitmap->IsValid()
|
||||
&& outBitmap && outBitmap->IsValid() )
|
||||
{
|
||||
status = B_MISMATCHED_VALUES;
|
||||
// see that bitmaps are compatible and that we support the conversion
|
||||
if ( inBitmap->Bounds().Width() <= outBitmap->Bounds().Width()
|
||||
&& inBitmap->Bounds().Height() <= outBitmap->Bounds().Height()
|
||||
&& ( outBitmap->ColorSpace() == B_RGB32
|
||||
|| outBitmap->ColorSpace() == B_RGBA32) )
|
||||
{
|
||||
int32 width = inBitmap->Bounds().IntegerWidth() + 1;
|
||||
int32 height = inBitmap->Bounds().IntegerHeight() + 1;
|
||||
int32 srcBpr = inBitmap->BytesPerRow();
|
||||
int32 dstBpr = outBitmap->BytesPerRow();
|
||||
uint8* srcBits = (uint8*)inBitmap->Bits();
|
||||
uint8* dstBits = (uint8*)outBitmap->Bits();
|
||||
switch (inBitmap->ColorSpace())
|
||||
{
|
||||
case B_YCbCr422:
|
||||
// Y0[7:0] Cb0[7:0] Y1[7:0] Cr0[7:0]
|
||||
// Y2[7:0] Cb2[7:0] Y3[7:0] Cr2[7:0]
|
||||
for ( int32 y = 0; y < height; y++ )
|
||||
{
|
||||
for ( int32 x = 0; x < width; x += 2 )
|
||||
{
|
||||
int32 srcOffset = x * 2;
|
||||
int32 dstOffset = x * 4;
|
||||
ycbcr_to_rgb( srcBits[srcOffset + 0],
|
||||
srcBits[srcOffset + 1],
|
||||
srcBits[srcOffset + 3],
|
||||
dstBits[dstOffset + 2],
|
||||
dstBits[dstOffset + 1],
|
||||
dstBits[dstOffset + 0] );
|
||||
ycbcr_to_rgb( srcBits[srcOffset + 2],
|
||||
srcBits[srcOffset + 1],
|
||||
srcBits[srcOffset + 3],
|
||||
dstBits[dstOffset + 6],
|
||||
dstBits[dstOffset + 5],
|
||||
dstBits[dstOffset + 4] );
|
||||
// take care of alpha
|
||||
dstBits[x * 4 + 3] = 255;
|
||||
dstBits[x * 4 + 7] = 255;
|
||||
}
|
||||
srcBits += srcBpr;
|
||||
dstBits += dstBpr;
|
||||
}
|
||||
status = B_OK;
|
||||
break;
|
||||
case B_YCbCr420:
|
||||
// Non-interlaced only!
|
||||
// Cb0 Y0 Y1 Cb2 Y2 Y3 on even scan lines ...
|
||||
// Cr0 Y0 Y1 Cr2 Y2 Y3 on odd scan lines
|
||||
status = B_ERROR;
|
||||
break;
|
||||
case B_YUV422:
|
||||
// U0[7:0] Y0[7:0] V0[7:0] Y1[7:0]
|
||||
// U2[7:0] Y2[7:0] V2[7:0] Y3[7:0]
|
||||
status = B_ERROR;
|
||||
break;
|
||||
case B_RGB32:
|
||||
case B_RGBA32:
|
||||
memcpy( dstBits, srcBits, inBitmap->BitsLength() );
|
||||
status = B_OK;
|
||||
break;
|
||||
case B_RGB16:
|
||||
// G[2:0],B[4:0] R[4:0],G[5:3]
|
||||
for ( int32 y = 0; y < height; y ++ )
|
||||
{
|
||||
for ( int32 x = 0; x < width; x++ )
|
||||
{
|
||||
int32 srcOffset = x * 2;
|
||||
int32 dstOffset = x * 4;
|
||||
uint8 blue = srcBits[srcOffset + 0] & 0x1f;
|
||||
uint8 green = ( srcBits[srcOffset + 0] >> 5 )
|
||||
| ( ( srcBits[srcOffset + 1] & 0x07 ) << 3 );
|
||||
uint8 red = srcBits[srcOffset + 1] & 0xf8;
|
||||
// homogeneously scale each component to 8 bit
|
||||
dstBits[dstOffset + 0] = (blue << 3) | (blue >> 2);
|
||||
dstBits[dstOffset + 1] = (green << 2) | (green >> 4);
|
||||
dstBits[dstOffset + 2] = red | (red >> 5);
|
||||
}
|
||||
srcBits += srcBpr;
|
||||
dstBits += dstBpr;
|
||||
}
|
||||
status = B_OK;
|
||||
break;
|
||||
default:
|
||||
//printf("unkown colorspace: %ld\n", inBitmap->ColorSpace());
|
||||
status = B_MISMATCHED_VALUES;
|
||||
break;
|
||||
}
|
||||
if ( status == B_OK )
|
||||
{
|
||||
if ( width < outBitmap->Bounds().IntegerWidth() + 1
|
||||
|| height < outBitmap->Bounds().IntegerHeight() + 1 )
|
||||
{
|
||||
scale_bitmap( outBitmap, width, height );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// clip_float
|
||||
inline uint8
|
||||
clip_float(float value)
|
||||
@@ -443,3 +140,4 @@ dimmed_color_cmap8(rgb_color color, rgb_color center, float dimLevel)
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,44 +19,6 @@
|
||||
class BBitmap;
|
||||
|
||||
const rgb_color kBlack = { 0, 0, 0, 255 };
|
||||
const rgb_color kWhite = { 255, 255, 255, 255 };
|
||||
|
||||
rgb_color ShiftColor(rgb_color , float );
|
||||
|
||||
inline rgb_color
|
||||
Color(int32 r, int32 g, int32 b, int32 alpha = 255)
|
||||
{
|
||||
rgb_color result;
|
||||
result.red = r;
|
||||
result.green = g;
|
||||
result.blue = b;
|
||||
result.alpha = alpha;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const float kDarkness = 1.06;
|
||||
const float kDimLevel = 0.6;
|
||||
|
||||
void ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to);
|
||||
void ReplaceTransparentColor(BBitmap *bitmap, rgb_color with);
|
||||
|
||||
// function can be used to scale the upper left part of
|
||||
// a bitmap to fill the entire bitmap, ie fromWidth
|
||||
// and fromHeight must be smaller or equal to the bitmaps size!
|
||||
// only supported colorspaces are B_RGB32 and B_RGBA32
|
||||
status_t scale_bitmap( BBitmap* bitmap,
|
||||
uint32 fromWidth, uint32 fromHeight );
|
||||
|
||||
// bitmaps need to be the same size, or this function will fail
|
||||
// currently supported conversions:
|
||||
// B_YCbCr422 -> B_RGB32
|
||||
// B_RGB32 -> B_RGB32
|
||||
// B_RGB16 -> B_RGB32
|
||||
// not yet implemented conversions:
|
||||
// B_YCbCr420 -> B_RGB32
|
||||
// B_YUV422 -> B_RGB32
|
||||
status_t convert_bitmap(BBitmap* inBitmap, BBitmap* outBitmap);
|
||||
|
||||
// dims bitmap (in place) by finding the distance of
|
||||
// the color at each pixel to the provided "center" color
|
||||
|
||||
Reference in New Issue
Block a user