xref: /haiku/src/kits/tracker/Bitmaps.cpp (revision e688bf23d48bfd1216a0cacbdbda5e35a1bcd779)
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 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 	return B_OK;
103 }
104 
105 
106 const void*
107 BImageResources::LoadResource(type_code type, int32 id,
108 	size_t* out_size) const
109 {
110 	// Serialize execution.
111 	// Looks like BResources is not really thread safe. We should
112 	// clean that up in the future and remove the locking from here.
113 	BAutolock lock(fLock);
114 	if (!lock.IsLocked())
115 		return 0;
116 
117 	// Return the resource.  Because we never change the BResources
118 	// object, the returned data will not change until TTracker is
119 	// destroyed.
120 	return const_cast<BResources*>(&fResources)->LoadResource(type, id,
121 		out_size);
122 }
123 
124 
125 const void*
126 BImageResources::LoadResource(type_code type, const char* name,
127 	size_t* out_size) const
128 {
129 	// Serialize execution.
130 	BAutolock lock(fLock);
131 	if (!lock.IsLocked())
132 		return NULL;
133 
134 	// Return the resource.  Because we never change the BResources
135 	// object, the returned data will not change until TTracker is
136 	// destroyed.
137 	return const_cast<BResources*>(&fResources)->LoadResource(type, name,
138 		out_size);
139 }
140 
141 
142 status_t
143 BImageResources::GetIconResource(int32 id, icon_size size,
144 	BBitmap* dest) const
145 {
146 	size_t length = 0;
147 	const void* data;
148 
149 #ifdef __HAIKU__
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 #endif
157 
158 	// fall back to R5 icon
159 	if (size != B_LARGE_ICON && size != B_MINI_ICON)
160 		return B_ERROR;
161 
162 	length = 0;
163 	data = LoadResource(size == B_LARGE_ICON ? 'ICON' : 'MICN', id, &length);
164 
165 	if (data == NULL
166 		|| length != (size_t)(size == B_LARGE_ICON ? 1024 : 256)) {
167 		TRESPASS();
168 		return B_ERROR;
169 	}
170 
171 #ifdef __HAIKU__
172 	if (dest->ColorSpace() != B_CMAP8) {
173 		return BIconUtils::ConvertFromCMAP8((uint8*)data, size, size,
174 			size, dest);
175 	}
176 #endif
177 
178 	dest->SetBits(data, (int32)length, 0, B_CMAP8);
179 	return B_OK;
180 }
181 
182 
183 status_t
184 BImageResources::GetIconResource(int32 id, const uint8** iconData,
185 	size_t* iconSize) const
186 {
187 #ifdef __HAIKU__
188 	// try to load vector icon data from resources
189 	size_t length = 0;
190 	const void* data = LoadResource(B_VECTOR_ICON_TYPE, id, &length);
191 	if (data == NULL)
192 		return B_ERROR;
193 
194 	*iconData = (const uint8*)data;
195 	*iconSize = length;
196 
197 	return B_OK;
198 #else
199 	return B_ERROR;
200 #endif
201 }
202 
203 
204 image_id
205 BImageResources::find_image(void* memAddr) const
206 {
207 	image_info info;
208 	int32 cookie = 0;
209 	while (get_next_image_info(0, &cookie, &info) == B_OK)
210 		if ((info.text <= memAddr
211 			&& (((uint8*)info.text)+info.text_size) > memAddr)
212 				|| (info.data <= memAddr
213 				&& (((uint8*)info.data)+info.data_size) > memAddr)) {
214 			// Found the image.
215 			return info.id;
216 		}
217 
218 	return -1;
219 }
220 
221 
222 status_t
223 BImageResources::GetBitmapResource(type_code type, int32 id,
224 	BBitmap** out) const
225 {
226 	*out = NULL;
227 
228 	size_t len = 0;
229 	const void* data = LoadResource(type, id, &len);
230 
231 	if (data == NULL) {
232 		TRESPASS();
233 		return B_ERROR;
234 	}
235 
236 	BMemoryIO stream(data, len);
237 
238 	// Try to read as an archived bitmap.
239 	stream.Seek(0, SEEK_SET);
240 	BMessage archive;
241 	status_t err = archive.Unflatten(&stream);
242 	if (err != B_OK)
243 		return err;
244 
245 	*out = new BBitmap(&archive);
246 	if (!*out)
247 		return B_ERROR;
248 
249 	err = (*out)->InitCheck();
250 	if (err != B_OK) {
251 		delete *out;
252 		*out = NULL;
253 	}
254 
255 	return err;
256 }
257 
258 
259 static BLocker resLock;
260 static BImageResources* resources = NULL;
261 
262 // This class is used as a static instance to delete the resources
263 // global object when the image is getting unloaded.
264 class _TTrackerCleanupResources {
265 public:
266 	_TTrackerCleanupResources() { }
267 	~_TTrackerCleanupResources()
268 	{
269 		delete resources;
270 		resources = NULL;
271 	}
272 };
273 
274 
275 namespace BPrivate {
276 
277 static _TTrackerCleanupResources CleanupResources;
278 
279 
280 BImageResources* GetTrackerResources()
281 {
282 	if (!resources) {
283 		BAutolock lock(&resLock);
284 		resources = new BImageResources(&resources);
285 	}
286 	return resources;
287 }
288 
289 }
290