xref: /haiku/src/kits/tracker/Bitmaps.cpp (revision 9ecf9d1c1d4888d341a6eac72112c72d1ae3a4cb)
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 	if (size != B_LARGE_ICON && size != B_MINI_ICON )
131 		return B_ERROR;
132 
133 	size_t length = 0;
134 	const void *data;
135 
136 	// try to load vector icon
137 	data = LoadResource(B_RAW_TYPE, id, &length);
138 
139 	if (data && BIconUtils::GetVectorIcon((uint8*)data, length, dest) == B_OK)
140 		return B_OK;
141 
142 	// fall back to R5 icon
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 image_id
164 BImageResources::find_image(void *memAddr) const
165 {
166 	image_info info;
167 	int32 cookie = 0;
168 	while (get_next_image_info(0, &cookie, &info) == B_OK)
169 		if ((info.text <= memAddr && (((uint8 *)info.text)+info.text_size) > memAddr)
170 			||(info.data <= memAddr && (((uint8 *)info.data)+info.data_size) > memAddr))
171 			// Found the image.
172 			return info.id;
173 
174 	return -1;
175 }
176 
177 status_t
178 BImageResources::GetBitmapResource(type_code type, int32 id, BBitmap **out) const
179 {
180 	*out = NULL;
181 
182 	size_t len = 0;
183 	const void *data = LoadResource(type, id, &len);
184 
185 	if (data == NULL) {
186 		TRESPASS();
187 		return B_ERROR;
188 	}
189 
190 	BMemoryIO stream(data, len);
191 
192 	// Try to read as an archived bitmap.
193 	stream.Seek(0, SEEK_SET);
194 	BMessage archive;
195 	status_t err = archive.Unflatten(&stream);
196 	if (err != B_OK)
197 		return err;
198 
199 	*out = new BBitmap(&archive);
200 	if (!*out)
201 		return B_ERROR;
202 
203 	err = (*out)->InitCheck();
204 	if (err != B_OK) {
205 		delete *out;
206 		*out = NULL;
207 	}
208 
209 	return err;
210 }
211 
212 
213 static BLocker resLock;
214 static BImageResources *resources = NULL;
215 
216 // This class is used as a static instance to delete the resources
217 // global object when the image is getting unloaded.
218 class _TTrackerCleanupResources
219 {
220 public:
221 	_TTrackerCleanupResources() { }
222 	~_TTrackerCleanupResources()
223 	{
224 		delete resources;
225 		resources = NULL;
226 	}
227 };
228 
229 
230 namespace BPrivate {
231 
232 static _TTrackerCleanupResources CleanupResources;
233 
234 
235 BImageResources *GetTrackerResources()
236 {
237 	if (!resources) {
238 		BAutolock lock(&resLock);
239 		resources = new BImageResources(&resources);
240 	}
241 	return resources;
242 }
243 
244 }
245