2 * Copyright 2013-2014, Stephan Aßmus <superstippi@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
6 #include "SharedBitmap.h"
11 #include <Application.h>
14 #include <IconUtils.h>
17 #include <Resources.h>
18 #include <TranslationUtils.h>
23 SharedBitmap::SharedBitmap(BBitmap
* bitmap
)
38 SharedBitmap::SharedBitmap(int32 resourceID
)
41 fResourceID(resourceID
),
53 SharedBitmap::SharedBitmap(const char* mimeType
)
68 SharedBitmap::SharedBitmap(BPositionIO
& data
)
76 status_t status
= data
.GetSize(&fSize
);
77 const off_t kMaxSize
= 1024 * 1024;
78 if (status
== B_OK
&& fSize
> 0 && fSize
<= kMaxSize
) {
79 fBuffer
= new(std::nothrow
) uint8
[fSize
];
80 if (fBuffer
!= NULL
) {
81 data
.Seek(0, SEEK_SET
);
84 size_t chunkSize
= std::min((off_t
)4096, fSize
);
85 while (bytesRead
< fSize
) {
86 ssize_t read
= data
.Read(fBuffer
+ bytesRead
, chunkSize
);
93 if (bytesRead
!= fSize
) {
101 fprintf(stderr
, "SharedBitmap(): Stream too large: %" B_PRIi64
102 ", max: %" B_PRIi64
"\n", fSize
, kMaxSize
);
112 SharedBitmap::~SharedBitmap()
123 SharedBitmap::Bitmap(Size which
)
125 if (fResourceID
== -1 && fMimeType
.Length() == 0 && fBuffer
== NULL
)
152 if (fBitmap
[index
] == NULL
) {
153 if (fResourceID
>= 0)
154 fBitmap
[index
] = _CreateBitmapFromResource(size
);
155 else if (fBuffer
!= NULL
)
156 fBitmap
[index
] = _CreateBitmapFromBuffer(size
);
157 else if (fMimeType
.Length() > 0)
158 fBitmap
[index
] = _CreateBitmapFromMimeType(size
);
161 return fBitmap
[index
];
166 SharedBitmap::_CreateBitmapFromResource(int32 size
) const
168 BResources resources
;
169 status_t status
= get_app_resources(resources
);
174 const void* data
= resources
.LoadResource(B_VECTOR_ICON_TYPE
, fResourceID
,
177 return _LoadIconFromBuffer(data
, dataSize
, size
);
179 data
= resources
.LoadResource(B_MESSAGE_TYPE
, fResourceID
, &dataSize
);
181 return _LoadBitmapFromBuffer(data
, dataSize
);
188 SharedBitmap::_CreateBitmapFromBuffer(int32 size
) const
190 BBitmap
* bitmap
= _LoadIconFromBuffer(fBuffer
, fSize
, size
);
193 bitmap
= _LoadBitmapFromBuffer(fBuffer
, fSize
);
200 SharedBitmap::_CreateBitmapFromMimeType(int32 size
) const
202 BMimeType
mimeType(fMimeType
.String());
203 status_t status
= mimeType
.InitCheck();
207 BBitmap
* bitmap
= new BBitmap(BRect(0, 0, size
- 1, size
- 1), 0, B_RGBA32
);
208 status
= bitmap
->InitCheck();
210 status
= mimeType
.GetIcon(bitmap
, B_MINI_ICON
);
212 if (status
!= B_OK
) {
222 SharedBitmap::_LoadBitmapFromBuffer(const void* buffer
, size_t size
) const
224 BMemoryIO
stream(buffer
, size
);
226 // Try to read as an archived bitmap.
227 BBitmap
* bitmap
= _LoadArchivedBitmapFromStream(stream
);
229 if (bitmap
== NULL
) {
230 // Try to read as a translator bitmap
231 stream
.Seek(0, SEEK_SET
);
232 bitmap
= _LoadTranslatorBitmapFromStream(stream
);
235 if (bitmap
!= NULL
) {
236 status_t status
= bitmap
->InitCheck();
237 if (status
!= B_OK
) {
248 SharedBitmap::_LoadArchivedBitmapFromStream(BPositionIO
& stream
) const
251 status_t status
= archive
.Unflatten(&stream
);
255 return new BBitmap(&archive
);
260 SharedBitmap::_LoadTranslatorBitmapFromStream(BPositionIO
& stream
) const
262 return BTranslationUtils::GetBitmap(&stream
);
267 SharedBitmap::_LoadIconFromBuffer(const void* data
, size_t dataSize
,
270 BBitmap
* bitmap
= new BBitmap(BRect(0, 0, size
- 1, size
- 1), 0,
272 status_t status
= bitmap
->InitCheck();
273 if (status
== B_OK
) {
274 status
= BIconUtils::GetVectorIcon(
275 reinterpret_cast<const uint8
*>(data
), dataSize
, bitmap
);
278 if (status
!= B_OK
) {