22#include <freerdp/config.h>
30#include <freerdp/log.h>
31#include <freerdp/freerdp.h>
32#include <freerdp/primitives.h>
34#if defined(WITH_CAIRO)
38#if defined(WITH_SWSCALE)
39#include <libswscale/swscale.h>
44#define TAG FREERDP_TAG("color")
46static BOOL freerdp_image_copy_from_pointer_data_int(
47 BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
48 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
49 const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp,
50 const gdiPalette* WINPR_RESTRICT palette);
52#if defined(WITH_CURSOR_DUMP)
53#include <winpr/path.h>
54#include <winpr/image.h>
55static char* get_dump_name(
char* prefix,
size_t len)
57 static uint64_t count = 0;
58 _snprintf(prefix, len,
"cursor_dump_%08" PRIx64, count++);
60 return GetCombinedPath(CURSOR_DUMP_DIR, prefix);
63static void dump_binary_data(FILE* fp,
const uint8_t* data,
size_t len)
66 (void)fprintf(fp,
"0x%02" PRIx8, data[0]);
67 for (
size_t x = 1; x < len; x++)
69 (void)fprintf(fp,
", 0x%02" PRIx8, data[x]);
73static void dump_uint_data(FILE* fp,
const uint32_t* data,
size_t len)
76 (void)fprintf(fp,
"0x%08" PRIx32, data[0]);
77 for (
size_t x = 1; x < len; x++)
79 (void)fprintf(fp,
", 0x%08" PRIx32, data[x]);
83static void dump_write_header(
const char* path,
const char* prefix)
87 winpr_asprintf(&header, &headerlen,
"%s.h", path);
90 FILE* fp = fopen(header,
"w");
96 (void)fprintf(fp,
"/* FreeRDP cursor dump to use for unit tests\n");
97 (void)fprintf(fp,
" * this file was auto generated by %s\n", __func__);
98 (void)fprintf(fp,
" * do not modify manually\n");
99 (void)fprintf(fp,
" */\n");
100 (void)fprintf(fp,
"\n");
101 (void)fprintf(fp,
"#pragma once\n");
102 (void)fprintf(fp,
"\n");
103 (void)fprintf(fp,
"#include <freerdp/codec/color.h>\n");
104 (void)fprintf(fp,
"#include <freerdp/graphics.h>\n");
105 (void)fprintf(fp,
"\n");
106 (void)fprintf(fp,
"extern const gdiPalette %s_palette;\n", prefix);
107 (void)fprintf(fp,
"extern const rdpPointer %s_pointer;\n", prefix);
108 (void)fprintf(fp,
"extern const uint8_t %s_image_bgra32[];\n", prefix);
112static void dump_write_c_file(
const char* path,
const char* prefix, UINT32 nXDst, UINT32 nYDst,
113 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT xorMask,
114 UINT32 xorMaskLength,
const BYTE* WINPR_RESTRICT andMask,
115 UINT32 andMaskLength, UINT32 xorBpp,
const gdiPalette* palette,
118 const uint32_t format = PIXEL_FORMAT_BGRA32;
119 const uint32_t bpp = FreeRDPGetBytesPerPixel(format);
120 const uint32_t step = nWidth * bpp;
123 size_t headerlen = 0;
124 winpr_asprintf(&header, &headerlen,
"%s.c", path);
127 FILE* fp = fopen(header,
"w");
132 (void)fprintf(fp,
"/* FreeRDP cursor dump to use for unit tests\n");
133 (void)fprintf(fp,
" * this file was auto generated by %s\n", __func__);
134 (void)fprintf(fp,
" * do not modify manually\n");
135 (void)fprintf(fp,
" */\n");
136 (void)fprintf(fp,
"\n");
137 (void)fprintf(fp,
"#include \"%s.h\"\n", prefix);
138 (void)fprintf(fp,
"\n");
140 (void)fprintf(fp,
"static const uint8_t andmask[] = {\n");
141 dump_binary_data(fp, andMask, andMaskLength);
142 (void)fprintf(fp,
"};\n");
143 (void)fprintf(fp,
"\n");
145 (void)fprintf(fp,
"static const uint8_t xormask[] = {\n");
146 dump_binary_data(fp, xorMask, xorMaskLength);
147 (void)fprintf(fp,
"};\n");
148 (void)fprintf(fp,
"\n");
149 (void)fprintf(fp,
"const gdiPalette %s_palette = {\n", prefix);
152 (void)fprintf(fp,
".format=%" PRIu32
",", palette->format);
153 (void)fprintf(fp,
".palette={");
154 dump_uint_data(fp, palette->palette, ARRAYSIZE(palette->palette));
155 (void)fprintf(fp,
"}\n");
158 (
void)fprintf(fp,
"0");
160 (void)fprintf(fp,
"};\n");
162 (void)fprintf(fp,
"\n");
163 (void)fprintf(fp,
"const rdpPointer %s_pointer = {\n", prefix);
164 (void)fprintf(fp,
".size = 0,\n");
165 (void)fprintf(fp,
".New = NULL,\n");
166 (void)fprintf(fp,
".Free = NULL,\n");
167 (void)fprintf(fp,
".Set = NULL,\n");
168 (void)fprintf(fp,
".SetNull = NULL,\n");
169 (void)fprintf(fp,
".SetDefault = NULL,\n");
170 (void)fprintf(fp,
".SetPosition = NULL,\n");
171 (void)fprintf(fp,
".paddingA = {0},\n");
172 (void)fprintf(fp,
".xPos = %" PRIu32
",\n", nXDst);
173 (void)fprintf(fp,
".yPos = %" PRIu32
",\n", nYDst);
174 (void)fprintf(fp,
".width = %" PRIu32
",\n", nWidth);
175 (void)fprintf(fp,
".height = %" PRIu32
",\n", nHeight);
176 (void)fprintf(fp,
".xorBpp = %" PRIu32
",\n", xorBpp);
177 (void)fprintf(fp,
".lengthAndMask = ARRAYSIZE(andmask),\n");
178 (void)fprintf(fp,
".lengthXorMask = ARRAYSIZE(xormask),\n");
179 (void)fprintf(fp,
".xorMaskData = xormask,\n");
180 (void)fprintf(fp,
".andMaskData = andmask,\n");
181 (void)fprintf(fp,
".paddingB = {0}\n");
182 (void)fprintf(fp,
"};\n");
183 (void)fprintf(fp,
"\n");
184 (void)fprintf(fp,
"const uint8_t %s_image_bgra32[]={\n", prefix);
185 dump_binary_data(fp, bmp, step * nHeight);
186 (void)fprintf(fp,
"};\n");
190 wImage* img = winpr_image_new();
193 img->data = WINPR_CAST_CONST_PTR_AWAY(bmp, BYTE*);
194 img->bitsPerPixel = 32;
195 img->bytesPerPixel = 4;
196 img->height = nHeight;
198 img->scanline = step;
199 img->type = WINPR_IMAGE_PNG;
200 char* imgname = NULL;
201 size_t imgnamesize = 0;
202 winpr_asprintf(&imgname, &imgnamesize,
"%s.png", path);
204 winpr_image_write(img, imgname);
206 winpr_image_free(img, FALSE);
215static void dump_pointer_data(UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
216 const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
217 const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength,
218 UINT32 xorBpp,
const gdiPalette* palette)
220 const uint32_t format = PIXEL_FORMAT_BGRA32;
221 const uint32_t bpp = FreeRDPGetBytesPerPixel(format);
222 const uint32_t step = nWidth * bpp;
223 BYTE* bmp = calloc(step * 2, nHeight);
224 char prefix[64] = { 0 };
225 char* path = get_dump_name(prefix,
sizeof(prefix));
230 if (!freerdp_image_copy_from_pointer_data_int(bmp, format, step, 0, 0, nWidth, nHeight, xorMask,
231 xorMaskLength, andMask, andMaskLength, xorBpp,
235 dump_write_header(path, prefix);
236 dump_write_c_file(path, prefix, nXDst, nYDst, nWidth, nHeight, xorMask, xorMaskLength, andMask,
237 andMaskLength, xorBpp, palette, bmp);
245#if !defined(WITHOUT_FREERDP_3x_DEPRECATED)
246BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height,
const BYTE* WINPR_RESTRICT data)
248 const size_t scanline = (width + 7ull) / 8ull;
249 const size_t required = scanline * height;
250 return freerdp_glyph_convert_ex(width, height, data, required);
254BYTE* freerdp_glyph_convert_ex(UINT32 width, UINT32 height,
const BYTE* WINPR_RESTRICT data,
262 const size_t scanline = (width + 7ull) / 8ull;
263 const size_t required = scanline * height;
267 if ((len == 0) || (width == 0) || (height == 0))
272 BYTE* dstData = (BYTE*)winpr_aligned_malloc(1ull * width * height, 16);
277 ZeroMemory(dstData, 1ULL * width * height);
278 BYTE* dstp = dstData;
280 for (UINT32 y = 0; y < height; y++)
282 const BYTE* srcp = &data[1ull * y * scanline];
284 for (UINT32 x = 0; x < width; x++)
286 if ((*srcp & (0x80 >> (x % 8))) != 0)
291 if (((x + 1) % 8 == 0) && x != 0)
299BOOL freerdp_image_copy_from_monochrome(BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat,
300 UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
301 UINT32 nHeight,
const BYTE* WINPR_RESTRICT pSrcData,
302 UINT32 backColor, UINT32 foreColor,
303 const gdiPalette* WINPR_RESTRICT palette)
305 const UINT32 dstBytesPerPixel = FreeRDPGetBytesPerPixel(DstFormat);
307 if (!pDstData || !pSrcData || !palette)
311 nDstStep = dstBytesPerPixel * nWidth;
313 const UINT32 monoStep = (nWidth + 7) / 8;
315 for (
size_t y = 0; y < nHeight; y++)
317 BYTE* pDstLine = &pDstData[((nYDst + y) * nDstStep)];
318 UINT32 monoBit = 0x80;
319 const BYTE* monoBits = &pSrcData[monoStep * y];
321 for (
size_t x = 0; x < nWidth; x++)
323 BYTE* pDstPixel = &pDstLine[((nXDst + x) * FreeRDPGetBytesPerPixel(DstFormat))];
324 BOOL monoPixel = (*monoBits & monoBit) ? TRUE : FALSE;
326 if (!(monoBit >>= 1))
333 FreeRDPWriteColor_int(pDstPixel, DstFormat, backColor);
335 FreeRDPWriteColor_int(pDstPixel, DstFormat, foreColor);
342static inline UINT32 freerdp_image_inverted_pointer_color(UINT32 x, UINT32 y, UINT32 format)
353 BYTE fill = (x + y) & 1 ? 0x00 : 0xFF;
354 return FreeRDPGetColor(format, fill, fill, fill, 0xFF);
361static void fill_gdi_palette_for_icon(
const BYTE* colorTable, UINT16 cbColorTable,
364 WINPR_ASSERT(palette);
366 palette->format = PIXEL_FORMAT_BGRX32;
367 ZeroMemory(palette->palette,
sizeof(palette->palette));
372 if ((cbColorTable % 4 != 0) || (cbColorTable / 4 > 256))
374 WLog_WARN(TAG,
"weird palette size: %u", cbColorTable);
378 for (UINT16 i = 0; i < cbColorTable / 4; i++)
380 palette->palette[i] = FreeRDPReadColor_int(&colorTable[4ULL * i], palette->format);
384static inline UINT32 div_ceil(UINT32 a, UINT32 b)
386 return (a + (b - 1)) / b;
389static inline UINT32 round_up(UINT32 a, UINT32 b)
391 return b * div_ceil(a, b);
394BOOL freerdp_image_copy_from_icon_data(BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat,
395 UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst, UINT16 nWidth,
396 UINT16 nHeight,
const BYTE* WINPR_RESTRICT bitsColor,
397 UINT16 cbBitsColor,
const BYTE* WINPR_RESTRICT bitsMask,
398 UINT16 cbBitsMask,
const BYTE* WINPR_RESTRICT colorTable,
399 UINT16 cbColorTable, UINT32 bpp)
404 if (!pDstData || !bitsColor)
407 if ((nWidth == 0) || (nHeight == 0))
426 WLog_WARN(TAG,
"1bpp and 4bpp icons are not supported");
430 format = PIXEL_FORMAT_RGB8;
434 format = PIXEL_FORMAT_RGB15;
438 format = PIXEL_FORMAT_RGB24;
442 format = PIXEL_FORMAT_BGRA32;
446 WLog_WARN(TAG,
"invalid icon bpp: %" PRIu32, bpp);
451 if (cbBitsColor < nWidth * nHeight * FreeRDPGetBytesPerPixel(format))
454 "cbBitsColor{%" PRIu32
"} < nWidth{%" PRIu32
"} * nHeight{%" PRIu32
455 "} * bpp{%" PRIu32
"}",
456 cbBitsColor, nWidth, nHeight, FreeRDPGetBytesPerPixel(format));
460 fill_gdi_palette_for_icon(colorTable, cbColorTable, &palette);
461 if (!freerdp_image_copy_no_overlap(pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight,
462 bitsColor, format, 0, 0, 0, &palette, FREERDP_FLIP_VERTICAL))
466 if (FreeRDPColorHasAlpha(DstFormat) && (cbBitsMask > 0))
468 BYTE* dstBuf = pDstData;
469 UINT32 dstBpp = FreeRDPGetBytesPerPixel(DstFormat);
476 const size_t stride = round_up(div_ceil(nWidth, 8), 4);
477 if (cbBitsMask < stride * (nHeight - 1ULL))
480 "cbBitsMask{%" PRIu32
"} < stride{%" PRIuz
"} * (nHeight{%" PRIu32
"} - 1)",
481 cbBitsMask, stride, nHeight);
485 for (UINT32 y = 0; y < nHeight; y++)
487 const BYTE* maskByte = &bitsMask[stride * (nHeight - 1ULL - y)];
490 for (UINT32 x = 0; x < nWidth; x++)
495 BYTE alpha = (*maskByte & nextBit) ? 0x00 : 0xFF;
498 UINT32 color = FreeRDPReadColor_int(dstBuf, DstFormat);
499 FreeRDPSplitColor(color, DstFormat, &r, &g, &b, NULL, &palette);
500 color = FreeRDPGetColor(DstFormat, r, g, b, alpha);
501 FreeRDPWriteColor_int(dstBuf, DstFormat, color);
517static BOOL freerdp_image_copy_from_pointer_data_1bpp(
518 BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
519 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
520 const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp)
530 vFlip = (xorBpp == 1) ? FALSE : TRUE;
531 andStep = (nWidth + 7) / 8;
532 andStep += (andStep % 2);
534 if (!xorMask || (xorMaskLength == 0))
536 if (!andMask || (andMaskLength == 0))
539 xorStep = (nWidth + 7) / 8;
540 xorStep += (xorStep % 2);
542 if (xorStep * nHeight > xorMaskLength)
545 if (andStep * nHeight > andMaskLength)
548 for (UINT32 y = 0; y < nHeight; y++)
550 const BYTE* andBits = NULL;
551 const BYTE* xorBits = NULL;
552 BYTE* pDstPixel = &pDstData[((1ULL * nYDst + y) * nDstStep) +
553 (1ULL * nXDst * FreeRDPGetBytesPerPixel(DstFormat))];
554 xorBit = andBit = 0x80;
558 xorBits = &xorMask[1ULL * xorStep * y];
559 andBits = &andMask[1ULL * andStep * y];
563 xorBits = &xorMask[1ULL * xorStep * (nHeight - y - 1)];
564 andBits = &andMask[1ULL * andStep * (nHeight - y - 1)];
567 for (UINT32 x = 0; x < nWidth; x++)
570 xorPixel = (*xorBits & xorBit) ? 1 : 0;
578 andPixel = (*andBits & andBit) ? 1 : 0;
586 if (!andPixel && !xorPixel)
587 color = FreeRDPGetColor(DstFormat, 0, 0, 0, 0xFF);
588 else if (!andPixel && xorPixel)
589 color = FreeRDPGetColor(DstFormat, 0xFF, 0xFF, 0xFF, 0xFF);
590 else if (andPixel && !xorPixel)
591 color = FreeRDPGetColor(DstFormat, 0, 0, 0, 0);
592 else if (andPixel && xorPixel)
593 color = freerdp_image_inverted_pointer_color(x, y, DstFormat);
595 FreeRDPWriteColor_int(pDstPixel, DstFormat, color);
596 pDstPixel += FreeRDPGetBytesPerPixel(DstFormat);
603static BOOL freerdp_image_copy_from_pointer_data_xbpp(
604 BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
605 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
606 const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp,
607 const gdiPalette* palette)
615 UINT32 dstBitsPerPixel = 0;
616 UINT32 xorBytesPerPixel = 0;
617 dstBitsPerPixel = FreeRDPGetBitsPerPixel(DstFormat);
619 vFlip = (xorBpp == 1) ? FALSE : TRUE;
620 andStep = (nWidth + 7) / 8;
621 andStep += (andStep % 2);
623 if (!xorMask || (xorMaskLength == 0))
626 xorBytesPerPixel = xorBpp >> 3;
627 xorStep = 1ULL * nWidth * xorBytesPerPixel;
628 xorStep += (xorStep % 2);
630 if (xorBpp == 8 && !palette)
632 WLog_ERR(TAG,
"null palette in conversion from %" PRIu32
" bpp to %" PRIu32
" bpp", xorBpp,
637 if (xorStep * nHeight > xorMaskLength)
642 if (andStep * nHeight > andMaskLength)
646 for (UINT32 y = 0; y < nHeight; y++)
648 const BYTE* xorBits = NULL;
649 const BYTE* andBits = NULL;
650 BYTE* pDstPixel = &pDstData[((1ULL * nYDst + y) * nDstStep) +
651 (1ULL * nXDst * FreeRDPGetBytesPerPixel(DstFormat))];
657 andBits = &andMask[andStep * y];
659 xorBits = &xorMask[xorStep * y];
664 andBits = &andMask[1ULL * andStep * (nHeight - y - 1)];
666 xorBits = &xorMask[1ULL * xorStep * (nHeight - y - 1)];
669 for (UINT32 x = 0; x < nWidth; x++)
671 UINT32 pixelFormat = 0;
678 andPixel = (*andBits & andBit) ? 1 : 0;
689 pixelFormat = PIXEL_FORMAT_BGRA32;
690 xorPixel = FreeRDPReadColor_int(xorBits, pixelFormat);
692 else if (xorBpp == 16)
694 pixelFormat = PIXEL_FORMAT_RGB15;
695 xorPixel = FreeRDPReadColor_int(xorBits, pixelFormat);
697 else if (xorBpp == 8)
699 pixelFormat = palette->format;
700 xorPixel = palette->palette[xorBits[0]];
704 pixelFormat = PIXEL_FORMAT_BGR24;
705 xorPixel = FreeRDPReadColor_int(xorBits, pixelFormat);
709 if (xorPixel == 0x00FFFFFFUL)
710 xorPixel |= 0xFF000000UL;
715 xorPixel |= 0xFF000000UL;
718 pixelFormat = PIXEL_FORMAT_ABGR32;
721 xorPixel = FreeRDPConvertColor(xorPixel, pixelFormat, PIXEL_FORMAT_ARGB32, palette);
722 xorBits += xorBytesPerPixel;
726 if (xorPixel == 0xFF000000UL)
727 xorPixel = 0x00000000;
728 else if (xorPixel == 0xFFFFFFFFUL)
729 xorPixel = freerdp_image_inverted_pointer_color(x, y, PIXEL_FORMAT_ARGB32);
732 color = FreeRDPConvertColor(xorPixel, PIXEL_FORMAT_ARGB32, DstFormat, palette);
733 FreeRDPWriteColor_int(pDstPixel, DstFormat, color);
734 pDstPixel += FreeRDPGetBytesPerPixel(DstFormat);
749BOOL freerdp_image_copy_from_pointer_data_int(
750 BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
751 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
752 const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength, UINT32 xorBpp,
753 const gdiPalette* WINPR_RESTRICT palette)
755 UINT32 dstBitsPerPixel = 0;
756 UINT32 dstBytesPerPixel = 0;
757 dstBitsPerPixel = FreeRDPGetBitsPerPixel(DstFormat);
758 dstBytesPerPixel = FreeRDPGetBytesPerPixel(DstFormat);
761 nDstStep = dstBytesPerPixel * nWidth;
763 for (UINT32 y = nYDst; y < nHeight; y++)
765 BYTE* WINPR_RESTRICT pDstLine = &pDstData[y * nDstStep + nXDst * dstBytesPerPixel];
766 memset(pDstLine, 0, 1ull * dstBytesPerPixel * (nWidth - nXDst));
772 return freerdp_image_copy_from_pointer_data_1bpp(
773 pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight, xorMask,
774 xorMaskLength, andMask, andMaskLength, xorBpp);
780 return freerdp_image_copy_from_pointer_data_xbpp(
781 pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight, xorMask,
782 xorMaskLength, andMask, andMaskLength, xorBpp, palette);
785 WLog_ERR(TAG,
"failed to convert from %" PRIu32
" bpp to %" PRIu32
" bpp", xorBpp,
791BOOL freerdp_image_copy_from_pointer_data(BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat,
792 UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
793 UINT32 nWidth, UINT32 nHeight,
794 const BYTE* WINPR_RESTRICT xorMask, UINT32 xorMaskLength,
795 const BYTE* WINPR_RESTRICT andMask, UINT32 andMaskLength,
796 UINT32 xorBpp,
const gdiPalette* WINPR_RESTRICT palette)
798#if defined(WITH_CURSOR_DUMP)
799 dump_pointer_data(nXDst, nYDst, nWidth, nHeight, xorMask, xorMaskLength, andMask, andMaskLength,
802 return freerdp_image_copy_from_pointer_data_int(pDstData, DstFormat, nDstStep, nXDst, nYDst,
803 nWidth, nHeight, xorMask, xorMaskLength,
804 andMask, andMaskLength, xorBpp, palette);
807static inline BOOL overlapping(
const BYTE* pDstData, UINT32 nYDst, UINT32 nDstStep,
808 const BYTE* pSrcData, UINT32 nYSrc, UINT32 nSrcStep, UINT32 nHeight)
810 const uintptr_t src = (uintptr_t)pSrcData;
811 const uintptr_t srcstart = src + 1ULL * nSrcStep * nYSrc;
812 const uintptr_t srcend = srcstart + 1ULL * nSrcStep * nHeight;
813 const uintptr_t dst = (uintptr_t)pDstData;
814 const uintptr_t dststart = dst + 1ULL * nDstStep * nYDst;
815 const uintptr_t dstend = dststart + 1ULL * nDstStep * nHeight;
817 if ((dststart >= srcstart) && (dststart <= srcend))
820 if ((dstend >= srcstart) && (dstend <= srcend))
826static inline BOOL freerdp_image_copy_bgr24_bgrx32(BYTE* WINPR_RESTRICT pDstData, UINT32 nDstStep,
827 UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
829 const BYTE* WINPR_RESTRICT pSrcData,
830 UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
831 int64_t srcVMultiplier, int64_t srcVOffset,
832 int64_t dstVMultiplier, int64_t dstVOffset)
835 const int64_t srcByte = 3;
836 const int64_t dstByte = 4;
838 for (int64_t y = 0; y < nHeight; y++)
840 const BYTE* WINPR_RESTRICT srcLine =
841 &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
842 BYTE* WINPR_RESTRICT dstLine =
843 &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
845 for (int64_t x = 0; x < nWidth; x++)
847 dstLine[(x + nXDst) * dstByte + 0] = srcLine[(x + nXSrc) * srcByte + 0];
848 dstLine[(x + nXDst) * dstByte + 1] = srcLine[(x + nXSrc) * srcByte + 1];
849 dstLine[(x + nXDst) * dstByte + 2] = srcLine[(x + nXSrc) * srcByte + 2];
856static inline BOOL freerdp_image_copy_bgrx32_bgrx32(BYTE* WINPR_RESTRICT pDstData, UINT32 nDstStep,
857 UINT32 nXDst, UINT32 nYDst, UINT32 nWidth,
859 const BYTE* WINPR_RESTRICT pSrcData,
860 UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
861 int64_t srcVMultiplier, int64_t srcVOffset,
862 int64_t dstVMultiplier, int64_t dstVOffset)
865 const int64_t srcByte = 4;
866 const int64_t dstByte = 4;
868 for (int64_t y = 0; y < nHeight; y++)
870 const BYTE* WINPR_RESTRICT srcLine =
871 &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
872 BYTE* WINPR_RESTRICT dstLine =
873 &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
875 for (int64_t x = 0; x < nWidth; x++)
877 dstLine[(x + nXDst) * dstByte + 0] = srcLine[(x + nXSrc) * srcByte + 0];
878 dstLine[(x + nXDst) * dstByte + 1] = srcLine[(x + nXSrc) * srcByte + 1];
879 dstLine[(x + nXDst) * dstByte + 2] = srcLine[(x + nXSrc) * srcByte + 2];
886static inline BOOL freerdp_image_copy_generic(
887 BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
888 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT pSrcData, UINT32 SrcFormat,
889 UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
const gdiPalette* WINPR_RESTRICT palette,
890 int64_t srcVMultiplier, int64_t srcVOffset, int64_t dstVMultiplier, int64_t dstVOffset)
893 const int64_t srcByte = 4;
894 const int64_t dstByte = 4;
896 for (int64_t y = 0; y < nHeight; y++)
898 const BYTE* WINPR_RESTRICT srcLine =
899 &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
900 BYTE* WINPR_RESTRICT dstLine =
901 &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
903 UINT32 color = FreeRDPReadColor_int(&srcLine[nXSrc * srcByte], SrcFormat);
904 UINT32 oldColor = color;
905 UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
906 FreeRDPWriteColorIgnoreAlpha_int(&dstLine[nXDst * dstByte], DstFormat, dstColor);
907 for (int64_t x = 1; x < nWidth; x++)
909 color = FreeRDPReadColor_int(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
910 if (color == oldColor)
912 FreeRDPWriteColorIgnoreAlpha_int(&dstLine[(x + nXDst) * dstByte], DstFormat,
918 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
919 FreeRDPWriteColorIgnoreAlpha_int(&dstLine[(x + nXDst) * dstByte], DstFormat,
928static inline BOOL freerdp_image_copy_no_overlap_dst_alpha(
929 BYTE* WINPR_RESTRICT pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
930 UINT32 nWidth, UINT32 nHeight,
const BYTE* WINPR_RESTRICT pSrcData, DWORD SrcFormat,
931 UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
const gdiPalette* WINPR_RESTRICT palette,
932 int64_t srcVMultiplier, int64_t srcVOffset, int64_t dstVMultiplier, int64_t dstVOffset)
934 WINPR_ASSERT(pDstData);
935 WINPR_ASSERT(pSrcData);
939 case PIXEL_FORMAT_BGR24:
942 case PIXEL_FORMAT_BGRX32:
943 case PIXEL_FORMAT_BGRA32:
944 return freerdp_image_copy_bgr24_bgrx32(
945 pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, pSrcData, nSrcStep,
946 nXSrc, nYSrc, srcVMultiplier, srcVOffset, dstVMultiplier, dstVOffset);
951 case PIXEL_FORMAT_BGRX32:
952 case PIXEL_FORMAT_BGRA32:
955 case PIXEL_FORMAT_BGRX32:
956 case PIXEL_FORMAT_BGRA32:
957 return freerdp_image_copy_bgrx32_bgrx32(
958 pDstData, nDstStep, nXDst, nYDst, nWidth, nHeight, pSrcData, nSrcStep,
959 nXSrc, nYSrc, srcVMultiplier, srcVOffset, dstVMultiplier, dstVOffset);
968 return freerdp_image_copy_generic(pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight,
969 pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc, palette,
970 srcVMultiplier, srcVOffset, dstVMultiplier, dstVOffset);
973BOOL freerdp_image_copy_overlap(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nXDst,
974 UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
const BYTE* pSrcData,
975 DWORD SrcFormat, UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
976 const gdiPalette* WINPR_RESTRICT palette, UINT32 flags)
978 const UINT32 dstByte = FreeRDPGetBytesPerPixel(DstFormat);
979 const UINT32 srcByte = FreeRDPGetBytesPerPixel(SrcFormat);
980 const UINT32 copyDstWidth = nWidth * dstByte;
981 const UINT32 xSrcOffset = nXSrc * srcByte;
982 const UINT32 xDstOffset = nXDst * dstByte;
983 const BOOL vSrcVFlip = (flags & FREERDP_FLIP_VERTICAL) ? TRUE : FALSE;
984 int64_t srcVOffset = 0;
985 int64_t srcVMultiplier = 1;
986 int64_t dstVOffset = 0;
987 int64_t dstVMultiplier = 1;
989 WINPR_ASSERT(overlapping(pDstData, nYDst, nDstStep, pSrcData, nYSrc, nSrcStep, nHeight));
991 if ((nWidth == 0) || (nHeight == 0))
994 if ((nHeight > INT32_MAX) || (nWidth > INT32_MAX))
997 if (!pDstData || !pSrcData)
1001 nDstStep = nWidth * FreeRDPGetBytesPerPixel(DstFormat);
1004 nSrcStep = nWidth * FreeRDPGetBytesPerPixel(SrcFormat);
1008 srcVOffset = (nHeight - 1ll) * nSrcStep;
1009 srcVMultiplier = -1;
1012 if (((flags & FREERDP_KEEP_DST_ALPHA) != 0) && FreeRDPColorHasAlpha(DstFormat))
1014 return freerdp_image_copy_no_overlap_dst_alpha(
1015 pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight, pSrcData, SrcFormat,
1016 nSrcStep, nXSrc, nYSrc, palette, srcVMultiplier, srcVOffset, dstVMultiplier,
1019 else if (FreeRDPAreColorFormatsEqualNoAlpha_int(SrcFormat, DstFormat))
1024 for (int64_t y = 0; y < nHeight; y++)
1026 const BYTE* srcLine =
1027 &pSrcData[(y + nYSrc) * nSrcStep * srcVMultiplier + srcVOffset];
1028 BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
1029 memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
1033 else if (nYDst > nYSrc)
1035 for (int64_t y = nHeight - 1; y >= 0; y--)
1037 const BYTE* srcLine =
1038 &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
1039 BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
1040 memcpy(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
1044 else if (nXSrc > nXDst)
1046 for (int64_t y = 0; y < nHeight; y++)
1048 const BYTE* srcLine =
1049 &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
1050 BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
1051 memmove(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
1055 else if (nXSrc < nXDst)
1057 for (int64_t y = nHeight - 1; y >= 0; y--)
1059 const BYTE* srcLine =
1060 &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
1061 BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
1062 memmove(&dstLine[xDstOffset], &srcLine[xSrcOffset], copyDstWidth);
1072 for (int64_t y = 0; y < nHeight; y++)
1074 const BYTE* srcLine = &pSrcData[srcVMultiplier * (y + nYSrc) * nSrcStep + srcVOffset];
1075 BYTE* dstLine = &pDstData[dstVMultiplier * (y + nYDst) * nDstStep + dstVOffset];
1077 UINT32 color = FreeRDPReadColor_int(&srcLine[1ULL * nXSrc * srcByte], SrcFormat);
1078 UINT32 oldColor = color;
1079 UINT32 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
1080 FreeRDPWriteColor_int(&dstLine[1ULL * nXDst * dstByte], DstFormat, dstColor);
1081 for (int64_t x = 1; x < nWidth; x++)
1083 color = FreeRDPReadColor_int(&srcLine[(x + nXSrc) * srcByte], SrcFormat);
1084 if (color == oldColor)
1086 FreeRDPWriteColor_int(&dstLine[(x + nXDst) * dstByte], DstFormat, dstColor);
1091 dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
1092 FreeRDPWriteColor_int(&dstLine[(x + nXDst) * dstByte], DstFormat, dstColor);
1101BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat, UINT32 nDstStep, UINT32 nXDst,
1102 UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
const BYTE* pSrcData,
1103 DWORD SrcFormat, UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
1104 const gdiPalette* WINPR_RESTRICT palette, UINT32 flags)
1106 if ((nHeight > INT32_MAX) || (nWidth > INT32_MAX))
1109 if (!pDstData || !pSrcData)
1112 if ((nWidth == 0) || (nHeight == 0))
1116 nDstStep = nWidth * FreeRDPGetBytesPerPixel(DstFormat);
1119 nSrcStep = nWidth * FreeRDPGetBytesPerPixel(SrcFormat);
1121 const BOOL ovl = overlapping(pDstData, nYDst, nDstStep, pSrcData, nYSrc, nSrcStep, nHeight);
1123 return freerdp_image_copy_overlap(pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth,
1124 nHeight, pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc,
1126 return freerdp_image_copy_no_overlap(pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth,
1127 nHeight, pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc,
1131BOOL freerdp_image_fill(BYTE* WINPR_RESTRICT pDstData, DWORD DstFormat, UINT32 nDstStep,
1132 UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 color)
1134 if ((nWidth == 0) || (nHeight == 0))
1136 const UINT32 bpp = FreeRDPGetBytesPerPixel(DstFormat);
1137 BYTE* WINPR_RESTRICT pFirstDstLine = NULL;
1138 BYTE* WINPR_RESTRICT pFirstDstLineXOffset = NULL;
1141 nDstStep = (nXDst + nWidth) * FreeRDPGetBytesPerPixel(DstFormat);
1143 pFirstDstLine = &pDstData[1ULL * nYDst * nDstStep];
1144 pFirstDstLineXOffset = &pFirstDstLine[1ULL * nXDst * bpp];
1146 for (
size_t x = 0; x < nWidth; x++)
1148 BYTE* pDst = &pFirstDstLine[(x + nXDst) * bpp];
1149 FreeRDPWriteColor_int(pDst, DstFormat, color);
1152 for (
size_t y = 1; y < nHeight; y++)
1154 BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep + 1ULL * nXDst * bpp];
1155 memcpy(pDstLine, pFirstDstLineXOffset, 1ull * nWidth * bpp);
1161BOOL freerdp_image_fill_ex(BYTE* WINPR_RESTRICT pDstData, DWORD DstFormat, UINT32 nDstStep,
1162 UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight, UINT32 color,
1165 if (FreeRDPColorHasAlpha(DstFormat) && ((flags & FREERDP_IMAGE_FILL_IGNORE_ALPHA) != 0))
1167 const UINT32 bpp = FreeRDPGetBytesPerPixel(DstFormat);
1171 FreeRDPSplitColor(color, DstFormat, &r, &g, &b, NULL, NULL);
1173 for (
size_t y = 0; y < nHeight; y++)
1175 BYTE* WINPR_RESTRICT line = &pDstData[(y + nYDst) * nDstStep];
1177 for (
size_t x = 0; x < nWidth; x++)
1179 BYTE* WINPR_RESTRICT dst = &line[x * bpp];
1180 const UINT32 dcolor = FreeRDPReadColor_int(dst, DstFormat);
1182 FreeRDPSplitColor(dcolor, DstFormat, NULL, NULL, NULL, &a, NULL);
1183 const UINT32 scolor = FreeRDPGetColor(DstFormat, r, g, b, a);
1184 if (!FreeRDPWriteColor_int(dst, DstFormat, scolor))
1190 return freerdp_image_fill(pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight, color);
1193#if defined(WITH_SWSCALE)
1194static enum AVPixelFormat av_format_for_buffer(UINT32 format)
1198 case PIXEL_FORMAT_ARGB32:
1199 return AV_PIX_FMT_BGRA;
1201 case PIXEL_FORMAT_XRGB32:
1202 return AV_PIX_FMT_BGR0;
1204 case PIXEL_FORMAT_BGRA32:
1205 return AV_PIX_FMT_RGBA;
1207 case PIXEL_FORMAT_BGRX32:
1208 return AV_PIX_FMT_RGB0;
1211 return AV_PIX_FMT_NONE;
1216BOOL freerdp_image_scale(BYTE* WINPR_RESTRICT pDstData, DWORD DstFormat, UINT32 nDstStep,
1217 UINT32 nXDst, UINT32 nYDst, UINT32 nDstWidth, UINT32 nDstHeight,
1218 const BYTE* WINPR_RESTRICT pSrcData, DWORD SrcFormat, UINT32 nSrcStep,
1219 UINT32 nXSrc, UINT32 nYSrc, UINT32 nSrcWidth, UINT32 nSrcHeight)
1224 nDstStep = nDstWidth * FreeRDPGetBytesPerPixel(DstFormat);
1227 nSrcStep = nSrcWidth * FreeRDPGetBytesPerPixel(SrcFormat);
1229#if defined(WITH_SWSCALE) || defined(WITH_CAIRO)
1230 const BYTE* src = &pSrcData[nXSrc * FreeRDPGetBytesPerPixel(SrcFormat) + nYSrc * nSrcStep];
1231 BYTE* dst = &pDstData[nXDst * FreeRDPGetBytesPerPixel(DstFormat) + nYDst * nDstStep];
1235 if ((nDstWidth == nSrcWidth) && (nDstHeight == nSrcHeight))
1237 return freerdp_image_copy_no_overlap(pDstData, DstFormat, nDstStep, nXDst, nYDst, nDstWidth,
1238 nDstHeight, pSrcData, SrcFormat, nSrcStep, nXSrc,
1239 nYSrc, NULL, FREERDP_FLIP_NONE);
1242#if defined(WITH_SWSCALE)
1245 struct SwsContext* resize = NULL;
1246 enum AVPixelFormat srcFormat = av_format_for_buffer(SrcFormat);
1247 enum AVPixelFormat dstFormat = av_format_for_buffer(DstFormat);
1248 const int srcStep[1] = { (int)nSrcStep };
1249 const int dstStep[1] = { (int)nDstStep };
1251 if ((srcFormat == AV_PIX_FMT_NONE) || (dstFormat == AV_PIX_FMT_NONE))
1254 resize = sws_getContext((
int)nSrcWidth, (
int)nSrcHeight, srcFormat, (
int)nDstWidth,
1255 (
int)nDstHeight, dstFormat, SWS_BILINEAR, NULL, NULL, NULL);
1260 res = sws_scale(resize, &src, srcStep, 0, (
int)nSrcHeight, &dst, dstStep);
1261 rc = (res == ((int)nDstHeight));
1263 sws_freeContext(resize);
1266#elif defined(WITH_CAIRO)
1268 const double sx = (double)nDstWidth / (
double)nSrcWidth;
1269 const double sy = (double)nDstHeight / (
double)nSrcHeight;
1270 cairo_t* cairo_context;
1271 cairo_surface_t *csrc, *cdst;
1273 if ((nSrcWidth > INT_MAX) || (nSrcHeight > INT_MAX) || (nSrcStep > INT_MAX))
1276 if ((nDstWidth > INT_MAX) || (nDstHeight > INT_MAX) || (nDstStep > INT_MAX))
1279 csrc = cairo_image_surface_create_for_data((
void*)src, CAIRO_FORMAT_ARGB32, (
int)nSrcWidth,
1280 (
int)nSrcHeight, (
int)nSrcStep);
1281 cdst = cairo_image_surface_create_for_data(dst, CAIRO_FORMAT_ARGB32, (
int)nDstWidth,
1282 (
int)nDstHeight, (
int)nDstStep);
1287 cairo_context = cairo_create(cdst);
1292 cairo_scale(cairo_context, sx, sy);
1293 cairo_set_operator(cairo_context, CAIRO_OPERATOR_SOURCE);
1294 cairo_set_source_surface(cairo_context, csrc, 0, 0);
1295 cairo_paint(cairo_context);
1298 cairo_destroy(cairo_context);
1300 cairo_surface_destroy(csrc);
1301 cairo_surface_destroy(cdst);
1305 WLog_WARN(TAG,
"SmartScaling requested but compiled without libcairo support!");
1311DWORD FreeRDPAreColorFormatsEqualNoAlpha(DWORD first, DWORD second)
1313 return FreeRDPAreColorFormatsEqualNoAlpha_int(first, second);
1316const char* FreeRDPGetColorFormatName(UINT32 format)
1324 ENTRY(PIXEL_FORMAT_ARGB32)
1325 ENTRY(PIXEL_FORMAT_XRGB32)
1326 ENTRY(PIXEL_FORMAT_ABGR32)
1327 ENTRY(PIXEL_FORMAT_XBGR32)
1328 ENTRY(PIXEL_FORMAT_BGRA32)
1329 ENTRY(PIXEL_FORMAT_BGRX32)
1330 ENTRY(PIXEL_FORMAT_RGBA32)
1331 ENTRY(PIXEL_FORMAT_RGBX32)
1332 ENTRY(PIXEL_FORMAT_BGRX32_DEPTH30)
1333 ENTRY(PIXEL_FORMAT_RGBX32_DEPTH30)
1334 ENTRY(PIXEL_FORMAT_RGB24)
1335 ENTRY(PIXEL_FORMAT_BGR24)
1336 ENTRY(PIXEL_FORMAT_RGB16)
1337 ENTRY(PIXEL_FORMAT_BGR16)
1338 ENTRY(PIXEL_FORMAT_ARGB15)
1339 ENTRY(PIXEL_FORMAT_RGB15)
1340 ENTRY(PIXEL_FORMAT_ABGR15)
1341 ENTRY(PIXEL_FORMAT_BGR15)
1342 ENTRY(PIXEL_FORMAT_RGB8)
1343 ENTRY(PIXEL_FORMAT_A4)
1344 ENTRY(PIXEL_FORMAT_MONO)
1352uint32_t FreeRDPGetColorFromatFromName(
const char* name)
1355 if (strcmp(name, #x) == 0) \
1361 ENTRY(PIXEL_FORMAT_ARGB32)
1362 ENTRY(PIXEL_FORMAT_XRGB32)
1363 ENTRY(PIXEL_FORMAT_ABGR32)
1364 ENTRY(PIXEL_FORMAT_XBGR32)
1365 ENTRY(PIXEL_FORMAT_BGRA32)
1366 ENTRY(PIXEL_FORMAT_BGRX32)
1367 ENTRY(PIXEL_FORMAT_RGBA32)
1368 ENTRY(PIXEL_FORMAT_RGBX32)
1369 ENTRY(PIXEL_FORMAT_BGRX32_DEPTH30)
1370 ENTRY(PIXEL_FORMAT_RGBX32_DEPTH30)
1371 ENTRY(PIXEL_FORMAT_RGB24)
1372 ENTRY(PIXEL_FORMAT_BGR24)
1373 ENTRY(PIXEL_FORMAT_RGB16)
1374 ENTRY(PIXEL_FORMAT_BGR16)
1375 ENTRY(PIXEL_FORMAT_ARGB15)
1376 ENTRY(PIXEL_FORMAT_RGB15)
1377 ENTRY(PIXEL_FORMAT_ABGR15)
1378 ENTRY(PIXEL_FORMAT_BGR15)
1379 ENTRY(PIXEL_FORMAT_RGB8)
1380 ENTRY(PIXEL_FORMAT_A4)
1381 ENTRY(PIXEL_FORMAT_MONO)
1387void FreeRDPSplitColor(UINT32 color, UINT32 format, BYTE* _r, BYTE* _g, BYTE* _b, BYTE* _a,
1388 const gdiPalette* palette)
1395 case PIXEL_FORMAT_ARGB32:
1397 *_a = (BYTE)(color >> 24);
1400 *_r = (BYTE)(color >> 16);
1403 *_g = (BYTE)(color >> 8);
1410 case PIXEL_FORMAT_XRGB32:
1412 *_r = (BYTE)(color >> 16);
1415 *_g = (BYTE)(color >> 8);
1425 case PIXEL_FORMAT_ABGR32:
1427 *_a = (BYTE)(color >> 24);
1430 *_b = (BYTE)(color >> 16);
1433 *_g = (BYTE)(color >> 8);
1440 case PIXEL_FORMAT_XBGR32:
1442 *_b = (BYTE)(color >> 16);
1445 *_g = (BYTE)(color >> 8);
1455 case PIXEL_FORMAT_RGBA32:
1457 *_r = (BYTE)(color >> 24);
1460 *_g = (BYTE)(color >> 16);
1463 *_b = (BYTE)(color >> 8);
1470 case PIXEL_FORMAT_RGBX32:
1472 *_r = (BYTE)(color >> 24);
1475 *_g = (BYTE)(color >> 16);
1478 *_b = (BYTE)(color >> 8);
1485 case PIXEL_FORMAT_BGRA32:
1487 *_b = (BYTE)(color >> 24);
1490 *_g = (BYTE)(color >> 16);
1493 *_r = (BYTE)(color >> 8);
1500 case PIXEL_FORMAT_BGRX32:
1502 *_b = (BYTE)(color >> 24);
1505 *_g = (BYTE)(color >> 16);
1508 *_r = (BYTE)(color >> 8);
1516 case PIXEL_FORMAT_RGB24:
1518 *_r = (BYTE)(color >> 16);
1521 *_g = (BYTE)(color >> 8);
1531 case PIXEL_FORMAT_BGR24:
1533 *_b = (BYTE)(color >> 16);
1536 *_g = (BYTE)(color >> 8);
1547 case PIXEL_FORMAT_RGB16:
1550 const UINT32 c = (color >> 11) & 0x1F;
1551 const UINT32 val = (c << 3) + c / 4;
1552 *_r = (BYTE)(val > 255 ? 255 : val);
1557 const UINT32 c = (color >> 5) & 0x3F;
1558 const UINT32 val = (c << 2) + c / 4 / 2;
1559 *_g = (BYTE)(val > 255 ? 255 : val);
1564 const UINT32 c = (color)&0x1F;
1565 const UINT32 val = (c << 3) + c / 4;
1566 *_b = (BYTE)(val > 255 ? 255 : val);
1574 case PIXEL_FORMAT_BGR16:
1577 const UINT32 c = (color)&0x1F;
1578 const UINT32 val = (c << 3) + c / 4;
1579 *_r = (BYTE)(val > 255 ? 255 : val);
1584 const UINT32 c = (color >> 5) & 0x3F;
1585 const UINT32 val = (c << 2) + c / 4 / 2;
1586 *_g = (BYTE)(val > 255 ? 255 : val);
1591 const UINT32 c = (color >> 11) & 0x1F;
1592 const UINT32 val = (c << 3) + c / 4;
1593 *_b = (BYTE)(val > 255 ? 255 : val);
1601 case PIXEL_FORMAT_ARGB15:
1604 const UINT32 c = (color >> 10) & 0x1F;
1605 const UINT32 val = (c << 3) + c / 4;
1606 *_r = (BYTE)(val > 255 ? 255 : val);
1611 const UINT32 c = (color >> 5) & 0x1F;
1612 const UINT32 val = (c << 3) + c / 4;
1613 *_g = (BYTE)(val > 255 ? 255 : val);
1618 const UINT32 c = (color)&0x1F;
1619 const UINT32 val = (c << 3) + c / 4;
1620 *_b = (BYTE)(val > 255 ? 255 : val);
1624 *_a = color & 0x8000 ? 0xFF : 0x00;
1628 case PIXEL_FORMAT_ABGR15:
1631 const UINT32 c = (color)&0x1F;
1632 const UINT32 val = (c << 3) + c / 4;
1633 *_r = (BYTE)(val > 255 ? 255 : val);
1638 const UINT32 c = (color >> 5) & 0x1F;
1639 const UINT32 val = (c << 3) + c / 4;
1640 *_g = (BYTE)(val > 255 ? 255 : val);
1645 const UINT32 c = (color >> 10) & 0x1F;
1646 const UINT32 val = (c << 3) + c / 4;
1647 *_b = (BYTE)(val > 255 ? 255 : val);
1651 *_a = color & 0x8000 ? 0xFF : 0x00;
1656 case PIXEL_FORMAT_RGB15:
1659 const UINT32 c = (color >> 10) & 0x1F;
1660 const UINT32 val = (c << 3) + c / 4;
1661 *_r = (BYTE)(val > 255 ? 255 : val);
1666 const UINT32 c = (color >> 5) & 0x1F;
1667 const UINT32 val = (c << 3) + c / 4;
1668 *_g = (BYTE)(val > 255 ? 255 : val);
1673 const UINT32 c = (color)&0x1F;
1674 const UINT32 val = (c << 3) + c / 4;
1675 *_b = (BYTE)(val > 255 ? 255 : val);
1683 case PIXEL_FORMAT_BGR15:
1686 const UINT32 c = (color)&0x1F;
1687 const UINT32 val = (c << 3) + c / 4;
1688 *_r = (BYTE)(val > 255 ? 255 : val);
1693 const UINT32 c = (color >> 5) & 0x1F;
1694 const UINT32 val = (c << 3) + c / 4;
1695 *_g = (BYTE)(val > 255 ? 255 : val);
1700 const UINT32 c = (color >> 10) & 0x1F;
1701 const UINT32 val = (c << 3) + c / 4;
1702 *_b = (BYTE)(val > 255 ? 255 : val);
1711 case PIXEL_FORMAT_RGB8:
1714 tmp = palette->palette[color];
1715 FreeRDPSplitColor(tmp, palette->format, _r, _g, _b, _a, NULL);
1735 case PIXEL_FORMAT_MONO:
1737 *_r = (color) ? 0xFF : 0x00;
1740 *_g = (color) ? 0xFF : 0x00;
1743 *_b = (color) ? 0xFF : 0x00;
1746 *_a = (color) ? 0xFF : 0x00;
1751 case PIXEL_FORMAT_A4:
1765 WLog_ERR(TAG,
"Unsupported format %s", FreeRDPGetColorFormatName(format));
1770BOOL FreeRDPWriteColorIgnoreAlpha(BYTE* WINPR_RESTRICT dst, UINT32 format, UINT32 color)
1772 return FreeRDPWriteColorIgnoreAlpha_int(dst, format, color);
1775BOOL FreeRDPWriteColor(BYTE* WINPR_RESTRICT dst, UINT32 format, UINT32 color)
1777 return FreeRDPWriteColor_int(dst, format, color);
1780UINT32 FreeRDPReadColor(
const BYTE* WINPR_RESTRICT src, UINT32 format)
1782 return FreeRDPReadColor_int(src, format);
1785UINT32 FreeRDPGetColor(UINT32 format, BYTE r, BYTE g, BYTE b, BYTE a)
1796 case PIXEL_FORMAT_ARGB32:
1797 return (_a << 24) | (_r << 16) | (_g << 8) | _b;
1799 case PIXEL_FORMAT_XRGB32:
1800 return (_r << 16) | (_g << 8) | _b;
1802 case PIXEL_FORMAT_ABGR32:
1803 return (_a << 24) | (_b << 16) | (_g << 8) | _r;
1805 case PIXEL_FORMAT_XBGR32:
1806 return (_b << 16) | (_g << 8) | _r;
1808 case PIXEL_FORMAT_RGBA32:
1809 return (_r << 24) | (_g << 16) | (_b << 8) | _a;
1811 case PIXEL_FORMAT_RGBX32:
1812 return (_r << 24) | (_g << 16) | (_b << 8) | _a;
1814 case PIXEL_FORMAT_BGRA32:
1815 return (_b << 24) | (_g << 16) | (_r << 8) | _a;
1817 case PIXEL_FORMAT_BGRX32:
1818 return (_b << 24) | (_g << 16) | (_r << 8) | _a;
1820 case PIXEL_FORMAT_RGBX32_DEPTH30:
1822 t = (_r << 22) | (_g << 12) | (_b << 2);
1824 return ((t & 0xff) << 24) | (((t >> 8) & 0xff) << 16) | (((t >> 16) & 0xff) << 8) |
1827 case PIXEL_FORMAT_BGRX32_DEPTH30:
1829 t = (_r << 22) | (_g << 12) | (_b << 2);
1831 return ((t & 0xff) << 24) | (((t >> 8) & 0xff) << 16) | (((t >> 16) & 0xff) << 8) |
1835 case PIXEL_FORMAT_RGB24:
1836 return (_r << 16) | (_g << 8) | _b;
1838 case PIXEL_FORMAT_BGR24:
1839 return (_b << 16) | (_g << 8) | _r;
1842 case PIXEL_FORMAT_RGB16:
1843 return (((_r >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | ((_b >> 3) & 0x1F);
1845 case PIXEL_FORMAT_BGR16:
1846 return (((_b >> 3) & 0x1F) << 11) | (((_g >> 2) & 0x3F) << 5) | ((_r >> 3) & 0x1F);
1848 case PIXEL_FORMAT_ARGB15:
1849 return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((_b >> 3) & 0x1F) |
1850 (_a ? 0x8000 : 0x0000);
1852 case PIXEL_FORMAT_ABGR15:
1853 return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((_r >> 3) & 0x1F) |
1854 (_a ? 0x8000 : 0x0000);
1857 case PIXEL_FORMAT_RGB15:
1858 return (((_r >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((_b >> 3) & 0x1F);
1860 case PIXEL_FORMAT_BGR15:
1861 return (((_b >> 3) & 0x1F) << 10) | (((_g >> 3) & 0x1F) << 5) | ((_r >> 3) & 0x1F);
1864 case PIXEL_FORMAT_RGB8:
1867 case PIXEL_FORMAT_A4:
1870 case PIXEL_FORMAT_MONO:
1872 WLog_ERR(TAG,
"Unsupported format %s", FreeRDPGetColorFormatName(format));
1877BOOL freerdp_image_copy_no_overlap(BYTE* WINPR_RESTRICT pDstData, DWORD DstFormat, UINT32 nDstStep,
1878 UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
1879 const BYTE* WINPR_RESTRICT pSrcData, DWORD SrcFormat,
1880 UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
1881 const gdiPalette* WINPR_RESTRICT palette, UINT32 flags)
1885 prims = primitives_get();
1887 WINPR_ASSERT(!overlapping(pDstData, nYDst, nDstStep, pSrcData, nYSrc, nSrcStep, nHeight));
1888 WINPR_ASSERT(prims);
1890 return prims->
copy_no_overlap(pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight,
1891 pSrcData, SrcFormat, nSrcStep, nXSrc, nYSrc, palette,
1892 flags) == PRIMITIVES_SUCCESS;
fn_copy_no_overlap_t copy_no_overlap