]> git.sesse.net Git - vlc/blob - plugins/beos/DrawingTidbits.cpp
898950cd9cf5a3a33c5d6ee7f68809f944426602
[vlc] / plugins / beos / DrawingTidbits.cpp
1 /*****************************************************************************
2  * DrawingTidbits.cpp
3  *****************************************************************************
4  * Copyright (C) 2001 VideoLAN
5  * $Id: DrawingTidbits.cpp,v 1.2.4.1 2002/09/03 12:00:24 tcastley Exp $
6  *
7  * Authors: Tony Castley <tcastley@mail.powerup.com.au>
8  *          Stephan Aßmus <stippi@yellowbites.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 #include <Bitmap.h>
26 #include <Debug.h>
27 #include <Screen.h>
28
29 #include "DrawingTidbits.h"
30
31 // ShiftComponent
32 inline uchar
33 ShiftComponent(uchar component, float percent)
34 {
35         // change the color by <percent>, make sure we aren't rounding
36         // off significant bits
37         if (percent >= 1)
38                 return (uchar)(component * (2 - percent));
39         else
40                 return (uchar)(255 - percent * (255 - component));
41 }
42
43 // ShiftColor
44 rgb_color
45 ShiftColor(rgb_color color, float percent)
46 {
47         rgb_color result = {
48                 ShiftComponent(color.red, percent),
49                 ShiftComponent(color.green, percent),
50                 ShiftComponent(color.blue, percent),
51                 0
52         };
53         
54         return result;
55 }
56
57 // CompareColors
58 static bool
59 CompareColors(const rgb_color a, const rgb_color b)
60 {
61         return a.red == b.red
62                 && a.green == b.green
63                 && a.blue == b.blue
64                 && a.alpha == b.alpha;
65 }
66
67 // ==
68 bool
69 operator==(const rgb_color &a, const rgb_color &b)
70 {
71         return CompareColors(a, b);
72 }
73
74 // !=
75 bool
76 operator!=(const rgb_color &a, const rgb_color &b)
77 {
78         return !CompareColors(a, b);
79 }
80
81 // ReplaceColor
82 void
83 ReplaceColor(BBitmap *bitmap, rgb_color from, rgb_color to)
84 {
85         ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
86         
87         BScreen screen(B_MAIN_SCREEN_ID);
88         uint32 fromIndex = screen.IndexForColor(from);
89         uint32 toIndex = screen.IndexForColor(to); 
90         
91         uchar *bits = (uchar *)bitmap->Bits();
92         int32 bitsLength = bitmap->BitsLength();        
93         for (int32 index = 0; index < bitsLength; index++) 
94                 if (bits[index] == fromIndex)
95                         bits[index] = toIndex;
96 }
97
98 // ReplaceTransparentColor
99 void 
100 ReplaceTransparentColor(BBitmap *bitmap, rgb_color with)
101 {
102         ASSERT(bitmap->ColorSpace() == B_COLOR_8_BIT); // other color spaces not implemented yet
103         
104         BScreen screen(B_MAIN_SCREEN_ID);
105         uint32 withIndex = screen.IndexForColor(with); 
106         
107         uchar *bits = (uchar *)bitmap->Bits();
108         int32 bitsLength = bitmap->BitsLength();        
109         for (int32 index = 0; index < bitsLength; index++) 
110                 if (bits[index] == B_TRANSPARENT_8_BIT)
111                         bits[index] = withIndex;
112 }
113
114
115 // convert_bitmap
116 status_t
117 convert_bitmap(BBitmap* inBitmap, BBitmap* outBitmap)
118 {
119         status_t status = B_BAD_VALUE;
120 /*      // see that we got valid bitmaps
121         if (inBitmap && inBitmap->IsValid()
122                 && outBitmap && outBitmap->IsValid())
123         {
124                 status = B_MISMATCHED_VALUES;
125                 // see that bitmaps are compatible and that we support the conversion
126                 if (inBitmap->Bounds().Width() == outBitmap->Bounds().Width()
127                         && inBitmap->Bounds().Height() == outBitmap->Bounds().Height()
128                         && (outBitmap->ColorSpace() == B_RGB32
129                                 || outBitmap->ColorSpace() == B_RGBA32))
130                 {
131                         int32 width = inBitmap->Bounds().IntegerWidth() + 1;
132                         int32 height = inBitmap->Bounds().IntegerHeight() + 1;
133                         int32 srcBpr = inBitmap->BytesPerRow();
134                         int32 dstBpr = outBitmap->BytesPerRow();
135                         uint8* srcbits = (uint8*)inbitmap->bits();
136                         uint8* dstbits = (uint8*)outbitmap->bits();
137                         switch (inBitmap->ColorSpace())
138                         {
139                                 case B_YCbCr422:
140                                         for (int32 y = 0; y < height; y ++)
141                                         {
142                                                 for (int32 x = 0; x < width; x += 2)
143                                                 {
144                                                         uint8 y = 
145                                                         uint8 cb = 
146                                                         uint8 cr = 
147                                                 }
148                                                 srcbits += srcBpr;
149                                                 dstbits += dstBpr;
150                                         }
151                                         status = B_OK;
152                                         break;
153                                 case B_YCbCr420:
154                                         status = B_OK;
155                                         break;
156                                 case B_YUV422:
157                                         status = B_OK;
158                                         break;
159                                 case B_RGB32:
160                                         memcpy(dstBits, srcBits, inBitmap->BitsLength());
161                                         status = B_OK;
162                                         break;
163                                 default:
164                                         status = B_MISMATCHED_VALUES;
165                                         break;
166                         }
167                 }
168         }*/
169         return status;
170 }
171
172 // clip_float
173 inline uint8
174 clip_float(float value)
175 {
176         if (value < 0)
177                 value = 0;
178         if (value > 255)
179                 value = 255;
180         return (uint8)value;
181 }
182
183 // dim_bitmap
184 status_t
185 dim_bitmap(BBitmap* bitmap, rgb_color center, float dimLevel)
186 {
187         status_t status = B_BAD_VALUE;
188         if (bitmap && bitmap->IsValid())
189         {
190                 switch (bitmap->ColorSpace())
191                 {
192                         case B_CMAP8:
193                         {
194                                 BScreen screen(B_MAIN_SCREEN_ID);
195                                 if (screen.IsValid())
196                                 {
197                                         // iterate over each pixel, get the respective
198                                         // color from the screen object, find the distance
199                                         // to the "center" color and shorten the distance
200                                         // by "dimLevel"
201                                         int32 length = bitmap->BitsLength();
202                                         uint8* bits = (uint8*)bitmap->Bits();
203                                         for (int32 i = 0; i < length; i++)
204                                         {
205                                                 // preserve transparent pixels
206                                                 if (bits[i] != B_TRANSPARENT_MAGIC_CMAP8)
207                                                 {
208                                                         // get color for this index
209                                                         rgb_color c = screen.ColorForIndex(bits[i]);
210                                                         // red
211                                                         float dist = (c.red - center.red) * dimLevel;
212                                                         c.red = clip_float(center.red + dist);
213                                                         // green
214                                                         dist = (c.green - center.green) * dimLevel;
215                                                         c.green = clip_float(center.green + dist);
216                                                         // blue
217                                                         dist = (c.blue - center.blue) * dimLevel;
218                                                         c.blue = clip_float(center.blue + dist);
219                                                         // write correct index of the dimmed color
220                                                         // back into bitmap (and hope the match is close...)
221                                                         bits[i] = screen.IndexForColor(c);
222                                                 }
223                                         }
224                                         status = B_OK;
225                                 }
226                                 break;
227                         }
228                         case B_RGB32:
229                         case B_RGBA32:
230                         {
231                                 // iterate over each color component, find the distance
232                                 // to the "center" color and shorten the distance
233                                 // by "dimLevel"
234                                 uint8* bits = (uint8*)bitmap->Bits();
235                                 int32 bpr = bitmap->BytesPerRow();
236                                 int32 pixels = bitmap->Bounds().IntegerWidth() + 1;
237                                 int32 lines = bitmap->Bounds().IntegerHeight() + 1;
238                                 // iterate over color components
239                                 for (int32 y = 0; y < lines; y++) {
240                                         for (int32 x = 0; x < pixels; x++) {
241                                                 int32 offset = 4 * x; // four bytes per pixel
242                                                 // blue
243                                                 float dist = (bits[offset + 0] - center.blue) * dimLevel;
244                                                 bits[offset + 0] = clip_float(center.blue + dist);
245                                                 // green
246                                                 dist = (bits[offset + 1] - center.green) * dimLevel;
247                                                 bits[offset + 1] = clip_float(center.green + dist);
248                                                 // red
249                                                 dist = (bits[offset + 2] - center.red) * dimLevel;
250                                                 bits[offset + 2] = clip_float(center.red + dist);
251                                                 // ignore alpha channel
252                                         }
253                                         // next line
254                                         bits += bpr;
255                                 }
256                                 status = B_OK;
257                                 break;
258                         }
259                         default:
260                                 status = B_ERROR;
261                                 break;
262                 }
263         }
264         return status;
265 }
266
267 // dimmed_color_cmap8
268 rgb_color
269 dimmed_color_cmap8(rgb_color color, rgb_color center, float dimLevel)
270 {
271         BScreen screen(B_MAIN_SCREEN_ID);
272         if (screen.IsValid())
273         {
274                 // red
275                 float dist = (color.red - center.red) * dimLevel;
276                 color.red = clip_float(center.red + dist);
277                 // green
278                 dist = (color.green - center.green) * dimLevel;
279                 color.green = clip_float(center.green + dist);
280                 // blue
281                 dist = (color.blue - center.blue) * dimLevel;
282                 color.blue = clip_float(center.blue + dist);
283                 // get color index for dimmed color
284                 int32 index = screen.IndexForColor(color);
285                 // put color at index (closest match in palette
286                 // to dimmed result) into returned color
287                 color = screen.ColorForIndex(index);
288         }
289         return color;
290 }