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