xref: /haiku/src/servers/app/ServerBitmap.cpp (revision cbe35e2031cb2bfb757422f35006bb9bd382bed1)
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