[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:
akallabeth 2025-02-20 11:44:46 +01:00
parent 4506a912e5
commit 018ce108eb
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
2 changed files with 226 additions and 6 deletions

View File

@ -1,5 +1,11 @@
# codec # 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 set(CODEC_SRCS
bulk.c bulk.c
bulk.h bulk.h

View File

@ -43,6 +43,205 @@
#define TAG FREERDP_TAG("color") #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) 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/ * http://msdn.microsoft.com/en-us/library/windows/hardware/ff556138/
*/ */
BOOL freerdp_image_copy_from_pointer_data(BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, BOOL freerdp_image_copy_from_pointer_data_int(
UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst, BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
UINT32 nWidth, UINT32 nHeight, UINT32 nWidth, UINT32 nHeight, const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength, const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp,
const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, const gdiPalette* WINPR_RESTRICT palette)
UINT32 xorBpp, const gdiPalette* WINPR_RESTRICT palette)
{ {
UINT32 dstBitsPerPixel = 0; UINT32 dstBitsPerPixel = 0;
UINT32 dstBytesPerPixel = 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, static INLINE BOOL overlapping(const BYTE* pDstData, UINT32 nYDst, UINT32 nDstStep,
const BYTE* pSrcData, UINT32 nYSrc, UINT32 nSrcStep, UINT32 nHeight) const BYTE* pSrcData, UINT32 nYSrc, UINT32 nSrcStep, UINT32 nHeight)
{ {