Merge pull request #1426 from awakecoding/master
Fragmented RemoteFX & NSCodec Encoding, Core Server-Side Fixes, WinPR Utilities Expansion
This commit is contained in:
commit
763d13db43
@ -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()
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
2
client/X11/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.xml
|
||||
generate_argument_docbook
|
@ -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")
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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*) ¶ms[0], &context->priv->ThreadPoolEnv);
|
||||
work_objects[1] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_decode_component_work_callback,
|
||||
(void*) ¶ms[1], &context->priv->ThreadPoolEnv);
|
||||
work_objects[2] = CreateThreadpoolWork((PTP_WORK_CALLBACK) rfx_decode_component_work_callback,
|
||||
(void*) ¶ms[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),
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ BOOL CreateProcessAsUserW(HANDLE hToken, LPCWSTR lpApplicationName, LPWSTR lpCom
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID ExitProcess(UINT uExitCode)
|
||||
DECLSPEC_NORETURN VOID ExitProcess(UINT uExitCode)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ set(${MODULE_PREFIX}_TESTS
|
||||
TestLinkedList.c
|
||||
TestListDictionary.c
|
||||
TestCmdLine.c
|
||||
TestBufferPool.c
|
||||
TestStreamPool.c
|
||||
TestMessageQueue.c
|
||||
TestMessagePipe.c)
|
||||
|
78
winpr/libwinpr/utils/test/TestBufferPool.c
Normal file
78
winpr/libwinpr/utils/test/TestBufferPool.c
Normal 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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user