xref: /haiku/src/kits/tracker/Bitmaps.cpp (revision 778611c7e6a61b8ba072212756ce53eda826360a)
1 /*
2 Open Tracker License
3 
4 Terms and Conditions
5 
6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved.
7 
8 Permission is hereby granted, free of charge, to any person obtaining a copy of
9 this software and associated documentation files (the "Software"), to deal in
10 the Software without restriction, including without limitation the rights to
11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12 of the Software, and to permit persons to whom the Software is furnished to do
13 so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice applies to all licensees
16 and shall be included in all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION
23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 
25 Except as contained in this notice, the name of Be Incorporated shall not be
26 used in advertising or otherwise to promote the sale, use or other dealings in
27 this Software without prior written authorization from Be Incorporated.
28 
29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered trademarks
30 of Be Incorporated in the United States and other countries. Other brand product
31 names are registered trademarks or trademarks of their respective holders.
32 All rights reserved.
33 */
34 
35 #include "Bitmaps.h"
36 #include "Utilities.h"
37 
38 #include <Autolock.h>
39 #include <Bitmap.h>
40 #include <Debug.h>
41 #include <DataIO.h>
42 #include <File.h>
43 #include <String.h>
44 #include <SupportDefs.h>
45 
46 #ifdef __HAIKU__
47 #	include <IconUtils.h>
48 #endif
49 
50 
51 //	#pragma mark - BImageResources
52 
53 
54 BImageResources::BImageResources(void* memAddr)
55 {
56 	image_id image = find_image(memAddr);
57 	image_info info;
58 	if (get_image_info(image, &info) == B_OK) {
59 #if _SUPPORTS_RESOURCES
60 		BFile file(&info.name[0], B_READ_ONLY);
61 #else
62 		BString name(&info.name[0]);
63 		name += ".rsrc";
64 		BFile file(name.String(), B_READ_ONLY);
65 #endif
66 		if (file.InitCheck() == B_OK)
67 			fResources.SetTo(&file);
68 	}
69 }
70 
71 
72 BImageResources::~BImageResources()
73 {
74 }
75 
76 
77 const BResources*
78 BImageResources::ViewResources() const
79 {
80 	if (fLock.Lock() != B_OK)
81 		return NULL;
82 
83 	return &fResources;
84 }
85 
86 
87 BResources*
88 BImageResources::ViewResources()
89 {
90 	if (fLock.Lock() != B_OK)
91 		return NULL;
92 
93 	return &fResources;
94 }
95 
96 
97 status_t
98 BImageResources::FinishResources(BResources* res) const
99 {
100 	ASSERT(res == &fResources);
101 	if (res != &fResources)
102 		return B_BAD_VALUE;
103 
104 	fLock.Unlock();
105 
106 	return B_OK;
107 }
108 
109 
110 const void*
111 BImageResources::LoadResource(type_code type, int32 id,
112 	size_t* out_size) const
113 {
114 	// Serialize execution.
115 	// Looks like BResources is not really thread safe. We should
116 	// clean that up in the future and remove the locking from here.
117 	BAutolock lock(fLock);
118 	if (!lock.IsLocked())
119 		return 0;
120 
121 	// Return the resource.  Because we never change the BResources
122 	// object, the returned data will not change until TTracker is
123 	// destroyed.
124 	return const_cast<BResources*>(&fResources)->LoadResource(type, id,
125 		out_size);
126 }
127 
128 
129 const void*
130 BImageResources::LoadResource(type_code type, const char* name,
131 	size_t* out_size) const
132 {
133 	// Serialize execution.
134 	BAutolock lock(fLock);
135 	if (!lock.IsLocked())
136 		return NULL;
137 
138 	// Return the resource.  Because we never change the BResources
139 	// object, the returned data will not change until TTracker is
140 	// destroyed.
141 	return const_cast<BResources*>(&fResources)->LoadResource(type, name,
142 		out_size);
143 }
144 
145 
146 status_t
147 BImageResources::GetIconResource(int32 id, icon_size size,
148 	BBitmap* dest) const
149 {
150 	size_t length = 0;
151 	const void* data;
152 
153 #ifdef __HAIKU__
154 	// try to load vector icon
155 	data = LoadResource(B_VECTOR_ICON_TYPE, id, &length);
156 	if (data != NULL
157 		&& BIconUtils::GetVectorIcon((uint8*)data, length, dest) == B_OK) {
158 		return B_OK;
159 	}
160 #endif
161 
162 	// fall back to R5 icon
163 	if (size != B_LARGE_ICON && size != B_MINI_ICON)
164 		return B_ERROR;
165 
166 	length = 0;
167 	data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length);
168 
169 	if (data == NULL
170 		|| length != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) {
171 		TRESPASS();
172 		return B_ERROR;
173 	}
174 
175 #ifdef __HAIKU__
176 	if (dest->ColorSpace() != B_CMAP8) {
177 		return BIconUtils::ConvertFromCMAP8((uint8*)data, size, size,
178 			size, dest);
179 	}
180 #endif
181 
182 	dest->SetBits(data, (int32)length, 0, B_CMAP8);
183 	return B_OK;
184 }
185 
186 
187 status_t
188 BImageResources::GetIconResource(int32 id, const uint8** iconData,
189 	size_t* iconSize) const
190 {
191 #ifdef __HAIKU__
192 	// try to load vector icon data from resources
193 	size_t length = 0;
194 	const void* data = LoadResource(B_VECTOR_ICON_TYPE, id, &length);
195 	if (data == NULL)
196 		return B_ERROR;
197 
198 	*iconData = (const uint8*)data;
199 	*iconSize = length;
200 
201 	return B_OK;
202 #else
203 	return B_ERROR;
204 #endif
205 }
206 
207 
208 image_id
209 BImageResources::find_image(void* memAddr) const
210 {
211 	image_info info;
212 	int32 cookie = 0;
213 	while (get_next_image_info(0, &cookie, &info) == B_OK) {
214 		if ((info.text <= memAddr
215 			&& (((uint8*)info.text)+info.text_size) > memAddr)
216 				|| (info.data <= memAddr
217 				&& (((uint8*)info.data)+info.data_size) > memAddr)) {
218 			// Found the image.
219 			return info.id;
220 		}
221 	}
222 
223 	return -1;
224 }
225 
226 
227 status_t
228 BImageResources::GetBitmapResource(type_code type, int32 id,
229 	BBitmap** out) const
230 {
231 	*out = NULL;
232 
233 	size_t len = 0;
234 	const void* data = LoadResource(type, id, &len);
235 
236 	if (data == NULL) {
237 		TRESPASS();
238 		return B_ERROR;
239 	}
240 
241 	BMemoryIO stream(data, len);
242 
243 	// Try to read as an archived bitmap.
244 	stream.Seek(0, SEEK_SET);
245 	BMessage archive;
246 	status_t result = archive.Unflatten(&stream);
247 	if (result != B_OK)
248 		return result;
249 
250 	*out = new BBitmap(&archive);
251 	if (*out == NULL)
252 		return B_ERROR;
253 
254 	result = (*out)->InitCheck();
255 	if (result != B_OK) {
256 		delete *out;
257 		*out = NULL;
258 	}
259 
260 	return result;
261 }
262 
263 
264 static BLocker resLock;
265 static BImageResources* resources = NULL;
266 
267 // This class is used as a static instance to delete the resources
268 // global object when the image is getting unloaded.
269 class _TTrackerCleanupResources {
270 public:
271 	_TTrackerCleanupResources()
272 	{
273 	}
274 
275 	~_TTrackerCleanupResources()
276 	{
277 		delete resources;
278 		resources = NULL;
279 	}
280 };
281 
282 
283 namespace BPrivate {
284 
285 static _TTrackerCleanupResources CleanupResources;
286 
287 BImageResources* GetTrackerResources()
288 {
289 	if (!resources) {
290 		BAutolock lock(&resLock);
291 		resources = new BImageResources(&resources);
292 	}
293 
294 	return resources;
295 }
296 
297 } // namespace BPrivate
298