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