From bdc6f9e7ef0a4ef9c8f729c2979af0c0207fd007 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sun, 5 Mar 2006 23:53:33 +0000 Subject: [PATCH] * Fixed a swapping bug for 16 bit colorspaces * Added some comments * Added some checking to avoid noop shifts * Added buffer length checks * Implemented (as Stephan suggested) a version of ConvertBits() that takes offsets. This new version allows to move a region of the source into a region (possibly not at the same point) on the dest while converting colorspaces on the fly. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16592 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/interface/ColorConversion.h | 11 +- src/kits/interface/Bitmap.cpp | 5 +- src/kits/interface/ColorConversion.cpp | 374 +++++++++++++------- src/servers/app/ServerBitmap.cpp | 4 +- 4 files changed, 258 insertions(+), 136 deletions(-) diff --git a/headers/private/interface/ColorConversion.h b/headers/private/interface/ColorConversion.h index 7e2160be3b..e3fcd6eefd 100644 --- a/headers/private/interface/ColorConversion.h +++ b/headers/private/interface/ColorConversion.h @@ -5,9 +5,14 @@ namespace BPrivate { -status_t ConvertBits(const void *srcBuffer, void *dstBuffer, - uint32 srcBytesPerRow, uint32 dstBytesPerRow, color_space srcColorSpace, - color_space dstColorSpace, int32 width, int32 height); +status_t ConvertBits(const void *srcBits, void *dstBits, int32 srcBitsLength, + int32 dstBitsLength, int32 srcBytesPerRow, int32 dstBytesPerRow, + color_space srcColorSpace, color_space dstColorSpace, int32 width, + int32 height); +status_t ConvertBits(const void *srcBits, void *dstBits, int32 srcBitsLength, + int32 dstBitsLength, int32 srcBytesPerRow, int32 dstBytesPerRow, + color_space srcColorSpace, color_space dstColorSpace, BPoint srcOffset, + BPoint dstOffset, int32 width, int32 height); /*! \brief Helper class for conversion between RGB and palette colors. diff --git a/src/kits/interface/Bitmap.cpp b/src/kits/interface/Bitmap.cpp index da81661166..37ef745037 100644 --- a/src/kits/interface/Bitmap.cpp +++ b/src/kits/interface/Bitmap.cpp @@ -519,8 +519,9 @@ BBitmap::ImportBits(const void *data, int32 length, int32 bpr, int32 offset, if (bpr < 0) bpr = get_bytes_per_row(colorSpace, width); - return BPrivate::ConvertBits(data, fBasePtr, bpr, fBytesPerRow, - colorSpace, fColorSpace, width, fBounds.IntegerHeight() + 1); + return BPrivate::ConvertBits(data, fBasePtr, length, fSize, bpr, + fBytesPerRow, colorSpace, fColorSpace, width, + fBounds.IntegerHeight() + 1); } // ImportBits diff --git a/src/kits/interface/ColorConversion.cpp b/src/kits/interface/ColorConversion.cpp index a8e276743b..b0d416edeb 100644 --- a/src/kits/interface/ColorConversion.cpp +++ b/src/kits/interface/ColorConversion.cpp @@ -14,6 +14,7 @@ #include "ColorConversion.h" #include #include +#include namespace BPrivate { @@ -621,51 +622,106 @@ ReadCMAP8(const uint8 **source, int32 index) template -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) +status_t +ConvertBits(const srcByte *srcBits, dstByte *dstBits, int32 srcBitsLength, + int32 dstBitsLength, 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, + color_space srcColorSpace, color_space dstColorSpace, BPoint srcOffset, + BPoint dstOffset, 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; + char *srcBitsEnd = (char *)srcBits + srcBitsLength; + char *dstBitsEnd = (char *)dstBits + dstBitsLength; + + int32 srcBitsPerRow = srcBytesPerRow << 3; + int32 dstBitsPerRow = dstBytesPerRow << 3; + + // Advance the buffers to reach their offsets + int32 srcOffsetX = (int32)srcOffset.x; + int32 dstOffsetX = (int32)dstOffset.x; + (char *)srcBits += ((int32)srcOffset.y * srcBitsPerRow + srcOffsetX + * srcBitsPerPixel) >> 3; + (char *)dstBits += ((int32)dstOffset.y * dstBitsPerRow + dstOffsetX + * dstBitsPerPixel) >> 3; + + // Ensure that the width fits + int32 srcWidth = (srcBitsPerRow - srcOffsetX * srcBitsPerPixel) + / srcBitsPerPixel; + if (srcWidth < width) + width = srcWidth; + + int32 dstWidth = (dstBitsPerRow - dstOffsetX * dstBitsPerPixel) + / dstBitsPerPixel; + if (dstWidth < width) + width = dstWidth; + + if (width < 0) + return B_OK; + + // Catch the copy case + if (srcColorSpace == dstColorSpace && srcBitsPerPixel % 8 == 0) { + int32 copyCount = (width * srcBitsPerPixel) >> 3; + for (int32 i = 0; i < height; i++) { + memcpy(dstBits, srcBits, copyCount); + + (char *)srcBits += srcBytesPerRow; + (char *)dstBits += dstBytesPerRow; + + if ((char *)srcBits > srcBitsEnd || (char *)dstBits > dstBitsEnd) + return B_OK; + } + + return B_OK; + } + + int32 srcLinePad = (srcBitsPerRow - width * srcBitsPerPixel) >> 3; + int32 dstLinePad = (dstBitsPerRow - 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); + source = srcFunc((const uint8 **)&srcBits, srcOffsetX++); else { - source = *srcBuffer; - srcBuffer++; + source = *srcBits; + srcBits++; } + // This is valid, as only 16 bit modes will need to swap if (srcSwap) source = (source << 8) | (source >> 8); if (redShift > 0) result = ((source >> redShift) & redMask); - else + else if (redShift < 0) result = ((source << -redShift) & redMask); + else + result = source & redMask; if (greenShift > 0) result |= ((source >> greenShift) & greenMask); - else + else if (greenShift < 0) result |= ((source << -greenShift) & greenMask); + else + result |= source & greenMask; if (blueShift > 0) result |= ((source >> blueShift) & blueMask); - else + else if (blueShift < 0) result |= ((source << -blueShift) & blueMask); + else + result |= source & blueMask; if (alphaBits > 0) { if (alphaShift > 0) result |= ((source >> alphaShift) & alphaMask); - else + else if (alphaShift < 0) result |= ((source << -alphaShift) & alphaMask); + else + result |= source & alphaMask; // if we only had one alpha bit we want it to be 0/255 if (alphaBits == 1 && result & alphaMask) @@ -673,132 +729,154 @@ ConvertBits(const srcByte *srcBuffer, dstByte *dstBuffer, int32 redShift, } else result |= alphaMask; + // This is valid, as only 16 bit modes will need to swap if (dstSwap) - *dstBuffer = (result << 8) | (result >> 8); + result = (result << 8) | (result >> 8); if (dstFunc) - dstFunc((uint8 **)&dstBuffer, (uint8 *)&result, j); + dstFunc((uint8 **)&dstBits, (uint8 *)&result, dstOffsetX++); else { - *dstBuffer = result; - dstBuffer++; + *dstBits = result; + dstBits++; } + + if ((char *)srcBits > srcBitsEnd || (char *)dstBits > dstBitsEnd) + return B_OK; } - (char *)srcBuffer += srcLinePad; - (char *)dstBuffer += dstLinePad; + (char *)srcBits += srcLinePad; + (char *)dstBits += dstLinePad; + dstOffsetX -= width; + srcOffsetX -= width; } + + return B_OK; } template 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) +ConvertBits(const srcByte *srcBits, void *dstBits, int32 srcBitsLength, + int32 dstBitsLength, int32 redShift, int32 greenShift, int32 blueShift, + int32 alphaShift, int32 alphaBits, int32 srcBytesPerRow, + int32 dstBytesPerRow, int32 srcBitsPerPixel, color_space srcColorSpace, + color_space dstColorSpace, BPoint srcOffset, BPoint dstOffset, 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); + ConvertBits(srcBits, (uint32 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 24, greenShift - 16, blueShift - 8, + alphaShift - 32, alphaBits, 0x00ff0000, 0x0000ff00, 0x000000ff, + 0xff000000, srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, + 32, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint32 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 16, greenShift - 24, blueShift - 32, + alphaShift - 8, alphaBits, 0x0000ff00, 0x00ff0000, 0xff000000, + 0x00000ff, srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 32, + srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint32 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 24, greenShift - 16, blueShift - 8, + 0, 0, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000, + srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 32, + srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint32 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 16, greenShift - 24, blueShift - 32, + 0, 0, 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff, + srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 32, + srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint8 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 24, greenShift - 16, blueShift - 8, + 0, 0, 0xff0000, 0x00ff00, 0x0000ff, 0x000000, srcBytesPerRow, + dstBytesPerRow, srcBitsPerPixel, 24, srcColorSpace, + dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint8 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 8, greenShift - 16, blueShift - 24, + 0, 0, 0x0000ff, 0x00ff00, 0xff0000, 0x000000, srcBytesPerRow, + dstBytesPerRow, srcBitsPerPixel, 24, srcColorSpace, + dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint16 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 16, greenShift - 11, blueShift - 5, + 0, 0, 0xf800, 0x07e0, 0x001f, 0x0000, srcBytesPerRow, + dstBytesPerRow, srcBitsPerPixel, 16, srcColorSpace, + dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint16 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 15, greenShift - 10, blueShift - 5, + alphaShift - 16, alphaBits, 0x7c00, 0x03e0, 0x001f, 0x8000, + srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 16, + srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint16 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 15, greenShift - 10, blueShift - 5, + 0, 0, 0x7c00, 0x03e0, 0x001f, 0x0000, srcBytesPerRow, + dstBytesPerRow, srcBitsPerPixel, 16, srcColorSpace, + dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint8 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 24, greenShift - 16, blueShift - 8, + 0, 0, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, + srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 8, + srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint8 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 24, greenShift - 16, blueShift - 8, + 0, 0, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000, + srcBytesPerRow, dstBytesPerRow, srcBitsPerPixel, 1, + srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + ConvertBits(srcBits, (uint8 *)dstBits, srcBitsLength, + dstBitsLength, redShift - 15, greenShift - 10, blueShift - 5, + 0, 0, 0x7c00, 0x03e0, 0x001f, 0x0000, srcBytesPerRow, + dstBytesPerRow, srcBitsPerPixel, 8, srcColorSpace, + dstColorSpace, srcOffset, dstOffset, width, height, srcSwap, + false, srcFunc, WriteCMAP8); break; default: @@ -813,8 +891,8 @@ ConvertBits(const srcByte *srcBuffer, void *dstBuffer, int32 redShift, /*! \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 srcBits The raw source buffer. + \param dstBits 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. @@ -826,93 +904,131 @@ ConvertBits(const srcByte *srcBuffer, void *dstBuffer, int32 redShift, - \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) +ConvertBits(const void *srcBits, void *dstBits, int32 srcBitsLength, + int32 dstBitsLength, int32 srcBytesPerRow, int32 dstBytesPerRow, + color_space srcColorSpace, color_space dstColorSpace, int32 width, + int32 height) { - if (!srcBuffer || !dstBuffer) - return B_BAD_VALUE; + return ConvertBits(srcBits, dstBits, srcBitsLength, dstBitsLength, + srcBytesPerRow, dstBytesPerRow, srcColorSpace, dstColorSpace, + BPoint(0, 0), BPoint(0, 0), width, height); +} - if (srcColorSpace == dstColorSpace && srcBytesPerRow == dstBytesPerRow) { - memcpy(dstBuffer, srcBuffer, height * srcBytesPerRow); - return B_OK; - } + +/*! \brief Converts a source buffer in one colorspace into a destination + buffer of another colorspace. + + \param srcBits The raw source buffer. + \param dstBits 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 srcOffset The offset at which to start reading in the source. + \param srcOffset The offset at which to start writing in the destination. + \param width The width (in pixels) to convert. + \param height The height (in pixels) to convert. + \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 *srcBits, void *dstBits, int32 srcBitsLength, + int32 dstBitsLength, int32 srcBytesPerRow, int32 dstBytesPerRow, + color_space srcColorSpace, color_space dstColorSpace, BPoint srcOffset, + BPoint dstOffset, int32 width, int32 height) +{ + if (!srcBits || !dstBits || srcBitsLength < 0 || dstBitsLength < 0 + || width < 0 || height < 0 || srcBytesPerRow < 0 || dstBytesPerRow < 0) + return B_BAD_VALUE; switch (srcColorSpace) { case B_RGBA32: - return ConvertBits((const uint32 *)srcBuffer, dstBuffer, 24, 16, - 8, 32, 8, srcBytesPerRow, dstBytesPerRow, 32, dstColorSpace, - width, height, false, NULL); + return ConvertBits((const uint32 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 24, 16, 8, 32, 8, srcBytesPerRow, + dstBytesPerRow, 32, srcColorSpace, dstColorSpace, srcOffset, + dstOffset, 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); + return ConvertBits((const uint32 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 16, 24, 32, 8, 8, srcBytesPerRow, + dstBytesPerRow, 32, srcColorSpace, dstColorSpace, srcOffset, + dstOffset, 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); + return ConvertBits((const uint32 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 24, 16, 8, 0, 0, srcBytesPerRow, dstBytesPerRow, + 32, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + return ConvertBits((const uint32 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 16, 24, 32, 0, 0, srcBytesPerRow, + dstBytesPerRow, 32, srcColorSpace, dstColorSpace, srcOffset, + dstOffset, 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); + return ConvertBits((const uint8 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 24, 16, 8, 0, 0, srcBytesPerRow, dstBytesPerRow, + 24, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + return ConvertBits((const uint8 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 8, 16, 24, 0, 0, srcBytesPerRow, dstBytesPerRow, + 24, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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, + return ConvertBits((const uint16 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 16, 11, 5, 0, 0, srcBytesPerRow, dstBytesPerRow, + 16, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + return ConvertBits((const uint16 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 15, 10, 5, 16, 1, srcBytesPerRow, + dstBytesPerRow, 16, srcColorSpace, dstColorSpace, srcOffset, + dstOffset, 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, + return ConvertBits((const uint16 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 15, 10, 5, 0, 0, srcBytesPerRow, dstBytesPerRow, + 16, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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, + return ConvertBits((const uint8 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 8, 8, 8, 0, 0, srcBytesPerRow, dstBytesPerRow, + 8, srcColorSpace, dstColorSpace, srcOffset, dstOffset, width, height, false, ReadGray8); break; case B_GRAY1: - return ConvertBits((const uint8 *)srcBuffer, dstBuffer, 8, 8, 8, 0, - 0, srcBytesPerRow, dstBytesPerRow, 1, dstColorSpace, width, + return ConvertBits((const uint8 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 8, 8, 8, 0, 0, srcBytesPerRow, dstBytesPerRow, + 1, srcColorSpace, dstColorSpace, srcOffset, dstOffset, 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); + return ConvertBits((const uint8 *)srcBits, dstBits, srcBitsLength, + dstBitsLength, 24, 16, 8, 32, 8, srcBytesPerRow, + dstBytesPerRow, 8, srcColorSpace, dstColorSpace, srcOffset, + dstOffset, width, height, false, ReadCMAP8); break; default: diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index c73fe34334..e0c22bf08e 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -253,8 +253,8 @@ ServerBitmap::ImportBits(const void *bits, int32 bitsLength, int32 bytesPerRow, if (!bits || bitsLength < 0 || bytesPerRow <= 0) return B_BAD_VALUE; - return BPrivate::ConvertBits(bits, fBuffer, bytesPerRow, fBytesPerRow, - colorSpace, fSpace, fWidth, fHeight); + return BPrivate::ConvertBits(bits, fBuffer, bitsLength, BitsLength(), + bytesPerRow, fBytesPerRow, colorSpace, fSpace, fWidth, fHeight); }