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 "ServerBitmap.h" 30 31 /*! 32 \brief Constructor called by the BitmapManager (only). 33 \param rect Size of the bitmap. 34 \param space Color space of the bitmap 35 \param flags Various bitmap flags to tweak the bitmap as defined in Bitmap.h 36 \param bytesperline Number of bytes in each row. -1 implies the default value. Any 37 value less than the the default will less than the default will be overridden, but any value 38 greater than the default will result in the number of bytes specified. 39 \param screen Screen assigned to the bitmap. 40 */ 41 ServerBitmap::ServerBitmap(BRect rect, color_space space, 42 int32 flags, int32 bytesPerLine, 43 screen_id screen) 44 : fInitialized(false), 45 fArea(B_ERROR), 46 fBuffer(NULL), 47 // WARNING: '1' is added to the width and height. 48 // Same is done in FBBitmap subclass, so if you 49 // modify here make sure to do the same under 50 // FBBitmap::SetSize(...) 51 fWidth(rect.IntegerWidth() + 1), 52 fHeight(rect.IntegerHeight() + 1), 53 fBytesPerRow(0), 54 fSpace(space), 55 fFlags(flags), 56 fBitsPerPixel(0) 57 // TODO: what about fToken and fOffset ?!? 58 59 { 60 _HandleSpace(space, bytesPerLine); 61 } 62 63 //! Copy constructor does not copy the buffer. 64 ServerBitmap::ServerBitmap(const ServerBitmap* bmp) 65 : fInitialized(false), 66 fArea(B_ERROR), 67 fBuffer(NULL) 68 // TODO: what about fToken and fOffset ?!? 69 { 70 if (bmp) { 71 fInitialized = bmp->fInitialized; 72 fWidth = bmp->fWidth; 73 fHeight = bmp->fHeight; 74 fBytesPerRow = bmp->fBytesPerRow; 75 fSpace = bmp->fSpace; 76 fFlags = bmp->fFlags; 77 fBitsPerPixel = bmp->fBitsPerPixel; 78 } else { 79 fWidth = 0; 80 fHeight = 0; 81 fBytesPerRow = 0; 82 fSpace = B_NO_COLOR_SPACE; 83 fFlags = 0; 84 fBitsPerPixel = 0; 85 } 86 } 87 88 /*! 89 \brief Empty. Defined for subclasses. 90 */ 91 ServerBitmap::~ServerBitmap() 92 { 93 // TODO: Maybe it would be wiser to free the buffer here, 94 // instead of do that in every subclass ? 95 } 96 97 /*! 98 \brief Internal function used by subclasses 99 100 Subclasses should call this so the buffer can automagically 101 be allocated on the heap. 102 */ 103 void 104 ServerBitmap::_AllocateBuffer(void) 105 { 106 uint32 length = BitsLength(); 107 if (length > 0) { 108 delete[] fBuffer; 109 fBuffer = new(nothrow) uint8[length]; 110 fInitialized = fBuffer != NULL; 111 } 112 } 113 114 /*! 115 \brief Internal function used by subclasses 116 117 Subclasses should call this to free the internal buffer. 118 */ 119 void 120 ServerBitmap::_FreeBuffer(void) 121 { 122 delete[] fBuffer; 123 fBuffer = NULL; 124 fInitialized = false; 125 } 126 127 /*! 128 \brief Internal function used to translate color space values to appropriate internal 129 values. 130 \param space Color space for the bitmap. 131 \param bytesPerRow Number of bytes per row to be used as an override. 132 */ 133 void 134 ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow) 135 { 136 // calculate the minimum bytes per row 137 // set fBitsPerPixel 138 int32 minBPR = 0; 139 switch(space) { 140 // 32-bit 141 case B_RGB32: 142 case B_RGBA32: 143 case B_RGB32_BIG: 144 case B_RGBA32_BIG: 145 case B_UVL32: 146 case B_UVLA32: 147 case B_LAB32: 148 case B_LABA32: 149 case B_HSI32: 150 case B_HSIA32: 151 case B_HSV32: 152 case B_HSVA32: 153 case B_HLS32: 154 case B_HLSA32: 155 case B_CMY32: 156 case B_CMYA32: 157 case B_CMYK32: 158 minBPR = fWidth * 4; 159 fBitsPerPixel = 32; 160 break; 161 162 // 24-bit 163 case B_RGB24_BIG: 164 case B_RGB24: 165 case B_LAB24: 166 case B_UVL24: 167 case B_HSI24: 168 case B_HSV24: 169 case B_HLS24: 170 case B_CMY24: 171 // TODO: These last two are calculated 172 // (width + 3) / 4 * 12 173 // in Bitmap.cpp, I don't understand why though. 174 case B_YCbCr444: 175 case B_YUV444: 176 minBPR = fWidth * 3; 177 fBitsPerPixel = 24; 178 break; 179 180 // 16-bit 181 case B_YUV9: 182 case B_YUV12: 183 case B_RGB15: 184 case B_RGBA15: 185 case B_RGB16: 186 case B_RGB16_BIG: 187 case B_RGB15_BIG: 188 case B_RGBA15_BIG: 189 minBPR = fWidth * 2; 190 fBitsPerPixel = 16; 191 break; 192 193 case B_YCbCr422: 194 case B_YUV422: 195 minBPR = (fWidth + 3) / 4 * 8; 196 fBitsPerPixel = 16; 197 break; 198 199 // 8-bit 200 case B_CMAP8: 201 case B_GRAY8: 202 minBPR = fWidth; 203 fBitsPerPixel = 8; 204 break; 205 206 // 1-bit 207 case B_GRAY1: 208 minBPR = (fWidth + 7) / 8; 209 fBitsPerPixel = 1; 210 break; 211 212 // TODO: ??? get a clue what these mean 213 case B_YCbCr411: 214 case B_YUV411: 215 case B_YUV420: 216 case B_YCbCr420: 217 minBPR = (fWidth + 3) / 4 * 6; 218 fBitsPerPixel = 0; 219 break; 220 221 case B_NO_COLOR_SPACE: 222 default: 223 fBitsPerPixel = 0; 224 break; 225 } 226 if (minBPR > 0 || bytesPerRow > 0) { 227 // add the padding or use the provided bytesPerRow if sufficient 228 if (bytesPerRow >= minBPR) { 229 fBytesPerRow = bytesPerRow; 230 } else { 231 fBytesPerRow = ((minBPR + 3) / 4) * 4; 232 } 233 } 234 } 235 236 UtilityBitmap::UtilityBitmap(BRect rect, color_space space, 237 int32 flags, int32 bytesperline, 238 screen_id screen) 239 : ServerBitmap(rect, space, flags, bytesperline, screen) 240 { 241 _AllocateBuffer(); 242 } 243 244 UtilityBitmap::UtilityBitmap(const ServerBitmap* bmp) 245 : ServerBitmap(bmp) 246 { 247 _AllocateBuffer(); 248 if (bmp->Bits()) 249 memcpy(Bits(), bmp->Bits(), bmp->BitsLength()); 250 } 251 252 UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, 253 uint32 width, uint32 height, 254 color_space format) 255 : ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0) 256 { 257 _AllocateBuffer(); 258 if (Bits()) 259 memcpy(Bits(), alreadyPaddedData, BitsLength()); 260 } 261 262 UtilityBitmap::~UtilityBitmap() 263 { 264 _FreeBuffer(); 265 } 266