2005-12-29 18:36:18 +03:00
|
|
|
/*
|
2006-02-05 21:14:14 +03:00
|
|
|
* Copyright 2001-2006, Haiku.
|
2005-12-29 18:36:18 +03:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* DarkWyrm <bpmagic@columbus.rr.com>
|
|
|
|
*/
|
2005-06-14 04:38:21 +04:00
|
|
|
|
2005-11-13 02:27:14 +03:00
|
|
|
|
2003-01-13 01:51:01 +03:00
|
|
|
#include "ServerBitmap.h"
|
2006-03-05 15:59:39 +03:00
|
|
|
#include "ColorConversion.h"
|
2003-01-13 01:51:01 +03:00
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
#include <new>
|
2006-02-05 21:14:14 +03:00
|
|
|
#include <stdio.h>
|
2005-12-29 18:36:18 +03:00
|
|
|
#include <string.h>
|
|
|
|
|
2005-11-13 02:27:14 +03:00
|
|
|
using std::nothrow;
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2003-01-13 01:51:01 +03:00
|
|
|
/*!
|
|
|
|
\brief Constructor called by the BitmapManager (only).
|
2003-01-20 02:04:58 +03:00
|
|
|
\param rect Size of the bitmap.
|
|
|
|
\param space Color space of the bitmap
|
|
|
|
\param flags Various bitmap flags to tweak the bitmap as defined in Bitmap.h
|
|
|
|
\param bytesperline Number of bytes in each row. -1 implies the default value. Any
|
|
|
|
value less than the the default will less than the default will be overridden, but any value
|
2003-01-13 01:51:01 +03:00
|
|
|
greater than the default will result in the number of bytes specified.
|
2003-01-20 02:04:58 +03:00
|
|
|
\param screen Screen assigned to the bitmap.
|
2003-01-13 01:51:01 +03:00
|
|
|
*/
|
2005-04-14 04:06:01 +04:00
|
|
|
ServerBitmap::ServerBitmap(BRect rect, color_space space,
|
2006-02-05 21:14:14 +03:00
|
|
|
int32 flags, int32 bytesPerRow,
|
2005-04-14 04:06:01 +04:00
|
|
|
screen_id screen)
|
|
|
|
: fInitialized(false),
|
|
|
|
fArea(B_ERROR),
|
|
|
|
fBuffer(NULL),
|
2005-12-29 18:36:18 +03:00
|
|
|
fReferenceCount(1),
|
2005-04-14 04:06:01 +04:00
|
|
|
// 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 ?!?
|
2003-01-13 01:51:01 +03:00
|
|
|
{
|
2006-02-05 21:14:14 +03:00
|
|
|
_HandleSpace(space, bytesPerRow);
|
2003-01-13 01:51:01 +03:00
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2003-01-13 01:51:01 +03:00
|
|
|
//! Copy constructor does not copy the buffer.
|
2005-04-14 04:06:01 +04:00
|
|
|
ServerBitmap::ServerBitmap(const ServerBitmap* bmp)
|
|
|
|
: fInitialized(false),
|
|
|
|
fArea(B_ERROR),
|
2005-12-29 18:36:18 +03:00
|
|
|
fBuffer(NULL),
|
|
|
|
fReferenceCount(1)
|
2005-04-14 04:06:01 +04:00
|
|
|
// TODO: what about fToken and fOffset ?!?
|
2003-01-13 01:51:01 +03:00
|
|
|
{
|
2005-04-14 04:06:01 +04:00
|
|
|
if (bmp) {
|
2005-06-14 04:38:21 +04:00
|
|
|
fInitialized = bmp->fInitialized;
|
2005-04-14 04:06:01 +04:00
|
|
|
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;
|
2003-01-13 01:51:01 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2003-01-13 01:51:01 +03:00
|
|
|
/*!
|
|
|
|
\brief Empty. Defined for subclasses.
|
|
|
|
*/
|
2005-04-14 04:06:01 +04:00
|
|
|
ServerBitmap::~ServerBitmap()
|
2003-01-13 01:51:01 +03:00
|
|
|
{
|
2005-06-01 12:55:39 +04:00
|
|
|
// TODO: Maybe it would be wiser to free the buffer here,
|
|
|
|
// instead of do that in every subclass ?
|
2003-01-13 01:51:01 +03:00
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
|
|
|
void
|
|
|
|
ServerBitmap::Acquire()
|
|
|
|
{
|
|
|
|
atomic_add(&fReferenceCount, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
ServerBitmap::_Release()
|
|
|
|
{
|
|
|
|
if (atomic_add(&fReferenceCount, -1) == 1)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-22 23:23:22 +03:00
|
|
|
/*!
|
|
|
|
\brief Internal function used by subclasses
|
|
|
|
|
|
|
|
Subclasses should call this so the buffer can automagically
|
|
|
|
be allocated on the heap.
|
|
|
|
*/
|
2005-04-14 04:06:01 +04:00
|
|
|
void
|
|
|
|
ServerBitmap::_AllocateBuffer(void)
|
2003-02-22 23:23:22 +03:00
|
|
|
{
|
2005-04-14 04:06:01 +04:00
|
|
|
uint32 length = BitsLength();
|
|
|
|
if (length > 0) {
|
2005-06-01 12:55:39 +04:00
|
|
|
delete[] fBuffer;
|
2005-06-14 04:38:21 +04:00
|
|
|
fBuffer = new(nothrow) uint8[length];
|
|
|
|
fInitialized = fBuffer != NULL;
|
2005-04-14 04:06:01 +04:00
|
|
|
}
|
2003-02-22 23:23:22 +03:00
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2003-02-22 23:23:22 +03:00
|
|
|
/*!
|
|
|
|
\brief Internal function used by subclasses
|
|
|
|
|
|
|
|
Subclasses should call this to free the internal buffer.
|
|
|
|
*/
|
2005-04-14 04:06:01 +04:00
|
|
|
void
|
2005-12-29 18:36:18 +03:00
|
|
|
ServerBitmap::_FreeBuffer()
|
2003-02-22 23:23:22 +03:00
|
|
|
{
|
2005-06-01 12:55:39 +04:00
|
|
|
delete[] fBuffer;
|
2005-04-14 04:06:01 +04:00
|
|
|
fBuffer = NULL;
|
2005-06-14 04:38:21 +04:00
|
|
|
fInitialized = false;
|
2003-02-22 23:23:22 +03:00
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2003-01-13 01:51:01 +03:00
|
|
|
/*!
|
|
|
|
\brief Internal function used to translate color space values to appropriate internal
|
|
|
|
values.
|
2003-01-20 02:04:58 +03:00
|
|
|
\param space Color space for the bitmap.
|
2005-04-14 04:06:01 +04:00
|
|
|
\param bytesPerRow Number of bytes per row to be used as an override.
|
2003-01-13 01:51:01 +03:00
|
|
|
*/
|
2005-04-14 04:06:01 +04:00
|
|
|
void
|
|
|
|
ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow)
|
2003-01-13 01:51:01 +03:00
|
|
|
{
|
2005-04-14 04:06:01 +04:00
|
|
|
// calculate the minimum bytes per row
|
|
|
|
// set fBitsPerPixel
|
|
|
|
int32 minBPR = 0;
|
|
|
|
switch(space) {
|
|
|
|
// 32-bit
|
2003-01-13 01:51:01 +03:00
|
|
|
case B_RGB32:
|
|
|
|
case B_RGBA32:
|
|
|
|
case B_RGB32_BIG:
|
|
|
|
case B_RGBA32_BIG:
|
|
|
|
case B_UVL32:
|
|
|
|
case B_UVLA32:
|
|
|
|
case B_LAB32:
|
|
|
|
case B_LABA32:
|
|
|
|
case B_HSI32:
|
|
|
|
case B_HSIA32:
|
|
|
|
case B_HSV32:
|
|
|
|
case B_HSVA32:
|
|
|
|
case B_HLS32:
|
|
|
|
case B_HLSA32:
|
|
|
|
case B_CMY32:
|
|
|
|
case B_CMYA32:
|
|
|
|
case B_CMYK32:
|
2005-04-14 04:06:01 +04:00
|
|
|
minBPR = fWidth * 4;
|
|
|
|
fBitsPerPixel = 32;
|
|
|
|
break;
|
2003-01-13 01:51:01 +03:00
|
|
|
|
2005-04-14 04:06:01 +04:00
|
|
|
// 24-bit
|
2003-01-13 01:51:01 +03:00
|
|
|
case B_RGB24_BIG:
|
|
|
|
case B_RGB24:
|
|
|
|
case B_LAB24:
|
|
|
|
case B_UVL24:
|
|
|
|
case B_HSI24:
|
|
|
|
case B_HSV24:
|
|
|
|
case B_HLS24:
|
|
|
|
case B_CMY24:
|
2005-04-14 04:06:01 +04:00
|
|
|
// 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;
|
2003-01-13 01:51:01 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
// 16-bit
|
|
|
|
case B_YUV9:
|
|
|
|
case B_YUV12:
|
|
|
|
case B_RGB15:
|
|
|
|
case B_RGBA15:
|
|
|
|
case B_RGB16:
|
|
|
|
case B_RGB16_BIG:
|
|
|
|
case B_RGB15_BIG:
|
|
|
|
case B_RGBA15_BIG:
|
2005-04-14 04:06:01 +04:00
|
|
|
minBPR = fWidth * 2;
|
|
|
|
fBitsPerPixel = 16;
|
2003-01-13 01:51:01 +03:00
|
|
|
break;
|
2005-04-14 04:06:01 +04:00
|
|
|
|
|
|
|
case B_YCbCr422:
|
|
|
|
case B_YUV422:
|
|
|
|
minBPR = (fWidth + 3) / 4 * 8;
|
|
|
|
fBitsPerPixel = 16;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// 8-bit
|
|
|
|
case B_CMAP8:
|
|
|
|
case B_GRAY8:
|
|
|
|
minBPR = fWidth;
|
|
|
|
fBitsPerPixel = 8;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// 1-bit
|
|
|
|
case B_GRAY1:
|
|
|
|
minBPR = (fWidth + 7) / 8;
|
|
|
|
fBitsPerPixel = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// TODO: ??? get a clue what these mean
|
|
|
|
case B_YCbCr411:
|
|
|
|
case B_YUV411:
|
|
|
|
case B_YUV420:
|
|
|
|
case B_YCbCr420:
|
|
|
|
minBPR = (fWidth + 3) / 4 * 6;
|
|
|
|
fBitsPerPixel = 0;
|
|
|
|
break;
|
|
|
|
|
2003-01-13 01:51:01 +03:00
|
|
|
case B_NO_COLOR_SPACE:
|
2005-04-14 04:06:01 +04:00
|
|
|
default:
|
|
|
|
fBitsPerPixel = 0;
|
2003-01-13 01:51:01 +03:00
|
|
|
break;
|
|
|
|
}
|
2005-04-14 04:06:01 +04:00
|
|
|
if (minBPR > 0 || bytesPerRow > 0) {
|
|
|
|
// add the padding or use the provided bytesPerRow if sufficient
|
|
|
|
if (bytesPerRow >= minBPR) {
|
|
|
|
fBytesPerRow = bytesPerRow;
|
|
|
|
} else {
|
|
|
|
fBytesPerRow = ((minBPR + 3) / 4) * 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2006-03-05 15:59:39 +03:00
|
|
|
status_t
|
|
|
|
ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow,
|
|
|
|
color_space colorSpace)
|
|
|
|
{
|
|
|
|
if (!bits || bitsLength < 0 || bytesPerRow <= 0)
|
|
|
|
return B_BAD_VALUE;
|
|
|
|
|
2006-03-06 02:53:33 +03:00
|
|
|
return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(),
|
|
|
|
bytesPerRow, fBytesPerRow, colorSpace, fSpace, fWidth, fHeight);
|
2006-03-05 15:59:39 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-02-05 21:14:14 +03:00
|
|
|
void
|
|
|
|
ServerBitmap::PrintToStream()
|
|
|
|
{
|
|
|
|
printf("Bitmap@%p: (%ld:%ld), space %ld, bpr %ld, buffer %p\n",
|
|
|
|
this, fWidth, fHeight, (int32)fSpace, fBytesPerRow, fBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
// #pragma mark -
|
|
|
|
|
|
|
|
|
2005-04-14 04:06:01 +04:00
|
|
|
UtilityBitmap::UtilityBitmap(BRect rect, color_space space,
|
|
|
|
int32 flags, int32 bytesperline,
|
|
|
|
screen_id screen)
|
|
|
|
: ServerBitmap(rect, space, flags, bytesperline, screen)
|
|
|
|
{
|
|
|
|
_AllocateBuffer();
|
2003-01-13 01:51:01 +03:00
|
|
|
}
|
2004-02-07 16:50:36 +03:00
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2005-04-14 04:06:01 +04:00
|
|
|
UtilityBitmap::UtilityBitmap(const ServerBitmap* bmp)
|
|
|
|
: ServerBitmap(bmp)
|
2004-02-07 16:50:36 +03:00
|
|
|
{
|
|
|
|
_AllocateBuffer();
|
2005-04-14 04:06:01 +04:00
|
|
|
if (bmp->Bits())
|
|
|
|
memcpy(Bits(), bmp->Bits(), bmp->BitsLength());
|
2004-02-07 16:50:36 +03:00
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2005-04-14 04:06:01 +04:00
|
|
|
UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData,
|
|
|
|
uint32 width, uint32 height,
|
|
|
|
color_space format)
|
|
|
|
: ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0)
|
2004-02-07 16:50:36 +03:00
|
|
|
{
|
|
|
|
_AllocateBuffer();
|
2005-04-14 04:06:01 +04:00
|
|
|
if (Bits())
|
|
|
|
memcpy(Bits(), alreadyPaddedData, BitsLength());
|
2004-02-07 16:50:36 +03:00
|
|
|
}
|
|
|
|
|
2005-12-29 18:36:18 +03:00
|
|
|
|
2005-04-14 04:06:01 +04:00
|
|
|
UtilityBitmap::~UtilityBitmap()
|
2004-02-07 16:50:36 +03:00
|
|
|
{
|
|
|
|
_FreeBuffer();
|
|
|
|
}
|