mirror of
https://github.com/opentx/opentx.git
synced 2025-07-15 12:25:12 +03:00
Transparent bitmaps supported/displayed in SD browser. BitmapBuffer: fixed wrong free() when using external data buffer.
This commit is contained in:
parent
9a23c3fcc6
commit
5e96d02120
4 changed files with 41 additions and 20 deletions
|
@ -461,7 +461,7 @@ const stbi_io_callbacks stbCallbacks = {
|
||||||
stbc_eof
|
stbc_eof
|
||||||
};
|
};
|
||||||
|
|
||||||
BitmapBuffer * BitmapBuffer::load(const char * filename)
|
BitmapBuffer * BitmapBuffer::load(const char * filename, bool transparent)
|
||||||
{
|
{
|
||||||
FIL imgFile;
|
FIL imgFile;
|
||||||
|
|
||||||
|
@ -471,24 +471,36 @@ BitmapBuffer * BitmapBuffer::load(const char * filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
int w, h, n;
|
int w, h, n;
|
||||||
unsigned char *data = stbi_load_from_callbacks(&stbCallbacks, &imgFile, &w, &h, &n, 3);
|
unsigned char *img = stbi_load_from_callbacks(&stbCallbacks, &imgFile, &w, &h, &n, transparent ? 4 : 3);
|
||||||
f_close(&imgFile);
|
f_close(&imgFile);
|
||||||
|
|
||||||
if (!data) {
|
if (!img) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//convert to 565 fromat
|
//convert to RGB565 or ARGB4444 fromat
|
||||||
// todo use dma2d for conversion from 888 to 565
|
// todo use dma2d for conversion from 888 to 565
|
||||||
unsigned char * p = data;
|
unsigned char * p = img;
|
||||||
BitmapBuffer * bmp = new BitmapBuffer(w, h);
|
BitmapBuffer * bmp = new BitmapBuffer(w, h);
|
||||||
uint16_t * dest = bmp->data;
|
uint16_t * dest = bmp->data;
|
||||||
if (bmp == NULL) {
|
if (bmp == NULL) {
|
||||||
TRACE("load_stb() malloc failed");
|
TRACE("load_stb() malloc failed");
|
||||||
stbi_image_free(data);
|
stbi_image_free(img);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (transparent) {
|
||||||
|
for(int row = 0; row < h; ++row) {
|
||||||
|
unsigned char *l = p;
|
||||||
|
for(int col = 0; col < w; ++col) {
|
||||||
|
*dest = ARGB(l[3], l[0], l[1], l[2]);
|
||||||
|
++dest;
|
||||||
|
l += 4;
|
||||||
|
}
|
||||||
|
p += 4 * w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
for(int row = 0; row < h; ++row) {
|
for(int row = 0; row < h; ++row) {
|
||||||
unsigned char *l = p;
|
unsigned char *l = p;
|
||||||
for(int col = 0; col < w; ++col) {
|
for(int col = 0; col < w; ++col) {
|
||||||
|
@ -498,6 +510,8 @@ BitmapBuffer * BitmapBuffer::load(const char * filename)
|
||||||
}
|
}
|
||||||
p += 3 * w;
|
p += 3 * w;
|
||||||
}
|
}
|
||||||
stbi_image_free(data);
|
}
|
||||||
|
|
||||||
|
stbi_image_free(img);
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,22 +64,27 @@ typedef BitmapBufferBase<const uint16_t> Bitmap;
|
||||||
|
|
||||||
class BitmapBuffer: public BitmapBufferBase<uint16_t>
|
class BitmapBuffer: public BitmapBufferBase<uint16_t>
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
bool dataAllocated;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BitmapBuffer(int width, int height):
|
BitmapBuffer(int width, int height):
|
||||||
BitmapBufferBase<uint16_t>(width, height, NULL)
|
BitmapBufferBase<uint16_t>(width, height, NULL),
|
||||||
|
dataAllocated(true)
|
||||||
{
|
{
|
||||||
data = (uint16_t *)malloc(width*height*sizeof(uint16_t));
|
data = (uint16_t *)malloc(width*height*sizeof(uint16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapBuffer(int width, int height, uint16_t * data):
|
BitmapBuffer(int width, int height, uint16_t * data):
|
||||||
BitmapBufferBase<uint16_t>(width, height, data)
|
BitmapBufferBase<uint16_t>(width, height, data),
|
||||||
|
dataAllocated(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
~BitmapBuffer()
|
~BitmapBuffer()
|
||||||
{
|
{
|
||||||
free(data);
|
if (dataAllocated && data) free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void clear()
|
inline void clear()
|
||||||
|
@ -132,7 +137,7 @@ class BitmapBuffer: public BitmapBufferBase<uint16_t>
|
||||||
|
|
||||||
void drawBitmapPatternPie(coord_t x0, coord_t y0, const uint8_t * img, LcdFlags flags, int startAngle, int endAngle);
|
void drawBitmapPatternPie(coord_t x0, coord_t y0, const uint8_t * img, LcdFlags flags, int startAngle, int endAngle);
|
||||||
|
|
||||||
static BitmapBuffer * load(const char * filename);
|
static BitmapBuffer * load(const char * filename, bool transparent = false);
|
||||||
|
|
||||||
void drawBitmapPattern(coord_t x, coord_t y, const uint8_t * bmp, LcdFlags flags, coord_t offset=0, coord_t width=0);
|
void drawBitmapPattern(coord_t x, coord_t y, const uint8_t * bmp, LcdFlags flags, coord_t offset=0, coord_t width=0);
|
||||||
|
|
||||||
|
|
|
@ -25,9 +25,11 @@
|
||||||
#undef OPAQUE
|
#undef OPAQUE
|
||||||
#undef RGB
|
#undef RGB
|
||||||
|
|
||||||
|
#define TO4BITS(x) ((x) >> 4)
|
||||||
#define TO5BITS(x) ((x) >> 3)
|
#define TO5BITS(x) ((x) >> 3)
|
||||||
#define TO6BITS(x) ((x) >> 2)
|
#define TO6BITS(x) ((x) >> 2)
|
||||||
#define RGB(r, g, b) ((TO5BITS(r) << 11) + (TO6BITS(g) << 5) + (TO5BITS(b) << 0))
|
#define RGB(r, g, b) ((TO5BITS(r) << 11) + (TO6BITS(g) << 5) + (TO5BITS(b) << 0))
|
||||||
|
#define ARGB(a, r, g, b) ((TO4BITS(a) << 12) + (TO4BITS(r) << 8) + (TO4BITS(g) << 4) + (TO4BITS(b) << 0))
|
||||||
#define WHITE RGB(0xFF, 0xFF, 0xFF)
|
#define WHITE RGB(0xFF, 0xFF, 0xFF)
|
||||||
#define BLACK RGB(0, 0, 0)
|
#define BLACK RGB(0, 0, 0)
|
||||||
#define YELLOW RGB(0xF0, 0xD0, 0x10)
|
#define YELLOW RGB(0xF0, 0xD0, 0x10)
|
||||||
|
|
|
@ -366,11 +366,11 @@ bool menuGeneralSdManager(evt_t _event)
|
||||||
if (currentBitmapIndex != menuVerticalPosition) {
|
if (currentBitmapIndex != menuVerticalPosition) {
|
||||||
currentBitmapIndex = menuVerticalPosition;
|
currentBitmapIndex = menuVerticalPosition;
|
||||||
delete currentBitmap;
|
delete currentBitmap;
|
||||||
currentBitmap = BitmapBuffer::load(reusableBuffer.sdmanager.lines[index]);
|
currentBitmap = BitmapBuffer::load(reusableBuffer.sdmanager.lines[index], true);
|
||||||
// TODO scale in case of a too large bitmap
|
// TODO scale in case of a too large bitmap
|
||||||
}
|
}
|
||||||
if (currentBitmap) {
|
if (currentBitmap) {
|
||||||
lcd->drawBitmap(LCD_W / 2, LCD_H / 2, currentBitmap);
|
lcd->drawAlphaBitmap(LCD_W / 2, LCD_H / 2, currentBitmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue