Wrote a new color conversion engine. It's 2-5 times faster than the old one (depending on colorspaces) and about half in size.
I've put it into ColorConversion.cpp and moved PaletteConverter there too, cleaning up Bitmap.cpp. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16580 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
7a25fcafda
commit
b09e53fae0
|
@ -0,0 +1,50 @@
|
|||
#ifndef _COLOR_CONVERSION_H_
|
||||
#define _COLOR_CONVERSION_H_
|
||||
|
||||
#include <GraphicsDefs.h>
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
status_t ConvertBits(const void *srcBuffer, void *dstBuffer,
|
||||
uint32 srcBytesPerRow, uint32 dstBytesPerRow, color_space srcColorSpace,
|
||||
color_space dstColorSpace, int32 width, int32 height);
|
||||
|
||||
|
||||
/*! \brief Helper class for conversion between RGB and palette colors.
|
||||
*/
|
||||
class PaletteConverter {
|
||||
public:
|
||||
PaletteConverter();
|
||||
PaletteConverter(const rgb_color *palette);
|
||||
PaletteConverter(const color_map *colorMap);
|
||||
~PaletteConverter();
|
||||
|
||||
status_t SetTo(const rgb_color *palette);
|
||||
status_t SetTo(const color_map *colorMap);
|
||||
status_t InitCheck() const;
|
||||
|
||||
inline uint8 IndexForRGB15(uint16 rgb) const;
|
||||
inline uint8 IndexForRGB15(uint8 red, uint8 green, uint8 blue) const;
|
||||
inline uint8 IndexForRGB16(uint16 rgb) const;
|
||||
inline uint8 IndexForRGB16(uint8 red, uint8 green, uint8 blue) const;
|
||||
inline uint8 IndexForRGB24(uint32 rgb) const;
|
||||
inline uint8 IndexForRGB24(uint8 red, uint8 green, uint8 blue) const;
|
||||
inline uint8 IndexForGray(uint8 gray) const;
|
||||
|
||||
inline const rgb_color &RGBColorForIndex(uint8 index) const;
|
||||
inline uint16 RGB15ColorForIndex(uint8 index) const;
|
||||
inline uint16 RGB16ColorForIndex(uint8 index) const;
|
||||
inline uint32 RGBA32ColorForIndex(uint8 index) const;
|
||||
inline void RGBA32ColorForIndex(uint8 index, uint8 &red, uint8 &green,
|
||||
uint8 &blue, uint8 &alpha) const;
|
||||
inline uint8 GrayColorForIndex(uint8 index) const;
|
||||
|
||||
private:
|
||||
const color_map *fColorMap;
|
||||
color_map *fOwnColorMap;
|
||||
status_t fCStatus;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,924 @@
|
|||
/*
|
||||
* Copyright 2001-2006, Haiku Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold (bonefish@users.sf.net)
|
||||
* Michael Lotz <mmlr@mlotz.ch>
|
||||
*/
|
||||
|
||||
/** This file contains colorspace conversion functions
|
||||
* and a palette <-> true color conversion class.
|
||||
*/
|
||||
|
||||
#include "ColorConversion.h"
|
||||
#include <Locker.h>
|
||||
#include <new.h>
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
// TODO: system palette -- hard-coded for now, when the app server is ready
|
||||
// we should use system_colors() or BScreen::ColorMap().
|
||||
const rgb_color kSystemPalette[] = {
|
||||
{ 0, 0, 0, 255 }, { 8, 8, 8, 255 }, { 16, 16, 16, 255 },
|
||||
{ 24, 24, 24, 255 }, { 32, 32, 32, 255 }, { 40, 40, 40, 255 },
|
||||
{ 48, 48, 48, 255 }, { 56, 56, 56, 255 }, { 64, 64, 64, 255 },
|
||||
{ 72, 72, 72, 255 }, { 80, 80, 80, 255 }, { 88, 88, 88, 255 },
|
||||
{ 96, 96, 96, 255 }, { 104, 104, 104, 255 }, { 112, 112, 112, 255 },
|
||||
{ 120, 120, 120, 255 }, { 128, 128, 128, 255 }, { 136, 136, 136, 255 },
|
||||
{ 144, 144, 144, 255 }, { 152, 152, 152, 255 }, { 160, 160, 160, 255 },
|
||||
{ 168, 168, 168, 255 }, { 176, 176, 176, 255 }, { 184, 184, 184, 255 },
|
||||
{ 192, 192, 192, 255 }, { 200, 200, 200, 255 }, { 208, 208, 208, 255 },
|
||||
{ 216, 216, 216, 255 }, { 224, 224, 224, 255 }, { 232, 232, 232, 255 },
|
||||
{ 240, 240, 240, 255 }, { 248, 248, 248, 255 }, { 0, 0, 255, 255 },
|
||||
{ 0, 0, 229, 255 }, { 0, 0, 204, 255 }, { 0, 0, 179, 255 },
|
||||
{ 0, 0, 154, 255 }, { 0, 0, 129, 255 }, { 0, 0, 105, 255 },
|
||||
{ 0, 0, 80, 255 }, { 0, 0, 55, 255 }, { 0, 0, 30, 255 },
|
||||
{ 255, 0, 0, 255 }, { 228, 0, 0, 255 }, { 203, 0, 0, 255 },
|
||||
{ 178, 0, 0, 255 }, { 153, 0, 0, 255 }, { 128, 0, 0, 255 },
|
||||
{ 105, 0, 0, 255 }, { 80, 0, 0, 255 }, { 55, 0, 0, 255 },
|
||||
{ 30, 0, 0, 255 }, { 0, 255, 0, 255 }, { 0, 228, 0, 255 },
|
||||
{ 0, 203, 0, 255 }, { 0, 178, 0, 255 }, { 0, 153, 0, 255 },
|
||||
{ 0, 128, 0, 255 }, { 0, 105, 0, 255 }, { 0, 80, 0, 255 },
|
||||
{ 0, 55, 0, 255 }, { 0, 30, 0, 255 }, { 0, 152, 51, 255 },
|
||||
{ 255, 255, 255, 255 }, { 203, 255, 255, 255 }, { 203, 255, 203, 255 },
|
||||
{ 203, 255, 152, 255 }, { 203, 255, 102, 255 }, { 203, 255, 51, 255 },
|
||||
{ 203, 255, 0, 255 }, { 152, 255, 255, 255 }, { 152, 255, 203, 255 },
|
||||
{ 152, 255, 152, 255 }, { 152, 255, 102, 255 }, { 152, 255, 51, 255 },
|
||||
{ 152, 255, 0, 255 }, { 102, 255, 255, 255 }, { 102, 255, 203, 255 },
|
||||
{ 102, 255, 152, 255 }, { 102, 255, 102, 255 }, { 102, 255, 51, 255 },
|
||||
{ 102, 255, 0, 255 }, { 51, 255, 255, 255 }, { 51, 255, 203, 255 },
|
||||
{ 51, 255, 152, 255 }, { 51, 255, 102, 255 }, { 51, 255, 51, 255 },
|
||||
{ 51, 255, 0, 255 }, { 255, 152, 255, 255 }, { 255, 152, 203, 255 },
|
||||
{ 255, 152, 152, 255 }, { 255, 152, 102, 255 }, { 255, 152, 51, 255 },
|
||||
{ 255, 152, 0, 255 }, { 0, 102, 255, 255 }, { 0, 102, 203, 255 },
|
||||
{ 203, 203, 255, 255 }, { 203, 203, 203, 255 }, { 203, 203, 152, 255 },
|
||||
{ 203, 203, 102, 255 }, { 203, 203, 51, 255 }, { 203, 203, 0, 255 },
|
||||
{ 152, 203, 255, 255 }, { 152, 203, 203, 255 }, { 152, 203, 152, 255 },
|
||||
{ 152, 203, 102, 255 }, { 152, 203, 51, 255 }, { 152, 203, 0, 255 },
|
||||
{ 102, 203, 255, 255 }, { 102, 203, 203, 255 }, { 102, 203, 152, 255 },
|
||||
{ 102, 203, 102, 255 }, { 102, 203, 51, 255 }, { 102, 203, 0, 255 },
|
||||
{ 51, 203, 255, 255 }, { 51, 203, 203, 255 }, { 51, 203, 152, 255 },
|
||||
{ 51, 203, 102, 255 }, { 51, 203, 51, 255 }, { 51, 203, 0, 255 },
|
||||
{ 255, 102, 255, 255 }, { 255, 102, 203, 255 }, { 255, 102, 152, 255 },
|
||||
{ 255, 102, 102, 255 }, { 255, 102, 51, 255 }, { 255, 102, 0, 255 },
|
||||
{ 0, 102, 152, 255 }, { 0, 102, 102, 255 }, { 203, 152, 255, 255 },
|
||||
{ 203, 152, 203, 255 }, { 203, 152, 152, 255 }, { 203, 152, 102, 255 },
|
||||
{ 203, 152, 51, 255 }, { 203, 152, 0, 255 }, { 152, 152, 255, 255 },
|
||||
{ 152, 152, 203, 255 }, { 152, 152, 152, 255 }, { 152, 152, 102, 255 },
|
||||
{ 152, 152, 51, 255 }, { 152, 152, 0, 255 }, { 102, 152, 255, 255 },
|
||||
{ 102, 152, 203, 255 }, { 102, 152, 152, 255 }, { 102, 152, 102, 255 },
|
||||
{ 102, 152, 51, 255 }, { 102, 152, 0, 255 }, { 51, 152, 255, 255 },
|
||||
{ 51, 152, 203, 255 }, { 51, 152, 152, 255 }, { 51, 152, 102, 255 },
|
||||
{ 51, 152, 51, 255 }, { 51, 152, 0, 255 }, { 230, 134, 0, 255 },
|
||||
{ 255, 51, 203, 255 }, { 255, 51, 152, 255 }, { 255, 51, 102, 255 },
|
||||
{ 255, 51, 51, 255 }, { 255, 51, 0, 255 }, { 0, 102, 51, 255 },
|
||||
{ 0, 102, 0, 255 }, { 203, 102, 255, 255 }, { 203, 102, 203, 255 },
|
||||
{ 203, 102, 152, 255 }, { 203, 102, 102, 255 }, { 203, 102, 51, 255 },
|
||||
{ 203, 102, 0, 255 }, { 152, 102, 255, 255 }, { 152, 102, 203, 255 },
|
||||
{ 152, 102, 152, 255 }, { 152, 102, 102, 255 }, { 152, 102, 51, 255 },
|
||||
{ 152, 102, 0, 255 }, { 102, 102, 255, 255 }, { 102, 102, 203, 255 },
|
||||
{ 102, 102, 152, 255 }, { 102, 102, 102, 255 }, { 102, 102, 51, 255 },
|
||||
{ 102, 102, 0, 255 }, { 51, 102, 255, 255 }, { 51, 102, 203, 255 },
|
||||
{ 51, 102, 152, 255 }, { 51, 102, 102, 255 }, { 51, 102, 51, 255 },
|
||||
{ 51, 102, 0, 255 }, { 255, 0, 255, 255 }, { 255, 0, 203, 255 },
|
||||
{ 255, 0, 152, 255 }, { 255, 0, 102, 255 }, { 255, 0, 51, 255 },
|
||||
{ 255, 175, 19, 255 }, { 0, 51, 255, 255 }, { 0, 51, 203, 255 },
|
||||
{ 203, 51, 255, 255 }, { 203, 51, 203, 255 }, { 203, 51, 152, 255 },
|
||||
{ 203, 51, 102, 255 }, { 203, 51, 51, 255 }, { 203, 51, 0, 255 },
|
||||
{ 152, 51, 255, 255 }, { 152, 51, 203, 255 }, { 152, 51, 152, 255 },
|
||||
{ 152, 51, 102, 255 }, { 152, 51, 51, 255 }, { 152, 51, 0, 255 },
|
||||
{ 102, 51, 255, 255 }, { 102, 51, 203, 255 }, { 102, 51, 152, 255 },
|
||||
{ 102, 51, 102, 255 }, { 102, 51, 51, 255 }, { 102, 51, 0, 255 },
|
||||
{ 51, 51, 255, 255 }, { 51, 51, 203, 255 }, { 51, 51, 152, 255 },
|
||||
{ 51, 51, 102, 255 }, { 51, 51, 51, 255 }, { 51, 51, 0, 255 },
|
||||
{ 255, 203, 102, 255 }, { 255, 203, 152, 255 }, { 255, 203, 203, 255 },
|
||||
{ 255, 203, 255, 255 }, { 0, 51, 152, 255 }, { 0, 51, 102, 255 },
|
||||
{ 0, 51, 51, 255 }, { 0, 51, 0, 255 }, { 203, 0, 255, 255 },
|
||||
{ 203, 0, 203, 255 }, { 203, 0, 152, 255 }, { 203, 0, 102, 255 },
|
||||
{ 203, 0, 51, 255 }, { 255, 227, 70, 255 }, { 152, 0, 255, 255 },
|
||||
{ 152, 0, 203, 255 }, { 152, 0, 152, 255 }, { 152, 0, 102, 255 },
|
||||
{ 152, 0, 51, 255 }, { 152, 0, 0, 255 }, { 102, 0, 255, 255 },
|
||||
{ 102, 0, 203, 255 }, { 102, 0, 152, 255 }, { 102, 0, 102, 255 },
|
||||
{ 102, 0, 51, 255 }, { 102, 0, 0, 255 }, { 51, 0, 255, 255 },
|
||||
{ 51, 0, 203, 255 }, { 51, 0, 152, 255 }, { 51, 0, 102, 255 },
|
||||
{ 51, 0, 51, 255 }, { 51, 0, 0, 255 }, { 255, 203, 51, 255 },
|
||||
{ 255, 203, 0, 255 }, { 255, 255, 0, 255 }, { 255, 255, 51, 255 },
|
||||
{ 255, 255, 102, 255 }, { 255, 255, 152, 255 }, { 255, 255, 203, 255 },
|
||||
{ 255, 255, 255, 0 } // B_TRANSPARENT_MAGIC_CMAP8
|
||||
};
|
||||
|
||||
|
||||
/*! \brief Returns the brightness of an RGB 24 color.
|
||||
\param red Value of the red component.
|
||||
\param green Value of the green component.
|
||||
\param blue Value of the blue component.
|
||||
\return The brightness for the supplied RGB color as a value between 0
|
||||
and 255.
|
||||
*/
|
||||
static inline
|
||||
uint8
|
||||
brightness_for(uint8 red, uint8 green, uint8 blue)
|
||||
{
|
||||
// brightness = 0.301 * red + 0.586 * green + 0.113 * blue
|
||||
// we use for performance reasons:
|
||||
// brightness = (308 * red + 600 * green + 116 * blue) / 1024
|
||||
return uint8((308 * red + 600 * green + 116 * blue) / 1024);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the "distance" between two RGB colors.
|
||||
|
||||
This functions defines an metric on the RGB color space. The distance
|
||||
between two colors is 0, if and only if the colors are equal.
|
||||
|
||||
\param red1 Red component of the first color.
|
||||
\param green1 Green component of the first color.
|
||||
\param blue1 Blue component of the first color.
|
||||
\param red2 Red component of the second color.
|
||||
\param green2 Green component of the second color.
|
||||
\param blue2 Blue component of the second color.
|
||||
\return The distance between the given colors.
|
||||
*/
|
||||
static inline
|
||||
unsigned
|
||||
color_distance(uint8 red1, uint8 green1, uint8 blue1,
|
||||
uint8 red2, uint8 green2, uint8 blue2)
|
||||
{
|
||||
// euklidian distance (its square actually)
|
||||
int rd = (int)red1 - (int)red2;
|
||||
int gd = (int)green1 - (int)green2;
|
||||
int bd = (int)blue1 - (int)blue2;
|
||||
//return rd * rd + gd * gd + bd * bd;
|
||||
|
||||
// distance according to psycho-visual tests
|
||||
int rmean = ((int)red1 + (int)red2) / 2;
|
||||
return (((512 + rmean) * rd * rd) >> 8)
|
||||
+ 4 * gd * gd
|
||||
+ (((767 - rmean) * bd * bd) >> 8);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Creates an uninitialized PaletteConverter.
|
||||
*/
|
||||
PaletteConverter::PaletteConverter()
|
||||
: fColorMap(NULL),
|
||||
fOwnColorMap(NULL),
|
||||
fCStatus(B_NO_INIT)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Creates a PaletteConverter and initializes it to the supplied
|
||||
palette.
|
||||
\param palette The palette being a 256 entry rgb_color array.
|
||||
*/
|
||||
PaletteConverter::PaletteConverter(const rgb_color *palette)
|
||||
: fColorMap(NULL),
|
||||
fOwnColorMap(NULL),
|
||||
fCStatus(B_NO_INIT)
|
||||
{
|
||||
SetTo(palette);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Creates a PaletteConverter and initializes it to the supplied
|
||||
color map.
|
||||
\param colorMap The completely initialized color map.
|
||||
*/
|
||||
PaletteConverter::PaletteConverter(const color_map *colorMap)
|
||||
: fColorMap(NULL),
|
||||
fOwnColorMap(NULL),
|
||||
fCStatus(B_NO_INIT)
|
||||
{
|
||||
SetTo(colorMap);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Frees all resources associated with this object.
|
||||
*/
|
||||
PaletteConverter::~PaletteConverter()
|
||||
{
|
||||
delete fOwnColorMap;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Initializes the converter to the supplied palette.
|
||||
\param palette The palette being a 256 entry rgb_color array.
|
||||
\return \c B_OK, if everything went fine, an error code otherwise.
|
||||
*/
|
||||
status_t
|
||||
PaletteConverter::SetTo(const rgb_color *palette)
|
||||
{
|
||||
// cleanup
|
||||
SetTo((const color_map*)NULL);
|
||||
status_t error = (palette ? B_OK : B_BAD_VALUE);
|
||||
// alloc color map
|
||||
if (error == B_OK) {
|
||||
fOwnColorMap = new(nothrow) color_map;
|
||||
if (fOwnColorMap == NULL)
|
||||
error = B_NO_MEMORY;
|
||||
}
|
||||
// init color map
|
||||
if (error == B_OK) {
|
||||
fColorMap = fOwnColorMap;
|
||||
// init color list
|
||||
memcpy(fOwnColorMap->color_list, palette, sizeof(rgb_color) * 256);
|
||||
// init index map
|
||||
// TODO: build this list takes about 2 seconds in qemu on my system
|
||||
// (because of color_distance())
|
||||
for (int32 color = 0; color < 32768; color++) {
|
||||
// get components
|
||||
uint8 red = (color & 0x7c00) >> 7;
|
||||
uint8 green = (color & 0x3e0) >> 2;
|
||||
uint8 blue = (color & 0x1f) << 3;
|
||||
red |= red >> 5;
|
||||
green |= green >> 5;
|
||||
blue |= blue >> 5;
|
||||
// find closest color
|
||||
uint8 closestIndex = 0;
|
||||
unsigned closestDistance = UINT_MAX;
|
||||
for (int32 i = 0; i < 256; i++) {
|
||||
const rgb_color &c = fOwnColorMap->color_list[i];
|
||||
unsigned distance = color_distance(red, green, blue,
|
||||
c.red, c.green, c.blue);
|
||||
if (distance < closestDistance) {
|
||||
closestIndex = i;
|
||||
closestDistance = distance;
|
||||
}
|
||||
}
|
||||
fOwnColorMap->index_map[color] = closestIndex;
|
||||
}
|
||||
// no need to init inversion map
|
||||
}
|
||||
fCStatus = error;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Initializes the converter to the supplied color map.
|
||||
\param colorMap The completely initialized color map.
|
||||
\return \c B_OK, if everything went fine, an error code otherwise.
|
||||
*/
|
||||
status_t
|
||||
PaletteConverter::SetTo(const color_map *colorMap)
|
||||
{
|
||||
// cleanup
|
||||
if (fOwnColorMap) {
|
||||
delete fOwnColorMap;
|
||||
fOwnColorMap = NULL;
|
||||
}
|
||||
// set
|
||||
fColorMap = colorMap;
|
||||
fCStatus = (fColorMap ? B_OK : B_BAD_VALUE);
|
||||
return fCStatus;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the result of the last initialization via constructor or
|
||||
SetTo().
|
||||
\return \c B_OK, if the converter is properly initialized, an error code
|
||||
otherwise.
|
||||
*/
|
||||
status_t
|
||||
PaletteConverter::InitCheck() const
|
||||
{
|
||||
return fCStatus;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given RGB 15 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param rgb The RGB 15 color value (R[14:10]G[9:5]B[4:0]).
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForRGB15(uint16 rgb) const
|
||||
{
|
||||
return fColorMap->index_map[rgb];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given RGB 15 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param red Red component of the color (R[4:0]).
|
||||
\param green Green component of the color (G[4:0]).
|
||||
\param blue Blue component of the color (B[4:0]).
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForRGB15(uint8 red, uint8 green, uint8 blue) const
|
||||
{
|
||||
// the 5 least significant bits are used
|
||||
return fColorMap->index_map[(red << 10) | (green << 5) | blue];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given RGB 16 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param rgb The RGB 16 color value (R[15:11]G[10:5]B[4:0]).
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForRGB16(uint16 rgb) const
|
||||
{
|
||||
return fColorMap->index_map[(rgb >> 1) & 0x7fe0 | rgb & 0x1f];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given RGB 16 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param red Red component of the color (R[4:0]).
|
||||
\param green Green component of the color (G[5:0]).
|
||||
\param blue Blue component of the color (B[4:0]).
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForRGB16(uint8 red, uint8 green, uint8 blue) const
|
||||
{
|
||||
// the 5 (for red, blue) / 6 (for green) least significant bits are used
|
||||
return fColorMap->index_map[(red << 10) | ((green & 0x3e) << 4) | blue];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given RGB 32 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param rgb The RGB 32 color value (R[31:24]G[23:16]B[15:8]).
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForRGB24(uint32 rgb) const
|
||||
{
|
||||
return fColorMap->index_map[((rgb & 0xf8000000) >> 17)
|
||||
| ((rgb & 0xf80000) >> 14)
|
||||
| ((rgb & 0xf800) >> 11)];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given RGB 24 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param red Red component of the color.
|
||||
\param green Green component of the color.
|
||||
\param blue Blue component of the color.
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForRGB24(uint8 red, uint8 green, uint8 blue) const
|
||||
{
|
||||
return fColorMap->index_map[((red & 0xf8) << 7)
|
||||
| ((green & 0xf8) << 2)
|
||||
| (blue >> 3)];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the palette color index closest to a given Gray 8 color.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param gray The Gray 8 color value.
|
||||
\return The palette color index for the supplied color.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::IndexForGray(uint8 gray) const
|
||||
{
|
||||
return IndexForRGB24(gray, gray, gray);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the RGB color for a given palette color index.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param index The palette color index.
|
||||
\return The color for the supplied palette color index.
|
||||
*/
|
||||
inline
|
||||
const rgb_color &
|
||||
PaletteConverter::RGBColorForIndex(uint8 index) const
|
||||
{
|
||||
return fColorMap->color_list[index];
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the RGB 15 color for a given palette color index.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param index The palette color index.
|
||||
\return The color for the supplied palette color index
|
||||
(R[14:10]G[9:5]B[4:0]).
|
||||
*/
|
||||
inline
|
||||
uint16
|
||||
PaletteConverter::RGB15ColorForIndex(uint8 index) const
|
||||
{
|
||||
const rgb_color &color = fColorMap->color_list[index];
|
||||
return ((color.red & 0xf8) << 7)
|
||||
| ((color.green & 0xf8) << 2)
|
||||
| (color.blue >> 3);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the RGB 16 color for a given palette color index.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param index The palette color index.
|
||||
\return The color for the supplied palette color index
|
||||
(R[15:11]G[10:5]B[4:0]).
|
||||
*/
|
||||
inline
|
||||
uint16
|
||||
PaletteConverter::RGB16ColorForIndex(uint8 index) const
|
||||
{
|
||||
const rgb_color &color = fColorMap->color_list[index];
|
||||
return ((color.red & 0xf8) << 8)
|
||||
| ((color.green & 0xfc) << 3)
|
||||
| (color.blue >> 3);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the RGBA 32 color for a given palette color index.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param index The palette color index.
|
||||
\return The color for the supplied palette color index
|
||||
(A[31:24]B[23:16]G[15:8]R[7:0]).
|
||||
*/
|
||||
inline
|
||||
uint32
|
||||
PaletteConverter::RGBA32ColorForIndex(uint8 index) const
|
||||
{
|
||||
const rgb_color &color = fColorMap->color_list[index];
|
||||
return (color.red << 16) | (color.green << 8) | color.blue
|
||||
| (color.alpha << 24);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the RGBA 32 color for a given palette color index.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param index The palette color index.
|
||||
\param red Reference to the variable the red component shall be stored
|
||||
into.
|
||||
\param green Reference to the variable the green component shall be stored
|
||||
into.
|
||||
\param blue Reference to the variable the blue component shall be stored
|
||||
into.
|
||||
\param alpha Reference to the variable the alpha component shall be stored
|
||||
into.
|
||||
*/
|
||||
inline
|
||||
void
|
||||
PaletteConverter::RGBA32ColorForIndex(uint8 index, uint8 &red, uint8 &green,
|
||||
uint8 &blue, uint8 &alpha) const
|
||||
{
|
||||
const rgb_color &color = fColorMap->color_list[index];
|
||||
red = color.red;
|
||||
green = color.green;
|
||||
blue = color.blue;
|
||||
alpha = color.alpha;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the Gray 8 color for a given palette color index.
|
||||
|
||||
The object must be properly initialized.
|
||||
|
||||
\param index The palette color index.
|
||||
\return The color for the supplied palette color index.
|
||||
*/
|
||||
inline
|
||||
uint8
|
||||
PaletteConverter::GrayColorForIndex(uint8 index) const
|
||||
{
|
||||
const rgb_color &color = fColorMap->color_list[index];
|
||||
return brightness_for(color.red, color.green, color.blue);
|
||||
}
|
||||
|
||||
|
||||
// TODO: Remove these and palette_converter() when BScreen is available.
|
||||
static BLocker gPaletteConverterLock("PalConvLock");
|
||||
static PaletteConverter gPaletteConverter;
|
||||
|
||||
|
||||
/*! \brief Returns a PaletteConverter using the system color palette.
|
||||
\return A PaletteConverter.
|
||||
*/
|
||||
static
|
||||
const PaletteConverter*
|
||||
palette_converter()
|
||||
{
|
||||
if (gPaletteConverterLock.Lock()) {
|
||||
if (gPaletteConverter.InitCheck() != B_OK)
|
||||
gPaletteConverter.SetTo(kSystemPalette);
|
||||
gPaletteConverterLock.Unlock();
|
||||
}
|
||||
return &gPaletteConverter;
|
||||
}
|
||||
|
||||
|
||||
typedef uint32 (readFunc)(const uint8 **source, int32 index);
|
||||
typedef void (writeFunc)(uint8 **dest, uint8 *data, int32 index);
|
||||
|
||||
|
||||
void
|
||||
WriteRGB24(uint8 **dest, uint8 *data, int32 index)
|
||||
{
|
||||
(*dest)[0] = data[0];
|
||||
(*dest)[1] = data[1];
|
||||
(*dest)[2] = data[2];
|
||||
*dest += 3;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
ReadRGB24(const uint8 **source, int32 index)
|
||||
{
|
||||
uint32 result = (*source)[0] | ((*source)[1] << 8) | ((*source)[2] << 16);
|
||||
*source += 3;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriteGray8(uint8 **dest, uint8 *data, int32 index)
|
||||
{
|
||||
**dest = data[2] * 308 + data[1] * 600 + data[0] * 116 >> 10;
|
||||
// this would boost the speed but is less accurate:
|
||||
//*dest = (data[2] << 8) + (data[1] << 9) + (data[0] << 8) >> 10;
|
||||
(*dest)++;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
ReadGray8(const uint8 **source, int32 index)
|
||||
{
|
||||
uint32 result = **source;
|
||||
(*source)++;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriteGray1(uint8 **dest, uint8 *data, int32 index)
|
||||
{
|
||||
int32 shift = 7 - (index % 8);
|
||||
**dest &= ~(0x01 << shift);
|
||||
**dest |= (data[2] * 308 + data[1] * 600 + data[0] * 116) >> (17 - shift);
|
||||
if (shift == 0)
|
||||
(*dest)++;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
ReadGray1(const uint8 **source, int32 index)
|
||||
{
|
||||
int32 shift = 7 - (index % 8);
|
||||
uint32 result = ((**source >> shift) & 0x01) ? 0xff : 0x00;
|
||||
if (shift == 0)
|
||||
(*source)++;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WriteCMAP8(uint8 **dest, uint8 *data, int32 index)
|
||||
{
|
||||
**dest = gPaletteConverter.IndexForRGB15(*(uint16 *)data);
|
||||
(*dest)++;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
ReadCMAP8(const uint8 **source, int32 index)
|
||||
{
|
||||
uint32 result = gPaletteConverter.RGBA32ColorForIndex(**source);
|
||||
(*source)++;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<typename srcByte, typename dstByte>
|
||||
void
|
||||
ConvertBits(const srcByte *srcBuffer, dstByte *dstBuffer, int32 redShift,
|
||||
int32 greenShift, int32 blueShift, int32 alphaShift, int32 alphaBits,
|
||||
uint32 redMask, uint32 greenMask, uint32 blueMask, uint32 alphaMask,
|
||||
int32 srcBytesPerRow, int32 dstBytesPerRow, int32 srcBitsPerPixel,
|
||||
int32 dstBitsPerPixel, int32 width, int32 height, bool srcSwap,
|
||||
bool dstSwap, readFunc *srcFunc, writeFunc *dstFunc)
|
||||
{
|
||||
int32 srcLinePad = ((srcBytesPerRow << 3) - width * srcBitsPerPixel) >> 3;
|
||||
int32 dstLinePad = ((dstBytesPerRow << 3) - width * dstBitsPerPixel) >> 3;
|
||||
|
||||
register uint32 result;
|
||||
register uint32 source;
|
||||
for (int32 i = 0; i < height; i++) {
|
||||
for (int32 j = 0; j < width; j++) {
|
||||
if (srcFunc)
|
||||
source = srcFunc((const uint8 **)&srcBuffer, j);
|
||||
else {
|
||||
source = *srcBuffer;
|
||||
srcBuffer++;
|
||||
}
|
||||
|
||||
if (srcSwap)
|
||||
source = (source << 8) | (source >> 8);
|
||||
|
||||
if (redShift > 0)
|
||||
result = ((source >> redShift) & redMask);
|
||||
else
|
||||
result = ((source << -redShift) & redMask);
|
||||
|
||||
if (greenShift > 0)
|
||||
result |= ((source >> greenShift) & greenMask);
|
||||
else
|
||||
result |= ((source << -greenShift) & greenMask);
|
||||
|
||||
if (blueShift > 0)
|
||||
result |= ((source >> blueShift) & blueMask);
|
||||
else
|
||||
result |= ((source << -blueShift) & blueMask);
|
||||
|
||||
if (alphaBits > 0) {
|
||||
if (alphaShift > 0)
|
||||
result |= ((source >> alphaShift) & alphaMask);
|
||||
else
|
||||
result |= ((source << -alphaShift) & alphaMask);
|
||||
|
||||
// if we only had one alpha bit we want it to be 0/255
|
||||
if (alphaBits == 1 && result & alphaMask)
|
||||
result |= alphaMask;
|
||||
} else
|
||||
result |= alphaMask;
|
||||
|
||||
if (dstSwap)
|
||||
*dstBuffer = (result << 8) | (result >> 8);
|
||||
|
||||
if (dstFunc)
|
||||
dstFunc((uint8 **)&dstBuffer, (uint8 *)&result, j);
|
||||
else {
|
||||
*dstBuffer = result;
|
||||
dstBuffer++;
|
||||
}
|
||||
}
|
||||
|
||||
(char *)srcBuffer += srcLinePad;
|
||||
(char *)dstBuffer += dstLinePad;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<typename srcByte>
|
||||
status_t
|
||||
ConvertBits(const srcByte *srcBuffer, void *dstBuffer, int32 redShift,
|
||||
int32 greenShift, int32 blueShift, int32 alphaShift, int32 alphaBits,
|
||||
int32 srcBytesPerRow, int32 dstBytesPerRow, int32 srcBitsPerPixel,
|
||||
color_space dstColorSpace, int32 width, int32 height, bool srcSwap,
|
||||
readFunc *srcFunc)
|
||||
{
|
||||
switch (dstColorSpace) {
|
||||
case B_RGBA32:
|
||||
ConvertBits(srcBuffer, (uint32 *)dstBuffer, redShift - 24,
|
||||
greenShift - 16, blueShift - 8, alphaShift - 32, alphaBits,
|
||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, srcBytesPerRow,
|
||||
dstBytesPerRow, srcBitsPerPixel, 32, width, height, srcSwap,
|
||||
false, srcFunc, NULL);
|
||||
break;
|
||||
|
||||
case B_RGBA32_BIG:
|
||||
ConvertBits(srcBuffer, (uint32 *)dstBuffer, redShift - 16,
|
||||
greenShift - 24, blueShift - 32, alphaShift - 8, alphaBits,
|
||||
0x0000ff00, 0x00ff0000, 0xff000000, 0x00000ff, srcBytesPerRow,
|
||||
dstBytesPerRow, srcBitsPerPixel, 32, width, height, srcSwap,
|
||||
false, srcFunc, NULL);
|
||||
break;
|
||||
|
||||
/* Note: we set the unused alpha to 255 here. This is because BeOS
|
||||
uses the unused alpha for B_OP_ALPHA even though it should
|
||||
not care about it. */
|
||||
case B_RGB32:
|
||||
ConvertBits(srcBuffer, (uint32 *)dstBuffer, redShift - 24,
|
||||
greenShift - 16, blueShift - 8, 0, 0, 0x00ff0000, 0x0000ff00,
|
||||
0x000000ff, 0xff000000, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 32, width, height, srcSwap, false, srcFunc,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case B_RGB32_BIG:
|
||||
ConvertBits(srcBuffer, (uint32 *)dstBuffer, redShift - 16,
|
||||
greenShift - 24, blueShift - 32, 0, 0, 0x0000ff00, 0x00ff0000,
|
||||
0xff000000, 0x000000ff, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 32, width, height, srcSwap, false, srcFunc,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case B_RGB24:
|
||||
ConvertBits(srcBuffer, (uint8 *)dstBuffer, redShift - 24,
|
||||
greenShift - 16, blueShift - 8, 0, 0, 0xff0000, 0x00ff00,
|
||||
0x0000ff, 0x000000, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 24, width, height, srcSwap, false, srcFunc,
|
||||
WriteRGB24);
|
||||
break;
|
||||
|
||||
case B_RGB24_BIG:
|
||||
ConvertBits(srcBuffer, (uint8 *)dstBuffer, redShift - 8,
|
||||
greenShift - 16, blueShift - 24, 0, 0, 0x0000ff, 0x00ff00,
|
||||
0xff0000, 0x000000, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 24, width, height, srcSwap, false, srcFunc,
|
||||
WriteRGB24);
|
||||
break;
|
||||
|
||||
case B_RGB16:
|
||||
case B_RGB16_BIG:
|
||||
ConvertBits(srcBuffer, (uint16 *)dstBuffer, redShift - 16,
|
||||
greenShift - 11, blueShift - 5, 0, 0, 0xf800, 0x07e0, 0x001f,
|
||||
0x0000, srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 16,
|
||||
width, height, srcSwap, dstColorSpace == B_RGB16_BIG, srcFunc,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case B_RGBA15:
|
||||
case B_RGBA15_BIG:
|
||||
ConvertBits(srcBuffer, (uint16 *)dstBuffer, redShift - 15,
|
||||
greenShift - 10, blueShift - 5, alphaShift - 16, alphaBits,
|
||||
0x7c00, 0x03e0, 0x001f, 0x8000, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 16, width, height, srcSwap,
|
||||
dstColorSpace == B_RGBA15_BIG, srcFunc, NULL);
|
||||
break;
|
||||
|
||||
case B_RGB15:
|
||||
case B_RGB15_BIG:
|
||||
ConvertBits(srcBuffer, (uint16 *)dstBuffer, redShift - 15,
|
||||
greenShift - 10, blueShift - 5, 0, 0, 0x7c00, 0x03e0, 0x001f,
|
||||
0x0000, srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 16,
|
||||
width, height, srcSwap, dstColorSpace == B_RGB15_BIG, srcFunc,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case B_GRAY8:
|
||||
ConvertBits(srcBuffer, (uint8 *)dstBuffer, redShift - 24,
|
||||
greenShift - 16, blueShift - 8, 0, 0, 0x00ff0000, 0x0000ff00,
|
||||
0x000000ff, 0x00000000, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 8, width, height, srcSwap, false, srcFunc,
|
||||
WriteGray8);
|
||||
break;
|
||||
|
||||
case B_GRAY1:
|
||||
ConvertBits(srcBuffer, (uint8 *)dstBuffer, redShift - 24,
|
||||
greenShift - 16, blueShift - 8, 0, 0, 0x00ff0000, 0x0000ff00,
|
||||
0x000000ff, 0x00000000, srcBytesPerRow, dstBytesPerRow,
|
||||
srcBitsPerPixel, 1, width, height, srcSwap, false, srcFunc,
|
||||
WriteGray1);
|
||||
break;
|
||||
|
||||
case B_CMAP8:
|
||||
palette_converter();
|
||||
ConvertBits(srcBuffer, (uint8 *)dstBuffer, redShift - 15,
|
||||
greenShift - 10, blueShift - 5, 0, 0, 0x7c00, 0x03e0, 0x001f,
|
||||
0x0000, srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 8,
|
||||
width, height, srcSwap, false, srcFunc, WriteCMAP8);
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Converts a source buffer in one colorspace into a destination
|
||||
buffer of another colorspace.
|
||||
|
||||
\param srcBuffer The raw source buffer.
|
||||
\param dstBuffer The raw destination buffer.
|
||||
\param srcBytesPerRow How many bytes per row the source buffer has got.
|
||||
\param dstBytesPerRow How many bytes per row the destination buffer has got.
|
||||
\param srcColorSpace The colorspace the source buffer is in.
|
||||
\param dstColorSpace The colorspace the buffer shall be converted to.
|
||||
\param width The width (in pixels) of each row.
|
||||
\param height The height (in pixels) of the buffers.
|
||||
\return
|
||||
- \c B_OK: Indicates success.
|
||||
- \c B_BAD_VALUE: \c NULL buffer or at least one colorspace is unsupported.
|
||||
*/
|
||||
status_t
|
||||
ConvertBits(const void *srcBuffer, void *dstBuffer, uint32 srcBytesPerRow,
|
||||
uint32 dstBytesPerRow, color_space srcColorSpace,
|
||||
color_space dstColorSpace, int32 width, int32 height)
|
||||
{
|
||||
if (!srcBuffer || !dstBuffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (srcColorSpace == dstColorSpace && srcBytesPerRow == dstBytesPerRow) {
|
||||
memcpy(dstBuffer, srcBuffer, height * srcBytesPerRow);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
switch (srcColorSpace) {
|
||||
case B_RGBA32:
|
||||
return ConvertBits((const uint32 *)srcBuffer, dstBuffer, 24, 16,
|
||||
8, 32, 8, srcBytesPerRow, dstBytesPerRow, 32, dstColorSpace,
|
||||
width, height, false, NULL);
|
||||
break;
|
||||
|
||||
case B_RGBA32_BIG:
|
||||
return ConvertBits((const uint32 *)srcBuffer, dstBuffer, 16, 24,
|
||||
32, 8, 8, srcBytesPerRow, dstBytesPerRow, 32, dstColorSpace,
|
||||
width, height, false, NULL);
|
||||
break;
|
||||
|
||||
case B_RGB32:
|
||||
return ConvertBits((const uint32 *)srcBuffer, dstBuffer, 24, 16,
|
||||
8, 0, 0, srcBytesPerRow, dstBytesPerRow, 32, dstColorSpace,
|
||||
width, height, false, NULL);
|
||||
break;
|
||||
|
||||
case B_RGB32_BIG:
|
||||
return ConvertBits((const uint32 *)srcBuffer, dstBuffer, 16, 24,
|
||||
32, 0, 0, srcBytesPerRow, dstBytesPerRow, 32, dstColorSpace,
|
||||
width, height, false, NULL);
|
||||
break;
|
||||
|
||||
case B_RGB24:
|
||||
return ConvertBits((const uint8 *)srcBuffer, dstBuffer, 24, 16, 8,
|
||||
0, 0, srcBytesPerRow, dstBytesPerRow, 24, dstColorSpace,
|
||||
width, height, false, ReadRGB24);
|
||||
break;
|
||||
|
||||
case B_RGB24_BIG:
|
||||
return ConvertBits((const uint8 *)srcBuffer, dstBuffer, 8, 16, 24,
|
||||
0, 0, srcBytesPerRow, dstBytesPerRow, 24, dstColorSpace,
|
||||
width, height, false, ReadRGB24);
|
||||
break;
|
||||
|
||||
case B_RGB16:
|
||||
case B_RGB16_BIG:
|
||||
return ConvertBits((const uint16 *)srcBuffer, dstBuffer, 16, 11, 5,
|
||||
0, 0, srcBytesPerRow, dstBytesPerRow, 16, dstColorSpace, width,
|
||||
height, srcColorSpace == B_RGB16_BIG, NULL);
|
||||
break;
|
||||
|
||||
case B_RGBA15:
|
||||
case B_RGBA15_BIG:
|
||||
return ConvertBits((const uint16 *)srcBuffer, dstBuffer, 15, 10, 5,
|
||||
16, 1, srcBytesPerRow, dstBytesPerRow, 16, dstColorSpace,
|
||||
width, height, srcColorSpace == B_RGBA15_BIG, NULL);
|
||||
break;
|
||||
|
||||
case B_RGB15:
|
||||
case B_RGB15_BIG:
|
||||
return ConvertBits((const uint16 *)srcBuffer, dstBuffer, 15, 10, 5,
|
||||
0, 0, srcBytesPerRow, dstBytesPerRow, 16, dstColorSpace, width,
|
||||
height, srcColorSpace == B_RGB15_BIG, NULL);
|
||||
break;
|
||||
|
||||
case B_GRAY8:
|
||||
return ConvertBits((const uint8 *)srcBuffer, dstBuffer, 8, 8, 8, 0,
|
||||
0, srcBytesPerRow, dstBytesPerRow, 8, dstColorSpace, width,
|
||||
height, false, ReadGray8);
|
||||
break;
|
||||
|
||||
case B_GRAY1:
|
||||
return ConvertBits((const uint8 *)srcBuffer, dstBuffer, 8, 8, 8, 0,
|
||||
0, srcBytesPerRow, dstBytesPerRow, 1, dstColorSpace, width,
|
||||
height, false, ReadGray1);
|
||||
break;
|
||||
|
||||
case B_CMAP8:
|
||||
palette_converter();
|
||||
return ConvertBits((const uint8 *)srcBuffer, dstBuffer, 24, 16, 8,
|
||||
32, 8, srcBytesPerRow, dstBytesPerRow, 8, dstColorSpace, width,
|
||||
height, false, ReadCMAP8);
|
||||
break;
|
||||
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace BPrivate
|
|
@ -38,8 +38,9 @@ MergeObject <libbe>interface_kit.o :
|
|||
ChannelControl.cpp
|
||||
ChannelSlider.cpp
|
||||
CheckBox.cpp
|
||||
ColorUtils.cc
|
||||
ColorConversion.cpp
|
||||
ColorControl.cpp
|
||||
ColorUtils.cc
|
||||
Control.cpp
|
||||
Deskbar.cpp
|
||||
Dragger.cpp
|
||||
|
|
Loading…
Reference in New Issue