Merge remote-tracking branch 'origin/master' into master-cmake

Conflicts:
	components/raop/raop.c
	components/raop/rtp.c
	main/cmd_squeezelite.c
This commit is contained in:
Sebastien
2020-03-08 09:54:50 -04:00
48 changed files with 951 additions and 481 deletions

View File

@@ -95,7 +95,7 @@ void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2,
memset( Device->Framebuffer, Color | (Color << 4), Device->FramebufferSize );
} else {
uint8_t _Color = Color | (Color << 4);
uint8_t Width = Device->Width;
int Width = Device->Width;
uint8_t *optr = Device->Framebuffer;
// try to do byte processing as much as possible
for (int r = y1; r <= y2; r++) {
@@ -113,7 +113,7 @@ void GDS_ClearWindow( struct GDS_Device* Device, int x1, int y1, int x2, int y2,
}
}
}
// make sure diplay will do update
Device->Dirty = true;
}
@@ -132,10 +132,29 @@ bool GDS_Reset( struct GDS_Device* Device ) {
return true;
}
void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) { Device->SetContrast( Device, Contrast); }
void GDS_SetHFlip( struct GDS_Device* Device, bool On ) { Device->SetHFlip( Device, On ); }
void GDS_SetVFlip( struct GDS_Device* Device, bool On ) { Device->SetVFlip( Device, On ); }
bool GDS_Init( struct GDS_Device* Device ) {
Device->FramebufferSize = (Device->Width * Device->Height) / (8 / Device->Depth);
// allocate FB unless explicitely asked not to
if (!(Device->Alloc & GDS_ALLOC_NONE)) {
if ((Device->Alloc & GDS_ALLOC_IRAM) || ((Device->Alloc & GDS_ALLOC_IRAM_SPI) && Device->IF == GDS_IF_SPI)) {
heap_caps_calloc( 1, Device->FramebufferSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA );
} else {
Device->Framebuffer = calloc( 1, Device->FramebufferSize );
}
NullCheck( Device->Framebuffer, return false );
}
bool Res = Device->Init( Device );
if (!Res) free(Device->Framebuffer);
return Res;
}
void GDS_SetContrast( struct GDS_Device* Device, uint8_t Contrast ) { if (Device->SetContrast) Device->SetContrast( Device, Contrast); }
void GDS_SetHFlip( struct GDS_Device* Device, bool On ) { if (Device->SetHFlip) Device->SetHFlip( Device, On ); }
void GDS_SetVFlip( struct GDS_Device* Device, bool On ) { if (Device->SetVFlip) Device->SetVFlip( Device, On ); }
int GDS_GetWidth( struct GDS_Device* Device ) { return Device->Width; }
int GDS_GetHeight( struct GDS_Device* Device ) { return Device->Height; }
void GDS_DisplayOn( struct GDS_Device* Device ) { Device->DisplayOn( Device ); }
void GDS_DisplayOff( struct GDS_Device* Device ) { Device->DisplayOff( Device ); }
void GDS_DisplayOn( struct GDS_Device* Device ) { if (Device->DisplayOn) Device->DisplayOn( Device ); }
void GDS_DisplayOff( struct GDS_Device* Device ) { if (Device->DisplayOff) Device->DisplayOff( Device ); }

View File

@@ -15,11 +15,12 @@
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,
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_BLACK (0)
#define GDS_COLOR_WHITE (-1)
#define GDS_COLOR_XOR (GDS_COLOR_MAX + 1)
struct GDS_Device;
struct GDS_FontDef;

View File

@@ -58,7 +58,7 @@ void GDS_DrawHLine( struct GDS_Device* Device, int x, int y, int Width, int Colo
if (XEnd >= Device->Width) XEnd = Device->Width - 1;
if (y < 0) y = 0;
else if (y >= Device->Height) x = Device->Height - 1;
else if (y >= Device->Height) y = Device->Height - 1;
for ( ; x < XEnd; x++ ) GDS_DrawPixelFast( Device, x, y, Color );
}
@@ -195,11 +195,11 @@ void GDS_DrawBox( struct GDS_Device* Device, int x1, int y1, int x2, int y2, int
void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color ) {
if (!Height) Height = Device->Height;
if (!Width) Width = Device->Width;
Height >>= 3;
if (Device->DrawBitmapCBR) {
Device->DrawBitmapCBR( Device, Data, Width, Height, Color );
} else if (Device->Depth == 1) {
Height >>= 3;
// need to do row/col swap and bit-reverse
for (int r = 0; r < Height; r++) {
uint8_t *optr = Device->Framebuffer + r*Device->Width, *iptr = Data + r;
@@ -211,6 +211,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int
} else if (Device->Depth == 4) {
uint8_t *optr = Device->Framebuffer;
int LineLen = Device->Width >> 1;
Height >>= 3;
for (int i = Width * Height, r = 0, c = 0; --i >= 0;) {
uint8_t Byte = BitReverseTable256[*Data++];
// we need to linearize code to let compiler better optimize
@@ -237,6 +238,7 @@ void GDS_DrawBitmapCBR(struct GDS_Device* Device, uint8_t *Data, int Width, int
if (++r == Height) { c++; r = 0; optr = Device->Framebuffer + (c >> 1); }
}
} else {
Height >>= 3;
// don't know bitdepth, use brute-force solution
for (int i = Width * Height, r = 0, c = 0; --i >= 0;) {
uint8_t Byte = *Data++;

View File

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

View File

@@ -7,6 +7,10 @@
#include "gds.h"
#include "gds_err.h"
#define GDS_ALLOC_NONE 0x80
#define GDS_ALLOC_IRAM 0x01
#define GDS_ALLOC_IRAM_SPI 0x02
#define GDS_CLIPDEBUG_NONE 0
#define GDS_CLIPDEBUG_WARNING 1
#define GDS_CLIPDEBUG_ERROR 2
@@ -55,8 +59,8 @@ typedef bool ( *WriteDataProc ) ( struct GDS_Device* Device, const uint8_t* Data
struct spi_device_t;
typedef struct spi_device_t* spi_device_handle_t;
#define IF_SPI 0
#define IF_I2C 1
#define GDS_IF_SPI 0
#define GDS_IF_I2C 1
struct GDS_Device {
uint8_t IF;
@@ -82,8 +86,9 @@ struct GDS_Device {
uint16_t Width;
uint16_t Height;
uint8_t Depth;
uint8_t* Framebuffer, *Shadowbuffer;
uint8_t Alloc;
uint8_t* Framebuffer;
uint16_t FramebufferSize;
bool Dirty;
@@ -95,12 +100,13 @@ struct GDS_Device {
// various driver-specific method
// must always provide
bool (*Init)( struct GDS_Device* Device);
void (*Update)( struct GDS_Device* Device );
// may provide if supported
void (*SetContrast)( struct GDS_Device* Device, uint8_t Contrast );
void (*DisplayOn)( struct GDS_Device* Device );
void (*DisplayOff)( struct GDS_Device* Device );
void (*SetHFlip)( struct GDS_Device* Device, bool On );
void (*SetVFlip)( struct GDS_Device* Device, bool On );
void (*Update)( struct GDS_Device* Device );
// must provide for depth other than 1 (vertical) and 4 (may provide for optimization)
void (*DrawPixelFast)( struct GDS_Device* Device, int X, int Y, int Color );
void (*DrawBitmapCBR)(struct GDS_Device* Device, uint8_t *Data, int Width, int Height, int Color );
@@ -117,6 +123,7 @@ struct GDS_Device {
};
bool GDS_Reset( struct GDS_Device* Device );
bool GDS_Init( struct GDS_Device* Device );
static inline bool IsPixelVisible( struct GDS_Device* Device, int x, int y ) {
bool Result = (
@@ -152,7 +159,7 @@ static inline void IRAM_ATTR GDS_DrawPixel1Fast( struct GDS_Device* Device, int
if ( Color == GDS_COLOR_XOR ) {
*FBOffset ^= BIT( YBit );
} else {
*FBOffset = ( Color == GDS_COLOR_WHITE ) ? *FBOffset | BIT( YBit ) : *FBOffset & ~BIT( YBit );
*FBOffset = ( Color == GDS_COLOR_BLACK ) ? *FBOffset & ~BIT( YBit ) : *FBOffset | BIT( YBit );
}
}
@@ -160,7 +167,7 @@ static inline void IRAM_ATTR GDS_DrawPixel4Fast( struct GDS_Device* Device, int
uint8_t* FBOffset;
FBOffset = Device->Framebuffer + ( (Y * Device->Width >> 1) + (X >> 1));
*FBOffset = X & 0x01 ? (*FBOffset & 0x0f) | (Color << 4) : ((*FBOffset & 0xf0) | Color);
*FBOffset = X & 0x01 ? (*FBOffset & 0x0f) | ((Color & 0x0f) << 4) : ((*FBOffset & 0xf0) | (Color & 0x0f));
}
static inline void IRAM_ATTR GDS_DrawPixelFast( struct GDS_Device* Device, int X, int Y, int Color ) {

View File

@@ -73,7 +73,7 @@ bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int
Device->WriteData = I2CDefaultWriteData;
Device->Address = I2CAddress;
Device->RSTPin = RSTPin;
Device->IF = IF_I2C;
Device->IF = GDS_IF_I2C;
Device->Width = Width;
Device->Height = Height;
@@ -83,7 +83,7 @@ bool GDS_I2CAttachDevice( struct GDS_Device* Device, int Width, int Height, int
GDS_Reset( Device );
}
return Device->Init( Device );
return GDS_Init( Device );
}
static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {

View File

@@ -58,7 +58,7 @@ bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int
Device->SPIHandle = SPIDevice;
Device->RSTPin = RSTPin;
Device->CSPin = CSPin;
Device->IF = IF_SPI;
Device->IF = GDS_IF_SPI;
Device->Width = Width;
Device->Height = Height;
@@ -68,7 +68,7 @@ bool GDS_SPIAttachDevice( struct GDS_Device* Device, int Width, int Height, int
GDS_Reset( Device );
}
return Device->Init( Device );
return GDS_Init( Device );
}
static bool SPIDefaultWriteBytes( spi_device_handle_t SPIHandle, int WriteMode, const uint8_t* Data, size_t DataLength ) {