mirror of
https://github.com/sle118/squeezelite-esp32.git
synced 2025-12-08 12:37:01 +03:00
scroller correction + JPEG improvements
This commit is contained in:
@@ -13,13 +13,14 @@
|
||||
monochrome mode is not such type of screen, SH1106 and SSD1306 are
|
||||
*/
|
||||
|
||||
enum { GDS_COLOR_L0 = 0, GDS_COLOR_L1, GDS_COLOR_L2, GDS_COLOR_L3, GDS_COLOR_L4, GDS_COLOR_L5, GDS_COLOR_L6, GDS_COLOR_L7,
|
||||
enum { GDS_COLOR_L0 = 0, GDS_COLOR_L1 = 1, GDS_COLOR_L2, GDS_COLOR_L3, GDS_COLOR_L4, GDS_COLOR_L5, GDS_COLOR_L6, GDS_COLOR_L7,
|
||||
GDS_COLOR_L8, GDS_COLOR_L9, GDS_COLOR_L10, GDS_COLOR_L11, GDS_COLOR_L12, GDS_COLOR_L13, GDS_COLOR_L14, GDS_COLOR_L15,
|
||||
GDS_COLOR_MAX
|
||||
};
|
||||
|
||||
#define GDS_COLOR_BLACK GDS_COLOR_L0
|
||||
#define GDS_COLOR_WHITE GDS_COLOR_L15
|
||||
#define GDS_COLOR_XOR 2
|
||||
#define GDS_COLOR_WHITE GDS_COLOR_L1
|
||||
#define GDS_COLOR_XOR (GDS_COLOR_MAX + 1)
|
||||
|
||||
struct GDS_Device;
|
||||
struct GDS_FontDef;
|
||||
|
||||
@@ -21,6 +21,7 @@ typedef struct {
|
||||
struct { // DirectDraw
|
||||
struct GDS_Device * Device;
|
||||
int XOfs, YOfs;
|
||||
int XMin, YMin;
|
||||
int Depth;
|
||||
};
|
||||
};
|
||||
@@ -38,9 +39,7 @@ static unsigned OutHandler(JDEC *Decoder, void *Bitmap, JRECT *Frame) {
|
||||
uint8_t *Pixels = (uint8_t*) Bitmap;
|
||||
|
||||
for (int y = Frame->top; y <= Frame->bottom; y++) {
|
||||
if (y < Context->YOfs) continue;
|
||||
for (int x = Frame->left; x <= Frame->right; x++) {
|
||||
if (x < Context->XOfs) continue;
|
||||
// Convert the 888 to RGB565
|
||||
uint16_t Value = (*Pixels++ & ~0x07) << 8;
|
||||
Value |= (*Pixels++ & ~0x03) << 3;
|
||||
@@ -57,12 +56,14 @@ static unsigned OutHandlerDirect(JDEC *Decoder, void *Bitmap, JRECT *Frame) {
|
||||
int Shift = 8 - Context->Depth;
|
||||
|
||||
for (int y = Frame->top; y <= Frame->bottom; y++) {
|
||||
if (y < Context->YMin) continue;
|
||||
for (int x = Frame->left; x <= Frame->right; x++) {
|
||||
if (x < Context->XMin) continue;
|
||||
// Convert the 888 to RGB565
|
||||
int Value = ((Pixels[0]*11 + Pixels[1]*59 + Pixels[2]*30) / 100) >> Shift;
|
||||
Pixels += 3;
|
||||
// used DrawPixel and not "fast" version as X,Y may be beyond screen
|
||||
GDS_DrawPixel( Context->Device, Context->XOfs + x, Context->YOfs + y, Value);
|
||||
GDS_DrawPixel( Context->Device, x + Context->XOfs, y + Context->YOfs, Value);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -90,11 +91,16 @@ static uint16_t* DecodeJPEG(uint8_t *Source, int *Width, int *Height, float Scal
|
||||
Decoder.scale = Scale;
|
||||
|
||||
if (Res == JDR_OK && !SizeOnly) {
|
||||
// find the scaling factor
|
||||
Context.OutData = malloc(Decoder.width * Decoder.height * sizeof(uint16_t));
|
||||
|
||||
// find the scaling factor
|
||||
uint8_t N = 0, ScaleInt = ceil(1.0 / Scale);
|
||||
ScaleInt--; ScaleInt |= ScaleInt >> 1; ScaleInt |= ScaleInt >> 2; ScaleInt++;
|
||||
while (ScaleInt >>= 1) N++;
|
||||
if (N > 3) {
|
||||
ESP_LOGW(TAG, "Image will not fit %dx%d", Decoder.width, Decoder.height);
|
||||
N = 3;
|
||||
}
|
||||
|
||||
// ready to decode
|
||||
if (Context.OutData) {
|
||||
@@ -102,7 +108,7 @@ static uint16_t* DecodeJPEG(uint8_t *Source, int *Width, int *Height, float Scal
|
||||
Context.Height = Decoder.height / (1 << N);
|
||||
if (Width) *Width = Context.Width;
|
||||
if (Height) *Height = Context.Height;
|
||||
Res = jd_decomp(&Decoder, OutHandler, N > 3 ? 3 : N);
|
||||
Res = jd_decomp(&Decoder, OutHandler, N);
|
||||
if (Res != JDR_OK) {
|
||||
ESP_LOGE(TAG, "Image decoder: jd_decode failed (%d)", Res);
|
||||
}
|
||||
@@ -202,16 +208,23 @@ bool GDS_DrawJPEG( struct GDS_Device* Device, uint8_t *Source, int x, int y, int
|
||||
uint8_t Ratio = XRatio < YRatio ? ceil(1/XRatio) : ceil(1/YRatio);
|
||||
Ratio--; Ratio |= Ratio >> 1; Ratio |= Ratio >> 2; Ratio++;
|
||||
while (Ratio >>= 1) N++;
|
||||
if (N > 3) {
|
||||
ESP_LOGW(TAG, "Image will not fit %dx%d", Decoder.width, Decoder.height);
|
||||
N = 3;
|
||||
}
|
||||
Context.Width /= 1 << N;
|
||||
Context.Height /= 1 << N;
|
||||
}
|
||||
|
||||
// then place it
|
||||
if (Fit & GDS_IMAGE_CENTER_X) Context.XOfs = x + ((Device->Width - x) - Context.Width) / 2;
|
||||
if (Fit & GDS_IMAGE_CENTER_Y) Context.YOfs = y + ((Device->Height - y) - Context.Height) / 2;
|
||||
if (Fit & GDS_IMAGE_CENTER_X) Context.XOfs = (Device->Width + x - Context.Width) / 2;
|
||||
if (Fit & GDS_IMAGE_CENTER_Y) Context.YOfs = (Device->Height + y - Context.Height) / 2;
|
||||
|
||||
Context.XMin = x - Context.XOfs;
|
||||
Context.YMin = y - Context.YOfs;
|
||||
|
||||
// do decompress & draw
|
||||
Res = jd_decomp(&Decoder, OutHandlerDirect, N > 3 ? 3 : N);
|
||||
Res = jd_decomp(&Decoder, OutHandlerDirect, N);
|
||||
if (Res == JDR_OK) {
|
||||
Ret = true;
|
||||
} else {
|
||||
|
||||
@@ -83,7 +83,7 @@ struct GDS_Device {
|
||||
uint16_t Height;
|
||||
uint8_t Depth;
|
||||
|
||||
uint8_t* Framebuffer, *Shadowbuffer;
|
||||
uint8_t* Framebuffer;
|
||||
uint16_t FramebufferSize;
|
||||
bool Dirty;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user