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