xref: /haiku/src/kits/tracker/Bitmaps.cpp (revision 4bd0c1066b227cec4b79883bdef697c7a27f2e90)
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 <IconUtils.h>
44 #include <String.h>
45 #include <SupportDefs.h>
46 
47 
48 //	#pragma mark - BImageResources
49 
50 
51 BImageResources::BImageResources(void* memAddr)
52 {
53 	image_id image = find_image(memAddr);
54 	image_info info;
55 	if (get_image_info(image, &info) == B_OK) {
56 #if _SUPPORTS_RESOURCES
57 		BFile file(&info.name[0], B_READ_ONLY);
58 #else
59 		BString name(&info.name[0]);
60 		name += ".rsrc";
61 		BFile file(name.String(), B_READ_ONLY);
62 #endif
63 		if (file.InitCheck() == B_OK)
64 			fResources.SetTo(&file);
65 	}
66 }
67 
68 
69 BImageResources::~BImageResources()
70 {
71 }
72 
73 
74 const BResources*
75 BImageResources::ViewResources() const
76 {
77 	if (fLock.Lock() != B_OK)
78 		return NULL;
79 
80 	return &fResources;
81 }
82 
83 
84 BResources*
85 BImageResources::ViewResources()
86 {
87 	if (fLock.Lock() != B_OK)
88 		return NULL;
89 
90 	return &fResources;
91 }
92 
93 
94 status_t
95 BImageResources::FinishResources(BResources* res) const
96 {
97 	ASSERT(res == &fResources);
98 	if (res != &fResources)
99 		return B_BAD_VALUE;
100 
101 	fLock.Unlock();
102 
103 	return B_OK;
104 }
105 
106 
107 const void*
108 BImageResources::LoadResource(type_code type, int32 id,
109 	size_t* out_size) const
110 {
111 	// Serialize execution.
112 	// Looks like BResources is not really thread safe. We should
113 	// clean that up in the future and remove the locking from here.
114 	BAutolock lock(fLock);
115 	if (!lock.IsLocked())
116 		return 0;
117 
118 	// Return the resource.  Because we never change the BResources
119 	// object, the returned data will not change until TTracker is
120 	// destroyed.
121 	return const_cast<BResources*>(&fResources)->LoadResource(type, id,
122 		out_size);
123 }
124 
125 
126 const void*
127 BImageResources::LoadResource(type_code type, const char* name,
128 	size_t* out_size) const
129 {
130 	// Serialize execution.
131 	BAutolock lock(fLock);
132 	if (!lock.IsLocked())
133 		return NULL;
134 
135 	// Return the resource.  Because we never change the BResources
136 	// object, the returned data will not change until TTracker is
137 	// destroyed.
138 	return const_cast<BResources*>(&fResources)->LoadResource(type, name,
139 		out_size);
140 }
141 
142 
143 status_t
144 BImageResources::GetIconResource(int32 id, icon_size size,
145 	BBitmap* dest) const
146 {
147 	size_t length = 0;
148 	const void* data;
149 
150 	// try to load vector icon
151 	data = LoadResource(B_VECTOR_ICON_TYPE, id, &length);
152 	if (data != NULL
153 		&& BIconUtils::GetVectorIcon((uint8*)data, length, dest) == B_OK) {
154 		return B_OK;
155 	}
156 
157 	// fall back to R5 icon
158 	if (size != B_LARGE_ICON && size != B_MINI_ICON)
159 		return B_ERROR;
160 
161 	length = 0;
162 	data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length);
163 
164 	if (data == NULL
165 		|| length != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) {
166 		TRESPASS();
167 		return B_ERROR;
168 	}
169 
170 	if (dest->ColorSpace() != B_CMAP8) {
171 		return BIconUtils::ConvertFromCMAP8((uint8*)data, size, size,
172 			size, dest);
173 	}
174 
175 	dest->SetBits(data, (int32)length, 0, B_CMAP8);
176 	return B_OK;
177 }
178 
179 
180 status_t
181 BImageResources::GetIconResource(int32 id, const uint8** iconData,
182 	size_t* iconSize) const
183 {
184 	// try to load vector icon data from resources
185 	size_t length = 0;
186 	const void* data = LoadResource(B_VECTOR_ICON_TYPE, id, &length);
187 	if (data == NULL)
188 		return B_ERROR;
189 
190 	*iconData = (const uint8*)data;
191 	*iconSize = length;
192 
193 	return B_OK;
194 }
195 
196 
197 image_id
198 BImageResources::find_image(void* memAddr) const
199 {
200 	image_info info;
201 	int32 cookie = 0;
202 	while (get_next_image_info(0, &cookie, &info) == B_OK) {
203 		if ((info.text <= memAddr
204 			&& (((uint8*)info.text)+info.text_size) > memAddr)
205 				|| (info.data <= memAddr
206 				&& (((uint8*)info.data)+info.data_size) > memAddr)) {
207 			// Found the image.
208 			return info.id;
209 		}
210 	}
211 
212 	return -1;
213 }
214 
215 
216 status_t
217 BImageResources::GetBitmapResource(type_code type, int32 id,
218 	BBitmap** out) const
219 {
220 	*out = NULL;
221 
222 	size_t len = 0;
223 	const void* data = LoadResource(type, id, &len);
224 
225 	if (data == NULL) {
226 		TRESPASS();
227 		return B_ERROR;
228 	}
229 
230 	BMemoryIO stream(data, len);
231 
232 	// Try to read as an archived bitmap.
233 	stream.Seek(0, SEEK_SET);
234 	BMessage archive;
235 	status_t result = archive.Unflatten(&stream);
236 	if (result != B_OK)
237 		return result;
238 
239 	*out = new BBitmap(&archive);
240 	if (*out == NULL)
241 		return B_ERROR;
242 
243 	result = (*out)->InitCheck();
244 	if (result != B_OK) {
245 		delete *out;
246 		*out = NULL;
247 	}
248 
249 	return result;
250 }
251 
252 
253 static BLocker resLock;
254 static BImageResources* resources = NULL;
255 
256 // This class is used as a static instance to delete the resources
257 // global object when the image is getting unloaded.
258 class _TTrackerCleanupResources {
259 public:
260 	_TTrackerCleanupResources()
261 	{
262 	}
263 
264 	~_TTrackerCleanupResources()
265 	{
266 		delete resources;
267 		resources = NULL;
268 	}
269 };
270 
271 
272 namespace BPrivate {
273 
274 static _TTrackerCleanupResources CleanupResources;
275 
276 BImageResources* GetTrackerResources()
277 {
278 	if (!resources) {
279 		BAutolock lock(&resLock);
280 		resources = new BImageResources(&resources);
281 	}
282 
283 	return resources;
284 }
285 
286 } // namespace BPrivate
287