1
0
Fork 0
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:
Damjan Adamic 2016-02-28 21:08:45 +01:00
parent 9a23c3fcc6
commit 5e96d02120
4 changed files with 41 additions and 20 deletions

View file

@ -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;
} }

View file

@ -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);

View file

@ -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)

View file

@ -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);
} }
} }