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