diff --git a/headers/private/servers/app/ServerBitmap.h b/headers/private/servers/app/ServerBitmap.h index de70766d5f..a12f526fe9 100644 --- a/headers/private/servers/app/ServerBitmap.h +++ b/headers/private/servers/app/ServerBitmap.h @@ -143,6 +143,12 @@ class UtilityBitmap : public ServerBitmap { screen_id screen = B_MAIN_SCREEN_ID); UtilityBitmap(const ServerBitmap* bmp); + UtilityBitmap(const uint8* alreadyPaddedData, + uint32 width, + uint32 height, + color_space format); + + virtual ~UtilityBitmap(); }; diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index ebeed96819..d5af2fd76c 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -36,54 +36,56 @@ greater than the default will result in the number of bytes specified. \param screen Screen assigned to the bitmap. */ -ServerBitmap::ServerBitmap(BRect rect,color_space space, int32 flags, - int32 bytesperline, screen_id screen) +ServerBitmap::ServerBitmap(BRect rect, color_space space, + int32 flags, int32 bytesPerLine, + screen_id screen) + : fInitialized(false), + fArea(B_ERROR), + fBuffer(NULL), + // WARNING: '1' is added to the width and height. + // Same is done in FBBitmap subclass, so if you + // modify here make sure to do the same under + // FBBitmap::SetSize(...) + fWidth(rect.IntegerWidth() + 1), + fHeight(rect.IntegerHeight() + 1), + fBytesPerRow(0), + fSpace(space), + fFlags(flags), + fBitsPerPixel(0) + // TODO: what about fToken and fOffset ?!? + { - fInitialized=false; - - // WARNING: '1' is added to the width and height. Same is done in FBBitmap - // subclass, so if you modify here make sure to do the same under FBBitmap::SetSize(...) - fWidth=rect.IntegerWidth()+1; - fHeight=rect.IntegerHeight()+1; - fSpace=space; - fArea=B_ERROR; - fBuffer=NULL; - fFlags=flags; - - _HandleSpace(space, bytesperline); + _HandleSpace(space, bytesPerLine); } //! Copy constructor does not copy the buffer. -ServerBitmap::ServerBitmap(const ServerBitmap *bmp) +ServerBitmap::ServerBitmap(const ServerBitmap* bmp) + : fInitialized(false), + fArea(B_ERROR), + fBuffer(NULL) + // TODO: what about fToken and fOffset ?!? { - fInitialized=false; - fArea=B_ERROR; - fBuffer=NULL; - - if(bmp) - { - fWidth=bmp->fWidth; - fHeight=bmp->fHeight; - fBytesPerRow=bmp->fBytesPerRow; - fSpace=bmp->fSpace; - fFlags=bmp->fFlags; - fBitsPerPixel=bmp->fBitsPerPixel; - } - else - { - fWidth=0; - fHeight=0; - fBytesPerRow=0; - fSpace=B_NO_COLOR_SPACE; - fFlags=0; - fBitsPerPixel=0; + if (bmp) { + fWidth = bmp->fWidth; + fHeight = bmp->fHeight; + fBytesPerRow = bmp->fBytesPerRow; + fSpace = bmp->fSpace; + fFlags = bmp->fFlags; + fBitsPerPixel = bmp->fBitsPerPixel; + } else { + fWidth = 0; + fHeight = 0; + fBytesPerRow = 0; + fSpace = B_NO_COLOR_SPACE; + fFlags = 0; + fBitsPerPixel = 0; } } /*! \brief Empty. Defined for subclasses. */ -ServerBitmap::~ServerBitmap(void) +ServerBitmap::~ServerBitmap() { } @@ -91,9 +93,10 @@ ServerBitmap::~ServerBitmap(void) \brief Gets the number of bytes occupied by the bitmap, including padding bytes. \return The number of bytes occupied by the bitmap, including padding. */ -uint32 ServerBitmap::BitsLength(void) const +uint32 +ServerBitmap::BitsLength(void) const { - return (uint32)(fBytesPerRow*fHeight); + return (uint32)(fBytesPerRow * fHeight); } /*! @@ -102,11 +105,14 @@ uint32 ServerBitmap::BitsLength(void) const Subclasses should call this so the buffer can automagically be allocated on the heap. */ -void ServerBitmap::_AllocateBuffer(void) +void +ServerBitmap::_AllocateBuffer(void) { - if(fBuffer!=NULL) + uint32 length = BitsLength(); + if (length > 0) { delete fBuffer; - fBuffer=new uint8[BitsLength()]; + fBuffer = new uint8[length]; + } } /*! @@ -114,29 +120,27 @@ void ServerBitmap::_AllocateBuffer(void) Subclasses should call this to free the internal buffer. */ -void ServerBitmap::_FreeBuffer(void) +void +ServerBitmap::_FreeBuffer(void) { - if(fBuffer!=NULL) - { - delete fBuffer; - fBuffer=NULL; - } + delete fBuffer; + fBuffer = NULL; } /*! \brief Internal function used to translate color space values to appropriate internal values. \param space Color space for the bitmap. - \param bytesperline Number of bytes per row. + \param bytesPerRow Number of bytes per row to be used as an override. */ -void ServerBitmap::_HandleSpace(color_space space, int32 bytesperline) +void +ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow) { - // Big convoluted mess just to handle every color space and dword align - // the buffer - switch(space) - { - // Buffer is dword-aligned, so nothing need be done - // aside from allocate the memory + // calculate the minimum bytes per row + // set fBitsPerPixel + int32 minBPR = 0; + switch(space) { + // 32-bit case B_RGB32: case B_RGBA32: case B_RGB32_BIG: @@ -154,8 +158,11 @@ void ServerBitmap::_HandleSpace(color_space space, int32 bytesperline) case B_CMY32: case B_CMYA32: case B_CMYK32: + minBPR = fWidth * 4; + fBitsPerPixel = 32; + break; - // 24-bit = 32-bit with extra 8 bits ignored + // 24-bit case B_RGB24_BIG: case B_RGB24: case B_LAB24: @@ -164,64 +171,14 @@ void ServerBitmap::_HandleSpace(color_space space, int32 bytesperline) case B_HSV24: case B_HLS24: case B_CMY24: - { - if(bytesperline<(fWidth*4)) - fBytesPerRow=fWidth*4; - else - fBytesPerRow=bytesperline; - fBitsPerPixel=32; + // TODO: These last two are calculated + // (width + 3) / 4 * 12 + // in Bitmap.cpp, I don't understand why though. + case B_YCbCr444: + case B_YUV444: + minBPR = fWidth * 3; + fBitsPerPixel = 24; break; - } - // Calculate size and dword-align - - // 1-bit - case B_GRAY1: - { - int32 numbytes=fWidth>>3; - if((fWidth % 8) != 0) - numbytes++; - if(bytesperline 0 || bytesPerRow > 0) { + // add the padding or use the provided bytesPerRow if sufficient + if (bytesPerRow >= minBPR) { + fBytesPerRow = bytesPerRow; + } else { + fBytesPerRow = ((minBPR + 3) / 4) * 4; + } + } } -UtilityBitmap::UtilityBitmap(BRect rect,color_space space, int32 flags, - int32 bytesperline, screen_id screen) -: ServerBitmap(rect,space,flags,bytesperline,screen) +UtilityBitmap::UtilityBitmap(BRect rect, color_space space, + int32 flags, int32 bytesperline, + screen_id screen) + : ServerBitmap(rect, space, flags, bytesperline, screen) { _AllocateBuffer(); } -UtilityBitmap::UtilityBitmap(const ServerBitmap *bmp) -: ServerBitmap(bmp) +UtilityBitmap::UtilityBitmap(const ServerBitmap* bmp) + : ServerBitmap(bmp) { _AllocateBuffer(); - if(bmp->Bits()) - memcpy(Bits(),bmp->Bits(),bmp->BitsLength()); + if (bmp->Bits()) + memcpy(Bits(), bmp->Bits(), bmp->BitsLength()); } -UtilityBitmap::~UtilityBitmap(void) +UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, + uint32 width, uint32 height, + color_space format) + : ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0) +{ + _AllocateBuffer(); + if (Bits()) + memcpy(Bits(), alreadyPaddedData, BitsLength()); +} + +UtilityBitmap::~UtilityBitmap() { _FreeBuffer(); }