From 65d7e17d4cc9ab363cad58129fd04c9ea71326f9 Mon Sep 17 00:00:00 2001 From: Martin Haimberger Date: Wed, 15 Jan 2014 05:52:48 -0800 Subject: [PATCH 01/18] improved WLog childlogger use per default now a WLOG_LEVEL_INHERIT level so the loglevel is taken from the first parent which has another level set. --- winpr/include/winpr/wlog.h | 9 +-- winpr/libwinpr/utils/wlog/BinaryAppender.c | 3 - winpr/libwinpr/utils/wlog/ConsoleAppender.c | 3 - winpr/libwinpr/utils/wlog/FileAppender.c | 3 - winpr/libwinpr/utils/wlog/wlog.c | 71 +++++++++++---------- 5 files changed, 43 insertions(+), 46 deletions(-) diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 87b79c8a2..eda5e60a3 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -48,6 +48,7 @@ typedef struct _wLogAppender wLogAppender; #define WLOG_ERROR 4 #define WLOG_FATAL 5 #define WLOG_OFF 6 +#define WLOG_LEVEL_INHERIT 0xFFFF /** * Log Message @@ -198,7 +199,7 @@ struct _wLog WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...); #define WLog_Print(_log, _log_level, _fmt, ...) \ - if (_log_level >= _log->Level) { \ + if (_log_level >= WLog_GetLogLevel(_log)) { \ wLogMessage _log_message; \ _log_message.Type = WLOG_MESSAGE_TEXT; \ _log_message.Level = _log_level; \ @@ -210,7 +211,7 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...); } #define WLog_Data(_log, _log_level, ...) \ - if (_log_level >= _log->Level) { \ + if (_log_level >= WLog_GetLogLevel(_log)) { \ wLogMessage _log_message; \ _log_message.Type = WLOG_MESSAGE_DATA; \ _log_message.Level = _log_level; \ @@ -222,7 +223,7 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...); } #define WLog_Image(_log, _log_level, ...) \ - if (_log_level >= _log->Level) { \ + if (_log_level >= WLog_GetLogLevel(_log)) { \ wLogMessage _log_message; \ _log_message.Type = WLOG_MESSAGE_IMAGE; \ _log_message.Level = _log_level; \ @@ -234,7 +235,7 @@ WINPR_API void WLog_PrintMessage(wLog* log, wLogMessage* message, ...); } #define WLog_Packet(_log, _log_level, ...) \ - if (_log_level >= _log->Level) { \ + if (_log_level >= WLog_GetLogLevel(_log)) { \ wLogMessage _log_message; \ _log_message.Type = WLOG_MESSAGE_PACKET; \ _log_message.Level = _log_level; \ diff --git a/winpr/libwinpr/utils/wlog/BinaryAppender.c b/winpr/libwinpr/utils/wlog/BinaryAppender.c index f77b99dbb..f0bd1ba5f 100644 --- a/winpr/libwinpr/utils/wlog/BinaryAppender.c +++ b/winpr/libwinpr/utils/wlog/BinaryAppender.c @@ -122,9 +122,6 @@ int WLog_BinaryAppender_WriteMessage(wLog* log, wLogBinaryAppender* appender, wL int FunctionNameLength; int TextStringLength; - if (message->Level > log->Level) - return 0; - fp = appender->FileDescriptor; if (!fp) diff --git a/winpr/libwinpr/utils/wlog/ConsoleAppender.c b/winpr/libwinpr/utils/wlog/ConsoleAppender.c index 0b4375a3e..c9ed6bc66 100644 --- a/winpr/libwinpr/utils/wlog/ConsoleAppender.c +++ b/winpr/libwinpr/utils/wlog/ConsoleAppender.c @@ -68,9 +68,6 @@ int WLog_ConsoleAppender_WriteMessage(wLog* log, wLogConsoleAppender* appender, FILE* fp; char prefix[WLOG_MAX_PREFIX_SIZE]; - if (message->Level < log->Level) - return 0; - fp = (appender->outputStream == WLOG_CONSOLE_STDERR) ? stderr : stdout; message->PrefixString = prefix; diff --git a/winpr/libwinpr/utils/wlog/FileAppender.c b/winpr/libwinpr/utils/wlog/FileAppender.c index 5acb75256..8904310cb 100644 --- a/winpr/libwinpr/utils/wlog/FileAppender.c +++ b/winpr/libwinpr/utils/wlog/FileAppender.c @@ -117,9 +117,6 @@ int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, wLogMe FILE* fp; char prefix[WLOG_MAX_PREFIX_SIZE]; - if (message->Level > log->Level) - return 0; - fp = appender->FileDescriptor; if (!fp) diff --git a/winpr/libwinpr/utils/wlog/wlog.c b/winpr/libwinpr/utils/wlog/wlog.c index 6df27a5ea..d6a2a9ac4 100644 --- a/winpr/libwinpr/utils/wlog/wlog.c +++ b/winpr/libwinpr/utils/wlog/wlog.c @@ -216,14 +216,20 @@ void WLog_PrintMessage(wLog* log, wLogMessage* message, ...) DWORD WLog_GetLogLevel(wLog* log) { - return log->Level; + if (log->Level == WLOG_LEVEL_INHERIT) { + return WLog_GetLogLevel(log->Parent); + } else { + return log->Level; + } } void WLog_SetLogLevel(wLog* log, DWORD logLevel) { - if (logLevel > WLOG_OFF) - logLevel = WLOG_OFF; + if ((logLevel > WLOG_OFF) && (logLevel != WLOG_LEVEL_INHERIT)) + { + logLevel = WLOG_OFF; + } log->Level = logLevel; } @@ -276,7 +282,7 @@ wLog* WLog_New(LPCSTR name , wLog* rootLogger) log->Name = _strdup(name); WLog_ParseName(log, name); - log->Parent = NULL; + log->Parent = rootLogger; log->ChildrenCount = 0; log->ChildrenSize = 16; @@ -285,41 +291,40 @@ wLog* WLog_New(LPCSTR name , wLog* rootLogger) log->Appender = NULL; if (rootLogger) { - log->Level = rootLogger->Level; + log->Level = WLOG_LEVEL_INHERIT; } else { log->Level = WLOG_WARN; - } + nSize = GetEnvironmentVariableA("WLOG_LEVEL", NULL, 0); - nSize = GetEnvironmentVariableA("WLOG_LEVEL", NULL, 0); - - if (nSize) - { - env = (LPSTR) malloc(nSize); - nSize = GetEnvironmentVariableA("WLOG_LEVEL", env, nSize); - - if (env) + if (nSize) { - if (_stricmp(env, "TRACE") == 0) - log->Level = WLOG_TRACE; - else if (_stricmp(env, "DEBUG") == 0) - log->Level = WLOG_DEBUG; - else if (_stricmp(env, "INFO") == 0) - log->Level = WLOG_INFO; - else if (_stricmp(env, "WARN") == 0) - log->Level = WLOG_WARN; - else if (_stricmp(env, "ERROR") == 0) - log->Level = WLOG_ERROR; - else if (_stricmp(env, "FATAL") == 0) - log->Level = WLOG_FATAL; - else if (_stricmp(env, "OFF") == 0) - log->Level = WLOG_OFF; - else if (_strnicmp(env, "0x", 2) == 0) - { - /* TODO: read custom hex value */ - } + env = (LPSTR) malloc(nSize); + nSize = GetEnvironmentVariableA("WLOG_LEVEL", env, nSize); - free(env); + if (env) + { + if (_stricmp(env, "TRACE") == 0) + log->Level = WLOG_TRACE; + else if (_stricmp(env, "DEBUG") == 0) + log->Level = WLOG_DEBUG; + else if (_stricmp(env, "INFO") == 0) + log->Level = WLOG_INFO; + else if (_stricmp(env, "WARN") == 0) + log->Level = WLOG_WARN; + else if (_stricmp(env, "ERROR") == 0) + log->Level = WLOG_ERROR; + else if (_stricmp(env, "FATAL") == 0) + log->Level = WLOG_FATAL; + else if (_stricmp(env, "OFF") == 0) + log->Level = WLOG_OFF; + else if (_strnicmp(env, "0x", 2) == 0) + { + /* TODO: read custom hex value */ + } + + free(env); + } } } } From 24ee27354099b2e275b802f9ccc86ac10d1fd75a Mon Sep 17 00:00:00 2001 From: Martin Haimberger Date: Wed, 15 Jan 2014 06:15:18 -0800 Subject: [PATCH 02/18] fixed compiler warning --- winpr/include/winpr/cmdline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/winpr/include/winpr/cmdline.h b/winpr/include/winpr/cmdline.h index e38f8fec4..6c5f605db 100644 --- a/winpr/include/winpr/cmdline.h +++ b/winpr/include/winpr/cmdline.h @@ -93,7 +93,7 @@ struct _COMMAND_LINE_ARGUMENT_A LPCSTR Name; DWORD Flags; LPCSTR Format; - LPSTR Default; + LPCSTR Default; LPSTR Value; LONG Index; LPCSTR Alias; From d1e75efb8c8822716aaf41acd3a947d0641e9b21 Mon Sep 17 00:00:00 2001 From: Hardening Date: Fri, 31 Jan 2014 17:02:50 +0100 Subject: [PATCH 03/18] Add a region component This patch adds a pixman_region like component in the utility components of FreeRdp. The data structure is exactly the same as in pixman_region but the implementation differs as we need fewer methods. The patch contains the corresponding unitary tests. --- .gitignore | 3 + include/freerdp/utils/region.h | 127 ++++ libfreerdp/utils/CMakeLists.txt | 5 + libfreerdp/utils/region.c | 753 ++++++++++++++++++++++ libfreerdp/utils/test/CMakeLists.txt | 48 ++ libfreerdp/utils/test/TestFreeRDPRegion.c | 662 +++++++++++++++++++ 6 files changed, 1598 insertions(+) create mode 100644 include/freerdp/utils/region.h create mode 100644 libfreerdp/utils/region.c create mode 100644 libfreerdp/utils/test/CMakeLists.txt create mode 100644 libfreerdp/utils/test/TestFreeRDPRegion.c diff --git a/.gitignore b/.gitignore index 5e3941bc4..2f614c39f 100755 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,9 @@ server/Sample/sfreerdp-server server/X11/xfreerdp-server xcode +# Generated test code +libfreerdp/utils/test/TestFreeRDPUtils.c + # Other *~ *.dir diff --git a/include/freerdp/utils/region.h b/include/freerdp/utils/region.h new file mode 100644 index 000000000..eff10debb --- /dev/null +++ b/include/freerdp/utils/region.h @@ -0,0 +1,127 @@ +/** + * Copyright © 2014 Thincast Technologies GmbH + * Copyright © 2014 Hardening + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __REGION_H___ +#define __REGION_H___ + +#include + +struct _REGION16_DATA; +typedef struct _REGION16_DATA REGION16_DATA; + +/** + * @brief + */ +struct _REGION16 { + RECTANGLE_16 extents; + REGION16_DATA *data; +}; +typedef struct _REGION16 REGION16; + +/** computes if two rectangles intersect + * @param r1 first rectangle + * @param r2 second rectangle + * @return if the two rectangles intersect + */ +BOOL rectangles_intersects(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2); + +/** computes the intersection of two rectangles + * @param r1 first rectangle + * @param r2 second rectangle + * @param dst resulting intersection + * @return if the two rectangles intersect + */ +BOOL rectangles_intersection(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2, RECTANGLE_16 *dst); + +/** initialize a region16 + * @param region the region to initialise + */ +void region16_init(REGION16 *region); + +/** @return the number of rectangles of this region16 */ +int region16_n_rects(const REGION16 *region); + +/** returns a pointer on rectangles and the number of rectangles in this region. + * nbRect can be set to NULL if not interested by the numnber of rectangles. + * @param region the input region + * @param nbRects a pointer that will be filled with the number of rectangles + * @return a pointer on the rectangles + */ +const RECTANGLE_16 *region16_rects(const REGION16 *region, int *nbRects); + +/** @return the extents rectangle of this region */ +const RECTANGLE_16 *region16_extents(const REGION16 *region); + +/** returns if the region is empty + * @param region + * @return if the region is empty + */ +BOOL region16_is_empty(const REGION16 *region); + +/** clears the region, the region is resetted to a (0,0,0,0) region + * @param region + */ +void region16_clear(REGION16 *region); + +/** dumps the region on stderr + * @param region the region to dump + */ +void region16_print(const REGION16 *region); + +/** copies the region to another region + * @param dst destination region + * @param src source region + * @return if the operation was successful (false meaning out-of-memory) + */ +BOOL region16_copy(REGION16 *dst, const REGION16 *src); + +/** adds a rectangle in src and stores the resulting region in dst + * @param dst destination region + * @param src source region + * @param rect the rectangle to add + * @return if the operation was successful (false meaning out-of-memory) + */ +BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect); + +/** returns if a rectangle intersects the region + * @param src the region + * @param arg2 the rectangle + * @return if region and rectangle intersect + */ +BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2); + +/** computes the intersection between a region and a rectangle + * @param dst destination region + * @param src the source region + * @param arg2 the rectangle that intersects + * @return if the operation was successful (false meaning out-of-memory) + */ +BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *arg2); + +/** release internal data associated with this region + * @param region the region to release + */ +void region16_uninit(REGION16 *region); + + +#endif /* __REGION_H___ */ diff --git a/libfreerdp/utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt index 10b767cd3..1f4aa0453 100644 --- a/libfreerdp/utils/CMakeLists.txt +++ b/libfreerdp/utils/CMakeLists.txt @@ -26,6 +26,7 @@ set(${MODULE_PREFIX}_SRCS pcap.c profiler.c rail.c + region.c signal.c stopwatch.c svc_plugin.c @@ -68,3 +69,7 @@ else() endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/libfreerdp/utils/region.c b/libfreerdp/utils/region.c new file mode 100644 index 000000000..235b2d094 --- /dev/null +++ b/libfreerdp/utils/region.c @@ -0,0 +1,753 @@ +/** + * Copyright © 2014 Thincast Technologies GmbH + * Copyright © 2014 Hardening + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +/* + * The functions in this file implement the Region abstraction largely inspired from + * pixman library. The following comment is taken from the pixman code. + * + * A Region is simply a set of disjoint(non-overlapping) rectangles, plus an + * "extent" rectangle which is the smallest single rectangle that contains all + * the non-overlapping rectangles. + * + * A Region is implemented as a "y-x-banded" array of rectangles. This array + * imposes two degrees of order. First, all rectangles are sorted by top side + * y coordinate first (y1), and then by left side x coordinate (x1). + * + * Furthermore, the rectangles are grouped into "bands". Each rectangle in a + * band has the same top y coordinate (y1), and each has the same bottom y + * coordinate (y2). Thus all rectangles in a band differ only in their left + * and right side (x1 and x2). Bands are implicit in the array of rectangles: + * there is no separate list of band start pointers. + * + * The y-x band representation does not minimize rectangles. In particular, + * if a rectangle vertically crosses a band (the rectangle has scanlines in + * the y1 to y2 area spanned by the band), then the rectangle may be broken + * down into two or more smaller rectangles stacked one atop the other. + * + * ----------- ----------- + * | | | | band 0 + * | | -------- ----------- -------- + * | | | | in y-x banded | | | | band 1 + * | | | | form is | | | | + * ----------- | | ----------- -------- + * | | | | band 2 + * -------- -------- + * + * An added constraint on the rectangles is that they must cover as much + * horizontal area as possible: no two rectangles within a band are allowed + * to touch. + * + * Whenever possible, bands will be merged together to cover a greater vertical + * distance (and thus reduce the number of rectangles). Two bands can be merged + * only if the bottom of one touches the top of the other and they have + * rectangles in the same places (of the same width, of course). + */ + +struct _REGION16_DATA { + long size; + long nbRects; +}; +typedef struct _REGION16_DATA REGION16_DATA; + +static REGION16_DATA empty_region = { 0, 0 }; + +void region16_init(REGION16 *region) +{ + assert(region); + + ZeroMemory(region, sizeof(REGION16)); + region->data = &empty_region; +} + +int region16_n_rects(const REGION16 *region) +{ + assert(region); + assert(region->data); + + return region->data->nbRects; +} + +const RECTANGLE_16 *region16_rects(const REGION16 *region, int *nbRects) +{ + REGION16_DATA *data; + + assert(region); + assert(region->data); + + data = region->data; + if (!data) + { + if (nbRects) + *nbRects = 0; + return 0; + } + + *nbRects = data->nbRects; + return (RECTANGLE_16 *)(data + 1); +} + +static inline RECTANGLE_16 *region16_rects_noconst(REGION16 *region) +{ + REGION16_DATA *data; + + data = region->data; + if (!data) + return 0; + + return (RECTANGLE_16 *)(data + 1); +} + +const RECTANGLE_16 *region16_extents(const REGION16 *region) +{ + return ®ion->extents; +} + +static RECTANGLE_16 *region16_extents_noconst(REGION16 *region) +{ + return ®ion->extents; +} + +BOOL region16_is_empty(const REGION16 *region) +{ + assert(region); + assert(region->data); + + return (region->data->nbRects == 0); +} + +BOOL rectangles_intersects(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2) +{ + RECTANGLE_16 tmp; + return rectangles_intersection(r1, r2, &tmp); +} + +BOOL rectangles_intersection(const RECTANGLE_16 *r1, const RECTANGLE_16 *r2, + RECTANGLE_16 *dst) +{ + dst->left = MAX(r1->left, r2->left); + dst->right = MIN(r1->right, r2->right); + dst->top = MAX(r1->top, r2->top); + dst->bottom = MIN(r1->bottom, r2->bottom); + + return (dst->left < dst->right) && (dst->top < dst->bottom); +} + +void region16_clear(REGION16 *region) +{ + assert(region); + assert(region->data); + + if (region->data->size) + free(region->data); + region->data = &empty_region; + + ZeroMemory(®ion->extents, sizeof(region->extents)); +} + +static inline REGION16_DATA *allocateRegion(long nbItems) +{ + long allocSize = sizeof(REGION16_DATA) + nbItems * sizeof(RECTANGLE_16); + REGION16_DATA *ret = (REGION16_DATA *)malloc(allocSize); + if (!ret) + return ret; + + ret->size = allocSize; + ret->nbRects = nbItems; + return ret; +} + +BOOL region16_copy(REGION16 *dst, const REGION16 *src) +{ + assert(dst); + assert(dst->data); + assert(src); + assert(src->data); + + if (dst == src) + return TRUE; + + dst->extents = src->extents; + if (dst->data->size) + free(dst->data); + + if (!src->data->size) + { + dst->data = &empty_region; + } + else + { + dst->data = allocateRegion(src->data->nbRects); + if (!dst->data) + return FALSE; + + memcpy(dst->data, src->data, src->data->size); + } + return TRUE; +} + +void region16_print(const REGION16 *region) +{ + const RECTANGLE_16 *rects; + int nbRects, i; + int currentBandY = -1; + + rects = region16_rects(region, &nbRects); + fprintf(stderr, "nrects=%d", nbRects); + + for (i = 0; i < nbRects; i++, rects++) + { + if (rects->top != currentBandY) + { + currentBandY = rects->top; + fprintf(stderr, "\nband %d: ", currentBandY); + } + + fprintf(stderr, "(%d,%d-%d,%d)", rects->left, rects->top, rects->right, rects->bottom); + } + + fprintf(stderr, "\n"); +} + +void region16_copy_band_with_union(RECTANGLE_16 *dst, + const RECTANGLE_16 *src, const RECTANGLE_16 *end, + UINT16 newTop, UINT16 newBottom, + const RECTANGLE_16 *unionRect, + int *dstCounter, + const RECTANGLE_16 **srcPtr, RECTANGLE_16 **dstPtr) +{ + UINT16 refY = src->top; + const RECTANGLE_16 *startOverlap, *endOverlap; + + /* merges a band with the given rect + * Input: + * unionRect + * | | + * | | + * ==============+===============+================================ + * |Item1| |Item2| |Item3| |Item4| |Item5| Band + * ==============+===============+================================ + * before | overlap | after + * + * Resulting band: + * +-----+ +----------------------+ +-----+ + * |Item1| | Item2 | |Item3| + * +-----+ +----------------------+ +-----+ + * + * We first copy as-is items that are before Item2, the first overlapping + * item. + * Then we find the last one that overlap unionRect to agregate Item2, Item3 + * and Item4 to create Item2. + * Finally Item5 is copied as Item3. + * + * When no unionRect is provided, we skip the two first steps to just copy items + */ + + if (unionRect) + { + /* items before unionRect */ + while ((src < end) && (src->top == refY) && (src->right < unionRect->left)) + { + dst->top = newTop; + dst->bottom = newBottom; + dst->right = src->right; + dst->left = src->left; + + src++; dst++; *dstCounter += 1; + } + + /* treat items overlapping with unionRect */ + startOverlap = unionRect; + endOverlap = unionRect; + + if ((src < end) && (src->top == refY) && (src->left < unionRect->left)) + startOverlap = src; + + while ((src < end) && (src->top == refY) && (src->right < unionRect->right)) + { + src++; + } + + if ((src < end) && (src->top == refY) && (src->left < unionRect->right)) + { + endOverlap = src; + src++; + } + + dst->bottom = newBottom; + dst->top = newTop; + dst->left = startOverlap->left; + dst->right = endOverlap->right; + dst++; *dstCounter += 1; + } + + /* treat remaining items on the same band */ + while ((src < end) && (src->top == refY)) + { + dst->top = newTop; + dst->bottom = newBottom; + dst->right = src->right; + dst->left = src->left; + + src++; dst++; *dstCounter += 1; + } + + if(srcPtr) + *srcPtr = src; + *dstPtr = dst; +} + +static RECTANGLE_16 *next_band(RECTANGLE_16 *band1, RECTANGLE_16 *endPtr, int *nbItems) +{ + UINT16 refY = band1->top; + + *nbItems = 0; + while((band1 < endPtr) && (band1->top == refY)) { + band1++; + *nbItems += 1; + } + return band1; +} + +static BOOL band_match(const RECTANGLE_16 *band1, const RECTANGLE_16 *band2, RECTANGLE_16 *endPtr) +{ + int refBand2 = band2->top; + const RECTANGLE_16 *band2Start = band2; + + while ((band1 < band2Start) && (band2 < endPtr) && (band2->top == refBand2)) { + if ((band1->left != band2->left) || (band1->right != band2->right)) + return FALSE; + + band1++; + band2++; + } + + if (band1 != band2Start) + return FALSE; + + return (band2 == endPtr) || (band2->top != refBand2); +} + +/** compute if the rectangle is fully included in the band + * @param band a pointer on the beginning of the band + * @param endPtr end of the region + * @param rect the rectangle to test + * @return if rect is fully included in an item of the band + */ +static BOOL rectangle_contained_in_band(const RECTANGLE_16 *band, const RECTANGLE_16 *endPtr, + const RECTANGLE_16 *rect) +{ + UINT16 refY = band->top; + + if ((band->top > rect->top) || (rect->bottom > band->bottom)) + return FALSE; + + /* note: as the band is sorted from left to right, once we've seen an item + * that is after rect->left we're sure that the result is False. + */ + while( (band < endPtr) && (band->top == refY) && (band->left <= rect->left)) + { + if (rect->right <= band->right) + return TRUE; + + band++; + } + return FALSE; +} + +BOOL region16_simplify_bands(REGION16 *region) +{ + /** Simplify bands consecutive band that touch and have the same items + * + * ==================== ==================== + * | 1 | | 2 | | | | | + * ==================== | | | | + * | 1 | | 2 | ====> | 1 | | 2 | + * ==================== | | | | + * | 1 | | 2 | | | | | + * ==================== ==================== + * + */ + RECTANGLE_16 *band1, *band2, *endPtr, *endBand, *tmp; + int nbRects, finalNbRects; + int bandItems, toMove; + + finalNbRects = nbRects = region16_n_rects(region); + if (nbRects < 2) + return TRUE; + + band1 = region16_rects_noconst(region); + endPtr = band1 + nbRects; + + do { + band2 = next_band(band1, endPtr, &bandItems); + if (band2 == endPtr) + break; + + if ((band1->bottom == band2->top) && band_match(band1, band2, endPtr)) + { + /* adjust the bottom of band1 items */ + tmp = band1; + while (tmp < band2) + { + tmp->bottom = band2->bottom; + tmp++; + } + + /* override band2, we don't move band1 pointer as the band after band2 + * may be merged too */ + endBand = band2 + bandItems; + toMove = (endPtr - endBand) * sizeof(RECTANGLE_16); + if (toMove) + memmove(band2, endBand, toMove); + finalNbRects -= bandItems; + endPtr -= bandItems; + } else { + band1 = band2; + } + } while(TRUE); + + if (finalNbRects != nbRects) + { + int allocSize = sizeof(REGION16_DATA) + finalNbRects * sizeof(RECTANGLE_16); + region->data = realloc(region->data, allocSize); + region->data->nbRects = finalNbRects; + region->data->size = allocSize; + } + return TRUE; +} + + +BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect) +{ + const RECTANGLE_16 *srcExtents; + RECTANGLE_16 *dstExtents; + const RECTANGLE_16 *currentBand, *endSrcRect, *nextBand; + REGION16_DATA *newItems; + RECTANGLE_16 *dstRect; + int usedRects, srcNbRects; + UINT16 topInterBand; + + assert(src); + assert(src->data); + assert(dst); + + srcExtents = region16_extents(src); + dstExtents = region16_extents_noconst(dst); + + if (!region16_n_rects(src)) + { + /* source is empty, so the union is rect */ + dst->extents = *rect; + dst->data = allocateRegion(1); + if (!dst->data) + return FALSE; + + dstRect = region16_rects_noconst(dst); + *dstRect = *rect; + return TRUE; + } + + newItems = allocateRegion((1 + region16_n_rects(src)) * 2); + if (!newItems) + return FALSE; + + dstRect = (RECTANGLE_16 *)(newItems + 1); + usedRects = 0; + + /* adds the piece of rect that is on the top of src */ + if (rect->top < srcExtents->top) + { + dstRect->top = rect->top; + dstRect->left = rect->left; + dstRect->right = rect->right; + dstRect->bottom = srcExtents->top; + + usedRects++; + dstRect++; + } + + /* treat possibly overlapping region */ + currentBand = region16_rects(src, &srcNbRects); + endSrcRect = currentBand + srcNbRects; + + while (currentBand < endSrcRect) + { + if ((currentBand->bottom <= rect->top) || (rect->bottom <= currentBand->top) || + rectangle_contained_in_band(currentBand, endSrcRect, rect) + ) + { + /* no overlap between rect and the band, rect is totally below or totally above + * the current band, or rect is already covered by an item of the band. + * let's copy all the rectangles from this band + +----+ + | | rect (case 1) + +----+ + + ================= + band of srcRect + ================= + +----+ + | | rect (case 2) + +----+ + */ + region16_copy_band_with_union(dstRect, + currentBand, endSrcRect, + currentBand->top, currentBand->bottom, + NULL, &usedRects, + &nextBand, &dstRect); + topInterBand = rect->top; + } + else + { + + /* rect overlaps the band: + | | | | + ====^=================| |==| |=========================== band + | top split | | | | + v | 1 | | 2 | + ^ | | | | +----+ +----+ + | merge zone | | | | | | | 4 | + v +----+ | | | | +----+ + ^ | | | 3 | + | bottom split | | | | + ====v=========================| |==| |=================== + | | | | + + possible cases: + 1) no top split, merge zone then a bottom split. The band will be splitted + in two + 2) not band split, only the merge zone, band merged with rect but not splitted + 3) a top split, the merge zone and no bottom split. The band will be split + in two + 4) a top split, the merge zone and also a bottom split. The band will be + splitted in 3, but the coalesce algorithm may merge the created bands + */ + UINT16 mergeTop = currentBand->top; + UINT16 mergeBottom = currentBand->bottom; + + /* test if we need a top split, case 3 and 4 */ + if (rect->top > currentBand->top) + { + region16_copy_band_with_union(dstRect, + currentBand, endSrcRect, + currentBand->top, rect->top, + NULL, &usedRects, + &nextBand, &dstRect); + mergeTop = rect->top; + } + + /* do the merge zone (all cases ) */ + if (rect->bottom < currentBand->bottom) + mergeBottom = rect->bottom; + region16_copy_band_with_union(dstRect, + currentBand, endSrcRect, + mergeTop, mergeBottom, + rect, &usedRects, + &nextBand, &dstRect); + + /* test if we need a bottom split, case 1 and 4 */ + if (rect->bottom < currentBand->bottom) + { + region16_copy_band_with_union(dstRect, + currentBand, endSrcRect, + mergeBottom, currentBand->bottom, + NULL, &usedRects, + &nextBand, &dstRect); + } + topInterBand = currentBand->bottom; + } + + /* test if a piece of rect should be inserted as a new band between + * the current band and the next one. band n and n+1 shouldn't touch. + * + * ============================================================== + * band n + * +------+ +------+ + * ===========| rect |====================| |=============== + * | | +------+ | | + * +------+ | rect | | rect | + * +------+ | | + * =======================================| |================ + * +------+ band n+1 + * =============================================================== + * + */ + if ((nextBand < endSrcRect) && (nextBand->top != currentBand->bottom) && + (rect->bottom > currentBand->bottom) && (rect->top < nextBand->top)) + { + dstRect->right = rect->right; + dstRect->left = rect->left; + dstRect->top = topInterBand; + dstRect->bottom = MIN(nextBand->top, rect->bottom); + dstRect++; usedRects++; + } + + currentBand = nextBand; + } + + /* adds the piece of rect that is below src */ + if (srcExtents->bottom < rect->bottom) + { + dstRect->top = MAX(srcExtents->bottom, rect->top); + dstRect->left = rect->left; + dstRect->right = rect->right; + dstRect->bottom = rect->bottom; + + usedRects++; + dstRect++; + } + + if ((src == dst) && (src->data->size)) + free(src->data); + + dstExtents->top = MIN(rect->top, srcExtents->top); + dstExtents->left = MIN(rect->left, srcExtents->left); + dstExtents->bottom = MAX(rect->bottom, srcExtents->bottom); + dstExtents->right = MAX(rect->right, srcExtents->right); + + newItems->size = sizeof(REGION16_DATA) + usedRects * sizeof(RECTANGLE_16); + dst->data = realloc(newItems, newItems->size); + if (!dst->data) + { + free(newItems); + return FALSE; + } + dst->data->nbRects = usedRects; + + return region16_simplify_bands(dst); +} + + +BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) { + assert(src); + assert(src->data); + + const RECTANGLE_16 *rect, *endPtr, *srcExtents;; + int nbRects; + + rect = region16_rects(src, &nbRects); + if (!nbRects) + return FALSE; + + srcExtents = region16_extents(src); + if (nbRects == 1) + return rectangles_intersects(srcExtents, arg2); + + if (!rectangles_intersects(srcExtents, arg2)) + return FALSE; + + endPtr = rect + nbRects; + + for (endPtr = rect + nbRects; rect < endPtr; rect++) + { + if (rectangles_intersects(rect, arg2)) + return TRUE; + } + + return FALSE; +} + +BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect) +{ + assert(src); + assert(src->data); + + REGION16_DATA *newItems; + const RECTANGLE_16 *srcPtr, *endPtr, *srcExtents; + RECTANGLE_16 *dstPtr; + int nbRects, usedRects; + RECTANGLE_16 common, newExtents; + + srcPtr = region16_rects(src, &nbRects); + if (!nbRects) + { + region16_clear(dst); + return TRUE; + } + + srcExtents = region16_extents(src); + if (nbRects == 1) + { + BOOL intersects = rectangles_intersection(srcExtents, rect, &common); + + region16_clear(dst); + if (intersects) + return region16_union_rect(dst, dst, &common); + return TRUE; + } + + newItems = allocateRegion(nbRects); + if (!newItems) + return FALSE; + dstPtr = (RECTANGLE_16 *)(newItems + 1); + usedRects = 0; + ZeroMemory(&newExtents, sizeof(newExtents)); + + /* accumulate intersecting rectangles, the final region16_simplify_bands() will + * do all the bad job to recreate correct rectangles + */ + for(endPtr = srcPtr + nbRects; srcPtr < endPtr; srcPtr++) + { + if (rectangles_intersection(srcPtr, rect, &common)) + { + *dstPtr = common; + usedRects++; + dstPtr++; + + newExtents.top = MIN(common.top, newExtents.top); + newExtents.left = MIN(common.left, newExtents.left); + newExtents.bottom = MAX(common.bottom, newExtents.bottom); + newExtents.right = MIN(common.right, newExtents.right); + } + } + + newItems->nbRects = usedRects; + newItems->size = sizeof(REGION16_DATA) + usedRects * sizeof(RECTANGLE_16); + + if (dst->data->size) + free(dst->data); + + dst->data = realloc(newItems, newItems->size); + if (!dst->data) + return FALSE; + + dst->extents = newExtents; + return region16_simplify_bands(dst); +} + +void region16_uninit(REGION16 *region) { + assert(region); + assert(region->data); + + if(region->data->size) + free(region->data); + region->data = 0; +} + + + + diff --git a/libfreerdp/utils/test/CMakeLists.txt b/libfreerdp/utils/test/CMakeLists.txt new file mode 100644 index 000000000..7ad20235d --- /dev/null +++ b/libfreerdp/utils/test/CMakeLists.txt @@ -0,0 +1,48 @@ +# FreeRDP: A Remote Desktop Protocol Implementation +# tests for utils cmake build script +# +# Copyright © 2014 Thincast Technologies GmbH +# Copyright © 2014 Hardening +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "TestFreeRDPUtils") +set(MODULE_PREFIX "TEST_FREERDP_UTILS") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestFreeRDPRegion.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-utils) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test") + diff --git a/libfreerdp/utils/test/TestFreeRDPRegion.c b/libfreerdp/utils/test/TestFreeRDPRegion.c new file mode 100644 index 000000000..33dfd6eb4 --- /dev/null +++ b/libfreerdp/utils/test/TestFreeRDPRegion.c @@ -0,0 +1,662 @@ +/** + * Copyright © 2014 Thincast Technologies GmbH + * Copyright © 2014 Hardening + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include + + +static BOOL compareRectangles(const RECTANGLE_16 *src1, const RECTANGLE_16 *src2, int nb) +{ + int i; + for (i = 0; i< nb; i++, src1++, src2++) + { + if (memcmp(src1, src2, sizeof(RECTANGLE_16))) + { + fprintf(stderr, "expecting rect %d (%d,%d-%d,%d) and have (%d,%d-%d,%d)\n", + i, src2->left, src2->top, src2->right, src2->bottom, + src1->left, src1->top, src1->right, src1->bottom + ); + return FALSE; + } + } + return TRUE; +} + + +static int test_basic() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + + /* R1 + R2 ==> disjointed rects */ + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r2 = {150, 301, 250, 401}; + + RECTANGLE_16 r1_r2[] = { + {0, 101, 200, 201}, + {150, 301, 250, 401} + }; + + /* r1 */ + region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out;; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 1 || memcmp(rects, &r1, sizeof(RECTANGLE_16))) + goto out; + + /* r1 + r2 */ + if (!region16_union_rect(®ion, ®ion, &r2)) + goto out;; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2, nbRects)) + goto out; + + + /* clear region */ + region16_clear(®ion); + region16_rects(®ion, &nbRects); + if (nbRects) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_r1_r3() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r3 = {150, 151, 250, 251}; + RECTANGLE_16 r1_r3[] = { + { 0, 101, 200, 151}, + { 0, 151, 250, 201}, + {150, 201, 250, 251} + }; + + region16_init(®ion); + /* + * +=============================================================== + * | + * |+-----+ +-----+ + * || r1 | | | + * || +-+------+ +-----+--------+ + * || | r3 | | | + * |+---+ | ====> +-----+--------+ + * | | | | | + * | +--------+ +--------+ + */ + + /* R1 + R3 */ + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) + goto out; + + + /* R3 + R1 */ + region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r3)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r3, nbRects)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_r9_r10() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + + /* + * +=============================================================== + * | + * | +---+ +---+ + * |+--|r10|-+ +--+---+-+ + * ||r9| | | | | + * || | | | | | + * || | | | =====> | | + * || | | | | | + * || | | | | | + * |+--| |-+ +--+---+-+ + * | +---+ +---+ + */ + RECTANGLE_16 r9 = { 0, 100, 400, 200}; + RECTANGLE_16 r10 = {200, 0, 300, 300}; + RECTANGLE_16 r9_r10[] = { + {200, 0, 300, 100}, + { 0, 100, 400, 200}, + {200, 200, 300, 300}, + }; + + region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r9)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r10)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r9_r10, nbRects)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_r1_r5() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r5 = {150, 121, 300, 131}; + + RECTANGLE_16 r1_r5[] = { + { 0, 101, 200, 121}, + { 0, 121, 300, 131}, + { 0, 131, 200, 201} + }; + + region16_init(®ion); + /* + * +=============================================================== + * | + * |+--------+ +--------+ + * || r1 | | | + * || +--+----+ +--------+----+ + * || | r5 | =====> | | + * || +-------+ +--------+----+ + * || | | | + * |+--------+ +--------+ + * | + * + */ + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r5)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r5, nbRects)) + goto out; + + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + +static int test_r1_r6() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r6 = {150, 121, 170, 131}; + + region16_init(®ion); + /* + * +=============================================================== + * | + * |+--------+ +--------+ + * || r1 | | | + * || +--+ | | | + * || |r6| | =====> | | + * || +--+ | | | + * || | | | + * |+--------+ +--------+ + * | + */ + region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r6)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 1 || !compareRectangles(rects, &r1, nbRects)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_r1_r2_r4() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r2 = {150, 301, 250, 401}; + RECTANGLE_16 r4 = {150, 251, 250, 301}; + RECTANGLE_16 r1_r2_r4[] = { + { 0, 101, 200, 201}, + {150, 251, 250, 401} + }; + + /* + * +=============================================================== + * | + * |+-----+ +-----+ + * || r1 | | | + * || | | | + * || | | | + * |+-----+ ====> +-----+ + * | + * | +--------+ +--------+ + * | | r4 | | | + * | +--------+ | | + * | | r2 | | | + * | | | | | + * | +--------+ +--------+ + * + */ + region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r2)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r4)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 2 || !compareRectangles(rects, r1_r2_r4, nbRects)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_r1_r7_r8() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r7 = {300, 101, 500, 201}; + RECTANGLE_16 r8 = {150, 121, 400, 131}; + + RECTANGLE_16 r1_r7_r8[] = { + { 0, 101, 200, 121}, + {300, 101, 500, 121}, + { 0, 121, 500, 131}, + { 0, 131, 200, 201}, + {300, 131, 500, 201}, + }; + + /* + * +=============================================================== + * | + * |+--------+ +--------+ +--------+ +--------+ + * || r1 | | r7 | | | | | + * || +------------+ | +--------+---+--------+ + * || | r8 | | =====> | | + * || +------------+ | +--------+---+--------+ + * || | | | | | | | + * |+--------+ +--------+ +--------+ +--------+ + * | + */ + region16_init(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r7)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r8)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects)) + goto out; + + region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r8)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r7)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects)) + goto out; + + region16_clear(®ion); + if (!region16_union_rect(®ion, ®ion, &r8)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r7)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, r1_r7_r8, nbRects)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_r1_r2_r3_r4() { + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r2 = {150, 301, 250, 401}; + RECTANGLE_16 r3 = {150, 151, 250, 251}; + RECTANGLE_16 r4 = {150, 251, 250, 301}; + + RECTANGLE_16 r1_r2_r3[] = { + { 0, 101, 200, 151}, + { 0, 151, 250, 201}, + {150, 201, 250, 251}, + {150, 301, 250, 401} + }; + + RECTANGLE_16 r1_r2_r3_r4[] = { + { 0, 101, 200, 151}, + { 0, 151, 250, 201}, + {150, 201, 250, 401} + }; + + region16_init(®ion); + /* + * +=============================================================== + * | + * |+-----+ +-----+ + * || r1 | | | + * || +-+------+ +-----+--------+ + * || | r3 | | | + * |+---+ | ====> +-----+--------+ + * | | | | | + * | +--------+ +--------+ + * | +--------+ +--------+ + * | | r2 | | | + * | | | | | + * | +--------+ +--------+ + */ + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r2)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 4 || !compareRectangles(rects, r1_r2_r3, 4)) + goto out; + + /* + * +=============================================================== + * | + * |+-----+ +-----+ + * || | | | + * |+-----+--------+ +-----+--------+ + * || | ==> | | + * |+-----+--------+ +-----+--------+ + * | | | | | + * | +--------+ | | + * | | + r4 | | | + * | +--------+ | | + * | | | | | + * | | | | | + * | +--------+ +--------+ + */ + if (!region16_union_rect(®ion, ®ion, &r4)) + goto out; + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3_r4, 3)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + + +static int test_from_weston() +{ + /* + * 0: 0,0 -> 640,32 (w=640 h=32) + * 1: 236,169 -> 268,201 (w=32 h=32) + * 2: 246,258 -> 278,290 (w=32 h=32) + */ + REGION16 region; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + RECTANGLE_16 r1 = { 0, 0, 640, 32}; + RECTANGLE_16 r2 = {236, 169, 268, 201}; + RECTANGLE_16 r3 = {246, 258, 278, 290}; + + RECTANGLE_16 r1_r2_r3[] = { + { 0, 0, 640, 32}, + {236, 169, 268, 201}, + {246, 258, 278, 290} + }; + + region16_init(®ion); + /* + * +=============================================================== + * |+-------------------------------------------------------------+ + * || r1 | + * |+-------------------------------------------------------------+ + * | + * | +---------------+ + * | | r2 | + * | +---------------+ + * | + * | +---------------+ + * | | r3 | + * | +---------------+ + * | + */ + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r2)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) + goto out; + + rects = region16_rects(®ion, &nbRects); + if (!rects || nbRects != 3 || !compareRectangles(rects, r1_r2_r3, 3)) + goto out; + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + +static int test_r1_inter_r3() { + REGION16 region, intersection; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r3 = {150, 151, 250, 251}; + + RECTANGLE_16 r1_inter_r3[] = { + {150, 151, 200, 201}, + }; + + region16_init(®ion); + region16_init(&intersection); + + /* + * +=============================================================== + * | + * |+-----+ + * || r1 | + * || +-+------+ +-+ + * || | r3 | r1&r3 | | + * |+---+ | ====> +-+ + * | | | + * | +--------+ + */ + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_intersects_rect(®ion, &r3)) + goto out; + + if (!region16_intersect_rect(&intersection, ®ion, &r3)) + goto out; + rects = region16_rects(&intersection, &nbRects); + if (!rects || nbRects != 1 || !compareRectangles(rects, r1_inter_r3, nbRects)) + goto out; + + + retCode = 0; +out: + region16_uninit(®ion); + return retCode; +} + +static int test_r1_r3_inter_r11() { + REGION16 region, intersection; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects; + RECTANGLE_16 r1 = { 0, 101, 200, 201}; + RECTANGLE_16 r3 = {150, 151, 250, 251}; + RECTANGLE_16 r11 ={170, 151, 600, 301}; + + RECTANGLE_16 r1_r3_inter_r11[] = { + {170, 151, 250, 251}, + }; + + region16_init(®ion); + region16_init(&intersection); + + /* + * +=============================================================== + * | + * |+-----+ + * || | + * || +------+ + * || r1+r3 | (r1+r3) & r11 + * || +----------------+ +--------+ + * |+---+ | | | ====> | | + * | | | | | | | + * | | | | | | | + * | +-|------+ | +--------+ + * | | r11 | + * | +----------------+ + * + * + * R1+R3 is made of 3 bands, R11 overlap the second and the third band. The + * intersection is made of two band that must be reassembled to give only + * one + */ + if (!region16_union_rect(®ion, ®ion, &r1)) + goto out; + if (!region16_union_rect(®ion, ®ion, &r3)) + goto out; + + if (!region16_intersects_rect(®ion, &r11)) + goto out; + + if (!region16_intersect_rect(&intersection, ®ion, &r11)) + goto out; + rects = region16_rects(&intersection, &nbRects); + if (!rects || nbRects != 1 || !compareRectangles(rects, r1_r3_inter_r11, nbRects)) + goto out; + + retCode = 0; +out: + region16_uninit(&intersection); + region16_uninit(®ion); + return retCode; +} + + +typedef int (*TestFunction)(); +struct UnitaryTest { + const char *name; + TestFunction func; +}; + +struct UnitaryTest tests[] = { + {"Basic trivial tests", test_basic}, + {"R1+R3 and R3+R1", test_r1_r3}, + {"R1+R5", test_r1_r5}, + {"R1+R6", test_r1_r6}, + {"R9+R10", test_r9_r10}, + {"R1+R2+R4", test_r1_r2_r4}, + {"R1+R7+R8 in many orders", test_r1_r7_r8}, + {"R1+R2+R3+R4", test_r1_r2_r3_r4}, + {"data from weston", test_from_weston}, + {"R1 & R3", test_r1_inter_r3}, + {"(R1+R3)&R11 (band merge)",test_r1_r3_inter_r11}, + + {NULL, NULL} +}; + +int TestFreeRDPRegion(int argc, char* argv[]) +{ + int i, testNb; + int retCode = -1; + + for (i = 0; tests[i].func; i++) + { + testNb++; + fprintf(stderr, "%d: %s\n", testNb, tests[i].name); + retCode = tests[i].func(); + if (retCode < 0) + break; + } + + if (retCode < 0) + fprintf(stderr, "failed for test %d\n", testNb); + + return retCode; +} From 2d16d929b6ac3b79dd7217426d7d94b68b3ec01e Mon Sep 17 00:00:00 2001 From: Hardening Date: Tue, 4 Feb 2014 12:02:55 +0100 Subject: [PATCH 04/18] Fix remoteFx encoder with topleft and bottomright rectangle This patch fixes the case where with a topleft and a bottomright rectangle, the encoder would send the full screen instead of only the intersected tiles. --- libfreerdp/codec/rfx.c | 479 +++++++++++++++++++++++------------ libfreerdp/codec/rfx_types.h | 6 + 2 files changed, 316 insertions(+), 169 deletions(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index f8e736d88..298e4d527 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -39,6 +39,7 @@ #include #include #include +#include #include "rfx_constants.h" #include "rfx_types.h" @@ -51,6 +52,15 @@ #include "rfx_sse2.h" #include "rfx_neon.h" +void *zmalloc(int size) { + void *ret; + ret = malloc(size); + if (ret) + ZeroMemory(ret, size); + return ret; +} + + #ifndef RFX_INIT_SIMD #define RFX_INIT_SIMD(_rfx_context) do { } while (0) #endif @@ -183,24 +193,13 @@ void rfx_decoder_tile_free(RFX_TILE* tile) RFX_TILE* rfx_encoder_tile_new() { - RFX_TILE* tile = NULL; - - tile = (RFX_TILE*) malloc(sizeof(RFX_TILE)); - - if (tile) - { - ZeroMemory(tile, sizeof(RFX_TILE)); - } - - return tile; + return (RFX_TILE *)zmalloc( sizeof(RFX_TILE) ); } void rfx_encoder_tile_free(RFX_TILE* tile) { if (tile) - { free(tile); - } } RFX_CONTEXT* rfx_context_new(BOOL encoder) @@ -212,36 +211,42 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) DWORD dwValue; SYSTEM_INFO sysinfo; RFX_CONTEXT* context; + wObject *pool; + RFX_CONTEXT_PRIV *priv; - context = (RFX_CONTEXT*) malloc(sizeof(RFX_CONTEXT)); - ZeroMemory(context, sizeof(RFX_CONTEXT)); + context = (RFX_CONTEXT*) zmalloc(sizeof(RFX_CONTEXT)); + if (!context) + return NULL; context->encoder = encoder; - - context->priv = (RFX_CONTEXT_PRIV*) malloc(sizeof(RFX_CONTEXT_PRIV)); - ZeroMemory(context->priv, sizeof(RFX_CONTEXT_PRIV)); + context->priv = priv = (RFX_CONTEXT_PRIV *)zmalloc( sizeof(RFX_CONTEXT_PRIV) ); + if (!priv) + goto error_priv; WLog_Init(); - context->priv->log = WLog_Get("com.freerdp.codec.rfx"); - WLog_OpenAppender(context->priv->log); + priv->log = WLog_Get("com.freerdp.codec.rfx"); + WLog_OpenAppender(priv->log); #ifdef WITH_DEBUG_RFX - WLog_SetLogLevel(context->priv->log, WLOG_DEBUG); + WLog_SetLogLevel(priv->log, WLOG_DEBUG); #endif - context->priv->TilePool = ObjectPool_New(TRUE); - ObjectPool_Object(context->priv->TilePool)->fnObjectInit = (OBJECT_INIT_FN) rfx_tile_init; + priv->TilePool = ObjectPool_New(TRUE); + if (!priv->TilePool) + goto error_tilePool; + pool = ObjectPool_Object(priv->TilePool); + pool->fnObjectInit = (OBJECT_INIT_FN) rfx_tile_init; if (context->encoder) { - ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_encoder_tile_new; - ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_encoder_tile_free; + pool->fnObjectNew = (OBJECT_NEW_FN) rfx_encoder_tile_new; + pool->fnObjectFree = (OBJECT_FREE_FN) rfx_encoder_tile_free; } else { - ObjectPool_Object(context->priv->TilePool)->fnObjectNew = (OBJECT_NEW_FN) rfx_decoder_tile_new; - ObjectPool_Object(context->priv->TilePool)->fnObjectFree = (OBJECT_FREE_FN) rfx_decoder_tile_free; + pool->fnObjectNew = (OBJECT_NEW_FN) rfx_decoder_tile_new; + pool->fnObjectFree = (OBJECT_FREE_FN) rfx_decoder_tile_free; } /* @@ -258,7 +263,9 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) * We then multiply by 3 to use a single, partioned buffer for all 3 channels. */ - context->priv->BufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); + priv->BufferPool = BufferPool_New(TRUE, (8192 + 32) * 3, 16); + if (!priv->BufferPool) + goto error_BufferPool; #ifdef _WIN32 { @@ -271,16 +278,16 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) GetVersionExA(&verinfo); isVistaOrLater = ((verinfo.dwMajorVersion >= 6) && (verinfo.dwMinorVersion >= 0)) ? TRUE : FALSE; - context->priv->UseThreads = isVistaOrLater; + priv->UseThreads = isVistaOrLater; } #else - context->priv->UseThreads = TRUE; + priv->UseThreads = TRUE; #endif GetNativeSystemInfo(&sysinfo); - context->priv->MinThreadCount = sysinfo.dwNumberOfProcessors; - context->priv->MaxThreadCount = 0; + priv->MinThreadCount = sysinfo.dwNumberOfProcessors; + priv->MaxThreadCount = 0; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\FreeRDP\\RemoteFX"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); @@ -289,33 +296,35 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) dwSize = sizeof(dwValue); if (RegQueryValueEx(hKey, _T("UseThreads"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) - context->priv->UseThreads = dwValue ? 1 : 0; + priv->UseThreads = dwValue ? 1 : 0; if (RegQueryValueEx(hKey, _T("MinThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) - context->priv->MinThreadCount = dwValue; + priv->MinThreadCount = dwValue; if (RegQueryValueEx(hKey, _T("MaxThreadCount"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) - context->priv->MaxThreadCount = dwValue; + priv->MaxThreadCount = dwValue; RegCloseKey(hKey); } - if (context->priv->UseThreads) + if (priv->UseThreads) { /* Call primitives_get here in order to avoid race conditions when using primitives_get */ /* from multiple threads. This call will initialize all function pointers correctly */ /* before any decoding threads are started */ primitives_get(); - context->priv->ThreadPool = CreateThreadpool(NULL); - InitializeThreadpoolEnvironment(&context->priv->ThreadPoolEnv); - SetThreadpoolCallbackPool(&context->priv->ThreadPoolEnv, context->priv->ThreadPool); + priv->ThreadPool = CreateThreadpool(NULL); + if (!priv->ThreadPool) + goto error_threadPool; + InitializeThreadpoolEnvironment(&priv->ThreadPoolEnv); + SetThreadpoolCallbackPool(&priv->ThreadPoolEnv, priv->ThreadPool); - if (context->priv->MinThreadCount) - SetThreadpoolThreadMinimum(context->priv->ThreadPool, context->priv->MinThreadCount); + if (priv->MinThreadCount) + SetThreadpoolThreadMinimum(priv->ThreadPool, priv->MinThreadCount); - if (context->priv->MaxThreadCount) - SetThreadpoolThreadMaximum(context->priv->ThreadPool, context->priv->MaxThreadCount); + if (priv->MaxThreadCount) + SetThreadpoolThreadMaximum(priv->ThreadPool, priv->MaxThreadCount); } /* initialize the default pixel format */ @@ -335,29 +344,47 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) RFX_INIT_SIMD(context); context->state = RFX_STATE_SEND_HEADERS; - return context; + +error_threadPool: + BufferPool_Free(priv->BufferPool); +error_BufferPool: + ObjectPool_Free(priv->TilePool); +error_tilePool: + free(priv); +error_priv: + free(context); + return NULL; } void rfx_context_free(RFX_CONTEXT* context) { + RFX_CONTEXT_PRIV *priv; + assert(NULL != context); assert(NULL != context->priv); assert(NULL != context->priv->TilePool); assert(NULL != context->priv->BufferPool); + priv = context->priv; if (context->quants) free(context->quants); - ObjectPool_Free(context->priv->TilePool); + ObjectPool_Free(priv->TilePool); rfx_profiler_print(context); rfx_profiler_free(context); - if (context->priv->UseThreads) + if (priv->UseThreads) { CloseThreadpool(context->priv->ThreadPool); DestroyThreadpoolEnvironment(&context->priv->ThreadPoolEnv); + + if (priv->workObjects) + free(priv->workObjects); + if (priv->tileWorkParams) + free(priv->tileWorkParams); + #ifdef WITH_PROFILER fprintf(stderr, "\nWARNING: Profiling results probably unusable with multithreaded RemoteFX codec!\n"); #endif @@ -610,10 +637,7 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag return FALSE; } - if (message->rects) - message->rects = (RFX_RECT*) realloc(message->rects, message->numRects * sizeof(RFX_RECT)); - else - message->rects = (RFX_RECT*) malloc(message->numRects * sizeof(RFX_RECT)); + message->rects = (RFX_RECT*) realloc(message->rects, message->numRects * sizeof(RFX_RECT)); /* rects */ for (i = 0; i < message->numRects; i++) @@ -624,8 +648,9 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag Stream_Read_UINT16(s, message->rects[i].width); /* width (2 bytes) */ Stream_Read_UINT16(s, message->rects[i].height); /* height (2 bytes) */ - WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (%d %d %d %d).", - i, message->rects[i].x, message->rects[i].y, message->rects[i].width, message->rects[i].height); + WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%d,%d w,h=%d %d).", i, + message->rects[i].x, message->rects[i].y, + message->rects[i].width, message->rects[i].height); } return TRUE; @@ -695,10 +720,7 @@ static BOOL rfx_process_message_tileset(RFX_CONTEXT* context, RFX_MESSAGE* messa Stream_Read_UINT32(s, tilesDataSize); /* tilesDataSize (4 bytes) */ - if (context->quants != NULL) - context->quants = (UINT32*) realloc((void*) context->quants, context->numQuant * 10 * sizeof(UINT32)); - else - context->quants = (UINT32*) malloc(context->numQuant * 10 * sizeof(UINT32)); + context->quants = (UINT32 *)realloc((void*) context->quants, context->numQuant * 10 * sizeof(UINT32)); quants = context->quants; @@ -1127,37 +1149,84 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta rfx_encode_rgb(param->context, param->tile); } -RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, - int numRects, BYTE* data, int width, int height, int scanline) +#define ALIGN_DOWN(value, alignto) ((value) - ((value) % (alignto))) +#define ALIGN_UP(value, alignto) ( (((value) + (alignto) - 1) / (alignto) ) * (alignto) ) + +static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region) { - int i, close_cnt; - int xIdx; - int yIdx; - int numTilesX; - int numTilesY; - UINT16 ax, ay; + int i; + const RFX_RECT *rect = rects; + + for(i = 0; i < numRects; i++, rect++) { + RECTANGLE_16 rect16; + + rect16.left = rect->x; + rect16.top = rect->y; + rect16.right = rect->x + rect->width; + rect16.bottom = rect->y + rect->height; + + if (!region16_union_rect(region, region, &rect16)) + return FALSE; + } + return TRUE; +} + + +BOOL setupWorkers(RFX_CONTEXT *context, int nbTiles) +{ + RFX_CONTEXT_PRIV *priv = context->priv; + + if (!context->priv->UseThreads) + return TRUE; + + priv->workObjects = (PTP_WORK *)realloc(priv->workObjects, sizeof(PTP_WORK) * nbTiles); + if (!priv->workObjects) + return FALSE; + + priv->tileWorkParams = (RFX_TILE_COMPOSE_WORK_PARAM *) + realloc(priv->tileWorkParams, sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * nbTiles); + if (!priv->tileWorkParams) + return FALSE; + + return TRUE; +} + + +RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects, + BYTE* data, int width, int height, int scanline) +{ + int i, maxNbTiles, maxTilesX, maxTilesY; + int xIdx, yIdx, regionNbRects; + int gridRelX, gridRelY, ax, ay, bytesPerPixel; RFX_TILE* tile; - RFX_RECT* rect; - int BytesPerPixel; + RFX_RECT* rfxRect; RFX_MESSAGE* message = NULL; - PTP_WORK* work_objects = NULL; - RFX_TILE_COMPOSE_WORK_PARAM* params = NULL; + PTP_WORK* workObject; + RFX_TILE_COMPOSE_WORK_PARAM *workParam; - message = (RFX_MESSAGE*) malloc(sizeof(RFX_MESSAGE)); + REGION16 rectsRegion, tilesRegion; + RECTANGLE_16 currentTileRect; + const RECTANGLE_16 *regionRect; + const RECTANGLE_16 *extents; +#if 0 + const RFX_RECT *tt = rects; + fprintf(stderr, "input with %d rect(s)\n", numRects); + for (i = 0; i < numRects; i++, tt++) + fprintf(stderr, "%d: %d,%d -> %d,%d (w=%d h=%d)\n", i, + tt->x, tt->y, tt->x + tt->width, tt->y + tt->height, + tt->width, tt->height + ); +#endif + + message = (RFX_MESSAGE *)zmalloc(sizeof(RFX_MESSAGE)); if (!message) return NULL; - ZeroMemory(message, sizeof(RFX_MESSAGE)); - if (context->state == RFX_STATE_SEND_HEADERS) rfx_update_context_properties(context); message->frameIdx = context->frameIdx++; - - message->numRects = numRects; - message->rects = (RFX_RECT*) rects; - if (!context->numQuant) { context->numQuant = 1; @@ -1167,133 +1236,210 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, context->quantIdxCb = 0; context->quantIdxCr = 0; } - - rect = (RFX_RECT*) &rects[0]; - BytesPerPixel = (context->bits_per_pixel / 8); - message->numQuant = context->numQuant; message->quantVals = context->quants; - numTilesX = (width + 63) / 64; - numTilesY = (height + 63) / 64; + rfxRect = (RFX_RECT*) &rects[0]; + bytesPerPixel = (context->bits_per_pixel / 8); - message->numTiles = numTilesX * numTilesY; - if (message->numTiles) - { - message->tiles = (RFX_TILE**) malloc(sizeof(RFX_TILE*) * message->numTiles); - ZeroMemory(message->tiles, sizeof(RFX_TILE*) * message->numTiles); - } + region16_init(&rectsRegion); + if (!computeRegion(rects, numRects, &rectsRegion)) + goto out_free_message; + extents = region16_extents(&rectsRegion); +/* fprintf(stderr, "\n\n%s: nrects(in/simplified)=%d/%d width=%d height=%d bounds=(%d,%d-%d,%d)\n", __FUNCTION__, + numRects, region16_n_rects(&rectsRegion), + width, height, + extents->left, extents->top, + extents->right, extents->bottom);*/ - WLog_Print(context->priv->log, WLOG_DEBUG, "x: %d y: %d width: %d height: %d scanline: %d BytesPerPixel: %d", - rect->x, rect->y, width, height, scanline, BytesPerPixel); + maxTilesX = ALIGN_UP(extents->right - extents->left, 64) / 64; + maxTilesY = ALIGN_UP(extents->bottom - extents->top, 64) / 64; + maxNbTiles = maxTilesX * maxTilesY; + + message->tiles = zmalloc(maxNbTiles * sizeof(RFX_TILE*)); + if (!message->tiles) + goto out_free_message; + + if (!setupWorkers(context, maxNbTiles)) + goto out_clean_tiles; if (context->priv->UseThreads) { - if (message->numTiles) - work_objects = (PTP_WORK*) malloc(sizeof(PTP_WORK) * message->numTiles); - if (!work_objects) - { - free(message); - return NULL; - } - params = (RFX_TILE_COMPOSE_WORK_PARAM*) - malloc(sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles); - if (!params) - { - if (message->tiles) - free(message->tiles); - free(message); - free(work_objects); - return NULL; - } - ZeroMemory(work_objects, sizeof(PTP_WORK) * message->numTiles); - ZeroMemory(params, sizeof(RFX_TILE_COMPOSE_WORK_PARAM) * message->numTiles); + workObject = context->priv->workObjects; + workParam = context->priv->tileWorkParams; } - close_cnt = 0; - for (yIdx = 0; yIdx < numTilesY; yIdx++) + regionRect = region16_rects(&rectsRegion, ®ionNbRects); + message->rects = rfxRect = zmalloc(regionNbRects * sizeof(RFX_RECT)); + if (!message->rects) + goto out_clean_tiles; + message->numRects = regionNbRects; + + region16_init(&tilesRegion); + + for (i = 0; i < regionNbRects; i++, regionRect++, rfxRect++) { - for (xIdx = 0; xIdx < numTilesX; xIdx++) + int startTileX = regionRect->left / 64; + int endTileX = (regionRect->right - 1) / 64; + + int startTileY = regionRect->top / 64; + int endTileY = (regionRect->bottom - 1) / 64; + + rfxRect->x = regionRect->left; + rfxRect->y = regionRect->top; + rfxRect->width = (regionRect->right - regionRect->left); + rfxRect->height = (regionRect->bottom - regionRect->top); + + /*fprintf(stderr, "%s: rect[%d,%d->%d,%d] start=(%d,%d) end=(%d,%d)\n", + __FUNCTION__, + regionRect->left, regionRect->top, regionRect->right, regionRect->bottom, + startTileX, startTileY, + endTileX, endTileY + ); + fprintf(stderr, "rfxRect=%d,%d w/h=%d,%d\n", rfxRect->x, rfxRect->y, rfxRect->width, rfxRect->height);*/ + + for (yIdx = startTileY, gridRelY = startTileY * 64; yIdx <= endTileY; yIdx++, gridRelY += 64 ) { - i = yIdx * numTilesX + xIdx; + int tileHeight = 64; + if ((yIdx == endTileY) && (gridRelY + 64 > height)) + tileHeight = height - gridRelY; - tile = message->tiles[i] = (RFX_TILE*) ObjectPool_Take(context->priv->TilePool); + currentTileRect.top = gridRelY; + currentTileRect.bottom = gridRelY + tileHeight; - tile->xIdx = xIdx; - tile->yIdx = yIdx; - tile->x = tile->xIdx * 64; - tile->y = tile->yIdx * 64; - tile->scanline = scanline; - tile->width = (xIdx < numTilesX - 1) ? 64 : width - xIdx * 64; - tile->height = (yIdx < numTilesY - 1) ? 64 : height - yIdx * 64; - - ax = rect->x + tile->x; - ay = rect->y + tile->y; - if (tile->data && tile->allocated) + for (xIdx = startTileX, gridRelX = startTileX * 64; xIdx <= endTileX; xIdx++, gridRelX += 64) { - free(tile->data); - tile->allocated = FALSE; - } - tile->data = &data[(ay * scanline) + (ax * BytesPerPixel)]; + int tileWidth = 64; + if ((xIdx == endTileX) && (gridRelX + 64 > width)) + tileWidth = width - gridRelX; - tile->quantIdxY = context->quantIdxY; - tile->quantIdxCb = context->quantIdxCb; - tile->quantIdxCr = context->quantIdxCr; + currentTileRect.left = gridRelX; + currentTileRect.right = gridRelX + tileWidth; - tile->YLen = 0; - tile->CbLen = 0; - tile->CrLen = 0; + /* checks if this tile is already treated */ + if (region16_intersects_rect(&tilesRegion, ¤tTileRect)) { + /*fprintf(stderr, "skipping %d,%d -> %d,%d\n", + currentTileRect.left, currentTileRect.top, + currentTileRect.right, currentTileRect.bottom + );*/ + continue; + } - tile->YCbCrData = (BYTE*) BufferPool_Take(context->priv->BufferPool, -1); + tile = (RFX_TILE *)ObjectPool_Take(context->priv->TilePool); + if (!tile) + goto out_clean_rects;; - tile->YData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 0) + 16]); - tile->CbData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 1) + 16]); - tile->CrData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 2) + 16]); + tile->xIdx = xIdx; + tile->yIdx = yIdx; + tile->x = gridRelX; + tile->y = gridRelY; + tile->scanline = scanline; + tile->width = tileWidth; + tile->height = tileHeight; - if (context->priv->UseThreads) - { - assert(params); + /*fprintf(stderr, "tile(%d,%d) - %d,%d->%d,%d (x=%d,y=%d,w=%d,h=%d),\n", + tile->xIdx, tile->yIdx, + currentTileRect.left, currentTileRect.top, + currentTileRect.right, currentTileRect.bottom, + tile->x, tile->y, + tile->width, tile->height + );*/ - params[i].context = context; - params[i].tile = tile; + ax = gridRelX; + ay = gridRelY; + if (tile->data && tile->allocated) + { + free(tile->data); + tile->allocated = FALSE; + } + tile->data = &data[(ay * scanline) + (ax * bytesPerPixel)]; - work_objects[i] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_compose_message_tile_work_callback, - (void*) ¶ms[i], &context->priv->ThreadPoolEnv); + tile->quantIdxY = context->quantIdxY; + tile->quantIdxCb = context->quantIdxCb; + tile->quantIdxCr = context->quantIdxCr; - SubmitThreadpoolWork(work_objects[i]); - close_cnt = i + 1; - } - else - { - rfx_encode_rgb(context, tile); - } - } + tile->YLen = tile->CbLen = tile->CrLen = 0; + + tile->YCbCrData = (BYTE *)BufferPool_Take(context->priv->BufferPool, -1); + if (!tile->YCbCrData) + goto out_clean_rects; + + tile->YData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 0) + 16]); + tile->CbData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 1) + 16]); + tile->CrData = (BYTE*) &(tile->YCbCrData[((8192 + 32) * 2) + 16]); + + if (context->priv->UseThreads) + { + workParam->context = context; + workParam->tile = tile; + + *workObject = CreateThreadpoolWork( + (PTP_WORK_CALLBACK)rfx_compose_message_tile_work_callback, + (void *)workParam, + &context->priv->ThreadPoolEnv + ); + + SubmitThreadpoolWork(*workObject); + + workObject++; + workParam++; + } + else + { + rfx_encode_rgb(context, tile); + } + + message->tiles[message->numTiles] = tile; + message->numTiles++; + + if (!region16_union_rect(&tilesRegion, &tilesRegion, ¤tTileRect)) + goto out_clean_rects; + } /* xIdx */ + } /* yIdx */ + } /* rects */ + + if (message->numTiles != maxNbTiles) + { + message->tiles = realloc(message->tiles, sizeof(RFX_TILE *) * message->numTiles); + if (!message->tiles) + goto out_clean_rects; } - message->tilesDataSize = 0; + region16_uninit(&tilesRegion); - for (i = 0; i < close_cnt; i++) + /* when using threads ensure all computations are done */ + message->tilesDataSize = 0; + workObject = context->priv->workObjects; + for (i = 0; i < message->numTiles; i++) { tile = message->tiles[i]; - - if (context->priv->UseThreads && work_objects) + if (context->priv->UseThreads) { - WaitForThreadpoolWorkCallbacks(work_objects[i], FALSE); - CloseThreadpoolWork(work_objects[i]); + WaitForThreadpoolWorkCallbacks(*workObject, FALSE); + CloseThreadpoolWork(*workObject); + workObject++; } message->tilesDataSize += rfx_tile_length(tile); } - if (work_objects) - free(work_objects); - - if (params) - free(params); + region16_uninit(&rectsRegion); return message; + +out_clean_rects: + free(message->rects); +out_clean_tiles: + free(message->tiles); + region16_uninit(&tilesRegion); +out_free_message: + fprintf(stderr, "remoteFx error\n"); + region16_uninit(&rectsRegion); + free(message); + return 0; } + RFX_MESSAGE* rfx_split_message(RFX_CONTEXT* context, RFX_MESSAGE* message, int* numMessages, int maxDataSize) { int i, j; @@ -1432,14 +1578,8 @@ void rfx_write_message_region(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* mes { /* Clipping rectangles are relative to destLeft, destTop */ -#if 1 - Stream_Write_UINT16(s, 0); /* x (2 bytes) */ - Stream_Write_UINT16(s, 0); /* y (2 bytes) */ -#else Stream_Write_UINT16(s, message->rects[i].x); /* x (2 bytes) */ Stream_Write_UINT16(s, message->rects[i].y); /* y (2 bytes) */ -#endif - Stream_Write_UINT16(s, message->rects[i].width); /* width (2 bytes) */ Stream_Write_UINT16(s, message->rects[i].height); /* height (2 bytes) */ } @@ -1483,3 +1623,4 @@ void rfx_compose_message(RFX_CONTEXT* context, wStream* s, rfx_message_free(context, message); } + diff --git a/libfreerdp/codec/rfx_types.h b/libfreerdp/codec/rfx_types.h index 309bd553c..07e48e400 100644 --- a/libfreerdp/codec/rfx_types.h +++ b/libfreerdp/codec/rfx_types.h @@ -38,12 +38,18 @@ #define DEBUG_RFX(fmt, ...) DEBUG_NULL(fmt, ## __VA_ARGS__) #endif +struct _RFX_TILE_COMPOSE_WORK_PARAM; +typedef struct _RFX_TILE_COMPOSE_WORK_PARAM RFX_TILE_COMPOSE_WORK_PARAM; + struct _RFX_CONTEXT_PRIV { wLog* log; wObjectPool* TilePool; BOOL UseThreads; + PTP_WORK* workObjects; + RFX_TILE_COMPOSE_WORK_PARAM* tileWorkParams; + DWORD MinThreadCount; DWORD MaxThreadCount; From 4cc037d148dcf32b40c4e851b06173ff894cb705 Mon Sep 17 00:00:00 2001 From: Hardening Date: Wed, 5 Feb 2014 14:07:22 +0100 Subject: [PATCH 05/18] Some fixes after Norbert code review There were a bug when the rectangles extents where not at the origin. Some debugging statement have laso been removed. --- libfreerdp/codec/rfx.c | 50 ++++++------------------------------------ 1 file changed, 7 insertions(+), 43 deletions(-) diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 298e4d527..a4e8ab871 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -1149,8 +1149,6 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta rfx_encode_rgb(param->context, param->tile); } -#define ALIGN_DOWN(value, alignto) ((value) - ((value) % (alignto))) -#define ALIGN_UP(value, alignto) ( (((value) + (alignto) - 1) / (alignto) ) * (alignto) ) static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region) { @@ -1171,6 +1169,7 @@ static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region) return TRUE; } +#define TILE_NO(v) ((v) / 64) BOOL setupWorkers(RFX_CONTEXT *context, int nbTiles) { @@ -1201,24 +1200,14 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int RFX_TILE* tile; RFX_RECT* rfxRect; RFX_MESSAGE* message = NULL; - PTP_WORK* workObject; - RFX_TILE_COMPOSE_WORK_PARAM *workParam; + PTP_WORK* workObject = NULL; + RFX_TILE_COMPOSE_WORK_PARAM *workParam = NULL; REGION16 rectsRegion, tilesRegion; RECTANGLE_16 currentTileRect; const RECTANGLE_16 *regionRect; const RECTANGLE_16 *extents; -#if 0 - const RFX_RECT *tt = rects; - fprintf(stderr, "input with %d rect(s)\n", numRects); - for (i = 0; i < numRects; i++, tt++) - fprintf(stderr, "%d: %d,%d -> %d,%d (w=%d h=%d)\n", i, - tt->x, tt->y, tt->x + tt->width, tt->y + tt->height, - tt->width, tt->height - ); -#endif - message = (RFX_MESSAGE *)zmalloc(sizeof(RFX_MESSAGE)); if (!message) return NULL; @@ -1239,21 +1228,16 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int message->numQuant = context->numQuant; message->quantVals = context->quants; - rfxRect = (RFX_RECT*) &rects[0]; + rfxRect = (RFX_RECT *)&rects[0]; bytesPerPixel = (context->bits_per_pixel / 8); region16_init(&rectsRegion); if (!computeRegion(rects, numRects, &rectsRegion)) goto out_free_message; extents = region16_extents(&rectsRegion); -/* fprintf(stderr, "\n\n%s: nrects(in/simplified)=%d/%d width=%d height=%d bounds=(%d,%d-%d,%d)\n", __FUNCTION__, - numRects, region16_n_rects(&rectsRegion), - width, height, - extents->left, extents->top, - extents->right, extents->bottom);*/ - maxTilesX = ALIGN_UP(extents->right - extents->left, 64) / 64; - maxTilesY = ALIGN_UP(extents->bottom - extents->top, 64) / 64; + maxTilesX = 1 + TILE_NO(extents->right - 1) - TILE_NO(extents->left); + maxTilesY = 1 + TILE_NO(extents->bottom - 1) - TILE_NO(extents->top); maxNbTiles = maxTilesX * maxTilesY; message->tiles = zmalloc(maxNbTiles * sizeof(RFX_TILE*)); @@ -1290,13 +1274,6 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int rfxRect->width = (regionRect->right - regionRect->left); rfxRect->height = (regionRect->bottom - regionRect->top); - /*fprintf(stderr, "%s: rect[%d,%d->%d,%d] start=(%d,%d) end=(%d,%d)\n", - __FUNCTION__, - regionRect->left, regionRect->top, regionRect->right, regionRect->bottom, - startTileX, startTileY, - endTileX, endTileY - ); - fprintf(stderr, "rfxRect=%d,%d w/h=%d,%d\n", rfxRect->x, rfxRect->y, rfxRect->width, rfxRect->height);*/ for (yIdx = startTileY, gridRelY = startTileY * 64; yIdx <= endTileY; yIdx++, gridRelY += 64 ) { @@ -1317,13 +1294,8 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int currentTileRect.right = gridRelX + tileWidth; /* checks if this tile is already treated */ - if (region16_intersects_rect(&tilesRegion, ¤tTileRect)) { - /*fprintf(stderr, "skipping %d,%d -> %d,%d\n", - currentTileRect.left, currentTileRect.top, - currentTileRect.right, currentTileRect.bottom - );*/ + if (region16_intersects_rect(&tilesRegion, ¤tTileRect)) continue; - } tile = (RFX_TILE *)ObjectPool_Take(context->priv->TilePool); if (!tile) @@ -1337,14 +1309,6 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int tile->width = tileWidth; tile->height = tileHeight; - /*fprintf(stderr, "tile(%d,%d) - %d,%d->%d,%d (x=%d,y=%d,w=%d,h=%d),\n", - tile->xIdx, tile->yIdx, - currentTileRect.left, currentTileRect.top, - currentTileRect.right, currentTileRect.bottom, - tile->x, tile->y, - tile->width, tile->height - );*/ - ax = gridRelX; ay = gridRelY; if (tile->data && tile->allocated) From 0915060f4087907afecb1b1e50368dbc2d0dcd55 Mon Sep 17 00:00:00 2001 From: Hardening Date: Wed, 5 Feb 2014 15:52:29 +0100 Subject: [PATCH 06/18] Fixes before pullreq Replaced zmalloc by calloc. Moved region from utils to codec. Fixed some typo and corner cases. --- .gitignore | 3 -- include/freerdp/{utils => codec}/region.h | 0 libfreerdp/codec/CMakeLists.txt | 1 + libfreerdp/{utils => codec}/region.c | 9 +++- libfreerdp/codec/rfx.c | 24 ++++------ libfreerdp/codec/test/CMakeLists.txt | 3 +- .../{utils => codec}/test/TestFreeRDPRegion.c | 2 +- libfreerdp/utils/CMakeLists.txt | 5 -- libfreerdp/utils/test/CMakeLists.txt | 48 ------------------- 9 files changed, 20 insertions(+), 75 deletions(-) rename include/freerdp/{utils => codec}/region.h (100%) rename libfreerdp/{utils => codec}/region.c (99%) rename libfreerdp/{utils => codec}/test/TestFreeRDPRegion.c (99%) delete mode 100644 libfreerdp/utils/test/CMakeLists.txt diff --git a/.gitignore b/.gitignore index 2f614c39f..5e3941bc4 100755 --- a/.gitignore +++ b/.gitignore @@ -102,9 +102,6 @@ server/Sample/sfreerdp-server server/X11/xfreerdp-server xcode -# Generated test code -libfreerdp/utils/test/TestFreeRDPUtils.c - # Other *~ *.dir diff --git a/include/freerdp/utils/region.h b/include/freerdp/codec/region.h similarity index 100% rename from include/freerdp/utils/region.h rename to include/freerdp/codec/region.h diff --git a/libfreerdp/codec/CMakeLists.txt b/libfreerdp/codec/CMakeLists.txt index d017b67df..6128c7e03 100644 --- a/libfreerdp/codec/CMakeLists.txt +++ b/libfreerdp/codec/CMakeLists.txt @@ -42,6 +42,7 @@ set(${MODULE_PREFIX}_SRCS rfx_rlgr.h rfx_types.h rfx.c + region.c nsc.c nsc_encode.c nsc_encode.h diff --git a/libfreerdp/utils/region.c b/libfreerdp/codec/region.c similarity index 99% rename from libfreerdp/utils/region.c rename to libfreerdp/codec/region.c index 235b2d094..725dfeb0b 100644 --- a/libfreerdp/utils/region.c +++ b/libfreerdp/codec/region.c @@ -23,7 +23,7 @@ #include #include -#include +#include /* * The functions in this file implement the Region abstraction largely inspired from @@ -380,7 +380,7 @@ static BOOL rectangle_contained_in_band(const RECTANGLE_16 *band, const RECTANGL BOOL region16_simplify_bands(REGION16 *region) { - /** Simplify bands consecutive band that touch and have the same items + /** Simplify consecutive bands that touch and have the same items * * ==================== ==================== * | 1 | | 2 | | | | | @@ -434,6 +434,11 @@ BOOL region16_simplify_bands(REGION16 *region) { int allocSize = sizeof(REGION16_DATA) + finalNbRects * sizeof(RECTANGLE_16); region->data = realloc(region->data, allocSize); + if (!region->data) + { + region->data = &empty_region; + return FALSE; + } region->data->nbRects = finalNbRects; region->data->size = allocSize; } diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index a4e8ab871..37d58314a 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include "rfx_constants.h" #include "rfx_types.h" @@ -52,14 +52,6 @@ #include "rfx_sse2.h" #include "rfx_neon.h" -void *zmalloc(int size) { - void *ret; - ret = malloc(size); - if (ret) - ZeroMemory(ret, size); - return ret; -} - #ifndef RFX_INIT_SIMD #define RFX_INIT_SIMD(_rfx_context) do { } while (0) @@ -193,7 +185,7 @@ void rfx_decoder_tile_free(RFX_TILE* tile) RFX_TILE* rfx_encoder_tile_new() { - return (RFX_TILE *)zmalloc( sizeof(RFX_TILE) ); + return (RFX_TILE *)calloc(1, sizeof(RFX_TILE)); } void rfx_encoder_tile_free(RFX_TILE* tile) @@ -214,12 +206,12 @@ RFX_CONTEXT* rfx_context_new(BOOL encoder) wObject *pool; RFX_CONTEXT_PRIV *priv; - context = (RFX_CONTEXT*) zmalloc(sizeof(RFX_CONTEXT)); + context = (RFX_CONTEXT*)calloc(1, sizeof(RFX_CONTEXT)); if (!context) return NULL; context->encoder = encoder; - context->priv = priv = (RFX_CONTEXT_PRIV *)zmalloc( sizeof(RFX_CONTEXT_PRIV) ); + context->priv = priv = (RFX_CONTEXT_PRIV *)calloc(1, sizeof(RFX_CONTEXT_PRIV) ); if (!priv) goto error_priv; @@ -638,6 +630,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context, RFX_MESSAGE* messag } message->rects = (RFX_RECT*) realloc(message->rects, message->numRects * sizeof(RFX_RECT)); + if (!message->rects) + return FALSE; /* rects */ for (i = 0; i < message->numRects; i++) @@ -1208,7 +1202,7 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int const RECTANGLE_16 *regionRect; const RECTANGLE_16 *extents; - message = (RFX_MESSAGE *)zmalloc(sizeof(RFX_MESSAGE)); + message = (RFX_MESSAGE *)calloc(1, sizeof(RFX_MESSAGE)); if (!message) return NULL; @@ -1240,7 +1234,7 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int maxTilesY = 1 + TILE_NO(extents->bottom - 1) - TILE_NO(extents->top); maxNbTiles = maxTilesX * maxTilesY; - message->tiles = zmalloc(maxNbTiles * sizeof(RFX_TILE*)); + message->tiles = calloc(maxNbTiles, sizeof(RFX_TILE*)); if (!message->tiles) goto out_free_message; @@ -1254,7 +1248,7 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int } regionRect = region16_rects(&rectsRegion, ®ionNbRects); - message->rects = rfxRect = zmalloc(regionNbRects * sizeof(RFX_RECT)); + message->rects = rfxRect = calloc(regionNbRects, sizeof(RFX_RECT)); if (!message->rects) goto out_clean_tiles; message->numRects = regionNbRects; diff --git a/libfreerdp/codec/test/CMakeLists.txt b/libfreerdp/codec/test/CMakeLists.txt index e1bced145..9a6368f7e 100644 --- a/libfreerdp/codec/test/CMakeLists.txt +++ b/libfreerdp/codec/test/CMakeLists.txt @@ -5,7 +5,8 @@ set(MODULE_PREFIX "TEST_FREERDP_CODEC") set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS - TestFreeRDPCodecPlanar.c) + TestFreeRDPCodecPlanar.c + TestFreeRDPRegion.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/libfreerdp/utils/test/TestFreeRDPRegion.c b/libfreerdp/codec/test/TestFreeRDPRegion.c similarity index 99% rename from libfreerdp/utils/test/TestFreeRDPRegion.c rename to libfreerdp/codec/test/TestFreeRDPRegion.c index 33dfd6eb4..188f73ca0 100644 --- a/libfreerdp/utils/test/TestFreeRDPRegion.c +++ b/libfreerdp/codec/test/TestFreeRDPRegion.c @@ -24,7 +24,7 @@ #include #include -#include +#include static BOOL compareRectangles(const RECTANGLE_16 *src1, const RECTANGLE_16 *src2, int nb) diff --git a/libfreerdp/utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt index 1f4aa0453..10b767cd3 100644 --- a/libfreerdp/utils/CMakeLists.txt +++ b/libfreerdp/utils/CMakeLists.txt @@ -26,7 +26,6 @@ set(${MODULE_PREFIX}_SRCS pcap.c profiler.c rail.c - region.c signal.c stopwatch.c svc_plugin.c @@ -69,7 +68,3 @@ else() endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") - -if(BUILD_TESTING) - add_subdirectory(test) -endif() diff --git a/libfreerdp/utils/test/CMakeLists.txt b/libfreerdp/utils/test/CMakeLists.txt deleted file mode 100644 index 7ad20235d..000000000 --- a/libfreerdp/utils/test/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -# FreeRDP: A Remote Desktop Protocol Implementation -# tests for utils cmake build script -# -# Copyright © 2014 Thincast Technologies GmbH -# Copyright © 2014 Hardening -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set(MODULE_NAME "TestFreeRDPUtils") -set(MODULE_PREFIX "TEST_FREERDP_UTILS") - -set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) - -set(${MODULE_PREFIX}_TESTS - TestFreeRDPRegion.c) - -create_test_sourcelist(${MODULE_PREFIX}_SRCS - ${${MODULE_PREFIX}_DRIVER} - ${${MODULE_PREFIX}_TESTS}) - -add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) - -set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS - MONOLITHIC ${MONOLITHIC_BUILD} - MODULE freerdp - MODULES freerdp-utils) - -target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) - -set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") - -foreach(test ${${MODULE_PREFIX}_TESTS}) - get_filename_component(TestName ${test} NAME_WE) - add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) -endforeach() - -set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test") - From 115a1e863d899eb5ef099ae0a837abf2a3fb1d1f Mon Sep 17 00:00:00 2001 From: Hardening Date: Fri, 7 Feb 2014 16:43:48 +0100 Subject: [PATCH 07/18] Fixes in intersection + checks Fix a bug in the extents of an intersection. Add some checks and assert that helps when using the remoteFx encoder. A speedup for intersection when bands are above the target rect. --- libfreerdp/codec/region.c | 6 +-- libfreerdp/codec/rfx.c | 19 +++++++-- libfreerdp/codec/test/TestFreeRDPRegion.c | 47 +++++++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/libfreerdp/codec/region.c b/libfreerdp/codec/region.c index 725dfeb0b..0b06c63d3 100644 --- a/libfreerdp/codec/region.c +++ b/libfreerdp/codec/region.c @@ -667,7 +667,7 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) { endPtr = rect + nbRects; - for (endPtr = rect + nbRects; rect < endPtr; rect++) + for (endPtr = rect + nbRects; (rect < endPtr) && (arg2->bottom > rect->top); rect++) { if (rectangles_intersects(rect, arg2)) return TRUE; @@ -715,7 +715,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE /* accumulate intersecting rectangles, the final region16_simplify_bands() will * do all the bad job to recreate correct rectangles */ - for(endPtr = srcPtr + nbRects; srcPtr < endPtr; srcPtr++) + for(endPtr = srcPtr + nbRects; (srcPtr < endPtr) && (rect->bottom > srcPtr->top); srcPtr++) { if (rectangles_intersection(srcPtr, rect, &common)) { @@ -726,7 +726,7 @@ BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE newExtents.top = MIN(common.top, newExtents.top); newExtents.left = MIN(common.left, newExtents.left); newExtents.bottom = MAX(common.bottom, newExtents.bottom); - newExtents.right = MIN(common.right, newExtents.right); + newExtents.right = MAX(common.right, newExtents.right); } } diff --git a/libfreerdp/codec/rfx.c b/libfreerdp/codec/rfx.c index 37d58314a..c212dc75c 100644 --- a/libfreerdp/codec/rfx.c +++ b/libfreerdp/codec/rfx.c @@ -1144,10 +1144,11 @@ void CALLBACK rfx_compose_message_tile_work_callback(PTP_CALLBACK_INSTANCE insta } -static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region) +static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region, int width, int height) { int i; const RFX_RECT *rect = rects; + const RECTANGLE_16 mainRect = { 0, 0, width, height }; for(i = 0; i < numRects; i++, rect++) { RECTANGLE_16 rect16; @@ -1160,7 +1161,8 @@ static BOOL computeRegion(const RFX_RECT* rects, int numRects, REGION16 *region) if (!region16_union_rect(region, region, &rect16)) return FALSE; } - return TRUE; + + return region16_intersect_rect(region, region, &mainRect); } #define TILE_NO(v) ((v) / 64) @@ -1202,6 +1204,13 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int const RECTANGLE_16 *regionRect; const RECTANGLE_16 *extents; + assert(data); + assert(rects); + assert(numRects > 0); + assert(width > 0); + assert(height > 0); + assert(scanline > 0); + message = (RFX_MESSAGE *)calloc(1, sizeof(RFX_MESSAGE)); if (!message) return NULL; @@ -1222,13 +1231,15 @@ RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects, int message->numQuant = context->numQuant; message->quantVals = context->quants; - rfxRect = (RFX_RECT *)&rects[0]; bytesPerPixel = (context->bits_per_pixel / 8); region16_init(&rectsRegion); - if (!computeRegion(rects, numRects, &rectsRegion)) + if (!computeRegion(rects, numRects, &rectsRegion, width, height)) goto out_free_message; + extents = region16_extents(&rectsRegion); + assert(extents->right - extents->left > 0); + assert(extents->bottom - extents->top > 0); maxTilesX = 1 + TILE_NO(extents->right - 1) - TILE_NO(extents->left); maxTilesY = 1 + TILE_NO(extents->bottom - 1) - TILE_NO(extents->top); diff --git a/libfreerdp/codec/test/TestFreeRDPRegion.c b/libfreerdp/codec/test/TestFreeRDPRegion.c index 188f73ca0..0136b238b 100644 --- a/libfreerdp/codec/test/TestFreeRDPRegion.c +++ b/libfreerdp/codec/test/TestFreeRDPRegion.c @@ -618,6 +618,52 @@ out: return retCode; } +static int test_norbert_case() { + REGION16 region, intersection; + int retCode = -1; + const RECTANGLE_16 *rects; + int nbRects, i; + + RECTANGLE_16 inRectangles[5] = { + {1680, 0, 1920, 242}, + { 294, 242, 971, 776}, + {1680, 242, 1920, 776}, + {1680, 776, 1920, 1036}, + { 2, 1040, 53, 1078} + }; + + RECTANGLE_16 screenRect = { + 0, 0, 1920, 1080 + }; + RECTANGLE_16 expected_inter_extents = { + 0, 0, 1920, 1078 + }; + + region16_init(®ion); + region16_init(&intersection); + + for (i = 0; i < 5; i++) + { + if (!region16_union_rect(®ion, ®ion, &inRectangles[i])) + goto out; + } + + if (!region16_intersect_rect(&intersection, ®ion, &screenRect)) + goto out; + rects = region16_rects(&intersection, &nbRects); + if (!rects || nbRects != 5 || !compareRectangles(rects, inRectangles, nbRects)) + goto out; + + if (!compareRectangles(region16_extents(&intersection), &expected_inter_extents, 1) ) + goto out; + + retCode = 0; +out: + region16_uninit(&intersection); + region16_uninit(®ion); + return retCode; +} + typedef int (*TestFunction)(); struct UnitaryTest { @@ -637,6 +683,7 @@ struct UnitaryTest tests[] = { {"data from weston", test_from_weston}, {"R1 & R3", test_r1_inter_r3}, {"(R1+R3)&R11 (band merge)",test_r1_r3_inter_r11}, + {"norbert case", test_norbert_case}, {NULL, NULL} }; From ea8c9956d23b80cb1c4072408042cea20bd3ad91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 11 Feb 2014 13:30:33 -0500 Subject: [PATCH 08/18] libfreerdp-codec: add some RemoteFX test data --- libfreerdp/codec/test/CMakeLists.txt | 3 +- .../codec/test/TestFreeRDPCodecRemoteFX.c | 762 ++++++++++++++++++ libfreerdp/codec/test/rfx.bmp | Bin 0 -> 16438 bytes 3 files changed, 764 insertions(+), 1 deletion(-) create mode 100644 libfreerdp/codec/test/TestFreeRDPCodecRemoteFX.c create mode 100644 libfreerdp/codec/test/rfx.bmp diff --git a/libfreerdp/codec/test/CMakeLists.txt b/libfreerdp/codec/test/CMakeLists.txt index 3ccf9da72..c80da1574 100644 --- a/libfreerdp/codec/test/CMakeLists.txt +++ b/libfreerdp/codec/test/CMakeLists.txt @@ -6,7 +6,8 @@ set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_TESTS TestFreeRDPCodecMppc.c - TestFreeRDPCodecPlanar.c) + TestFreeRDPCodecPlanar.c + TestFreeRDPCodecRemoteFX.c) create_test_sourcelist(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_DRIVER} diff --git a/libfreerdp/codec/test/TestFreeRDPCodecRemoteFX.c b/libfreerdp/codec/test/TestFreeRDPCodecRemoteFX.c new file mode 100644 index 000000000..9e2c042ae --- /dev/null +++ b/libfreerdp/codec/test/TestFreeRDPCodecRemoteFX.c @@ -0,0 +1,762 @@ +#include +#include + +#include +#include + +/** + * The following is an annotated dump of a TS_RFX_TILESET message containing a single encoded 64x64 tile. + * + * + * c7 cc -> TS_RFX_TILESET::CodecChannelT::blockType = WBT_EXTENSION + * 3e 0b 00 00 -> TS_RFX_TILESET::CodecChannelT::blockLen = 2878 + * 01 -> TS_RFX_TILESET::codecId = 1 + * 00 -> TS_RFX_TILESET::channelId = 0 + * c2 ca -> TS_RFX_TILESET::subtype = CBT_TILESET + * 00 00 -> TS_RFX_TILESET::idx = 0x00 + * 51 50 -> TS_RFX_TILESET::properties + * TS_RFX_TILESET::properties::lt = TRUE (1) + * TS_RFX_TILESET::properties::flags = VIDEO_MODE (0) + * TS_RFX_TILESET::properties::cct = COL_CONV_ICT (1) + * TS_RFX_TILESET::properties::xft = CLW_XFORM_DWT_53_A (1) + * TS_RFX_TILESET::properties::et = CLW_ENTROPY_RLGR3 (4) + * TS_RFX_TILESET::properties::qt = SCALAR_QUANTIZATION (1) + * 01 -> TS_RFX_TILESET::numQuant = 1 + * 40 -> TS_RFX_TILESET::tileSize = 64 + * 01 00 -> TS_RFX_TILESET::numTiles = 1 + * 23 0b 00 00 -> TS_RFX_TILESET::tilesDataSize = 2851 + * 66 66 77 88 98 -> TS_RFX_TILESET::quantVals + * TS_RFX_TILESET::quantVals::LL3 = 6 + * TS_RFX_TILESET::quantVals::LH3 = 6 + * TS_RFX_TILESET::quantVals::HL3 = 6 + * TS_RFX_TILESET::quantVals::HH3 = 6 + * TS_RFX_TILESET::quantVals::LH2 = 7 + * TS_RFX_TILESET::quantVals::HL2 = 7 + * TS_RFX_TILESET::quantVals::HH2 = 8 + * TS_RFX_TILESET::quantVals::LH1 = 8 + * TS_RFX_TILESET::quantVals::HL1 = 8 + * TS_RFX_TILESET::quantVals::HH1 = 9 + * + * TS_RFX_TILE message (section 2.2.2.3.4.1). + * + * c3 ca -> TS_RFX_TILE::BlockT::blockType = CBT_TILE + * 23 0b -> TS_RFX_TILE::BlockT::blockLen = 2851 + * 00 -> TS_RFX_TILE::quantIdxY = 0 + * 00 -> TS_RFX_TILE::quantIdxCb = 0 + * 00 -> TS_RFX_TILE::quantIdxCr = 0 + * 00 00 -> TS_RFX_TILE::xIdx = 0 + * 00 00 -> TS_RFX_TILE::yIdx = 0 + * ae 03 -> TS_RFX_TILE::YLen = 942 + * cf 03 -> TS_RFX_TILE::CbLen = 975 + * 93 03 -> TS_RFX_TILE::CrLen = 915 + * 0000002e:000003db -> TS_RFX_TILE::YData + * 000003dc:000007aa -> TS_RFX_TILE::CbData + * 000007ab:00000b3d -> TS_RFX_TILE::CrData + */ + +const BYTE TEST_RFX_TILESET[2878] = + "\xc7\xcc\x3e\x0b\x00\x00\x01\x01\xc2\xca\x00\x00\x51\x50\x01\x40" + "\x01\x00\x23\x0b\x00\x00\x66\x66\x77\x88\x98\xc3\xca\x23\x0b\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\xae\x03\xcf\x03\x93\x03\xc0\x01" + "\x01\x15\x48\x99\xc7\x41\xa1\x12\x68\x11\xdc\x22\x29\x74\xef\xfd" + "\x20\x92\xe0\x4e\xa8\x69\x3b\xfd\x41\x83\xbf\x28\x53\x0c\x1f\xe2" + "\x54\x0c\x77\x7c\xa3\x05\x7c\x30\xd0\x9c\xe8\x09\x39\x1a\x5d\xff" + "\xe2\x01\x22\x13\x80\x90\x87\xd2\x9f\xfd\xfd\x50\x09\x0d\x24\xa0" + "\x8f\xab\xfe\x3c\x04\x84\xc6\x9c\xde\xf8\x80\xc3\x22\x50\xaf\x4c" + "\x2a\x7f\xfe\xe0\x5c\xa9\x52\x8a\x06\x7d\x3d\x09\x03\x65\xa3\xaf" + "\xd2\x61\x1f\x72\x04\x50\x8d\x3e\x16\x4a\x3f\xff\xfd\x41\x42\x87" + "\x24\x37\x06\x17\x2e\x56\x05\x9c\x1c\xb3\x84\x6a\xff\xfb\x43\x8b" + "\xa3\x7a\x32\x43\x28\xe1\x1f\x50\x54\xfc\xca\xa5\xdf\xff\x08\x04" + "\x48\x15\x61\xd9\x76\x43\xf8\x2a\x07\xe9\x65\xf7\xc6\x89\x2d\x40" + "\xa1\xc3\x35\x8d\xf5\xed\xf5\x91\xae\x2f\xcc\x01\xce\x03\x48\xc0" + "\x8d\x63\xf4\xfd\x50\x20\x2d\x0c\x9b\xb0\x8d\x13\xc0\x8a\x09\x52" + "\x1b\x02\x6e\x42\x3b\xd0\x13\x4e\x84\x01\x26\x88\x6a\x04\x84\x34" + "\x2a\xa5\x00\xba\x54\x48\x58\xea\x54\x02\xb4\x1d\xa7\xfa\x47\x82" + "\xec\x7a\x77\xfd\x00\x92\x66\x62\x04\xa6\x9b\xff\xf6\x80\xc0\x69" + "\x01\xc2\x3e\x90\x14\x20\x2f\xfc\x40\x96\x59\x58\x0c\xb1\x13\x68" + "\x20\x2e\xb5\xf5\xdf\xff\xf8\xfc\x56\x88\x60\x24\x53\xb5\x41\x46" + "\x5f\xf8\xf1\x7e\xde\x4a\x08\x97\xe0\x55\x03\x8f\xe5\x75\x61\x03" + "\xf2\xe1\x90\x01\xa2\x8e\x88\x04\x98\x05\x93\x6b\xff\xea\xc0\x60" + "\xa1\x88\x04\x49\xbf\xf7\xff\x8c\xb4\x59\x90\x80\x30\x64\x53\xff" + "\xf5\xc4\x48\xda\xda\xcb\x80\x38\x61\x57\xb2\xaf\x00\xe8\x7b\x46" + "\xe6\xd8\x02\x03\x8a\x06\x18\x14\x32\x83\xd0\x8a\xee\xbc\x81\xb4" + "\x28\xc4\x7f\xf9\xa1\x69\x00\x91\xc5\x51\xff\xfe\x3f\xe9\xf1\x70" + "\x30\x24\x10\xa7\xcb\x1f\x8a\x24\x93\xed\x83\x00\x36\x20\xd1\x50" + "\xe7\xd8\xad\x58\x20\x09\x22\x80\xd0\xca\x5d\x1a\xd7\xf1\x60\x75" + "\x2a\xf2\xd7\xf8\xc0\x32\x45\x86\x00\x43\x01\xfe\x80\xf7\x42\x81" + "\x74\x84\x4c\xa1\x60\x4c\xcb\x14\x58\x01\x4d\x18\xa1\xaa\x47\x0e" + "\x11\x1a\x40\x7d\x41\x02\xe3\x30\xcd\x33\x81\x34\x06\x46\x83\xa2" + "\x47\x1c\x04\xaa\x20\x12\xa2\x8b\x81\xc4\x9c\xa0\x2e\x06\x32\xf8" + "\x86\x85\x01\xe8\x70\xf9\x46\x09\x6a\xbf\xe0\xf5\xa4\xc8\x78\xe7" + "\xd2\x97\x0b\xbc\x3c\x97\xff\xd5\x40\x94\xb2\xc1\x18\x18\x11\x1f" + "\x43\xc1\x18\xc3\x83\x7f\x9a\x31\xc4\x8e\x70\x56\xda\xf6\x17\xde" + "\xd1\x02\x0d\x42\x21\x13\xdc\x3a\x3c\x40\x9e\xf4\x01\x43\xea\x0c" + "\x46\x73\xa2\x7b\x0c\x80\xff\xe4\xad\x2e\x09\xb4\x63\xb0\x8c\x54" + "\x59\xfa\xac\x76\x36\x10\x05\xf0\x98\x88\x83\x42\x00\x20\x71\xcc" + "\xc1\xa9\x97\x3e\x5a\x0d\x04\x50\x92\x23\x20\x0d\x0a\x1c\x57\xd7" + "\xff\x10\xf2\x03\x0f\x58\x1b\xa5\x11\xf8\xf1\xb4\x12\xdb\x1a\x48" + "\x56\x1f\xe3\xc7\x50\xe9\x16\xb4\xbc\xb0\x40\x93\xea\xb5\x5b\x2f" + "\xfc\x50\x0a\x6f\xcc\x25\xe0\x06\xab\x5f\x24\xfe\x8b\xcb\x42\x43" + "\x7e\x69\x02\x25\xc7\x38\x00\x6e\xe5\x80\xa8\xa4\x30\x44\x15\x8f" + "\xe9\x0c\xd3\xa6\xc2\x14\x34\x4a\xfe\x03\x7f\x06\xa5\x91\x02\x54" + "\xf1\xa1\xa1\x53\xbf\x11\xf2\x8f\x83\x67\x80\x09\x08\x12\x3f\xfd" + "\x44\x91\xc2\x83\x30\x50\x07\x02\x82\x4d\x31\x34\x06\x41\x79\x6f" + "\xf0\xcc\x03\x79\x00\x2c\x05\x24\xec\x8d\x29\x15\xaf\x44\xc8\xeb" + "\x4f\xe1\xfd\xf1\x41\x48\x81\x08\xaf\xfe\x51\x48\xce\xe7\xf9\xb6" + "\x0a\x30\x83\x11\xf0\x0c\x3b\xd2\xa6\x24\x24\xef\x25\xfa\x5a\x3e" + "\x92\x3e\x79\x0e\x35\x61\xc8\xaa\x1c\x2e\x9a\x27\x7f\xff\xf0\x7d" + "\x30\x5b\xbc\x91\xff\xfe\x43\x24\x28\x66\xa7\x70\x99\x28\x6e\x2b" + "\x18\x2b\xd4\xa1\x77\x3b\x96\x9f\xf7\xeb\xbe\x1f\x04\x34\x75\x84" + "\x31\x42\x4c\x65\xaa\x09\x50\xa0\xc4\x51\x31\xd3\x26\x3a\x1b\xf4" + "\x6e\x4a\x4e\x17\x25\x84\x78\x7d\x2c\x3f\x46\x18\xca\x5f\xf9\xe5" + "\x38\x2f\xd8\x71\x94\x94\xe2\xcc\xa3\x15\xb0\xda\xa9\xcb\x58\xe4" + "\x18\x77\x93\x8a\x51\xc6\x23\xc4\x4e\x6d\xd9\x14\x1e\x9b\x8d\xbc" + "\xcb\x9d\xc4\x18\x05\xf5\xa9\x29\xf8\x6d\x29\x38\xc7\x44\xe5\x3a" + "\xcd\xba\x61\x98\x4a\x57\x02\x96\x42\x02\xd9\x37\x11\xde\x2d\xd4" + "\x3f\xfe\x61\xe7\x33\xd7\x89\x4a\xdd\xb0\x34\x47\xf4\xdc\xad\xaa" + "\xc9\x9d\x7e\x6d\x4b\xcc\xdc\x17\x89\x57\xfd\xbb\x37\x75\x47\x5a" + "\xec\x2c\x6e\x3c\x15\x92\x54\x64\x2c\xab\x9e\xab\x2b\xdd\x3c\x66" + "\xa0\x8f\x47\x5e\x93\x1a\x37\x16\xf4\x89\x23\x00\x00\xb0\x33\x56" + "\xfa\x14\x1e\xff\x48\x7a\x7e\x0f\x10\x1f\xf4\x91\xc8\x10\x56\x84" + "\xff\x08\xec\xb4\xac\x0e\x0f\xff\xad\xc5\xe0\x1a\x2f\x82\x04\x9f" + "\x91\xc2\x0e\xfe\x48\x36\x79\x01\x42\x14\xff\xfe\x30\xf0\x08\x18" + "\xf1\x81\x45\x9a\x60\xc1\x79\xf0\x14\x12\x10\xce\xea\x31\x5a\xff" + "\xfc\x20\x13\x82\x2f\xc9\x02\x1f\x81\xcb\x00\xe1\x10\xd2\xb4\xbe" + "\x87\xff\xb0\x1e\x27\x81\xb7\x04\x06\x3c\xc2\x04\xf6\x06\x0e\x28" + "\xbc\x40\xbf\x12\x1e\x86\xd4\x6a\x7f\x18\x1b\x96\x85\x4c\x16\x80" + "\xdf\x2c\xa5\x8d\x86\xa3\x4a\x8a\xb4\x1b\xa1\x38\xa9\xd5\xff\xff" + "\xea\x06\x20\xd2\x95\x1e\xf4\x2f\xb2\x12\x0e\x61\x78\x4a\x17\x52" + "\x5d\xe4\x25\x1f\xfe\xc0\xb3\x1f\xff\xff\xec\x02\x82\x80\x90\x41" + "\x88\xde\x48\x2c\x42\x52\x0b\x2f\x43\x7e\x50\x78\xf2\x67\x78\x41" + "\x34\x3d\xc8\x0f\x67\xa1\xeb\x21\xfe\xc0\x1f\x22\x60\x41\x6c\x00" + "\x92\x4b\x60\x10\xd0\x0d\x01\x35\x05\x0e\x87\xa2\xa0\x5d\x1f\xa3" + "\xaf\x7f\xf1\xbe\x8f\xcd\xa5\x00\x1c\x10\x40\x15\x76\x81\x05\xef" + "\xee\x00\x60\x84\x00\x99\x40\x4a\x82\x17\xe9\xfc\xc4\x7f\xff\xfd" + "\x04\x80\x06\x06\xdc\xaf\xa7\x7e\x94\x75\x74\x01\x00\xe0\x91\x00" + "\x85\x7f\x8e\xd6\x0b\x20\x21\x30\xca\x62\x8e\x07\x04\xe9\x45\x40" + "\x5f\x47\x4a\x30\x15\x41\xcb\xdf\xff\xfc\xbf\xc3\xb4\x46\x6a\x01" + "\x40\xd0\xa7\x34\x18\x24\x1c\x2a\x45\xfe\xa8\x05\x08\x61\xfd\xa8" + "\x80\x71\x01\x25\x9c\xc1\x47\x17\x37\x02\x7a\x15\xff\xf3\x01\x45" + "\x7f\xd6\x80\x60\x83\x67\xf8\x9d\x2f\xf4\xdd\x8c\x30\x01\x51\x42" + "\xbc\x43\x7a\x6b\x9f\x84\x1e\x00\x48\xc1\xe0\xb7\xe0\x7e\x99\xf2" + "\x4a\xe9\x40\x02\x81\xc3\x00\x24\x3a\xc5\x52\x0f\x91\xc8\x68\x25" + "\x40\x99\xa4\x25\x1a\x04\xd0\xa2\x91\xdd\xeb\x93\x00\x21\x49\x24" + "\x8b\x40\x75\x38\x14\xa1\xfd\x3f\x88\x25\xbf\x32\x00\xe3\x19\xfc" + "\xb9\xf8\x6f\x81\xc0\x01\xb3\x93\x20\x09\x08\x25\x84\xe1\x34\xd4" + "\x1b\x48\x88\x11\xa0\x15\x59\xd7\x07\x81\x81\x3b\xa1\x40\x2e\x2f" + "\x48\x70\x09\xc4\x76\x49\x0f\x2e\x50\x2e\x46\x19\xa4\x16\xa2\x1b" + "\x84\xa2\x89\x58\xfc\x4f\x3f\x40\x90\x4c\xa3\x01\x32\x09\x02\x80" + "\x9c\x91\x13\x2c\xba\xde\x5d\x99\xf2\xff\xff\x3d\x5a\x1f\xa9\x02" + "\x90\x8f\xf3\x08\xbd\x01\xf8\xd0\x2a\x95\x41\x0c\x40\x0a\x20\xc4" + "\xd4\xcc\x6b\x0f\xf0\x80\xb1\x5d\x28\x3d\x08\xc2\xf8\x31\x02\x49" + "\x88\x14\x28\xed\xe8\x86\x3b\x00\x9f\x95\x06\x37\x15\xa4\x59\xc8" + "\x80\xb6\x10\xf0\xe5\xb8\x18\x00\x56\x1c\xff\x95\x21\x0e\x7f\x2b" + "\xc5\x08\x59\x10\xe1\x46\x31\x8d\xec\xe0\xa1\x99\xbb\x21\xff\xfe" + "\x30\x10\xd0\x05\xe3\x08\x50\xfc\xf3\x0e\x00\x8d\x68\x8e\x07\xa6" + "\x80\x34\x42\xed\x1f\x88\x00\xf0\x8a\x21\xae\xf7\xfb\x80\x28\x86" + "\x0f\xff\xff\x82\xea\x47\x95\x91\xe0\x04\x01\x44\x0c\x29\xff\x0e" + "\x33\xe8\xc0\x54\x04\x23\xfc\x81\x5b\xf0\x3c\x07\x10\x70\x30\xd8" + "\x21\x6f\xef\xde\x46\x09\x43\xfa\x5f\xff\x0d\x72\x30\xdd\x00\xdb" + "\xe4\x48\x24\x97\x08\x46\xb1\x49\xc4\x4d\x80\x12\x60\xff\xa4\xa6" + "\xff\xf6\x8c\x00\x40\x05\x02\xb4\x0f\xf0\x3e\xfc\x84\x38\x81\x94" + "\x8b\xfe\x49\xef\xc0\x10\x49\x88\x28\xa2\x1c\x2a\x8b\x64\xd4\x86" + "\xd7\xff\xff\xff\xeb\x91\x6b\x11\x10\x00\x69\x4c\xbf\xb4\x1c\xd8" + "\x00\x07\x16\x80\x60\x0a\x1c\x82\x42\x27\x82\x43\xc9\x0a\x64\x20" + "\x5a\x5f\x4e\xbf\x8c\x38\x82\x36\x02\x07\x72\x79\x07\x23\xb4\xbb" + "\x57\x5f\xe8\x04\xdd\x39\xe9\x07\x95\xbe\x04\x2b\xdd\x8e\x22\xdc" + "\x14\x2c\x61\xa3\xa9\xcd\x4f\x82\x5d\xa0\x44\xdf\xf4\x96\xff\xf5" + "\x2b\xff\xfe\x01\x19\xd2\xa2\x9e\x43\xa5\x7f\xf0\x4c\x4c\x2b\x3c" + "\x33\xe2\x55\xff\x04\x06\x29\x2c\x0d\x22\x5d\x7c\x93\xba\x18\xaf" + "\xf9\x32\xa6\xc3\x99\x46\x79\xe3\x06\xa6\x38\x8b\x92\x22\x4b\xdb" + "\x1b\x36\x20\xb0\x6c\x20\xce\x37\x42\xe1\x66\xd4\x49\x34\x42\x8b" + "\xfa\x9c\x12\x99\xdc\x06\x87\xfa\x46\xf8\x2f\x04\xa9\xd8\x82\x07" + "\xa6\x30\x0f\xc0\xdf\x35\xe8\x90\xf0\xff\xff\xa8\xe0\xd7\x02\x60" + "\x1a\xc3\x20\x28\xa2\x31\x29\x3c\xeb\x04\xa5\xdd\x48\x0e\x82\xa4" + "\xb6\x56\x22\x06\x57\xe0\xda\x10\x27\x31\x0e\x11\x77\xfe\x02\x60" + "\x16\x48\x81\x8c\x0d\x05\x17\x7f\xcb\xbb\x7e\x25\x2a\x41\xfd\x8a" + "\x7f\xc9\x36\x7c\xe0\x98\x7e\x92\xef\x7e\x06\x03\x13\x3e\x20\x3a" + "\xbf\x4c\xc3\x0f\x2e\x80\x74\xbf\x39\x3c\xf0\xa6\xb2\xe9\x3f\x41" + "\x55\x1f\x2c\xf5\xd2\x7e\x8c\xae\x4e\xaa\x61\x3c\xbc\x3f\xc4\xc7" + "\x36\xdc\x23\xc8\xb8\x52\xe2\x8a\x80\x18\x00\x00\xb2\x46\xa2\x56" + "\x0d\x12\x94\xaa\xbd\x01\x07\xff\xfa\x34\x0c\x5f\xf8\x0c\x12\x50" + "\xaf\xd6\xd1\x89\x40\xa4\xff\xe0\xce\xc4\x49\x25\x9d\xc1\xff\x7e" + "\x60\x24\x5d\xcc\x10\xc0\xbe\x5a\x12\xd3\xc3\xfe\x2d\x40\x7c\x28" + "\x9e\x71\x01\xd2\x6e\x86\x0b\xc8\xf2\x9b\x45\x08\x4c\x04\x52\x7e" + "\xf2\x7e\xd9\xcc\x0b\x1c\x20\x80\xae\xaf\xfe\xb0\x6d\x23\xf2\x41" + "\xe3\x2e\x20\x11\x4b\x74\x89\xdd\xff\xa8\x38\xa3\x95\x82\x15\xf0" + "\xd0\xd5\xf1\x92\x8e\xee\xc0\x26\x81\xe9\x47\xff\xee\x0d\x20\x34" + "\x31\x3a\xef\x40\xb2\x29\x47\x19\x7f\x04\x27\xf1\x90\x85\x09\x86" + "\x7d\x42\xe2\x54\x5d\x5f\xe8\x0e\xd0\x2c\xaa\x16\xbf\x04\xa7\xf8" + "\xa2\x46\x0b\x08\x7a\x79\xe9\x28\x62\x7c\x33\xf4\x0b\x14\x82\xfa" + "\x61\xeb\xc1\xff\x4c\xa4\x11\x7f\x03\x68\x44\xc1\x1f\x81\x3a\x6c" + "\x77\x95\x02\x2b\x53\x80\xe5\x10\x1e\x90\xe8\xfd\x1f\xa6\x40\x0b" + "\x13\xff\x4e\x4d\x7f\x52\xe8\xaf\x9a\xc1\x80\x0f\x0a\x14\x02\x3c" + "\xc0\x09\x13\xe7\xdc\xc0\x1a\x28\xa0\xe4\x83\x8e\x03\x88\xd5\xaf" + "\x1a\xbd\x91\x00\xb7\x4e\xba\xdf\xf8\xdb\xcc\x02\x43\xc4\x14\x2a" + "\x3f\xc8\x0d\x09\x1c\x44\xf4\x01\x3c\xca\x28\x56\x80\xa6\x85\x00" + "\xea\x3e\x8f\xeb\x9f\xfc\x6e\x07\xc4\xe0\x30\x78\xa0\x1e\x6f\x54" + "\x78\x51\xff\x56\x4a\x01\x47\x02\x4c\x21\x3b\xfb\x90\x0a\xcc\x1d" + "\xd2\x47\xff\xfc\x70\x18\x22\xc0\xb9\x2f\xe9\x7f\x91\xd3\x66\x2f" + "\x80\x2c\x24\xa7\xfa\x84\x51\xab\x6b\x72\x00\xab\x33\x04\xcf\x43" + "\xff\x17\x51\x84\x0c\x01\x50\x10\x8f\x90\x34\x41\x44\x84\x8e\x08" + "\x19\x04\x48\x50\x84\x38\x3d\x02\x52\xf9\x7c\xd2\xd0\x1f\x13\x42" + "\xa0\x21\x41\xc4\x02\x02\x3d\x09\xc8\xfd\x60\x7d\x35\x4f\x7f\xff" + "\xf9\x97\x6a\xd8\x00\xc3\x83\x00\x09\x50\x4b\x90\x8a\xc7\x94\x4d" + "\x47\xc1\x62\x32\x28\x24\x09\x52\x2e\x2e\x1c\x96\x44\xa0\x09\xc8" + "\xce\x64\xa9\x1c\x19\x0e\x52\x3e\x3e\x19\x93\xa0\x36\x26\x22\x08" + "\x9a\x00\xdd\x66\x3a\x93\xd5\x89\xd1\x40\x06\xd4\xa8\x22\x73\x7b" + "\x3d\x3f\xe3\x04\x94\xff\xff\xff\xff\x0c\x56\x77\xac\xe0\xc4\x06" + "\x1f\xb8\xa5\x80\xfd\x68\x1c\x32\x16\x03\xde\x71\x2a\x3d\x14\x19" + "\xbe\xc2\x88\xd9\x24\x92\x5f\xc5\x90\x0a\x85\xc2\x3f\x87\x03\xa8" + "\x26\x17\xc4\x06\x86\x12\x87\x76\x0a\x48\x16\xed\x96\x93\xec\x1b" + "\x30\x73\xe8\x1a\x3f\xff\x4d\xce\x40\xf3\x0c\x51\x4b\x84\x9e\x67" + "\x2b\x15\x40\x1a\xa0\xfc\x10\x0f\xd8\x81\x35\x87\xff\x98\x0f\x40" + "\x00\xba\xc0\x71\xe2\x00\x18\x28\xb3\x82\xcc\x80\x6a\xa0\x43\xff" + "\x2d\xd6\x04\x8a\x68\xff\xff\xff\xfc\x1a\xf3\x1a\x2a\x06\xc0\x01" + "\x40\x0c\x30\xc1\xd0\xd7\x4f\xcb\x74\x1f\x07\xd3\xb4\x0d\x88\x98" + "\xea\xda\x9f\xce\x2b\x3c\x55\xb3\x40\x14\xff\xff\xff\xea\xdb\x9b" + "\x92\xd8\x68\x08\x0b\x41\x09\x26\x40\x8c\xf1\xb0\x9a\x98\xc0\x80" + "\x8b\xf0\x3d\xe7\xec\x19\x68\x21\x03\x29\x7f\xe1\x6d\x4c\x0f\x01" + "\xd1\x51\x01\x1a\x50\x2a\x59\x27\x80\xc1\x6e\x33\xf1\x80\xe1\x49" + "\x08\xe9\x17\xff\xff\xff\x80\x5a\x10\x10\x36\x5e\xca\xf8\x3a\x00" + "\x1e\xb0\x06\x84\x01\xf3\x07\x1b\x4a\xc0\x1e\x21\x43\x8e\xa5\x55" + "\x77\xc7\x65\x7c\xc2\xdf\x5e\x0c\x42\x20\xd2\x48\x61\xc8\x1c\x65" + "\xf8\xfe\x4c\x88\x71\x1f\x82\x50\x81\xa3\x54\x09\x13\x28\x52\xf5" + "\xe0\x82\xc3\x06\x7f\xfa\x2c\xcf\xf8\xf4\x7f\xff\xfd\x01\x49\xa4" + "\xb8\xde\x62\x84\xfe\xed\x65\x1f\x3c\x3c\xb2\x50\x76\x30\x5b\x03" + "\xc0\x08\xa6\x64\x90\xc8\xcd\x14\x6e\x69\x46\x7a\xc6\x1c\x87\xd7" + "\x48\x7b\x49\x05\x2d\x5e\x7f\xcb\x67\xf0\xd9\x0d\x1e\x9e\x53\xb7" + "\x64\xa5\xa5\x10\x39\x06\x11\x3f\xb1\xa9\xa6\xe8\x4d\x47\x77\xda" + "\x43\x76\x89\x45\x09\x70\xc2\x38\x0f\x09\x6f\xe7\x2d\x82\x35\x07" + "\xfe\x64\x18\x2e\xb8\x04\x42\x54\x80\x43\x12\x6c\x9a\x55\xc9\x0a" + "\xa0\x79\x47\x52\x65\x2a\xff\x50\x11\xc9\x4e\xfe\x5b\x30\xa4\xe8" + "\x30\x63\xff\x21\x12\x1b\xdc\x1c\x01\x41\x51\x1f\xff\xfa\xc3\xe3" + "\x55\xf1\x66\xe2\xd5\x78\x5e\xfa\x4d\xf2\x61\x01\x26\x15\xa9\xf9" + "\xd9\x32\x41\x90\x36\x4e\xae\xe3\x0b\x16\x56\x8c\x6e\x42\x5d\xd8" + "\x1e\xfe\x1d\x40\x3a\x50\x9f\x09\x14\xeb\x6e\x48\x7a\x91\x88\x7b" + "\x7d\x8f\x72\x42\x39\xb0\x1c\x65\x18\x23\x8b\x60\x30\x00"; + +/** + * 64x64 XRGB Image + */ + +const UINT32 TEST_RFX_XRGB_IMAGE[4096] = +{ + 0x00229cdf, 0x00249de0, 0x00259fe2, 0x002ca5e8, 0x00229cdf, 0x00229ce0, 0x00239de0, 0x00229ce0, + 0x00229cdf, 0x00229cdf, 0x00239ce0, 0x00249ce0, 0x00249ce0, 0x00219ce3, 0x001e9ce6, 0x00209ae2, + 0x002299dd, 0x002199de, 0x00209adf, 0x00209ae0, 0x001f9be0, 0x001e9ae0, 0x001d99e0, 0x001c98e0, + 0x001b97df, 0x001e96dc, 0x002194d9, 0x001f93dd, 0x001d93e0, 0x001b94dc, 0x001895d8, 0x001c92db, + 0x00208fde, 0x001b91de, 0x001693df, 0x001793df, 0x001992df, 0x001891df, 0x00178fdf, 0x00178edf, + 0x00168dde, 0x00158cdd, 0x00148cdc, 0x00128cda, 0x00118cd9, 0x00118bd9, 0x00128ada, 0x001289da, + 0x001288db, 0x001187da, 0x001186da, 0x001085da, 0x000f85d9, 0x000f84d9, 0x000e83d9, 0x000d82d8, + 0x000d82d8, 0x000d81d8, 0x000d80d7, 0x000d7fd7, 0x000d7ed6, 0x000d7ed6, 0x000d7ed6, 0x000d7ed6, + 0x00259fe1, 0x0027a1e2, 0x0029a2e3, 0x002ba4e6, 0x00249fe1, 0x00249fe1, 0x00249fe1, 0x00249ee1, + 0x00239ee1, 0x00249ee1, 0x00249ee1, 0x00259de1, 0x00259de2, 0x00249de2, 0x00229de2, 0x00229ce1, + 0x00229bdf, 0x00219ce0, 0x00209ce1, 0x00209ce2, 0x00209ce2, 0x00209ae0, 0x002199de, 0x001f99df, + 0x001d98e0, 0x001e97e0, 0x001f97e0, 0x001d96df, 0x001c95de, 0x001c94e0, 0x001c94e1, 0x001d93e1, + 0x001d92e0, 0x001b93de, 0x001a94dc, 0x001a93de, 0x001a93e0, 0x001992e0, 0x001891df, 0x00188fdf, + 0x00178edf, 0x00168ede, 0x00158edd, 0x00148ddc, 0x00138ddb, 0x00138cdb, 0x00138bdb, 0x00128adb, + 0x001289db, 0x001288db, 0x001187db, 0x001186db, 0x001085db, 0x000f84da, 0x000e83d9, 0x000e83d9, + 0x000e83d9, 0x000e82d9, 0x000e81d8, 0x000e80d8, 0x000d7fd7, 0x000d7fd7, 0x000d7fd7, 0x000d7fd7, + 0x0027a3e3, 0x002aa4e3, 0x002ea6e3, 0x002aa4e3, 0x0026a2e3, 0x0026a1e3, 0x0025a1e3, 0x0025a0e3, + 0x0025a0e3, 0x0025a0e3, 0x00259fe3, 0x00269fe3, 0x00269ee4, 0x00279ee1, 0x00279edf, 0x00259ee0, + 0x00239ee1, 0x00219ee2, 0x00209ee4, 0x00209de4, 0x00219de3, 0x00229be0, 0x002499dc, 0x002299de, + 0x001f98e0, 0x001d99e4, 0x001b9ae7, 0x001c98e2, 0x001c96dc, 0x001e94e3, 0x002092ea, 0x001d94e6, + 0x001a96e2, 0x001c96de, 0x001d95da, 0x001c94de, 0x001b94e1, 0x001a93e0, 0x001a92e0, 0x001991e0, + 0x001890e0, 0x001790df, 0x00178fde, 0x00168fde, 0x00158edd, 0x00148ddd, 0x00138cdc, 0x00138bdc, + 0x00128adc, 0x001289dc, 0x001188dc, 0x001187dd, 0x001086dd, 0x000f85db, 0x000e83d9, 0x000e84da, + 0x000f84da, 0x000e83da, 0x000e82d9, 0x000e81d9, 0x000e80d8, 0x000e80d8, 0x000e80d8, 0x000e80d8, + 0x002aa7e5, 0x002da7e4, 0x0031a8e3, 0x002ca6e3, 0x0027a4e4, 0x0027a3e4, 0x0027a3e4, 0x0027a3e4, + 0x0026a2e4, 0x0026a2e4, 0x0027a1e5, 0x0027a0e5, 0x0027a0e6, 0x0026a0e5, 0x0025a0e4, 0x00259fe4, + 0x00259ee3, 0x00239ee5, 0x00229fe6, 0x00229fe5, 0x00229fe4, 0x0013a5e6, 0x001b9fe8, 0x0016a0e8, + 0x0011a0e7, 0x00129fef, 0x00139ef7, 0x001b99ec, 0x00179ae2, 0x00149ce4, 0x001d98e5, 0x001c97e6, + 0x001b96e7, 0x001c98dc, 0x001d97df, 0x001c96e1, 0x001c94e2, 0x001b94e1, 0x001b93e1, 0x001a93e0, + 0x001a92e0, 0x001991e0, 0x001890e0, 0x001790df, 0x00168fdf, 0x00158ede, 0x00158dde, 0x00148cdd, + 0x00138bdc, 0x00128add, 0x001289dd, 0x001188de, 0x001187de, 0x000f85dc, 0x000d83da, 0x000f85db, + 0x001086db, 0x000f84db, 0x000f83da, 0x000e82da, 0x000e81da, 0x000e81da, 0x000e81da, 0x000e81da, + 0x002caae7, 0x0030aae5, 0x0034abe3, 0x002ea8e4, 0x0029a6e5, 0x0028a6e5, 0x0028a5e5, 0x0028a5e5, + 0x0028a5e6, 0x0028a4e6, 0x0028a3e7, 0x0028a2e7, 0x0028a1e8, 0x0025a2e9, 0x0023a3ea, 0x0025a0e8, + 0x00279ee6, 0x00259fe7, 0x0023a0e9, 0x0018a4f5, 0x000ea7ff, 0x001ba6de, 0x00558ebb, 0x006f839c, + 0x0089797e, 0x008d797c, 0x00917979, 0x007f7b94, 0x005687af, 0x00229bd6, 0x0004a4fd, 0x00109df4, + 0x001c97eb, 0x001c9ada, 0x001c98e4, 0x001c97e3, 0x001d95e2, 0x001c95e2, 0x001c94e2, 0x001c94e1, + 0x001b94e1, 0x001a93e1, 0x001a92e1, 0x001991e1, 0x001890e1, 0x00178fe0, 0x00158edf, 0x00148dde, + 0x00138cdd, 0x00128bde, 0x00128adf, 0x001289df, 0x001188e0, 0x000f85dd, 0x000d83da, 0x000f85db, + 0x001187dd, 0x001086dc, 0x000f84dc, 0x000e83db, 0x000e81db, 0x000e81db, 0x000e81db, 0x000e81db, + 0x0030abe5, 0x0036afe8, 0x0034abe4, 0x002faae5, 0x002ba8e6, 0x0036aee8, 0x0026a6e8, 0x0029a7e7, + 0x002ca8e7, 0x002da7e6, 0x002fa5e5, 0x002ca5e7, 0x0029a4e9, 0x002ba5e5, 0x002ca5e2, 0x0010aaef, + 0x0013adf6, 0x0023a3f8, 0x006091a5, 0x00a6755d, 0x00ec5915, 0x00ff490c, 0x00fa5504, 0x00ff590f, + 0x00ff5d1b, 0x00ff6116, 0x00fa6412, 0x00ff550f, 0x00ff4b0d, 0x00fb4918, 0x00f54823, 0x008e737e, + 0x00269eda, 0x0006a2ff, 0x001d97e2, 0x001799ea, 0x001c97e4, 0x001a98e4, 0x001898e4, 0x001a96e3, + 0x001b95e3, 0x001a94e2, 0x001a93e0, 0x001992e1, 0x001891e2, 0x001790e1, 0x00168fe0, 0x00158fdf, + 0x00138ede, 0x00138ddf, 0x00138ce0, 0x00128be0, 0x001189e0, 0x001087de, 0x000f85db, 0x00138ae0, + 0x000f87dc, 0x000f86dc, 0x000f85dc, 0x000f84dc, 0x000e83db, 0x000e83db, 0x000e83db, 0x000e83db, + 0x0034abe2, 0x003cb4ec, 0x0034ace5, 0x0031abe6, 0x002daae8, 0x0044b6eb, 0x0024a7ea, 0x0029aaea, + 0x002face9, 0x0032a9e6, 0x0035a7e3, 0x0030a7e6, 0x002ba8ea, 0x0025aaf0, 0x0020adf6, 0x004d8ba7, + 0x00b8674c, 0x00ff5510, 0x00f7650c, 0x00f86313, 0x00fa611b, 0x00f0671f, 0x00fc6222, 0x00fb6926, + 0x00f96f29, 0x00f67122, 0x00f3721b, 0x00f26b20, 0x00f16424, 0x00ff5622, 0x00ff531f, 0x00ff4b17, + 0x00ff440e, 0x00b1615b, 0x001f95e0, 0x00129bf0, 0x001c9ae5, 0x00189ae6, 0x00159be7, 0x001898e6, + 0x001b95e5, 0x001b95e2, 0x001995e0, 0x001994e1, 0x001892e2, 0x001792e1, 0x001691e0, 0x001590df, + 0x00148fdf, 0x00148fe0, 0x00148fe1, 0x00128de1, 0x00108be0, 0x001189de, 0x001186dd, 0x00178fe4, + 0x000e87db, 0x000e87dc, 0x000f87dd, 0x000f85dc, 0x000e84dc, 0x000e84dc, 0x000e84dc, 0x000e84dc, + 0x0036b1eb, 0x0036b4f0, 0x002eafed, 0x002caeec, 0x002aadec, 0x0041b4ef, 0x0029abe9, 0x002cabe8, + 0x002fabe7, 0x0031abe6, 0x0032aae6, 0x002faae7, 0x002ca9e8, 0x0025a7eb, 0x00946a5f, 0x00ff3e06, + 0x00f95618, 0x00e27312, 0x00f87329, 0x00f77427, 0x00f77626, 0x00f27628, 0x00f8712b, 0x00f9772e, + 0x00f97e30, 0x00f77f2e, 0x00f5812b, 0x00f57b2c, 0x00f5752d, 0x00fd6a2b, 0x00fb652a, 0x00f65e2c, + 0x00f1572e, 0x00ff4810, 0x00ff460f, 0x00817680, 0x0002a7f1, 0x002496ea, 0x00199be4, 0x001b98e4, + 0x001d96e5, 0x001b96e2, 0x001a96e0, 0x001995e1, 0x001794e3, 0x001793e2, 0x001692e1, 0x001691e0, + 0x001590df, 0x001591e1, 0x001591e3, 0x00138fe1, 0x00108ce0, 0x00128be0, 0x00158ae0, 0x00168de2, + 0x000f89dd, 0x000f88dd, 0x000f88dd, 0x000f86dd, 0x000f85dc, 0x000f85dc, 0x000f85dc, 0x000f85dc, + 0x005fc1e7, 0x0057bee8, 0x004fbbe9, 0x004ebae6, 0x004ebae3, 0x0051b6ee, 0x002eaee8, 0x002eade6, + 0x002fabe5, 0x002face7, 0x002eade9, 0x002eace7, 0x002daae5, 0x0015b2ff, 0x00ec4310, 0x00f15016, + 0x00f75d1c, 0x00f87123, 0x00f9862a, 0x00f6882d, 0x00f48b31, 0x00f48532, 0x00f47f33, 0x00f78535, + 0x00fa8c37, 0x00f88e39, 0x00f7903a, 0x00f88b38, 0x00f98635, 0x00f87e35, 0x00f77635, 0x00f76d34, + 0x00f76532, 0x00f85e31, 0x00f95730, 0x00ff5125, 0x00f65237, 0x0003a5fd, 0x001e9be1, 0x001e98e3, + 0x001f96e5, 0x001c97e2, 0x001a97df, 0x001896e1, 0x001795e4, 0x001794e3, 0x001793e2, 0x001692e1, + 0x001692e0, 0x001693e2, 0x001794e4, 0x001391e2, 0x000f8ee0, 0x00148ee1, 0x00198ee3, 0x00148ce1, + 0x000f8bde, 0x000f8ade, 0x000f89de, 0x000f88dd, 0x000f86dd, 0x000f86dd, 0x000f86dd, 0x000f86dd, + 0x003cb6ee, 0x0036b4ef, 0x0030b2f0, 0x0030b1ee, 0x002fb1ec, 0x0038b0ef, 0x002eaee9, 0x002faee8, + 0x0031ade6, 0x002fafe8, 0x002eb1ea, 0x0031adec, 0x0029afee, 0x0030aac8, 0x00ff3d05, 0x00fa501a, + 0x00f96021, 0x00f87428, 0x00f7882f, 0x00fa9638, 0x00f59b38, 0x00f5973b, 0x00f6923e, 0x00f89440, + 0x00fa9742, 0x00fa9a44, 0x00fa9d46, 0x00f99845, 0x00f89444, 0x00f98d43, 0x00fa8641, 0x00f97d3f, + 0x00f9743d, 0x00f77039, 0x00f56d35, 0x00ff6122, 0x00bf6c63, 0x00129eef, 0x00229ae8, 0x001c99ed, + 0x00179ce4, 0x001498f0, 0x001b94e1, 0x001a96e2, 0x001998e3, 0x001897e4, 0x001896e5, 0x001895e4, + 0x001993e2, 0x001792e1, 0x001590df, 0x001692e2, 0x001793e5, 0x001490e4, 0x00128ee2, 0x00118de3, + 0x00108de3, 0x00118bde, 0x001289d9, 0x000f88e2, 0x000c89dd, 0x001085e0, 0x000987e4, 0x000987e4, + 0x0040b5e9, 0x003bb4e9, 0x0037b2ea, 0x0037b2e9, 0x0038b1e8, 0x0033b0ea, 0x002eaeeb, 0x0030afe9, + 0x0033afe8, 0x0030b2ea, 0x002eb5ec, 0x0034aff2, 0x0025b4f7, 0x008d7f86, 0x00f64f00, 0x00ed5c1e, + 0x00fa6326, 0x00f7762d, 0x00f58a35, 0x00fea242, 0x00f7ab3f, 0x00f7a843, 0x00f7a548, 0x00f9a34a, + 0x00faa24c, 0x00fba64f, 0x00fcaa52, 0x00f9a652, 0x00f7a252, 0x00fa9c50, 0x00fd974e, 0x00fc8d4b, + 0x00fb8348, 0x00f68341, 0x00f1823a, 0x00f5732c, 0x00718cac, 0x00179af0, 0x002599ef, 0x002697e9, + 0x00269bc6, 0x001696f1, 0x001d91e3, 0x001c96e3, 0x001b9be3, 0x001a99e6, 0x001998e9, 0x001b97e7, + 0x001c95e5, 0x001891df, 0x00138dda, 0x001992e2, 0x001e98ea, 0x001592e6, 0x000b8de2, 0x000e8ee5, + 0x00108fe9, 0x00128cdf, 0x001489d4, 0x000e88e6, 0x00088cdc, 0x001184e4, 0x000488ec, 0x000488ec, + 0x003eb6ea, 0x003bb5eb, 0x0038b4eb, 0x0038b4eb, 0x0038b3eb, 0x0035b2eb, 0x0033b1ec, 0x0034b1eb, + 0x0035b1ea, 0x0032b3e9, 0x0030b5e9, 0x0034b0f0, 0x0023b6f8, 0x00c56044, 0x00f9540c, 0x00f26322, + 0x00f77029, 0x00f77d2f, 0x00f78b35, 0x00fba142, 0x00f6b046, 0x00fbb44f, 0x00f7b051, 0x00f9af54, + 0x00fbad56, 0x00fcb25a, 0x00feb75d, 0x00fab35f, 0x00f6b061, 0x00faac5d, 0x00fda95a, 0x00fb9f55, + 0x00f99551, 0x00f7914b, 0x00f68d45, 0x00ff7e23, 0x001ba5f0, 0x00129ef4, 0x002896f1, 0x00239fb1, + 0x006c9600, 0x003c9c82, 0x00179ef8, 0x00169cf4, 0x00149de3, 0x00169ae5, 0x001897e7, 0x001995e6, + 0x001a93e5, 0x001993e3, 0x001793e0, 0x001c98e6, 0x001a95e5, 0x001692e5, 0x00138fe5, 0x00138ceb, + 0x00138be3, 0x000087e4, 0x00007cf5, 0x001a86d3, 0x000d8cf1, 0x00008fe2, 0x000d85ea, 0x000886f1, + 0x003cb7ec, 0x003bb7ed, 0x003ab6ed, 0x0039b6ed, 0x0038b5ed, 0x0037b5ed, 0x0037b4ed, 0x0037b3ed, + 0x0036b3ec, 0x0034b4e9, 0x0031b5e5, 0x0035b1ef, 0x0021b8fa, 0x00fd4203, 0x00fc581e, 0x00f86a26, + 0x00f47c2d, 0x00f78431, 0x00f98c36, 0x00f8a041, 0x00f6b54d, 0x00fec05b, 0x00f6bc5a, 0x00f8ba5d, + 0x00fbb861, 0x00fdbe65, 0x00ffc469, 0x00fbc16c, 0x00f5bd70, 0x00fabc6b, 0x00febb66, 0x00fab160, + 0x00f6a75a, 0x00f89f55, 0x00fa984f, 0x00df956f, 0x0008a6fc, 0x00259ddb, 0x00159ff3, 0x004aa172, + 0x0069a90d, 0x0062a406, 0x005a981b, 0x0034969b, 0x000e99ff, 0x001297f2, 0x001695e4, 0x001793e5, + 0x001892e5, 0x001995e6, 0x001a98e7, 0x00209deb, 0x001593df, 0x001892e4, 0x001a91e9, 0x002095eb, + 0x00259dd1, 0x00d0f772, 0x00c1f396, 0x000083f1, 0x001782a0, 0x003c7e2f, 0x001787cc, 0x000b8ada, + 0x003db9ed, 0x003cb8ed, 0x003bb8ed, 0x003ab7ed, 0x0039b7ed, 0x0039b7ed, 0x0039b6ed, 0x003ab6ed, + 0x003ab6ed, 0x0037b4ed, 0x0034b2ec, 0x0035abf3, 0x006e96b3, 0x00ff4601, 0x00f86520, 0x00f67329, + 0x00f58131, 0x00f78b37, 0x00f9953e, 0x00f8a649, 0x00f8b854, 0x00fcc260, 0x00f8c465, 0x00f9c36a, + 0x00fac26e, 0x00fac773, 0x00facb77, 0x00fbcb7b, 0x00fccb7e, 0x00fac87b, 0x00f8c578, 0x00f9bc72, + 0x00fbb46d, 0x00f6b069, 0x00feaa57, 0x0094a0a5, 0x0013a1f3, 0x00219df0, 0x00199eff, 0x0071c124, + 0x0079b826, 0x0072b21e, 0x006aaa24, 0x0067a125, 0x00649a19, 0x00419d72, 0x001f9fcb, 0x001994ff, + 0x001399f1, 0x00199cf4, 0x001ea0f8, 0x001b9cff, 0x001193f6, 0x001293f1, 0x001393ec, 0x000083ff, + 0x0072cca0, 0x00cbf982, 0x00d0ffac, 0x0079a046, 0x00337700, 0x003a7c03, 0x000d8de2, 0x000d8edb, + 0x003fbbee, 0x003ebaed, 0x003db9ed, 0x003cb9ed, 0x003bb8ed, 0x003bb8ed, 0x003cb9ee, 0x003cb9ee, + 0x003db9ef, 0x003ab4f1, 0x0037aff3, 0x0032b3fe, 0x00b48f7d, 0x00ff5907, 0x00f37122, 0x00f57c2b, + 0x00f68735, 0x00f7923d, 0x00f89d45, 0x00f9ac50, 0x00f9bb5a, 0x00f9c465, 0x00facd71, 0x00facd76, + 0x00facd7b, 0x00f7cf80, 0x00f4d286, 0x00fcd689, 0x00ffd98c, 0x00fbd48b, 0x00f3cf8a, 0x00f9c885, + 0x00ffc17f, 0x00f5c27d, 0x00ffbc5e, 0x0048abdc, 0x001e9deb, 0x001ea2e8, 0x001da8e5, 0x0099d31c, + 0x008acb22, 0x0082c427, 0x007abc2c, 0x0075b429, 0x0070ad25, 0x006dab17, 0x006ba908, 0x005ea912, + 0x00519f54, 0x00489b6d, 0x003e9887, 0x003b9592, 0x00389880, 0x00449663, 0x00509446, 0x0083b43c, + 0x004f851b, 0x00afe187, 0x009fcc83, 0x00368011, 0x0043821c, 0x0032853c, 0x000492f9, 0x001092dd, + 0x0040bcee, 0x003fbcee, 0x003ebbee, 0x003dbaed, 0x003cbaed, 0x003cb9ed, 0x003cb9ec, 0x003cb9ec, + 0x003cb8ec, 0x003fb4f0, 0x0043aff5, 0x000ebbe9, 0x00ffb897, 0x00f7814d, 0x00f57623, 0x00f6812e, + 0x00f88c39, 0x00f89943, 0x00f8a64d, 0x00f8b257, 0x00f9bd60, 0x00fac96d, 0x00fbd47b, 0x00fad681, + 0x00fad788, 0x00fbd98e, 0x00fbda93, 0x00fae5a1, 0x00fed692, 0x00fadea0, 0x00f9db98, 0x00fad694, + 0x00fbd090, 0x00ffd285, 0x00ffc778, 0x00009afd, 0x0026a8f2, 0x0020a4f8, 0x0053bea5, 0x00a4da31, + 0x009dd638, 0x0097d03a, 0x0091ca3d, 0x008bc539, 0x0085c035, 0x007dbe31, 0x0074bc2d, 0x0076b81c, + 0x0077b027, 0x0072ab25, 0x006da724, 0x006ba328, 0x0068a31f, 0x0058951a, 0x0078b745, 0x00bbf181, + 0x0073ad4c, 0x00417c15, 0x00508b1e, 0x0043861c, 0x00498614, 0x0017868b, 0x000b90f6, 0x00168ee8, + 0x0042beef, 0x0041bdee, 0x0040bcee, 0x003fbced, 0x003ebbed, 0x003dbaec, 0x003db9eb, 0x003cb8ea, + 0x003bb7e9, 0x0039b9f0, 0x0037bbf7, 0x0050b5dc, 0x00ff9744, 0x00fec49d, 0x00f87a24, 0x00f88530, + 0x00f9913d, 0x00f8a049, 0x00f7af55, 0x00f8b85d, 0x00f9c065, 0x00face75, 0x00fcdb85, 0x00fbde8d, + 0x00fae195, 0x00fee29b, 0x00ffe2a0, 0x00fbe9a4, 0x00ffbe6b, 0x00fdde9f, 0x00ffe8a6, 0x00fbe3a3, + 0x00f8dea0, 0x00fdd899, 0x00b6bdab, 0x00119ff1, 0x001ea4e9, 0x001a9fff, 0x0089d465, 0x00b0e245, + 0x00b0e04e, 0x00acdc4e, 0x00a7d94e, 0x00a1d649, 0x009ad345, 0x0097ce3d, 0x0094c935, 0x008dc534, + 0x0086c133, 0x007bbc32, 0x006fb731, 0x006db330, 0x006cae2e, 0x007eba3f, 0x0070a531, 0x007bb54f, + 0x00579a20, 0x005c9f2b, 0x00519425, 0x0080b965, 0x00609a1d, 0x000390e3, 0x00118ef2, 0x001c89f2, + 0x0044c0ef, 0x0043bfef, 0x0042beee, 0x0040bdee, 0x003fbcee, 0x003fbbed, 0x0040baeb, 0x003eb9ed, + 0x003cb9ee, 0x0037b9eb, 0x0027bcf7, 0x00949c8f, 0x00fb9637, 0x00f9bc7c, 0x00f9b585, 0x00f7994a, + 0x00f69b43, 0x00f6a64e, 0x00f7b259, 0x00f8bc66, 0x00fac672, 0x00fad380, 0x00fae08d, 0x00f9e698, + 0x00f9eba2, 0x00feeaa6, 0x00ffeaab, 0x00fcefa9, 0x00faba62, 0x00fbdc99, 0x00fff4b9, 0x00fbecb2, + 0x00f7e6ab, 0x00ffe5a3, 0x0064b1d1, 0x00199ff0, 0x00269fe9, 0x000499f2, 0x00e3f051, 0x00d5ef58, + 0x00c0e364, 0x00bde165, 0x00bae065, 0x00b5de5d, 0x00b0dc56, 0x00aad74e, 0x00a3d346, 0x009bd043, + 0x0093cd3f, 0x008cc93e, 0x0084c63c, 0x0081c139, 0x007dbc36, 0x008bc746, 0x0089c245, 0x0063a02c, + 0x0065aa2c, 0x005ea42d, 0x00509626, 0x00a4cf98, 0x00d9eadd, 0x00b9ddff, 0x00389ef4, 0x00008fd4, + 0x0046c1ef, 0x0044c0ef, 0x0043bfef, 0x0042beef, 0x0040bdef, 0x0042bced, 0x0043baec, 0x0040baf0, + 0x003dbaf4, 0x0035b8e7, 0x0017bdf7, 0x00d97f50, 0x00f79147, 0x00f7a554, 0x00ffdbba, 0x00f8a24d, + 0x00f3a549, 0x00f5ad53, 0x00f7b55e, 0x00f9c16f, 0x00fbcc7f, 0x00f9d88a, 0x00f8e595, 0x00f8eda2, + 0x00f8f5ae, 0x00fff3b2, 0x00fff2b6, 0x00fef5ae, 0x00f4b659, 0x00f9db93, 0x00feffcd, 0x00fbf6c1, + 0x00f7edb6, 0x00fff2ac, 0x0013a4f7, 0x0016a5f0, 0x0018a5e8, 0x0056b4cd, 0x00f1f271, 0x00d5ef84, + 0x00cfe67b, 0x00cde77c, 0x00cbe77c, 0x00c9e672, 0x00c7e567, 0x00bce15f, 0x00b1dd57, 0x00a9dc51, + 0x00a0da4b, 0x009dd749, 0x009ad447, 0x0094cf43, 0x008fcb3f, 0x0088c43c, 0x0082be39, 0x0072b430, + 0x0063a928, 0x0059a028, 0x004e9827, 0x00a0c479, 0x00fffbf7, 0x007fd3f5, 0x00038fe2, 0x000e89e2, + 0x0048c3ef, 0x0046c2ef, 0x0045c1f0, 0x0043c0f0, 0x0042bff0, 0x0042beee, 0x0043bdec, 0x0041bcef, + 0x003fbcf2, 0x002fc0fe, 0x0036bdfc, 0x00f54c00, 0x00ff8a52, 0x00faa65e, 0x00fdc48e, 0x00fbc185, + 0x00f5ae50, 0x00f7b65e, 0x00f9be6c, 0x00fac978, 0x00fbd485, 0x00fede98, 0x00ffe8aa, 0x00fdeeae, + 0x00f9f5b2, 0x00fcf6ba, 0x00fff7c2, 0x00fcf0b2, 0x00f7cc6e, 0x00fbde91, 0x00fdfcca, 0x00fffbd1, + 0x00fffdc8, 0x00cae4c8, 0x0016a1f2, 0x001da4ef, 0x0012a1f1, 0x009fd5b9, 0x00eaf28c, 0x00dcf095, + 0x00d9eb90, 0x00d9ec93, 0x00d9ec95, 0x00d6eb8c, 0x00d4ea83, 0x00c9e779, 0x00bfe36f, 0x00b8e368, + 0x00b1e262, 0x00afe05e, 0x00addf5a, 0x00a3d952, 0x0099d449, 0x008ecb41, 0x0084c33a, 0x0075b833, + 0x0066ac2c, 0x005da329, 0x00559927, 0x004b9421, 0x002499b9, 0x001593fe, 0x000993d8, 0x000f90d8, + 0x004ac5ef, 0x0048c4f0, 0x0046c2f0, 0x0045c1f1, 0x0043c0f1, 0x0043bfef, 0x0043bfed, 0x0042beee, + 0x0041bdf0, 0x0038bbf0, 0x0072a1b8, 0x00ff5d1e, 0x00f97931, 0x00f5a151, 0x00f9ad61, 0x00fee0bd, + 0x00f8b758, 0x00fabf69, 0x00fcc87a, 0x00fcd282, 0x00fcdc8b, 0x00fbde8f, 0x00fbe193, 0x00fbeba4, + 0x00fbf5b5, 0x00faf8c2, 0x00f9fcce, 0x00f9ecb7, 0x00fae183, 0x00fee290, 0x00fbfac8, 0x00fdf8d8, + 0x00fffccb, 0x008bcedc, 0x00189fee, 0x0025a3ee, 0x000b9dfb, 0x00e8f6a5, 0x00e4f1a6, 0x00e4f0a6, + 0x00e4efa6, 0x00e5f1aa, 0x00e6f2ad, 0x00e3f1a6, 0x00e0ef9e, 0x00d7ec93, 0x00cde987, 0x00c8ea80, + 0x00c2eb78, 0x00c1ea73, 0x00c0e96e, 0x00b1e360, 0x00a3dd53, 0x0094d247, 0x0086c83b, 0x0078bc35, + 0x0069b030, 0x0062a52b, 0x005b9b27, 0x0057920a, 0x000995fc, 0x000d96e5, 0x001091eb, 0x001091eb, + 0x004ac5f0, 0x0049c4f0, 0x0047c3f1, 0x0045c2f1, 0x0044c1f2, 0x0041c1f2, 0x003fc1f2, 0x003fbff1, + 0x003fbcf0, 0x0032c3fe, 0x00be7f6e, 0x00fe6526, 0x00f67b35, 0x00f59a4d, 0x00f8ab5c, 0x00fbd0a0, + 0x00f7c783, 0x00fec16b, 0x00fdd17f, 0x00fbdb87, 0x00f9e590, 0x00f8ed9a, 0x00f7f4a5, 0x00fbea9a, + 0x00ffdf8e, 0x00fce3a0, 0x00f7e6b1, 0x00fceecc, 0x00fffbcb, 0x00fff3c7, 0x00fcf1c3, 0x00fef5d2, + 0x00fffcd3, 0x004bb5e7, 0x0021a5ed, 0x001ca2ee, 0x003daae2, 0x00eef6ac, 0x00e6f2b1, 0x00e8f2b5, + 0x00e9f3b8, 0x00eaf4ba, 0x00ebf5bc, 0x00e8f3b6, 0x00e6f2af, 0x00e0f0a8, 0x00dbeea2, 0x00d6ef9a, + 0x00d1f092, 0x00c9ed82, 0x00c1eb73, 0x00b0e362, 0x00a1dc51, 0x0094d347, 0x0088ca3e, 0x007bbf38, + 0x006eb433, 0x0066a92e, 0x005da01b, 0x003d9448, 0x000a93f6, 0x000e94ec, 0x001193f0, 0x001193f0, + 0x004bc5f1, 0x004ac5f1, 0x0048c4f1, 0x0047c3f2, 0x0045c3f2, 0x0040c3f4, 0x003bc4f6, 0x003cbff3, + 0x003ebbf0, 0x002dcaff, 0x00ff5d25, 0x00fe6d2f, 0x00f37d39, 0x00f59348, 0x00f8a958, 0x00f7c083, + 0x00f7d7ae, 0x00ffc36d, 0x00ffda84, 0x00fbe48c, 0x00f7ee94, 0x00f8ed9e, 0x00faeca7, 0x00f9f1b4, + 0x00f8f6c1, 0x00fcf6c8, 0x00fff6d0, 0x00fef2d3, 0x00fcf4ba, 0x00fffee8, 0x00f7fdea, 0x00fdfde3, + 0x00fffcdc, 0x000b9df1, 0x002aaaed, 0x001baaf6, 0x0080c8da, 0x00fdffbb, 0x00e8f2bd, 0x00ebf4c4, + 0x00eff7cb, 0x00eff7cb, 0x00eff7cb, 0x00edf6c5, 0x00ebf5c0, 0x00eaf4be, 0x00e8f3bd, 0x00e4f4b4, + 0x00e0f6ab, 0x00d0f191, 0x00c1ec77, 0x00b0e463, 0x009edb4e, 0x0095d448, 0x008bcc42, 0x007fc23b, + 0x0073b935, 0x006aac31, 0x0060a510, 0x00229687, 0x000b91f1, 0x000e93f3, 0x001294f5, 0x001294f5, + 0x004cc6f1, 0x004bc5f2, 0x0049c5f2, 0x0047c4f2, 0x0046c4f2, 0x0043c4f1, 0x0040c4f0, 0x0042c0f3, + 0x0039c1f6, 0x005eacca, 0x00fb591e, 0x00f36e31, 0x00f88135, 0x00fb923f, 0x00fbaf5e, 0x00ffc373, + 0x00fde2ba, 0x00ffcd75, 0x00ffd372, 0x00ffe584, 0x00fff796, 0x00fef4a2, 0x00fdf1ae, 0x00fff8c2, + 0x00fcf8cd, 0x00fef8d2, 0x00fff9d6, 0x00fef6e1, 0x00fcf5dd, 0x00fffbee, 0x00fbfce8, 0x00fffce0, + 0x00b2e0e8, 0x0019a4f0, 0x0026abec, 0x0016a8f6, 0x00c2e4d8, 0x00f9fac5, 0x00eff6cb, 0x00f0f7ce, + 0x00f1f8d2, 0x00f1f8d1, 0x00f2f9d1, 0x00f1f9cd, 0x00f1f9ca, 0x00f2fbca, 0x00f4fdca, 0x00e7f8b6, + 0x00daf3a2, 0x00cbef8a, 0x00bcec71, 0x00b0e661, 0x00a5e151, 0x009ad949, 0x008fd240, 0x0083c73b, + 0x0077bc35, 0x006ab31d, 0x005ea905, 0x00138dea, 0x001193ef, 0x001093f0, 0x000f93f0, 0x000f93f0, + 0x004dc6f2, 0x004cc6f2, 0x004ac5f3, 0x0048c5f3, 0x0047c5f3, 0x0046c4ef, 0x0046c4eb, 0x0048c0f3, + 0x0034c7fb, 0x00989591, 0x00fc6428, 0x00f1773b, 0x00fc8432, 0x00ff9135, 0x00ffb564, 0x00ffbe5a, + 0x00f3ddb6, 0x00ccd097, 0x00b4cea5, 0x00b0d3b1, 0x00abd7bd, 0x00c3e1bf, 0x00daebc1, 0x00f5fdc7, + 0x00ffffbd, 0x00fffecd, 0x00fffcdc, 0x00fffce0, 0x00fbfce5, 0x00fdfbe6, 0x00fffae7, 0x00fffbdd, + 0x0061c4f4, 0x0026aaee, 0x0022abec, 0x0010a7f6, 0x00ffffd7, 0x00f5f5d0, 0x00f6fad9, 0x00f4f9d9, + 0x00f2f9da, 0x00f3fad8, 0x00f4fbd7, 0x00f5fcd5, 0x00f7fdd4, 0x00f3face, 0x00f0f7c8, 0x00e2f4b0, + 0x00d4f199, 0x00c5ee82, 0x00b7eb6b, 0x00b1e95f, 0x00abe754, 0x009fdf49, 0x0094d83f, 0x0087cc3a, + 0x007bc034, 0x006bb425, 0x005ba332, 0x000495f9, 0x001795ee, 0x001293ed, 0x000c91eb, 0x000c91eb, + 0x004fc8f3, 0x004dc8f3, 0x004cc8f4, 0x004bc8f4, 0x0049c8f4, 0x0047c5f2, 0x0045c2ef, 0x0042c2f8, + 0x0034c8ff, 0x00df6746, 0x00ff632a, 0x00ff701b, 0x00e18b53, 0x00a4a185, 0x0063c1cd, 0x0026c0ff, + 0x002ab8ff, 0x0025b5f1, 0x0027b7f9, 0x0026b5f6, 0x0023b3f2, 0x0024b5fa, 0x0025b7ff, 0x00189ddf, + 0x0043bbf4, 0x009edae8, 0x00f9f9dc, 0x00f3fbe6, 0x00ffffea, 0x00fdffe6, 0x00fafce2, 0x00ffffff, + 0x001ea8ef, 0x001ca8f1, 0x001ba8f2, 0x005bc4f1, 0x00ffffe7, 0x00fbf9e1, 0x00fbfce3, 0x00f8fbe0, + 0x00f5fadd, 0x00f5fbdb, 0x00f5fbda, 0x00f6fcd7, 0x00f6fdd3, 0x00f0f8c9, 0x00ebf4be, 0x00dff2a9, + 0x00d4f094, 0x00c7f47b, 0x00baf862, 0x00b0ef58, 0x00a6e64e, 0x00a3e248, 0x0098d73a, 0x008acd38, + 0x007bc435, 0x0070b821, 0x003b9c84, 0x000d93f4, 0x001394ed, 0x001193e9, 0x000f92e6, 0x000f92e6, + 0x0050c9f4, 0x004fcaf4, 0x004ecaf5, 0x004dcaf5, 0x004ccaf6, 0x0048c5f4, 0x0045c0f3, 0x0047c2ef, + 0x004ac4eb, 0x00ff521f, 0x00a79a92, 0x0051b7e6, 0x0028c7ff, 0x002cc4f9, 0x0031c1f1, 0x003fbbf0, + 0x0037c0ef, 0x0039b9f0, 0x003bb3f1, 0x0038b5f4, 0x0036b7f7, 0x0032b9f0, 0x002fbbe8, 0x002fb8eb, + 0x002fb5ed, 0x0020acf3, 0x0010a3fa, 0x0070c9f3, 0x00f5f9df, 0x00f6fbde, 0x00f6fdde, 0x00d8ebe4, + 0x0011a5ee, 0x002db2f5, 0x0014a5f8, 0x00a5e2ec, 0x00fffff8, 0x00fffef3, 0x00fffded, 0x00fcfde6, + 0x00f8fce0, 0x00f7fcde, 0x00f6fcdd, 0x00f6fcd8, 0x00f5fdd3, 0x00edf7c4, 0x00e5f1b4, 0x00e5f5b8, + 0x00e4f9bb, 0x00ecfed2, 0x00f3ffe9, 0x00edfedb, 0x00e8f9cd, 0x00caef89, 0x009cd636, 0x0084c72e, + 0x006bb826, 0x006cb315, 0x001a95d6, 0x001591ef, 0x001093eb, 0x001193e6, 0x001294e1, 0x001294e1, + 0x0052cbf4, 0x0050caf4, 0x004ecaf4, 0x004ccaf3, 0x004ac9f3, 0x0048c8f5, 0x0046c7f6, 0x0040bfed, + 0x0041bfeb, 0x0041d4f9, 0x0033c9fc, 0x002fc9ff, 0x0042c3ec, 0x0040c3f4, 0x003ec3fc, 0x0035bbf4, + 0x0033bbf3, 0x0049bdf7, 0x0039b7f9, 0x0037b7f6, 0x0035b7f2, 0x002eb5f4, 0x0028b3f5, 0x002fbbf8, + 0x002fbaf2, 0x0030b5f2, 0x0031b0f1, 0x001facf6, 0x000dabed, 0x007fd2ed, 0x00ffffe6, 0x0080d9d2, + 0x002faaf8, 0x001dafec, 0x0003aae6, 0x00fff8ff, 0x00fffffe, 0x00fffff9, 0x00fffdf4, 0x00fdfeeb, + 0x00fbfee3, 0x00f9fde1, 0x00f7fce0, 0x00f5fdd8, 0x00f4fdcf, 0x00f5fce2, 0x00f6fde8, 0x00f3fde8, + 0x00f1fde9, 0x00ebfdd3, 0x00e6fdbe, 0x00e0f8ba, 0x00daf2b7, 0x00eafcd2, 0x00f2fde6, 0x00b7de8d, + 0x0084c73d, 0x009ab848, 0x0014a1f9, 0x000494f3, 0x001094ef, 0x001095ec, 0x001095e9, 0x001095e9, + 0x0054ccf5, 0x0051cbf4, 0x004ecaf3, 0x004cc9f2, 0x0049c8f1, 0x0048cbf5, 0x0048cef9, 0x0040c4f3, + 0x0049cafc, 0x0040c2f1, 0x0047caf5, 0x0046c7f4, 0x0046c4f3, 0x0039b5ee, 0x002ca5e8, 0x002eb1e1, + 0x0056c1ea, 0x006dc9e9, 0x0037c2e5, 0x0051caeb, 0x006bd2f1, 0x0074d1f5, 0x007dcff9, 0x0056c7f8, + 0x001fafe8, 0x0025b1ee, 0x002cb3f4, 0x003eb5f9, 0x002bb3ee, 0x001baff5, 0x0032b5f0, 0x003fb2f9, + 0x0026a9f2, 0x001faeeb, 0x003fb8f4, 0x00fcfff3, 0x00ffffff, 0x00ffffff, 0x00fffefb, 0x00fefff1, + 0x00feffe6, 0x00fbffe5, 0x00f8fde3, 0x00f5fdd7, 0x00f3fecb, 0x00f5fbeb, 0x00f7feee, 0x00f2fdde, + 0x00edfccf, 0x00e3f9b0, 0x00d9f692, 0x00d2f48b, 0x00ccf184, 0x00ceee97, 0x00d0eaa9, 0x00daebc1, + 0x00f4fbe9, 0x007fc679, 0x005ac1ff, 0x001aa1eb, 0x001195f2, 0x000f96f2, 0x000e97f2, 0x000e97f2, + 0x0054cdf5, 0x0052ccf4, 0x004fcbf3, 0x004dc9f3, 0x004ac8f2, 0x0049c6f2, 0x0047c4f2, 0x0049d2f3, + 0x0046c8f3, 0x004dc5fc, 0x002c9add, 0x001883cd, 0x00046cbe, 0x000080c5, 0x000f96d4, 0x002eaddb, + 0x0060c6eb, 0x0076cdef, 0x0051caea, 0x0069d2f0, 0x0081daf5, 0x009ae4f7, 0x00b3eff9, 0x00cffaff, + 0x00e3feff, 0x009ae1ff, 0x0048bcf7, 0x0011b5dd, 0x0032aef0, 0x0028acfc, 0x0031b2f3, 0x0034b1f6, + 0x0025adf0, 0x0026acf6, 0x0098d1fc, 0x00fffdf8, 0x00ffffff, 0x00fffffb, 0x00fefff4, 0x00fdffee, + 0x00fcfde7, 0x00fbfee4, 0x00faffe0, 0x00f8fde7, 0x00f7fcef, 0x00f3fbeb, 0x00effdd9, 0x00e9fbc2, + 0x00e3f9ac, 0x00d9f49b, 0x00ceef8b, 0x00c1ea76, 0x00b4e562, 0x00abdd5a, 0x00a2d261, 0x00c1e98e, + 0x00dbe8b9, 0x0096d4ff, 0x008ed0fa, 0x0042aeee, 0x001095f1, 0x001096f1, 0x000f96f1, 0x000f96f1, + 0x0055cef5, 0x0053ccf4, 0x0050cbf4, 0x004ecaf4, 0x004cc8f4, 0x0051caf7, 0x0057cbfa, 0x0045c0ea, + 0x001a75c7, 0x000058ad, 0x00015bb4, 0x00066fc0, 0x000b84cd, 0x000093ce, 0x0011a7e0, 0x003eb9e6, + 0x006bcbeb, 0x007ed1f6, 0x006cd3f0, 0x0082dbf4, 0x0098e3f9, 0x00a5ecf7, 0x00b2f4f5, 0x00c7f7f9, + 0x00ddfafd, 0x00f2ffff, 0x00f8fff6, 0x00bcebfe, 0x0022b4f2, 0x0029afff, 0x002fb0f7, 0x0029b1f2, + 0x0023b1ee, 0x001aa7fa, 0x00cae6f4, 0x00f7f8f4, 0x00feffff, 0x00fefff7, 0x00feffed, 0x00fcffeb, + 0x00fbfae9, 0x00fbfee3, 0x00fbffdc, 0x00fbffe9, 0x00fbfff7, 0x00f1fedd, 0x00e7fbc3, 0x00e0f6b4, + 0x00d8f0a5, 0x00ceec94, 0x00c4e884, 0x00b8e678, 0x00ace36c, 0x00a0df53, 0x0094d455, 0x0080bd41, + 0x00d2e599, 0x002ca1f4, 0x0030a2f6, 0x00209cf3, 0x001096f1, 0x001096f1, 0x001096f1, 0x001096f1, + 0x0055cef4, 0x0053cdf4, 0x0051cbf5, 0x0050cbf5, 0x004ecaf6, 0x004dc9f4, 0x0054d0fa, 0x002b86ce, + 0x000752b1, 0x00045fb9, 0x000a74c9, 0x000882ce, 0x000691d4, 0x0002a0d5, 0x0024b5e7, 0x004cc4ea, + 0x0074d3ee, 0x0083d9f5, 0x007fddf4, 0x0093e4f6, 0x00a8ecf9, 0x00b6f2f9, 0x00c3f9f9, 0x00d3fafb, + 0x00e3fcfc, 0x00edfefb, 0x00f0f9f3, 0x00ffffff, 0x00fffdff, 0x007edcef, 0x0026adfd, 0x002aaff7, + 0x002db2f2, 0x0034b1e0, 0x0009a7f7, 0x008dd3f5, 0x00fdfbf9, 0x00fffff6, 0x00fdffeb, 0x00fcffe6, + 0x00fcfce0, 0x00f9fcde, 0x00f7fcdd, 0x00fcffef, 0x00f9fdec, 0x00e8f5d0, 0x00dff5bd, 0x00d9f1ad, + 0x00d2ed9d, 0x00c5e97e, 0x00b8e26d, 0x00abdd5e, 0x009fd74f, 0x0098c95f, 0x0092c735, 0x008bc942, + 0x0080b34d, 0x00009bf2, 0x001894f8, 0x001595f5, 0x001397f2, 0x001296f1, 0x001195f0, 0x001195f0, + 0x0056cff4, 0x0054cdf5, 0x0052ccf5, 0x0051cbf7, 0x0051cbf9, 0x0049c8f1, 0x0051d5fa, 0x001662c1, + 0x00005cbb, 0x000874cd, 0x00037cce, 0x00028dd4, 0x00019edb, 0x0009aedc, 0x0037c2ee, 0x005acfef, + 0x007edcf0, 0x0088e1f4, 0x0092e6f8, 0x00a5eef8, 0x00b9f5f9, 0x00c7f9fb, 0x00d5fdfe, 0x00dffdfc, + 0x00e9fdfa, 0x00f0fefe, 0x00f8ffff, 0x00fafffe, 0x00fdfffc, 0x00fdfbff, 0x001db0e8, 0x002ab1ee, + 0x0037b2f5, 0x0025b9f7, 0x0029b4f8, 0x0022aff5, 0x001baaf2, 0x009fd7f6, 0x00fdffea, 0x00fcfee0, + 0x00fcfdd7, 0x00f8fada, 0x00f4f7dd, 0x00fdfef5, 0x00f6fae1, 0x00dfecc3, 0x00d8efb6, 0x00d2eca6, + 0x00ccea95, 0x00bce567, 0x00abdb56, 0x009fd344, 0x0092cb33, 0x0085c824, 0x0079b46a, 0x003a9eaf, + 0x000c97ff, 0x001994f9, 0x000f9bee, 0x00139af0, 0x001699f3, 0x001497f1, 0x001295ef, 0x001295ef, + 0x0058d0f5, 0x0056cef5, 0x0053cdf4, 0x0053ccf6, 0x0052cbf8, 0x0053d6fb, 0x004fc8fc, 0x00004cad, + 0x00096fca, 0x000b80d4, 0x000588d5, 0x000598db, 0x0005a8e1, 0x0018b6e6, 0x003fc8f2, 0x0063d3f3, + 0x0086dff5, 0x0091e4f7, 0x009ce9fa, 0x00aef0f9, 0x00c0f7f9, 0x00cbfafb, 0x00d7fdfd, 0x00defdfc, + 0x00e6fefb, 0x00f0fffe, 0x00faffff, 0x00f2fefb, 0x00fefffd, 0x00c6e9fb, 0x001eb0ec, 0x0030b4f6, + 0x0030b7f8, 0x0019a8f7, 0x0026b0f0, 0x0022aef3, 0x001eabf5, 0x0027aafa, 0x001ca6f6, 0x007dcdea, + 0x00dff4dd, 0x00eaffb0, 0x00fdfeed, 0x00ffffef, 0x00fcf9d3, 0x00edeeb4, 0x00e6e9ac, 0x00d9e68a, + 0x00cbe367, 0x00b9e153, 0x00a6dd4d, 0x0075c57f, 0x0043adb0, 0x00229bf3, 0x000a9cff, 0x000998f6, + 0x00109cef, 0x00189aee, 0x00149ded, 0x00159bf0, 0x001599f2, 0x001397f0, 0x001195ee, 0x001195ee, + 0x005ad1f6, 0x0057cff5, 0x0054cef4, 0x0054cdf6, 0x0053cbf8, 0x004dd3f4, 0x002c9add, 0x00045ec1, + 0x000572c9, 0x000683d2, 0x000794dc, 0x0008a2e2, 0x0008b1e8, 0x0028bfef, 0x0048cef6, 0x006bd8f8, + 0x008fe3fa, 0x009be8fa, 0x00a6edfb, 0x00b7f3fb, 0x00c7f9fa, 0x00d0fbfc, 0x00d9fdfd, 0x00defefd, + 0x00e2fffc, 0x00effffe, 0x00fcffff, 0x00ebfef7, 0x00fffffe, 0x008fd7f8, 0x001eb0f1, 0x002eb0f6, + 0x0018abec, 0x00e0f7fd, 0x0024ade9, 0x0023acf1, 0x0021acf8, 0x0026aef7, 0x002cb0f6, 0x001aa9f5, + 0x0008a3f4, 0x0022a7f9, 0x004cc2f2, 0x006dcdef, 0x007ec9db, 0x007fcac2, 0x0081c6c6, 0x0061bccb, + 0x0041b3d0, 0x0024a7e9, 0x00089bff, 0x00119dff, 0x001a9fff, 0x000f99e9, 0x00149cf9, 0x00159cf7, + 0x00159cf5, 0x00179df1, 0x00199eed, 0x00179cef, 0x001599f1, 0x001397ef, 0x001195ed, 0x001195ed, + 0x005cd2f6, 0x0059d0f5, 0x0055cff3, 0x0054cdf5, 0x0053ccf8, 0x0051d5f6, 0x00167bcf, 0x000467c6, + 0x00067bcf, 0x00068bd7, 0x00059cdf, 0x0008a9e5, 0x000ab6eb, 0x002bc4f1, 0x004cd2f7, 0x006ddbf9, + 0x008ee5fa, 0x009deafb, 0x00aceffb, 0x00bdf5fb, 0x00cefbfa, 0x00d5fbfc, 0x00dcfcfd, 0x00dcfefd, + 0x00ddfffd, 0x00e4fffd, 0x00eafffd, 0x00fffffe, 0x00ffffff, 0x0027c0de, 0x0026b5f6, 0x001fb0f9, + 0x004dc6ff, 0x00fff9ef, 0x00fefffa, 0x008bd8f7, 0x0018a7f3, 0x001daaf4, 0x0023acf6, 0x0022acf3, + 0x0022abf0, 0x001aa3f2, 0x001aa6ee, 0x0018a8f5, 0x000ea2f3, 0x0011a4f2, 0x0014a4ff, 0x0015a3fc, + 0x0016a3fa, 0x0017a2f3, 0x0019a2ec, 0x000e99fe, 0x00169bed, 0x0000a1ff, 0x002b9de8, 0x0061b5b0, + 0x00109af7, 0x00149cf2, 0x00189eed, 0x00169cef, 0x00149af0, 0x001298ee, 0x001096ec, 0x001096ec, + 0x005fd3f7, 0x005bd2f5, 0x0056d0f3, 0x0055cef5, 0x0053cdf7, 0x0056d8f8, 0x00005cc0, 0x000370cb, + 0x000785d6, 0x000594dc, 0x0004a3e2, 0x0008afe8, 0x000cbcee, 0x002ec8f3, 0x0050d5f9, 0x006fdefa, + 0x008de7fb, 0x009fecfb, 0x00b1f2fb, 0x00c3f7fb, 0x00d4fcfa, 0x00d9fcfc, 0x00defcfd, 0x00dbfdfd, + 0x00d9fffd, 0x00d9fdfb, 0x00d9fcfa, 0x00e5fafa, 0x00a4eaf7, 0x002badfb, 0x002fb9fa, 0x001aaeed, + 0x0099dbf8, 0x00ffffff, 0x00fefdfc, 0x00fffefd, 0x00fffffd, 0x008cd4fa, 0x0019a9f6, 0x0018a9f7, + 0x0016aaf9, 0x001aa7f3, 0x001ea5ee, 0x001fa7f2, 0x0021a9f6, 0x001ea7f7, 0x001ba5f7, 0x0017a4f9, + 0x0012a2fb, 0x000b9dfd, 0x000399fe, 0x0026a2fa, 0x006fc0b0, 0x00cfca5e, 0x00ffe528, 0x0074b4b3, + 0x000b98fa, 0x00119af4, 0x00179dee, 0x00159cee, 0x00139aef, 0x001198ed, 0x000f96eb, 0x000f96eb, + 0x005dd1f6, 0x005bd2f5, 0x0058d2f4, 0x0053cef4, 0x0056d2fb, 0x0040b2e6, 0x000164c6, 0x000376cf, + 0x000487d7, 0x000296dd, 0x0001a4e4, 0x0004b1ea, 0x0007bdf1, 0x001bc8f2, 0x0043d5fc, 0x0064ddfb, + 0x0085e6fb, 0x0098ebfc, 0x00acf1fd, 0x00bef9ff, 0x00cfffff, 0x00cffdff, 0x00cff9fb, 0x00d2fefe, + 0x00d5ffff, 0x00c6f9ff, 0x00b8efff, 0x005ad7d9, 0x0040b9e9, 0x002fb9ff, 0x002bb2f0, 0x0028afeb, + 0x00def0f2, 0x00ffffff, 0x00feffff, 0x00fffefe, 0x00fffefa, 0x00fffffa, 0x00fffff9, 0x00c2e8f0, + 0x0084cde7, 0x0053bbe9, 0x0022a9eb, 0x0014a1ff, 0x00069ff8, 0x000fa0f8, 0x0019a3eb, 0x0043b1e1, + 0x006ec2c9, 0x00b0d79a, 0x00f2eb6b, 0x00ebee32, 0x00f8e647, 0x00ffe23a, 0x00fde142, 0x000098f4, + 0x0019a1fc, 0x00169ef7, 0x00129bf1, 0x00139af1, 0x00149af0, 0x001298ee, 0x001096ec, 0x001096ec, + 0x005ccff6, 0x005bd2f6, 0x005ad4f6, 0x0052cdf2, 0x005ad6fe, 0x00298cd5, 0x00026ccc, 0x00027bd2, + 0x000189d8, 0x000097df, 0x0000a6e6, 0x0000b2ed, 0x0002bef4, 0x0009c7f1, 0x0035d5ff, 0x0059ddfd, + 0x007ce5fb, 0x0091eafd, 0x00a6f0ff, 0x00b1f2ff, 0x00bbf5ff, 0x00bef5fc, 0x00c1f6f9, 0x00c1f7f7, + 0x00c1f9f4, 0x00c7fdfc, 0x00cdffff, 0x00c2f9f8, 0x005acdf4, 0x0039b1f3, 0x0038baf5, 0x002ab4f7, + 0x00fcfbf8, 0x00fdfeff, 0x00feffff, 0x00fffeff, 0x00fffcf6, 0x00fdfef2, 0x00f7ffee, 0x00fcffea, + 0x00ffffe5, 0x00ffffd8, 0x00ffffcb, 0x00fffbf1, 0x00ffffdf, 0x00fdfdc2, 0x00f7ff88, 0x00fbfe92, + 0x00ffff7f, 0x00fdfc6c, 0x00faf759, 0x00f8f059, 0x00f7e958, 0x00f7e359, 0x00d0d368, 0x000998ff, + 0x00189aef, 0x00129af2, 0x000c99f5, 0x001199f3, 0x001599f2, 0x001397f0, 0x001195ee, 0x001195ee, + 0x005fd2f9, 0x005cd3f8, 0x0059d4f6, 0x0058d3f8, 0x005edaff, 0x001971cd, 0x00026ecd, 0x00037bd3, + 0x000488d9, 0x000497e0, 0x0005a6e6, 0x0001ade7, 0x0000b5e8, 0x0007beea, 0x0023cbf5, 0x004cd7f8, + 0x0074e4fc, 0x0089e8fd, 0x009fecfe, 0x00a5edfe, 0x00abeffe, 0x00aeeffc, 0x00b0eff9, 0x00b3f3f9, + 0x00b6f6f8, 0x00b6f9fc, 0x00b5fcff, 0x00daf3ff, 0x001ab9f1, 0x0028b3f4, 0x002bb3f6, 0x0073cef4, + 0x00fdfdf5, 0x00fdfefa, 0x00fdfffe, 0x00fffef9, 0x00fffdf3, 0x00fdfeee, 0x00faffe9, 0x00fdffe4, + 0x00ffffde, 0x00ffffd0, 0x00ffffc2, 0x00fdfad7, 0x00fffcf3, 0x00ffffc0, 0x00fcfbc5, 0x00fcff84, + 0x00fcfb8b, 0x00fbf67a, 0x00f9f269, 0x00f7ed5e, 0x00f4e954, 0x00f7e948, 0x0087bda9, 0x00109afc, + 0x00179cf2, 0x00149bf1, 0x00119af1, 0x001399f2, 0x001698f3, 0x001496f1, 0x001294ef, 0x001294ef, + 0x0062d4fc, 0x005dd4f9, 0x0059d4f6, 0x0056d1f6, 0x0053cef5, 0x00014ebe, 0x00026fcd, 0x00057bd4, + 0x000787da, 0x000996e0, 0x000ca5e7, 0x000bb0e9, 0x0009bbeb, 0x0015c5f3, 0x0021d0fc, 0x0046dafc, + 0x006ce3fc, 0x0082e6fd, 0x0097e9fe, 0x0099e9fe, 0x009ce8fe, 0x009ee9fb, 0x00a0e9f9, 0x00a6eefa, + 0x00acf3fc, 0x00b0effc, 0x00b5ecfb, 0x0089ddf9, 0x0028b4f3, 0x003ebef7, 0x001eadf7, 0x00bde8f0, + 0x00fefff2, 0x00fefff3, 0x00fdfff4, 0x00fefef2, 0x00fefef0, 0x00fefeea, 0x00fefee4, 0x00fefede, + 0x00fefed8, 0x00fcffc9, 0x00fbffba, 0x00f6fea0, 0x00ffffce, 0x00fff9f6, 0x00ffffc9, 0x00fdf7be, + 0x00f8f87a, 0x00f9f66b, 0x00f9f35c, 0x00f5ee56, 0x00f1e84f, 0x00f8ee37, 0x003fa7ea, 0x00189df5, + 0x00179df4, 0x00169cf1, 0x00159bee, 0x00169af2, 0x001798f5, 0x001596f3, 0x001394f1, 0x001394f1, + 0x0066d7fc, 0x005fd1f5, 0x0060d4f6, 0x0059d8f9, 0x00399ddb, 0x000858be, 0x00096ccd, 0x000c7ad2, + 0x001087d7, 0x001296df, 0x0013a6e8, 0x0013b0eb, 0x001bc3f5, 0x000fc8f3, 0x0017d0f9, 0x0027d3f4, + 0x004bd7f7, 0x0061dbf8, 0x0077def9, 0x007fe0fa, 0x0088e1fa, 0x008de4fb, 0x0091e7fb, 0x0096eafc, + 0x009aedfd, 0x009feafb, 0x00a3e7fa, 0x005eccfb, 0x002db7f5, 0x0024b8f9, 0x0014b1f5, 0x00fffbff, + 0x00feffec, 0x00ffffed, 0x00ffffee, 0x00ffffec, 0x00fefdeb, 0x00fefde4, 0x00fefddd, 0x00fefed6, + 0x00fefece, 0x00fcfdc1, 0x00fcfcb5, 0x00f6fb8d, 0x00f8fc8a, 0x00f8facc, 0x00f8fef2, 0x00f9ffbe, + 0x00fbf9c2, 0x00fbf8ac, 0x00fcf796, 0x00faf491, 0x00f7f18d, 0x00ffe5a9, 0x000096f7, 0x00089af7, + 0x00159ef7, 0x00169df4, 0x00169cf0, 0x00169bf2, 0x001699f4, 0x001497f3, 0x001396f1, 0x001396f1, + 0x006bd9fb, 0x0061cef1, 0x0067d3f7, 0x005cdefd, 0x001f6cc0, 0x000f63bf, 0x000f6acd, 0x001478d1, + 0x001887d4, 0x001997df, 0x001aa6e9, 0x0014a9e4, 0x001dbbef, 0x000dbeeb, 0x0023c5f6, 0x0013c6ed, + 0x002acbf3, 0x0040cff4, 0x0056d4f4, 0x0065d7f6, 0x0074daf7, 0x007bdffb, 0x0083e5fe, 0x0086e6fe, + 0x0089e8fd, 0x008ee5fb, 0x0092e2fa, 0x0033bcfc, 0x0032b9f7, 0x0031bafd, 0x0057c5f7, 0x00f4ffde, + 0x00fdffe7, 0x00ffffe7, 0x00ffffe7, 0x00ffffe6, 0x00fdfce6, 0x00fdfddd, 0x00fdfdd5, 0x00fdfdcd, + 0x00fefdc5, 0x00fdfaba, 0x00fcf8af, 0x00fef99f, 0x00fffb8e, 0x00fafe77, 0x00f4fb7d, 0x00f9f8d2, + 0x00fdffee, 0x00fefedf, 0x00fffcd0, 0x00fefacd, 0x00fdf9ca, 0x00a6d3ce, 0x000399eb, 0x001ea1ec, + 0x00149ffa, 0x00159ef6, 0x00179ef2, 0x00169cf3, 0x00159af3, 0x001499f2, 0x001398f1, 0x001398f1, + 0x0055d4f4, 0x005bd1f1, 0x0069d6f6, 0x006ee2ff, 0x000c50a8, 0x001161be, 0x000f6acd, 0x001f83d6, + 0x001f89dc, 0x000f8cdd, 0x001a9be0, 0x0022b1f4, 0x001dabe1, 0x0014aedf, 0x0026bdee, 0x0015bae7, + 0x001fc1ef, 0x0025c7ef, 0x002bcdef, 0x003dcdf1, 0x004ecef3, 0x005bd6f9, 0x0068defe, 0x006eddfc, + 0x0073ddfb, 0x0076ddf5, 0x0070d3f7, 0x0031bafb, 0x0033b9f6, 0x0024b6ff, 0x00a4dee5, 0x00f9ffdc, + 0x00fdfedc, 0x00ffffdc, 0x00ffffdc, 0x00fefedb, 0x00fcfdda, 0x00fdfdd2, 0x00fdfdcb, 0x00fdfdc3, + 0x00fefdbc, 0x00fdfbaf, 0x00fcfaa2, 0x00fdfb93, 0x00fefb83, 0x00fcfd6b, 0x00f9fc60, 0x00fbf85d, + 0x00fdf74c, 0x00fef576, 0x00fff2a1, 0x00f6ec87, 0x00f8e360, 0x0051bbb4, 0x000d9afe, 0x001a9ef7, + 0x00159ef6, 0x00159df4, 0x00159df2, 0x00149bf2, 0x001299f2, 0x001299f2, 0x001299f2, 0x001299f2, + 0x0067d4fd, 0x0069d6f9, 0x006cd9f5, 0x004fb7dc, 0x001953af, 0x001c67c6, 0x00005abd, 0x001a7eca, + 0x00157bd4, 0x000581dc, 0x002aa1e7, 0x000189d3, 0x002dabe3, 0x0023a7dc, 0x0029b4e6, 0x0017ade1, + 0x0014b7ec, 0x0015b9ea, 0x0016bbe9, 0x001fbfec, 0x0028c2ef, 0x003bcdf7, 0x004ed8ff, 0x0056d5fb, + 0x005dd2f8, 0x005ed6f0, 0x004ec5f4, 0x002fb9fa, 0x0035b8f4, 0x0017b1ff, 0x00f0f7d2, 0x00feffda, + 0x00fdfcd2, 0x00fdfdd1, 0x00fdfed1, 0x00fdfecf, 0x00fcfecd, 0x00fcfdc7, 0x00fdfdc0, 0x00fdfdb9, + 0x00fdfdb2, 0x00fdfca4, 0x00fdfc95, 0x00fdfc87, 0x00fdfc79, 0x00fdfa6c, 0x00fef85f, 0x00f9f645, + 0x00f6ef47, 0x00f2e938, 0x00efe428, 0x00eee425, 0x00ffdd05, 0x000399ff, 0x0017a1f5, 0x00179ef4, + 0x00169cf3, 0x00159cf3, 0x00149cf3, 0x00129bf1, 0x001099f0, 0x00119af1, 0x00129bf2, 0x00129bf2, + 0x0066d5fb, 0x0070d5fc, 0x0078e2ff, 0x003b86c7, 0x00235fba, 0x001e6aba, 0x00227ad1, 0x002787d8, + 0x00248cd7, 0x001d8dd4, 0x002189d1, 0x002ca1ea, 0x002296d5, 0x0031aaef, 0x0020a1db, 0x0017a1dd, + 0x000ea1e0, 0x001aace3, 0x0013b1eb, 0x0010b8ed, 0x000dc0ef, 0x001cc1ef, 0x002cc3f0, 0x0036c4f2, + 0x0040c5f4, 0x0047c9f2, 0x0045c3f6, 0x0031bafa, 0x0031b7f7, 0x004cc2f4, 0x00f5fac0, 0x00fdffc6, + 0x00fdfcc5, 0x00fdfdc4, 0x00fdfdc4, 0x00fcfdc2, 0x00fbfdc1, 0x00f8f9b6, 0x00fdfdb3, 0x00fdfdab, + 0x00fdfca3, 0x00fcfc95, 0x00fcfb88, 0x00fcfb7b, 0x00fbfb6d, 0x00fcf962, 0x00fcf757, 0x00f8f245, + 0x00f4eb41, 0x00f0e532, 0x00ebe023, 0x00fbe01c, 0x00c5d244, 0x000aa2fe, 0x00169ff9, 0x00179ff6, + 0x00189ff3, 0x00179ef2, 0x00159df2, 0x00179ff5, 0x0018a1f8, 0x00159ef5, 0x00129bf2, 0x00129bf2, + 0x0065d7fa, 0x0064d1f7, 0x005de7ff, 0x0004439b, 0x000e4ca5, 0x00317bcd, 0x000455c1, 0x000053c9, + 0x000368c6, 0x002687ca, 0x002881ca, 0x002789d1, 0x002791d7, 0x000774c9, 0x00178dcf, 0x001f9ce1, + 0x00179be4, 0x001e9eda, 0x000097de, 0x0003a5e6, 0x0008b1ee, 0x0009b0e8, 0x000aafe2, 0x0017b4e9, + 0x0024b9ef, 0x0030bdf4, 0x003cc1f9, 0x0034bcf9, 0x002cb6f9, 0x0080d2e8, 0x00fafdaf, 0x00fcfdb3, + 0x00fdfcb7, 0x00fdfcb7, 0x00fdfdb7, 0x00fcfcb6, 0x00fbfcb5, 0x00f4f4a5, 0x00fdfda5, 0x00fcfc9d, + 0x00fcfc94, 0x00fbfb87, 0x00fbfb7b, 0x00fafa6e, 0x00fafa61, 0x00faf758, 0x00faf54e, 0x00f7ee44, + 0x00f3e73a, 0x00ede12c, 0x00e7db1e, 0x00ffd21a, 0x0078b090, 0x0009a0fd, 0x00159dfd, 0x0018a0f8, + 0x001aa2f2, 0x0018a0f2, 0x00169ef2, 0x00139bf2, 0x001099f1, 0x00119af2, 0x00129bf3, 0x00129bf3, + 0x0060d4f7, 0x0067dcfd, 0x004fc2f0, 0x00002c8a, 0x002e6bc0, 0x000547ad, 0x000044ba, 0x003685c4, + 0x00064ebc, 0x001462c3, 0x002d70cb, 0x000f5ab4, 0x002274cd, 0x001169c2, 0x001979c2, 0x001d80d0, + 0x001980d7, 0x001a86d3, 0x001090de, 0x00038dda, 0x000599e6, 0x00059ce1, 0x00049edd, 0x0005a6e1, + 0x0000a7de, 0x001fb6ee, 0x0039bdf7, 0x0038bcf6, 0x0024b5fc, 0x00bfe8b9, 0x00fafea2, 0x00fbfca5, + 0x00fcfaa8, 0x00fcfca7, 0x00fdfda6, 0x00fbfca3, 0x00f9fb9f, 0x00f6f795, 0x00fafb92, 0x00fbfb8b, + 0x00fbfb85, 0x00fafa79, 0x00fafa6d, 0x00f9f961, 0x00f8f956, 0x00f9f64c, 0x00f9f442, 0x00f5ec39, + 0x00f2e531, 0x00efde28, 0x00ecd620, 0x00eed900, 0x0032a6e5, 0x0019a4ff, 0x0029a4f4, 0x0020a2f4, + 0x0018a0f5, 0x00179ef4, 0x00159df4, 0x00139bf3, 0x001199f2, 0x00129af2, 0x00129af3, 0x00129af3, + 0x005bd1f5, 0x0063dffa, 0x00318dcc, 0x00062d91, 0x000e499a, 0x0000369f, 0x00003897, 0x00155fb6, + 0x0053aad9, 0x0031a6e2, 0x0045bcef, 0x006dddff, 0x0076defa, 0x006dd9f9, 0x0064d5f9, 0x0054c5f3, + 0x0045b5ed, 0x00238ed6, 0x001277ce, 0x00006cc6, 0x000282de, 0x000187db, 0x00008dd7, 0x00079be1, + 0x000099dc, 0x0022b1f0, 0x0036baf4, 0x003cbcf4, 0x001cb5ff, 0x00fffe89, 0x00fbff96, 0x00fbfc98, + 0x00fbf99a, 0x00fcfb98, 0x00fdfd96, 0x00fafb90, 0x00f6f98a, 0x00f7f984, 0x00f8fa7f, 0x00fafa7a, + 0x00fbfb75, 0x00fafa6a, 0x00f9f960, 0x00f8f855, 0x00f7f84a, 0x00f7f540, 0x00f8f336, 0x00f4eb2f, + 0x00f0e328, 0x00f0da24, 0x00f0d121, 0x00e9ca24, 0x00049bff, 0x0020a3f6, 0x0016a1f7, 0x0016a0f7, + 0x00169ef7, 0x00159df6, 0x00149cf5, 0x00139bf4, 0x00129af3, 0x00129af3, 0x00129af3, 0x00129af3, + 0x005ae3ff, 0x0064d8ff, 0x000d4798, 0x00002682, 0x001d6bb7, 0x003aa2de, 0x005fe5ff, 0x0052d8fd, + 0x004dd6f6, 0x0048ccf5, 0x005fd0f6, 0x0068d9ff, 0x0061d3f8, 0x005bd2f8, 0x0042cbff, 0x0053cefe, + 0x0051cff5, 0x0049caf6, 0x004acdff, 0x0040baff, 0x000e7edb, 0x000069c2, 0x000584da, 0x000184d5, + 0x00068cd8, 0x0038bef8, 0x003abef7, 0x0035beff, 0x0062c7e2, 0x00fbf379, 0x00f8fa83, 0x00f9f983, + 0x00faf884, 0x00f9f77f, 0x00f7f77b, 0x00f8f979, 0x00f9fa77, 0x00f8f972, 0x00f7f86c, 0x00fcfc6c, + 0x00f9f864, 0x00f8f85b, 0x00f8f752, 0x00f7f649, 0x00f6f53f, 0x00f5f237, 0x00f4ef2f, 0x00f1e628, + 0x00eede20, 0x00ead61f, 0x00f2cc11, 0x009db96c, 0x000c9ffe, 0x001ba3f9, 0x0017a2f9, 0x0017a0f9, + 0x00169ef8, 0x00169df7, 0x00159cf6, 0x00149bf5, 0x00139af5, 0x00139af5, 0x00139af5, 0x00139af5, + 0x0060d8f9, 0x005bd9f8, 0x004cadd7, 0x0069ddff, 0x0056ddf8, 0x0055d6fc, 0x0055d0ff, 0x005cd5ff, + 0x0053cbf2, 0x004bcaf6, 0x0043cafa, 0x0047c9f8, 0x004cc8f6, 0x005ccff1, 0x0046ccf8, 0x0055caff, + 0x003ec4fa, 0x0043c3fb, 0x0048c2fd, 0x003ebff4, 0x0044ccfb, 0x0037b3fc, 0x000b7bdd, 0x00006dc9, + 0x000d80d4, 0x004eccff, 0x003ec3fa, 0x002ec2ff, 0x00a7dea8, 0x00f8ec5b, 0x00f5f570, 0x00f7f66f, + 0x00faf76e, 0x00f5f467, 0x00f1f060, 0x00f6f663, 0x00fbfc65, 0x00f8f95f, 0x00f6f659, 0x00fefe5d, + 0x00f7f652, 0x00f7f54c, 0x00f7f545, 0x00f6f33d, 0x00f6f235, 0x00f3ef2f, 0x00f1eb29, 0x00efe221, + 0x00ecd818, 0x00e5d21a, 0x00f3c700, 0x0052a9b4, 0x0014a4fb, 0x0015a3fb, 0x0017a3fc, 0x0017a1fa, + 0x00179ff8, 0x00169df8, 0x00159cf7, 0x00159bf7, 0x001499f6, 0x001499f6, 0x001499f6, 0x001499f6, + 0x0058cff2, 0x0059ddfd, 0x0055d5f9, 0x005ddeff, 0x004dcef3, 0x004dcbf3, 0x004cc8f3, 0x0056d2fc, + 0x0059d3fd, 0x0050cefb, 0x0047cafa, 0x0048c9f9, 0x0049c7f9, 0x0051cbf6, 0x0045c9f9, 0x004bc8fd, + 0x003fc5f9, 0x0041c4fa, 0x0043c2fb, 0x003bbdf3, 0x003ac0f4, 0x003ec7fc, 0x003ac6fc, 0x0025a1e3, + 0x001f8dd9, 0x0037b9f7, 0x0026bbfa, 0x002abbf4, 0x00ced857, 0x00f9fa5b, 0x00d9db49, 0x00edec58, + 0x00faf560, 0x00f2ef4d, 0x00e9ea3b, 0x00eeef46, 0x00f2f451, 0x00f9f34f, 0x00edf145, 0x00fef84b, + 0x00f4f542, 0x00f5f43d, 0x00f6f337, 0x00f5f131, 0x00f5ef2b, 0x00f2eb27, 0x00f0e622, 0x00eedb1d, + 0x00ecd117, 0x00f1cc09, 0x00f5c509, 0x000fadff, 0x0017a1f9, 0x0018a1f9, 0x0018a1f8, 0x0018a0f9, + 0x00179ff9, 0x00169df9, 0x00169cf8, 0x00159bf8, 0x001599f8, 0x001599f8, 0x001599f8, 0x001599f8, + 0x0060d5fb, 0x005bd3fb, 0x0056d2fb, 0x0055d1fc, 0x0055d0fe, 0x0054d0fa, 0x0053d1f6, 0x0051cef7, + 0x004ecbf8, 0x004dcbf9, 0x004ccafb, 0x0049c8fb, 0x0047c6fc, 0x0045c6fb, 0x0043c6fa, 0x0041c6fa, + 0x0040c7f9, 0x003fc5f9, 0x003ec3f9, 0x003fc3fb, 0x0041c4fd, 0x0038baf2, 0x0040c1f8, 0x003dc3fb, + 0x003bc5fe, 0x0037c1f6, 0x0034beef, 0x002ebcf0, 0x00ded722, 0x00bfdc38, 0x00dee142, 0x00ecea4a, + 0x00eae442, 0x00eee942, 0x00f2ee42, 0x00eeed3f, 0x00eaec3d, 0x00fbee3f, 0x00e5ec31, 0x00fff239, + 0x00f2f531, 0x00f4f32e, 0x00f5f12a, 0x00f5ee25, 0x00f4ec21, 0x00f2e71e, 0x00f0e11c, 0x00eed519, + 0x00ecc917, 0x00dec40c, 0x00bbbe39, 0x000798f8, 0x001a9ff8, 0x001a9ff7, 0x001a9ff5, 0x00189ff7, + 0x00179ff9, 0x00179ef9, 0x00169cf9, 0x00169bf9, 0x001699f9, 0x001699f9, 0x001699f9, 0x001699f9, + 0x005cd4f9, 0x0058d4f9, 0x0055d3f9, 0x0056d2fa, 0x0058d0fb, 0x0056d0f8, 0x0054d0f6, 0x0051cef7, + 0x004dccf9, 0x004ccbfa, 0x004bcafb, 0x0049c8fb, 0x0047c7fb, 0x0045c7fb, 0x0043c6fa, 0x0041c6fa, + 0x0040c6f9, 0x003fc4f9, 0x003ec3f9, 0x003ec2fa, 0x003ec2fb, 0x003abef5, 0x003ec2f8, 0x003bc1f9, + 0x0037c0f9, 0x0036beff, 0x0035bbff, 0x0067bb84, 0x00b0d219, 0x00b4d31a, 0x00d3da39, 0x00e2dd3d, + 0x00d6d532, 0x00e1df38, 0x00ece93e, 0x00e1e636, 0x00e9e536, 0x00f1e634, 0x00e5e42b, 0x00f6e62e, + 0x00e9eb29, 0x00f0ee2a, 0x00f0e824, 0x00ece420, 0x00e9e01d, 0x00ebdb1c, 0x00edd71c, 0x00e9ce19, + 0x00e5c516, 0x00e7c004, 0x006cb292, 0x00109dfc, 0x0018a1f7, 0x001aa0f5, 0x001ca0f3, 0x0019a0f6, + 0x00179ff9, 0x00169ef9, 0x00169cf9, 0x00159bf8, 0x00159af8, 0x001499f8, 0x001499f7, 0x001499f7, + 0x0058d4f6, 0x0056d4f6, 0x0054d5f7, 0x0057d3f7, 0x005bd1f8, 0x0058d0f6, 0x0054cff5, 0x0050cef8, + 0x004dcdfa, 0x004bcbfb, 0x004acafb, 0x0048c9fb, 0x0046c7fb, 0x0045c7fa, 0x0043c7fa, 0x0042c6fa, + 0x0040c6f9, 0x003fc4f9, 0x003ec3f9, 0x003dc1f9, 0x003cc0f9, 0x003cc1f8, 0x003cc2f7, 0x0038bff6, + 0x0034bbf5, 0x0035bdfd, 0x0037beff, 0x0046bcfc, 0x0082c92c, 0x00a0be02, 0x00b8c420, 0x00d8cf31, + 0x00d2d632, 0x00d4d52e, 0x00d7d42a, 0x00cdd725, 0x00e9df2f, 0x00e6dd2a, 0x00e4dc25, 0x00edd922, + 0x00e0e220, 0x00ede927, 0x00eae01e, 0x00e4da1c, 0x00ded319, 0x00e5d01a, 0x00ebcd1b, 0x00e5c818, + 0x00dec214, 0x00f0bc00, 0x001da5eb, 0x0019a1ff, 0x0016a2f7, 0x0019a2f4, 0x001ea2f1, 0x001aa0f5, + 0x00169ff9, 0x00169ef8, 0x00159df8, 0x00159cf8, 0x00149bf8, 0x00139af7, 0x001299f6, 0x001299f6, + 0x005ed5f9, 0x0063d6fc, 0x0068d6ff, 0x005fd3fc, 0x0056d0f8, 0x0053cff8, 0x0051cef8, 0x004ecdf9, + 0x004bccfb, 0x004acbfb, 0x0048cafb, 0x0047c9fa, 0x0046c8fb, 0x0044c7fa, 0x0043c7fa, 0x0042c6fa, + 0x0040c5f9, 0x003fc4f9, 0x003ec3f9, 0x003dc1f9, 0x003cc0f9, 0x003bc1f9, 0x003bc1f8, 0x0038bff7, + 0x0036bdf7, 0x0035bdfa, 0x0034bdfe, 0x0022c3f6, 0x0027bbfc, 0x0053b0b2, 0x009bc606, 0x00c1d322, + 0x00d3dd36, 0x00b4ba12, 0x00c4c71f, 0x00c5cf22, 0x00d9d82d, 0x00dfdb30, 0x00dcd52b, 0x00e8d520, + 0x00d5d51c, 0x00e8e428, 0x00ece324, 0x00d1ce1f, 0x00d3c51d, 0x00dcc302, 0x00cfc312, 0x00e3c209, + 0x00e3be00, 0x0084bf6e, 0x000ca0f6, 0x00129ffd, 0x0018a2f6, 0x0019a1f5, 0x001ba1f4, 0x0018a0f6, + 0x00169ff8, 0x00159ef8, 0x00159df8, 0x00149cf7, 0x00139bf7, 0x00129af6, 0x001098f4, 0x001098f4, + 0x0065d7fb, 0x005dd4fa, 0x0056d2f8, 0x0053d0f9, 0x0050cff9, 0x004fcef9, 0x004dcdfa, 0x004bcdfa, + 0x004accfb, 0x0048cbfb, 0x0047cafb, 0x0046c9fa, 0x0045c8fa, 0x0044c7fa, 0x0043c7fa, 0x0042c6fa, + 0x0040c5fa, 0x003fc4f9, 0x003ec3f9, 0x003dc1f9, 0x003bc0f9, 0x003ac0f9, 0x0039c0f9, 0x0038bff9, + 0x0037bff9, 0x0034bef8, 0x0031bcf7, 0x0033bbf8, 0x0035bbfa, 0x002cbcff, 0x0061c2df, 0x0093cb85, + 0x00c5d52b, 0x00cbd82f, 0x00b0bb13, 0x00b5be17, 0x00b9c21b, 0x00c7c826, 0x00c5bf21, 0x00dbc817, + 0x00cac819, 0x00dbd722, 0x00ddd61a, 0x00b7bd0d, 0x00c8bd04, 0x00d0c000, 0x00adc951, 0x006cb8b1, + 0x0004a3ff, 0x0013a4fb, 0x0021a4f5, 0x001ea3f5, 0x001aa1f6, 0x0019a1f6, 0x0018a0f7, 0x0017a0f7, + 0x00169ff8, 0x00159ef7, 0x00149ef7, 0x00139df7, 0x00139cf6, 0x00119af4, 0x000f98f2, 0x000f98f2, + 0x005cd5f9, 0x0058d3f8, 0x0053d1f8, 0x0052d0f9, 0x0050cff9, 0x004ecefa, 0x004ccdfa, 0x004accfa, + 0x0048ccfa, 0x0047cbfa, 0x0046cafa, 0x0045c9fa, 0x0044c8fa, 0x0043c7fa, 0x0042c7fa, 0x0041c6fa, + 0x0040c5fa, 0x003fc4f9, 0x003ec2f9, 0x003cc1f9, 0x003bc0f9, 0x003ac0f9, 0x0038bff9, 0x0037bff9, + 0x0036bff9, 0x0035bdf6, 0x0034bbf3, 0x0035b9f7, 0x0035b8fb, 0x0022b5ff, 0x002fb5ff, 0x004dbae6, + 0x006bbfce, 0x0027b1c5, 0x006cbc7c, 0x008abd49, 0x00a7be15, 0x00b9bf09, 0x00ccc000, 0x00dac43d, + 0x00bbca20, 0x00aec73e, 0x0099bc54, 0x005aad8b, 0x0036abc4, 0x0004b3ff, 0x0015a7ff, 0x0021a4ff, + 0x0019a0fb, 0x001ba2fa, 0x001da4f9, 0x001ba3f8, 0x001aa1f7, 0x0019a1f7, 0x0018a0f7, 0x0017a0f7, + 0x00169ff8, 0x00159ef7, 0x00149ef7, 0x00139df7, 0x00129cf6, 0x00119af5, 0x000f99f3, 0x000f99f3, + 0x0053d2f6, 0x0052d1f7, 0x0051d1f8, 0x0050d0f9, 0x004fcffa, 0x004dcefa, 0x004bcdfa, 0x0049ccfa, + 0x0047cbfa, 0x0046caf9, 0x0045caf9, 0x0044c9f9, 0x0044c8fa, 0x0043c7fa, 0x0042c6f9, 0x0041c6f9, + 0x0040c5fa, 0x003fc4f9, 0x003dc2f9, 0x003cc1f9, 0x003ac0f9, 0x0039c0f9, 0x0038bff9, 0x0036bff9, + 0x0035bef8, 0x0036bcf4, 0x0038baf0, 0x0036b8f6, 0x0034b5fc, 0x002cb6f9, 0x0023b7f6, 0x0025b5fa, + 0x0028b4ff, 0x0028b6ff, 0x0029b7ff, 0x001fb5ff, 0x0015b2ff, 0x0020aef7, 0x003cb9ff, 0x005acbf0, + 0x0042befa, 0x002ab6fc, 0x0012adff, 0x0018acfc, 0x001eacfa, 0x001ea9fd, 0x001ea7ff, 0x001ba8fa, + 0x0018a8f4, 0x0018a6f8, 0x0018a4fd, 0x0019a3fa, 0x001aa1f7, 0x0019a1f7, 0x0018a0f8, 0x0017a0f8, + 0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf6, 0x00119af5, 0x001099f4, 0x001099f4, + 0x0054d1f8, 0x0052d1f8, 0x0051d0f9, 0x004fcff9, 0x004ecffa, 0x004ccefa, 0x004acdf9, 0x0048ccf9, + 0x0045cbf9, 0x0045caf9, 0x0044c9f9, 0x0043c8f9, 0x0043c8f9, 0x0042c7f9, 0x0042c6f9, 0x0041c5f9, + 0x0040c5fa, 0x003fc4f9, 0x003dc2f9, 0x003bc1f9, 0x003ac0fa, 0x0038bff9, 0x0037bff9, 0x0036bef9, + 0x0034bef8, 0x0035bcf6, 0x0035baf5, 0x0034b8f8, 0x0033b6fc, 0x002eb6f9, 0x0029b6f7, 0x0029b5f8, + 0x002ab4fa, 0x002ab5fb, 0x002ab5fc, 0x002ab2f6, 0x002aafef, 0x001ba9f6, 0x009bcfd9, 0x006dcfe9, + 0x0074c7e4, 0x0080c9dd, 0x0019adfb, 0x001cacf9, 0x001fabf8, 0x001fa9f9, 0x001ea7fb, 0x001ca7f9, + 0x001aa7f6, 0x001aa5f8, 0x001aa4fb, 0x001aa3fa, 0x001aa2f8, 0x0019a1f8, 0x0018a0f8, 0x0017a0f8, + 0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf6, 0x00119bf5, 0x00119af5, 0x00119af5, + 0x0055d0f9, 0x0053d0fa, 0x0051d0fa, 0x004fcffa, 0x004dcffa, 0x004bcefa, 0x0049cdf9, 0x0046ccf9, + 0x0044caf8, 0x0043caf8, 0x0043c9f8, 0x0043c8f9, 0x0042c8f9, 0x0042c7f9, 0x0041c6f9, 0x0041c6f9, + 0x0040c5fa, 0x003ec3f9, 0x003dc2fa, 0x003bc1fa, 0x0039c0fa, 0x0038bff9, 0x0036bff9, 0x0035bef9, + 0x0034bdf8, 0x0033bcf9, 0x0033bafa, 0x0032b9fb, 0x0032b8fc, 0x0030b7fa, 0x002eb6f8, 0x002db5f7, + 0x002bb4f5, 0x002bb4f6, 0x002bb3f7, 0x0029b2f9, 0x0028b2fc, 0x0030b2f7, 0x0012a8fe, 0x007fd4e1, + 0x0058bbe6, 0x0015aafb, 0x001fadf8, 0x0020acf7, 0x0020aaf5, 0x001fa9f6, 0x001ea8f7, 0x001da6f7, + 0x001ca5f8, 0x001ca4f8, 0x001ba3f9, 0x001ba3f9, 0x001ba2f9, 0x0019a1f9, 0x0018a0f8, 0x0017a0f8, + 0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf5, 0x00129bf5, 0x00129bf5, 0x00129bf5, + 0x0055d0f9, 0x0053d0fa, 0x0051d0fa, 0x004fcffa, 0x004dcffa, 0x004bcefa, 0x0049cdf9, 0x0046ccf9, + 0x0044caf8, 0x0043caf8, 0x0043c9f8, 0x0043c8f9, 0x0042c8f9, 0x0042c7f9, 0x0041c6f9, 0x0041c6f9, + 0x0040c5fa, 0x003ec3f9, 0x003dc2fa, 0x003bc1fa, 0x0039c0fa, 0x0038bff9, 0x0036bff9, 0x0035bef9, + 0x0034bdf8, 0x0033bcf9, 0x0033bafa, 0x0032b9fb, 0x0032b8fc, 0x0030b7fa, 0x002eb6f8, 0x002db5f7, + 0x002bb4f5, 0x002bb4f6, 0x002bb3f7, 0x002ab2f8, 0x0029b2fa, 0x002db6f5, 0x001db5f6, 0x00239bff, + 0x0020b6f3, 0x000cacfb, 0x001eacf7, 0x001fabf6, 0x0020aaf5, 0x001fa9f6, 0x001ea8f7, 0x001da6f7, + 0x001ca5f8, 0x001ca4f8, 0x001ba3f9, 0x001ba3f9, 0x001ba2f9, 0x0019a1f9, 0x0018a0f8, 0x0017a0f8, + 0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf5, 0x00129bf5, 0x00129bf5, 0x00129bf5, + 0x0055d0f9, 0x0053d0fa, 0x0051d0fa, 0x004fcffa, 0x004dcffa, 0x004bcefa, 0x0049cdf9, 0x0046ccf9, + 0x0044caf8, 0x0043caf8, 0x0043c9f8, 0x0043c8f9, 0x0042c8f9, 0x0042c7f9, 0x0041c6f9, 0x0041c6f9, + 0x0040c5fa, 0x003ec3f9, 0x003dc2fa, 0x003bc1fa, 0x0039c0fa, 0x0038bff9, 0x0036bff9, 0x0035bef9, + 0x0034bdf8, 0x0033bcf9, 0x0033bafa, 0x0032b9fb, 0x0032b8fc, 0x0030b7fa, 0x002eb6f8, 0x002db5f7, + 0x002bb4f5, 0x002bb4f6, 0x002bb3f7, 0x002bb2f8, 0x002bb1f8, 0x0022aff9, 0x0019acfa, 0x001eadf7, + 0x0024aef3, 0x0020adf5, 0x001dabf6, 0x001fabf6, 0x0020aaf5, 0x001fa9f6, 0x001ea8f7, 0x001da6f7, + 0x001ca5f8, 0x001ca4f8, 0x001ba3f9, 0x001ba3f9, 0x001ba2f9, 0x0019a1f9, 0x0018a0f8, 0x0017a0f8, + 0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf5, 0x00129bf5, 0x00129bf5, 0x00129bf5, + 0x0055d0f9, 0x0053d0fa, 0x0051d0fa, 0x004fcffa, 0x004dcffa, 0x004bcefa, 0x0049cdf9, 0x0046ccf9, + 0x0044caf8, 0x0043caf8, 0x0043c9f8, 0x0043c8f9, 0x0042c8f9, 0x0042c7f9, 0x0041c6f9, 0x0041c6f9, + 0x0040c5fa, 0x003ec3f9, 0x003dc2fa, 0x003bc1fa, 0x0039c0fa, 0x0038bff9, 0x0036bff9, 0x0035bef9, + 0x0034bdf8, 0x0033bcf9, 0x0033bafa, 0x0032b9fb, 0x0032b8fc, 0x0030b7fa, 0x002eb6f8, 0x002db5f7, + 0x002bb4f5, 0x002bb4f6, 0x002bb3f7, 0x002bb2f8, 0x002bb1f8, 0x0022aff9, 0x0019acfa, 0x001eadf7, + 0x0024aef3, 0x0020adf5, 0x001dabf6, 0x001fabf6, 0x0020aaf5, 0x001fa9f6, 0x001ea8f7, 0x001da6f7, + 0x001ca5f8, 0x001ca4f8, 0x001ba3f9, 0x001ba3f9, 0x001ba2f9, 0x0019a1f9, 0x0018a0f8, 0x0017a0f8, + 0x00169ff8, 0x00159ef7, 0x00149df7, 0x00139cf6, 0x00129bf5, 0x00129bf5, 0x00129bf5, 0x00129bf5 +}; + +int TestFreeRDPCodecRemoteFX(int argc, char* argv[]) +{ + return 0; +} diff --git a/libfreerdp/codec/test/rfx.bmp b/libfreerdp/codec/test/rfx.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2b66651732366cbc24ce165ae458c561eb6ffc24 GIT binary patch literal 16438 zcmeHuXH=Bu{_Rd;iYKx6-g`G2ajrq5fZym!B&=H#5a*8kJ}aMxYewf1>uhKa|$fBpA7Or1M=3Y>pN^MCsj zQ;55YqP&3ae8oRgo_@y1Uw?{D^hEK=-YE6ygKGc5aK3kb)(gdas_&nEroQj(MA?ZR zs65dXrC!}p;Mo&}o;^^+*TpKlyYbl-#hzVI?9mxT$2%e4y(@BDd!XPLe|D@3@?AS2 z+pRtFj&?@jpWRV-q!WscwI$l2=x7HN9choEKl%DlI}{#li-H4fkbj^xau2jb&Vd%l z+1~=W`&uG*Z%gF;!RH>n-%adlj+|Z1kh7E6(G=O+n>@v~Cdk@KY-xfgoBtCfl=$@iH%{^Osa}NoBu?_XPEfCtJyD`+<4ygjN6CrqD18Q12d5^Umwy z7plBEp_KlR@7@_@u3b@cv^y$YyP(vay!lzK8+CB%(&?E7)Zs`66d$Grhp7Smq43YA zIuuZcd}@$S4f3f$J~hbyqXi16LBa0k)ZnT8b9Xj%YLTnzKn-%9X`t%x92MsWqWt_2 zlwBA>4F;q9Y(JD!lfOVc%83g4NQG}dR1y`w{EXU^tC~=Q3i?Q;Pft`3{?vNe#T(q5MQ^RM0Ofk9S6uJ8kcblP)Ns4yDgDD4|b0^@ab` zp@etl3$Kd7P(8sA

xA2fmf*yWud#XKUi`N4AU1A10@qDjaCOg8JfVNs&o+YTWOLL~gIur9 zD5nNxd|gUEC}oU1)j^GuPK=X|C^<^dA4=#C#m?NIYS5Y*v_j$jmMEeIMbw~J^@G3h zSA8O%8st-hJo-T%`Trdi0mD&!bu`M!zv9v`R9+Z_>MNsBeXcL6&JRG&}fN_W*;i(v{FIawF+8( z%J)kYGRD6A_)(%INmF4n04%q3;(~4ES0?&u=a0^qmpi*BQ|JQ$2bvRnTp*f_BuR z>2w7v)&`^4ts8XSEm1*VsPt-&D(^O^qy`l#f1=opws$4}qvU^-{Ev|T;WpHuHMMAs z5)}u@e}8inQiB5K!gBga-kzq^peb|1a}D^OdEq%~gGWObG8*+)hobJvVANe62yMvQ z&;$%Xb--X$1&}{=sk}52RrHVQi-S>nz7JM^>55k-(UwakwEVsl1HKp0?*{>We-hCD zCj$n3D`M!+5{7SrdOD zKmQ_X+MCZL;kQ}#C{V-?lR%cEhf0^5-{d~jB$rVj6W=3 z?0yk0{GQ8ZKB?2F4FX2eZ$_*VG5iAweHJPhv&aIw|4S(G?us&xuH@g1v7z=6Qy%HE+|)#V8JA8Lk@L#<{vD zmoe7cj0wlhm~_;FDXt=>9+xrQOUBHTGG=&4n9k3p9hC6)ZW)t*moV`M3FE#I;IhGt zp3D=UtiJ>8sg|hr>WO+!=7JOLp!1+_GY_h@vdn{iah!4C)S^APlPBXrjfGNbQ9<7* zKinFnhgzcSU<-orzZ#f9ex1j4s_2~PFj3Kn8%RV!v`Z+K;K)|#M0%rLO zc=wEiIes$cpR;1oB^wrU(96=EM<=9|=w9aOi?YLA=om)7Qk}jrWS-%x23asa#EOMM0^YwW zVd-TnmS3}BWtao2ugh4=pRWv*vHYSPOMLh}Hwo_@5isMR1-&*a(D`?QiT2mK_eZc# zFTj00wx4(l;;D8pouCdU**kc#ub>Z9G9Og1E|k#+ifQ*s*3b&Kj;K)mfVrTSHKC0C zLHQoQ{2P$IyCd`mnxOPgpk`MS=y$({y0EuUA2tE?H^vj=P#-#$7=!u{;`$iWT^~*V zU~LQ?0WGzV!+YSRsdjW-#{B-Jh#|k3Fk+{G(Ff?$z9Qy^TCn1-1Ir`G^OlIU;Z}SW zWycry6|9f8;+se_)uyxm7Z@oWmi@s`X3Pkp_D^+463iZ!#A{b$j!HYn$3nj?Jg)*X-ecYP!IGW75$8IzdyE;YA{68Y%%TmuqS}vn|3VjZPWMF5#C_;@e>(<8{E7h~Kcdg& zZ_qAa175qh4lOUP!uvi8vB7&5_IOOfQMU=$>M<6dxKGDS*9CYhWCuF!nvXptSFz)f z4_a&;jn3Pr;jLXGAsuamf}_pR5HW?AOdY7fE&9SOYCzs~&q3eNg-nL|>NM8KrZ^t1 zVD2{7yr0Y%y3K-d2bj-2>G!n#2iIu(NZK@>yvcFf6B&PG$vBi_#j#u~PFKh{`osa> zLKz-;5?uN7!>Ly6N>lJloC3QSV7Sm1;@R%-k6Mfoxo0u<$w`b)J&uV9M=&mSKV0ta z!icEfF(l##bPoRs{epf*p8)#D`3>lQW*xen`4>96EyIkkU$9Mo8*?syk2b%(jjsC_ zp!4o&XuW$j_U~>7%i-5i&ACz=H5Cn!Z##9Urw;Yhp^iG#((X0nu3>J_-5dwu_88=c zF2MBT3Qpd4p!ct=*}FtcJVL)`+%LH*U?qM3v%3<0OqQ`L&xV7AR=AbO@Gd3iQUzx< zR;-Is;8SSFxoQPx%B<8vglD!L0g*SL_i4fYnttrl5uau3#f;J*%qu4H12He>JZ3*R zjTz})n3#MVF7d7y6?+hGM(@VRh)oy~_BDoI-+-Z4)?@Om%^2bT4d#b#LU*qZFv#a4 z^l@E?&u(r-7q2xaJNyz1hg!g}w==YNr$c*Z8XBBBJoSZo#zgI{DfEL$&KRh@IR-*R zKm2*Z6=U43_>FP9D^$X}o~(7=7R)}&^QlMHCCp4egK4SWn4EMBlj0BHtp__XE_xeANBoYNar-eNW-kW&euBZ5 zKEsf+tI*ed0X$O9qM#-RO2JLmn6b!U9neP4{7VDX7qpS&9Wj+YFbz6tV4^Qng}XqA zY=;F~a_|mo)%&dNxAGVVej;Z38?pE@<2O{m*U^mUM~v-k32qf4{OUzqF^jlnRB*$f z@U;UU-Z0@9eLqQYAlhQZjd}rr{F!i;dC$KscTnw-6tWcG8uZvn{+lXO@LN?9k%;dq zQ5pTo5m~h-3 z23sVzYIDq3v`@jRbByWxcI;w3TX2QkZwOc)CE*vw{VvA6N1+3k=-*cw?6_u@aLZyt zj6i$qZ20PtfFq2H1e+a?`EPk>C(09GIL%l*+Xed5Epao`2L}u_aMR`EaBU8b)#bpA zI8gfpJ8Ckpu__*4m)*g?%EIw+X)sn5U&ZpG%UG0i2D39f@pj@NjK8-NZ-)Pf!GZt8 zfHN!6&vOZSxW0#*+{-vvBeRb+M)u)m(8j(C-Thh6Q3E|S&{G379_pXPgpRpEcY7?t zPk)E5D;12`C}H7gGuB>~5LxWNvM>=}+>!C?LmRfI*|0y~hCj*gScw&9Ypn=1TM;A5 zNVZ7`tCO&U`QR|~!9&@KY|)NH8}okhel+;BN5h#uu%3J!{+4Q-)0g9%j?k9llD-0$ z4VCgTBBZ z|BunndjcB<|8dI@hMqu}@H;kA07L7kc`Dff^X@&4B6N6j<(0fbkA%AM1gVFa&*Q z`(Ya#827sovyPdu?4pPrcLiL@60qT(f}Obv4wPHr+92Q*`Jb%Aa{_J$JH2Sq2_!*qKZs&h{vUy{h%h#K;%q<@#%WbkMP+6!HwztEX|UnlzA3RLm4 z63L1()jzBv3S=|#tY+jASvCvO?H0s~I>taPE*gs9s>{G8Qye}PZ?RvX|5u*FtkN?W zpXGtEN&Db(e-nCye}kPTCct#83F=*2K|>#?Jlf0&Q~Uy$66V94FproEO9FLJ{ow8l zYVZ#I;9YcEq~NI6c~piigc8>u(*41#6(g7%CbM@KZJ2^kC zL!0aC@q}}+mOHZAW6e=X{w0im6{f^RrnA3z(VZJ`e+NXyv@kvqk@t2_(1^b!>23kN@!2ow3&I_xNOSW#k^sDprP##0L8 zzLarLP5r9vMriDM`UG>Ly%M*?VuTrTk!Gu*b_Vv}VVFn_W`%n}I^7yZ*GAB~HbnYF zHW`MCeYtDu22=QC7!{i{Ce*mF(g*bH5i5xbh4Ek)kwyNA4kKzA3k?o|K4d_OtsX&A z8ID?Vu-}x1o%%;O-jIxoHL1=Vq+#CJ_+Sf^=;f$A-4O;i_Wkb7xI<9)2&@B1>gwGY-noAeWE z$X%EA1nw zA3NgmG9YBd3%L9BD@fY;I+Bk8#pjtrZgO{)xDJ-bo1sfz4^!TDNM#-n>il6gU4taV z!7dk&lK~b*grhbBhLE06xI-0!7#G0<=o`$J=R3kwnE;b0@VgEOL_JYUf6%Z`RAV5Y zKA<54qQIfYJ!=(0So{5T*>J5(#?I>d_@y!&>&pVMxX2evGFP+voZfk%zpy3d|$_0kZP_*q`3%} z^*K0MpN7qvSZpW_$12)=ewGhb$9upf?kJ|l@5kKhTVe19MA!B(yS1Uux1t6up<^7V zFr_SY#(-hS$UF4{@~<>T1LIwrvK%^c zF_ruQvGORy27gHAo3Ki8aM&|pvll_OYv6FG+-ZOMu#LPFa;y&OLfa2y?&oZMvk%0O z0n7_MVPFqvA%_}%uh?N@%-fJFvknR-n3)et*caTZE5Z$JHqO>d z2O{f%^~qw`*cV)$10;Oi7#Uk%N9G?dBhTYylw5cjl{eZmPcUDle*$ySZpQl&$eI(7 zbXVx}cWL)T*zH;5Ur5_mlDEoV=4%7&^lPi;0qTOf!V)qZV%Ts97dmja+!w|xJz);$ z3i%RyiF2J%lk__ZOhpJ%YEVz^TKYx0WJ5?pJpwhA*jJf@&&v|Axa2107M#PD*dGye zc^Zs7UsX>00~U|Q(4OFq%d0)=xi{8%)Bc`qpra2o(Do`UkC(%o@&V)EeOQ~yNU^Rw8rtNLk zRPxV(-BCz;my*Ah{A~~%wa)q`X8p-}Nd7@QQweAfyHL#YrQXm7_JSDL1Hu*d!a;*! zzR0|A<~2y?=@&6`m}fU2FMcy(61L#MgKbERSc}x_JgehbrQ-b>l#?x>?v6B`%^>lN zT{zJOW z+W!jgz`Tr#i?8u)^dIcg20=)h11WC<dU?r_QA*N|F(>Q z)@bnHewZ~tg^<1)=CleUy zi9;b}E`VJ4HLO(!VXgCl)esD;a1XLAgE^13w-wR{^2j>}R{Da>&t$m*Ld{uNFAsuz zlfB`Uju7)aoq5q_cTg|xK&g+MaR8Q!9Uxq659t#5u|72TcZK16H-1k4INucl&q<`S z?O^q52|MRUhv!R>c~2wg?$=nAkb?f4#jc0^0NLYpn7rug^nnKYf|fa;-lGL-S^rd6 z9E9O3@nB%^peku6_s)w^dyz5C9!~Umg}Z+K+t2XaFL)Z_W4?k{RuJbO z14cH~;+;yKwQ|=wwZsmS2Vgr*9Zxam@oZgB?*DCnOUg%#ffcZ1EQcX!5gbpJBlExj zJX-%E(l)(_?7c7W>=ocxf%=+4C{Csr(gkw{S)@@O^_Kum;%J z`zgpK5(z!$#UegqxHtHNKR?R8U<==`=PvC-LB@wV5z90JJ}eXPuk=(XYW`#HGk9^< z_oUx?viJM1{3oTYhL}zbGCt&U8I;^rNcy$|lD>Ko>6>0c4$ldTk2fO!mr-^31yqOf z>@4b4_6p2ZS#w}3{{i;uy>KuF9QFQiXaiu=vJP+-lZ@9PT5iB5-GE{Xg<{Nw{w8x8 zX9ElSU{mtFXY4cQdAFwRRqm{R9`prw)<4cZDr^}abG}*WdzJ3uIn_lMKx>tGkpfT^hya7$n>!`imm^*?tu%-5ZEtkD<*?QP3x5J@1 zPI$smeS-Dv6eNu=*&p)kaU7zSy@sUqjgj{28;pOR zAG2SoKF9OapjI&7>%{!W`jX1?*z|r7vfg73TMMc1XUN4{AhQ>;mNO?-9f7UJ9rk)J z)(0QRRcBy*v`yV6w zAHBQU2eyJWXC3s(tP|;iS_5=F1iTe)DIOMHDorx-#d;Fm4cfRq z>`ewipEME1cBdFXANh9m9+aD#=uY9BcJ9O%APt4cif#RUdpaX>IeXvD9hn1o z?{ph;-|2x!XDuiT7=rxsyzj_UGGchUqX+4Eq{TnaI5 zC3H_#ai=uTS@TWdE>MEoA&vXHT>5^RdJaOKkEufnk;I-qj{NTOvzx><;w-=8M(iOr z66@&?tGQF1!MJ}%Yr$BJ0sYIh=u_T+mkT&U)Ar`mjL+vbXWcil2U2UG&XcpBnhW__ zg*Ee^tmWU(_P-!*_XONp-3zzA?25;~_C)rce#kn|n{!VWJl@*_HJl?exkJ`o8iBmi zy!*`mkK)r!Q5ML%2Eptr!kcp+)`ULM8M=Fexl0~R-cz_&c?TBm)n(Q1!$!cwUiL2c zdJpLPvE*}~996`SceI^nVv>mKd>=rZ;m_R|`+qRcZz48Wt@xNTzz2-?83qw=*Ydtq zg$})nYtgybis@;waQOWLl22P$eCYE$S5bXmwZEC~#nYSv)p&TuUshxG@uyI#R>FH) zBlyp0ilj{=5WR%G|6<_5zg|MZp1w%f)}I-wf_Hnpd5_{$R}`u} z0`F}#a6YIGYK+pW|KPn5-s8F18>YzNkfPs$6fp|Yjlrl++ls4pnH+5hBR?m|^#*x{ za_{MHGQpqkPx8Ghv4@;D5nsu?KSL~It)FM+y(*qHjIT0ca7jJ7=2f9%nu5bYzrgO> zm_1<|_DSUK$DNP*WDjKUX3W$62HM|9{wf6KeS7}rJpY=HeS>*le%(-9e&=P}nhxCG zH5w7~UctSOTeBA)f{^9Ri$C;4%oi;Xv#|qGw|3#Z@(#{>HHC+H@A}|Nyqm-sk+VX< zsYWPa&roIikbI~jJ$J4-|t_hL+@N2dOYScLBlz)5iDoAL*RL;!28!~?`u(gpYd-Z|L44) zKb5lO%vGPl%v@^A8{X?x*AH(zt|(LWlmcGC2=Yo z?3K(Z3%N6z4JGMaC_FFE+uW4?0p2@*8JRm@K=uLl>rw1=qxg45xu7)eV{A0?+>rcs zkkd|4#uh=sCPBbP+V*Fj{d~vgdh%RPzxb3jZUuQS5_r~b5ir?o!5D)X!?fgHsYmz1 z26TH;gBFhrSby^*96sE4oZ)Q5nNad&ypzAc`fpKZVdj4`XMn#$%3cF8X9cpj>`)56 zfLO2;wkJ!Vq!O7Q!N7fhCE-2D3DY2|d5rr(J!b~-(M+BTE`fZ160G;8!5%XUraOH7 zXgX}XH&(Feb#N`r-ANNDkC^+pFIQrQ;sOI=MV*Lmc*gTJ`FzD#{@i578l4`WSSIDet4EJgE!t<-G43nCLsf)aWR$+vJN>-SvtGz59tI1Ad-IpZXA*5&?N zisxQDZZ<6Ho-BR_>^v`$Vkc9Bw_%Op-X)S}Aa}>Z7B>mD2jiW;Ly>ckvCsP>^6kDn zFBpgqvXilbHlCfAgJpH~Si?LvS8Kq88VzP@8?ex1zm@gqGN$C{yBW?xFq5_7zo=OxCzME(-_i|l#Bc zx4&P=`yRI;db~<|cZ5KgozG|dng1m6m)QSG?0^3Q86R=}Sq3ScylHPM_kkjJAr@+& z@|PZQ7o14$i~*IuHIDq_{>J|S`QM)mmA@QA4G448c%B_jV$GWX>FyZD{b(q+U9j^u z@9(7rp<{Xo#^t7CVnHcJWmg}Xr2?~`czL~>7f7gqYem1jV*%0EuE|5QkS z<1a-|BwyZDWvv%t-h$=MSeS2*f<4lO8jNB8KNExFx8ubqUv$48ju9!@82Ka(Lo+il zFe3|nvXU^YhwgJ#*^Oy|ftpG_3E%HRzmMjt=RC=$Kl8PD!7YXfa-S;EkT?(HLEjj+VDV&@JvhdZxr;NOlf}=M`a4WHAXZVxHSA;Mw1Nr`_cwa(_hbJP))o|H<*>{!q33 zzxm7m8-La3#}nfqk-v0j4C~)0o_~$tdFY$WgY<<6{+?mXTI@$4zzSzrXl9`XcKiFjqltf$48iWKNsB-Zevp16}%teiT#(C z<9+~h$@ND3J*zhC^LoI_7?=H6?|FAjWZf6YU-%#Sa~G!ezub|lu%t21KVC%s^!HT8 zdkSsO8mQV{e#CPia+k|T|>id=m7w$V0&on$zM9p9M9dj=--hs(2@N4n)8lG`~Q#py?N(?8mN$*^?osHKF@re{Av4S z_BBbo)4(22Oqfonz27tL56RuhpS7R$-)Vnm?VAXhIZys8?ngtS?M3E2iF+UU)|;?$ z_hSnm2|0}CUaAJ6LtqXW#B(s7r*I!CT^j(~HSQ1i`zDSHyq}T5dlI*o!Fq}L>oWVO zK+ZFlx>Fy%=Diu=9DUxOnw;(YwC8p9y^MwbfxlU`|KIR`6MvERm#KmI#t_~mVm Date: Tue, 11 Feb 2014 17:32:08 -0500 Subject: [PATCH 09/18] libfreerdp-gdi: fix mem3blt color conversion --- libfreerdp/gdi/gdi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 03039aa92..38a40b48a 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -673,8 +673,8 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) brush = &mem3blt->brush; bitmap = (gdiBitmap*) mem3blt->bitmap; - foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 32, gdi->clrconv); - backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 32, gdi->clrconv); + foreColor = freerdp_color_convert_var_bgr(mem3blt->foreColor, gdi->srcBpp, 32, gdi->clrconv); + backColor = freerdp_color_convert_var_bgr(mem3blt->backColor, gdi->srcBpp, 32, gdi->clrconv); if (brush->style == GDI_BS_SOLID) { From 0a2af868efcbf6a274858b9570e2caf86b73803e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Tue, 11 Feb 2014 18:02:26 -0500 Subject: [PATCH 10/18] libfreerdp-gdi: fix mem3blt SetTextColor --- libfreerdp/gdi/gdi.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 38a40b48a..2454a16ce 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -667,14 +667,17 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) UINT32 foreColor; UINT32 backColor; gdiBitmap* bitmap; + GDI_COLOR originalColor; HGDI_BRUSH originalBrush; rdpGdi* gdi = context->gdi; brush = &mem3blt->brush; bitmap = (gdiBitmap*) mem3blt->bitmap; - foreColor = freerdp_color_convert_var_bgr(mem3blt->foreColor, gdi->srcBpp, 32, gdi->clrconv); - backColor = freerdp_color_convert_var_bgr(mem3blt->backColor, gdi->srcBpp, 32, gdi->clrconv); + foreColor = freerdp_color_convert_rgb(mem3blt->foreColor, gdi->srcBpp, 24, gdi->clrconv); + backColor = freerdp_color_convert_rgb(mem3blt->backColor, gdi->srcBpp, 24, gdi->clrconv); + + originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); if (brush->style == GDI_BS_SOLID) { @@ -718,6 +721,8 @@ void gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) { fprintf(stderr, "Mem3Blt unimplemented brush style:%d\n", brush->style); } + + gdi_SetTextColor(gdi->drawing->hdc, originalColor); } void gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) From 8a44b2baa6a677e433f648b1f80abd245aaa7461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 12 Feb 2014 00:43:02 -0500 Subject: [PATCH 11/18] libfreerdp-core: add spn-class option --- client/common/cmdline.c | 5 +++ include/freerdp/settings.h | 4 +- libfreerdp/common/settings.c | 9 ++++ libfreerdp/core/gateway/ncacn_http.c | 1 - libfreerdp/core/nla.c | 61 ++++++++++++++++++++++++++-- libfreerdp/core/nla.h | 1 + libfreerdp/core/settings.c | 2 + libfreerdp/core/transport.c | 8 ++++ 8 files changed, 86 insertions(+), 5 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 2bdd76071..cfbdb5aa2 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -124,6 +124,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "cert-ignore", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, "ignore certificate" }, { "pcb", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Preconnection Blob" }, { "pcid", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Preconnection Id" }, + { "spn-class", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "SPN authentication service class" }, { "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" }, { "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" }, { "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" }, @@ -1138,6 +1139,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, settings->ServerHostname = _strdup(arg->Value); } } + CommandLineSwitchCase(arg, "spn-class") + { + settings->AuthenticationServiceClass = _strdup(arg->Value); + } CommandLineSwitchCase(arg, "vmconnect") { settings->ServerPort = 2179; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 11806054d..4ebb1bfa6 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -597,6 +597,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_NegotiationFlags 1095 #define FreeRDP_NegotiateSecurityLayer 1096 #define FreeRDP_RestrictedAdminModeRequired 1097 +#define FreeRDP_AuthenticationServiceClass 1098 #define FreeRDP_MstscCookieMode 1152 #define FreeRDP_CookieMaxLength 1153 #define FreeRDP_PreconnectionId 1154 @@ -948,7 +949,8 @@ struct rdp_settings ALIGN64 UINT32 NegotiationFlags; /* 1095 */ ALIGN64 BOOL NegotiateSecurityLayer; /* 1096 */ ALIGN64 BOOL RestrictedAdminModeRequired; /* 1097 */ - UINT64 padding1152[1152 - 1098]; /* 1098 */ + ALIGN64 char* AuthenticationServiceClass; /* 1098 */ + UINT64 padding1152[1152 - 1099]; /* 1099 */ /* Connection Cookie */ ALIGN64 BOOL MstscCookieMode; /* 1152 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index f2b501a0a..6ad75ef49 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -2137,6 +2137,10 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) return settings->DynamicDSTTimeZoneKeyName; break; + case FreeRDP_AuthenticationServiceClass: + return settings->AuthenticationServiceClass; + break; + case FreeRDP_PreconnectionBlob: return settings->PreconnectionBlob; break; @@ -2317,6 +2321,11 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) settings->DynamicDSTTimeZoneKeyName = _strdup(param); break; + case FreeRDP_AuthenticationServiceClass: + free(settings->AuthenticationServiceClass); + settings->AuthenticationServiceClass = _strdup(param); + break; + case FreeRDP_PreconnectionBlob: free(settings->PreconnectionBlob); settings->PreconnectionBlob = _strdup(param); diff --git a/libfreerdp/core/gateway/ncacn_http.c b/libfreerdp/core/gateway/ncacn_http.c index 35525f5c7..83daaa33f 100644 --- a/libfreerdp/core/gateway/ncacn_http.c +++ b/libfreerdp/core/gateway/ncacn_http.c @@ -161,7 +161,6 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel) return 0; } - //ntlm_client_make_spn(ntlm, NULL, settings->GatewayHostname); if (!ntlm_client_make_spn(ntlm, _T("HTTP"), settings->GatewayHostname)) { return 0; diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index d106d2471..f4f45561c 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1315,6 +1316,59 @@ void credssp_buffer_free(rdpCredssp* credssp) sspi_SecBufferFree(&credssp->authInfo); } +LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname) +{ + DWORD status; + DWORD SpnLength; + LPTSTR hostnameX = NULL; + LPTSTR ServiceClassX = NULL; + LPTSTR ServicePrincipalName = NULL; + +#ifdef UNICODE + ConvertToUnicode(CP_UTF8, 0, hostname, -1, &hostnameX, 0); + ConvertToUnicode(CP_UTF8, 0, ServiceClass, -1, &ServiceClassX, 0); +#else + hostnameX = _strdup(hostname); + ServiceClassX = _strdup(ServiceClass); +#endif + + if (!ServiceClass) + { + ServicePrincipalName = (LPTSTR) _tcsdup(hostnameX); + free(ServiceClassX); + free(hostnameX); + + return ServicePrincipalName; + } + + SpnLength = 0; + status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, NULL); + + if (status != ERROR_BUFFER_OVERFLOW) + { + free(ServiceClassX); + free(hostnameX); + return NULL; + } + + ServicePrincipalName = (LPTSTR) malloc(SpnLength * sizeof(TCHAR)); + + status = DsMakeSpn(ServiceClassX, hostnameX, NULL, 0, NULL, &SpnLength, ServicePrincipalName); + + if (status != ERROR_SUCCESS) + { + free(ServicePrincipalName); + free(ServiceClassX); + free(hostnameX); + return NULL; + } + + free(ServiceClassX); + free(hostnameX); + + return ServicePrincipalName; +} + /** * Create new CredSSP state machine. * @param transport @@ -1326,15 +1380,16 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* rdpCredssp* credssp; credssp = (rdpCredssp*) malloc(sizeof(rdpCredssp)); - ZeroMemory(credssp, sizeof(rdpCredssp)); - if (credssp != NULL) + if (credssp) { HKEY hKey; LONG status; DWORD dwType; DWORD dwSize; + ZeroMemory(credssp, sizeof(rdpCredssp)); + credssp->instance = instance; credssp->settings = settings; credssp->server = settings->ServerMode; @@ -1382,7 +1437,7 @@ rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* void credssp_free(rdpCredssp* credssp) { - if (credssp != NULL) + if (credssp) { if (credssp->table) credssp->table->DeleteSecurityContext(&credssp->context); diff --git a/libfreerdp/core/nla.h b/libfreerdp/core/nla.h index 5a4baa299..24eeb8d4b 100644 --- a/libfreerdp/core/nla.h +++ b/libfreerdp/core/nla.h @@ -58,6 +58,7 @@ struct rdp_credssp }; int credssp_authenticate(rdpCredssp* credssp); +LPTSTR credssp_make_spn(const char* ServiceClass, const char* hostname); rdpCredssp* credssp_new(freerdp* instance, rdpTransport* transport, rdpSettings* settings); void credssp_free(rdpCredssp* credssp); diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 07db3ab77..316d90d42 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -453,6 +453,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->ClientAddress = _strdup(settings->ClientAddress); /* 769 */ _settings->ClientDir = _strdup(settings->ClientDir); /* 770 */ _settings->DynamicDSTTimeZoneKeyName = _strdup(settings->DynamicDSTTimeZoneKeyName); /* 897 */ + _settings->AuthenticationServiceClass = _strdup(settings->AuthenticationServiceClass); /* 1098 */ _settings->PreconnectionBlob = _strdup(settings->PreconnectionBlob); /* 1155 */ _settings->KerberosKdc = _strdup(settings->KerberosKdc); /* 1344 */ _settings->KerberosRealm = _strdup(settings->KerberosRealm); /* 1345 */ @@ -820,6 +821,7 @@ void freerdp_settings_free(rdpSettings* settings) free(settings->RedirectionDomain); free(settings->RedirectionPassword); free(settings->RedirectionTsvUrl); + free(settings->AuthenticationServiceClass); freerdp_target_net_addresses_free(settings); freerdp_device_collection_free(settings); freerdp_static_channel_collection_free(settings); diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index affd27f5c..f0fe28d50 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -292,8 +292,16 @@ BOOL transport_connect_nla(rdpTransport* transport) return TRUE; if (!transport->credssp) + { transport->credssp = credssp_new(instance, transport, settings); + if (settings->AuthenticationServiceClass) + { + transport->credssp->ServicePrincipalName = + credssp_make_spn(settings->AuthenticationServiceClass, settings->ServerHostname); + } + } + if (credssp_authenticate(transport->credssp) < 0) { if (!connectErrorCode) From f4140abd2c5b8c53d50b0237f8e579234b3d200d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andre=CC=81=20Moreau?= Date: Wed, 12 Feb 2014 11:51:57 -0500 Subject: [PATCH 12/18] cmake: remove unused FindNPP.cmake --- CMakeLists.txt | 5 -- cmake/FindNPP.cmake | 119 -------------------------------------------- 2 files changed, 124 deletions(-) delete mode 100644 cmake/FindNPP.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 13265f13b..85132055b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -377,10 +377,6 @@ set(IPP_FEATURE_TYPE "OPTIONAL") set(IPP_FEATURE_PURPOSE "performance") set(IPP_FEATURE_DESCRIPTION "Intel Integrated Performance Primitives library") -set(NPP_FEATURE_TYPE "OPTIONAL") -set(NPP_FEATURE_PURPOSE "performance") -set(NPP_FEATURE_DESCRIPTION "NVIDIA Performance Primitives library") - set(JPEG_FEATURE_TYPE "OPTIONAL") set(JPEG_FEATURE_PURPOSE "codec") set(JPEG_FEATURE_DESCRIPTION "use JPEG library") @@ -458,7 +454,6 @@ if(TARGET_ARCH MATCHES "x86|x64") # Intel Performance Primitives find_feature(IPP ${IPP_FEATURE_TYPE} ${IPP_FEATURE_PURPOSE} ${IPP_FEATURE_DESCRIPTION}) endif() - find_feature(NPP ${NPP_FEATURE_TYPE} ${NPP_FEATURE_PURPOSE} ${NPP_FEATURE_DESCRIPTION}) endif() # Path to put FreeRDP data diff --git a/cmake/FindNPP.cmake b/cmake/FindNPP.cmake deleted file mode 100644 index 7b04ee43a..000000000 --- a/cmake/FindNPP.cmake +++ /dev/null @@ -1,119 +0,0 @@ -############################################################################### -# -# FindNPP.cmake -# -# NPP_LIBRARY_ROOT_DIR -- Path to the NPP dorectory. -# NPP_INCLUDES -- NPP Include directories. -# NPP_LIBRARIES -- NPP libraries. -# NPP_VERSION -- NPP version in format "major.minor.build". -# -# If not found automatically, please set NPP_LIBRARY_ROOT_DIR -# in CMake or set enviroment varivabe $NPP_ROOT -# -# Author: Anatoly Baksheev, Itseez Ltd. -# -# The MIT License -# -# License for the specific language governing rights and limitations under -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the "Software"), -# to deal in the Software without restriction, including without limitation -# the rights to use, copy, modify, merge, publish, distribute, sublicense, -# and/or sell copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -# DEALINGS IN THE SOFTWARE. -# -############################################################################### - -cmake_policy(PUSH) -cmake_minimum_required(VERSION 2.8.0) -cmake_policy(POP) - -if(NOT "${NPP_LIBRARY_ROOT_DIR}" STREQUAL "${NPP_LIBRARY_ROOT_DIR_INTERNAL}") - unset(NPP_INCLUDES CACHE) - unset(NPP_LIBRARIES CACHE) -endif() - -if(CMAKE_SIZEOF_VOID_P EQUAL 4) - if (UNIX OR APPLE) - set(NPP_SUFFIX "32") - else() - set(NPP_SUFFIX "-mt") - endif() -else(CMAKE_SIZEOF_VOID_P EQUAL 4) - if (UNIX OR APPLE) - set(NPP_SUFFIX "64") - else() - set(NPP_SUFFIX "-mt-x64") - endif() -endif(CMAKE_SIZEOF_VOID_P EQUAL 4) - -find_path(CUDA_ROOT_DIR "doc/CUDA_Toolkit_Release_Notes.txt" - PATHS "/Developer/NVIDIA" - PATH_SUFFIXES "CUDA-5.0" - DOC "CUDA root directory") - -find_path(NPP_INCLUDES "npp.h" - PATHS "${CUDA_ROOT_DIR}" - PATH_SUFFIXES "include" - DOC "NPP include directory") -mark_as_advanced(NPP_INCLUDES) - -find_library(NPP_LIBRARIES - NAMES "npp" "libnpp" "npp${NPP_SUFFIX}" "libnpp${NPP_SUFFIX}" - PATHS "${CUDA_ROOT_DIR}" - PATH_SUFFIXES "lib" - DOC "NPP library") -mark_as_advanced(NPP_LIBRARIES) - -if(EXISTS ${NPP_INCLUDES}/nppversion.h) - file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_major REGEX "#define NPP_VERSION_MAJOR.*") - file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_minor REGEX "#define NPP_VERSION_MINOR.*") - file(STRINGS ${NPP_INCLUDES}/nppversion.h npp_build REGEX "#define NPP_VERSION_BUILD.*") - - string(REGEX REPLACE "#define NPP_VERSION_MAJOR[ \t]+|//.*" "" npp_major ${npp_major}) - string(REGEX REPLACE "#define NPP_VERSION_MINOR[ \t]+|//.*" "" npp_minor ${npp_minor}) - string(REGEX REPLACE "#define NPP_VERSION_BUILD[ \t]+|//.*" "" npp_build ${npp_build}) - - string(REGEX MATCH "[0-9]+" npp_major ${npp_major}) - string(REGEX MATCH "[0-9]+" npp_minor ${npp_minor}) - string(REGEX MATCH "[0-9]+" npp_build ${npp_build}) - set(NPP_VERSION "${npp_major}.${npp_minor}.${npp_build}") -endif() - -if(NOT EXISTS ${NPP_LIBRARIES} OR NOT EXISTS ${NPP_INCLUDES}/npp.h) - set(NPP_FOUND FALSE) - message(WARNING "NPP headers/libraries are not found. Please specify NPP_LIBRARY_ROOT_DIR in CMake or set $NPP_ROOT_DIR.") -endif() - -include(FindPackageHandleStandardArgs) - -find_package_handle_standard_args(NPP - REQUIRED_VARS - NPP_INCLUDES - NPP_LIBRARIES - NPP_VERSION) - -if(APPLE) - # We need to add the path to cudart to the linker using rpath, since the library name for the cuda libraries is prepended with @rpath. - get_filename_component(_cuda_path_to_npp "${NPP_LIBRARIES}" PATH) - if(_cuda_path_to_npp) - list(APPEND NPP_LIBRARIES -Wl,-rpath "-Wl,${_cuda_path_to_npp}") - endif() -endif() - -set(NPP_FOUND TRUE) - -set(NPP_LIBRARY_ROOT_DIR_INTERNAL "${NPP_LIBRARY_ROOT_DIR}" CACHE INTERNAL - "This is the value of the last time NPP_LIBRARY_ROOT_DIR was set successfully." FORCE) - From 35a1aeac99ed962c5844c30ec7a4006ca8e2189e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 13 Feb 2014 11:59:05 -0500 Subject: [PATCH 13/18] libfreerdp-gdi: minor cleanup, set text color on PatBlt --- libfreerdp/gdi/gdi.c | 44 +++++++++++++++++++++++---------------- libfreerdp/gdi/graphics.c | 31 ++++++++++++++++----------- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index 2454a16ce..2bc0091b4 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -313,7 +313,7 @@ static const UINT32 rop3_code_table[] = }; /* Hatch Patterns as monochrome data */ -static BYTE GDI_BS_HACHTED_PATTERNS[] = +static BYTE GDI_BS_HATCHED_PATTERNS[] = { 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, /* HS_HORIZONTAL */ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, /* HS_VERTICAL */ @@ -438,7 +438,7 @@ gdiBitmap* gdi_bitmap_new_ex(rdpGdi* gdi, int width, int height, int bpp, BYTE* void gdi_bitmap_free_ex(gdiBitmap* bitmap) { - if (bitmap != NULL) + if (bitmap) { gdi_SelectObject(bitmap->hdc, (HGDIOBJECT) bitmap->org_bitmap); gdi_DeleteObject((HGDIOBJECT) bitmap->bitmap); @@ -457,7 +457,7 @@ void gdi_set_bounds(rdpContext* context, rdpBounds* bounds) { rdpGdi* gdi = context->gdi; - if (bounds != NULL) + if (bounds) { gdi_SetClipRgn(gdi->drawing->hdc, bounds->left, bounds->top, bounds->right - bounds->left + 1, bounds->bottom - bounds->top + 1); @@ -480,18 +480,24 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { BYTE* data; rdpBrush* brush; + UINT32 foreColor; + UINT32 backColor; + GDI_COLOR originalColor; HGDI_BRUSH originalBrush; rdpGdi* gdi = context->gdi; brush = &patblt->brush; + foreColor = freerdp_color_convert_rgb(patblt->foreColor, gdi->srcBpp, 24, gdi->clrconv); + backColor = freerdp_color_convert_rgb(patblt->backColor, gdi->srcBpp, 24, gdi->clrconv); + + originalColor = gdi_SetTextColor(gdi->drawing->hdc, foreColor); + if (brush->style == GDI_BS_SOLID) { - UINT32 color; originalBrush = gdi->drawing->hdc->brush; - color = freerdp_color_convert_rgb(patblt->foreColor, gdi->srcBpp, 32, gdi->clrconv); - gdi->drawing->hdc->brush = gdi_CreateSolidBrush(color); + gdi->drawing->hdc->brush = gdi_CreateSolidBrush(foreColor); gdi_PatBlt(gdi->drawing->hdc, patblt->nLeftRect, patblt->nTopRect, patblt->nWidth, patblt->nHeight, gdi_rop3_code(patblt->bRop)); @@ -503,7 +509,7 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { HGDI_BITMAP hBmp; - data = freerdp_mono_image_convert(GDI_BS_HACHTED_PATTERNS + 8 * brush->hatch, 8, 8, 1, + data = freerdp_mono_image_convert(GDI_BS_HATCHED_PATTERNS + 8 * brush->hatch, 8, 8, 1, gdi->dstBpp, patblt->backColor, patblt->foreColor, gdi->clrconv); hBmp = gdi_CreateBitmap(8, 8, gdi->drawing->hdc->bitsPerPixel, data); @@ -546,6 +552,8 @@ void gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) { fprintf(stderr, "unimplemented brush style:%d\n", brush->style); } + + gdi_SetTextColor(gdi->drawing->hdc, originalColor); } void gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) @@ -562,7 +570,7 @@ void gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) GDI_RECT rect; HGDI_BRUSH hBrush; UINT32 brush_color; - rdpGdi *gdi = context->gdi; + rdpGdi* gdi = context->gdi; gdi_CRgnToRect(opaque_rect->nLeftRect, opaque_rect->nTopRect, opaque_rect->nWidth, opaque_rect->nHeight, &rect); @@ -582,7 +590,7 @@ void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_o HGDI_BRUSH hBrush; UINT32 brush_color; DELTA_RECT* rectangle; - rdpGdi *gdi = context->gdi; + rdpGdi* gdi = context->gdi; for (i = 1; i < (int) multi_opaque_rect->numRectangles + 1; i++) { @@ -600,19 +608,19 @@ void gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* multi_o } } -void gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) +void gdi_line_to(rdpContext* context, LINE_TO_ORDER* lineTo) { UINT32 color; HGDI_PEN hPen; - rdpGdi *gdi = context->gdi; + rdpGdi* gdi = context->gdi; - color = freerdp_color_convert_rgb(line_to->penColor, gdi->srcBpp, 32, gdi->clrconv); - hPen = gdi_CreatePen(line_to->penStyle, line_to->penWidth, (GDI_COLOR) color); + color = freerdp_color_convert_rgb(lineTo->penColor, gdi->srcBpp, 32, gdi->clrconv); + hPen = gdi_CreatePen(lineTo->penStyle, lineTo->penWidth, (GDI_COLOR) color); gdi_SelectObject(gdi->drawing->hdc, (HGDIOBJECT) hPen); - gdi_SetROP2(gdi->drawing->hdc, line_to->bRop2); + gdi_SetROP2(gdi->drawing->hdc, lineTo->bRop2); - gdi_MoveToEx(gdi->drawing->hdc, line_to->nXStart, line_to->nYStart, NULL); - gdi_LineTo(gdi->drawing->hdc, line_to->nXEnd, line_to->nYEnd); + gdi_MoveToEx(gdi->drawing->hdc, lineTo->nXStart, lineTo->nYStart, NULL); + gdi_LineTo(gdi->drawing->hdc, lineTo->nXEnd, lineTo->nYEnd); gdi_DeleteObject((HGDIOBJECT) hPen); } @@ -620,12 +628,12 @@ void gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) void gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) { int i; + INT32 x; + INT32 y; UINT32 color; HGDI_PEN hPen; DELTA_POINT* points; rdpGdi* gdi = context->gdi; - INT32 x; - INT32 y; color = freerdp_color_convert_rgb(polyline->penColor, gdi->srcBpp, 32, gdi->clrconv); hPen = gdi_CreatePen(GDI_PS_SOLID, 1, (GDI_COLOR) color); diff --git a/libfreerdp/gdi/graphics.c b/libfreerdp/gdi/graphics.c index 2be36a50a..084c1b17c 100644 --- a/libfreerdp/gdi/graphics.c +++ b/libfreerdp/gdi/graphics.c @@ -96,36 +96,37 @@ void gdi_Bitmap_Paint(rdpContext* context, rdpBitmap* bitmap) void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, BYTE* data, int width, int height, int bpp, int length, - BOOL compressed, int codec_id) + BOOL compressed, int codecId) { + BOOL status; UINT16 size; - RFX_MESSAGE* msg; BYTE* src; BYTE* dst; int yindex; int xindex; rdpGdi* gdi; - BOOL status; + RFX_MESSAGE* msg; size = width * height * ((bpp + 7) / 8); - if (bitmap->data == NULL) + if (!bitmap->data) bitmap->data = (BYTE*) malloc(size); else bitmap->data = (BYTE*) realloc(bitmap->data, size); - switch (codec_id) + switch (codecId) { case RDP_CODEC_ID_NSCODEC: gdi = context->gdi; nsc_process_message(gdi->nsc_context, bpp, width, height, data, length); - freerdp_image_flip(((NSC_CONTEXT*)gdi->nsc_context)->BitmapData, bitmap->data, width, height, bpp); + freerdp_image_flip(((NSC_CONTEXT*) gdi->nsc_context)->BitmapData, bitmap->data, width, height, bpp); break; + case RDP_CODEC_ID_REMOTEFX: gdi = context->gdi; rfx_context_set_pixel_format(gdi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); msg = rfx_process_message(gdi->rfx_context, data, length); - if (msg == NULL) + if (!msg) { fprintf(stderr, "gdi_Bitmap_Decompress: rfx Decompression Failed\n"); } @@ -159,7 +160,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap, { status = bitmap_decompress(data, bitmap->data, width, height, length, bpp, bpp); - if (status == FALSE) + if (!status) { fprintf(stderr, "gdi_Bitmap_Decompress: Bitmap Decompression Failed\n"); } @@ -268,8 +269,11 @@ void gdi_register_graphics(rdpGraphics* graphics) rdpBitmap* bitmap; rdpGlyph* glyph; - bitmap = (rdpBitmap*) malloc(sizeof(rdpBitmap)); - ZeroMemory(bitmap, sizeof(rdpBitmap)); + bitmap = (rdpBitmap*) calloc(1, sizeof(rdpBitmap)); + + if (!bitmap) + return; + bitmap->size = sizeof(gdiBitmap); bitmap->New = gdi_Bitmap_New; @@ -281,8 +285,11 @@ void gdi_register_graphics(rdpGraphics* graphics) graphics_register_bitmap(graphics, bitmap); free(bitmap); - glyph = (rdpGlyph*) malloc(sizeof(rdpGlyph)); - ZeroMemory(glyph, sizeof(rdpGlyph)); + glyph = (rdpGlyph*) calloc(1, sizeof(rdpGlyph)); + + if (!glyph) + return; + glyph->size = sizeof(gdiGlyph); glyph->New = gdi_Glyph_New; From 87be2e0f80fa9b3fb6bae2eb6a65d4a33737eed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 14 Feb 2014 00:43:31 -0500 Subject: [PATCH 14/18] freerdp: add option to disable credentials delegation --- client/common/cmdline.c | 5 +++++ include/freerdp/settings.h | 4 +++- libfreerdp/common/settings.c | 8 ++++++++ libfreerdp/core/nla.c | 9 ++++++--- libfreerdp/core/settings.c | 1 + 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index cfbdb5aa2..29d964f59 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -125,6 +125,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "pcb", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Preconnection Blob" }, { "pcid", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Preconnection Id" }, { "spn-class", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "SPN authentication service class" }, + { "credentials-delegation", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Disable credentials delegation" }, { "vmconnect", COMMAND_LINE_VALUE_OPTIONAL, "", NULL, NULL, -1, NULL, "Hyper-V console (use port 2179, disable negotiation)" }, { "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" }, { "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" }, @@ -1143,6 +1144,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->AuthenticationServiceClass = _strdup(arg->Value); } + CommandLineSwitchCase(arg, "credentials-delegation") + { + settings->DisableCredentialsDelegation = arg->Value ? FALSE : TRUE; + } CommandLineSwitchCase(arg, "vmconnect") { settings->ServerPort = 2179; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 4ebb1bfa6..daa98623f 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -598,6 +598,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_NegotiateSecurityLayer 1096 #define FreeRDP_RestrictedAdminModeRequired 1097 #define FreeRDP_AuthenticationServiceClass 1098 +#define FreeRDP_DisableCredentialsDelegation 1099 #define FreeRDP_MstscCookieMode 1152 #define FreeRDP_CookieMaxLength 1153 #define FreeRDP_PreconnectionId 1154 @@ -950,7 +951,8 @@ struct rdp_settings ALIGN64 BOOL NegotiateSecurityLayer; /* 1096 */ ALIGN64 BOOL RestrictedAdminModeRequired; /* 1097 */ ALIGN64 char* AuthenticationServiceClass; /* 1098 */ - UINT64 padding1152[1152 - 1099]; /* 1099 */ + ALIGN64 BOOL DisableCredentialsDelegation; /* 1099 */ + UINT64 padding1152[1152 - 1100]; /* 1100 */ /* Connection Cookie */ ALIGN64 BOOL MstscCookieMode; /* 1152 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 6ad75ef49..19bf5f784 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -654,6 +654,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) return settings->RestrictedAdminModeRequired; break; + case FreeRDP_DisableCredentialsDelegation: + return settings->DisableCredentialsDelegation; + break; + case FreeRDP_MstscCookieMode: return settings->MstscCookieMode; break; @@ -1122,6 +1126,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->RestrictedAdminModeRequired = param; break; + case FreeRDP_DisableCredentialsDelegation: + settings->DisableCredentialsDelegation = param; + break; + case FreeRDP_MstscCookieMode: settings->MstscCookieMode = param; break; diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index f4f45561c..970652d4f 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -123,6 +123,9 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) settings = credssp->settings; instance = (freerdp*) settings->instance; + if (settings->RestrictedAdminModeRequired) + settings->DisableCredentialsDelegation = TRUE; + if ((!settings->Password) || (!settings->Username) || (!strlen(settings->Password)) || (!strlen(settings->Username))) { @@ -998,7 +1001,7 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) UserLength = credssp->identity.UserLength; PasswordLength = credssp->identity.PasswordLength; - if (credssp->settings->RestrictedAdminModeRequired) + if (credssp->settings->DisableCredentialsDelegation) { credssp->identity.DomainLength = 0; credssp->identity.UserLength = 0; @@ -1008,10 +1011,10 @@ void credssp_encode_ts_credentials(rdpCredssp* credssp) length = ber_sizeof_sequence(credssp_sizeof_ts_credentials(credssp)); sspi_SecBufferAlloc(&credssp->ts_credentials, length); - s = Stream_New(credssp->ts_credentials.pvBuffer, length); + s = Stream_New((BYTE*) credssp->ts_credentials.pvBuffer, length); credssp_write_ts_credentials(credssp, s); - if (credssp->settings->RestrictedAdminModeRequired) + if (credssp->settings->DisableCredentialsDelegation) { credssp->identity.DomainLength = DomainLength; credssp->identity.UserLength = UserLength; diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 316d90d42..5db64acdb 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -618,6 +618,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->Authentication = settings->Authentication; /* 1092 */ _settings->NegotiateSecurityLayer = settings->NegotiateSecurityLayer; /* 1096 */ _settings->RestrictedAdminModeRequired = settings->RestrictedAdminModeRequired; /* 1097 */ + _settings->DisableCredentialsDelegation = settings->DisableCredentialsDelegation; /* 1099 */ _settings->MstscCookieMode = settings->MstscCookieMode; /* 1152 */ _settings->SendPreconnectionPdu = settings->SendPreconnectionPdu; /* 1156 */ _settings->IgnoreCertificate = settings->IgnoreCertificate; /* 1408 */ From 858923836c12b6201630ee3e3c2100991387ab24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 15 Feb 2014 21:57:33 -0500 Subject: [PATCH 15/18] libfreerdp-codec: fix windows compilation for new region code --- libfreerdp/codec/region.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libfreerdp/codec/region.c b/libfreerdp/codec/region.c index 0b06c63d3..3757eacf8 100644 --- a/libfreerdp/codec/region.c +++ b/libfreerdp/codec/region.c @@ -110,7 +110,7 @@ const RECTANGLE_16 *region16_rects(const REGION16 *region, int *nbRects) return (RECTANGLE_16 *)(data + 1); } -static inline RECTANGLE_16 *region16_rects_noconst(REGION16 *region) +static INLINE RECTANGLE_16 *region16_rects_noconst(REGION16 *region) { REGION16_DATA *data; @@ -168,7 +168,7 @@ void region16_clear(REGION16 *region) ZeroMemory(®ion->extents, sizeof(region->extents)); } -static inline REGION16_DATA *allocateRegion(long nbItems) +static INLINE REGION16_DATA *allocateRegion(long nbItems) { long allocSize = sizeof(REGION16_DATA) + nbItems * sizeof(RECTANGLE_16); REGION16_DATA *ret = (REGION16_DATA *)malloc(allocSize); @@ -647,13 +647,14 @@ BOOL region16_union_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 } -BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) { +BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) +{ + const RECTANGLE_16 *rect, *endPtr, *srcExtents; + int nbRects; + assert(src); assert(src->data); - const RECTANGLE_16 *rect, *endPtr, *srcExtents;; - int nbRects; - rect = region16_rects(src, &nbRects); if (!nbRects) return FALSE; @@ -678,15 +679,15 @@ BOOL region16_intersects_rect(const REGION16 *src, const RECTANGLE_16 *arg2) { BOOL region16_intersect_rect(REGION16 *dst, const REGION16 *src, const RECTANGLE_16 *rect) { - assert(src); - assert(src->data); - REGION16_DATA *newItems; const RECTANGLE_16 *srcPtr, *endPtr, *srcExtents; RECTANGLE_16 *dstPtr; int nbRects, usedRects; RECTANGLE_16 common, newExtents; + assert(src); + assert(src->data); + srcPtr = region16_rects(src, &nbRects); if (!nbRects) { From 5a7cffe59cb475e4384c59ab63e70e3774cd7a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 26 Feb 2014 12:34:08 -0500 Subject: [PATCH 16/18] winpr: expand specstrings and error definitions --- winpr/include/winpr/crt.h | 7 +- winpr/include/winpr/crypto.h | 10 + winpr/include/winpr/error.h | 95 ++++ winpr/include/winpr/registry.h | 2 - winpr/include/winpr/spec.h | 888 ++++++++++++++++++++++++++++++++- winpr/include/winpr/wtypes.h | 37 ++ 6 files changed, 1029 insertions(+), 10 deletions(-) diff --git a/winpr/include/winpr/crt.h b/winpr/include/winpr/crt.h index 694544a43..326b13b9a 100644 --- a/winpr/include/winpr/crt.h +++ b/winpr/include/winpr/crt.h @@ -26,6 +26,7 @@ #include +#include #include #include @@ -53,12 +54,6 @@ WINPR_API PVOID SecureZeroMemory(PVOID ptr, SIZE_T cnt); typedef int errno_t; #endif -#define RTL_NUMBER_OF_V1(A) (sizeof(A) / sizeof((A)[0])) -#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A) - -#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) -#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A) - #ifdef __cplusplus extern "C" { #endif diff --git a/winpr/include/winpr/crypto.h b/winpr/include/winpr/crypto.h index 67aa8d024..75488865a 100644 --- a/winpr/include/winpr/crypto.h +++ b/winpr/include/winpr/crypto.h @@ -31,6 +31,16 @@ #else +/* ncrypt.h */ + +typedef ULONG_PTR NCRYPT_HANDLE; +typedef ULONG_PTR NCRYPT_PROV_HANDLE; +typedef ULONG_PTR NCRYPT_KEY_HANDLE; +typedef ULONG_PTR NCRYPT_HASH_HANDLE; +typedef ULONG_PTR NCRYPT_SECRET_HANDLE; + +/* wincrypt.h */ + #define GET_ALG_CLASS(x) (x & (7 << 13)) #define GET_ALG_TYPE(x) (x & (15 << 9)) #define GET_ALG_SID(x) (x & (511)) diff --git a/winpr/include/winpr/error.h b/winpr/include/winpr/error.h index 077d2ca14..6f59e4884 100644 --- a/winpr/include/winpr/error.h +++ b/winpr/include/winpr/error.h @@ -37,6 +37,60 @@ extern "C" { #define NO_ERROR 0 #endif +#define E_UNEXPECTED 0x8000FFFF +#define E_NOTIMPL 0x80004001 +#define E_OUTOFMEMORY 0x8007000E +#define E_INVALIDARG 0x80070057 +#define E_NOINTERFACE 0x80004002 +#define E_POINTER 0x80004003 +#define E_HANDLE 0x80070006 +#define E_ABORT 0x80004004 +#define E_FAIL 0x80004005 +#define E_ACCESSDENIED 0x80070005 + +#define CO_E_INIT_TLS 0x80004006 +#define CO_E_INIT_SHARED_ALLOCATOR 0x80004007 +#define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008 +#define CO_E_INIT_CLASS_CACHE 0x80004009 +#define CO_E_INIT_RPC_CHANNEL 0x8000400A +#define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400B +#define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400C +#define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400D +#define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400E +#define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400F +#define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010 +#define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011 +#define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012 +#define CO_E_CANT_REMOTE 0x80004013 +#define CO_E_BAD_SERVER_NAME 0x80004014 +#define CO_E_WRONG_SERVER_IDENTITY 0x80004015 +#define CO_E_OLE1DDE_DISABLED 0x80004016 +#define CO_E_RUNAS_SYNTAX 0x80004017 +#define CO_E_CREATEPROCESS_FAILURE 0x80004018 +#define CO_E_RUNAS_CREATEPROCESS_FAILURE 0x80004019 +#define CO_E_RUNAS_LOGON_FAILURE 0x8000401A +#define CO_E_LAUNCH_PERMSSION_DENIED 0x8000401B +#define CO_E_START_SERVICE_FAILURE 0x8000401C +#define CO_E_REMOTE_COMMUNICATION_FAILURE 0x8000401D +#define CO_E_SERVER_START_TIMEOUT 0x8000401E +#define CO_E_CLSREG_INCONSISTENT 0x8000401F +#define CO_E_IIDREG_INCONSISTENT 0x80004020 +#define CO_E_NOT_SUPPORTED 0x80004021 +#define CO_E_RELOAD_DLL 0x80004022 +#define CO_E_MSI_ERROR 0x80004023 +#define CO_E_ATTEMPT_TO_CREATE_OUTSIDE_CLIENT_CONTEXT 0x80004024 +#define CO_E_SERVER_PAUSED 0x80004025 +#define CO_E_SERVER_NOT_PAUSED 0x80004026 +#define CO_E_CLASS_DISABLED 0x80004027 +#define CO_E_CLRNOTAVAILABLE 0x80004028 +#define CO_E_ASYNC_WORK_REJECTED 0x80004029 +#define CO_E_SERVER_INIT_TIMEOUT 0x8000402A +#define CO_E_NO_SECCTX_IN_ACTIVATE 0x8000402B +#define CO_E_TRACKER_CONFIG 0x80004030 +#define CO_E_THREADPOOL_CONFIG 0x80004031 +#define CO_E_SXS_CONFIG 0x80004032 +#define CO_E_MALFORMED_SPN 0x80004033 + #define FACILITY_WINDOWSUPDATE 36 #define FACILITY_WINDOWS_CE 24 #define FACILITY_WINDOWS 8 @@ -2879,6 +2933,47 @@ extern "C" { #define ERROR_STATE_CONTAINER_NAME_SIZE_LIMIT_EXCEEDED 0x00003DCA #define ERROR_API_UNAVAILABLE 0x00003DE1 +#ifndef FACILITY_WEBSERVICES +#define FACILITY_WEBSERVICES 61 +#define WS_S_ASYNC 0x003D0000 +#define WS_S_END 0x003D0001 +#define WS_E_INVALID_FORMAT 0x803D0000 +#define WS_E_OBJECT_FAULTED 0x803D0001 +#define WS_E_NUMERIC_OVERFLOW 0x803D0002 +#define WS_E_INVALID_OPERATION 0x803D0003 +#define WS_E_OPERATION_ABORTED 0x803D0004 +#define WS_E_ENDPOINT_ACCESS_DENIED 0x803D0005 +#define WS_E_OPERATION_TIMED_OUT 0x803D0006 +#define WS_E_OPERATION_ABANDONED 0x803D0007 +#define WS_E_QUOTA_EXCEEDED 0x803D0008 +#define WS_E_NO_TRANSLATION_AVAILABLE 0x803D0009 +#define WS_E_SECURITY_VERIFICATION_FAILURE 0x803D000A +#define WS_E_ADDRESS_IN_USE 0x803D000B +#define WS_E_ADDRESS_NOT_AVAILABLE 0x803D000C +#define WS_E_ENDPOINT_NOT_FOUND 0x803D000D +#define WS_E_ENDPOINT_NOT_AVAILABLE 0x803D000E +#define WS_E_ENDPOINT_FAILURE 0x803D000F +#define WS_E_ENDPOINT_UNREACHABLE 0x803D0010 +#define WS_E_ENDPOINT_ACTION_NOT_SUPPORTED 0x803D0011 +#define WS_E_ENDPOINT_TOO_BUSY 0x803D0012 +#define WS_E_ENDPOINT_FAULT_RECEIVED 0x803D0013 +#define WS_E_ENDPOINT_DISCONNECTED 0x803D0014 +#define WS_E_PROXY_FAILURE 0x803D0015 +#define WS_E_PROXY_ACCESS_DENIED 0x803D0016 +#define WS_E_NOT_SUPPORTED 0x803D0017 +#define WS_E_PROXY_REQUIRES_BASIC_AUTH 0x803D0018 +#define WS_E_PROXY_REQUIRES_DIGEST_AUTH 0x803D0019 +#define WS_E_PROXY_REQUIRES_NTLM_AUTH 0x803D001A +#define WS_E_PROXY_REQUIRES_NEGOTIATE_AUTH 0x803D001B +#define WS_E_SERVER_REQUIRES_BASIC_AUTH 0x803D001C +#define WS_E_SERVER_REQUIRES_DIGEST_AUTH 0x803D001D +#define WS_E_SERVER_REQUIRES_NTLM_AUTH 0x803D001E +#define WS_E_SERVER_REQUIRES_NEGOTIATE_AUTH 0x803D001F +#define WS_E_INVALID_ENDPOINT_URL 0x803D0020 +#define WS_E_OTHER 0x803D0021 +#define WS_E_SECURITY_TOKEN_EXPIRED 0x803D0022 +#define WS_E_SECURITY_SYSTEM_FAILURE 0x803D0023 +#endif #define EXCEPTION_MAXIMUM_PARAMETERS 15 diff --git a/winpr/include/winpr/registry.h b/winpr/include/winpr/registry.h index e6f9757f4..229bc6f13 100644 --- a/winpr/include/winpr/registry.h +++ b/winpr/include/winpr/registry.h @@ -102,8 +102,6 @@ extern "C" { #define REG_QWORD 11 #define REG_QWORD_LITTLE_ENDIAN 11 -#define WINAPI WINPR_API - typedef HANDLE HKEY; typedef HANDLE* PHKEY; diff --git a/winpr/include/winpr/spec.h b/winpr/include/winpr/spec.h index 917e8af82..27d8ade2c 100644 --- a/winpr/include/winpr/spec.h +++ b/winpr/include/winpr/spec.h @@ -28,6 +28,29 @@ #else +#define DUMMYUNIONNAME u +#define DUMMYUNIONNAME1 u1 +#define DUMMYUNIONNAME2 u2 +#define DUMMYUNIONNAME3 u3 +#define DUMMYUNIONNAME4 u4 +#define DUMMYUNIONNAME5 u5 +#define DUMMYUNIONNAME6 u6 +#define DUMMYUNIONNAME7 u7 +#define DUMMYUNIONNAME8 u8 + +#define DUMMYSTRUCTNAME s +#define DUMMYSTRUCTNAME1 s1 +#define DUMMYSTRUCTNAME2 s2 +#define DUMMYSTRUCTNAME3 s3 +#define DUMMYSTRUCTNAME4 s4 +#define DUMMYSTRUCTNAME5 s5 + +#if (defined(_M_AMD64) || defined(_M_ARM)) && !defined(_WIN32) +#define _UNALIGNED __unaligned +#else +#define _UNALIGNED +#endif + #ifndef DECLSPEC_ALIGN #if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(MIDL_PASS) #define DECLSPEC_ALIGN(x) __declspec(align(x)) @@ -44,8 +67,6 @@ #define MEMORY_ALLOCATION_ALIGNMENT 8 #endif -#define DUMMYSTRUCTNAME s - #ifdef __GNUC__ #ifndef __declspec #define __declspec(e) __attribute__((e)) @@ -60,6 +81,869 @@ #endif #endif /* DECLSPEC_NORETURN */ +/** + * Header Annotations: + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa383701/ + */ + +#define __field_bcount(size) __notnull __byte_writableTo(size) +#define __field_ecount(size) __notnull __elem_writableTo(size) +#define __post_invalid _Post_ __notvalid + +#define __deref_in +#define __deref_in_ecount(size) +#define __deref_in_bcount(size) +#define __deref_in_opt +#define __deref_in_ecount_opt(size) +#define __deref_in_bcount_opt(size) +#define __deref_opt_in +#define __deref_opt_in_ecount(size) +#define __deref_opt_in_bcount(size) +#define __deref_opt_in_opt +#define __deref_opt_in_ecount_opt(size) +#define __deref_opt_in_bcount_opt(size) +#define __out_awcount(expr,size) +#define __in_awcount(expr,size) +#define __nullnullterminated +#define __in_data_source(src_sym) +#define __kernel_entry +#define __out_data_source(src_sym) +#define __analysis_noreturn +#define _Check_return_opt_ +#define _Check_return_wat_ + +#define __inner_exceptthat +#define __inner_typefix(ctype) +#define _Always_(annos) +#define _Analysis_noreturn_ +#define _Analysis_assume_(expr) +#define _At_(target, annos) +#define _At_buffer_(target, iter, bound, annos) +#define _Check_return_ +#define _COM_Outptr_ +#define _COM_Outptr_opt_ +#define _COM_Outptr_opt_result_maybenull_ +#define _COM_Outptr_result_maybenull_ +#define _Const_ +#define _Deref_in_bound_ +#define _Deref_in_range_(lb,ub) +#define _Deref_inout_bound_ +#define _Deref_inout_z_ +#define _Deref_inout_z_bytecap_c_(size) +#define _Deref_inout_z_cap_c_(size) +#define _Deref_opt_out_ +#define _Deref_opt_out_opt_ +#define _Deref_opt_out_opt_z_ +#define _Deref_opt_out_z_ +#define _Deref_out_ +#define _Deref_out_bound_ +#define _Deref_out_opt_ +#define _Deref_out_opt_z_ +#define _Deref_out_range_(lb,ub) +#define _Deref_out_z_ +#define _Deref_out_z_bytecap_c_(size) +#define _Deref_out_z_cap_c_(size) +#define _Deref_post_bytecap_(size) +#define _Deref_post_bytecap_c_(size) +#define _Deref_post_bytecap_x_(size) +#define _Deref_post_bytecount_(size) +#define _Deref_post_bytecount_c_(size) +#define _Deref_post_bytecount_x_(size) +#define _Deref_post_cap_(size) +#define _Deref_post_cap_c_(size) +#define _Deref_post_cap_x_(size) +#define _Deref_post_count_(size) +#define _Deref_post_count_c_(size) +#define _Deref_post_count_x_(size) +#define _Deref_post_maybenull_ +#define _Deref_post_notnull_ +#define _Deref_post_null_ +#define _Deref_post_opt_bytecap_(size) +#define _Deref_post_opt_bytecap_c_(size) +#define _Deref_post_opt_bytecap_x_(size) +#define _Deref_post_opt_bytecount_(size) +#define _Deref_post_opt_bytecount_c_(size) +#define _Deref_post_opt_bytecount_x_(size) +#define _Deref_post_opt_cap_(size) +#define _Deref_post_opt_cap_c_(size) +#define _Deref_post_opt_cap_x_(size) +#define _Deref_post_opt_count_(size) +#define _Deref_post_opt_count_c_(size) +#define _Deref_post_opt_count_x_(size) +#define _Deref_post_opt_valid_ +#define _Deref_post_opt_valid_bytecap_(size) +#define _Deref_post_opt_valid_bytecap_c_(size) +#define _Deref_post_opt_valid_bytecap_x_(size) +#define _Deref_post_opt_valid_cap_(size) +#define _Deref_post_opt_valid_cap_c_(size) +#define _Deref_post_opt_valid_cap_x_(size) +#define _Deref_post_opt_z_ +#define _Deref_post_opt_z_bytecap_(size) +#define _Deref_post_opt_z_bytecap_c_(size) +#define _Deref_post_opt_z_bytecap_x_(size) +#define _Deref_post_opt_z_cap_(size) +#define _Deref_post_opt_z_cap_c_(size) +#define _Deref_post_opt_z_cap_x_(size) +#define _Deref_post_valid_ +#define _Deref_post_valid_bytecap_(size) +#define _Deref_post_valid_bytecap_c_(size) +#define _Deref_post_valid_bytecap_x_(size) +#define _Deref_post_valid_cap_(size) +#define _Deref_post_valid_cap_c_(size) +#define _Deref_post_valid_cap_x_(size) +#define _Deref_post_z_ +#define _Deref_post_z_bytecap_(size) +#define _Deref_post_z_bytecap_c_(size) +#define _Deref_post_z_bytecap_x_(size) +#define _Deref_post_z_cap_(size) +#define _Deref_post_z_cap_c_(size) +#define _Deref_post_z_cap_x_(size) +#define _Deref_pre_bytecap_(size) +#define _Deref_pre_bytecap_c_(size) +#define _Deref_pre_bytecap_x_(size) +#define _Deref_pre_bytecount_(size) +#define _Deref_pre_bytecount_c_(size) +#define _Deref_pre_bytecount_x_(size) +#define _Deref_pre_cap_(size) +#define _Deref_pre_cap_c_(size) +#define _Deref_pre_cap_x_(size) +#define _Deref_pre_count_(size) +#define _Deref_pre_count_c_(size) +#define _Deref_pre_count_x_(size) +#define _Deref_pre_invalid_ +#define _Deref_pre_maybenull_ +#define _Deref_pre_notnull_ +#define _Deref_pre_null_ +#define _Deref_pre_opt_bytecap_(size) +#define _Deref_pre_opt_bytecap_c_(size) +#define _Deref_pre_opt_bytecap_x_(size) +#define _Deref_pre_opt_bytecount_(size) +#define _Deref_pre_opt_bytecount_c_(size) +#define _Deref_pre_opt_bytecount_x_(size) +#define _Deref_pre_opt_cap_(size) +#define _Deref_pre_opt_cap_c_(size) +#define _Deref_pre_opt_cap_x_(size) +#define _Deref_pre_opt_count_(size) +#define _Deref_pre_opt_count_c_(size) +#define _Deref_pre_opt_count_x_(size) +#define _Deref_pre_opt_valid_ +#define _Deref_pre_opt_valid_bytecap_(size) +#define _Deref_pre_opt_valid_bytecap_c_(size) +#define _Deref_pre_opt_valid_bytecap_x_(size) +#define _Deref_pre_opt_valid_cap_(size) +#define _Deref_pre_opt_valid_cap_c_(size) +#define _Deref_pre_opt_valid_cap_x_(size) +#define _Deref_pre_opt_z_ +#define _Deref_pre_opt_z_bytecap_(size) +#define _Deref_pre_opt_z_bytecap_c_(size) +#define _Deref_pre_opt_z_bytecap_x_(size) +#define _Deref_pre_opt_z_cap_(size) +#define _Deref_pre_opt_z_cap_c_(size) +#define _Deref_pre_opt_z_cap_x_(size) +#define _Deref_pre_readonly_ +#define _Deref_pre_valid_ +#define _Deref_pre_valid_bytecap_(size) +#define _Deref_pre_valid_bytecap_c_(size) +#define _Deref_pre_valid_bytecap_x_(size) +#define _Deref_pre_valid_cap_(size) +#define _Deref_pre_valid_cap_c_(size) +#define _Deref_pre_valid_cap_x_(size) +#define _Deref_pre_writeonly_ +#define _Deref_pre_z_ +#define _Deref_pre_z_bytecap_(size) +#define _Deref_pre_z_bytecap_c_(size) +#define _Deref_pre_z_bytecap_x_(size) +#define _Deref_pre_z_cap_(size) +#define _Deref_pre_z_cap_c_(size) +#define _Deref_pre_z_cap_x_(size) +#define _Deref_prepost_bytecap_(size) +#define _Deref_prepost_bytecap_x_(size) +#define _Deref_prepost_bytecount_(size) +#define _Deref_prepost_bytecount_x_(size) +#define _Deref_prepost_cap_(size) +#define _Deref_prepost_cap_x_(size) +#define _Deref_prepost_count_(size) +#define _Deref_prepost_count_x_(size) +#define _Deref_prepost_opt_bytecap_(size) +#define _Deref_prepost_opt_bytecap_x_(size) +#define _Deref_prepost_opt_bytecount_(size) +#define _Deref_prepost_opt_bytecount_x_(size) +#define _Deref_prepost_opt_cap_(size) +#define _Deref_prepost_opt_cap_x_(size) +#define _Deref_prepost_opt_count_(size) +#define _Deref_prepost_opt_count_x_(size) +#define _Deref_prepost_opt_valid_ +#define _Deref_prepost_opt_valid_bytecap_(size) +#define _Deref_prepost_opt_valid_bytecap_x_(size) +#define _Deref_prepost_opt_valid_cap_(size) +#define _Deref_prepost_opt_valid_cap_x_(size) +#define _Deref_prepost_opt_z_ +#define _Deref_prepost_opt_z_bytecap_(size) +#define _Deref_prepost_opt_z_cap_(size) +#define _Deref_prepost_valid_ +#define _Deref_prepost_valid_bytecap_(size) +#define _Deref_prepost_valid_bytecap_x_(size) +#define _Deref_prepost_valid_cap_(size) +#define _Deref_prepost_valid_cap_x_(size) +#define _Deref_prepost_z_ +#define _Deref_prepost_z_bytecap_(size) +#define _Deref_prepost_z_cap_(size) +#define _Deref_ret_bound_ +#define _Deref_ret_opt_z_ +#define _Deref_ret_range_(lb,ub) +#define _Deref_ret_z_ +#define _Deref2_pre_readonly_ +#define _Field_range_(min,max) +#define _Field_size_(size) +#define _Field_size_bytes_(size) +#define _Field_size_bytes_full_(size) +#define _Field_size_bytes_full_opt_(size) +#define _Field_size_bytes_opt_(size) +#define _Field_size_bytes_part_(size, count) +#define _Field_size_bytes_part_opt_(size, count) +#define _Field_size_full_(size) +#define _Field_size_full_opt_(size) +#define _Field_size_opt_(size) +#define _Field_size_part_(size, count) +#define _Field_size_part_opt_(size, count) +#define _Field_z_ +#define _Function_class_(x) +#define _Group_(annos) +#define _In_ +#define _In_bound_ +#define _In_bytecount_(size) +#define _In_bytecount_c_(size) +#define _In_bytecount_x_(size) +#define _In_count_(size) +#define _In_count_c_(size) +#define _In_count_x_(size) +#define _In_defensive_(annotes) +#define _In_opt_ +#define _In_opt_bytecount_(size) +#define _In_opt_bytecount_c_(size) +#define _In_opt_bytecount_x_(size) +#define _In_opt_count_(size) +#define _In_opt_count_c_(size) +#define _In_opt_count_x_(size) +#define _In_opt_ptrdiff_count_(size) +#define _In_opt_z_ +#define _In_opt_z_bytecount_(size) +#define _In_opt_z_bytecount_c_(size) +#define _In_opt_z_count_(size) +#define _In_opt_z_count_c_(size) +#define _In_ptrdiff_count_(size) +#define _In_range_(lb,ub) +#define _In_reads_(size) +#define _In_reads_bytes_(size) +#define _In_reads_bytes_opt_(size) +#define _In_reads_opt_(size) +#define _In_reads_opt_z_(size) +#define _In_reads_or_z_(size) +#define _In_reads_to_ptr_(ptr) +#define _In_reads_to_ptr_opt_(ptr) +#define _In_reads_to_ptr_opt_z_(ptr) +#define _In_reads_to_ptr_z_(ptr) +#define _In_reads_z_(size) +#define _In_z_ +#define _In_z_bytecount_(size) +#define _In_z_bytecount_c_(size) +#define _In_z_count_(size) +#define _In_z_count_c_(size) +#define _Inout_ +#define _Inout_bytecap_(size) +#define _Inout_bytecap_c_(size) +#define _Inout_bytecap_x_(size) +#define _Inout_bytecount_(size) +#define _Inout_bytecount_c_(size) +#define _Inout_bytecount_x_(size) +#define _Inout_cap_(size) +#define _Inout_cap_c_(size) +#define _Inout_cap_x_(size) +#define _Inout_count_(size) +#define _Inout_count_c_(size) +#define _Inout_count_x_(size) +#define _Inout_defensive_(annotes) +#define _Inout_opt_ +#define _Inout_opt_bytecap_(size) +#define _Inout_opt_bytecap_c_(size) +#define _Inout_opt_bytecap_x_(size) +#define _Inout_opt_bytecount_(size) +#define _Inout_opt_bytecount_c_(size) +#define _Inout_opt_bytecount_x_(size) +#define _Inout_opt_cap_(size) +#define _Inout_opt_cap_c_(size) +#define _Inout_opt_cap_x_(size) +#define _Inout_opt_count_(size) +#define _Inout_opt_count_c_(size) +#define _Inout_opt_count_x_(size) +#define _Inout_opt_ptrdiff_count_(size) +#define _Inout_opt_z_ +#define _Inout_opt_z_bytecap_(size) +#define _Inout_opt_z_bytecap_c_(size) +#define _Inout_opt_z_bytecap_x_(size) +#define _Inout_opt_z_bytecount_(size) +#define _Inout_opt_z_bytecount_c_(size) +#define _Inout_opt_z_cap_(size) +#define _Inout_opt_z_cap_c_(size) +#define _Inout_opt_z_cap_x_(size) +#define _Inout_opt_z_count_(size) +#define _Inout_opt_z_count_c_(size) +#define _Inout_ptrdiff_count_(size) +#define _Inout_updates_(size) +#define _Inout_updates_all_(size) +#define _Inout_updates_all_opt_(size) +#define _Inout_updates_bytes_(size) +#define _Inout_updates_bytes_all_(size) +#define _Inout_updates_bytes_all_opt_(size) +#define _Inout_updates_bytes_opt_(size) +#define _Inout_updates_bytes_to_(size,count) +#define _Inout_updates_bytes_to_opt_(size,count) +#define _Inout_updates_opt_(size) +#define _Inout_updates_opt_z_(size) +#define _Inout_updates_to_(size,count) +#define _Inout_updates_to_opt_(size,count) +#define _Inout_updates_z_(size) +#define _Inout_z_ +#define _Inout_z_bytecap_(size) +#define _Inout_z_bytecap_c_(size) +#define _Inout_z_bytecap_x_(size) +#define _Inout_z_bytecount_(size) +#define _Inout_z_bytecount_c_(size) +#define _Inout_z_cap_(size) +#define _Inout_z_cap_c_(size) +#define _Inout_z_cap_x_(size) +#define _Inout_z_count_(size) +#define _Inout_z_count_c_(size) +#define _Interlocked_operand_ +#define _Literal_ +#define _Maybenull_ +#define _Maybevalid_ +#define _Maybe_raises_SEH_exception +#define _Must_inspect_result_ +#define _Notliteral_ +#define _Notnull_ +#define _Notref_ +#define _Notvalid_ +#define _Null_ +#define _Null_terminated_ +#define _NullNull_terminated_ +#define _On_failure_(annos) +#define _Out_ +#define _Out_bound_ +#define _Out_bytecap_(size) +#define _Out_bytecap_c_(size) +#define _Out_bytecap_post_bytecount_(cap,count) +#define _Out_bytecap_x_(size) +#define _Out_bytecapcount_(capcount) +#define _Out_bytecapcount_x_(capcount) +#define _Out_cap_(size) +#define _Out_cap_c_(size) +#define _Out_cap_m_(mult,size) +#define _Out_cap_post_count_(cap,count) +#define _Out_cap_x_(size) +#define _Out_capcount_(capcount) +#define _Out_capcount_x_(capcount) +#define _Out_defensive_(annotes) +#define _Out_opt_ +#define _Out_opt_bytecap_(size) +#define _Out_opt_bytecap_c_(size) +#define _Out_opt_bytecap_post_bytecount_(cap,count) +#define _Out_opt_bytecap_x_(size) +#define _Out_opt_bytecapcount_(capcount) +#define _Out_opt_bytecapcount_x_(capcount) +#define _Out_opt_cap_(size) +#define _Out_opt_cap_c_(size) +#define _Out_opt_cap_m_(mult,size) +#define _Out_opt_cap_post_count_(cap,count) +#define _Out_opt_cap_x_(size) +#define _Out_opt_capcount_(capcount) +#define _Out_opt_capcount_x_(capcount) +#define _Out_opt_ptrdiff_cap_(size) +#define _Out_opt_z_bytecap_(size) +#define _Out_opt_z_bytecap_c_(size) +#define _Out_opt_z_bytecap_post_bytecount_(cap,count) +#define _Out_opt_z_bytecap_x_(size) +#define _Out_opt_z_bytecapcount_(capcount) +#define _Out_opt_z_cap_(size) +#define _Out_opt_z_cap_c_(size) +#define _Out_opt_z_cap_m_(mult,size) +#define _Out_opt_z_cap_post_count_(cap,count) +#define _Out_opt_z_cap_x_(size) +#define _Out_opt_z_capcount_(capcount) +#define _Out_ptrdiff_cap_(size) +#define _Out_range_(lb,ub) +#define _Out_writes_(size) +#define _Out_writes_all_(size) +#define _Out_writes_all_opt_(size) +#define _Out_writes_bytes_(size) +#define _Out_writes_bytes_all_(size) +#define _Out_writes_bytes_all_opt_(size) +#define _Out_writes_bytes_opt_(size) +#define _Out_writes_bytes_to_(size,count) +#define _Out_writes_bytes_to_opt_(size,count) +#define _Out_writes_opt_(size) +#define _Out_writes_opt_z_(size) +#define _Out_writes_to_(size,count) +#define _Out_writes_to_opt_(size,count) +#define _Out_writes_to_ptr_(ptr) +#define _Out_writes_to_ptr_opt_(ptr) +#define _Out_writes_to_ptr_opt_z_(ptr) +#define _Out_writes_to_ptr_z_(ptr) +#define _Out_writes_z_(size) +#define _Out_z_bytecap_(size) +#define _Out_z_bytecap_c_(size) +#define _Out_z_bytecap_post_bytecount_(cap,count) +#define _Out_z_bytecap_x_(size) +#define _Out_z_bytecapcount_(capcount) +#define _Out_z_cap_(size) +#define _Out_z_cap_c_(size) +#define _Out_z_cap_m_(mult,size) +#define _Out_z_cap_post_count_(cap,count) +#define _Out_z_cap_x_(size) +#define _Out_z_capcount_(capcount) +#define _Outptr_ +#define _Outptr_opt_ +#define _Outptr_opt_result_buffer_(size) +#define _Outptr_opt_result_buffer_all_(size) +#define _Outptr_opt_result_buffer_all_maybenull_(size) +#define _Outptr_opt_result_buffer_maybenull_(size) +#define _Outptr_opt_result_buffer_to_(size, count) +#define _Outptr_opt_result_buffer_to_maybenull_(size, count) +#define _Outptr_opt_result_bytebuffer_(size) +#define _Outptr_opt_result_bytebuffer_all_(size) +#define _Outptr_opt_result_bytebuffer_all_maybenull_(size) +#define _Outptr_opt_result_bytebuffer_maybenull_(size) +#define _Outptr_opt_result_bytebuffer_to_(size, count) +#define _Outptr_opt_result_bytebuffer_to_maybenull_(size, count) +#define _Outptr_opt_result_maybenull_ +#define _Outptr_opt_result_maybenull_z_ +#define _Outptr_opt_result_nullonfailure_ +#define _Outptr_opt_result_z_ +#define _Outptr_result_buffer_(size) +#define _Outptr_result_buffer_all_(size) +#define _Outptr_result_buffer_all_maybenull_(size) +#define _Outptr_result_buffer_maybenull_(size) +#define _Outptr_result_buffer_to_(size, count) +#define _Outptr_result_buffer_to_maybenull_(size, count) +#define _Outptr_result_bytebuffer_(size) +#define _Outptr_result_bytebuffer_all_(size) +#define _Outptr_result_bytebuffer_all_maybenull_(size) +#define _Outptr_result_bytebuffer_maybenull_(size) +#define _Outptr_result_bytebuffer_to_(size, count) +#define _Outptr_result_bytebuffer_to_maybenull_(size, count) +#define _Outptr_result_maybenull_ +#define _Outptr_result_maybenull_z_ +#define _Outptr_result_nullonfailure_ +#define _Outptr_result_z_ +#define _Outref_ +#define _Outref_result_buffer_(size) +#define _Outref_result_buffer_all_(size) +#define _Outref_result_buffer_all_maybenull_(size) +#define _Outref_result_buffer_maybenull_(size) +#define _Outref_result_buffer_to_(size, count) +#define _Outref_result_buffer_to_maybenull_(size, count) +#define _Outref_result_bytebuffer_(size) +#define _Outref_result_bytebuffer_all_(size) +#define _Outref_result_bytebuffer_all_maybenull_(size) +#define _Outref_result_bytebuffer_maybenull_(size) +#define _Outref_result_bytebuffer_to_(size, count) +#define _Outref_result_bytebuffer_to_maybenull_(size, count) +#define _Outref_result_maybenull_ +#define _Outref_result_nullonfailure_ +#define _Points_to_data_ +#define _Post_ +#define _Post_bytecap_(size) +#define _Post_bytecount_(size) +#define _Post_bytecount_c_(size) +#define _Post_bytecount_x_(size) +#define _Post_cap_(size) +#define _Post_count_(size) +#define _Post_count_c_(size) +#define _Post_count_x_(size) +#define _Post_defensive_ +#define _Post_equal_to_(expr) +#define _Post_invalid_ +#define _Post_maybenull_ +#define _Post_maybez_ +#define _Post_notnull_ +#define _Post_null_ +#define _Post_ptr_invalid_ +#define _Post_readable_byte_size_(size) +#define _Post_readable_size_(size) +#define _Post_satisfies_(cond) +#define _Post_valid_ +#define _Post_writable_byte_size_(size) +#define _Post_writable_size_(size) +#define _Post_z_ +#define _Post_z_bytecount_(size) +#define _Post_z_bytecount_c_(size) +#define _Post_z_bytecount_x_(size) +#define _Post_z_count_(size) +#define _Post_z_count_c_(size) +#define _Post_z_count_x_(size) +#define _Pre_ +#define _Pre_bytecap_(size) +#define _Pre_bytecap_c_(size) +#define _Pre_bytecap_x_(size) +#define _Pre_bytecount_(size) +#define _Pre_bytecount_c_(size) +#define _Pre_bytecount_x_(size) +#define _Pre_cap_(size) +#define _Pre_cap_c_(size) +#define _Pre_cap_c_one_ +#define _Pre_cap_for_(param) +#define _Pre_cap_m_(mult,size) +#define _Pre_cap_x_(size) +#define _Pre_count_(size) +#define _Pre_count_c_(size) +#define _Pre_count_x_(size) +#define _Pre_defensive_ +#define _Pre_equal_to_(expr) +#define _Pre_invalid_ +#define _Pre_maybenull_ +#define _Pre_notnull_ +#define _Pre_null_ +#define _Pre_opt_bytecap_(size) +#define _Pre_opt_bytecap_c_(size) +#define _Pre_opt_bytecap_x_(size) +#define _Pre_opt_bytecount_(size) +#define _Pre_opt_bytecount_c_(size) +#define _Pre_opt_bytecount_x_(size) +#define _Pre_opt_cap_(size) +#define _Pre_opt_cap_c_(size) +#define _Pre_opt_cap_c_one_ +#define _Pre_opt_cap_for_(param) +#define _Pre_opt_cap_m_(mult,size) +#define _Pre_opt_cap_x_(size) +#define _Pre_opt_count_(size) +#define _Pre_opt_count_c_(size) +#define _Pre_opt_count_x_(size) +#define _Pre_opt_ptrdiff_cap_(ptr) +#define _Pre_opt_ptrdiff_count_(ptr) +#define _Pre_opt_valid_ +#define _Pre_opt_valid_bytecap_(size) +#define _Pre_opt_valid_bytecap_c_(size) +#define _Pre_opt_valid_bytecap_x_(size) +#define _Pre_opt_valid_cap_(size) +#define _Pre_opt_valid_cap_c_(size) +#define _Pre_opt_valid_cap_x_(size) +#define _Pre_opt_z_ +#define _Pre_opt_z_bytecap_(size) +#define _Pre_opt_z_bytecap_c_(size) +#define _Pre_opt_z_bytecap_x_(size) +#define _Pre_opt_z_cap_(size) +#define _Pre_opt_z_cap_c_(size) +#define _Pre_opt_z_cap_x_(size) +#define _Pre_ptrdiff_cap_(ptr) +#define _Pre_ptrdiff_count_(ptr) +#define _Pre_readable_byte_size_(size) +#define _Pre_readable_size_(size) +#define _Pre_readonly_ +#define _Pre_satisfies_(cond) +#define _Pre_unknown_ +#define _Pre_valid_ +#define _Pre_valid_bytecap_(size) +#define _Pre_valid_bytecap_c_(size) +#define _Pre_valid_bytecap_x_(size) +#define _Pre_valid_cap_(size) +#define _Pre_valid_cap_c_(size) +#define _Pre_valid_cap_x_(size) +#define _Pre_writable_byte_size_(size) +#define _Pre_writable_size_(size) +#define _Pre_writeonly_ +#define _Pre_z_ +#define _Pre_z_bytecap_(size) +#define _Pre_z_bytecap_c_(size) +#define _Pre_z_bytecap_x_(size) +#define _Pre_z_cap_(size) +#define _Pre_z_cap_c_(size) +#define _Pre_z_cap_x_(size) +#define _Prepost_bytecount_(size) +#define _Prepost_bytecount_c_(size) +#define _Prepost_bytecount_x_(size) +#define _Prepost_count_(size) +#define _Prepost_count_c_(size) +#define _Prepost_count_x_(size) +#define _Prepost_opt_bytecount_(size) +#define _Prepost_opt_bytecount_c_(size) +#define _Prepost_opt_bytecount_x_(size) +#define _Prepost_opt_count_(size) +#define _Prepost_opt_count_c_(size) +#define _Prepost_opt_count_x_(size) +#define _Prepost_opt_valid_ +#define _Prepost_opt_z_ +#define _Prepost_valid_ +#define _Prepost_z_ +#define _Printf_format_string_ +#define _Raises_SEH_exception_ +#define _Maybe_raises_SEH_exception_ +#define _Readable_bytes_(size) +#define _Readable_elements_(size) +#define _Reserved_ +#define _Result_nullonfailure_ +#define _Result_zeroonfailure_ +#define __inner_callback +#define _Ret_ +#define _Ret_bound_ +#define _Ret_bytecap_(size) +#define _Ret_bytecap_c_(size) +#define _Ret_bytecap_x_(size) +#define _Ret_bytecount_(size) +#define _Ret_bytecount_c_(size) +#define _Ret_bytecount_x_(size) +#define _Ret_cap_(size) +#define _Ret_cap_c_(size) +#define _Ret_cap_x_(size) +#define _Ret_count_(size) +#define _Ret_count_c_(size) +#define _Ret_count_x_(size) +#define _Ret_maybenull_ +#define _Ret_maybenull_z_ +#define _Ret_notnull_ +#define _Ret_null_ +#define _Ret_opt_ +#define _Ret_opt_bytecap_(size) +#define _Ret_opt_bytecap_c_(size) +#define _Ret_opt_bytecap_x_(size) +#define _Ret_opt_bytecount_(size) +#define _Ret_opt_bytecount_c_(size) +#define _Ret_opt_bytecount_x_(size) +#define _Ret_opt_cap_(size) +#define _Ret_opt_cap_c_(size) +#define _Ret_opt_cap_x_(size) +#define _Ret_opt_count_(size) +#define _Ret_opt_count_c_(size) +#define _Ret_opt_count_x_(size) +#define _Ret_opt_valid_ +#define _Ret_opt_z_ +#define _Ret_opt_z_bytecap_(size) +#define _Ret_opt_z_bytecount_(size) +#define _Ret_opt_z_cap_(size) +#define _Ret_opt_z_count_(size) +#define _Ret_range_(lb,ub) +#define _Ret_valid_ +#define _Ret_writes_(size) +#define _Ret_writes_bytes_(size) +#define _Ret_writes_bytes_maybenull_(size) +#define _Ret_writes_bytes_to_(size,count) +#define _Ret_writes_bytes_to_maybenull_(size,count) +#define _Ret_writes_maybenull_(size) +#define _Ret_writes_maybenull_z_(size) +#define _Ret_writes_to_(size,count) +#define _Ret_writes_to_maybenull_(size,count) +#define _Ret_writes_z_(size) +#define _Ret_z_ +#define _Ret_z_bytecap_(size) +#define _Ret_z_bytecount_(size) +#define _Ret_z_cap_(size) +#define _Ret_z_count_(size) +#define _Return_type_success_(expr) +#define _Scanf_format_string_ +#define _Scanf_s_format_string_ +#define _Struct_size_bytes_(size) +#define _Success_(expr) +#define _Unchanged_(e) +#define _Use_decl_annotations_ +#define _Valid_ +#define _When_(expr, annos) +#define _Writable_bytes_(size) +#define _Writable_elements_(size) + + +#define __bcount(size) +#define __bcount_opt(size) +#define __deref_bcount(size) +#define __deref_bcount_opt(size) +#define __deref_ecount(size) +#define __deref_ecount_opt(size) +#define __deref_in +#define __deref_in_bcount(size) +#define __deref_in_bcount_opt(size) +#define __deref_in_ecount(size) +#define __deref_in_ecount_opt(size) +#define __deref_in_opt +#define __deref_inout +#define __deref_inout_bcount(size) +#define __deref_inout_bcount_full(size) +#define __deref_inout_bcount_full_opt(size) +#define __deref_inout_bcount_opt(size) +#define __deref_inout_bcount_part(size,length) +#define __deref_inout_bcount_part_opt(size,length) +#define __deref_inout_ecount(size) +#define __deref_inout_ecount_full(size) +#define __deref_inout_ecount_full_opt(size) +#define __deref_inout_ecount_opt(size) +#define __deref_inout_ecount_part(size,length) +#define __deref_inout_ecount_part_opt(size,length) +#define __deref_inout_opt +#define __deref_opt_bcount(size) +#define __deref_opt_bcount_opt(size) +#define __deref_opt_ecount(size) +#define __deref_opt_ecount_opt(size) +#define __deref_opt_in +#define __deref_opt_in_bcount(size) +#define __deref_opt_in_bcount_opt(size) +#define __deref_opt_in_ecount(size) +#define __deref_opt_in_ecount_opt(size) +#define __deref_opt_in_opt +#define __deref_opt_inout +#define __deref_opt_inout_bcount(size) +#define __deref_opt_inout_bcount_full(size) +#define __deref_opt_inout_bcount_full_opt(size) +#define __deref_opt_inout_bcount_opt(size) +#define __deref_opt_inout_bcount_part(size,length) +#define __deref_opt_inout_bcount_part_opt(size,length) +#define __deref_opt_inout_ecount(size) +#define __deref_opt_inout_ecount_full(size) +#define __deref_opt_inout_ecount_full_opt(size) +#define __deref_opt_inout_ecount_opt(size) +#define __deref_opt_inout_ecount_part(size,length) +#define __deref_opt_inout_ecount_part_opt(size,length) +#define __deref_opt_inout_opt +#define __deref_opt_out +#define __deref_opt_out_bcount(size) +#define __deref_opt_out_bcount_full(size) +#define __deref_opt_out_bcount_full_opt(size) +#define __deref_opt_out_bcount_opt(size) +#define __deref_opt_out_bcount_part(size,length) +#define __deref_opt_out_bcount_part_opt(size,length) +#define __deref_opt_out_ecount(size) +#define __deref_opt_out_ecount_full(size) +#define __deref_opt_out_ecount_full_opt(size) +#define __deref_opt_out_ecount_opt(size) +#define __deref_opt_out_ecount_part(size,length) +#define __deref_opt_out_ecount_part_opt(size,length) +#define __deref_opt_out_opt +#define __deref_out +#define __deref_out_bcount(size) +#define __deref_out_bcount_full(size) +#define __deref_out_bcount_full_opt(size) +#define __deref_out_bcount_opt(size) +#define __deref_out_bcount_part(size,length) +#define __deref_out_bcount_part_opt(size,length) +#define __deref_out_ecount(size) +#define __deref_out_ecount_full(size) +#define __deref_out_ecount_full_opt(size) +#define __deref_out_ecount_opt(size) +#define __deref_out_ecount_part(size,length) +#define __deref_out_ecount_part_opt(size,length) +#define __deref_out_opt +#define __ecount(size) +#define __ecount_opt(size) +#define __in +#define __in_bcount(size) +#define __in_bcount_opt(size) +#define __in_ecount(size) +#define __in_ecount_opt(size) +#define __in_opt +#define __inout +#define __inout_bcount(size) +#define __inout_bcount_full(size) +#define __inout_bcount_full_opt(size) +#define __inout_bcount_opt(size) +#define __inout_bcount_part(size,length) +#define __inout_bcount_part_opt(size,length) +#define __inout_ecount(size) +#define __inout_ecount_full(size) +#define __inout_ecount_full_opt(size) +#define __inout_ecount_opt(size) +#define __inout_ecount_part(size,length) +#define __inout_ecount_part_opt(size,length) +#define __inout_opt +#define __out +#define __out_bcount(size) +#define __out_bcount_full(size) +#define __out_bcount_full_opt(size) +#define __out_bcount_opt(size) +#define __out_bcount_part(size,length) +#define __out_bcount_part_opt(size,length) +#define __out_ecount(size) +#define __out_ecount_full(size) +#define __out_ecount_full_opt(size) +#define __out_ecount_opt(size) +#define __out_ecount_part(size,length) +#define __out_ecount_part_opt(size,length) +#define __out_opt + +#define __blocksOn(resource) +#define __callback +#define __checkReturn +#define __format_string +#define __in_awcount(expr,size) +#define __nullnullterminated +#define __nullterminated +#define __out_awcount(expr,size) +#define __override +#define __reserved +#define __success(expr) +#define __typefix(ctype) + +#ifndef _countof +#ifndef __cplusplus +#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0])) +#else +extern "C++" { +template +char (*__countof_helper(_CountofType (&_Array)[_SizeOfArray]))[_SizeOfArray]; +#define _countof(_Array) sizeof(*__countof_helper(_Array)) +} +#endif +#endif + +/** + * RTL Definitions + */ + +#define MINCHAR 0x80 +#define MAXCHAR 0x7F +#define MINSHORT 0x8000 +#define MAXSHORT 0x7FFF +#define MINLONG 0x80000000 +#define MAXLONG 0x7FFFFFFF +#define MAXBYTE 0xFF +#define MAXWORD 0xFFFF +#define MAXDWORD 0xFFFFFFFF + +#define FIELD_OFFSET(type, field) ((LONG)(LONG_PTR)&(((type *)0)->field)) + +#define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field)) + +#define RTL_SIZEOF_THROUGH_FIELD(type, field) \ + (FIELD_OFFSET(type, field) + RTL_FIELD_SIZE(type, field)) + +#define RTL_CONTAINS_FIELD(Struct, Size, Field) \ + ((((PCHAR)(&(Struct)->Field)) + sizeof((Struct)->Field)) <= (((PCHAR)(Struct))+(Size))) + +#define RTL_NUMBER_OF_V1(A) (sizeof(A) / sizeof((A)[0])) +#define RTL_NUMBER_OF_V2(A) RTL_NUMBER_OF_V1(A) + +#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A) + +#define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A) +#define _ARRAYSIZE(A) RTL_NUMBER_OF_V1(A) + +#define RTL_FIELD_TYPE(type, field) (((type*)0)->field) + +#define RTL_NUMBER_OF_FIELD(type, field) (RTL_NUMBER_OF(RTL_FIELD_TYPE(type, field))) + +#define RTL_PADDING_BETWEEN_FIELDS(T, F1, F2) \ + ((FIELD_OFFSET(T, F2) > FIELD_OFFSET(T, F1)) \ + ? (FIELD_OFFSET(T, F2) - FIELD_OFFSET(T, F1) - RTL_FIELD_SIZE(T, F1)) \ + : (FIELD_OFFSET(T, F1) - FIELD_OFFSET(T, F2) - RTL_FIELD_SIZE(T, F2))) + +#if defined(__cplusplus) +#define RTL_CONST_CAST(type) const_cast +#else +#define RTL_CONST_CAST(type) (type) +#endif + +#define RTL_BITS_OF(sizeOfArg) (sizeof(sizeOfArg) * 8) + +#define RTL_BITS_OF_FIELD(type, field) (RTL_BITS_OF(RTL_FIELD_TYPE(type, field))) + +#define CONTAINING_RECORD(address, type, field) \ + ((type *)((PCHAR)(address) - (ULONG_PTR)(&((type *)0)->field))) + #endif #endif /* WINPR_SPEC_H */ diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index f3f1ce64d..1e2a3f802 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -26,12 +26,20 @@ #include #include +#include + +#ifdef _WIN32 +#include +#endif + #if defined(__OBJC__) && defined(__APPLE__) #include #endif #ifndef _WIN32 +#define WINAPI + #define __int8 char #define __int16 short #define __int32 int @@ -305,4 +313,33 @@ typedef LONG NTSTATUS; typedef NTSTATUS *PNTSTATUS; #endif +#ifndef _WIN32 + +typedef struct tagDEC +{ + USHORT wReserved; + union { + struct { + BYTE scale; + BYTE sign; + } DUMMYSTRUCTNAME; + USHORT signscale; + } DUMMYUNIONNAME; + ULONG Hi32; + union { + struct { + ULONG Lo32; + ULONG Mid32; + } DUMMYSTRUCTNAME2; + ULONGLONG Lo64; + } DUMMYUNIONNAME2; +} DECIMAL; + +typedef DECIMAL *LPDECIMAL; + +#define DECIMAL_NEG ((BYTE) 0x80) +#define DECIMAL_SETZERO(dec) { (dec).Lo64 = 0; (dec).Hi32 = 0; (dec).signscale = 0; } + +#endif + #endif /* WINPR_WTYPES_H */ From 019877da9763c03244e27ae33c3864e9ab78da4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 26 Feb 2014 13:35:49 -0500 Subject: [PATCH 17/18] winpr: fix compilation on Windows --- winpr/libwinpr/rpc/midl.c | 4 ++++ winpr/libwinpr/utils/wlog/FileAppender.c | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/rpc/midl.c b/winpr/libwinpr/rpc/midl.c index aab05d549..51116a68b 100644 --- a/winpr/libwinpr/rpc/midl.c +++ b/winpr/libwinpr/rpc/midl.c @@ -26,6 +26,8 @@ #include +#ifndef _WIN32 + void* MIDL_user_allocate(size_t cBytes) { return (malloc(cBytes)); @@ -35,3 +37,5 @@ void MIDL_user_free(void* p) { free(p); } + +#endif diff --git a/winpr/libwinpr/utils/wlog/FileAppender.c b/winpr/libwinpr/utils/wlog/FileAppender.c index 8904310cb..c14552857 100644 --- a/winpr/libwinpr/utils/wlog/FileAppender.c +++ b/winpr/libwinpr/utils/wlog/FileAppender.c @@ -127,8 +127,10 @@ int WLog_FileAppender_WriteMessage(wLog* log, wLogFileAppender* appender, wLogMe fprintf(fp, "%s%s\n", message->PrefixString, message->TextString); - //fflush(fp); /* slow! */ - +#ifdef _WIN32 + fflush(fp); /* slow! */ +#endif + return 1; } From 25ff5ccd69755aa8f75b716efed5460f6c05ec42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 27 Feb 2014 12:07:46 -0500 Subject: [PATCH 18/18] libwinpr-locale: add stubs and definitions --- winpr/include/winpr/locale.h | 495 ++++++++++++++++++ winpr/include/winpr/wtypes.h | 5 + winpr/libwinpr/locale/CMakeLists.txt | 49 ++ winpr/libwinpr/locale/ModuleOptions.cmake | 8 + winpr/libwinpr/locale/locale.c | 96 ++++ winpr/libwinpr/locale/module.def | 2 + winpr/libwinpr/locale/test/.gitignore | 2 + winpr/libwinpr/locale/test/CMakeLists.txt | 30 ++ .../locale/test/TestLocaleFormatMessage.c | 8 + 9 files changed, 695 insertions(+) create mode 100644 winpr/include/winpr/locale.h create mode 100644 winpr/libwinpr/locale/CMakeLists.txt create mode 100644 winpr/libwinpr/locale/ModuleOptions.cmake create mode 100644 winpr/libwinpr/locale/locale.c create mode 100644 winpr/libwinpr/locale/module.def create mode 100644 winpr/libwinpr/locale/test/.gitignore create mode 100644 winpr/libwinpr/locale/test/CMakeLists.txt create mode 100644 winpr/libwinpr/locale/test/TestLocaleFormatMessage.c diff --git a/winpr/include/winpr/locale.h b/winpr/include/winpr/locale.h new file mode 100644 index 000000000..b63b421bd --- /dev/null +++ b/winpr/include/winpr/locale.h @@ -0,0 +1,495 @@ +/** + * WinPR: Windows Portable Runtime + * Localization Functions + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef WINPR_LOCALE_H +#define WINPR_LOCALE_H + +#include +#include + +#ifndef _WIN32 + +#define LANG_NEUTRAL 0x00 +#define LANG_INVARIANT 0x7f + +#define LANG_AFRIKAANS 0x36 +#define LANG_ALBANIAN 0x1c +#define LANG_ALSATIAN 0x84 +#define LANG_AMHARIC 0x5e +#define LANG_ARABIC 0x01 +#define LANG_ARMENIAN 0x2b +#define LANG_ASSAMESE 0x4d +#define LANG_AZERI 0x2c +#define LANG_AZERBAIJANI 0x2c +#define LANG_BANGLA 0x45 +#define LANG_BASHKIR 0x6d +#define LANG_BASQUE 0x2d +#define LANG_BELARUSIAN 0x23 +#define LANG_BENGALI 0x45 +#define LANG_BRETON 0x7e +#define LANG_BOSNIAN 0x1a +#define LANG_BOSNIAN_NEUTRAL 0x781a +#define LANG_BULGARIAN 0x02 +#define LANG_CATALAN 0x03 +#define LANG_CENTRAL_KURDISH 0x92 +#define LANG_CHEROKEE 0x5c +#define LANG_CHINESE 0x04 +#define LANG_CHINESE_SIMPLIFIED 0x04 +#define LANG_CHINESE_TRADITIONAL 0x7c04 +#define LANG_CORSICAN 0x83 +#define LANG_CROATIAN 0x1a +#define LANG_CZECH 0x05 +#define LANG_DANISH 0x06 +#define LANG_DARI 0x8c +#define LANG_DIVEHI 0x65 +#define LANG_DUTCH 0x13 +#define LANG_ENGLISH 0x09 +#define LANG_ESTONIAN 0x25 +#define LANG_FAEROESE 0x38 +#define LANG_FARSI 0x29 +#define LANG_FILIPINO 0x64 +#define LANG_FINNISH 0x0b +#define LANG_FRENCH 0x0c +#define LANG_FRISIAN 0x62 +#define LANG_FULAH 0x67 +#define LANG_GALICIAN 0x56 +#define LANG_GEORGIAN 0x37 +#define LANG_GERMAN 0x07 +#define LANG_GREEK 0x08 +#define LANG_GREENLANDIC 0x6f +#define LANG_GUJARATI 0x47 +#define LANG_HAUSA 0x68 +#define LANG_HAWAIIAN 0x75 +#define LANG_HEBREW 0x0d +#define LANG_HINDI 0x39 +#define LANG_HUNGARIAN 0x0e +#define LANG_ICELANDIC 0x0f +#define LANG_IGBO 0x70 +#define LANG_INDONESIAN 0x21 +#define LANG_INUKTITUT 0x5d +#define LANG_IRISH 0x3c +#define LANG_ITALIAN 0x10 +#define LANG_JAPANESE 0x11 +#define LANG_KANNADA 0x4b +#define LANG_KASHMIRI 0x60 +#define LANG_KAZAK 0x3f +#define LANG_KHMER 0x53 +#define LANG_KICHE 0x86 +#define LANG_KINYARWANDA 0x87 +#define LANG_KONKANI 0x57 +#define LANG_KOREAN 0x12 +#define LANG_KYRGYZ 0x40 +#define LANG_LAO 0x54 +#define LANG_LATVIAN 0x26 +#define LANG_LITHUANIAN 0x27 +#define LANG_LOWER_SORBIAN 0x2e +#define LANG_LUXEMBOURGISH 0x6e +#define LANG_MACEDONIAN 0x2f +#define LANG_MALAY 0x3e +#define LANG_MALAYALAM 0x4c +#define LANG_MALTESE 0x3a +#define LANG_MANIPURI 0x58 +#define LANG_MAORI 0x81 +#define LANG_MAPUDUNGUN 0x7a +#define LANG_MARATHI 0x4e +#define LANG_MOHAWK 0x7c +#define LANG_MONGOLIAN 0x50 +#define LANG_NEPALI 0x61 +#define LANG_NORWEGIAN 0x14 +#define LANG_OCCITAN 0x82 +#define LANG_ODIA 0x48 +#define LANG_ORIYA 0x48 +#define LANG_PASHTO 0x63 +#define LANG_PERSIAN 0x29 +#define LANG_POLISH 0x15 +#define LANG_PORTUGUESE 0x16 +#define LANG_PULAR 0x67 +#define LANG_PUNJABI 0x46 +#define LANG_QUECHUA 0x6b +#define LANG_ROMANIAN 0x18 +#define LANG_ROMANSH 0x17 +#define LANG_RUSSIAN 0x19 +#define LANG_SAKHA 0x85 +#define LANG_SAMI 0x3b +#define LANG_SANSKRIT 0x4f +#define LANG_SCOTTISH_GAELIC 0x91 +#define LANG_SERBIAN 0x1a +#define LANG_SERBIAN_NEUTRAL 0x7c1a +#define LANG_SINDHI 0x59 +#define LANG_SINHALESE 0x5b +#define LANG_SLOVAK 0x1b +#define LANG_SLOVENIAN 0x24 +#define LANG_SOTHO 0x6c +#define LANG_SPANISH 0x0a +#define LANG_SWAHILI 0x41 +#define LANG_SWEDISH 0x1d +#define LANG_SYRIAC 0x5a +#define LANG_TAJIK 0x28 +#define LANG_TAMAZIGHT 0x5f +#define LANG_TAMIL 0x49 +#define LANG_TATAR 0x44 +#define LANG_TELUGU 0x4a +#define LANG_THAI 0x1e +#define LANG_TIBETAN 0x51 +#define LANG_TIGRIGNA 0x73 +#define LANG_TIGRINYA 0x73 +#define LANG_TSWANA 0x32 +#define LANG_TURKISH 0x1f +#define LANG_TURKMEN 0x42 +#define LANG_UIGHUR 0x80 +#define LANG_UKRAINIAN 0x22 +#define LANG_UPPER_SORBIAN 0x2e +#define LANG_URDU 0x20 +#define LANG_UZBEK 0x43 +#define LANG_VALENCIAN 0x03 +#define LANG_VIETNAMESE 0x2a +#define LANG_WELSH 0x52 +#define LANG_WOLOF 0x88 +#define LANG_XHOSA 0x34 +#define LANG_YAKUT 0x85 +#define LANG_YI 0x78 +#define LANG_YORUBA 0x6a +#define LANG_ZULU 0x35 + +#define SUBLANG_NEUTRAL 0x00 +#define SUBLANG_DEFAULT 0x01 +#define SUBLANG_SYS_DEFAULT 0x02 +#define SUBLANG_CUSTOM_DEFAULT 0x03 +#define SUBLANG_CUSTOM_UNSPECIFIED 0x04 +#define SUBLANG_UI_CUSTOM_DEFAULT 0x05 + +#define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01 +#define SUBLANG_ALBANIAN_ALBANIA 0x01 +#define SUBLANG_ALSATIAN_FRANCE 0x01 +#define SUBLANG_AMHARIC_ETHIOPIA 0x01 +#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01 +#define SUBLANG_ARABIC_IRAQ 0x02 +#define SUBLANG_ARABIC_EGYPT 0x03 +#define SUBLANG_ARABIC_LIBYA 0x04 +#define SUBLANG_ARABIC_ALGERIA 0x05 +#define SUBLANG_ARABIC_MOROCCO 0x06 +#define SUBLANG_ARABIC_TUNISIA 0x07 +#define SUBLANG_ARABIC_OMAN 0x08 +#define SUBLANG_ARABIC_YEMEN 0x09 +#define SUBLANG_ARABIC_SYRIA 0x0a +#define SUBLANG_ARABIC_JORDAN 0x0b +#define SUBLANG_ARABIC_LEBANON 0x0c +#define SUBLANG_ARABIC_KUWAIT 0x0d +#define SUBLANG_ARABIC_UAE 0x0e +#define SUBLANG_ARABIC_BAHRAIN 0x0f +#define SUBLANG_ARABIC_QATAR 0x10 +#define SUBLANG_ARMENIAN_ARMENIA 0x01 +#define SUBLANG_ASSAMESE_INDIA 0x01 +#define SUBLANG_AZERI_LATIN 0x01 +#define SUBLANG_AZERI_CYRILLIC 0x02 +#define SUBLANG_AZERBAIJANI_AZERBAIJAN_LATIN 0x01 +#define SUBLANG_AZERBAIJANI_AZERBAIJAN_CYRILLIC 0x02 +#define SUBLANG_BANGLA_INDIA 0x01 +#define SUBLANG_BANGLA_BANGLADESH 0x02 +#define SUBLANG_BASHKIR_RUSSIA 0x01 +#define SUBLANG_BASQUE_BASQUE 0x01 +#define SUBLANG_BELARUSIAN_BELARUS 0x01 +#define SUBLANG_BENGALI_INDIA 0x01 +#define SUBLANG_BENGALI_BANGLADESH 0x02 +#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05 +#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08 +#define SUBLANG_BRETON_FRANCE 0x01 +#define SUBLANG_BULGARIAN_BULGARIA 0x01 +#define SUBLANG_CATALAN_CATALAN 0x01 +#define SUBLANG_CENTRAL_KURDISH_IRAQ 0x01 +#define SUBLANG_CHEROKEE_CHEROKEE 0x01 +#define SUBLANG_CHINESE_TRADITIONAL 0x01 +#define SUBLANG_CHINESE_SIMPLIFIED 0x02 +#define SUBLANG_CHINESE_HONGKONG 0x03 +#define SUBLANG_CHINESE_SINGAPORE 0x04 +#define SUBLANG_CHINESE_MACAU 0x05 +#define SUBLANG_CORSICAN_FRANCE 0x01 +#define SUBLANG_CZECH_CZECH_REPUBLIC 0x01 +#define SUBLANG_CROATIAN_CROATIA 0x01 +#define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04 +#define SUBLANG_DANISH_DENMARK 0x01 +#define SUBLANG_DARI_AFGHANISTAN 0x01 +#define SUBLANG_DIVEHI_MALDIVES 0x01 +#define SUBLANG_DUTCH 0x01 +#define SUBLANG_DUTCH_BELGIAN 0x02 +#define SUBLANG_ENGLISH_US 0x01 +#define SUBLANG_ENGLISH_UK 0x02 +#define SUBLANG_ENGLISH_AUS 0x03 +#define SUBLANG_ENGLISH_CAN 0x04 +#define SUBLANG_ENGLISH_NZ 0x05 +#define SUBLANG_ENGLISH_EIRE 0x06 +#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07 +#define SUBLANG_ENGLISH_JAMAICA 0x08 +#define SUBLANG_ENGLISH_CARIBBEAN 0x09 +#define SUBLANG_ENGLISH_BELIZE 0x0a +#define SUBLANG_ENGLISH_TRINIDAD 0x0b +#define SUBLANG_ENGLISH_ZIMBABWE 0x0c +#define SUBLANG_ENGLISH_PHILIPPINES 0x0d +#define SUBLANG_ENGLISH_INDIA 0x10 +#define SUBLANG_ENGLISH_MALAYSIA 0x11 +#define SUBLANG_ENGLISH_SINGAPORE 0x12 +#define SUBLANG_ESTONIAN_ESTONIA 0x01 +#define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01 +#define SUBLANG_FILIPINO_PHILIPPINES 0x01 +#define SUBLANG_FINNISH_FINLAND 0x01 +#define SUBLANG_FRENCH 0x01 +#define SUBLANG_FRENCH_BELGIAN 0x02 +#define SUBLANG_FRENCH_CANADIAN 0x03 +#define SUBLANG_FRENCH_SWISS 0x04 +#define SUBLANG_FRENCH_LUXEMBOURG 0x05 +#define SUBLANG_FRENCH_MONACO 0x06 +#define SUBLANG_FRISIAN_NETHERLANDS 0x01 +#define SUBLANG_FULAH_SENEGAL 0x02 +#define SUBLANG_GALICIAN_GALICIAN 0x01 +#define SUBLANG_GEORGIAN_GEORGIA 0x01 +#define SUBLANG_GERMAN 0x01 +#define SUBLANG_GERMAN_SWISS 0x02 +#define SUBLANG_GERMAN_AUSTRIAN 0x03 +#define SUBLANG_GERMAN_LUXEMBOURG 0x04 +#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05 +#define SUBLANG_GREEK_GREECE 0x01 +#define SUBLANG_GREENLANDIC_GREENLAND 0x01 +#define SUBLANG_GUJARATI_INDIA 0x01 +#define SUBLANG_HAUSA_NIGERIA_LATIN 0x01 +#define SUBLANG_HAWAIIAN_US 0x01 +#define SUBLANG_HEBREW_ISRAEL 0x01 +#define SUBLANG_HINDI_INDIA 0x01 +#define SUBLANG_HUNGARIAN_HUNGARY 0x01 +#define SUBLANG_ICELANDIC_ICELAND 0x01 +#define SUBLANG_IGBO_NIGERIA 0x01 +#define SUBLANG_INDONESIAN_INDONESIA 0x01 +#define SUBLANG_INUKTITUT_CANADA 0x01 +#define SUBLANG_INUKTITUT_CANADA_LATIN 0x02 +#define SUBLANG_IRISH_IRELAND 0x02 +#define SUBLANG_ITALIAN 0x01 +#define SUBLANG_ITALIAN_SWISS 0x02 +#define SUBLANG_JAPANESE_JAPAN 0x01 +#define SUBLANG_KANNADA_INDIA 0x01 +#define SUBLANG_KASHMIRI_SASIA 0x02 +#define SUBLANG_KASHMIRI_INDIA 0x02 +#define SUBLANG_KAZAK_KAZAKHSTAN 0x01 +#define SUBLANG_KHMER_CAMBODIA 0x01 +#define SUBLANG_KICHE_GUATEMALA 0x01 +#define SUBLANG_KINYARWANDA_RWANDA 0x01 +#define SUBLANG_KONKANI_INDIA 0x01 +#define SUBLANG_KOREAN 0x01 +#define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01 +#define SUBLANG_LAO_LAO 0x01 +#define SUBLANG_LATVIAN_LATVIA 0x01 +#define SUBLANG_LITHUANIAN 0x01 +#define SUBLANG_LOWER_SORBIAN_GERMANY 0x02 +#define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01 +#define SUBLANG_MACEDONIAN_MACEDONIA 0x01 +#define SUBLANG_MALAY_MALAYSIA 0x01 +#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02 +#define SUBLANG_MALAYALAM_INDIA 0x01 +#define SUBLANG_MALTESE_MALTA 0x01 +#define SUBLANG_MAORI_NEW_ZEALAND 0x01 +#define SUBLANG_MAPUDUNGUN_CHILE 0x01 +#define SUBLANG_MARATHI_INDIA 0x01 +#define SUBLANG_MOHAWK_MOHAWK 0x01 +#define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01 +#define SUBLANG_MONGOLIAN_PRC 0x02 +#define SUBLANG_NEPALI_INDIA 0x02 +#define SUBLANG_NEPALI_NEPAL 0x01 +#define SUBLANG_NORWEGIAN_BOKMAL 0x01 +#define SUBLANG_NORWEGIAN_NYNORSK 0x02 +#define SUBLANG_OCCITAN_FRANCE 0x01 +#define SUBLANG_ODIA_INDIA 0x01 +#define SUBLANG_ORIYA_INDIA 0x01 +#define SUBLANG_PASHTO_AFGHANISTAN 0x01 +#define SUBLANG_PERSIAN_IRAN 0x01 +#define SUBLANG_POLISH_POLAND 0x01 +#define SUBLANG_PORTUGUESE 0x02 +#define SUBLANG_PORTUGUESE_BRAZILIAN 0x01 +#define SUBLANG_PULAR_SENEGAL 0x02 +#define SUBLANG_PUNJABI_INDIA 0x01 +#define SUBLANG_PUNJABI_PAKISTAN 0x02 +#define SUBLANG_QUECHUA_BOLIVIA 0x01 +#define SUBLANG_QUECHUA_ECUADOR 0x02 +#define SUBLANG_QUECHUA_PERU 0x03 +#define SUBLANG_ROMANIAN_ROMANIA 0x01 +#define SUBLANG_ROMANSH_SWITZERLAND 0x01 +#define SUBLANG_RUSSIAN_RUSSIA 0x01 +#define SUBLANG_SAKHA_RUSSIA 0x01 +#define SUBLANG_SAMI_NORTHERN_NORWAY 0x01 +#define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02 +#define SUBLANG_SAMI_NORTHERN_FINLAND 0x03 +#define SUBLANG_SAMI_LULE_NORWAY 0x04 +#define SUBLANG_SAMI_LULE_SWEDEN 0x05 +#define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06 +#define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07 +#define SUBLANG_SAMI_SKOLT_FINLAND 0x08 +#define SUBLANG_SAMI_INARI_FINLAND 0x09 +#define SUBLANG_SANSKRIT_INDIA 0x01 +#define SUBLANG_SCOTTISH_GAELIC 0x01 +#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN 0x06 +#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x07 +#define SUBLANG_SERBIAN_MONTENEGRO_LATIN 0x0b +#define SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC 0x0c +#define SUBLANG_SERBIAN_SERBIA_LATIN 0x09 +#define SUBLANG_SERBIAN_SERBIA_CYRILLIC 0x0a +#define SUBLANG_SERBIAN_CROATIA 0x01 +#define SUBLANG_SERBIAN_LATIN 0x02 +#define SUBLANG_SERBIAN_CYRILLIC 0x03 +#define SUBLANG_SINDHI_INDIA 0x01 +#define SUBLANG_SINDHI_PAKISTAN 0x02 +#define SUBLANG_SINDHI_AFGHANISTAN 0x02 +#define SUBLANG_SINHALESE_SRI_LANKA 0x01 +#define SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA 0x01 +#define SUBLANG_SLOVAK_SLOVAKIA 0x01 +#define SUBLANG_SLOVENIAN_SLOVENIA 0x01 +#define SUBLANG_SPANISH 0x01 +#define SUBLANG_SPANISH_MEXICAN 0x02 +#define SUBLANG_SPANISH_MODERN 0x03 +#define SUBLANG_SPANISH_GUATEMALA 0x04 +#define SUBLANG_SPANISH_COSTA_RICA 0x05 +#define SUBLANG_SPANISH_PANAMA 0x06 +#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07 +#define SUBLANG_SPANISH_VENEZUELA 0x08 +#define SUBLANG_SPANISH_COLOMBIA 0x09 +#define SUBLANG_SPANISH_PERU 0x0a +#define SUBLANG_SPANISH_ARGENTINA 0x0b +#define SUBLANG_SPANISH_ECUADOR 0x0c +#define SUBLANG_SPANISH_CHILE 0x0d +#define SUBLANG_SPANISH_URUGUAY 0x0e +#define SUBLANG_SPANISH_PARAGUAY 0x0f +#define SUBLANG_SPANISH_BOLIVIA 0x10 +#define SUBLANG_SPANISH_EL_SALVADOR 0x11 +#define SUBLANG_SPANISH_HONDURAS 0x12 +#define SUBLANG_SPANISH_NICARAGUA 0x13 +#define SUBLANG_SPANISH_PUERTO_RICO 0x14 +#define SUBLANG_SPANISH_US 0x15 +#define SUBLANG_SWAHILI_KENYA 0x01 +#define SUBLANG_SWEDISH 0x01 +#define SUBLANG_SWEDISH_FINLAND 0x02 +#define SUBLANG_SYRIAC_SYRIA 0x01 +#define SUBLANG_TAJIK_TAJIKISTAN 0x01 +#define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02 +#define SUBLANG_TAMAZIGHT_MOROCCO_TIFINAGH 0x04 +#define SUBLANG_TAMIL_INDIA 0x01 +#define SUBLANG_TAMIL_SRI_LANKA 0x02 +#define SUBLANG_TATAR_RUSSIA 0x01 +#define SUBLANG_TELUGU_INDIA 0x01 +#define SUBLANG_THAI_THAILAND 0x01 +#define SUBLANG_TIBETAN_PRC 0x01 +#define SUBLANG_TIGRIGNA_ERITREA 0x02 +#define SUBLANG_TIGRINYA_ERITREA 0x02 +#define SUBLANG_TIGRINYA_ETHIOPIA 0x01 +#define SUBLANG_TSWANA_BOTSWANA 0x02 +#define SUBLANG_TSWANA_SOUTH_AFRICA 0x01 +#define SUBLANG_TURKISH_TURKEY 0x01 +#define SUBLANG_TURKMEN_TURKMENISTAN 0x01 +#define SUBLANG_UIGHUR_PRC 0x01 +#define SUBLANG_UKRAINIAN_UKRAINE 0x01 +#define SUBLANG_UPPER_SORBIAN_GERMANY 0x01 +#define SUBLANG_URDU_PAKISTAN 0x01 +#define SUBLANG_URDU_INDIA 0x02 +#define SUBLANG_UZBEK_LATIN 0x01 +#define SUBLANG_UZBEK_CYRILLIC 0x02 +#define SUBLANG_VALENCIAN_VALENCIA 0x02 +#define SUBLANG_VIETNAMESE_VIETNAM 0x01 +#define SUBLANG_WELSH_UNITED_KINGDOM 0x01 +#define SUBLANG_WOLOF_SENEGAL 0x01 +#define SUBLANG_XHOSA_SOUTH_AFRICA 0x01 +#define SUBLANG_YAKUT_RUSSIA 0x01 +#define SUBLANG_YI_PRC 0x01 +#define SUBLANG_YORUBA_NIGERIA 0x01 +#define SUBLANG_ZULU_SOUTH_AFRICA 0x01 + +#define SORT_DEFAULT 0x0 + +#define SORT_INVARIANT_MATH 0x1 + +#define SORT_JAPANESE_XJIS 0x0 +#define SORT_JAPANESE_UNICODE 0x1 +#define SORT_JAPANESE_RADICALSTROKE 0x4 + +#define SORT_CHINESE_BIG5 0x0 +#define SORT_CHINESE_PRCP 0x0 +#define SORT_CHINESE_UNICODE 0x1 +#define SORT_CHINESE_PRC 0x2 +#define SORT_CHINESE_BOPOMOFO 0x3 +#define SORT_CHINESE_RADICALSTROKE 0x4 + +#define SORT_KOREAN_KSC 0x0 +#define SORT_KOREAN_UNICODE 0x1 + +#define SORT_GERMAN_PHONE_BOOK 0x1 + +#define SORT_HUNGARIAN_DEFAULT 0x0 +#define SORT_HUNGARIAN_TECHNICAL 0x1 + +#define SORT_GEORGIAN_TRADITIONAL 0x0 +#define SORT_GEORGIAN_MODERN 0x1 + +#define MAKELANGID(p, s) ((((WORD)(s)) << 10) | (WORD)(p)) +#define PRIMARYLANGID(lgid) ((WORD)(lgid) & 0x3FF) +#define SUBLANGID(lgid) ((WORD)(lgid) >> 10) + +#define NLS_VALID_LOCALE_MASK 0x000FFFFF + +#define MAKELCID(lgid, srtid) ((DWORD)((((DWORD)((WORD)(srtid))) << 16) | ((DWORD)((WORD)(lgid))))) + +#define MAKESORTLCID(lgid, srtid, ver) \ + ((DWORD)((MAKELCID(lgid, srtid)) | (((DWORD)((WORD)(ver))) << 20))) + +#define LANGIDFROMLCID(lcid) ((WORD)(lcid)) +#define SORTIDFROMLCID(lcid) ((WORD)((((DWORD)(lcid)) >> 16) & 0xF)) + +#define SORTVERSIONFROMLCID(lcid) ((WORD)((((DWORD)(lcid)) >> 20) & 0xF)) + +#define LOCALE_NAME_MAX_LENGTH 85 + + +#define LANG_SYSTEM_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT)) +#define LANG_USER_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)) + +#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT)) +#define LOCALE_USER_DEFAULT (MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT)) + +#define LOCALE_CUSTOM_DEFAULT \ + (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_DEFAULT), SORT_DEFAULT)) + +#define LOCALE_CUSTOM_UNSPECIFIED \ + (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_CUSTOM_UNSPECIFIED), SORT_DEFAULT)) + +#define LOCALE_CUSTOM_UI_DEFAULT \ + (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_UI_CUSTOM_DEFAULT), SORT_DEFAULT)) + +#define LOCALE_NEUTRAL \ + (MAKELCID(MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), SORT_DEFAULT)) + +#define LOCALE_INVARIANT \ + (MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)) + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif + +#endif /* WINPR_LOCALE_H */ + diff --git a/winpr/include/winpr/wtypes.h b/winpr/include/winpr/wtypes.h index 1e2a3f802..be617ec72 100644 --- a/winpr/include/winpr/wtypes.h +++ b/winpr/include/winpr/wtypes.h @@ -340,6 +340,11 @@ typedef DECIMAL *LPDECIMAL; #define DECIMAL_NEG ((BYTE) 0x80) #define DECIMAL_SETZERO(dec) { (dec).Lo64 = 0; (dec).Hi32 = 0; (dec).signscale = 0; } +typedef char CCHAR; +typedef DWORD LCID; +typedef PDWORD PLCID; +typedef WORD LANGID; + #endif #endif /* WINPR_WTYPES_H */ diff --git a/winpr/libwinpr/locale/CMakeLists.txt b/winpr/libwinpr/locale/CMakeLists.txt new file mode 100644 index 000000000..913ace67d --- /dev/null +++ b/winpr/libwinpr/locale/CMakeLists.txt @@ -0,0 +1,49 @@ +# WinPR: Windows Portable Runtime +# libwinpr-dsparse cmake build script +# +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set(MODULE_NAME "winpr-locale") +set(MODULE_PREFIX "WINPR_LOCALE") + +set(${MODULE_PREFIX}_SRCS + locale.c) + +if(MSVC AND (NOT MONOLITHIC_BUILD)) + set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def) +endif() + +add_complex_library(MODULE ${MODULE_NAME} TYPE "OBJECT" + MONOLITHIC ${MONOLITHIC_BUILD} + SOURCES ${${MODULE_PREFIX}_SRCS}) + +set_target_properties(${MODULE_NAME} PROPERTIES VERSION ${WINPR_VERSION_FULL} SOVERSION ${WINPR_VERSION} PREFIX "lib") + +if(WIN32) + set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ntdsapi) +endif() + +if(MONOLITHIC_BUILD) + set(WINPR_LIBS ${WINPR_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) +else() + target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT WinPRTargets) +endif() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/winpr/libwinpr/locale/ModuleOptions.cmake b/winpr/libwinpr/locale/ModuleOptions.cmake new file mode 100644 index 000000000..2ed13a07c --- /dev/null +++ b/winpr/libwinpr/locale/ModuleOptions.cmake @@ -0,0 +1,8 @@ + +set(MINWIN_LAYER "1") +set(MINWIN_GROUP "core") +set(MINWIN_MAJOR_VERSION "2") +set(MINWIN_MINOR_VERSION "1") +set(MINWIN_SHORT_NAME "localization") +set(MINWIN_LONG_NAME "Localization Functions") +set(MODULE_LIBRARY_NAME "api-ms-win-${MINWIN_GROUP}-${MINWIN_SHORT_NAME}-l${MINWIN_LAYER}-${MINWIN_MAJOR_VERSION}-${MINWIN_MINOR_VERSION}") diff --git a/winpr/libwinpr/locale/locale.c b/winpr/libwinpr/locale/locale.c new file mode 100644 index 000000000..439401128 --- /dev/null +++ b/winpr/libwinpr/locale/locale.c @@ -0,0 +1,96 @@ +/** + * WinPR: Windows Portable Runtime + * Localization Functions + * + * Copyright 2014 Marc-Andre Moreau + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +/** + * api-ms-win-core-localization-l1-2-1.dll: + * + * ConvertDefaultLocale + * EnumSystemGeoID + * EnumSystemLocalesA + * EnumSystemLocalesEx + * EnumSystemLocalesW + * FindNLSString + * FindNLSStringEx + * FormatMessageA + * FormatMessageW + * GetACP + * GetCalendarInfoEx + * GetCalendarInfoW + * GetCPInfo + * GetCPInfoExW + * GetFileMUIInfo + * GetFileMUIPath + * GetGeoInfoW + * GetLocaleInfoA + * GetLocaleInfoEx + * GetLocaleInfoW + * GetNLSVersion + * GetNLSVersionEx + * GetOEMCP + * GetProcessPreferredUILanguages + * GetSystemDefaultLangID + * GetSystemDefaultLCID + * GetSystemPreferredUILanguages + * GetThreadLocale + * GetThreadPreferredUILanguages + * GetThreadUILanguage + * GetUILanguageInfo + * GetUserDefaultLangID + * GetUserDefaultLCID + * GetUserDefaultLocaleName + * GetUserGeoID + * GetUserPreferredUILanguages + * IdnToAscii + * IdnToUnicode + * IsDBCSLeadByte + * IsDBCSLeadByteEx + * IsNLSDefinedString + * IsValidCodePage + * IsValidLanguageGroup + * IsValidLocale + * IsValidLocaleName + * IsValidNLSVersion + * LCMapStringA + * LCMapStringEx + * LCMapStringW + * LocaleNameToLCID + * ResolveLocaleName + * SetCalendarInfoW + * SetLocaleInfoW + * SetProcessPreferredUILanguages + * SetThreadLocale + * SetThreadPreferredUILanguages + * SetThreadUILanguage + * SetUserGeoID + * VerLanguageNameA + * VerLanguageNameW + */ + +#ifndef _WIN32 + + + +#endif + diff --git a/winpr/libwinpr/locale/module.def b/winpr/libwinpr/locale/module.def new file mode 100644 index 000000000..593aba52f --- /dev/null +++ b/winpr/libwinpr/locale/module.def @@ -0,0 +1,2 @@ +LIBRARY "libwinpr-locale" +EXPORTS diff --git a/winpr/libwinpr/locale/test/.gitignore b/winpr/libwinpr/locale/test/.gitignore new file mode 100644 index 000000000..ac4611812 --- /dev/null +++ b/winpr/libwinpr/locale/test/.gitignore @@ -0,0 +1,2 @@ +TestLocale +TestLocale.c diff --git a/winpr/libwinpr/locale/test/CMakeLists.txt b/winpr/libwinpr/locale/test/CMakeLists.txt new file mode 100644 index 000000000..33025b56b --- /dev/null +++ b/winpr/libwinpr/locale/test/CMakeLists.txt @@ -0,0 +1,30 @@ + +set(MODULE_NAME "TestLocale") +set(MODULE_PREFIX "TEST_LOCALE") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestLocaleFormatMessage.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-locale) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") diff --git a/winpr/libwinpr/locale/test/TestLocaleFormatMessage.c b/winpr/libwinpr/locale/test/TestLocaleFormatMessage.c new file mode 100644 index 000000000..b733872f9 --- /dev/null +++ b/winpr/libwinpr/locale/test/TestLocaleFormatMessage.c @@ -0,0 +1,8 @@ + +#include + +int TestLocaleFormatMessage(int argc, char* argv[]) +{ + return 0; +} +