1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2005, Haiku, Inc. 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: ServerBitmap.cpp 23 // Author: DarkWyrm <bpmagic@columbus.rr.com> 24 // Description: Bitmap class used by the server 25 // 26 //------------------------------------------------------------------------------ 27 #include <new> 28 29 #include <string.h> 30 31 #include "ServerBitmap.h" 32 33 using std::nothrow; 34 35 /*! 36 \brief Constructor called by the BitmapManager (only). 37 \param rect Size of the bitmap. 38 \param space Color space of the bitmap 39 \param flags Various bitmap flags to tweak the bitmap as defined in Bitmap.h 40 \param bytesperline Number of bytes in each row. -1 implies the default value. Any 41 value less than the the default will less than the default will be overridden, but any value 42 greater than the default will result in the number of bytes specified. 43 \param screen Screen assigned to the bitmap. 44 */ 45 ServerBitmap::ServerBitmap(BRect rect, color_space space, 46 int32 flags, int32 bytesPerLine, 47 screen_id screen) 48 : fInitialized(false), 49 fArea(B_ERROR), 50 fBuffer(NULL), 51 // WARNING: '1' is added to the width and height. 52 // Same is done in FBBitmap subclass, so if you 53 // modify here make sure to do the same under 54 // FBBitmap::SetSize(...) 55 fWidth(rect.IntegerWidth() + 1), 56 fHeight(rect.IntegerHeight() + 1), 57 fBytesPerRow(0), 58 fSpace(space), 59 fFlags(flags), 60 fBitsPerPixel(0) 61 // TODO: what about fToken and fOffset ?!? 62 63 { 64 _HandleSpace(space, bytesPerLine); 65 } 66 67 //! Copy constructor does not copy the buffer. 68 ServerBitmap::ServerBitmap(const ServerBitmap* bmp) 69 : fInitialized(false), 70 fArea(B_ERROR), 71 fBuffer(NULL) 72 // TODO: what about fToken and fOffset ?!? 73 { 74 if (bmp) { 75 fInitialized = bmp->fInitialized; 76 fWidth = bmp->fWidth; 77 fHeight = bmp->fHeight; 78 fBytesPerRow = bmp->fBytesPerRow; 79 fSpace = bmp->fSpace; 80 fFlags = bmp->fFlags; 81 fBitsPerPixel = bmp->fBitsPerPixel; 82 } else { 83 fWidth = 0; 84 fHeight = 0; 85 fBytesPerRow = 0; 86 fSpace = B_NO_COLOR_SPACE; 87 fFlags = 0; 88 fBitsPerPixel = 0; 89 } 90 } 91 92 /*! 93 \brief Empty. Defined for subclasses. 94 */ 95 ServerBitmap::~ServerBitmap() 96 { 97 // TODO: Maybe it would be wiser to free the buffer here, 98 // instead of do that in every subclass ? 99 } 100 101 /*! 102 \brief Internal function used by subclasses 103 104 Subclasses should call this so the buffer can automagically 105 be allocated on the heap. 106 */ 107 void 108 ServerBitmap::_AllocateBuffer(void) 109 { 110 uint32 length = BitsLength(); 111 if (length > 0) { 112 delete[] fBuffer; 113 fBuffer = new(nothrow) uint8[length]; 114 fInitialized = fBuffer != NULL; 115 } 116 } 117 118 /*! 119 \brief Internal function used by subclasses 120 121 Subclasses should call this to free the internal buffer. 122 */ 123 void 124 ServerBitmap::_FreeBuffer(void) 125 { 126 delete[] fBuffer; 127 fBuffer = NULL; 128 fInitialized = false; 129 } 130 131 /*! 132 \brief Internal function used to translate color space values to appropriate internal 133 values. 134 \param space Color space for the bitmap. 135 \param bytesPerRow Number of bytes per row to be used as an override. 136 */ 137 void 138 ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow) 139 { 140 // calculate the minimum bytes per row 141 // set fBitsPerPixel 142 int32 minBPR = 0; 143 switch(space) { 144 // 32-bit 145 case B_RGB32: 146 case B_RGBA32: 147 case B_RGB32_BIG: 148 case B_RGBA32_BIG: 149 case B_UVL32: 150 case B_UVLA32: 151 case B_LAB32: 152 case B_LABA32: 153 case B_HSI32: 154 case B_HSIA32: 155 case B_HSV32: 156 case B_HSVA32: 157 case B_HLS32: 158 case B_HLSA32: 159 case B_CMY32: 160 case B_CMYA32: 161 case B_CMYK32: 162 minBPR = fWidth * 4; 163 fBitsPerPixel = 32; 164 break; 165 166 // 24-bit 167 case B_RGB24_BIG: 168 case B_RGB24: 169 case B_LAB24: 170 case B_UVL24: 171 case B_HSI24: 172 case B_HSV24: 173 case B_HLS24: 174 case B_CMY24: 175 // TODO: These last two are calculated 176 // (width + 3) / 4 * 12 177 // in Bitmap.cpp, I don't understand why though. 178 case B_YCbCr444: 179 case B_YUV444: 180 minBPR = fWidth * 3; 181 fBitsPerPixel = 24; 182 break; 183 184 // 16-bit 185 case B_YUV9: 186 case B_YUV12: 187 case B_RGB15: 188 case B_RGBA15: 189 case B_RGB16: 190 case B_RGB16_BIG: 191 case B_RGB15_BIG: 192 case B_RGBA15_BIG: 193 minBPR = fWidth * 2; 194 fBitsPerPixel = 16; 195 break; 196 197 case B_YCbCr422: 198 case B_YUV422: 199 minBPR = (fWidth + 3) / 4 * 8; 200 fBitsPerPixel = 16; 201 break; 202 203 // 8-bit 204 case B_CMAP8: 205 case B_GRAY8: 206 minBPR = fWidth; 207 fBitsPerPixel = 8; 208 break; 209 210 // 1-bit 211 case B_GRAY1: 212 minBPR = (fWidth + 7) / 8; 213 fBitsPerPixel = 1; 214 break; 215 216 // TODO: ??? get a clue what these mean 217 case B_YCbCr411: 218 case B_YUV411: 219 case B_YUV420: 220 case B_YCbCr420: 221 minBPR = (fWidth + 3) / 4 * 6; 222 fBitsPerPixel = 0; 223 break; 224 225 case B_NO_COLOR_SPACE: 226 default: 227 fBitsPerPixel = 0; 228 break; 229 } 230 if (minBPR > 0 || bytesPerRow > 0) { 231 // add the padding or use the provided bytesPerRow if sufficient 232 if (bytesPerRow >= minBPR) { 233 fBytesPerRow = bytesPerRow; 234 } else { 235 fBytesPerRow = ((minBPR + 3) / 4) * 4; 236 } 237 } 238 } 239 240 UtilityBitmap::UtilityBitmap(BRect rect, color_space space, 241 int32 flags, int32 bytesperline, 242 screen_id screen) 243 : ServerBitmap(rect, space, flags, bytesperline, screen) 244 { 245 _AllocateBuffer(); 246 } 247 248 UtilityBitmap::UtilityBitmap(const ServerBitmap* bmp) 249 : ServerBitmap(bmp) 250 { 251 _AllocateBuffer(); 252 if (bmp->Bits()) 253 memcpy(Bits(), bmp->Bits(), bmp->BitsLength()); 254 } 255 256 UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, 257 uint32 width, uint32 height, 258 color_space format) 259 : ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0) 260 { 261 _AllocateBuffer(); 262 if (Bits()) 263 memcpy(Bits(), alreadyPaddedData, BitsLength()); 264 } 265 266 UtilityBitmap::~UtilityBitmap() 267 { 268 _FreeBuffer(); 269 } 270