mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
[codec,curso] add option do dump cursor images
* dump raw data and converted image to build binary directory when run
This commit is contained in:
parent
4506a912e5
commit
018ce108eb
@ -1,5 +1,11 @@
|
||||
# codec
|
||||
|
||||
option(WITH_CURSOR_DUMP "Dump mouse cursor data to binary directory" OFF)
|
||||
if(WITH_CURSOR_DUMP)
|
||||
add_compile_definitions(WITH_CURSOR_DUMP)
|
||||
add_compile_definitions(CURSOR_DUMP_DIR="${CMAKE_CURRENT_BINARY_DIR}")
|
||||
endif()
|
||||
|
||||
set(CODEC_SRCS
|
||||
bulk.c
|
||||
bulk.h
|
||||
|
@ -43,6 +43,205 @@
|
||||
|
||||
#define TAG FREERDP_TAG("color")
|
||||
|
||||
static BOOL freerdp_image_copy_from_pointer_data_int(
|
||||
BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
|
||||
UINT32 nWidth, UINT32 nHeight, const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
|
||||
const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp,
|
||||
const gdiPalette* WINPR_RESTRICT palette);
|
||||
|
||||
#if defined(WITH_CURSOR_DUMP)
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/image.h>
|
||||
static char* get_dump_name(char* prefix, size_t len)
|
||||
{
|
||||
static uint64_t count = 0;
|
||||
_snprintf(prefix, len, "cursor_dump_%08" PRIx64, count++);
|
||||
|
||||
return GetCombinedPath(CURSOR_DUMP_DIR, prefix);
|
||||
}
|
||||
|
||||
static void dump_binary_data(FILE* fp, const uint8_t* data, size_t len)
|
||||
{
|
||||
if (len > 0)
|
||||
(void)fprintf(fp, "0x%02" PRIx8, data[0]);
|
||||
for (size_t x = 1; x < len; x++)
|
||||
{
|
||||
(void)fprintf(fp, ", 0x%02" PRIx8, data[x]);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_uint_data(FILE* fp, const uint32_t* data, size_t len)
|
||||
{
|
||||
if (len > 0)
|
||||
(void)fprintf(fp, "0x%08" PRIx32, data[0]);
|
||||
for (size_t x = 1; x < len; x++)
|
||||
{
|
||||
(void)fprintf(fp, ", 0x%08" PRIx32, data[x]);
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_write_header(const char* path, const char* prefix)
|
||||
{
|
||||
char* header = NULL;
|
||||
size_t headerlen = 0;
|
||||
winpr_asprintf(&header, &headerlen, "%s.h", path);
|
||||
if (!header)
|
||||
return;
|
||||
FILE* fp = fopen(header, "w");
|
||||
free(header);
|
||||
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
(void)fprintf(fp, "/* FreeRDP cursor dump to use for unit tests\n");
|
||||
(void)fprintf(fp, " * this file was auto generated by %s\n", __func__);
|
||||
(void)fprintf(fp, " * do not modify manually\n");
|
||||
(void)fprintf(fp, " */\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "#pragma once\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "#include <freerdp/codec/color.h>\n");
|
||||
(void)fprintf(fp, "#include <freerdp/graphics.h>\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "extern const gdiPalette %s_palette;\n", prefix);
|
||||
(void)fprintf(fp, "extern const rdpPointer %s_pointer;\n", prefix);
|
||||
(void)fprintf(fp, "extern const uint8_t %s_image_bgra32[];\n", prefix);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
static void dump_write_c_file(const char* path, const char* prefix, UINT32 nXDst, UINT32 nYDst,
|
||||
UINT32 nWidth, UINT32 nHeight, const BYTE* WINPR_RESTRICT xorMask,
|
||||
UINT32 xorMaskLength, const BYTE* WINPR_RESTRICT andMask,
|
||||
UINT32 andMaskLength, UINT32 xorBpp, const gdiPalette* palette,
|
||||
const uint8_t* bmp)
|
||||
{
|
||||
const uint32_t format = PIXEL_FORMAT_BGRA32;
|
||||
const uint32_t bpp = FreeRDPGetBytesPerPixel(format);
|
||||
const uint32_t step = nWidth * bpp;
|
||||
|
||||
char* header = NULL;
|
||||
size_t headerlen = 0;
|
||||
winpr_asprintf(&header, &headerlen, "%s.c", path);
|
||||
if (!header)
|
||||
return;
|
||||
FILE* fp = fopen(header, "w");
|
||||
free(header);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
(void)fprintf(fp, "/* FreeRDP cursor dump to use for unit tests\n");
|
||||
(void)fprintf(fp, " * this file was auto generated by %s\n", __func__);
|
||||
(void)fprintf(fp, " * do not modify manually\n");
|
||||
(void)fprintf(fp, " */\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "#include \"%s.h\"\n", prefix);
|
||||
(void)fprintf(fp, "\n");
|
||||
|
||||
(void)fprintf(fp, "static const uint8_t andmask[] = {\n");
|
||||
dump_binary_data(fp, andMask, andMaskLength);
|
||||
(void)fprintf(fp, "};\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
|
||||
(void)fprintf(fp, "static const uint8_t xormask[] = {\n");
|
||||
dump_binary_data(fp, xorMask, xorMaskLength);
|
||||
(void)fprintf(fp, "};\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "const gdiPalette %s_palette = {\n", prefix);
|
||||
if (palette)
|
||||
{
|
||||
(void)fprintf(fp, ".format=%" PRIu32 ",", palette->format);
|
||||
(void)fprintf(fp, ".palette={");
|
||||
dump_uint_data(fp, palette->palette, ARRAYSIZE(palette->palette));
|
||||
(void)fprintf(fp, "}\n");
|
||||
}
|
||||
else
|
||||
(void)fprintf(fp, "0");
|
||||
|
||||
(void)fprintf(fp, "};\n");
|
||||
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "const rdpPointer %s_pointer = {\n", prefix);
|
||||
(void)fprintf(fp, ".size = 0,\n");
|
||||
(void)fprintf(fp, ".New = NULL,\n");
|
||||
(void)fprintf(fp, ".Free = NULL,\n");
|
||||
(void)fprintf(fp, ".Set = NULL,\n");
|
||||
(void)fprintf(fp, ".SetNull = NULL,\n");
|
||||
(void)fprintf(fp, ".SetDefault = NULL,\n");
|
||||
(void)fprintf(fp, ".SetPosition = NULL,\n");
|
||||
(void)fprintf(fp, ".paddingA = {0},\n");
|
||||
(void)fprintf(fp, ".xPos = %" PRIu32 ",\n", nXDst);
|
||||
(void)fprintf(fp, ".yPos = %" PRIu32 ",\n", nYDst);
|
||||
(void)fprintf(fp, ".width = %" PRIu32 ",\n", nWidth);
|
||||
(void)fprintf(fp, ".height = %" PRIu32 ",\n", nHeight);
|
||||
(void)fprintf(fp, ".xorBpp = %" PRIu32 ",\n", xorBpp);
|
||||
(void)fprintf(fp, ".lengthAndMask = ARRAYSIZE(andmask),\n");
|
||||
(void)fprintf(fp, ".lengthXorMask = ARRAYSIZE(xormask),\n");
|
||||
(void)fprintf(fp, ".xorMaskData = xormask,\n");
|
||||
(void)fprintf(fp, ".andMaskData = andmask,\n");
|
||||
(void)fprintf(fp, ".paddingB = {0}\n");
|
||||
(void)fprintf(fp, "};\n");
|
||||
(void)fprintf(fp, "\n");
|
||||
(void)fprintf(fp, "const uint8_t %s_image_bgra32[]={\n", prefix);
|
||||
dump_binary_data(fp, bmp, step * nHeight);
|
||||
(void)fprintf(fp, "};\n");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
wImage* img = winpr_image_new();
|
||||
if (img)
|
||||
{
|
||||
img->data = WINPR_CAST_CONST_PTR_AWAY(bmp, BYTE*);
|
||||
img->bitsPerPixel = 32;
|
||||
img->bytesPerPixel = 4;
|
||||
img->height = nHeight;
|
||||
img->width = nWidth;
|
||||
img->scanline = step;
|
||||
img->type = WINPR_IMAGE_PNG;
|
||||
char* imgname = NULL;
|
||||
size_t imgnamesize = 0;
|
||||
winpr_asprintf(&imgname, &imgnamesize, "%s.png", path);
|
||||
if (imgname)
|
||||
winpr_image_write(img, imgname);
|
||||
free(imgname);
|
||||
winpr_image_free(img, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief dump a mouse cursor raw data and resulting image.
|
||||
*
|
||||
* The whole data is dumped into current binary directory as .c and .h files ready to use
|
||||
* as unit test. The image data is also stored as png
|
||||
*/
|
||||
static void dump_pointer_data(UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
|
||||
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
|
||||
const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength,
|
||||
UINT32 xorBpp, const gdiPalette* palette)
|
||||
{
|
||||
const uint32_t format = PIXEL_FORMAT_BGRA32;
|
||||
const uint32_t bpp = FreeRDPGetBytesPerPixel(format);
|
||||
const uint32_t step = nWidth * bpp;
|
||||
BYTE* bmp = calloc(step * 2, nHeight);
|
||||
char prefix[64] = { 0 };
|
||||
char* path = get_dump_name(prefix, sizeof(prefix));
|
||||
|
||||
if (!bmp || !path)
|
||||
goto fail;
|
||||
|
||||
if (!freerdp_image_copy_from_pointer_data_int(bmp, format, step, 0, 0, nWidth, nHeight, xorMask,
|
||||
xorMaskLength, andMask, andMaskLength, xorBpp,
|
||||
palette))
|
||||
goto fail;
|
||||
|
||||
dump_write_header(path, prefix);
|
||||
dump_write_c_file(path, prefix, nXDst, nYDst, nWidth, nHeight, xorMask, xorMaskLength, andMask,
|
||||
andMaskLength, xorBpp, palette, bmp);
|
||||
|
||||
fail:
|
||||
free(bmp);
|
||||
free(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height, const BYTE* WINPR_RESTRICT data)
|
||||
{
|
||||
/*
|
||||
@ -520,12 +719,11 @@ static BOOL freerdp_image_copy_from_pointer_data_xbpp(
|
||||
* http://msdn.microsoft.com/en-us/library/windows/hardware/ff556138/
|
||||
*/
|
||||
|
||||
BOOL freerdp_image_copy_from_pointer_data(BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat,
|
||||
UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
|
||||
UINT32 nWidth, UINT32 nHeight,
|
||||
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
|
||||
const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength,
|
||||
UINT32 xorBpp, const gdiPalette* WINPR_RESTRICT palette)
|
||||
BOOL freerdp_image_copy_from_pointer_data_int(
|
||||
BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
|
||||
UINT32 nWidth, UINT32 nHeight, const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
|
||||
const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp,
|
||||
const gdiPalette* WINPR_RESTRICT palette)
|
||||
{
|
||||
UINT32 dstBitsPerPixel = 0;
|
||||
UINT32 dstBytesPerPixel = 0;
|
||||
@ -563,6 +761,22 @@ BOOL freerdp_image_copy_from_pointer_data(BYTE* WINPR_RESTRICT pDstData, UINT32
|
||||
}
|
||||
}
|
||||
|
||||
BOOL freerdp_image_copy_from_pointer_data(BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat,
|
||||
UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
|
||||
UINT32 nWidth, UINT32 nHeight,
|
||||
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
|
||||
const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength,
|
||||
UINT32 xorBpp, const gdiPalette* WINPR_RESTRICT palette)
|
||||
{
|
||||
#if defined(WITH_CURSOR_DUMP)
|
||||
dump_pointer_data(nXDst, nYDst, nWidth, nHeight, xorMask, xorMaskLength, andMask, andMaskLength,
|
||||
xorBpp, palette);
|
||||
#endif
|
||||
return freerdp_image_copy_from_pointer_data_int(pDstData, DstFormat, nDstStep, nXDst, nYDst,
|
||||
nWidth, nHeight, xorMask, xorMaskLength,
|
||||
andMask, andMaskLength, xorBpp, palette);
|
||||
}
|
||||
|
||||
static INLINE BOOL overlapping(const BYTE* pDstData, UINT32 nYDst, UINT32 nDstStep,
|
||||
const BYTE* pSrcData, UINT32 nYSrc, UINT32 nSrcStep, UINT32 nHeight)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user