Merge pull request #1426 from awakecoding/master

Fragmented RemoteFX & NSCodec Encoding, Core Server-Side Fixes, WinPR Utilities Expansion
This commit is contained in:
Marc-André Moreau 2013-08-15 11:08:44 -07:00
commit 763d13db43
39 changed files with 1642 additions and 882 deletions

View File

@ -227,21 +227,24 @@ if(APPLE)
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_IOS_EXTERNAL_SSL_PATH})
set_property(GLOBAL PROPERTY XCODE_ATTRIBUTE_SKIP_INSTALL YES)
else()
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
if(NOT DEFINED CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES i386 x86_64)
endif()
if(IS_DIRECTORY /opt/local/include)
include_directories(/opt/local/include)
link_directories(/opt/local/lib)
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.5")
endif()
if(WITH_CLANG)
set(CMAKE_C_COMPILER "clang")
endif()
if (WITH_VERBOSE)
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v")
# Tell the compiler where to look for the FreeRDP framework
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -v")
endif()
endif()

View File

@ -1,10 +1,10 @@
project(MacFreeRDP-library)
set(MODULE_NAME "MacFreeRDP-library")
set(MODULE_OUTPUT_NAME "MacFreeRDP")
set(MODULE_PREFIX "FREERDP_CLIENT_MAC-LIB")
set(MODULE_PREFIX "FREERDP_CLIENT_MAC_LIBRARY")
# Import frameworks
find_library(FOUNDATION_LIBRARY Foundation)
find_library(COCOA_LIBRARY Cocoa)
find_library(APPKIT_LIBRARY AppKit)
@ -21,46 +21,50 @@ set(MACOSX_BUNDLE_SHORT_VERSION_STRING 1.1.0)
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.1.0)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2013. All Rights Reserved.")
set(${MODULE_NAME}_RESOURCES "en.lproj/InfoPlist.strings")
set(${MODULE_PREFIX}_XIBS PasswordDialog.xib)
# OS X Interface Builder files
file(GLOB ${MODULE_NAME}_XIBS *.xib)
set(${MODULE_PREFIX}_SOURCES "")
# source files
file(GLOB ${MODULE_NAME}_SRC *.c *.m)
set(${MODULE_PREFIX}_OBJECTIVE_SOURCES
main.m
mf_client.m
MRDPCursor.m
MRDPView.m
PasswordDialog.m)
# header files
file(GLOB ${MODULE_NAME}_HEADERS *.h)
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
set(${MODULE_PREFIX}_HEADERS
mfreerdp.h
mf_client.h
MRDPCursor.h
MRDPView.h
PasswordDialog.h)
set(${MODULE_PREFIX}_RESOURCES "en.lproj/InfoPlist.strings")
# Include XIB file in Xcode resources.
if("${CMAKE_GENERATOR}" MATCHES "Xcode")
message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}")
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS})
set(${MODULE_PREFIX}_RESOURCES ${${MODULE_PREFIX}_RESOURCES} ${${MODULE_PREFIX}_XIBS})
endif()
add_library(${MODULE_NAME}
SHARED
../common/client.c
${${MODULE_NAME}_SRC}
${${MODULE_NAME}_HEADERS}
${${MODULE_NAME}_RESOURCES})
${${MODULE_PREFIX}_SOURCES}
${${MODULE_PREFIX}_HEADERS}
${${MODULE_PREFIX}_RESOURCES})
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAME}")
# configures the framework to always be looked for in the application bundle in the Frameworks sub-folder.
SET_TARGET_PROPERTIES(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/)
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_INSTALL_PATH @executable_path/../Frameworks/)
set_target_properties(${MODULE_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXECUTABLE_OUTPUT_PATH}
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXECUTABLE_OUTPUT_PATH})
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
set(MODULE_VERSION, 1.1.0)
set_target_properties(${MODULE_NAME} PROPERTIES
FRAMEWORK TRUE
MACOSX_FRAMEWORK_IDENTIFIER com.awakecoding.${MODULE_NAME}
@ -153,16 +157,16 @@ endif()
add_custom_command (TARGET ${MODULE_NAME} POST_BUILD
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources/${XIB_WE}.nib ${xib}
--compile ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Versions/${MACOSX_BUNDLE_SHORT_VERSION_STRING}/Resources/${XIB_WE}.nib ${CMAKE_CURRENT_SOURCE_DIR}/${xib}
COMMENT "Compiling ${xib}")
endforeach()
# endif()
# Copy the public header files into the framework
foreach(HEADER ${${MODULE_NAME}_HEADERS})
foreach(HEADER ${${MODULE_PREFIX}_HEADERS})
# message("adding post-build dependency: ${LIB}")
add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
COMMAND ditto ${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/
COMMAND ditto ${CMAKE_CURRENT_SOURCE_DIR}/${HEADER} ${CMAKE_CURRENT_BINARY_DIR}/$(CONFIGURATION)/${MODULE_OUTPUT_NAME}.framework/Headers/
COMMENT Copying public header files to ${MODULE_NAME})
endforeach()

View File

@ -65,7 +65,6 @@
#import "freerdp/client/file.h"
#import "freerdp/client/cmdline.h"
/******************************************
Forward declarations
******************************************/
@ -804,9 +803,6 @@ BOOL mac_pre_connect(freerdp* instance)
instance->update->EndPaint = mac_end_paint;
instance->update->SetBounds = mac_set_bounds;
//instance->update->BitmapUpdate = mac_bitmap_update;
mfContext *mfc = (mfContext*) instance->context;
MRDPView* view = (MRDPView*) mfc->view;
settings = instance->settings;

View File

@ -1,15 +1,14 @@
project(MacFreeRDP-client)
project(MacFreeRDP)
set(MODULE_NAME "MacFreeRDP")
set(MODULE_OUTPUT_NAME "MacFreeRDP")
set(MODULE_PREFIX "FREERDP_CLIENT_MAC_CLIENT")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -mmacosx-version-min=10.5")
# Import libraries
find_library(FOUNDATION_LIBRARY Foundation)
find_library(COCOA_LIBRARY Cocoa)
find_library(APPKIT_LIBRARY AppKit)
#find_library(FREERDP_LIBRARY NAMES MacFreeRDP PATHS ${CMAKE_CURRENT_BINARY_DIR}/../${CONFIGURATION})
set(MACOSX_BUNDLE_INFO_STRING "MacFreeRDP")
set(MACOSX_BUNDLE_ICON_FILE "FreeRDP.icns")
@ -27,28 +26,32 @@ set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication")
mark_as_advanced(COCOA_LIBRARY FOUNDATION_LIBRARY APPKIT_LIBRARY)
set(APP_TYPE MACOSX_BUNDLE)
# OS X Interface Builder files
file(GLOB ${MODULE_NAME}_XIBS *.xib)
set(${MODULE_PREFIX}_XIBS MainMenu.xib)
set(${MODULE_NAME}_RESOURCES ${MACOSX_BUNDLE_ICON_FILE})
set(${MODULE_PREFIX}_SOURCES "")
set(${MODULE_PREFIX}_OBJECTIVE_SOURCES
main.m
AppDelegate.m)
list(APPEND ${MODULE_PREFIX}_SOURCES ${${MODULE_PREFIX}_OBJECTIVE_SOURCES})
set(${MODULE_PREFIX}_HEADERS
AppDelegate.h)
set(${MODULE_PREFIX}_RESOURCES ${MACOSX_BUNDLE_ICON_FILE})
# Include XIB file in Xcode resources.
if("${CMAKE_GENERATOR}" MATCHES "Xcode")
message(STATUS "Adding Xcode XIB resources for ${MODULE_NAME}")
set(${MODULE_NAME}_RESOURCES ${${MODULE_NAME}_RESOURCES} ${${MODULE_NAME}_XIBS})
endif("${CMAKE_GENERATOR}" MATCHES "Xcode")
# Headers
file(GLOB ${MODULE_NAME}_HEADERS *.h)
# Source
file(GLOB ${MODULE_NAME}_SOURCES *.m)
set(${MODULE_PREFIX}_RESOURCES ${${MODULE_PREFIX}_RESOURCES} ${${MODULE_PREFIX}_XIBS})
endif()
add_executable(${MODULE_NAME}
${APP_TYPE}
${${MODULE_NAME}_HEADERS}
${${MODULE_NAME}_SOURCES}
${${MODULE_NAME}_RESOURCES})
${${MODULE_PREFIX}_HEADERS}
${${MODULE_PREFIX}_SOURCES}
${${MODULE_PREFIX}_RESOURCES})
set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAME}")
@ -56,14 +59,7 @@ set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME "${MODULE_OUTPUT_NAM
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Info.plist ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
# This allows for automatic xib to nib ibitool
set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_NAME}_RESOURCES}")
# Automatic ref counting
# temporary turn off for x86_64 build issue
# set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
# Support for automatic reference counting requires non-fragile abi.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fobjc-nonfragile-abi")
set_target_properties(${MODULE_NAME} PROPERTIES RESOURCE "${${MODULE_PREFIX}_RESOURCES}")
# Tell the compiler where to look for the FreeRDP framework
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F../")
@ -72,8 +68,6 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -F../")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS
"${XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS} ${CMAKE_CURRENT_BINARY_DIR}/../$(CONFIGURATION)")
set_target_properties(${MODULE_NAME} PROPERTIES XCODE_ATTRIBUTE_ARCHS "$(NATIVE_ARCH_ACTUAL)")
# Set the info plist to the custom instance
set_target_properties(${MODULE_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/Info.plist)
@ -106,13 +100,13 @@ if("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
add_custom_command(TARGET ${MODULE_NAME} PRE_BUILD COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources)
# Compile the .xib files using the 'ibtool' program with the destination being the app package
foreach(xib ${${MODULE_NAME}_XIBS})
foreach(xib ${${MODULE_PREFIX}_XIBS})
get_filename_component(XIB_WE ${xib} NAME_WE)
add_custom_command (TARGET ${MODULE_NAME} POST_BUILD
COMMAND ${IBTOOL} --errors --warnings --notices --output-format human-readable-text
--compile ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources/${XIB_WE}.nib ${xib}
--compile ${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}/${MODULE_OUTPUT_NAME}.app/Contents/Resources/${XIB_WE}.nib ${CMAKE_CURRENT_SOURCE_DIR}/${xib}
COMMENT "Compiling ${xib}")
endforeach()
endif("${CMAKE_GENERATOR}" MATCHES "Unix Makefiles")
endif()

View File

@ -575,14 +575,14 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
message = rfx_process_message(rfx_context, surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
/* blit each tile */
for (i = 0; i < message->num_tiles; i++)
for (i = 0; i < message->numTiles; i++)
{
tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop;
freerdp_image_convert(message->tiles[i]->data, wfc->tile->pdata, 64, 64, 32, 32, wfc->clrconv);
for (j = 0; j < message->num_rects; j++)
for (j = 0; j < message->numRects; j++)
{
wf_set_clip_rgn(wfc,
surface_bits_command->destLeft + message->rects[j].x,
@ -596,7 +596,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
wf_set_null_clip_rgn(wfc);
/* invalidate regions */
for (i = 0; i < message->num_rects; i++)
for (i = 0; i < message->numRects; i++)
{
tx = surface_bits_command->destLeft + message->rects[i].x;
ty = surface_bits_command->destTop + message->rects[i].y;
@ -618,7 +618,7 @@ void wf_gdi_surface_bits(wfContext* wfc, SURFACE_BITS_COMMAND* surface_bits_comm
bitmap_info.bmiHeader.biCompression = BI_RGB;
SetDIBitsToDevice(wfc->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height, 0, 0, 0, surface_bits_command->height,
nsc_context->bmpdata, &bitmap_info, DIB_RGB_COLORS);
nsc_context->BitmapData, &bitmap_info, DIB_RGB_COLORS);
wf_invalidate_region(wfc, surface_bits_command->destLeft, surface_bits_command->destTop,
surface_bits_command->width, surface_bits_command->height);
}

2
client/X11/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.xml
generate_argument_docbook

View File

@ -80,31 +80,43 @@ if(WITH_MANPAGES)
configure_file(xfreerdp.1.xml.in xfreerdp.1.xml @ONLY IMMEDIATE)
add_executable(generate_argument_docbook
generate_argument_docbook.c)
target_link_libraries(generate_argument_docbook winpr-utils freerdp-core freerdp-utils freerdp-client)
add_executable(generate_argument_docbook generate_argument_docbook.c)
set(GAD_LIBS freerdp-client)
set_complex_link_libraries(VARIABLE GAD_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-utils)
set_complex_link_libraries(VARIABLE GAD_LIBS MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-core freerdp-utils)
message(WARNING "GAD_LIBS: ${GAD_LIBS}")
target_link_libraries(generate_argument_docbook ${GAD_LIBS})
add_custom_command(OUTPUT xfreerdp.1
COMMAND generate_argument_docbook
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml
generate_argument_docbook)
COMMAND generate_argument_docbook
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${XSLTPROC_EXECUTABLE} ${DOCBOOKXSL_DIR}/manpages/docbook.xsl xfreerdp.1.xml
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS
${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1.xml
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-examples.1.xml
${CMAKE_CURRENT_SOURCE_DIR}/xfreerdp-channels.1.xml
generate_argument_docbook)
add_custom_target(xfreerdp.manpage ALL
DEPENDS xfreerdp.1)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/xfreerdp.1 DESTINATION share/man/man1)
else(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE)
else()
message(WARNING "WITH_MANPAGES was set, but xsltproc was not found. man-pages will not be installed")
endif(DOCBOOKXSL_FOUND AND XSLTPROC_EXECUTABLE)
endif()
endif(WITH_MANPAGES)
set(XSHM_FEATURE_TYPE "REQUIRED")

View File

@ -950,10 +950,10 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
XSetClipRectangles(xfc->display, xfc->gc,
surface_bits_command->destLeft, surface_bits_command->destTop,
(XRectangle*) message->rects, message->num_rects, YXBanded);
(XRectangle*) message->rects, message->numRects, YXBanded);
/* Draw the tiles to primary surface, each is 64x64. */
for (i = 0; i < message->num_tiles; i++)
for (i = 0; i < message->numTiles; i++)
{
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,
(char*) message->tiles[i]->data, 64, 64, 32, 0);
@ -966,7 +966,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
}
/* Copy the updated region from backstore to the window. */
for (i = 0; i < message->num_rects; i++)
for (i = 0; i < message->numRects; i++)
{
tx = message->rects[i].x + surface_bits_command->destLeft;
ty = message->rects[i].y + surface_bits_command->destTop;
@ -988,7 +988,7 @@ void xf_gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits
xfc->bmp_codec_nsc = (BYTE*) realloc(xfc->bmp_codec_nsc,
surface_bits_command->width * surface_bits_command->height * 4);
freerdp_image_flip(nsc_context->bmpdata, xfc->bmp_codec_nsc,
freerdp_image_flip(nsc_context->BitmapData, xfc->bmp_codec_nsc,
surface_bits_command->width, surface_bits_command->height, 32);
image = XCreateImage(xfc->display, xfc->visual, 24, ZPixmap, 0,

View File

@ -404,7 +404,7 @@ void test_message(void)
message = rfx_process_message(context, s->pointer, s->capacity);
if (i == 0)
{
for (j = 0; j < message->num_tiles; j++)
for (j = 0; j < message->numTiles; j++)
{
dump_ppm_image(message->tiles[j]->data);
}

View File

@ -42,9 +42,25 @@ struct _NSC_STREAM
};
typedef struct _NSC_STREAM NSC_STREAM;
struct _NSC_MESSAGE
{
int x;
int y;
UINT32 width;
UINT32 height;
BYTE* data;
int scanline;
UINT32 MaxPlaneSize;
BYTE* PlaneBuffers[5];
UINT32 OrgByteCount[4];
UINT32 PlaneByteCount[4];
};
typedef struct _NSC_MESSAGE NSC_MESSAGE;
typedef struct _NSC_CONTEXT_PRIV NSC_CONTEXT_PRIV;
typedef struct _NSC_CONTEXT NSC_CONTEXT;
struct _NSC_CONTEXT
{
UINT32 OrgByteCount[4]; /* original byte length of luma, chroma orange, chroma green, alpha variable in order */
@ -52,15 +68,15 @@ struct _NSC_CONTEXT
UINT16 bpp;
UINT16 width;
UINT16 height;
BYTE* bmpdata; /* final argb values in little endian order */
UINT32 bmpdata_length; /* the maximum length of the buffer that bmpdata points to */
BYTE* BitmapData; /* final argb values in little endian order */
UINT32 BitmapDataLength; /* the maximum length of the buffer that bmpdata points to */
RDP_PIXEL_FORMAT pixel_format;
/* color palette allocated by the application */
const BYTE* palette;
void (*decode)(NSC_CONTEXT* context);
void (*encode)(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride);
void (*encode)(NSC_CONTEXT* context, BYTE* BitmapData, int rowstride);
NSC_CONTEXT_PRIV* priv;
};
@ -73,6 +89,11 @@ FREERDP_API void nsc_compose_message(NSC_CONTEXT* context, wStream* s,
BYTE* bmpdata, int width, int height, int rowstride);
FREERDP_API void nsc_context_free(NSC_CONTEXT* context);
FREERDP_API NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
int width, int height, int scanline, int* numMessages, int maxDataSize);
FREERDP_API int nsc_write_message(NSC_CONTEXT* context, wStream* s, NSC_MESSAGE* message);
FREERDP_API int nsc_message_free(NSC_CONTEXT* context, NSC_MESSAGE* message);
#ifdef __cplusplus
}
#endif

View File

@ -22,6 +22,7 @@
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <winpr/stream.h>
@ -50,18 +51,36 @@ struct _RFX_TILE
{
UINT16 x;
UINT16 y;
int width;
int height;
BYTE* data;
int scanline;
BYTE quantIdxY;
BYTE quantIdxCb;
BYTE quantIdxCr;
UINT16 xIdx;
UINT16 yIdx;
UINT16 YLen;
UINT16 CbLen;
UINT16 CrLen;
BYTE* YData;
BYTE* CbData;
BYTE* CrData;
};
typedef struct _RFX_TILE RFX_TILE;
struct _RFX_MESSAGE
{
UINT32 frameIdx;
/**
* The rects array represents the updated region of the frame. The UI
* requires to clip drawing destination base on the union of the rects.
*/
UINT16 num_rects;
UINT16 numRects;
RFX_RECT* rects;
BOOL freeRects;
/**
* The tiles array represents the actual frame data. Each tile is always
@ -69,15 +88,35 @@ struct _RFX_MESSAGE
* rects described above) are valid. Pixels outside of the region may
* contain arbitrary data.
*/
UINT16 num_tiles;
UINT16 numTiles;
RFX_TILE** tiles;
UINT16 numQuant;
UINT32* quantVals;
UINT32 tilesDataSize;
BOOL freeArray;
};
typedef struct _RFX_MESSAGE RFX_MESSAGE;
typedef struct _RFX_CONTEXT_PRIV RFX_CONTEXT_PRIV;
enum _RFX_STATE
{
RFX_STATE_INITIAL,
RFX_STATE_SERVER_UNINITIALIZED,
RFX_STATE_SEND_HEADERS,
RFX_STATE_SEND_FRAME_DATA,
RFX_STATE_FRAME_DATA_SENT,
RFX_STATE_FINAL
};
typedef enum _RFX_STATE RFX_STATE;
struct _RFX_CONTEXT
{
RFX_STATE state;
UINT16 flags;
UINT16 properties;
UINT16 width;
@ -93,13 +132,12 @@ struct _RFX_CONTEXT
const BYTE* palette;
/* temporary data within a frame */
UINT32 frame_idx;
BOOL header_processed;
BYTE num_quants;
UINT32 frameIdx;
BYTE numQuant;
UINT32* quants;
BYTE quant_idx_y;
BYTE quant_idx_cb;
BYTE quant_idx_cr;
BYTE quantIdxY;
BYTE quantIdxCb;
BYTE quantIdxCr;
/* routines */
void (*quantization_decode)(INT16* buffer, const UINT32* quantization_values);
@ -130,6 +168,12 @@ FREERDP_API void rfx_compose_message_header(RFX_CONTEXT* context, wStream* s);
FREERDP_API void rfx_compose_message(RFX_CONTEXT* context, wStream* s,
const RFX_RECT* rects, int num_rects, BYTE* image_data, int width, int height, int rowstride);
FREERDP_API RFX_MESSAGE* rfx_encode_message(RFX_CONTEXT* context, const RFX_RECT* rects,
int numRects, BYTE* data, int width, int height, int scanline);
FREERDP_API RFX_MESSAGE* rfx_encode_messages(RFX_CONTEXT* context, const RFX_RECT* rects, int numRects,
BYTE* data, int width, int height, int scanline, int* numMessages, int maxDataSize);
FREERDP_API void rfx_write_message(RFX_CONTEXT* context, wStream* s, RFX_MESSAGE* message);
#ifdef __cplusplus
}
#endif

View File

@ -134,6 +134,14 @@ enum SURFCMD_FRAMEACTION
SURFACECMD_FRAMEACTION_END = 0x0001
};
struct _SURFACE_FRAME
{
UINT32 frameId;
UINT32 commandCount;
SURFACE_BITS_COMMAND* commands;
};
typedef struct _SURFACE_FRAME SURFACE_FRAME;
/* defined inside libfreerdp-core */
typedef struct rdp_update_proxy rdpUpdateProxy;

View File

@ -61,7 +61,7 @@ static void nsc_decode(NSC_CONTEXT* context)
INT16 b_val;
BYTE* bmpdata;
bmpdata = context->bmpdata;
bmpdata = context->BitmapData;
rw = ROUND_UP_TO(context->width, 8);
shift = context->nsc_stream.ColorLossLevel - 1; /* colorloss recovery + YCoCg shift */
@ -69,17 +69,19 @@ static void nsc_decode(NSC_CONTEXT* context)
{
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
{
yplane = context->priv->plane_buf[0] + y * rw; /* Y */
coplane = context->priv->plane_buf[1] + (y >> 1) * (rw >> 1); /* Co, supersampled */
cgplane = context->priv->plane_buf[2] + (y >> 1) * (rw >> 1); /* Cg, supersampled */
yplane = context->priv->PlaneBuffers[0] + y * rw; /* Y */
coplane = context->priv->PlaneBuffers[1] + (y >> 1) * (rw >> 1); /* Co, supersampled */
cgplane = context->priv->PlaneBuffers[2] + (y >> 1) * (rw >> 1); /* Cg, supersampled */
}
else
{
yplane = context->priv->plane_buf[0] + y * context->width; /* Y */
coplane = context->priv->plane_buf[1] + y * context->width; /* Co */
cgplane = context->priv->plane_buf[2] + y * context->width; /* Cg */
yplane = context->priv->PlaneBuffers[0] + y * context->width; /* Y */
coplane = context->priv->PlaneBuffers[1] + y * context->width; /* Co */
cgplane = context->priv->PlaneBuffers[2] + y * context->width; /* Cg */
}
aplane = context->priv->plane_buf[3] + y * context->width; /* A */
aplane = context->priv->PlaneBuffers[3] + y * context->width; /* A */
for (x = 0; x < context->width; x++)
{
y_val = (INT16) *yplane;
@ -100,13 +102,14 @@ static void nsc_decode(NSC_CONTEXT* context)
}
}
static void nsc_rle_decode(BYTE* in, BYTE* out, UINT32 origsz)
static void nsc_rle_decode(BYTE* in, BYTE* out, UINT32 originalSize)
{
UINT32 len;
UINT32 left;
BYTE value;
left = origsz;
left = originalSize;
while (left > 4)
{
value = *in++;
@ -119,6 +122,7 @@ static void nsc_rle_decode(BYTE* in, BYTE* out, UINT32 origsz)
else if (value == *in)
{
in++;
if (*in < 0xFF)
{
len = (UINT32) *in++;
@ -130,7 +134,8 @@ static void nsc_rle_decode(BYTE* in, BYTE* out, UINT32 origsz)
len = *((UINT32*) in);
in += 4;
}
memset(out, value, len);
FillMemory(out, len, value);
out += len;
left -= len;
}
@ -148,24 +153,24 @@ static void nsc_rle_decompress_data(NSC_CONTEXT* context)
{
UINT16 i;
BYTE* rle;
UINT32 origsize;
UINT32 planesize;
UINT32 planeSize;
UINT32 originalSize;
rle = context->nsc_stream.Planes;
for (i = 0; i < 4; i++)
{
origsize = context->OrgByteCount[i];
planesize = context->nsc_stream.PlaneByteCount[i];
originalSize = context->OrgByteCount[i];
planeSize = context->nsc_stream.PlaneByteCount[i];
if (planesize == 0)
memset(context->priv->plane_buf[i], 0xff, origsize);
else if (planesize < origsize)
nsc_rle_decode(rle, context->priv->plane_buf[i], origsize);
if (planeSize == 0)
FillMemory(context->priv->PlaneBuffers[i], originalSize, 0xFF);
else if (planeSize < originalSize)
nsc_rle_decode(rle, context->priv->PlaneBuffers[i], originalSize);
else
memcpy(context->priv->plane_buf[i], rle, origsize);
CopyMemory(context->priv->PlaneBuffers[i], rle, originalSize);
rle += planesize;
rle += planeSize;
}
}
@ -192,31 +197,37 @@ static void nsc_context_initialize(NSC_CONTEXT* context, wStream* s)
nsc_stream_initialize(context, s);
length = context->width * context->height * 4;
if (context->bmpdata == NULL)
if (!context->BitmapData)
{
context->bmpdata = malloc(length + 16);
ZeroMemory(context->bmpdata, length + 16);
context->bmpdata_length = length;
context->BitmapData = malloc(length + 16);
ZeroMemory(context->BitmapData, length + 16);
context->BitmapDataLength = length;
}
else if (length > context->bmpdata_length)
else if (length > context->BitmapDataLength)
{
context->bmpdata = realloc(context->bmpdata, length + 16);
context->bmpdata_length = length;
context->BitmapData = realloc(context->BitmapData, length + 16);
context->BitmapDataLength = length;
}
tempWidth = ROUND_UP_TO(context->width, 8);
tempHeight = ROUND_UP_TO(context->height, 2);
/* The maximum length a decoded plane can reach in all cases */
length = tempWidth * tempHeight;
if (length > context->priv->plane_buf_length)
if (length > context->priv->PlaneBuffersLength)
{
for (i = 0; i < 4; i++)
context->priv->plane_buf[i] = (BYTE*) realloc(context->priv->plane_buf[i], length);
context->priv->plane_buf_length = length;
context->priv->PlaneBuffers[i] = (BYTE*) realloc(context->priv->PlaneBuffers[i], length);
context->priv->PlaneBuffersLength = length;
}
for (i = 0; i < 4; i++)
context->OrgByteCount[i]=context->width * context->height;
{
context->OrgByteCount[i] = context->width * context->height;
}
if (context->nsc_stream.ChromaSubSamplingLevel > 0) /* [MS-RDPNSC] 2.2 */
{
@ -238,20 +249,58 @@ static void nsc_profiler_print(NSC_CONTEXT* context)
PROFILER_PRINT_FOOTER;
}
NSC_CONTEXT* nsc_context_new(void)
{
UINT8 i;
NSC_CONTEXT* context;
context = (NSC_CONTEXT*) calloc(1, sizeof(NSC_CONTEXT));
context->priv = (NSC_CONTEXT_PRIV*) calloc(1, sizeof(NSC_CONTEXT_PRIV));
for (i = 0; i < 5; ++i)
{
context->priv->PlaneBuffers[i] = NULL;
}
context->BitmapData = NULL;
context->decode = nsc_decode;
context->encode = nsc_encode;
context->priv->PlanePool = BufferPool_New(TRUE, 0, 16);
PROFILER_CREATE(context->priv->prof_nsc_rle_decompress_data, "nsc_rle_decompress_data");
PROFILER_CREATE(context->priv->prof_nsc_decode, "nsc_decode");
PROFILER_CREATE(context->priv->prof_nsc_rle_compress_data, "nsc_rle_compress_data");
PROFILER_CREATE(context->priv->prof_nsc_encode, "nsc_encode");
/* Default encoding parameters */
context->nsc_stream.ColorLossLevel = 3;
context->nsc_stream.ChromaSubSamplingLevel = 1;
/* init optimized methods */
NSC_INIT_SIMD(context);
return context;
}
void nsc_context_free(NSC_CONTEXT* context)
{
int i;
for (i = 0; i < 4; i++)
{
if (context->priv->plane_buf[i])
if (context->priv->PlaneBuffers[i])
{
free(context->priv->plane_buf[i]);
context->priv->plane_buf[i] = NULL;
free(context->priv->PlaneBuffers[i]);
context->priv->PlaneBuffers[i] = NULL;
}
}
if (context->bmpdata)
free(context->bmpdata);
if (context->BitmapData)
free(context->BitmapData);
BufferPool_Free(context->priv->PlanePool);
nsc_profiler_print(context);
PROFILER_FREE(context->priv->prof_nsc_rle_decompress_data);
@ -261,71 +310,44 @@ void nsc_context_free(NSC_CONTEXT* context)
free(context->priv);
free(context);
context = NULL;
}
NSC_CONTEXT* nsc_context_new(void)
{
NSC_CONTEXT* nsc_context;
UINT8 i;
nsc_context = (NSC_CONTEXT*) calloc(1, sizeof(NSC_CONTEXT));
nsc_context->priv = (NSC_CONTEXT_PRIV*) calloc(1, sizeof(NSC_CONTEXT_PRIV));
for (i=0; i < 5; ++i)
{
nsc_context->priv->plane_buf[i] = NULL;
}
nsc_context->bmpdata = NULL;
nsc_context->decode = nsc_decode;
nsc_context->encode = nsc_encode;
PROFILER_CREATE(nsc_context->priv->prof_nsc_rle_decompress_data, "nsc_rle_decompress_data");
PROFILER_CREATE(nsc_context->priv->prof_nsc_decode, "nsc_decode");
PROFILER_CREATE(nsc_context->priv->prof_nsc_rle_compress_data, "nsc_rle_compress_data");
PROFILER_CREATE(nsc_context->priv->prof_nsc_encode, "nsc_encode");
/* Default encoding parameters */
nsc_context->nsc_stream.ColorLossLevel = 3;
nsc_context->nsc_stream.ChromaSubSamplingLevel = 1;
/* init optimized methods */
NSC_INIT_SIMD(nsc_context);
return nsc_context;
}
void nsc_context_set_pixel_format(NSC_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format)
{
context->pixel_format = pixel_format;
switch (pixel_format)
{
case RDP_PIXEL_FORMAT_B8G8R8A8:
case RDP_PIXEL_FORMAT_R8G8B8A8:
context->bpp = 32;
break;
case RDP_PIXEL_FORMAT_B8G8R8:
case RDP_PIXEL_FORMAT_R8G8B8:
context->bpp = 24;
break;
case RDP_PIXEL_FORMAT_B5G6R5_LE:
case RDP_PIXEL_FORMAT_R5G6B5_LE:
context->bpp = 16;
break;
case RDP_PIXEL_FORMAT_P4_PLANER:
context->bpp = 4;
break;
case RDP_PIXEL_FORMAT_P8:
context->bpp = 8;
break;
default:
context->bpp = 0;
break;
}
}
void nsc_process_message(NSC_CONTEXT* context, UINT16 bpp,
UINT16 width, UINT16 height, BYTE* data, UINT32 length)
void nsc_process_message(NSC_CONTEXT* context, UINT16 bpp, UINT16 width, UINT16 height, BYTE* data, UINT32 length)
{
wStream* s;

View File

@ -24,10 +24,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <winpr/crt.h>
#include <freerdp/codec/nsc.h>
#include "nsc_types.h"
@ -42,13 +45,16 @@ static void nsc_context_initialize_encode(NSC_CONTEXT* context)
tempWidth = ROUND_UP_TO(context->width, 8);
tempHeight = ROUND_UP_TO(context->height, 2);
/* The maximum length a decoded plane can reach in all cases */
length = tempWidth * tempHeight + 16;
if (length > context->priv->plane_buf_length)
if (length > context->priv->PlaneBuffersLength)
{
for (i = 0; i < 5; i++)
context->priv->plane_buf[i] = (BYTE*) realloc(context->priv->plane_buf[i], length);
context->priv->plane_buf_length = length;
context->priv->PlaneBuffers[i] = (BYTE*) realloc(context->priv->PlaneBuffers[i], length);
context->priv->PlaneBuffersLength = length;
}
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
@ -67,7 +73,7 @@ static void nsc_context_initialize_encode(NSC_CONTEXT* context)
}
}
static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* data, int scanline)
{
UINT16 x;
UINT16 y;
@ -89,18 +95,19 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
tempHeight = ROUND_UP_TO(context->height, 2);
rw = (context->nsc_stream.ChromaSubSamplingLevel > 0 ? tempWidth : context->width);
ccl = context->nsc_stream.ColorLossLevel;
yplane = context->priv->plane_buf[0];
coplane = context->priv->plane_buf[1];
cgplane = context->priv->plane_buf[2];
aplane = context->priv->plane_buf[3];
yplane = context->priv->PlaneBuffers[0];
coplane = context->priv->PlaneBuffers[1];
cgplane = context->priv->PlaneBuffers[2];
aplane = context->priv->PlaneBuffers[3];
for (y = 0; y < context->height; y++)
{
src = bmpdata + (context->height - 1 - y) * rowstride;
yplane = context->priv->plane_buf[0] + y * rw;
coplane = context->priv->plane_buf[1] + y * rw;
cgplane = context->priv->plane_buf[2] + y * rw;
aplane = context->priv->plane_buf[3] + y * context->width;
src = data + (context->height - 1 - y) * scanline;
yplane = context->priv->PlaneBuffers[0] + y * rw;
coplane = context->priv->PlaneBuffers[1] + y * rw;
cgplane = context->priv->PlaneBuffers[2] + y * rw;
aplane = context->priv->PlaneBuffers[3] + y * context->width;
for (x = 0; x < context->width; x++)
{
switch (context->pixel_format)
@ -111,24 +118,28 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
r_val = *src++;
a_val = *src++;
break;
case RDP_PIXEL_FORMAT_R8G8B8A8:
r_val = *src++;
g_val = *src++;
b_val = *src++;
a_val = *src++;
break;
case RDP_PIXEL_FORMAT_B8G8R8:
b_val = *src++;
g_val = *src++;
r_val = *src++;
a_val = 0xFF;
break;
case RDP_PIXEL_FORMAT_R8G8B8:
r_val = *src++;
g_val = *src++;
b_val = *src++;
a_val = 0xFF;
break;
case RDP_PIXEL_FORMAT_B5G6R5_LE:
b_val = (INT16) (((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
g_val = (INT16) ((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
@ -136,6 +147,7 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
a_val = 0xFF;
src += 2;
break;
case RDP_PIXEL_FORMAT_R5G6B5_LE:
r_val = (INT16) (((*(src + 1)) & 0xF8) | ((*(src + 1)) >> 5));
g_val = (INT16) ((((*(src + 1)) & 0x07) << 5) | (((*src) & 0xE0) >> 3));
@ -143,6 +155,7 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
a_val = 0xFF;
src += 2;
break;
case RDP_PIXEL_FORMAT_P4_PLANER:
{
int shift;
@ -162,6 +175,7 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
}
a_val = 0xFF;
break;
case RDP_PIXEL_FORMAT_P8:
{
int idx = (*src) * 3;
@ -173,16 +187,20 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
}
a_val = 0xFF;
break;
default:
r_val = g_val = b_val = a_val = 0;
break;
}
*yplane++ = (BYTE) ((r_val >> 2) + (g_val >> 1) + (b_val >> 2));
/* Perform color loss reduction here */
*coplane++ = (BYTE) ((r_val - b_val) >> ccl);
*cgplane++ = (BYTE) ((-(r_val >> 1) + g_val - (b_val >> 1)) >> ccl);
*aplane++ = a_val;
}
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (x % 2) == 1)
{
*yplane = *(yplane - 1);
@ -190,11 +208,12 @@ static void nsc_encode_argb_to_aycocg(NSC_CONTEXT* context, BYTE* bmpdata, int r
*cgplane = *(cgplane - 1);
}
}
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (y % 2) == 1)
{
memcpy(yplane + rw, yplane, rw);
memcpy(coplane + rw, coplane, rw);
memcpy(cgplane + rw, cgplane, rw);
CopyMemory(yplane + rw, yplane, rw);
CopyMemory(coplane + rw, coplane, rw);
CopyMemory(cgplane + rw, cgplane, rw);
}
}
@ -216,12 +235,13 @@ static void nsc_encode_subsampling(NSC_CONTEXT* context)
for (y = 0; y < tempHeight >> 1; y++)
{
co_dst = context->priv->plane_buf[1] + y * (tempWidth >> 1);
cg_dst = context->priv->plane_buf[2] + y * (tempWidth >> 1);
co_src0 = (INT8*) context->priv->plane_buf[1] + (y << 1) * tempWidth;
co_dst = context->priv->PlaneBuffers[1] + y * (tempWidth >> 1);
cg_dst = context->priv->PlaneBuffers[2] + y * (tempWidth >> 1);
co_src0 = (INT8*) context->priv->PlaneBuffers[1] + (y << 1) * tempWidth;
co_src1 = co_src0 + tempWidth;
cg_src0 = (INT8*) context->priv->plane_buf[2] + (y << 1) * tempWidth;
cg_src0 = (INT8*) context->priv->PlaneBuffers[2] + (y << 1) * tempWidth;
cg_src1 = cg_src0 + tempWidth;
for (x = 0; x < tempWidth >> 1; x++)
{
*co_dst++ = (BYTE) (((INT16) *co_src0 + (INT16) *(co_src0 + 1) +
@ -239,24 +259,25 @@ static void nsc_encode_subsampling(NSC_CONTEXT* context)
void nsc_encode(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
{
nsc_encode_argb_to_aycocg(context, bmpdata, rowstride);
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
{
nsc_encode_subsampling(context);
}
}
static UINT32 nsc_rle_encode(BYTE* in, BYTE* out, UINT32 origsz)
static UINT32 nsc_rle_encode(BYTE* in, BYTE* out, UINT32 originalSize)
{
UINT32 left;
UINT32 runlength = 1;
UINT32 planesize = 0;
UINT32 planeSize = 0;
left = origsz;
left = originalSize;
/**
* We quit the loop if the running compressed size is larger than the original.
* In such cases data will be sent uncompressed.
*/
while (left > 4 && planesize < origsz - 4)
while (left > 4 && planeSize < originalSize - 4)
{
if (left > 5 && *in == *(in + 1))
{
@ -265,7 +286,7 @@ static UINT32 nsc_rle_encode(BYTE* in, BYTE* out, UINT32 origsz)
else if (runlength == 1)
{
*out++ = *in;
planesize++;
planeSize++;
}
else if (runlength < 256)
{
@ -273,7 +294,7 @@ static UINT32 nsc_rle_encode(BYTE* in, BYTE* out, UINT32 origsz)
*out++ = *in;
*out++ = runlength - 2;
runlength = 1;
planesize += 3;
planeSize += 3;
}
else
{
@ -285,52 +306,213 @@ static UINT32 nsc_rle_encode(BYTE* in, BYTE* out, UINT32 origsz)
*out++ = (runlength & 0x00FF0000) >> 16;
*out++ = (runlength & 0xFF000000) >> 24;
runlength = 1;
planesize += 7;
planeSize += 7;
}
in++;
left--;
}
if (planesize < origsz - 4)
{
memcpy(out, in, 4);
}
planesize += 4;
return planesize;
if (planeSize < originalSize - 4)
CopyMemory(out, in, 4);
planeSize += 4;
return planeSize;
}
static void nsc_rle_compress_data(NSC_CONTEXT* context)
{
UINT16 i;
BYTE* rle;
UINT32 origsize;
UINT32 planesize;
rle = context->nsc_stream.Planes;
UINT32 planeSize;
UINT32 originalSize;
for (i = 0; i < 4; i++)
{
origsize = context->OrgByteCount[i];
if (origsize == 0)
originalSize = context->OrgByteCount[i];
if (originalSize == 0)
{
planesize = 0;
planeSize = 0;
}
else
{
planesize = nsc_rle_encode(context->priv->plane_buf[i],
context->priv->plane_buf[4], origsize);
if (planesize < origsize)
memcpy(context->priv->plane_buf[i], context->priv->plane_buf[4], planesize);
planeSize = nsc_rle_encode(context->priv->PlaneBuffers[i], context->priv->PlaneBuffers[4], originalSize);
if (planeSize < originalSize)
CopyMemory(context->priv->PlaneBuffers[i], context->priv->PlaneBuffers[4], planeSize);
else
planesize = origsize;
planeSize = originalSize;
}
context->nsc_stream.PlaneByteCount[i] = planesize;
context->nsc_stream.PlaneByteCount[i] = planeSize;
}
}
void nsc_compose_message(NSC_CONTEXT* context, wStream* s,
BYTE* bmpdata, int width, int height, int rowstride)
UINT32 nsc_compute_byte_count(NSC_CONTEXT* context, UINT32* ByteCount, UINT32 width, UINT32 height)
{
UINT32 tempWidth;
UINT32 tempHeight;
UINT32 maxPlaneSize;
tempWidth = ROUND_UP_TO(width, 8);
tempHeight = ROUND_UP_TO(height, 2);
maxPlaneSize = tempWidth * tempHeight + 16;
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
{
ByteCount[0] = tempWidth * height;
ByteCount[1] = tempWidth * tempHeight / 4;
ByteCount[2] = tempWidth * tempHeight / 4;
ByteCount[3] = width * height;
}
else
{
ByteCount[0] = width * height;
ByteCount[1] = width * height;
ByteCount[2] = width * height;
ByteCount[3] = width * height;
}
return maxPlaneSize;
}
NSC_MESSAGE* nsc_encode_messages(NSC_CONTEXT* context, BYTE* data, int x, int y,
int width, int height, int scanline, int* numMessages, int maxDataSize)
{
int i, j, k;
int dataOffset;
int rows, cols;
int BytesPerPixel;
int MaxRegionWidth;
int MaxRegionHeight;
UINT32 ByteCount[4];
UINT32 MaxPlaneSize;
UINT32 MaxMessageSize;
NSC_MESSAGE* messages;
k = 0;
MaxRegionWidth = 64 * 4;
MaxRegionHeight = 64 * 2;
BytesPerPixel = (context->bpp / 8);
rows = (width + (MaxRegionWidth - (width % MaxRegionWidth))) / MaxRegionWidth;
cols = (height + (MaxRegionHeight - (height % MaxRegionHeight))) / MaxRegionHeight;
*numMessages = rows * cols;
MaxPlaneSize = nsc_compute_byte_count(context, (UINT32*) ByteCount, width, height);
MaxMessageSize = ByteCount[0] + ByteCount[1] + ByteCount[2] + ByteCount[3] + 20;
maxDataSize -= 1024; /* reserve enough space for headers */
messages = (NSC_MESSAGE*) malloc(sizeof(NSC_MESSAGE) * (*numMessages));
ZeroMemory(messages, sizeof(sizeof(NSC_MESSAGE) * (*numMessages)));
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
messages[k].x = x + (i * MaxRegionWidth);
messages[k].y = y + (j * MaxRegionHeight);
messages[k].width = (i < (rows - 1)) ? MaxRegionWidth : width - (i * MaxRegionWidth);
messages[k].height = (j < (cols - 1)) ? MaxRegionHeight : height - (j * MaxRegionHeight);
messages[k].data = data;
messages[k].scanline = scanline;
messages[k].MaxPlaneSize = nsc_compute_byte_count(context,
(UINT32*) messages[k].OrgByteCount, messages[k].width, messages[k].height);
k++;
}
}
*numMessages = k;
for (i = 0; i < *numMessages; i++)
{
messages[i].PlaneBuffers[0] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize);
messages[i].PlaneBuffers[1] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize);
messages[i].PlaneBuffers[2] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize);
messages[i].PlaneBuffers[3] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize);
messages[i].PlaneBuffers[4] = (BYTE*) BufferPool_Take(context->priv->PlanePool, messages[i].MaxPlaneSize);
}
for (i = 0; i < *numMessages; i++)
{
context->width = messages[i].width;
context->height = messages[i].height;
context->OrgByteCount[0] = messages[i].OrgByteCount[0];
context->OrgByteCount[1] = messages[i].OrgByteCount[1];
context->OrgByteCount[2] = messages[i].OrgByteCount[2];
context->OrgByteCount[3] = messages[i].OrgByteCount[3];
context->priv->PlaneBuffersLength = messages[i].MaxPlaneSize;
context->priv->PlaneBuffers[0] = messages[i].PlaneBuffers[0];
context->priv->PlaneBuffers[1] = messages[i].PlaneBuffers[1];
context->priv->PlaneBuffers[2] = messages[i].PlaneBuffers[2];
context->priv->PlaneBuffers[3] = messages[i].PlaneBuffers[3];
context->priv->PlaneBuffers[4] = messages[i].PlaneBuffers[4];
dataOffset = (messages[i].y * messages[i].scanline) + (messages[i].x * BytesPerPixel);
PROFILER_ENTER(context->priv->prof_nsc_encode);
context->encode(context, &data[dataOffset], scanline);
PROFILER_EXIT(context->priv->prof_nsc_encode);
PROFILER_ENTER(context->priv->prof_nsc_rle_compress_data);
nsc_rle_compress_data(context);
PROFILER_EXIT(context->priv->prof_nsc_rle_compress_data);
messages[i].PlaneByteCount[0] = context->nsc_stream.PlaneByteCount[0];
messages[i].PlaneByteCount[1] = context->nsc_stream.PlaneByteCount[1];
messages[i].PlaneByteCount[2] = context->nsc_stream.PlaneByteCount[2];
messages[i].PlaneByteCount[3] = context->nsc_stream.PlaneByteCount[3];
}
context->priv->PlaneBuffers[0] = NULL;
context->priv->PlaneBuffers[1] = NULL;
context->priv->PlaneBuffers[2] = NULL;
context->priv->PlaneBuffers[3] = NULL;
context->priv->PlaneBuffers[4] = NULL;
return messages;
}
int nsc_write_message(NSC_CONTEXT* context, wStream* s, NSC_MESSAGE* message)
{
int i;
Stream_EnsureRemainingCapacity(s, 20);
Stream_Write_UINT32(s, message->PlaneByteCount[0]); /* LumaPlaneByteCount (4 bytes) */
Stream_Write_UINT32(s, message->PlaneByteCount[1]); /* OrangeChromaPlaneByteCount (4 bytes) */
Stream_Write_UINT32(s, message->PlaneByteCount[2]); /* GreenChromaPlaneByteCount (4 bytes) */
Stream_Write_UINT32(s, message->PlaneByteCount[3]); /* AlphaPlaneByteCount (4 bytes) */
Stream_Write_UINT8(s, context->nsc_stream.ColorLossLevel); /* ColorLossLevel (1 byte) */
Stream_Write_UINT8(s, context->nsc_stream.ChromaSubSamplingLevel); /* ChromaSubsamplingLevel (1 byte) */
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
for (i = 0; i < 4; i++)
{
if (message->PlaneByteCount[i] > 0)
{
Stream_EnsureRemainingCapacity(s, (int) message->PlaneByteCount[i]);
Stream_Write(s, message->PlaneBuffers[i], message->PlaneByteCount[i]);
}
}
return 0;
}
int nsc_message_free(NSC_CONTEXT* context, NSC_MESSAGE* message)
{
BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[0]);
BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[1]);
BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[2]);
BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[3]);
BufferPool_Return(context->priv->PlanePool, message->PlaneBuffers[4]);
return 0;
}
void nsc_compose_message(NSC_CONTEXT* context, wStream* s, BYTE* data, int width, int height, int scanline)
{
int i;
@ -340,7 +522,7 @@ void nsc_compose_message(NSC_CONTEXT* context, wStream* s,
/* ARGB to AYCoCg conversion, chroma subsampling and colorloss reduction */
PROFILER_ENTER(context->priv->prof_nsc_encode);
context->encode(context, bmpdata, rowstride);
context->encode(context, data, scanline);
PROFILER_EXIT(context->priv->prof_nsc_encode);
/* RLE encode */
@ -363,7 +545,7 @@ void nsc_compose_message(NSC_CONTEXT* context, wStream* s,
if (context->nsc_stream.PlaneByteCount[i] > 0)
{
Stream_EnsureRemainingCapacity(s, (int) context->nsc_stream.PlaneByteCount[i]);
Stream_Write(s, context->priv->plane_buf[i], context->nsc_stream.PlaneByteCount[i]);
Stream_Write(s, context->priv->PlaneBuffers[i], context->nsc_stream.PlaneByteCount[i]);
}
}
}

View File

@ -28,10 +28,12 @@
#include <xmmintrin.h>
#include <emmintrin.h>
#include <winpr/crt.h>
#include "nsc_types.h"
#include "nsc_sse2.h"
static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* data, int scanline)
{
UINT16 x;
UINT16 y;
@ -56,18 +58,19 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
tempHeight = ROUND_UP_TO(context->height, 2);
rw = (context->nsc_stream.ChromaSubSamplingLevel > 0 ? tempWidth : context->width);
ccl = context->nsc_stream.ColorLossLevel;
yplane = context->priv->plane_buf[0];
coplane = context->priv->plane_buf[1];
cgplane = context->priv->plane_buf[2];
aplane = context->priv->plane_buf[3];
yplane = context->priv->PlaneBuffers[0];
coplane = context->priv->PlaneBuffers[1];
cgplane = context->priv->PlaneBuffers[2];
aplane = context->priv->PlaneBuffers[3];
for (y = 0; y < context->height; y++)
{
src = bmpdata + (context->height - 1 - y) * rowstride;
yplane = context->priv->plane_buf[0] + y * rw;
coplane = context->priv->plane_buf[1] + y * rw;
cgplane = context->priv->plane_buf[2] + y * rw;
aplane = context->priv->plane_buf[3] + y * context->width;
src = data + (context->height - 1 - y) * scanline;
yplane = context->priv->PlaneBuffers[0] + y * rw;
coplane = context->priv->PlaneBuffers[1] + y * rw;
cgplane = context->priv->PlaneBuffers[2] + y * rw;
aplane = context->priv->PlaneBuffers[3] + y * context->width;
for (x = 0; x < context->width; x += 8)
{
switch (context->pixel_format)
@ -79,6 +82,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
a_val = _mm_set_epi16(*(src + 31), *(src + 27), *(src + 23), *(src + 19), *(src + 15), *(src + 11), *(src + 7), *(src + 3));
src += 32;
break;
case RDP_PIXEL_FORMAT_R8G8B8A8:
r_val = _mm_set_epi16(*(src + 28), *(src + 24), *(src + 20), *(src + 16), *(src + 12), *(src + 8), *(src + 4), *src);
g_val = _mm_set_epi16(*(src + 29), *(src + 25), *(src + 21), *(src + 17), *(src + 13), *(src + 9), *(src + 5), *(src + 1));
@ -86,6 +90,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
a_val = _mm_set_epi16(*(src + 31), *(src + 27), *(src + 23), *(src + 19), *(src + 15), *(src + 11), *(src + 7), *(src + 3));
src += 32;
break;
case RDP_PIXEL_FORMAT_B8G8R8:
b_val = _mm_set_epi16(*(src + 21), *(src + 18), *(src + 15), *(src + 12), *(src + 9), *(src + 6), *(src + 3), *src);
g_val = _mm_set_epi16(*(src + 22), *(src + 19), *(src + 16), *(src + 13), *(src + 10), *(src + 7), *(src + 4), *(src + 1));
@ -93,6 +98,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
a_val = _mm_set1_epi16(0xFF);
src += 24;
break;
case RDP_PIXEL_FORMAT_R8G8B8:
r_val = _mm_set_epi16(*(src + 21), *(src + 18), *(src + 15), *(src + 12), *(src + 9), *(src + 6), *(src + 3), *src);
g_val = _mm_set_epi16(*(src + 22), *(src + 19), *(src + 16), *(src + 13), *(src + 10), *(src + 7), *(src + 4), *(src + 1));
@ -100,6 +106,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
a_val = _mm_set1_epi16(0xFF);
src += 24;
break;
case RDP_PIXEL_FORMAT_B5G6R5_LE:
b_val = _mm_set_epi16(
(((*(src + 15)) & 0xF8) | ((*(src + 15)) >> 5)),
@ -131,6 +138,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
a_val = _mm_set1_epi16(0xFF);
src += 16;
break;
case RDP_PIXEL_FORMAT_R5G6B5_LE:
r_val = _mm_set_epi16(
(((*(src + 15)) & 0xF8) | ((*(src + 15)) >> 5)),
@ -162,6 +170,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
a_val = _mm_set1_epi16(0xFF);
src += 16;
break;
case RDP_PIXEL_FORMAT_P4_PLANER:
{
int shift;
@ -206,6 +215,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
}
a_val = _mm_set1_epi16(0xFF);
break;
case RDP_PIXEL_FORMAT_P8:
{
r_val = _mm_set_epi16(
@ -239,6 +249,7 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
}
a_val = _mm_set1_epi16(0xFF);
break;
default:
r_val = g_val = b_val = a_val = _mm_set1_epi16(0);
break;
@ -266,18 +277,20 @@ static void nsc_encode_argb_to_aycocg_sse2(NSC_CONTEXT* context, BYTE* bmpdata,
cgplane += 8;
aplane += 8;
}
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (context->width % 2) == 1)
{
context->priv->plane_buf[0][y * rw + context->width] = context->priv->plane_buf[0][y * rw + context->width - 1];
context->priv->plane_buf[1][y * rw + context->width] = context->priv->plane_buf[1][y * rw + context->width - 1];
context->priv->plane_buf[2][y * rw + context->width] = context->priv->plane_buf[2][y * rw + context->width - 1];
context->priv->PlaneBuffers[0][y * rw + context->width] = context->priv->PlaneBuffers[0][y * rw + context->width - 1];
context->priv->PlaneBuffers[1][y * rw + context->width] = context->priv->PlaneBuffers[1][y * rw + context->width - 1];
context->priv->PlaneBuffers[2][y * rw + context->width] = context->priv->PlaneBuffers[2][y * rw + context->width - 1];
}
}
if (context->nsc_stream.ChromaSubSamplingLevel > 0 && (y % 2) == 1)
{
memcpy(yplane + rw, yplane, rw);
memcpy(coplane + rw, coplane, rw);
memcpy(cgplane + rw, cgplane, rw);
CopyMemory(yplane + rw, yplane, rw);
CopyMemory(coplane + rw, coplane, rw);
CopyMemory(cgplane + rw, cgplane, rw);
}
}
@ -302,12 +315,13 @@ static void nsc_encode_subsampling_sse2(NSC_CONTEXT* context)
for (y = 0; y < tempHeight >> 1; y++)
{
co_dst = context->priv->plane_buf[1] + y * (tempWidth >> 1);
cg_dst = context->priv->plane_buf[2] + y * (tempWidth >> 1);
co_src0 = (INT8*) context->priv->plane_buf[1] + (y << 1) * tempWidth;
co_dst = context->priv->PlaneBuffers[1] + y * (tempWidth >> 1);
cg_dst = context->priv->PlaneBuffers[2] + y * (tempWidth >> 1);
co_src0 = (INT8*) context->priv->PlaneBuffers[1] + (y << 1) * tempWidth;
co_src1 = co_src0 + tempWidth;
cg_src0 = (INT8*) context->priv->plane_buf[2] + (y << 1) * tempWidth;
cg_src0 = (INT8*) context->priv->PlaneBuffers[2] + (y << 1) * tempWidth;
cg_src1 = cg_src0 + tempWidth;
for (x = 0; x < tempWidth >> 1; x += 8)
{
t = _mm_loadu_si128((__m128i*) co_src0);
@ -333,9 +347,10 @@ static void nsc_encode_subsampling_sse2(NSC_CONTEXT* context)
}
}
static void nsc_encode_sse2(NSC_CONTEXT* context, BYTE* bmpdata, int rowstride)
static void nsc_encode_sse2(NSC_CONTEXT* context, BYTE* data, int scanline)
{
nsc_encode_argb_to_aycocg_sse2(context, bmpdata, rowstride);
nsc_encode_argb_to_aycocg_sse2(context, data, scanline);
if (context->nsc_stream.ChromaSubSamplingLevel > 0)
{
nsc_encode_subsampling_sse2(context);

View File

@ -25,6 +25,9 @@
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/collections.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/profiler.h>
@ -33,8 +36,10 @@
struct _NSC_CONTEXT_PRIV
{
BYTE* plane_buf[5]; /* Decompressed Plane Buffers in the respective order */
UINT32 plane_buf_length; /* Lengths of each plane buffer */
wBufferPool* PlanePool;
BYTE* PlaneBuffers[5]; /* Decompressed Plane Buffers in the respective order */
UINT32 PlaneBuffersLength; /* Lengths of each plane buffer */
/* profilers */
PROFILER_DEFINE(prof_nsc_rle_decompress_data);

File diff suppressed because it is too large Load Diff

View File

@ -125,98 +125,29 @@ static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantizatio
/* rfx_decode_ycbcr_to_rgb code now resides in the primitives library. */
struct _RFX_COMPONENT_WORK_PARAM
{
int size;
INT16* buffer;
const BYTE* data;
RFX_CONTEXT* context;
const UINT32* quantization_values;
};
typedef struct _RFX_COMPONENT_WORK_PARAM RFX_COMPONENT_WORK_PARAM;
void CALLBACK rfx_decode_component_work_callback(PTP_CALLBACK_INSTANCE instance, void* context, PTP_WORK work)
{
RFX_COMPONENT_WORK_PARAM* param = (RFX_COMPONENT_WORK_PARAM*) context;
rfx_decode_component(param->context, param->quantization_values, param->data, param->size, param->buffer);
}
/* stride is bytes between rows in the output buffer. */
BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
int y_size, const UINT32* y_quants,
int cb_size, const UINT32* cb_quants,
int cr_size, const UINT32* cr_quants, BYTE* rgb_buffer, int stride)
BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int stride)
{
INT16* pSrcDst[3];
UINT32 *y_quants, *cb_quants, *cr_quants;
static const prim_size_t roi_64x64 = { 64, 64 };
const primitives_t *prims = primitives_get();
PROFILER_ENTER(context->priv->prof_rfx_decode_rgb);
y_quants = context->quants + (tile->quantIdxY * 10);
cb_quants = context->quants + (tile->quantIdxCb * 10);
cr_quants = context->quants + (tile->quantIdxCr * 10);
pSrcDst[0] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* y_r_buffer */
pSrcDst[1] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cb_g_buffer */
pSrcDst[2] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cr_b_buffer */
#if 0
if (context->priv->UseThreads)
{
PTP_WORK work_objects[3];
RFX_COMPONENT_WORK_PARAM params[3];
rfx_decode_component(context, y_quants, tile->YData, tile->YLen, pSrcDst[0]); /* YData */
params[0].context = context;
params[0].quantization_values = y_quants;
params[0].buffer = Stream_Pointer(data_in);
params[0].capacity = y_size;
params[0].buffer = pSrcDst[0];
Stream_Seek(data_in, y_size);
rfx_decode_component(context, cb_quants, tile->CbData, tile->CbLen, pSrcDst[1]); /* CbData */
params[1].context = context;
params[1].quantization_values = cb_quants;
params[1].buffer = Stream_Pointer(data_in);
params[1].capacity = cb_size;
params[1].buffer = pSrcDst[1];
Stream_Seek(data_in, cb_size);
params[2].context = context;
params[2].quantization_values = cr_quants;
params[2].buffer = Stream_Pointer(data_in);
params[2].capacity = cr_size;
params[2].buffer = pSrcDst[2];
Stream_Seek(data_in, cr_size);
work_objects[0] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_decode_component_work_callback,
(void*) &params[0], &context->priv->ThreadPoolEnv);
work_objects[1] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_decode_component_work_callback,
(void*) &params[1], &context->priv->ThreadPoolEnv);
work_objects[2] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_decode_component_work_callback,
(void*) &params[2], &context->priv->ThreadPoolEnv);
SubmitThreadpoolWork(work_objects[0]);
SubmitThreadpoolWork(work_objects[1]);
SubmitThreadpoolWork(work_objects[2]);
WaitForThreadpoolWorkCallbacks(work_objects[0], FALSE);
WaitForThreadpoolWorkCallbacks(work_objects[1], FALSE);
WaitForThreadpoolWorkCallbacks(work_objects[2], FALSE);
}
else
#endif
{
if (Stream_GetRemainingLength(data_in) < y_size + cb_size + cr_size)
{
DEBUG_WARN("rfx_decode_rgb: packet too small for y_size+cb_size+cr_size");
return FALSE;
}
rfx_decode_component(context, y_quants, Stream_Pointer(data_in), y_size, pSrcDst[0]); /* YData */
Stream_Seek(data_in, y_size);
rfx_decode_component(context, cb_quants, Stream_Pointer(data_in), cb_size, pSrcDst[1]); /* CbData */
Stream_Seek(data_in, cb_size);
rfx_decode_component(context, cr_quants, Stream_Pointer(data_in), cr_size, pSrcDst[2]); /* CrData */
Stream_Seek(data_in, cr_size);
}
rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen, pSrcDst[2]); /* CrData */
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);
prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16),

View File

@ -23,11 +23,7 @@
#include <freerdp/codec/rfx.h>
/* stride is bytes between rows in the output buffer. */
BOOL rfx_decode_rgb(RFX_CONTEXT* context, wStream* data_in,
int y_size, const UINT32 * y_quants,
int cb_size, const UINT32 * cb_quants,
int cr_size, const UINT32 * cr_quants, BYTE* rgb_buffer,
int stride);
BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int stride);
#endif /* __RFX_DECODE_H */

View File

@ -174,9 +174,9 @@ static void rfx_encode_format_rgb(const BYTE* rgb_data, int width, int height, i
while (y_exceed > 0)
{
memcpy(r_buf, r_last, 64 * sizeof(INT16));
memcpy(g_buf, g_last, 64 * sizeof(INT16));
memcpy(b_buf, b_last, 64 * sizeof(INT16));
CopyMemory(r_buf, r_last, 64 * sizeof(INT16));
CopyMemory(g_buf, g_last, 64 * sizeof(INT16));
CopyMemory(b_buf, b_last, 64 * sizeof(INT16));
r_buf += 64;
g_buf += 64;
b_buf += 64;
@ -217,14 +217,19 @@ static void rfx_encode_component(RFX_CONTEXT* context, const UINT32* quantizatio
BufferPool_Return(context->priv->BufferPool, dwt_buffer);
}
void rfx_encode_rgb(RFX_CONTEXT* context, const BYTE* rgb_data, int width, int height, int rowstride,
const UINT32* y_quants, const UINT32* cb_quants, const UINT32* cr_quants,
wStream* data_out, int* y_size, int* cb_size, int* cr_size)
void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile)
{
INT16* pSrcDst[3];
int YLen, CbLen, CrLen;
UINT32 *YQuant, *CbQuant, *CrQuant;
primitives_t* prims = primitives_get();
static const prim_size_t roi_64x64 = { 64, 64 };
YLen = CbLen = CrLen = 0;
YQuant = context->quants + (tile->quantIdxY * 10);
CbQuant = context->quants + (tile->quantIdxCb * 10);
CrQuant = context->quants + (tile->quantIdxCr * 10);
pSrcDst[0] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* y_r_buffer */
pSrcDst[1] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cb_g_buffer */
pSrcDst[2] = (INT16*)((BYTE*)BufferPool_Take(context->priv->BufferPool, -1) + 16); /* cr_b_buffer */
@ -232,7 +237,7 @@ void rfx_encode_rgb(RFX_CONTEXT* context, const BYTE* rgb_data, int width, int h
PROFILER_ENTER(context->priv->prof_rfx_encode_rgb);
PROFILER_ENTER(context->priv->prof_rfx_encode_format_rgb);
rfx_encode_format_rgb(rgb_data, width, height, rowstride,
rfx_encode_format_rgb(tile->data, tile->width, tile->height, tile->scanline,
context->pixel_format, context->palette, pSrcDst[0], pSrcDst[1], pSrcDst[2]);
PROFILER_EXIT(context->priv->prof_rfx_encode_format_rgb);
@ -241,22 +246,22 @@ void rfx_encode_rgb(RFX_CONTEXT* context, const BYTE* rgb_data, int width, int h
pSrcDst, 64 * sizeof(INT16), &roi_64x64);
PROFILER_EXIT(context->priv->prof_rfx_rgb_to_ycbcr);
/* Ensure the buffer is reasonably large enough */
Stream_EnsureRemainingCapacity(data_out, 4096);
/**
* We need to clear the buffers as the RLGR encoder expects it to be initialized to zero.
* This allows simplifying and improving the performance of the encoding process.
*/
rfx_encode_component(context, y_quants, pSrcDst[0],
Stream_Pointer(data_out), Stream_GetRemainingLength(data_out), y_size);
Stream_Seek(data_out, *y_size);
ZeroMemory(tile->YData, 4096);
ZeroMemory(tile->CbData, 4096);
ZeroMemory(tile->CrData, 4096);
Stream_EnsureRemainingCapacity(data_out, 4096);
rfx_encode_component(context, cb_quants, pSrcDst[1],
Stream_Pointer(data_out), Stream_GetRemainingLength(data_out), cb_size);
Stream_Seek(data_out, *cb_size);
rfx_encode_component(context, YQuant, pSrcDst[0], tile->YData, 4096, &YLen);
rfx_encode_component(context, CbQuant, pSrcDst[1], tile->CbData, 4096, &CbLen);
rfx_encode_component(context, CrQuant, pSrcDst[2], tile->CrData, 4096, &CrLen);
Stream_EnsureRemainingCapacity(data_out, 4096);
rfx_encode_component(context, cr_quants, pSrcDst[2],
Stream_Pointer(data_out), Stream_GetRemainingLength(data_out), cr_size);
Stream_Seek(data_out, *cr_size);
tile->YLen = (UINT16) YLen;
tile->CbLen = (UINT16) CbLen;
tile->CrLen = (UINT16) CrLen;
PROFILER_EXIT(context->priv->prof_rfx_encode_rgb);

View File

@ -22,9 +22,7 @@
#include <freerdp/codec/rfx.h>
void rfx_encode_rgb(RFX_CONTEXT* context, const BYTE* rgb_data, int width, int height, int rowstride,
const UINT32* y_quants, const UINT32* cb_quants, const UINT32* cr_quants,
wStream* data_out, int* y_size, int* cb_size, int* cr_size);
void rfx_encode_rgb(RFX_CONTEXT* context, RFX_TILE* tile);
#endif

View File

@ -39,7 +39,7 @@
struct _RFX_CONTEXT_PRIV
{
wQueue* TilePool;
wObjectPool* TilePool;
BOOL UseThreads;
DWORD MinThreadCount;
@ -49,7 +49,6 @@ struct _RFX_CONTEXT_PRIV
TP_CALLBACK_ENVIRON ThreadPoolEnv;
wBufferPool* BufferPool;
wStreamPool* EncoderStreamPool;
/* profilers */
PROFILER_DEFINE(prof_rfx_decode_rgb);

View File

@ -178,7 +178,7 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
switch (updateType)
{
case UPDATE_TYPE_BITMAP:
if (!update_read_bitmap(update, s, &update->bitmap_update))
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
return FALSE;
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
break;

View File

@ -234,6 +234,7 @@ static void freerdp_listener_close(freerdp_listener* instance)
for (i = 0; i < listener->num_sockfds; i++)
{
close(listener->sockfds[i]);
CloseHandle(listener->events[i]);
}
listener->num_sockfds = 0;

View File

@ -34,15 +34,13 @@
#include <freerdp/peer.h>
#include <freerdp/codec/bitmap.h>
/*
static const char* const UPDATE_TYPE_STRINGS[] =
const char* const UPDATE_TYPE_STRINGS[] =
{
"Orders",
"Bitmap",
"Palette",
"Synchronize"
};
*/
extern const BYTE PRIMARY_DRAWING_ORDER_FIELD_BYTES[];
@ -68,80 +66,148 @@ BOOL update_recv_orders(rdpUpdate* update, wStream* s)
return TRUE;
}
BOOL update_read_bitmap_data(wStream* s, BITMAP_DATA* bitmap_data)
BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData)
{
if (Stream_GetRemainingLength(s) < 18)
return FALSE;
Stream_Read_UINT16(s, bitmap_data->destLeft);
Stream_Read_UINT16(s, bitmap_data->destTop);
Stream_Read_UINT16(s, bitmap_data->destRight);
Stream_Read_UINT16(s, bitmap_data->destBottom);
Stream_Read_UINT16(s, bitmap_data->width);
Stream_Read_UINT16(s, bitmap_data->height);
Stream_Read_UINT16(s, bitmap_data->bitsPerPixel);
Stream_Read_UINT16(s, bitmap_data->flags);
Stream_Read_UINT16(s, bitmap_data->bitmapLength);
Stream_Read_UINT16(s, bitmapData->destLeft);
Stream_Read_UINT16(s, bitmapData->destTop);
Stream_Read_UINT16(s, bitmapData->destRight);
Stream_Read_UINT16(s, bitmapData->destBottom);
Stream_Read_UINT16(s, bitmapData->width);
Stream_Read_UINT16(s, bitmapData->height);
Stream_Read_UINT16(s, bitmapData->bitsPerPixel);
Stream_Read_UINT16(s, bitmapData->flags);
Stream_Read_UINT16(s, bitmapData->bitmapLength);
if (bitmap_data->flags & BITMAP_COMPRESSION)
if (bitmapData->flags & BITMAP_COMPRESSION)
{
if (!(bitmap_data->flags & NO_BITMAP_COMPRESSION_HDR))
if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))
{
Stream_Read_UINT16(s, bitmap_data->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
Stream_Read_UINT16(s, bitmap_data->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
Stream_Read_UINT16(s, bitmap_data->cbScanWidth); /* cbScanWidth (2 bytes) */
Stream_Read_UINT16(s, bitmap_data->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
bitmap_data->bitmapLength = bitmap_data->cbCompMainBodySize;
Stream_Read_UINT16(s, bitmapData->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
Stream_Read_UINT16(s, bitmapData->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
Stream_Read_UINT16(s, bitmapData->cbScanWidth); /* cbScanWidth (2 bytes) */
Stream_Read_UINT16(s, bitmapData->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
bitmapData->bitmapLength = bitmapData->cbCompMainBodySize;
}
bitmap_data->compressed = TRUE;
Stream_GetPointer(s, bitmap_data->bitmapDataStream);
Stream_Seek(s, bitmap_data->bitmapLength);
bitmapData->compressed = TRUE;
Stream_GetPointer(s, bitmapData->bitmapDataStream);
Stream_Seek(s, bitmapData->bitmapLength);
}
else
{
if (Stream_GetRemainingLength(s) < bitmap_data->bitmapLength)
if (Stream_GetRemainingLength(s) < bitmapData->bitmapLength)
return FALSE;
bitmap_data->compressed = FALSE;
Stream_GetPointer(s, bitmap_data->bitmapDataStream);
Stream_Seek(s, bitmap_data->bitmapLength);
bitmapData->compressed = FALSE;
Stream_GetPointer(s, bitmapData->bitmapDataStream);
Stream_Seek(s, bitmapData->bitmapLength);
}
return TRUE;
}
BOOL update_read_bitmap(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmap_update)
BOOL update_write_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA* bitmapData)
{
Stream_EnsureRemainingCapacity(s, 64 + bitmapData->bitmapLength);
bitmapData->flags = 0;
bitmapData->cbCompFirstRowSize = 0;
if (bitmapData->compressed)
bitmapData->flags |= BITMAP_COMPRESSION;
if (update->context->settings->NoBitmapCompressionHeader)
{
bitmapData->flags |= NO_BITMAP_COMPRESSION_HDR;
bitmapData->cbCompMainBodySize = bitmapData->bitmapLength;
}
Stream_Write_UINT16(s, bitmapData->destLeft);
Stream_Write_UINT16(s, bitmapData->destTop);
Stream_Write_UINT16(s, bitmapData->destRight);
Stream_Write_UINT16(s, bitmapData->destBottom);
Stream_Write_UINT16(s, bitmapData->width);
Stream_Write_UINT16(s, bitmapData->height);
Stream_Write_UINT16(s, bitmapData->bitsPerPixel);
Stream_Write_UINT16(s, bitmapData->flags);
Stream_Write_UINT16(s, bitmapData->bitmapLength);
if (bitmapData->flags & BITMAP_COMPRESSION)
{
if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))
{
Stream_Write_UINT16(s, bitmapData->cbCompFirstRowSize); /* cbCompFirstRowSize (2 bytes) */
Stream_Write_UINT16(s, bitmapData->cbCompMainBodySize); /* cbCompMainBodySize (2 bytes) */
Stream_Write_UINT16(s, bitmapData->cbScanWidth); /* cbScanWidth (2 bytes) */
Stream_Write_UINT16(s, bitmapData->cbUncompressedSize); /* cbUncompressedSize (2 bytes) */
}
Stream_Write(s, bitmapData->bitmapDataStream, bitmapData->bitmapLength);
}
else
{
Stream_Write(s, bitmapData->bitmapDataStream, bitmapData->bitmapLength);
}
return TRUE;
}
BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate)
{
int i;
if (Stream_GetRemainingLength(s) < 2)
return FALSE;
Stream_Read_UINT16(s, bitmap_update->number); /* numberRectangles (2 bytes) */
Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
if (bitmap_update->number > bitmap_update->count)
if (bitmapUpdate->number > bitmapUpdate->count)
{
UINT16 count;
count = bitmap_update->number * 2;
count = bitmapUpdate->number * 2;
bitmap_update->rectangles = (BITMAP_DATA*) realloc(bitmap_update->rectangles,
bitmapUpdate->rectangles = (BITMAP_DATA*) realloc(bitmapUpdate->rectangles,
sizeof(BITMAP_DATA) * count);
memset(&bitmap_update->rectangles[bitmap_update->count], 0,
sizeof(BITMAP_DATA) * (count - bitmap_update->count));
ZeroMemory(&bitmapUpdate->rectangles[bitmapUpdate->count],
sizeof(BITMAP_DATA) * (count - bitmapUpdate->count));
bitmap_update->count = count;
bitmapUpdate->count = count;
}
/* rectangles */
for (i = 0; i < (int) bitmap_update->number; i++)
for (i = 0; i < (int) bitmapUpdate->number; i++)
{
if (!update_read_bitmap_data(s, &bitmap_update->rectangles[i]))
if (!update_read_bitmap_data(update, s, &bitmapUpdate->rectangles[i]))
return FALSE;
}
return TRUE;
}
BOOL update_write_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate)
{
int i;
Stream_EnsureRemainingCapacity(s, 32);
Stream_Write_UINT16(s, UPDATE_TYPE_BITMAP); /* updateType */
Stream_Write_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
/* rectangles */
for (i = 0; i < (int) bitmapUpdate->number; i++)
{
if (!update_write_bitmap_data(update, s, &bitmapUpdate->rectangles[i]))
return FALSE;
}
return TRUE;
}
BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_update)
{
int i;
@ -354,7 +420,7 @@ BOOL update_recv(rdpUpdate* update, wStream* s)
Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */
//fprintf(stderr, "%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
//printf("%s Update Data PDU\n", UPDATE_TYPE_STRINGS[updateType]);
IFCALL(update->BeginPaint, context);
@ -369,7 +435,7 @@ BOOL update_recv(rdpUpdate* update, wStream* s)
break;
case UPDATE_TYPE_BITMAP:
if (!update_read_bitmap(update, s, &update->bitmap_update))
if (!update_read_bitmap_update(update, s, &update->bitmap_update))
return FALSE;
IFCALL(update->BitmapUpdate, context, &update->bitmap_update);
break;
@ -793,6 +859,23 @@ static void update_send_desktop_resize(rdpContext* context)
rdp_server_reactivate(context->rdp);
}
static void update_send_bitmap_update(rdpContext* context, BITMAP_UPDATE* bitmapUpdate)
{
wStream* s;
rdpRdp* rdp = context->rdp;
rdpUpdate* update = context->update;
update_force_flush(context);
s = fastpath_update_pdu_init(rdp->fastpath);
update_write_bitmap_update(update, s, bitmapUpdate);
fastpath_send_update_pdu(rdp->fastpath, FASTPATH_UPDATETYPE_BITMAP, s);
update_force_flush(context);
Stream_Release(s);
}
/**
* Primary Drawing Orders
*/
@ -1423,6 +1506,7 @@ void update_register_server_callbacks(rdpUpdate* update)
update->SetBounds = update_set_bounds;
update->Synchronize = update_send_synchronize;
update->DesktopResize = update_send_desktop_resize;
update->BitmapUpdate = update_send_bitmap_update;
update->SurfaceBits = update_send_surface_bits;
update->SurfaceFrameMarker = update_send_surface_frame_marker;
update->SurfaceCommand = update_send_surface_command;

View File

@ -45,7 +45,7 @@ void update_free_bitmap(BITMAP_UPDATE* bitmap_update);
void update_reset_state(rdpUpdate* update);
void update_post_connect(rdpUpdate* update);
BOOL update_read_bitmap(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmap_update);
BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bitmapUpdate);
BOOL update_read_palette(rdpUpdate* update, wStream* s, PALETTE_UPDATE* palette_update);
BOOL update_recv_play_sound(rdpUpdate* update, wStream* s);
BOOL update_recv_pointer(rdpUpdate* update, wStream* s);

View File

@ -789,10 +789,10 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
message = rfx_process_message(rfx_context,
surface_bits_command->bitmapData, surface_bits_command->bitmapDataLength);
DEBUG_GDI("num_rects %d num_tiles %d", message->num_rects, message->num_tiles);
DEBUG_GDI("num_rects %d num_tiles %d", message->numRects, message->numTiles);
/* blit each tile */
for (i = 0; i < message->num_tiles; i++)
for (i = 0; i < message->numTiles; i++)
{
tx = message->tiles[i]->x + surface_bits_command->destLeft;
ty = message->tiles[i]->y + surface_bits_command->destTop;
@ -805,7 +805,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
#endif
for (j = 0; j < message->num_rects; j++)
for (j = 0; j < message->numRects; j++)
{
gdi_SetClipRgn(gdi->primary->hdc,
surface_bits_command->destLeft + message->rects[j].x,
@ -828,7 +828,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
gdi->image->bitmap->bitsPerPixel = surface_bits_command->bpp;
gdi->image->bitmap->bytesPerPixel = gdi->image->bitmap->bitsPerPixel / 8;
gdi->image->bitmap->data = (BYTE*) realloc(gdi->image->bitmap->data, gdi->image->bitmap->width * gdi->image->bitmap->height * 4);
freerdp_image_flip(nsc_context->bmpdata, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32);
freerdp_image_flip(nsc_context->BitmapData, gdi->image->bitmap->data, gdi->image->bitmap->width, gdi->image->bitmap->height, 32);
gdi_BitBlt(gdi->primary->hdc, surface_bits_command->destLeft, surface_bits_command->destTop, surface_bits_command->width, surface_bits_command->height, gdi->image->hdc, 0, 0, GDI_SRCCOPY);
}
else if (surface_bits_command->codecID == RDP_CODEC_ID_NONE)

View File

@ -119,7 +119,7 @@ void gdi_Bitmap_Decompress(rdpContext* context, rdpBitmap* bitmap,
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)->bmpdata, 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;

View File

@ -138,7 +138,7 @@ void wf_update_encode(wfInfo* wfi)
rfx_compose_message(wfi->rfx_context, wfi->s, &rect, 1,
pDataBits, width, height, stride);
wfi->frame_idx = wfi->rfx_context->frame_idx;
wfi->frame_idx = wfi->rfx_context->frameIdx;
cmd->destLeft = wfi->invalid.left;
cmd->destTop = wfi->invalid.top;

View File

@ -35,12 +35,16 @@ extern "C" {
#endif
typedef void* (*OBJECT_NEW_FN)(void);
typedef void (*OBJECT_INIT_FN)(void* obj);
typedef void (*OBJECT_UNINIT_FN)(void* obj);
typedef void (*OBJECT_FREE_FN)(void* obj);
typedef void (*OBJECT_EQUALS_FN)(void* objA, void* objB);
struct _wObject
{
OBJECT_NEW_FN fnObjectNew;
OBJECT_INIT_FN fnObjectInit;
OBJECT_UNINIT_FN fnObjectUninit;
OBJECT_FREE_FN fnObjectFree;
OBJECT_EQUALS_FN fnObjectEquals;
};
@ -308,18 +312,33 @@ WINPR_API void CountdownEvent_Free(wCountdownEvent* countdown);
/* BufferPool */
struct _wBufferPool
struct _wBufferPoolItem
{
int size;
int capacity;
void** array;
CRITICAL_SECTION lock;
int fixedSize;
void* buffer;
};
typedef struct _wBufferPoolItem wBufferPoolItem;
struct _wBufferPool
{
int defaultSize;
DWORD alignment;
BOOL synchronized;
CRITICAL_SECTION lock;
int aSize;
int aCapacity;
wBufferPoolItem* aArray;
int uSize;
int uCapacity;
wBufferPoolItem* uArray;
};
typedef struct _wBufferPool wBufferPool;
WINPR_API int BufferPool_GetPoolSize(wBufferPool* pool);
WINPR_API int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer);
WINPR_API void* BufferPool_Take(wBufferPool* pool, int bufferSize);
WINPR_API void BufferPool_Return(wBufferPool* pool, void* buffer);
WINPR_API void BufferPool_Clear(wBufferPool* pool);

View File

@ -53,7 +53,7 @@
#endif
#ifndef DECLSPEC_NORETURN
#if (defined(__GNUC__) || defined(_MSC_VER))
#if (defined(__GNUC__) || defined(_MSC_VER) || defined(__clang__))
#define DECLSPEC_NORETURN __declspec(noreturn)
#else
#define DECLSPEC_NORETURN

View File

@ -35,12 +35,12 @@
#include <malloc.h>
#endif
struct _aligned_meminfo {
struct _aligned_meminfo
{
size_t size;
void *base_addr;
void* base_addr;
};
void* _aligned_malloc(size_t size, size_t alignment)
{
return _aligned_offset_malloc(size, alignment, 0);
@ -75,13 +75,13 @@ void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
/* malloc size + alignment to make sure we can align afterwards */
tmpptr = malloc(size + alignment + sizeof(struct _aligned_meminfo));
if (!tmpptr)
return NULL;
memptr = (void *)((((size_t)((PBYTE)tmpptr + alignment + offset + sizeof(struct _aligned_meminfo)) & ~(alignment - 1)) - offset));
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memptr - sizeof(struct _aligned_meminfo))));
ameminfo = (struct _aligned_meminfo*) (((size_t)((PBYTE)memptr - sizeof(struct _aligned_meminfo))));
ameminfo->base_addr = tmpptr;
ameminfo->size = size;
@ -90,8 +90,8 @@ void* _aligned_offset_malloc(size_t size, size_t alignment, size_t offset)
void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, size_t offset)
{
struct _aligned_meminfo *ameminfo;
void *newmem;
void* newmem;
struct _aligned_meminfo* ameminfo;
if (!memblock)
return _aligned_offset_malloc(size, alignment, offset);
@ -101,15 +101,17 @@ void* _aligned_offset_realloc(void* memblock, size_t size, size_t alignment, siz
_aligned_free(memblock);
return NULL;
}
/* The following is not very performant but a simple and working solution */
newmem = _aligned_offset_malloc(size, alignment, offset);
if (!newmem)
return NULL;
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
memcpy(newmem, memblock, ameminfo->size);
ameminfo = (struct _aligned_meminfo*) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
CopyMemory(newmem, memblock, ameminfo->size);
_aligned_free(memblock);
return newmem;
}
@ -125,11 +127,12 @@ size_t _aligned_msize(void* memblock, size_t alignment, size_t offset)
void _aligned_free(void* memblock)
{
struct _aligned_meminfo *ameminfo;
struct _aligned_meminfo* ameminfo;
if (!memblock)
return;
ameminfo = (struct _aligned_meminfo *) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
ameminfo = (struct _aligned_meminfo*) (((size_t)((PBYTE)memblock - sizeof(struct _aligned_meminfo))));
free(ameminfo->base_addr);
}

View File

@ -87,7 +87,7 @@ BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCom
return TRUE;
}
VOID ExitProcess(UINT uExitCode)
DECLSPEC_NORETURN VOID ExitProcess(UINT uExitCode)
{
}

View File

@ -34,35 +34,170 @@
* Methods
*/
void BufferPool_ShiftAvailable(wBufferPool* pool, int index, int count)
{
if (count > 0)
{
if (pool->aSize + count > pool->aCapacity)
{
pool->aCapacity *= 2;
pool->aArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * pool->aCapacity);
}
MoveMemory(&pool->aArray[index + count], &pool->aArray[index], (pool->aSize - index) * sizeof(wBufferPoolItem));
pool->aSize += count;
}
else if (count < 0)
{
MoveMemory(&pool->aArray[index], &pool->aArray[index - count], (pool->aSize - index) * sizeof(wBufferPoolItem));
pool->aSize += count;
}
}
void BufferPool_ShiftUsed(wBufferPool* pool, int index, int count)
{
if (count > 0)
{
if (pool->uSize + count > pool->uCapacity)
{
pool->uCapacity *= 2;
pool->uArray = (wBufferPoolItem*) realloc(pool->uArray, sizeof(wBufferPoolItem) * pool->uCapacity);
}
MoveMemory(&pool->uArray[index + count], &pool->uArray[index], (pool->uSize - index) * sizeof(wBufferPoolItem));
pool->uSize += count;
}
else if (count < 0)
{
MoveMemory(&pool->uArray[index], &pool->uArray[index - count], (pool->uSize - index) * sizeof(wBufferPoolItem));
pool->uSize += count;
}
}
/**
* Get the buffer pool size
*/
int BufferPool_GetPoolSize(wBufferPool* pool)
{
int size;
if (pool->synchronized)
EnterCriticalSection(&pool->lock);
size = pool->uSize;
if (pool->synchronized)
LeaveCriticalSection(&pool->lock);
return size;
}
/**
* Get the size of a pooled buffer
*/
int BufferPool_GetBufferSize(wBufferPool* pool, void* buffer)
{
int size = 0;
int index = 0;
BOOL found = FALSE;
if (pool->synchronized)
EnterCriticalSection(&pool->lock);
for (index = 0; index < pool->uSize; index++)
{
if (pool->uArray[index].buffer == buffer)
{
size = pool->uArray[index].size;
found = TRUE;
break;
}
}
if (pool->synchronized)
LeaveCriticalSection(&pool->lock);
return (found) ? size : -1;
}
/**
* Gets a buffer of at least the specified size from the pool.
*/
void* BufferPool_Take(wBufferPool* pool, int bufferSize)
void* BufferPool_Take(wBufferPool* pool, int size)
{
int index;
int maxSize;
int maxIndex;
int foundIndex;
BOOL found = FALSE;
void* buffer = NULL;
if (pool->synchronized)
EnterCriticalSection(&pool->lock);
if (pool->fixedSize)
{
if (pool->size > 0)
buffer = pool->array[--(pool->size)];
maxSize = 0;
maxIndex = 0;
if (!buffer)
if (size < 1)
size = pool->defaultSize;
for (index = 0; index < pool->aSize; index++)
{
if (pool->aArray[index].size > maxSize)
{
if (pool->alignment)
buffer = _aligned_malloc(pool->fixedSize, pool->alignment);
else
buffer = malloc(pool->fixedSize);
maxIndex = index;
maxSize = pool->aArray[index].size;
}
if (pool->aArray[index].size >= size)
{
foundIndex = index;
found = TRUE;
break;
}
}
if (!found && maxSize)
{
foundIndex = maxIndex;
found = TRUE;
}
if (!found)
{
if (pool->alignment)
buffer = _aligned_malloc(size, pool->alignment);
else
buffer = malloc(size);
}
else
{
fprintf(stderr, "Variable-size BufferPool not yet implemented\n");
buffer = pool->aArray[index].buffer;
if (maxSize < size)
{
if (pool->alignment)
buffer = _aligned_realloc(buffer, size, pool->alignment);
else
buffer = realloc(buffer, size);
}
BufferPool_ShiftAvailable(pool, foundIndex, -1);
}
if (pool->uSize + 1 > pool->uCapacity)
{
pool->uCapacity *= 2;
pool->uArray = (wBufferPoolItem*) realloc(pool->uArray, sizeof(wBufferPoolItem) * pool->uCapacity);
}
pool->uArray[pool->uSize].buffer = buffer;
pool->uArray[pool->uSize].size = size;
(pool->uSize)++;
if (pool->synchronized)
LeaveCriticalSection(&pool->lock);
@ -75,16 +210,40 @@ void* BufferPool_Take(wBufferPool* pool, int bufferSize)
void BufferPool_Return(wBufferPool* pool, void* buffer)
{
int size = 0;
int index = 0;
BOOL found = FALSE;
if (pool->synchronized)
EnterCriticalSection(&pool->lock);
if ((pool->size + 1) >= pool->capacity)
for (index = 0; index < pool->uSize; index++)
{
pool->capacity *= 2;
pool->array = (void**) realloc(pool->array, sizeof(void*) * pool->capacity);
if (pool->uArray[index].buffer == buffer)
{
found = TRUE;
break;
}
}
pool->array[(pool->size)++] = buffer;
if (found)
{
size = pool->uArray[index].size;
BufferPool_ShiftUsed(pool, index, -1);
}
if (size)
{
if ((pool->aSize + 1) >= pool->aCapacity)
{
pool->aCapacity *= 2;
pool->aArray = (wBufferPoolItem*) realloc(pool->aArray, sizeof(wBufferPoolItem) * pool->aCapacity);
}
pool->aArray[pool->aSize].buffer = buffer;
pool->aArray[pool->aSize].size = size;
(pool->aSize)++;
}
if (pool->synchronized)
LeaveCriticalSection(&pool->lock);
@ -99,14 +258,24 @@ void BufferPool_Clear(wBufferPool* pool)
if (pool->synchronized)
EnterCriticalSection(&pool->lock);
while (pool->size > 0)
while (pool->aSize > 0)
{
(pool->size)--;
(pool->aSize)--;
if (pool->alignment)
_aligned_free(pool->array[pool->size]);
_aligned_free(pool->aArray[pool->aSize].buffer);
else
free(pool->array[pool->size]);
free(pool->aArray[pool->aSize].buffer);
}
while (pool->uSize > 0)
{
(pool->uSize)--;
if (pool->alignment)
_aligned_free(pool->uArray[pool->uSize].buffer);
else
free(pool->uArray[pool->uSize].buffer);
}
if (pool->synchronized)
@ -117,7 +286,7 @@ void BufferPool_Clear(wBufferPool* pool)
* Construction, Destruction
*/
wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
wBufferPool* BufferPool_New(BOOL synchronized, int defaultSize, DWORD alignment)
{
wBufferPool* pool = NULL;
@ -125,10 +294,10 @@ wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
if (pool)
{
pool->fixedSize = fixedSize;
pool->defaultSize = defaultSize;
if (pool->fixedSize < 0)
pool->fixedSize = 0;
if (pool->defaultSize < 0)
pool->defaultSize = 0;
pool->alignment = alignment;
pool->synchronized = synchronized;
@ -136,14 +305,13 @@ wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment)
if (pool->synchronized)
InitializeCriticalSectionAndSpinCount(&pool->lock, 4000);
if (!pool->fixedSize)
{
fprintf(stderr, "Variable-size BufferPool not yet implemented\n");
}
pool->aSize = 0;
pool->aCapacity = 32;
pool->aArray = (wBufferPoolItem*) malloc(sizeof(wBufferPoolItem) * pool->aCapacity);
pool->size = 0;
pool->capacity = 32;
pool->array = (void**) malloc(sizeof(void*) * pool->capacity);
pool->uSize = 0;
pool->uCapacity = 32;
pool->uArray = (wBufferPoolItem*) malloc(sizeof(wBufferPoolItem) * pool->uCapacity);
}
return pool;
@ -158,7 +326,8 @@ void BufferPool_Free(wBufferPool* pool)
if (pool->synchronized)
DeleteCriticalSection(&pool->lock);
free(pool->array);
free(pool->aArray);
free(pool->uArray);
free(pool);
}

View File

@ -43,17 +43,23 @@ int ListDictionary_Count(wListDictionary* listDictionary)
int count = 0;
wListDictionaryItem* item;
if (!listDictionary->head)
return 0;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = listDictionary->head;
while (item)
if (listDictionary->head)
{
count++;
item = item->next;
item = listDictionary->head;
while (item)
{
count++;
item = item->next;
}
}
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
return count;
}
@ -97,6 +103,9 @@ void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
wListDictionaryItem* item;
wListDictionaryItem* lastItem;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = (wListDictionaryItem*) malloc(sizeof(wListDictionaryItem));
item->key = key;
@ -107,15 +116,19 @@ void ListDictionary_Add(wListDictionary* listDictionary, void* key, void* value)
if (!listDictionary->head)
{
listDictionary->head = item;
return;
}
else
{
lastItem = listDictionary->head;
while (lastItem->next)
lastItem = lastItem->next;
lastItem->next = item;
}
lastItem = listDictionary->head;
while (lastItem->next)
lastItem = lastItem->next;
lastItem->next = item;
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
}
/**
@ -127,19 +140,25 @@ void ListDictionary_Clear(wListDictionary* listDictionary)
wListDictionaryItem* item;
wListDictionaryItem* nextItem;
if (!listDictionary->head)
return;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = listDictionary->head;
while (item)
if (listDictionary->head)
{
nextItem = item->next;
free(item);
item = nextItem;
item = listDictionary->head;
while (item)
{
nextItem = item->next;
free(item);
item = nextItem;
}
listDictionary->head = NULL;
}
listDictionary->head = NULL;
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
}
/**
@ -148,22 +167,31 @@ void ListDictionary_Clear(wListDictionary* listDictionary)
BOOL ListDictionary_Contains(wListDictionary* listDictionary, void* key)
{
BOOL status = FALSE;
wListDictionaryItem* item;
if (!listDictionary->head)
return FALSE;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = listDictionary->head;
while (item)
if (listDictionary->head)
{
if (item->key == key)
break;
item = listDictionary->head;
item = item->next;
while (item)
{
if (item->key == key)
break;
item = item->next;
}
status = (item) ? TRUE : FALSE;
}
return (item) ? TRUE : FALSE;
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
return status;
}
/**
@ -175,35 +203,42 @@ void ListDictionary_Remove(wListDictionary* listDictionary, void* key)
wListDictionaryItem* item;
wListDictionaryItem* prevItem;
if (!listDictionary->head)
return;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = listDictionary->head;
if (listDictionary->head->key == key)
if (listDictionary->head)
{
listDictionary->head = listDictionary->head->next;
free(item);
return;
}
item = listDictionary->head;
if (!item->next)
return;
prevItem = item;
item = item->next;
while (item)
{
if (item->key == key)
if (listDictionary->head->key == key)
{
prevItem->next = item->next;
listDictionary->head = listDictionary->head->next;
free(item);
break;
}
else
{
if (item->next)
{
prevItem = item;
item = item->next;
item = item->next;
while (item)
{
if (item->key == key)
{
prevItem->next = item->next;
free(item);
break;
}
item = item->next;
}
}
}
}
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
}
/**
@ -212,22 +247,31 @@ void ListDictionary_Remove(wListDictionary* listDictionary, void* key)
void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key)
{
void* value = NULL;
wListDictionaryItem* item;
if (!listDictionary->head)
return NULL;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = listDictionary->head;
while (item)
if (listDictionary->head)
{
if (item->key == key)
break;
item = listDictionary->head;
item = item->next;
while (item)
{
if (item->key == key)
break;
item = item->next;
}
}
return (item) ? item->value : NULL;
value = (item) ? item->value : NULL;
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
return value;
}
/**
@ -236,25 +280,34 @@ void* ListDictionary_GetItemValue(wListDictionary* listDictionary, void* key)
BOOL ListDictionary_SetItemValue(wListDictionary* listDictionary, void* key, void* value)
{
BOOL status = FALSE;
wListDictionaryItem* item;
if (!listDictionary->head)
return FALSE;
if (listDictionary->synchronized)
EnterCriticalSection(&listDictionary->lock);
item = listDictionary->head;
while (item)
if (listDictionary->head)
{
if (item->key == key)
break;
item = listDictionary->head;
item = item->next;
while (item)
{
if (item->key == key)
break;
item = item->next;
}
if (item)
item->value = value;
status = (item) ? TRUE : FALSE;
}
if (item)
item->value = value;
if (listDictionary->synchronized)
LeaveCriticalSection(&listDictionary->lock);
return (item) ? TRUE : FALSE;
return status;
}
/**
@ -272,6 +325,8 @@ wListDictionary* ListDictionary_New(BOOL synchronized)
listDictionary->synchronized = synchronized;
listDictionary->head = NULL;
InitializeCriticalSectionAndSpinCount(&listDictionary->lock, 4000);
}
return listDictionary;
@ -282,6 +337,7 @@ void ListDictionary_Free(wListDictionary* listDictionary)
if (listDictionary)
{
ListDictionary_Clear(listDictionary);
DeleteCriticalSection(&listDictionary->lock);
free(listDictionary);
}
}

View File

@ -54,6 +54,9 @@ void* ObjectPool_Take(wObjectPool* pool)
obj = pool->object.fnObjectNew();
}
if (pool->object.fnObjectInit)
pool->object.fnObjectInit(obj);
if (pool->synchronized)
LeaveCriticalSection(&pool->lock);
@ -77,6 +80,9 @@ void ObjectPool_Return(wObjectPool* pool, void* obj)
pool->array[(pool->size)++] = obj;
if (pool->object.fnObjectUninit)
pool->object.fnObjectUninit(obj);
if (pool->synchronized)
LeaveCriticalSection(&pool->lock);
}

View File

@ -12,6 +12,7 @@ set(${MODULE_PREFIX}_TESTS
TestLinkedList.c
TestListDictionary.c
TestCmdLine.c
TestBufferPool.c
TestStreamPool.c
TestMessageQueue.c
TestMessagePipe.c)

View File

@ -0,0 +1,78 @@
#include <winpr/crt.h>
#include <winpr/stream.h>
#include <winpr/collections.h>
int TestBufferPool(int argc, char* argv[])
{
int PoolSize;
int BufferSize;
int DefaultSize;
wBufferPool* pool;
BYTE* Buffers[10];
DefaultSize = 1234;
pool = BufferPool_New(TRUE, DefaultSize, 16);
Buffers[0] = BufferPool_Take(pool, -1);
Buffers[1] = BufferPool_Take(pool, 0);
Buffers[2] = BufferPool_Take(pool, 2048);
PoolSize = BufferPool_GetPoolSize(pool);
if (PoolSize != 3)
{
printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 3);
return -1;
}
BufferSize = BufferPool_GetBufferSize(pool, Buffers[0]);
if (BufferSize != DefaultSize)
{
printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %d\n", BufferSize, DefaultSize);
return -1;
}
BufferSize = BufferPool_GetBufferSize(pool, Buffers[1]);
if (BufferSize != DefaultSize)
{
printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %d\n", BufferSize, DefaultSize);
return -1;
}
BufferSize = BufferPool_GetBufferSize(pool, Buffers[2]);
if (BufferSize != 2048)
{
printf("BufferPool_GetBufferSize failure: Actual: %d Expected: %d\n", BufferSize, 2048);
return -1;
}
BufferPool_Return(pool, Buffers[1]);
PoolSize = BufferPool_GetPoolSize(pool);
if (PoolSize != 2)
{
printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 2);
return -1;
}
BufferPool_Clear(pool);
PoolSize = BufferPool_GetPoolSize(pool);
if (PoolSize != 0)
{
printf("BufferPool_GetPoolSize failure: Actual: %d Expected: %d\n", PoolSize, 0);
return -1;
}
BufferPool_Free(pool);
return 0;
}

View File

@ -17,7 +17,7 @@ int TestListDictionary(int argc, char* argv[])
char* value;
wListDictionary* list;
list = ListDictionary_New(FALSE);
list = ListDictionary_New(TRUE);
ListDictionary_Add(list, key1, val1);
ListDictionary_Add(list, key2, val2);