mirror of https://github.com/FreeRDP/FreeRDP
Merge pull request #5381 from akallabeth/swscale
Added image scaling api for software drawing.
This commit is contained in:
commit
49805aae89
|
@ -37,16 +37,7 @@ set(${MODULE_PREFIX}_SRCS
|
|||
wlf_channels.h
|
||||
)
|
||||
|
||||
find_package(Cairo)
|
||||
|
||||
list (APPEND ${MODULE_PREFIX}_LIBS freerdp-client freerdp uwac)
|
||||
if (CAIRO_FOUND)
|
||||
add_definitions(-DCAIRO_FOUND=1)
|
||||
include_directories(${CAIRO_INCLUDE_DIR})
|
||||
list(APPEND ${MODULE_PREFIX}_LIBS ${CAIRO_LIBRARY})
|
||||
else(CAIRO_FOUND)
|
||||
message(WARNING "libcairo not detected, compiling without wayland smart scaling support!")
|
||||
endif(CAIRO_FOUND)
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
#include <linux/input.h>
|
||||
|
||||
#include <uwac/uwac.h>
|
||||
#if defined(CAIRO_FOUND)
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#include "wlfreerdp.h"
|
||||
#include "wlf_input.h"
|
||||
|
@ -623,44 +620,8 @@ BOOL wlf_copy_image(const void* src, size_t srcStride, size_t srcWidth, size_t s
|
|||
|
||||
if (scale)
|
||||
{
|
||||
#if defined(CAIRO_FOUND)
|
||||
const double sx = (double)dstWidth / (double)srcWidth;
|
||||
const double sy = (double)dstHeight / (double)srcHeight;
|
||||
cairo_t* cairo_context;
|
||||
cairo_surface_t* csrc, *cdst;
|
||||
|
||||
if ((srcWidth > INT_MAX) || (srcHeight > INT_MAX) || (srcStride > INT_MAX))
|
||||
return FALSE;
|
||||
|
||||
if ((dstWidth > INT_MAX) || (dstHeight > INT_MAX) || (dstStride > INT_MAX))
|
||||
return FALSE;
|
||||
|
||||
csrc = cairo_image_surface_create_for_data((void*)src, CAIRO_FORMAT_ARGB32, (int)srcWidth,
|
||||
(int)srcHeight, (int)srcStride);
|
||||
cdst = cairo_image_surface_create_for_data(dst, CAIRO_FORMAT_ARGB32, (int)dstWidth,
|
||||
(int)dstHeight, (int)dstStride);
|
||||
|
||||
if (!csrc || !cdst)
|
||||
goto fail;
|
||||
|
||||
cairo_context = cairo_create(cdst);
|
||||
|
||||
if (!cairo_context)
|
||||
goto fail2;
|
||||
|
||||
cairo_scale(cairo_context, sx, sy);
|
||||
cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface(cairo_context, csrc, 0, 0);
|
||||
cairo_paint(cairo_context);
|
||||
rc = TRUE;
|
||||
fail2:
|
||||
cairo_destroy(cairo_context);
|
||||
fail:
|
||||
cairo_surface_destroy(csrc);
|
||||
cairo_surface_destroy(cdst);
|
||||
#else
|
||||
WLog_WARN(TAG, "SmartScaling requested but compiled without libcairo support!");
|
||||
#endif
|
||||
return freerdp_image_scale(dst, PIXEL_FORMAT_BGRA32, dstStride, 0, 0, dstWidth, dstHeight,
|
||||
src, PIXEL_FORMAT_BGRA32, srcStride, 0, 0, srcWidth, srcHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -698,8 +659,6 @@ BOOL wlf_scale_coordinates(rdpContext* context, UINT32* px, UINT32* py, BOOL fro
|
|||
if (!context->settings->SmartSizing)
|
||||
return TRUE;
|
||||
|
||||
/* If libcairo is not compiled, smart scaling is ignored. */
|
||||
#if defined(CAIRO_FOUND)
|
||||
gdi = context->gdi;
|
||||
|
||||
if (UwacWindowGetDrawingBufferGeometry(wlf->window, &geometry, NULL) != UWAC_SUCCESS)
|
||||
|
@ -719,6 +678,5 @@ BOOL wlf_scale_coordinates(rdpContext* context, UINT32* px, UINT32* py, BOOL fro
|
|||
*py /= sy;
|
||||
}
|
||||
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -145,11 +145,14 @@ endif(WITH_FFMPEG)
|
|||
|
||||
option(USE_VERSION_FROM_GIT_TAG "Extract FreeRDP version from git tag." OFF)
|
||||
|
||||
if(ANDROID)
|
||||
include(ConfigOptionsAndroid)
|
||||
option(WITH_CAIRO "Use CAIRO image library for screen resizing" OFF)
|
||||
option(WITH_SWSCALE "Use SWScale image library for screen resizing" OFF)
|
||||
|
||||
if (ANDROID)
|
||||
include(ConfigOptionsAndroid)
|
||||
endif(ANDROID)
|
||||
|
||||
if(IOS)
|
||||
include(ConfigOptionsiOS)
|
||||
if (IOS)
|
||||
include(ConfigOptionsiOS)
|
||||
endif(IOS)
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
include(FindPkgConfig)
|
||||
|
||||
if (PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(SWScale swscale)
|
||||
endif()
|
||||
|
||||
find_path(SWScale_INCLUDE_DIR libswscale / swscale.h PATHS $ {SWScale_INCLUDE_DIRS})
|
||||
find_library(SWScale_LIBRARY swscale PATHS $ {SWScale_LIBRARY_DIRS})
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SWScale DEFAULT_MSG SWScale_INCLUDE_DIR SWScale_LIBRARY)
|
||||
|
||||
mark_as_advanced(SWScale_INCLUDE_DIR SWScale_LIBRARY)
|
||||
|
|
@ -752,7 +752,7 @@ static INLINE BOOL WriteColor(BYTE* dst, UINT32 format, UINT32 color)
|
|||
* @return The converted pixel color in dstFormat representation
|
||||
*/
|
||||
static INLINE UINT32 FreeRDPConvertColor(UINT32 color, UINT32 srcFormat,
|
||||
UINT32 dstFormat, const gdiPalette* palette)
|
||||
UINT32 dstFormat, const gdiPalette* palette)
|
||||
{
|
||||
BYTE r = 0;
|
||||
BYTE g = 0;
|
||||
|
@ -862,6 +862,32 @@ FREERDP_API BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat,
|
|||
UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
|
||||
const gdiPalette* palette, UINT32 flags);
|
||||
|
||||
/***
|
||||
*
|
||||
* @param pDstData destination buffer
|
||||
* @param DstFormat destination buffer format
|
||||
* @param nDstStep destination buffer stride (line in bytes) 0 for default
|
||||
* @param nXDst destination buffer offset x
|
||||
* @param nYDst destination buffer offset y
|
||||
* @param nDstWidth width of destination in pixels
|
||||
* @param nDstHeight height of destination in pixels
|
||||
* @param pSrcData source buffer
|
||||
* @param SrcFormat source buffer format
|
||||
* @param nSrcStep source buffer stride (line in bytes) 0 for default
|
||||
* @param nXSrc source buffer x offset in pixels
|
||||
* @param nYSrc source buffer y offset in pixels
|
||||
* @param nSrcWidth width of source in pixels
|
||||
* @param nSrcHeight height of source in pixels
|
||||
*
|
||||
* @return TRUE if success, FALSE otherwise
|
||||
*/
|
||||
FREERDP_API BOOL freerdp_image_scale(BYTE* pDstData, DWORD DstFormat,
|
||||
UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
|
||||
UINT32 nDstWidth, UINT32 nDstHeight,
|
||||
const BYTE* pSrcData, DWORD SrcFormat,
|
||||
UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
|
||||
UINT32 nSrcWidth, UINT32 nSrcHeight);
|
||||
|
||||
/***
|
||||
*
|
||||
* @param pDstData destionation buffer
|
||||
|
|
|
@ -79,6 +79,28 @@ macro (freerdp_definition_add)
|
|||
set (LIBFREERDP_DEFINITIONS ${LIBFREERDP_DEFINITIONS} PARENT_SCOPE)
|
||||
endmacro()
|
||||
|
||||
if (WITH_SWSCALE)
|
||||
find_package(SWScale REQUIRED)
|
||||
endif(WITH_SWSCALE)
|
||||
if (WITH_CAIRO)
|
||||
find_package(Cairo REQUIRED)
|
||||
endif(WITH_CAIRO)
|
||||
|
||||
if (SWScale_FOUND)
|
||||
add_definitions(-DSWSCALE_FOUND=1)
|
||||
include_directories(${SWScale_INCLUDE_DIR})
|
||||
freerdp_library_add(${SWScale_LIBRARY})
|
||||
else(SWScale_FOUND)
|
||||
|
||||
if (CAIRO_FOUND)
|
||||
add_definitions(-DCAIRO_FOUND=1)
|
||||
include_directories(${CAIRO_INCLUDE_DIR})
|
||||
freerdp_library_add(${CAIRO_LIBRARY})
|
||||
else(CAIRO_FOUND)
|
||||
message(WARNING "neigter swscale nor libcairo detected, compiling without image scaling support!")
|
||||
endif(CAIRO_FOUND)
|
||||
endif(SWScale_FOUND)
|
||||
|
||||
set(${MODULE_PREFIX}_SUBMODULES
|
||||
utils
|
||||
common
|
||||
|
|
|
@ -33,6 +33,14 @@
|
|||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/primitives.h>
|
||||
|
||||
#if defined(CAIRO_FOUND)
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#if defined(SWSCALE_FOUND)
|
||||
#include <libswscale/swscale.h>
|
||||
#endif
|
||||
|
||||
#define TAG FREERDP_TAG("color")
|
||||
|
||||
BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height, const BYTE* data)
|
||||
|
@ -570,3 +578,109 @@ BOOL freerdp_image_fill(BYTE* pDstData, DWORD DstFormat,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(SWSCALE_FOUND)
|
||||
static int av_format_for_buffer(UINT32 format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case PIXEL_FORMAT_ARGB32:
|
||||
return AV_PIX_FMT_BGRA;
|
||||
|
||||
case PIXEL_FORMAT_XRGB32:
|
||||
return AV_PIX_FMT_BGR0;
|
||||
|
||||
case PIXEL_FORMAT_BGRA32:
|
||||
return AV_PIX_FMT_RGBA;
|
||||
|
||||
case PIXEL_FORMAT_BGRX32:
|
||||
return AV_PIX_FMT_RGB0;
|
||||
|
||||
default:
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL freerdp_image_scale(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep,
|
||||
UINT32 nXDst, UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight,
|
||||
const BYTE* pSrcData, DWORD SrcFormat, UINT32 nSrcStep,
|
||||
UINT32 nXSrc, UINT32 nYSrc, UINT32 nSrcWidth, UINT32 nSrcHeight)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
const BYTE* src = &pSrcData[nXSrc * 4 + nYSrc * nSrcStep];
|
||||
BYTE* dst = &pDstData[nXDst * 4 + nYDst * nDstStep];
|
||||
#if defined(SWSCALE_FOUND)
|
||||
{
|
||||
int res;
|
||||
struct SwsContext* resize;
|
||||
int srcFormat = av_format_for_buffer(SrcFormat);
|
||||
int dstFormat = av_format_for_buffer(DstFormat);
|
||||
const int srcStep[1] = { nSrcStep };
|
||||
const int dstStep[1] = { nDstStep };
|
||||
|
||||
if ((srcFormat == AV_PIX_FMT_NONE) || (dstFormat == AV_PIX_FMT_NONE))
|
||||
return FALSE;
|
||||
|
||||
resize = sws_getContext(nSrcWidth + nXSrc, nSrcHeight + nYSrc, srcFormat,
|
||||
nDstWidth + nXDst, nDstHeight + nYDst, dstFormat,
|
||||
SWS_BICUBIC, NULL, NULL, NULL);
|
||||
|
||||
if (!resize)
|
||||
goto fail;
|
||||
|
||||
res = sws_scale(resize, &pSrcData, srcStep, 0, nSrcHeight + nYSrc, &pDstData, dstStep);
|
||||
rc = (res == (nDstHeight + nYDst));
|
||||
fail:
|
||||
sws_freeContext(resize);
|
||||
}
|
||||
#elif defined(CAIRO_FOUND)
|
||||
{
|
||||
const double sx = (double)nDstWidth / (double)nSrcWidth;
|
||||
const double sy = (double)nDstHeight / (double)nSrcHeight;
|
||||
cairo_t* cairo_context;
|
||||
cairo_surface_t* csrc, *cdst;
|
||||
|
||||
if ((nSrcWidth > INT_MAX) || (nSrcHeight > INT_MAX) || (nSrcStep > INT_MAX))
|
||||
return FALSE;
|
||||
|
||||
if ((nDstWidth > INT_MAX) || (nDstHeight > INT_MAX) || (nDstStep > INT_MAX))
|
||||
return FALSE;
|
||||
|
||||
csrc = cairo_image_surface_create_for_data((void*)src,
|
||||
CAIRO_FORMAT_ARGB32, (int)nSrcWidth, (int)nSrcHeight, (int)nSrcStep);
|
||||
cdst = cairo_image_surface_create_for_data(dst,
|
||||
CAIRO_FORMAT_ARGB32, (int)nDstWidth, (int)nDstHeight, (int)nDstStep);
|
||||
|
||||
if (!csrc || !cdst)
|
||||
goto fail;
|
||||
|
||||
cairo_context = cairo_create(cdst);
|
||||
|
||||
if (!cairo_context)
|
||||
goto fail2;
|
||||
|
||||
cairo_scale(cairo_context, sx, sy);
|
||||
cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_set_source_surface(cairo_context, csrc, 0, 0);
|
||||
cairo_paint(cairo_context);
|
||||
rc = TRUE;
|
||||
fail2:
|
||||
cairo_destroy(cairo_context);
|
||||
fail:
|
||||
cairo_surface_destroy(csrc);
|
||||
cairo_surface_destroy(cdst);
|
||||
}
|
||||
#else
|
||||
|
||||
if ((nDstWidth == nSrcWidth) && (nDstHeight == nSrcHeight))
|
||||
{
|
||||
return freerdp_image_copy(pDstData, DstFormat, nDstStep, nXDst, nYDst, nDstWidth, nDstHeight,
|
||||
pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc,
|
||||
NULL, FREERDP_FLIP_NONE);
|
||||
}
|
||||
|
||||
WLog_WARN(TAG, "SmartScaling requested but compiled without libcairo support!");
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue