Merge pull request #2076 from awakecoding/egfx

MS-RDPEGFX Improvements
This commit is contained in:
Marc-André Moreau 2014-09-05 19:50:25 -04:00
commit 763410a66d
47 changed files with 5884 additions and 1289 deletions

View File

@ -180,31 +180,41 @@ void xf_draw_screen_scaled(xfContext *xfc, int x, int y, int w, int h, BOOL scal
void xf_sw_begin_paint(rdpContext *context)
{
rdpGdi *gdi = context->gdi;
rdpGdi* gdi = context->gdi;
gdi->primary->hdc->hwnd->invalid->null = 1;
gdi->primary->hdc->hwnd->ninvalid = 0;
}
void xf_sw_end_paint(rdpContext *context)
{
rdpGdi *gdi;
int i;
INT32 x, y;
UINT32 w, h;
xfContext *xfc = (xfContext *) context;
gdi = context->gdi;
if(!xfc->remote_app)
int ninvalid;
HGDI_RGN cinvalid;
xfContext* xfc = (xfContext*) context;
rdpGdi* gdi = context->gdi;
x = gdi->primary->hdc->hwnd->invalid->x;
y = gdi->primary->hdc->hwnd->invalid->y;
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
if (!xfc->remote_app)
{
if(!xfc->complex_regions)
if (!xfc->complex_regions)
{
if(gdi->primary->hdc->hwnd->invalid->null)
if (gdi->primary->hdc->hwnd->invalid->null)
return;
x = gdi->primary->hdc->hwnd->invalid->x;
y = gdi->primary->hdc->hwnd->invalid->y;
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
xf_lock_x11(xfc, FALSE);
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
{
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
}
@ -212,27 +222,27 @@ void xf_sw_end_paint(rdpContext *context)
{
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
}
xf_unlock_x11(xfc, FALSE);
}
else
{
int i;
int ninvalid;
HGDI_RGN cinvalid;
if(gdi->primary->hdc->hwnd->ninvalid < 1)
if (gdi->primary->hdc->hwnd->ninvalid < 1)
return;
ninvalid = gdi->primary->hdc->hwnd->ninvalid;
cinvalid = gdi->primary->hdc->hwnd->cinvalid;
xf_lock_x11(xfc, FALSE);
for(i = 0; i < ninvalid; i++)
for (i = 0; i < ninvalid; i++)
{
x = cinvalid[i].x;
y = cinvalid[i].y;
w = cinvalid[i].w;
h = cinvalid[i].h;
//combine xfc->primary with xfc->image
XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h);
if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y))
{
xf_draw_screen_scaled(xfc, x, y, w, h, TRUE);
}
@ -241,20 +251,21 @@ void xf_sw_end_paint(rdpContext *context)
XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y);
}
}
XFlush(xfc->display);
xf_unlock_x11(xfc, FALSE);
}
}
else
{
if(gdi->primary->hdc->hwnd->invalid->null)
if (gdi->primary->hdc->hwnd->invalid->null)
return;
x = gdi->primary->hdc->hwnd->invalid->x;
y = gdi->primary->hdc->hwnd->invalid->y;
w = gdi->primary->hdc->hwnd->invalid->w;
h = gdi->primary->hdc->hwnd->invalid->h;
xf_lock_x11(xfc, FALSE);
xf_rail_paint(xfc, context->rail, x, y, x + w - 1, y + h - 1);
xf_unlock_x11(xfc, FALSE);
}
}
@ -264,12 +275,15 @@ void xf_sw_desktop_resize(rdpContext *context)
rdpSettings *settings;
xfContext *xfc = (xfContext *) context;
settings = xfc->instance->settings;
xf_lock_x11(xfc, TRUE);
if(!xfc->fullscreen)
if (!xfc->fullscreen)
{
rdpGdi *gdi = context->gdi;
gdi_resize(gdi, xfc->width, xfc->height);
if(xfc->image)
if (xfc->image)
{
xfc->image->data = NULL;
XDestroyImage(xfc->image);
@ -277,6 +291,7 @@ void xf_sw_desktop_resize(rdpContext *context)
(char *) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0);
}
}
xf_unlock_x11(xfc, TRUE);
}

View File

@ -949,6 +949,11 @@ void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
DEBUG_WARN( "EllipseCB\n");
}
void xf_gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker)
{
}
void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
{
rdpSettings* settings;
@ -1187,5 +1192,7 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update)
update->SurfaceBits = xf_gdi_surface_bits;
update->SurfaceFrameMarker = xf_gdi_surface_frame_marker;
update->altsec->FrameMarker = xf_gdi_frame_marker;
}

View File

@ -477,20 +477,34 @@ int xf_SurfaceCommand_Alpha(xfContext* xfc, RdpgfxClientContext* context, RDPGFX
int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context, RDPGFX_SURFACE_COMMAND* cmd)
{
int status = 0;
BYTE* DstData = NULL;
int i, j;
int status;
BYTE* DstData;
RFX_RECT* rect;
int nXDst, nYDst;
int nXSrc, nYSrc;
int nWidth, nHeight;
int nbUpdateRects;
xfGfxSurface* surface;
RECTANGLE_16 invalidRect;
REGION16 updateRegion;
RECTANGLE_16 updateRect;
RECTANGLE_16* updateRects;
REGION16 clippingRects;
RECTANGLE_16 clippingRect;
RFX_PROGRESSIVE_TILE* tile;
PROGRESSIVE_BLOCK_REGION* region;
surface = (xfGfxSurface*) context->GetSurfaceData(context, cmd->surfaceId);
if (!surface)
return -1;
progressive_create_surface_context(xfc->progressive, cmd->surfaceId, surface->width, surface->height);
DstData = surface->data;
status = progressive_decompress(xfc->progressive, cmd->data, cmd->length, &DstData,
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height);
PIXEL_FORMAT_XRGB32, surface->scanline, cmd->left, cmd->top, cmd->width, cmd->height, cmd->surfaceId);
if (status < 0)
{
@ -498,19 +512,54 @@ int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context,
return -1;
}
printf("xf_SurfaceCommand_Progressive: status: %d\n", status);
region = &(xfc->progressive->region);
/* fill with blue for now to distinguish from the rest */
region16_init(&clippingRects);
freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
cmd->left, cmd->top, cmd->width, cmd->height, 0x0000FF);
for (i = 0; i < region->numRects; i++)
{
rect = &(region->rects[i]);
invalidRect.left = cmd->left;
invalidRect.top = cmd->top;
invalidRect.right = cmd->right;
invalidRect.bottom = cmd->bottom;
clippingRect.left = cmd->left + rect->x;
clippingRect.top = cmd->top + rect->y;
clippingRect.right = clippingRect.left + rect->width;
clippingRect.bottom = clippingRect.top + rect->height;
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
region16_union_rect(&clippingRects, &clippingRects, &clippingRect);
}
for (i = 0; i < region->numTiles; i++)
{
tile = region->tiles[i];
updateRect.left = cmd->left + tile->x;
updateRect.top = cmd->top + tile->y;
updateRect.right = updateRect.left + 64;
updateRect.bottom = updateRect.top + 64;
region16_init(&updateRegion);
region16_intersect_rect(&updateRegion, &clippingRects, &updateRect);
updateRects = (RECTANGLE_16*) region16_rects(&updateRegion, &nbUpdateRects);
for (j = 0; j < nbUpdateRects; j++)
{
nXDst = updateRects[j].left;
nYDst = updateRects[j].top;
nWidth = updateRects[j].right - updateRects[j].left;
nHeight = updateRects[j].bottom - updateRects[j].top;
nXSrc = nXDst - (cmd->left + tile->x);
nYSrc = nYDst - (cmd->top + tile->y);
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32,
surface->scanline, nXDst, nYDst, nWidth, nHeight,
tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, nXSrc, nYSrc);
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]);
}
region16_uninit(&updateRegion);
}
if (!xfc->inGfxFrame)
xf_OutputUpdate(xfc);
@ -597,6 +646,7 @@ int xf_CreateSurface(RdpgfxClientContext* context, RDPGFX_CREATE_SURFACE_PDU* cr
int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* deleteSurface)
{
xfGfxSurface* surface = NULL;
xfContext* xfc = (xfContext*) context->custom;
surface = (xfGfxSurface*) context->GetSurfaceData(context, deleteSurface->surfaceId);
@ -609,6 +659,8 @@ int xf_DeleteSurface(RdpgfxClientContext* context, RDPGFX_DELETE_SURFACE_PDU* de
context->SetSurfaceData(context, deleteSurface->surfaceId, NULL);
progressive_delete_surface_context(xfc->progressive, deleteSurface->surfaceId);
return 1;
}

View File

@ -389,7 +389,6 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y)
void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor)
{
xfContext* context_ = (xfContext*) context;
xfContext* xfc = (xfContext*) context;
bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(bgcolor, context->settings->ColorDepth, xfc->clrconv);

View File

@ -23,21 +23,22 @@
#include <freerdp/api.h>
#include <freerdp/types.h>
#ifdef WITH_LIBAVCODEC
#ifdef WITH_OPENH264
#undef WITH_OPENH264
#endif
#endif
typedef struct _H264_CONTEXT H264_CONTEXT;
#ifdef WITH_OPENH264
#include "wels/codec_def.h"
#include "wels/codec_api.h"
#endif
typedef BOOL (*pfnH264SubsystemInit)(H264_CONTEXT* h264);
typedef void (*pfnH264SubsystemUninit)(H264_CONTEXT* h264);
#ifdef WITH_LIBAVCODEC
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#endif
typedef int (*pfnH264SubsystemDecompress)(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
struct _H264_CONTEXT_SUBSYSTEM
{
const char* name;
pfnH264SubsystemInit Init;
pfnH264SubsystemUninit Uninit;
pfnH264SubsystemDecompress Decompress;
};
typedef struct _H264_CONTEXT_SUBSYSTEM H264_CONTEXT_SUBSYSTEM;
struct _H264_CONTEXT
{
@ -49,18 +50,9 @@ struct _H264_CONTEXT
UINT32 height;
int scanline;
#ifdef WITH_OPENH264
ISVCDecoder* pDecoder;
#endif
#ifdef WITH_LIBAVCODEC
AVCodec* codec;
AVCodecContext* codecContext;
AVCodecParserContext* codecParser;
AVFrame* videoFrame;
#endif
void* pSystemData;
H264_CONTEXT_SUBSYSTEM* subsystem;
};
typedef struct _H264_CONTEXT H264_CONTEXT;
#ifdef __cplusplus
extern "C" {
@ -71,8 +63,6 @@ FREERDP_API int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize
FREERDP_API int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
FREERDP_API void h264_context_reset(H264_CONTEXT* h264);
FREERDP_API H264_CONTEXT* h264_context_new(BOOL Compressor);
FREERDP_API void h264_context_free(H264_CONTEXT* h264);

View File

@ -23,6 +23,7 @@
#include <freerdp/api.h>
#include <freerdp/types.h>
#include <winpr/wlog.h>
#include <winpr/collections.h>
#include <freerdp/codec/rfx.h>
@ -47,15 +48,6 @@
#define PROGRESSIVE_BLOCKS_REGION 0x0002
#define PROGRESSIVE_BLOCKS_TILE 0x0004
struct _RFX_PROGRESSIVE_CODEC_QUANT
{
BYTE quality;
BYTE yQuantValues[5];
BYTE cbQuantValues[5];
BYTE crQuantValues[5];
};
typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT;
struct _RFX_COMPONENT_CODEC_QUANT
{
BYTE LL3;
@ -71,6 +63,15 @@ struct _RFX_COMPONENT_CODEC_QUANT
};
typedef struct _RFX_COMPONENT_CODEC_QUANT RFX_COMPONENT_CODEC_QUANT;
struct _RFX_PROGRESSIVE_CODEC_QUANT
{
BYTE quality;
RFX_COMPONENT_CODEC_QUANT yQuantValues;
RFX_COMPONENT_CODEC_QUANT cbQuantValues;
RFX_COMPONENT_CODEC_QUANT crQuantValues;
};
typedef struct _RFX_PROGRESSIVE_CODEC_QUANT RFX_PROGRESSIVE_CODEC_QUANT;
struct _PROGRESSIVE_BLOCK
{
UINT16 blockType;
@ -205,6 +206,25 @@ struct _RFX_PROGRESSIVE_TILE
BYTE* cbRawData;
BYTE* crSrlData;
BYTE* crRawData;
int x;
int y;
int width;
int height;
BYTE* data;
BYTE* current;
int pass;
BYTE* sign;
RFX_COMPONENT_CODEC_QUANT yBitPos;
RFX_COMPONENT_CODEC_QUANT cbBitPos;
RFX_COMPONENT_CODEC_QUANT crBitPos;
RFX_COMPONENT_CODEC_QUANT yQuant;
RFX_COMPONENT_CODEC_QUANT cbQuant;
RFX_COMPONENT_CODEC_QUANT crQuant;
RFX_COMPONENT_CODEC_QUANT yProgQuant;
RFX_COMPONENT_CODEC_QUANT cbProgQuant;
RFX_COMPONENT_CODEC_QUANT crProgQuant;
};
typedef struct _RFX_PROGRESSIVE_TILE RFX_PROGRESSIVE_TILE;
@ -223,7 +243,7 @@ struct _PROGRESSIVE_BLOCK_REGION
RFX_RECT* rects;
RFX_COMPONENT_CODEC_QUANT* quantVals;
RFX_PROGRESSIVE_CODEC_QUANT* quantProgVals;
RFX_PROGRESSIVE_TILE* tiles;
RFX_PROGRESSIVE_TILE** tiles;
};
typedef struct _PROGRESSIVE_BLOCK_REGION PROGRESSIVE_BLOCK_REGION;
@ -245,17 +265,30 @@ struct _PROGRESSIVE_BLOCK_FRAME_END
};
typedef struct _PROGRESSIVE_BLOCK_FRAME_END PROGRESSIVE_BLOCK_FRAME_END;
struct _PROGRESSIVE_SURFACE_CONTEXT
{
UINT16 id;
UINT32 width;
UINT32 height;
UINT32 gridWidth;
UINT32 gridHeight;
UINT32 gridSize;
RFX_PROGRESSIVE_TILE* tiles;
};
typedef struct _PROGRESSIVE_SURFACE_CONTEXT PROGRESSIVE_SURFACE_CONTEXT;
struct _PROGRESSIVE_CONTEXT
{
BOOL Compressor;
wLog* log;
wBufferPool* bufferPool;
UINT32 cRects;
RFX_RECT* rects;
UINT32 cTiles;
RFX_PROGRESSIVE_TILE* tiles;
RFX_PROGRESSIVE_TILE** tiles;
UINT32 cQuant;
RFX_COMPONENT_CODEC_QUANT* quantVals;
@ -265,6 +298,8 @@ struct _PROGRESSIVE_CONTEXT
PROGRESSIVE_BLOCK_REGION region;
RFX_PROGRESSIVE_CODEC_QUANT quantProgValFull;
wHashTable* SurfaceContexts;
};
typedef struct _PROGRESSIVE_CONTEXT PROGRESSIVE_CONTEXT;
@ -275,7 +310,10 @@ extern "C" {
FREERDP_API int progressive_compress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize);
FREERDP_API int progressive_decompress(PROGRESSIVE_CONTEXT* progressive, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight);
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight, UINT16 surfaceId);
FREERDP_API int progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, UINT32 height);
FREERDP_API int progressive_delete_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId);
FREERDP_API void progressive_context_reset(PROGRESSIVE_CONTEXT* progressive);

View File

@ -136,6 +136,10 @@ typedef pstatus_t (*__sign_16s_t)(
const INT16 *pSrc,
INT16 *pDst,
INT32 len);
typedef pstatus_t (*__yCbCrToRGB_16s8u_P3AC4R_t)(
const INT16* pSrc[3], INT32 srcStep,
BYTE* pDst, INT32 dstStep,
const prim_size_t* roi);
typedef pstatus_t (*__yCbCrToRGB_16s16s_P3P3_t)(
const INT16 *pSrc[3], INT32 srcStep,
INT16 *pDst[3], INT32 dstStep,
@ -199,6 +203,7 @@ typedef struct
/* Sign */
__sign_16s_t sign_16s;
/* Color conversions */
__yCbCrToRGB_16s8u_P3AC4R_t yCbCrToRGB_16s8u_P3AC4R;
__yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3;
__RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3;
__RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R;

View File

@ -1,35 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Bitmap File Format Utils
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FREERDP_UTILS_BITMAP_H
#define FREERDP_UTILS_BITMAP_H
#include <freerdp/api.h>
#ifdef __cplusplus
extern "C" {
#endif
FREERDP_API void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_UTILS_BITMAP_H */

View File

@ -28,65 +28,17 @@
#include <freerdp/codec/color.h>
#include <freerdp/codec/h264.h>
#define USE_GRAY_SCALE 0
#define USE_UPCONVERT 0
#ifdef WITH_OPENH264
static BYTE clip(int x)
static INLINE BYTE clip(int x)
{
if (x < 0) return 0;
if (x > 255) return 255;
return (BYTE)x;
return (BYTE) x;
}
static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V)
static INLINE UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V)
{
BYTE R, G, B;
#if USE_GRAY_SCALE
/*
* Displays the Y plane as a gray-scale image.
*/
R = Y;
G = Y;
B = Y;
#else
int C, D, E;
#if 0
/*
* Documented colorspace conversion from YUV to RGB.
* See http://msdn.microsoft.com/en-us/library/ms893078.aspx
*/
C = Y - 16;
D = U - 128;
E = V - 128;
R = clip(( 298 * C + 409 * E + 128) >> 8);
G = clip(( 298 * C - 100 * D - 208 * E + 128) >> 8);
B = clip(( 298 * C + 516 * D + 128) >> 8);
#endif
#if 0
/*
* These coefficients produce better results.
* See http://www.microchip.com/forums/m599060.aspx
*/
C = Y;
D = U - 128;
E = V - 128;
R = clip(( 256 * C + 359 * E + 128) >> 8);
G = clip(( 256 * C - 88 * D - 183 * E + 128) >> 8);
B = clip(( 256 * C + 454 * D + 128) >> 8);
#endif
#if 1
/*
* These coefficients produce excellent results.
*/
BYTE R, G, B;
C = Y;
D = U - 128;
@ -95,87 +47,524 @@ static UINT32 YUV_to_RGB(BYTE Y, BYTE U, BYTE V)
R = clip(( 256 * C + 403 * E + 128) >> 8);
G = clip(( 256 * C - 48 * D - 120 * E + 128) >> 8);
B = clip(( 256 * C + 475 * D + 128) >> 8);
#endif
#endif
return RGB32(R, G, B);
}
#endif /* WITH_OPENH264 */
#if USE_UPCONVERT
static BYTE* convert_420_to_444(BYTE* chroma420, int chroma420Width, int chroma420Height, int chroma420Stride)
static int g_H264FrameId = 0;
static BOOL g_H264DumpFrames = FALSE;
static void h264_dump_h264_data(BYTE* data, int size)
{
BYTE *chroma444, *src, *dst;
int chroma444Width;
int chroma444Height;
int i, j;
FILE* fp;
char buf[4096];
chroma444Width = chroma420Width * 2;
chroma444Height = chroma420Height * 2;
chroma444 = (BYTE*) malloc(chroma444Width * chroma444Height);
if (!chroma444)
return NULL;
/* Upconvert in the horizontal direction. */
for (j = 0; j < chroma420Height; j++)
{
src = chroma420 + j * chroma420Stride;
dst = chroma444 + j * chroma444Width;
dst[0] = src[0];
for (i = 1; i < chroma420Width; i++)
{
dst[2*i-1] = (3 * src[i-1] + src[i] + 2) >> 2;
dst[2*i] = (src[i-1] + 3 * src[i] + 2) >> 2;
}
dst[chroma444Width-1] = src[chroma420Width-1];
}
/* Upconvert in the vertical direction (in-place, bottom-up). */
for (i = 0; i < chroma444Width; i++)
{
src = chroma444 + i + (chroma420Height-2) * chroma444Width;
dst = chroma444 + i + (2*(chroma420Height-2)+1) * chroma444Width;
dst[2*chroma444Width] = src[chroma444Width];
for (j = chroma420Height - 2; j >= 0; j--)
{
dst[chroma444Width] = (src[0] + 3 * src[chroma444Width] + 2) >> 2;
dst[0] = (3 * src[0] + src[chroma444Width] + 2) >> 2;
dst -= 2 * chroma444Width;
src -= chroma444Width;
}
}
return chroma444;
sprintf_s(buf, sizeof(buf), "/tmp/wlog/bs_%d.h264", g_H264FrameId);
fp = fopen(buf, "wb");
fwrite(data, 1, size, fp);
fflush(fp);
fclose(fp);
}
void h264_dump_yuv_data(BYTE* yuv[], int width, int height, int stride[])
{
FILE* fp;
BYTE* srcp;
char buf[4096];
int j;
sprintf_s(buf, sizeof(buf), "/tmp/wlog/H264_%d.ppm", g_H264FrameId);
fp = fopen(buf, "wb");
fwrite("P5\n", 1, 3, fp);
sprintf_s(buf, sizeof(buf), "%d %d\n", width, height);
fwrite(buf, 1, strlen(buf), fp);
fwrite("255\n", 1, 4, fp);
srcp = yuv[0];
for (j = 0; j < height; j++)
{
fwrite(srcp, 1, width, fp);
srcp += stride[0];
}
fflush(fp);
fclose(fp);
}
int h264_prepare_rgb_buffer(H264_CONTEXT* h264, int width, int height)
{
UINT32 size;
h264->width = width;
h264->height = height;
h264->scanline = h264->width * 4;
size = h264->scanline * h264->height;
if (size > h264->size)
{
h264->size = size;
h264->data = (BYTE*) realloc(h264->data, h264->size);
memset(h264->data, 0, h264->size);
}
if (!h264->data)
return -1;
return 1;
}
int freerdp_image_copy_yuv420p_to_xrgb(BYTE* pDstData, int nDstStep, int nXDst, int nYDst,
int nWidth, int nHeight, BYTE* pSrcData[3], int nSrcStep[2], int nXSrc, int nYSrc)
{
int x, y;
BYTE* pDstPixel8;
BYTE *pY, *pU, *pV;
int shift = 1;
pY = pSrcData[0] + (nYSrc * nSrcStep[0]) + nXSrc;
pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++)
{
pU = pSrcData[1] + ((nYSrc + y) >> shift) * nSrcStep[1];
pV = pSrcData[2] + ((nYSrc + y) >> shift) * nSrcStep[1];
for (x = 0; x < nWidth; x++)
{
BYTE Y, U, V;
Y = *pY;
U = pU[(nXSrc + x) >> shift];
V = pV[(nXSrc + x) >> shift];
*((UINT32*) pDstPixel8) = YUV_to_RGB(Y, U, V);
pDstPixel8 += 4;
pY++;
}
pDstPixel8 += (nDstStep - (nWidth * 4));
pY += (nSrcStep[0] - nWidth);
}
return 1;
}
/**
* Dummy subsystem
*/
static int dummy_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
return -1;
}
static void dummy_uninit(H264_CONTEXT* h264)
{
}
static BOOL dummy_init(H264_CONTEXT* h264)
{
return TRUE;
}
static H264_CONTEXT_SUBSYSTEM g_Subsystem_dummy =
{
"dummy",
dummy_init,
dummy_uninit,
dummy_decompress
};
/**
* OpenH264 subsystem
*/
#ifdef WITH_OPENH264
#include "wels/codec_def.h"
#include "wels/codec_api.h"
struct _H264_CONTEXT_OPENH264
{
ISVCDecoder* pDecoder;
};
typedef struct _H264_CONTEXT_OPENH264 H264_CONTEXT_OPENH264;
static BOOL g_openh264_trace_enabled = FALSE;
static void openh264_trace_callback(H264_CONTEXT* h264, int level, const char* message)
{
printf("%d - %s\n", level, message);
}
static int openh264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
BYTE* pYUVData[3];
DECODING_STATE state;
SBufferInfo sBufferInfo;
SSysMEMBuffer* pSystemBuffer;
H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData;
if (!sys->pDecoder)
return -1;
/*
* Decompress the image. The RDP host only seems to send I420 format.
*/
pYUVData[0] = NULL;
pYUVData[1] = NULL;
pYUVData[2] = NULL;
ZeroMemory(&sBufferInfo, sizeof(sBufferInfo));
state = (*sys->pDecoder)->DecodeFrame2(
sys->pDecoder,
pSrcData,
SrcSize,
pYUVData,
&sBufferInfo);
/**
* Calling DecodeFrame2 twice apparently works around Openh264 issue #1136:
* https://github.com/cisco/openh264/issues/1136
*
* This is a hack, but it works and it is only necessary for the first frame.
*/
if (sBufferInfo.iBufferStatus != 1)
state = (*sys->pDecoder)->DecodeFrame2(sys->pDecoder, NULL, 0, pYUVData, &sBufferInfo);
pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer;
#if 0
printf("h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]\n",
state, pYUVData[0], pYUVData[1], pYUVData[2], sBufferInfo.iBufferStatus,
pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat,
pSystemBuffer->iStride[0], pSystemBuffer->iStride[1]);
#endif
if (state != 0)
return -1;
if (!pYUVData[0] || !pYUVData[1] || !pYUVData[2])
return -1;
if (sBufferInfo.iBufferStatus != 1)
return -1;
if (pSystemBuffer->iFormat != videoFormatI420)
return -1;
/* Convert I420 (same as IYUV) to XRGB. */
if (g_H264DumpFrames)
{
h264_dump_yuv_data(pYUVData, pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iStride);
}
g_H264FrameId++;
if (h264_prepare_rgb_buffer(h264, pSystemBuffer->iWidth, pSystemBuffer->iHeight) < 0)
return -1;
freerdp_image_copy_yuv420p_to_xrgb(h264->data, h264->scanline, 0, 0,
h264->width, h264->height, pYUVData, pSystemBuffer->iStride, 0, 0);
return 1;
}
static void openh264_uninit(H264_CONTEXT* h264)
{
H264_CONTEXT_OPENH264* sys = (H264_CONTEXT_OPENH264*) h264->pSystemData;
if (sys)
{
if (sys->pDecoder)
{
(*sys->pDecoder)->Uninitialize(sys->pDecoder);
WelsDestroyDecoder(sys->pDecoder);
sys->pDecoder = NULL;
}
free(sys);
h264->pSystemData = NULL;
}
}
static BOOL openh264_init(H264_CONTEXT* h264)
{
long status;
SDecodingParam sDecParam;
H264_CONTEXT_OPENH264* sys;
static int traceLevel = WELS_LOG_DEBUG;
static EVideoFormatType videoFormat = videoFormatI420;
static WelsTraceCallback traceCallback = (WelsTraceCallback) openh264_trace_callback;
sys = (H264_CONTEXT_OPENH264*) calloc(1, sizeof(H264_CONTEXT_OPENH264));
if (!sys)
{
goto EXCEPTION;
}
h264->pSystemData = (void*) sys;
WelsCreateDecoder(&sys->pDecoder);
if (!sys->pDecoder)
{
printf("Failed to create OpenH264 decoder\n");
goto EXCEPTION;
}
ZeroMemory(&sDecParam, sizeof(sDecParam));
sDecParam.iOutputColorFormat = videoFormatI420;
sDecParam.uiEcActiveFlag = 1;
sDecParam.sVideoProperty.eVideoBsType = VIDEO_BITSTREAM_DEFAULT;
status = (*sys->pDecoder)->Initialize(sys->pDecoder, &sDecParam);
if (status != 0)
{
printf("Failed to initialize OpenH264 decoder (status=%ld)\n", status);
goto EXCEPTION;
}
status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat);
if (status != 0)
{
printf("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status);
}
if (g_openh264_trace_enabled)
{
status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_LEVEL, &traceLevel);
if (status != 0)
{
printf("Failed to set trace level option on OpenH264 decoder (status=%ld)\n", status);
}
status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_CALLBACK, &traceCallback);
if (status != 0)
{
printf("Failed to set trace callback option on OpenH264 decoder (status=%ld)\n", status);
}
status = (*sys->pDecoder)->SetOption(sys->pDecoder, DECODER_OPTION_TRACE_CALLBACK_CONTEXT, &h264);
if (status != 0)
{
printf("Failed to set trace callback context option on OpenH264 decoder (status=%ld)\n", status);
}
}
return TRUE;
EXCEPTION:
openh264_uninit(h264);
return FALSE;
}
static H264_CONTEXT_SUBSYSTEM g_Subsystem_OpenH264 =
{
"OpenH264",
openh264_init,
openh264_uninit,
openh264_decompress
};
#endif
/**
* libavcodec subsystem
*/
#ifdef WITH_LIBAVCODEC
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
struct _H264_CONTEXT_LIBAVCODEC
{
AVCodec* codec;
AVCodecContext* codecContext;
AVCodecParserContext* codecParser;
AVFrame* videoFrame;
};
typedef struct _H264_CONTEXT_LIBAVCODEC H264_CONTEXT_LIBAVCODEC;
static int libavcodec_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
int status;
int gotFrame = 0;
AVPacket packet;
H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData;
av_init_packet(&packet);
packet.data = pSrcData;
packet.size = SrcSize;
status = avcodec_decode_video2(sys->codecContext, sys->videoFrame, &gotFrame, &packet);
if (status < 0)
{
printf("Failed to decode video frame (status=%d)\n", status);
return -1;
}
printf("libavcodec_decompress: frame decoded (status=%d, gotFrame=%d, width=%d, height=%d, Y=[%p,%d], U=[%p,%d], V=[%p,%d])\n",
status, gotFrame, sys->videoFrame->width, sys->videoFrame->height,
sys->videoFrame->data[0], sys->videoFrame->linesize[0],
sys->videoFrame->data[1], sys->videoFrame->linesize[1],
sys->videoFrame->data[2], sys->videoFrame->linesize[2]);
fflush(stdout);
if (gotFrame)
{
if (g_H264DumpFrames)
{
h264_dump_yuv_data(sys->videoFrame->data, sys->videoFrame->width, sys->videoFrame->height, sys->videoFrame->linesize);
}
if (h264_prepare_rgb_buffer(h264, sys->videoFrame->width, sys->videoFrame->height) < 0)
return -1;
freerdp_image_copy_yuv420p_to_xrgb(h264->data, h264->scanline, 0, 0,
h264->width, h264->height, sys->videoFrame->data, sys->videoFrame->linesize, 0, 0);
}
return 1;
}
static void libavcodec_uninit(H264_CONTEXT* h264)
{
H264_CONTEXT_LIBAVCODEC* sys = (H264_CONTEXT_LIBAVCODEC*) h264->pSystemData;
if (!sys)
return;
if (sys->videoFrame)
{
av_free(sys->videoFrame);
}
if (sys->codecParser)
{
av_parser_close(sys->codecParser);
}
if (sys->codecContext)
{
avcodec_close(sys->codecContext);
av_free(sys->codecContext);
}
free(sys);
h264->pSystemData = NULL;
}
static BOOL libavcodec_init(H264_CONTEXT* h264)
{
H264_CONTEXT_LIBAVCODEC* sys;
sys = (H264_CONTEXT_LIBAVCODEC*) calloc(1, sizeof(H264_CONTEXT_LIBAVCODEC));
if (!sys)
{
goto EXCEPTION;
}
h264->pSystemData = (void*) sys;
avcodec_register_all();
sys->codec = avcodec_find_decoder(CODEC_ID_H264);
if (!sys->codec)
{
printf("Failed to find libav H.264 codec\n");
goto EXCEPTION;
}
sys->codecContext = avcodec_alloc_context3(sys->codec);
if (!sys->codecContext)
{
printf("Failed to allocate libav codec context\n");
goto EXCEPTION;
}
if (sys->codec->capabilities & CODEC_CAP_TRUNCATED)
{
sys->codecContext->flags |= CODEC_FLAG_TRUNCATED;
}
if (avcodec_open2(sys->codecContext, sys->codec, NULL) < 0)
{
printf("Failed to open libav codec\n");
goto EXCEPTION;
}
sys->codecParser = av_parser_init(CODEC_ID_H264);
if (!sys->codecParser)
{
printf("Failed to initialize libav parser\n");
goto EXCEPTION;
}
sys->videoFrame = avcodec_alloc_frame();
if (!sys->videoFrame)
{
printf("Failed to allocate libav frame\n");
goto EXCEPTION;
}
return TRUE;
EXCEPTION:
libavcodec_uninit(h264);
return FALSE;
}
static H264_CONTEXT_SUBSYSTEM g_Subsystem_libavcodec =
{
"libavcodec",
libavcodec_init,
libavcodec_uninit,
libavcodec_decompress
};
#endif
int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
BYTE** ppDstData, DWORD DstFormat, int nDstStep, int nXDst, int nYDst, int nWidth, int nHeight)
{
#ifdef WITH_OPENH264
DECODING_STATE state;
SBufferInfo sBufferInfo;
SSysMEMBuffer* pSystemBuffer;
UINT32 UncompressedSize;
BYTE* pDstData;
BYTE* pYUVData[3];
BYTE* pY;
BYTE* pU;
BYTE* pV;
int Y, U, V;
int i, j;
UINT32 UncompressedSize;
if (!h264 || !h264->pDecoder)
if (!h264)
return -1;
#if 0
DEBUG_MSG("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, DstFormat=%lx, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n",
pSrcData, SrcSize, *ppDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight);
printf("h264_decompress: pSrcData=%p, SrcSize=%u, pDstData=%p, nDstStep=%d, nXDst=%d, nYDst=%d, nWidth=%d, nHeight=%d)\n",
pSrcData, SrcSize, *ppDstData, nDstStep, nXDst, nYDst, nWidth, nHeight);
#endif
/* Allocate a destination buffer (if needed). */
@ -197,87 +586,13 @@ int h264_decompress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize,
*ppDstData = pDstData;
}
/*
* Decompress the image. The RDP host only seems to send I420 format.
*/
pYUVData[0] = NULL;
pYUVData[1] = NULL;
pYUVData[2] = NULL;
ZeroMemory(&sBufferInfo, sizeof(sBufferInfo));
state = (*h264->pDecoder)->DecodeFrame2(
h264->pDecoder,
pSrcData,
SrcSize,
pYUVData,
&sBufferInfo);
pSystemBuffer = &sBufferInfo.UsrData.sSystemBuffer;
#if 0
DEBUG_MSG("h264_decompress: state=%u, pYUVData=[%p,%p,%p], bufferStatus=%d, width=%d, height=%d, format=%d, stride=[%d,%d]\n",
state, pYUVData[0], pYUVData[1], pYUVData[2], sBufferInfo.iBufferStatus,
pSystemBuffer->iWidth, pSystemBuffer->iHeight, pSystemBuffer->iFormat,
pSystemBuffer->iStride[0], pSystemBuffer->iStride[1]);
#endif
if (state != 0)
return -1;
if (!pYUVData[0] || !pYUVData[1] || !pYUVData[2])
return -1;
if (sBufferInfo.iBufferStatus != 1)
return -1;
if (pSystemBuffer->iFormat != videoFormatI420)
return -1;
/* Convert I420 (same as IYUV) to XRGB. */
pY = pYUVData[0];
pU = pYUVData[1];
pV = pYUVData[2];
#if USE_UPCONVERT
/* Convert 4:2:0 YUV to 4:4:4 YUV. */
pU = convert_420_to_444(pU, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]);
pV = convert_420_to_444(pV, pSystemBuffer->iWidth / 2, pSystemBuffer->iHeight / 2, pSystemBuffer->iStride[1]);
#endif
for (j = 0; j < nHeight; j++)
if (g_H264DumpFrames)
{
BYTE *pXRGB = pDstData + ((nYDst + j) * nDstStep) + (nXDst * 4);
int y = nYDst + j;
for (i = 0; i < nWidth; i++)
{
int x = nXDst + i;
Y = pY[(y * pSystemBuffer->iStride[0]) + x];
#if USE_UPCONVERT
U = pU[(y * pSystemBuffer->iWidth) + x];
V = pV[(y * pSystemBuffer->iWidth) + x];
#else
U = pU[(y/2) * pSystemBuffer->iStride[1] + (x/2)];
V = pV[(y/2) * pSystemBuffer->iStride[1] + (x/2)];
#endif
*(UINT32*)pXRGB = YUV_to_RGB(Y, U, V);
pXRGB += 4;
}
h264_dump_h264_data(pSrcData, SrcSize);
}
#if USE_UPCONVERT
free(pU);
free(pV);
#endif
#endif
return 1;
return h264->subsystem->Decompress(h264, pSrcData, SrcSize,
pDstData, DstFormat, nDstStep, nXDst, nYDst, nWidth, nHeight);
}
int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize)
@ -285,9 +600,25 @@ int h264_compress(H264_CONTEXT* h264, BYTE* pSrcData, UINT32 SrcSize, BYTE** ppD
return 1;
}
void h264_context_reset(H264_CONTEXT* h264)
BOOL h264_context_init(H264_CONTEXT* h264)
{
#ifdef WITH_LIBAVCODEC
if (g_Subsystem_libavcodec.Init(h264))
{
h264->subsystem = &g_Subsystem_libavcodec;
return TRUE;
}
#endif
#ifdef WITH_OPENH264
if (g_Subsystem_OpenH264.Init(h264))
{
h264->subsystem = &g_Subsystem_OpenH264;
return TRUE;
}
#endif
return FALSE;
}
H264_CONTEXT* h264_context_new(BOOL Compressor)
@ -300,69 +631,29 @@ H264_CONTEXT* h264_context_new(BOOL Compressor)
{
h264->Compressor = Compressor;
#ifdef WITH_OPENH264
h264->subsystem = &g_Subsystem_dummy;
if (h264_prepare_rgb_buffer(h264, 256, 256) < 0)
return NULL;
if (!h264_context_init(h264))
{
static EVideoFormatType videoFormat = videoFormatI420;
SDecodingParam sDecParam;
long status;
WelsCreateDecoder(&h264->pDecoder);
if (!h264->pDecoder)
{
DEBUG_MSG("Failed to create OpenH264 decoder\n");
goto EXCEPTION;
}
ZeroMemory(&sDecParam, sizeof(sDecParam));
sDecParam.iOutputColorFormat = videoFormatARGB;
status = (*h264->pDecoder)->Initialize(h264->pDecoder, &sDecParam);
if (status != 0)
{
DEBUG_MSG("Failed to initialize OpenH264 decoder (status=%ld)\n", status);
goto EXCEPTION;
}
status = (*h264->pDecoder)->SetOption(h264->pDecoder, DECODER_OPTION_DATAFORMAT, &videoFormat);
if (status != 0)
{
DEBUG_MSG("Failed to set data format option on OpenH264 decoder (status=%ld)\n", status);
}
free(h264);
return NULL;
}
#endif
h264_context_reset(h264);
}
return h264;
#ifdef WITH_OPENH264
EXCEPTION:
if (h264->pDecoder)
{
WelsDestroyDecoder(h264->pDecoder);
}
#endif
free(h264);
return NULL;
}
void h264_context_free(H264_CONTEXT* h264)
{
if (h264)
{
#ifdef WITH_OPENH264
if (h264->pDecoder)
{
(*h264->pDecoder)->Uninitialize(h264->pDecoder);
WelsDestroyDecoder(h264->pDecoder);
}
#endif
free(h264->data);
h264->subsystem->Uninit(h264);
free(h264);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@
#include "rfx_decode.h"
/* stride is bytes between rows in the output buffer. */
static void rfx_decode_format_rgb(INT16* r_buf, INT16* g_buf, INT16* b_buf,
void rfx_decode_format_rgb(INT16* r_buf, INT16* g_buf, INT16* b_buf,
RDP_PIXEL_FORMAT pixel_format, BYTE* dst_buf, int stride)
{
primitives_t *prims = primitives_get();
@ -146,9 +146,7 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer, int
pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* cr_b_buffer */
rfx_decode_component(context, y_quants, tile->YData, tile->YLen, pSrcDst[0]); /* YData */
rfx_decode_component(context, cb_quants, tile->CbData, tile->CbLen, pSrcDst[1]); /* CbData */
rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen, pSrcDst[2]); /* CrData */
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);

View File

@ -27,23 +27,24 @@
#include "rfx_differential.h"
void rfx_differential_decode(INT16* buffer, int buffer_size)
void rfx_differential_decode(INT16* buffer, int size)
{
INT16* src;
INT16* dst;
INT16* ptr = buffer;
INT16* end = &buffer[size - 1];
for (src = buffer, dst = buffer + 1; buffer_size > 1; src++, dst++, buffer_size--)
while (ptr != end)
{
*dst += *src;
ptr[1] += ptr[0];
ptr++;
}
}
void rfx_differential_encode(INT16* buffer, int buffer_size)
void rfx_differential_encode(INT16* buffer, int size)
{
INT16 n1, n2;
INT16* dst;
for (n1 = *buffer, dst = buffer + 1; buffer_size > 1; dst++, buffer_size--)
for (n1 = *buffer, dst = buffer + 1; size > 1; dst++, size--)
{
n2 = *dst;
*dst -= n1;

View File

@ -22,7 +22,7 @@
#include <freerdp/codec/rfx.h>
void rfx_differential_decode(INT16* buffer, int buffer_size);
void rfx_differential_encode(INT16* buffer, int buffer_size);
void rfx_differential_decode(INT16* buffer, int size);
void rfx_differential_encode(INT16* buffer, int size);
#endif /* __RFX_DIFFERENTIAL_H */

View File

@ -110,9 +110,9 @@ static void rfx_dwt_2d_decode_block(INT16* buffer, INT16* idwt, int subband_widt
void rfx_dwt_2d_decode(INT16* buffer, INT16* dwt_buffer)
{
rfx_dwt_2d_decode_block(buffer + 3840, dwt_buffer, 8);
rfx_dwt_2d_decode_block(buffer + 3072, dwt_buffer, 16);
rfx_dwt_2d_decode_block(buffer, dwt_buffer, 32);
rfx_dwt_2d_decode_block(&buffer[3840], dwt_buffer, 8);
rfx_dwt_2d_decode_block(&buffer[3072], dwt_buffer, 16);
rfx_dwt_2d_decode_block(&buffer[0], dwt_buffer, 32);
}
static void rfx_dwt_2d_encode_block(INT16* buffer, INT16* dwt, int subband_width)
@ -192,7 +192,7 @@ static void rfx_dwt_2d_encode_block(INT16* buffer, INT16* dwt, int subband_width
void rfx_dwt_2d_encode(INT16* buffer, INT16* dwt_buffer)
{
rfx_dwt_2d_encode_block(buffer, dwt_buffer, 32);
rfx_dwt_2d_encode_block(buffer + 3072, dwt_buffer, 16);
rfx_dwt_2d_encode_block(buffer + 3840, dwt_buffer, 8);
rfx_dwt_2d_encode_block(&buffer[0], dwt_buffer, 32);
rfx_dwt_2d_encode_block(&buffer[3072], dwt_buffer, 16);
rfx_dwt_2d_encode_block(&buffer[3840], dwt_buffer, 8);
}

View File

@ -51,21 +51,18 @@ rfx_quantization_decode_block_NEON(INT16 * buffer, const int buffer_size, const
while(buf < buf_end);
}
void
rfx_quantization_decode_NEON(INT16 * buffer, const UINT32 * quantization_values)
void rfx_quantization_decode_NEON(INT16 * buffer, const UINT32 * quantVals)
{
rfx_quantization_decode_block_NEON(buffer, 4096, 5);
rfx_quantization_decode_block_NEON(buffer, 1024, quantization_values[8] - 6); /* HL1 */
rfx_quantization_decode_block_NEON(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
rfx_quantization_decode_block_NEON(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
rfx_quantization_decode_block_NEON(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
rfx_quantization_decode_block_NEON(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
rfx_quantization_decode_block_NEON(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
rfx_quantization_decode_block_NEON(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
rfx_quantization_decode_block_NEON(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
rfx_quantization_decode_block_NEON(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
rfx_quantization_decode_block_NEON(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
rfx_quantization_decode_block_NEON(&buffer[0], 1024, quantVals[8] - 1); /* HL1 */
rfx_quantization_decode_block_NEON(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
rfx_quantization_decode_block_NEON(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
rfx_quantization_decode_block_NEON(&buffer[3072], 256, quantVals[5] - 1); /* HL2 */
rfx_quantization_decode_block_NEON(&buffer[3328], 256, quantVals[4] - 1); /* LH2 */
rfx_quantization_decode_block_NEON(&buffer[3584], 256, quantVals[6] - 1); /* HH2 */
rfx_quantization_decode_block_NEON(&buffer[3840], 64, quantVals[2] - 1); /* HL3 */
rfx_quantization_decode_block_NEON(&buffer[3904], 64, quantVals[1] - 1); /* LH3 */
rfx_quantization_decode_block_NEON(&buffer[3968], 64, quantVals[3] - 1); /* HH3 */
rfx_quantization_decode_block_NEON(&buffer[4032], 64, quantVals[0] - 1); /* LL3 */
}

View File

@ -22,9 +22,28 @@
#endif
#include <freerdp/primitives.h>
#include "rfx_quantization.h"
static void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor)
/*
* Band Offset Dimensions Size
*
* HL1 0 32x32 1024
* LH1 1024 32x32 1024
* HH1 2048 32x32 1024
*
* HL2 3072 16x16 256
* LH2 3328 16x16 256
* HH2 3584 16x16 256
*
* HL3 3840 8x8 64
* LH3 3904 8x8 64
* HH3 3968 8x8 64
*
* LL3 4032 8x8 64
*/
void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor)
{
if (factor == 0)
return;
@ -32,23 +51,20 @@ static void rfx_quantization_decode_block(const primitives_t *prims, INT16* buff
prims->lShiftC_16s(buffer, factor, buffer, buffer_size);
}
void rfx_quantization_decode(INT16* buffer, const UINT32* quantization_values)
void rfx_quantization_decode(INT16* buffer, const UINT32* quantVals)
{
const primitives_t *prims = primitives_get();
const primitives_t* prims = primitives_get();
/* Scale the values so that they are represented as 11.5 fixed-point number */
rfx_quantization_decode_block(prims, buffer, 4096, 5);
rfx_quantization_decode_block(prims, buffer, 1024, quantization_values[8] - 6); /* HL1 */
rfx_quantization_decode_block(prims, buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
rfx_quantization_decode_block(prims, buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
rfx_quantization_decode_block(prims, buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
rfx_quantization_decode_block(prims, buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
rfx_quantization_decode_block(prims, buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
rfx_quantization_decode_block(prims, buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
rfx_quantization_decode_block(prims, buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
rfx_quantization_decode_block(prims, buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
rfx_quantization_decode_block(prims, buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
rfx_quantization_decode_block(prims, &buffer[0], 1024, quantVals[8] - 1); /* HL1 */
rfx_quantization_decode_block(prims, &buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
rfx_quantization_decode_block(prims, &buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
rfx_quantization_decode_block(prims, &buffer[3072], 256, quantVals[5] - 1); /* HL2 */
rfx_quantization_decode_block(prims, &buffer[3328], 256, quantVals[4] - 1); /* LH2 */
rfx_quantization_decode_block(prims, &buffer[3584], 256, quantVals[6] - 1); /* HH2 */
rfx_quantization_decode_block(prims, &buffer[3840], 64, quantVals[2] - 1); /* HL3 */
rfx_quantization_decode_block(prims, &buffer[3904], 64, quantVals[1] - 1); /* LH3 */
rfx_quantization_decode_block(prims, &buffer[3968], 64, quantVals[3] - 1); /* HH3 */
rfx_quantization_decode_block(prims, &buffer[4032], 64, quantVals[0] - 1); /* LL3 */
}
static void rfx_quantization_encode_block(INT16* buffer, int buffer_size, UINT32 factor)

View File

@ -25,4 +25,6 @@
void rfx_quantization_decode(INT16* buffer, const UINT32* quantization_values);
void rfx_quantization_encode(INT16* buffer, const UINT32* quantization_values);
void rfx_quantization_decode_block(const primitives_t *prims, INT16* buffer, int buffer_size, UINT32 factor);
#endif /* __RFX_QUANTIZATION_H */

View File

@ -82,22 +82,20 @@ rfx_quantization_decode_block_sse2(INT16* buffer, const int buffer_size, const U
} while(ptr < buf_end);
}
static void rfx_quantization_decode_sse2(INT16* buffer, const UINT32* quantization_values)
static void rfx_quantization_decode_sse2(INT16* buffer, const UINT32* quantVals)
{
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16));
rfx_quantization_decode_block_sse2(buffer, 4096, 5);
rfx_quantization_decode_block_sse2(buffer, 1024, quantization_values[8] - 6); /* HL1 */
rfx_quantization_decode_block_sse2(buffer + 1024, 1024, quantization_values[7] - 6); /* LH1 */
rfx_quantization_decode_block_sse2(buffer + 2048, 1024, quantization_values[9] - 6); /* HH1 */
rfx_quantization_decode_block_sse2(buffer + 3072, 256, quantization_values[5] - 6); /* HL2 */
rfx_quantization_decode_block_sse2(buffer + 3328, 256, quantization_values[4] - 6); /* LH2 */
rfx_quantization_decode_block_sse2(buffer + 3584, 256, quantization_values[6] - 6); /* HH2 */
rfx_quantization_decode_block_sse2(buffer + 3840, 64, quantization_values[2] - 6); /* HL3 */
rfx_quantization_decode_block_sse2(buffer + 3904, 64, quantization_values[1] - 6); /* LH3 */
rfx_quantization_decode_block_sse2(buffer + 3968, 64, quantization_values[3] - 6); /* HH3 */
rfx_quantization_decode_block_sse2(buffer + 4032, 64, quantization_values[0] - 6); /* LL3 */
rfx_quantization_decode_block_sse2(&buffer[0], 1024, quantVals[8] - 1); /* HL1 */
rfx_quantization_decode_block_sse2(&buffer[1024], 1024, quantVals[7] - 1); /* LH1 */
rfx_quantization_decode_block_sse2(&buffer[2048], 1024, quantVals[9] - 1); /* HH1 */
rfx_quantization_decode_block_sse2(&buffer[3072], 256, quantVals[5] - 1); /* HL2 */
rfx_quantization_decode_block_sse2(&buffer[3328], 256, quantVals[4] - 1); /* LH2 */
rfx_quantization_decode_block_sse2(&buffer[3584], 256, quantVals[6] - 1); /* HH2 */
rfx_quantization_decode_block_sse2(&buffer[3840], 64, quantVals[2] - 1); /* HL3 */
rfx_quantization_decode_block_sse2(&buffer[3904], 64, quantVals[1] - 1); /* LH3 */
rfx_quantization_decode_block_sse2(&buffer[3968], 64, quantVals[3] - 1); /* HH3 */
rfx_quantization_decode_block_sse2(&buffer[4032], 64, quantVals[0] - 1); /* LL3 */
}
static __inline void __attribute__((ATTRIBUTES))
@ -342,9 +340,9 @@ static void rfx_dwt_2d_decode_sse2(INT16* buffer, INT16* dwt_buffer)
{
_mm_prefetch_buffer((char*) buffer, 4096 * sizeof(INT16));
rfx_dwt_2d_decode_block_sse2(buffer + 3840, dwt_buffer, 8);
rfx_dwt_2d_decode_block_sse2(buffer + 3072, dwt_buffer, 16);
rfx_dwt_2d_decode_block_sse2(buffer, dwt_buffer, 32);
rfx_dwt_2d_decode_block_sse2(&buffer[3840], dwt_buffer, 8);
rfx_dwt_2d_decode_block_sse2(&buffer[3072], dwt_buffer, 16);
rfx_dwt_2d_decode_block_sse2(&buffer[0], dwt_buffer, 32);
}
static __inline void __attribute__((ATTRIBUTES))

File diff suppressed because it is too large Load Diff

View File

@ -321,7 +321,7 @@ rdpSettings* freerdp_settings_new(DWORD flags)
settings->DrawGdiPlusEnabled = FALSE;
settings->FrameMarkerCommandEnabled = FALSE;
settings->FrameMarkerCommandEnabled = TRUE;
settings->SurfaceFrameMarkerEnabled = TRUE;
settings->BitmapCacheV3Enabled = FALSE;

View File

@ -164,6 +164,8 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bit
Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */
WLog_Print(update->log, WLOG_DEBUG, "BitmapUpdate: %d", bitmapUpdate->number);
if (bitmapUpdate->number > bitmapUpdate->count)
{
UINT16 count;

View File

@ -26,11 +26,11 @@
#include <stdlib.h>
#include <winpr/crt.h>
#include <winpr/image.h>
#include <freerdp/api.h>
#include <freerdp/freerdp.h>
#include <freerdp/constants.h>
#include <freerdp/utils/bitmap.h>
#include <freerdp/codec/color.h>
#include <freerdp/codec/bitmap.h>
#include <freerdp/codec/rfx.h>
@ -764,6 +764,11 @@ void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb)
DEBUG_WARN( "EllipseCB\n");
}
void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker)
{
}
void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker)
{
DEBUG_GDI("frameId %d frameAction %d",
@ -828,7 +833,7 @@ void gdi_surface_bits(rdpContext* context, SURFACE_BITS_COMMAND* surface_bits_co
#ifdef DUMP_REMOTEFX_TILES
sprintf(tile_bitmap, "/tmp/rfx/tile_%d.bmp", tilenum++);
freerdp_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
winpr_bitmap_write(tile_bitmap, gdi->tile->bitmap->data, 64, 64, 32);
#endif
@ -943,6 +948,8 @@ void gdi_register_update_callbacks(rdpUpdate* update)
update->SurfaceBits = gdi_surface_bits;
update->SurfaceFrameMarker = gdi_surface_frame_marker;
update->altsec->FrameMarker = gdi_frame_marker;
}
void gdi_init_primary(rdpGdi* gdi)

View File

@ -100,6 +100,6 @@ endif()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp")
if(BUILD_TESTING AND ((NOT WIN32) AND (NOT APPLE)))
# add_subdirectory(test)
add_subdirectory(test)
endif()

View File

@ -33,6 +33,64 @@
#endif /* !MINMAX */
/* ------------------------------------------------------------------------- */
pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep,
BYTE* pDst, int dstStep, const prim_size_t* roi)
{
int x, y;
INT16 R, G, B;
double Y, Cb, Cr;
BYTE* pRGB = pDst;
const INT16* pY = pSrc[0];
const INT16* pCb = pSrc[1];
const INT16* pCr = pSrc[2];
int srcPad = (srcStep - (roi->width * 2)) / 2;
int dstPad = (dstStep - (roi->width * 4)) / 4;
for (y = 0; y < roi->height; y++)
{
for (x = 0; x < roi->width; x++)
{
Y = (double) ((*pY++ >> 1) + 2048);
Cb = (double) (*pCb++ >> 1);
Cr = (double) (*pCr++ >> 1);
R = (INT16) (((int) (Y + (1.402524948120117L * Cr) + 8.0L)) >> 4);
G = (INT16) (((int) (Y - (0.3437300026416779L * Cb) - (0.7144010066986084L * Cr) + 8.0L)) >> 4);
B = (INT16) (((int) (Y + (1.769904971122742L * Cb) + 8.0L)) >> 4);
if (R < 0)
R = 0;
else if (R > 255)
R = 255;
if (G < 0)
G = 0;
else if (G > 255)
G = 255;
if (B < 0)
B = 0;
else if (B > 255)
B = 255;
*pRGB++ = (BYTE) B;
*pRGB++ = (BYTE) G;
*pRGB++ = (BYTE) R;
*pRGB++ = 0xFF;
}
pY += srcPad;
pCb += srcPad;
pCr += srcPad;
pRGB += dstPad;
}
return PRIMITIVES_SUCCESS;
}
/* ------------------------------------------------------------------------- */
pstatus_t general_yCbCrToRGB_16s16s_P3P3(
const INT16 *pSrc[3], INT32 srcStep,
INT16 *pDst[3], INT32 dstStep,
@ -217,9 +275,10 @@ pstatus_t general_RGBToRGB_16s8u_P3AC4R(
/* ------------------------------------------------------------------------- */
void primitives_init_colors(primitives_t* prims)
{
prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
prims->yCbCrToRGB_16s8u_P3AC4R = general_yCbCrToRGB_16s8u_P3AC4R;
prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3;
prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3;
prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
primitives_init_colors_opt(prims);
}

View File

@ -22,6 +22,7 @@
#ifndef __PRIM_COLORS_H_INCLUDED__
#define __PRIM_COLORS_H_INCLUDED__
pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(const INT16* pSrc[3], int srcStep, BYTE* pDst, int dstStep, const prim_size_t* roi);
pstatus_t general_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi);
pstatus_t general_RGBToYCbCr_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi);
pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi);

View File

@ -1,2 +1,3 @@
prim_test
TestPrimitives.c

View File

@ -1,155 +1,50 @@
# FreeRDP: A Remote Desktop Protocol Client
# primitives test makefile builder
# vi:ts=4 sw=4:
#
# (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing permissions
# and limitations under the License.
#
# TODO: Integrate this into the testing framework, in some form.
# Right now this produces a standalone test that covers both functionality
# and performance of the primitives library entrypoints.
set(MODULE_NAME "TestPrimitives")
set(MODULE_PREFIX "TEST_FREERDP_PRIMITIVES")
cmake_minimum_required(VERSION 2.8)
set(MODULE_NAME "prim_test")
set(MODULE_PREFIX "PRIMITIVES_LIBRARY_TEST")
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(PRIMITIVE_TEST_CFILES
set(${MODULE_PREFIX}_TESTS
TestPrimitives16to32bpp.c
TestPrimitivesAdd.c
TestPrimitivesAlphaComp.c
TestPrimitivesAndOr.c
TestPrimitivesColors.c
TestPrimitivesCopy.c
TestPrimitivesSet.c
TestPrimitivesShift.c
TestPrimitivesSign.c
TestPrimitivesYCbCr.c
TestPrimitivesYCoCg.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
set(${MODULE_PREFIX}_EXTRA_SRCS
prim_test.c
test_16to32bpp.c
test_add.c
test_alphaComp.c
test_andor.c
test_colors.c
test_copy.c
test_set.c
test_shift.c
test_sign.c
test_YCoCg.c
../prim_16to32bpp.c
../prim_add.c
../prim_andor.c
../prim_alphaComp.c
../prim_colors.c
../prim_copy.c
../prim_set.c
../prim_shift.c
../prim_sign.c
../prim_YCoCg.c
../prim_16to32bpp_opt.c
../prim_add_opt.c
../prim_alphaComp_opt.c
../prim_andor_opt.c
../prim_colors_opt.c
../prim_set_opt.c
../prim_shift_opt.c
../prim_sign_opt.c
../prim_YCoCg_opt.c
../primitives.c
)
set(PRIMITIVE_TEST_HEADERS
measure.h
prim_test.h
../prim_internal.h
)
measure.h)
set(PRIMITIVE_TEST_SRCS
${PRIMITIVE_TEST_CFILES}
${PRIMITIVE_TEST_HEADERS}
)
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_EXTRA_SRCS})
include_directories(. ../../.. ../../../include ../../../winpr/include)
add_definitions(-DPRIM_STATIC=auto -DALL_PRIMITIVES_VERSIONS -DHAVE_CONFIG_H)
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE freerdp
MODULES freerdp-primitives)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} winpr)
# If these haven't been set by the caller, set them now to defaults.
if(NOT DEFINED WITH_IPP)
set(WITH_IPP FALSE)
endif()
if(NOT DEFINED WITH_SSE2)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*")
set(WITH_SSE2 FALSE)
else()
set(WITH_SSE2 TRUE)
endif()
endif()
if(NOT DEFINED WITH_NEON)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "arm*")
set(WITH_NEON TRUE)
else()
set(WITH_NEON FALSE)
endif()
endif()
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
if(WITH_SSE2)
if(CMAKE_COMPILER_IS_GNUCC)
set(OPTFLAGS "${OPTFLAGS} -msse2 -mssse3 -O2 -Wdeclaration-after-statement")
endif()
add_definitions(-DPRIM_STATIC=auto -DALL_PRIMITIVES_VERSIONS)
if(MSVC)
set(OPTFLAGS "${OPTFLAGS} /arch:SSE2")
endif()
elseif(WITH_NEON)
if(CMAKE_COMPILER_IS_GNUCC)
set(OPTFLAGS "${OPTFLAGS} -mfpu=neon -mfloat-abi=${ARM_FP_ABI} -O2")
endif()
# TODO: Add MSVC equivalent
endif()
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
add_executable(prim_test ${PRIMITIVE_TEST_SRCS})
if(WITH_IPP)
if(NOT DEFINED IPP_FOUND)
include(../../../cmake/FindIPP.cmake)
endif()
# IPP PATH debugging messages
message(IPP_FOUND=${IPP_FOUND})
message(IPP_VERSION_STR=${IPP_VERSION_STR})
message(IPP_VERSION_MAJOR=${IPP_VERSION_MAJOR})
message(IPP_VERSION_MINOR=${IPP_VERSION_MINOR})
message(IPP_VERSION_BUILD=${IPP_VERSION_BUILD})
message(IPP_ROOT_DIR=${IPP_ROOT_DIR})
message(IPP_INCLUDE_DIRS=${IPP_INCLUDE_DIRS})
message(IPP_LIBRARY_DIRS=${IPP_LIBRARY_DIRS})
message(IPP_LIBRARIES=${IPP_LIBRARIES})
message(IPP_COMPILER_LIBRARY_DIRS=${IPP_COMPILER_LIBRARY_DIRS})
message(IPP_COMPILER_LIBRARIES=${IPP_COMPILER_LIBRARIES})
message(IPP_LIBRARY_LIST=${IPP_LIBRARY_LIST})
message(IPP_LIB_PREFIX=${IPP_LIB_PREFIX})
message(IPP_LIB_SUFFIX=${IPP_LIB_SUFFIX})
message(IPP_PREFIX=${IPP_PREFIX})
message(IPP_SUFFIX=${IPP_SUFFIX})
message(IPPCORE=${IPPCORE})
message(IPPS=${IPPS})
message(IPPI=${IPPI})
message(IPPCC=${IPPCC})
message(IPPCV=${IPPCV})
message(IPPVM=${IPPVM})
if(CMAKE_COMPILER_IS_GNUCC)
foreach(INCLDIR ${IPP_INCLUDE_DIRS})
set(OPTFLAGS "${OPTFLAGS} -I${INCLDIR}")
endforeach(INCLDIR)
endif()
target_link_libraries(prim_test ${IPP_LIBRARY_LIST})
endif()
set_property(SOURCE ${PRIMITIVE_TEST_CFILES} PROPERTY COMPILE_FLAGS ${OPTFLAGS})
find_library(WINPR_SYSINFO NAMES winpr-sysinfo HINTS ../../../winpr/libwinpr/sysinfo)
target_link_libraries(prim_test rt ${WINPR_SYSINFO})
if(NOT TESTING_OUTPUT_DIRECTORY)
set(TESTING_OUTPUT_DIRECTORY .)
endif()
add_test(prim_test ${TESTING_OUTPUT_DIRECTORY}/prim_test functionality)
foreach(test ${${MODULE_PREFIX}_TESTS})
get_filename_component(TestName ${test} NAME_WE)
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
endforeach()
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/Test")

View File

@ -28,6 +28,8 @@
static const int RGB_TRIAL_ITERATIONS = 1000;
static const float TEST_TIME = 4.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_RGB565ToARGB_16u32u_C3C4(
const UINT16* pSrc, INT32 srcStep,
UINT32* pDst, INT32 dstStep,
@ -134,7 +136,7 @@ static BOOL try_16To32(
/* ------------------------------------------------------------------------- */
int test_RGB565ToARGB_16u32u_C3C4_func(void)
{
INT16 ALIGN(data16[4096+3]);
UINT16 ALIGN(data16[4096+3]);
BOOL success;
success = TRUE;
@ -176,7 +178,6 @@ int test_RGB565ToARGB_16u32u_C3C4_speed(void)
{
UINT16 ALIGN(src[4096]);
UINT32 ALIGN(dst[4096]);
int i;
int size_array[] = { 64 };
get_random_data(src, sizeof(src));
@ -186,3 +187,23 @@ int test_RGB565ToARGB_16u32u_C3C4_speed(void)
size_array, 1, RGB_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitives16to32bpp(int argc, char* argv[])
{
int status;
status = test_RGB565ToARGB_16u32u_C3C4_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_RGB565ToARGB_16u32u_C3C4_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -23,6 +23,8 @@
static const int ADD16S_PRETEST_ITERATIONS = 300000*64;
static const int TEST_TIME = 2.0; // seconds
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_add_16s(
const INT16 *pSrc1, const INT16 *pSrc2, INT16 *pDst, int len);
extern pstatus_t sse3_add_16s(
@ -112,3 +114,23 @@ int test_add16s_speed(void)
test_sizes, NUM_TEST_SIZES, ADD16S_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesAdd(int argc, char* argv[])
{
int status;
status = test_add16s_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_add16s_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -22,6 +22,8 @@
static const int ALPHA_PRETEST_ITERATIONS = 5000000;
static const float TEST_TIME = 5.0;
extern BOOL g_TestPrimitivesPerformance;
static const int block_size[] = { 4, 64, 256 };
#define NUM_BLOCK_SIZES (sizeof(block_size)/sizeof(int))
#define MAX_BLOCK_SIZE 256
@ -233,3 +235,23 @@ int test_alphaComp_speed(void)
return SUCCESS;
}
int TestPrimitivesAlphaComp(int argc, char* argv[])
{
int status;
status = test_alphaComp_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_alphaComp_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -23,6 +23,8 @@
static const int ANDOR_PRETEST_ITERATIONS = 100000;
static const int TEST_TIME = 2.0; // seconds
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_andC_32u(const UINT32 *pSrc, UINT32 val,
UINT32 *pDst, int len);
extern pstatus_t sse3_andC_32u(const UINT32 *pSrc, UINT32 val,
@ -185,3 +187,36 @@ int test_or_32u_speed(void)
test_sizes, NUM_TEST_SIZES, ANDOR_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesAndOr(int argc, char* argv[])
{
int status;
status = test_and_32u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_and_32u_speed();
if (status != SUCCESS)
return 1;
}
status = test_or_32u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_or_32u_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -23,6 +23,8 @@ static const int RGB_TRIAL_ITERATIONS = 1000;
static const int YCBCR_TRIAL_ITERATIONS = 1000;
static const float TEST_TIME = 4.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3],
int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi);
extern pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3],
@ -241,3 +243,36 @@ int test_yCbCrToRGB_16s16s_P3P3_speed(void)
size_array, 1, YCBCR_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesColors(int argc, char* argv[])
{
int status;
status = test_RGBToRGB_16s8u_P3AC4R_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_RGBToRGB_16s8u_P3AC4R_speed();
if (status != SUCCESS)
return 1;
}
status = test_yCbCrToRGB_16s16s_P3P3_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_yCbCrToRGB_16s16s_P3P3_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -26,6 +26,8 @@ static const int TEST_TIME = 1.0; // seconds
extern pstatus_t sse3_copy_8u(const BYTE *pSrc, BYTE *pDst, int len);
#endif
extern BOOL g_TestPrimitivesPerformance;
/* ------------------------------------------------------------------------- */
int test_copy8u_func(void)
{
@ -84,3 +86,23 @@ int test_copy8u_speed(void)
test_sizes, NUM_TEST_SIZES, MEMCPY_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesCopy(int argc, char* argv[])
{
int status;
status = test_copy8u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_copy8u_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -23,6 +23,8 @@ static const int MEMSET8_PRETEST_ITERATIONS = 100000000;
static const int MEMSET32_PRETEST_ITERATIONS = 40000000;
static const float TEST_TIME = 1.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_set_8u(BYTE val, BYTE *pDst, int len);
extern pstatus_t sse2_set_8u(BYTE val, BYTE *pDst, int len);
extern pstatus_t general_set_32s(INT32 val, INT32 *pDst, int len);
@ -303,3 +305,49 @@ int test_set32s_speed(void)
#endif
return SUCCESS;
}
int TestPrimitivesSet(int argc, char* argv[])
{
int status;
status = test_set8u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_set8u_speed();
if (status != SUCCESS)
return 1;
}
status = test_set32s_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_set32s_speed();
if (status != SUCCESS)
return 1;
}
status = test_set32u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_set32u_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -23,6 +23,8 @@
static const int SHIFT_PRETEST_ITERATIONS = 50000;
static const float TEST_TIME = 1.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_lShiftC_16s(
const INT16 *pSrc, int val, INT16 *pDst, int len);
extern pstatus_t general_rShiftC_16s(
@ -187,3 +189,62 @@ int test_rShift_16u_speed(void)
test_sizes, NUM_TEST_SIZES, SHIFT_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesShift(int argc, char* argv[])
{
int status;
status = test_lShift_16s_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_lShift_16s_speed();
if (status != SUCCESS)
return 1;
}
status = test_lShift_16u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_lShift_16u_speed();
if (status != SUCCESS)
return 1;
}
status = test_rShift_16s_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_rShift_16s_speed();
if (status != SUCCESS)
return 1;
}
status = test_rShift_16u_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_rShift_16u_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -22,6 +22,8 @@
static const int SIGN_PRETEST_ITERATIONS = 100000;
static const float TEST_TIME = 1.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, int len);
#ifdef WITH_SSE2
extern pstatus_t ssse3_sign_16s(const INT16 *pSrc, INT16 *pDst, int len);
@ -101,3 +103,23 @@ int test_sign16s_speed(void)
test_sizes, NUM_TEST_SIZES, SIGN_PRETEST_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesSign(int argc, char* argv[])
{
int status;
status = test_sign16s_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_sign16s_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,8 @@
static const int YCOCG_TRIAL_ITERATIONS = 20000;
static const float TEST_TIME = 4.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_YCoCgRToRGB_8u_AC4R(const BYTE *pSrc, INT32 srcStep,
BYTE *pDst, INT32 dstStep, UINT32 width, UINT32 height,
UINT8 shift, BOOL withAlpha, BOOL invert);
@ -97,7 +99,6 @@ int test_YCoCgRToRGB_8u_AC4R_speed(void)
{
INT32 ALIGN(in[4096]);
INT32 ALIGN(out[4096]);
int i;
int size_array[] = { 64 };
get_random_data(in, sizeof(in));
@ -107,3 +108,23 @@ int test_YCoCgRToRGB_8u_AC4R_speed(void)
size_array, 1, YCOCG_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitivesYCoCg(int argc, char* argv[])
{
int status;
status = test_YCoCgRToRGB_8u_AC4R_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_YCoCgRToRGB_8u_AC4R_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}

View File

@ -18,108 +18,22 @@
#include "prim_test.h"
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <winpr/platform.h>
#include <winpr/sysinfo.h>
#include <winpr/platform.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <time.h>
BOOL g_TestPrimitivesPerformance = FALSE;
int test_sizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
int Quiet = 0;
/* ------------------------------------------------------------------------- */
typedef struct
{
UINT32 flag;
const char *str;
} flagpair_t;
static const flagpair_t flags[] =
{
#ifdef _M_IX86_AMD64
{ PF_MMX_INSTRUCTIONS_AVAILABLE, "MMX" },
{ PF_3DNOW_INSTRUCTIONS_AVAILABLE, "3DNow" },
{ PF_SSE_INSTRUCTIONS_AVAILABLE, "SSE" },
{ PF_SSE2_INSTRUCTIONS_AVAILABLE, "SSE2" },
{ PF_SSE3_INSTRUCTIONS_AVAILABLE, "SSE3" },
#elif defined(_M_ARM)
{ PF_ARM_VFP3, "VFP3" },
{ PF_ARM_INTEL_WMMX, "IWMMXT" },
{ PF_ARM_NEON_INSTRUCTIONS_AVAILABLE, "NEON" },
#endif
};
static const flagpair_t flags_extended[] =
{
#ifdef _M_IX86_AMD64
{ PF_EX_3DNOW_PREFETCH, "3DNow-PF" },
{ PF_EX_SSSE3, "SSSE3" },
{ PF_EX_SSE41, "SSE4.1" },
{ PF_EX_SSE42, "SSE4.2" },
{ PF_EX_AVX, "AVX" },
{ PF_EX_FMA, "FMA" },
{ PF_EX_AVX_AES, "AVX-AES" },
{ PF_EX_AVX2, "AVX2" },
#elif defined(_M_ARM)
{ PF_EX_ARM_VFP1, "VFP1"},
{ PF_EX_ARM_VFP4, "VFP4" },
#endif
};
void primitives_flags_str(char* str, size_t len)
{
int i;
*str = '\0';
--len; /* for the '/0' */
for (i = 0; i < sizeof(flags) / sizeof(flagpair_t); ++i)
{
if (IsProcessorFeaturePresent(flags[i].flag))
{
int slen = strlen(flags[i].str) + 1;
if (len < slen)
break;
if (*str != '\0')
strcat(str, " ");
strcat(str, flags[i].str);
len -= slen;
}
}
for (i = 0; i < sizeof(flags_extended) / sizeof(flagpair_t); ++i)
{
if (IsProcessorFeaturePresentEx(flags_extended[i].flag))
{
int slen = strlen(flags_extended[i].str) + 1;
if (len < slen)
break;
if (*str != '\0')
strcat(str, " ");
strcat(str, flags_extended[i].str);
len -= slen;
}
}
}
/* ------------------------------------------------------------------------- */
static void get_random_data_lrand(
void *buffer,
size_t size)
static void get_random_data_lrand(void *buffer, size_t size)
{
static int seeded = 0;
long int *ptr = (long int *) buffer;
@ -145,11 +59,9 @@ static void get_random_data_lrand(
}
/* ------------------------------------------------------------------------- */
void get_random_data(
void *buffer,
size_t size)
void get_random_data(void *buffer, size_t size)
{
#ifdef linux
#ifdef __linux__
size_t offset = 0;
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0)
@ -171,373 +83,39 @@ void get_random_data(
}
/* ------------------------------------------------------------------------- */
float _delta_time(
const struct timespec *t0,
const struct timespec *t1)
float _delta_time(const struct timespec *t0, const struct timespec *t1)
{
INT64 secs = (INT64) (t1->tv_sec) - (INT64) (t0->tv_sec);
long nsecs = t1->tv_nsec - t0->tv_nsec;
INT64 secs = (INT64) (t1->tv_sec) - (INT64) (t0->tv_sec);
long nsecs = t1->tv_nsec - t0->tv_nsec;
double retval;
if (nsecs < 0)
if (nsecs < 0)
{
--secs;
nsecs += 1000000000;
}
retval = (double) secs + (double) nsecs / (double) 1000000000.0;
return (retval < 0.0) ? 0.0 : (float) retval;
--secs;
nsecs += 1000000000;
}
retval = (double) secs + (double) nsecs / (double) 1000000000.0;
return (retval < 0.0) ? 0.0 : (float) retval;
}
/* ------------------------------------------------------------------------- */
void _floatprint(
float t,
char *output)
void _floatprint(float t, char *output)
{
/* I don't want to link against -lm, so avoid log,exp,... */
float f = 10.0;
/* I don't want to link against -lm, so avoid log,exp,... */
float f = 10.0;
int i;
while (t > f) f *= 10.0;
f /= 1000.0;
i = ((int) (t/f+0.5)) * (int) f;
if (t < 0.0) sprintf(output, "%f", t);
else if (i == 0) sprintf(output, "%d", (int) (t+0.5));
else if (t < 1e+3) sprintf(output, "%3d", i);
else if (t < 1e+6) sprintf(output, "%3d,%03d",
i/1000, i % 1000);
else if (t < 1e+9) sprintf(output, "%3d,%03d,000",
i/1000000, (i % 1000000) / 1000);
else if (t < 1e+12) sprintf(output, "%3d,%03d,000,000",
i/1000000000, (i % 1000000000) / 1000000);
else sprintf(output, "%f", t);
}
/* ------------------------------------------------------------------------- */
/* Specific areas to test: */
#define TEST_COPY8 (1<<0)
#define TEST_SET8 (1<<1)
#define TEST_SET32S (1<<2)
#define TEST_SET32U (1<<3)
#define TEST_SIGN16S (1<<4)
#define TEST_ADD16S (1<<5)
#define TEST_LSHIFT16S (1<<6)
#define TEST_LSHIFT16U (1<<7)
#define TEST_RSHIFT16S (1<<8)
#define TEST_RSHIFT16U (1<<9)
#define TEST_RGB (1<<10)
#define TEST_ALPHA (1<<11)
#define TEST_AND (1<<12)
#define TEST_OR (1<<13)
#define TEST_YCOCG (1<<14)
#define TEST_16TO32 (1<<15)
/* Specific types of testing: */
#define TEST_FUNCTIONALITY (1<<0)
#define TEST_PERFORMANCE (1<<1)
/* ------------------------------------------------------------------------- */
typedef struct
{
const char *testStr;
UINT32 bits;
} test_t;
static const test_t testList[] =
{
{ "all", 0xFFFFFFFFU },
{ "copy", TEST_COPY8 },
{ "copy8", TEST_COPY8 },
{ "set", TEST_SET8|TEST_SET32S|TEST_SET32U },
{ "set8", TEST_SET8 },
{ "set32", TEST_SET32S|TEST_SET32U },
{ "set32s", TEST_SET32S },
{ "set32u", TEST_SET32U },
{ "sign", TEST_SIGN16S },
{ "sign16s", TEST_SIGN16S },
{ "add", TEST_ADD16S },
{ "add16s", TEST_ADD16S },
{ "lshift", TEST_LSHIFT16S|TEST_LSHIFT16U },
{ "rshift", TEST_RSHIFT16S|TEST_RSHIFT16U },
{ "shift", TEST_LSHIFT16S|TEST_LSHIFT16U|TEST_RSHIFT16S|TEST_RSHIFT16U },
{ "lshift16s", TEST_LSHIFT16S },
{ "lshift16u", TEST_LSHIFT16U },
{ "rshift16s", TEST_RSHIFT16S },
{ "rshift16u", TEST_RSHIFT16U },
{ "rgb", TEST_RGB },
{ "color", TEST_RGB },
{ "colors", TEST_RGB },
{ "ycocg", TEST_YCOCG },
{ "alpha", TEST_ALPHA },
{ "and", TEST_AND },
{ "or", TEST_OR },
{ "16to32", TEST_16TO32 }
};
#define NUMTESTS (sizeof(testList)/sizeof(test_t))
static const test_t testTypeList[] =
{
{ "functionality", TEST_FUNCTIONALITY },
{ "performance", TEST_PERFORMANCE },
};
#define NUMTESTTYPES (sizeof(testTypeList)/sizeof(test_t))
int main(int argc, char** argv)
{
int i;
char hints[1024];
UINT32 testSet = 0;
UINT32 testTypes = 0;
int results = SUCCESS;
/* Parse command line for the test set. */
for (i = 1; i < argc; ++i)
{
int j;
BOOL found = 0;
for (j=0; j<NUMTESTS; ++j)
{
if (strcasecmp(argv[i], testList[j].testStr) == 0)
{
testSet |= testList[j].bits;
found = 1;
break;
}
}
for (j=0; j<NUMTESTTYPES; ++j)
{
if (strcasecmp(argv[i], testTypeList[j].testStr) == 0)
{
testTypes |= testTypeList[j].bits;
found = 1;
break;
}
}
if (!found)
{
if (strstr(argv[i], "help") != NULL)
{
printf("Available tests:\n");
for (j=0; j<NUMTESTS; ++j)
{
printf(" %s\n", testList[j].testStr);
}
for (j=0; j<NUMTESTTYPES; ++j)
{
printf(" %s\n", testTypeList[j].testStr);
}
}
else fprintf(stderr, "Unknown parameter '%s'!\n", argv[i]);
}
}
if (testSet == 0)
testSet = 0xffffffff;
if (testTypes == 0)
testTypes = 0xffffffff;
primitives_init();
primitives_flags_str(hints, sizeof(hints));
printf("Hints: %s\n", hints);
/* COPY */
if (testSet & TEST_COPY8)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_copy8u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_copy8u_speed();
}
}
/* SET */
if (testSet & TEST_SET8)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_set8u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_set8u_speed();
}
}
if (testSet & TEST_SET32S)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_set32s_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_set32s_speed();
}
}
if (testSet & TEST_SET32U)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_set32u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_set32u_speed();
}
}
/* SIGN */
if (testSet & TEST_SIGN16S)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_sign16s_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_sign16s_speed();
}
}
/* ADD */
if (testSet & TEST_ADD16S)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_add16s_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_add16s_speed();
}
}
/* SHIFTS */
if (testSet & TEST_LSHIFT16S)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_lShift_16s_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_lShift_16s_speed();
}
}
if (testSet & TEST_LSHIFT16U)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_lShift_16u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_lShift_16u_speed();
}
}
if (testSet & TEST_RSHIFT16S)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_rShift_16s_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_rShift_16s_speed();
}
}
if (testSet & TEST_RSHIFT16U)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_rShift_16u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_rShift_16u_speed();
}
}
/* COLORS */
if (testSet & TEST_RGB)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_RGBToRGB_16s8u_P3AC4R_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_RGBToRGB_16s8u_P3AC4R_speed();
}
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_yCbCrToRGB_16s16s_P3P3_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_yCbCrToRGB_16s16s_P3P3_speed();
}
}
if (testSet & TEST_YCOCG)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_YCoCgRToRGB_8u_AC4R_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_YCoCgRToRGB_8u_AC4R_speed();
}
}
/* 16 to 32 BPP */
if (testSet & TEST_16TO32)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_RGB565ToARGB_16u32u_C3C4_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_RGB565ToARGB_16u32u_C3C4_speed();
}
}
/* ALPHA COMPOSITION */
if (testSet & TEST_ALPHA)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_alphaComp_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_alphaComp_speed();
}
}
/* AND & OR */
if (testSet & TEST_AND)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_and_32u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_and_32u_speed();
}
}
if (testSet & TEST_OR)
{
if (testTypes & TEST_FUNCTIONALITY)
{
results |= test_or_32u_func();
}
if (testTypes & TEST_PERFORMANCE)
{
results |= test_or_32u_speed();
}
}
primitives_deinit();
return results;
while (t > f) f *= 10.0;
f /= 1000.0;
i = ((int) (t/f+0.5)) * (int) f;
if (t < 0.0) sprintf(output, "%f", t);
else if (i == 0) sprintf(output, "%d", (int) (t+0.5));
else if (t < 1e+3) sprintf(output, "%3d", i);
else if (t < 1e+6) sprintf(output, "%3d,%03d",
i/1000, i % 1000);
else if (t < 1e+9) sprintf(output, "%3d,%03d,000",
i/1000000, (i % 1000000) / 1000);
else if (t < 1e+12) sprintf(output, "%3d,%03d,000,000",
i/1000000000, (i % 1000000000) / 1000000);
else sprintf(output, "%f", t);
}

View File

@ -20,31 +20,22 @@
#ifndef __PRIMTEST_H_INCLUDED__
#define __PRIMTEST_H_INCLUDED__
#include <config.h>
#include <stdint.h>
#include <winpr/crt.h>
#include <winpr/spec.h>
#include <winpr/wtypes.h>
#include <measure.h>
#include <string.h>
#include <stdio.h>
#include <winpr/platform.h>
#include <freerdp/primitives.h>
#include <winpr/platform.h>
#include "measure.h"
#ifdef WITH_IPP
#include <ipps.h>
#include <ippi.h>
#endif
#define BLOCK_ALIGNMENT 16
#ifdef __GNUC__
#define ALIGN(x) x __attribute((aligned(BLOCK_ALIGNMENT)))
#define POSSIBLY_UNUSED(x) x __attribute((unused))
#else
/* TODO: Someone needs to finish this for non-GNU C */
#define ALIGN(x) x
#define POSSIBLY_UNUSED(x) x
#endif
#define ALIGN(x) x DECLSPEC_ALIGN(MEMORY_ALLOCATION_ALIGNMENT)
#define ABS(_x_) ((_x_) < 0 ? (-(_x_)) : (_x_))
#define MAX_TEST_SIZE 4096

View File

@ -20,7 +20,6 @@ set(MODULE_PREFIX "FREERDP_UTILS")
set(${MODULE_PREFIX}_SRCS
event.c
bitmap.c
passphrase.c
pcap.c
profiler.c

View File

@ -1,110 +0,0 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Bitmap File Format Utils
*
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <freerdp/types.h>
#include <freerdp/utils/debug.h>
#include <freerdp/utils/bitmap.h>
typedef struct
{
BYTE magic[2];
} BITMAP_MAGIC;
typedef struct
{
UINT32 filesz;
UINT16 creator1;
UINT16 creator2;
UINT32 bmp_offset;
} BITMAP_CORE_HEADER;
typedef struct
{
UINT32 header_sz;
INT32 width;
INT32 height;
UINT16 nplanes;
UINT16 bitspp;
UINT32 compress_type;
UINT32 bmp_bytesz;
INT32 hres;
INT32 vres;
UINT32 ncolors;
UINT32 nimpcolors;
} BITMAP_INFO_HEADER;
void freerdp_bitmap_write(char* filename, void* data, int width, int height, int bpp)
{
FILE* fp;
BITMAP_MAGIC magic;
BITMAP_CORE_HEADER header;
BITMAP_INFO_HEADER info_header;
fp = fopen(filename, "w+b");
if (fp == NULL)
{
DEBUG_WARN( "failed to open file %s\n", filename);
return;
}
magic.magic[0] = 'B';
magic.magic[1] = 'M';
header.creator1 = 0;
header.creator2 = 0;
header.bmp_offset =
sizeof(BITMAP_MAGIC) +
sizeof(BITMAP_CORE_HEADER) +
sizeof(BITMAP_INFO_HEADER);
info_header.bmp_bytesz = width * height * (bpp / 8);
header.filesz =
header.bmp_offset +
info_header.bmp_bytesz;
info_header.width = width;
info_header.height = (-1) * height;
info_header.nplanes = 1;
info_header.bitspp = bpp;
info_header.compress_type = 0;
info_header.hres = width;
info_header.vres = height;
info_header.ncolors = 0;
info_header.nimpcolors = 0;
info_header.header_sz = sizeof(BITMAP_INFO_HEADER);
fwrite((void*) &magic, sizeof(BITMAP_MAGIC), 1, fp);
fwrite((void*) &header, sizeof(BITMAP_CORE_HEADER), 1, fp);
fwrite((void*) &info_header, sizeof(BITMAP_INFO_HEADER), 1, fp);
fwrite((void*) data, info_header.bmp_bytesz, 1, fp);
fclose(fp);
}

View File

@ -114,11 +114,6 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3
if (dataFlags & CHANNEL_FLAG_LAST)
{
if (Stream_Capacity(s) != Stream_GetPosition(s))
{
DEBUG_WARN( "svc_plugin_process_received: read error\n");
}
plugin->data_in = NULL;
Stream_SealLength(s);
Stream_SetPosition(s, 0);

View File

@ -0,0 +1,53 @@
/**
* WinPR: Windows Portable Runtime
* Image Utils
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_IMAGE_H
#define WINPR_IMAGE_H
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
struct _wImage
{
int width;
int height;
BYTE* data;
int scanline;
int bitsPerPixel;
int bytesPerPixel;
};
typedef struct _wImage wImage;
#ifdef __cplusplus
extern "C" {
#endif
WINPR_API int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp);
WINPR_API int winpr_image_write(wImage* image, const char* filename);
WINPR_API int winpr_image_read(wImage* image, const char* filename);
WINPR_API wImage* winpr_image_new();
WINPR_API void winpr_image_free(wImage* image, BOOL bFreeBuffer);
#ifdef __cplusplus
}
#endif
#endif /* WINPR_IMAGE_H */

View File

@ -75,6 +75,7 @@ set(${MODULE_PREFIX}_SRCS
ini.c
sam.c
ntlm.c
image.c
print.c
stream.c
debug.c

View File

@ -0,0 +1,219 @@
/**
* WinPR: Windows Portable Runtime
* Image Utils
*
* Copyright 2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/crt.h>
#include <winpr/image.h>
/**
* Refer to "Compressed Image File Formats: JPEG, PNG, GIF, XBM, BMP" book
*/
#if defined(__APPLE__)
#pragma pack(1)
#else
#pragma pack(push, 1)
#endif
struct _WINPR_BITMAP_FILE_HEADER
{
BYTE bfType[2];
UINT32 bfSize;
UINT16 bfReserved1;
UINT16 bfReserved2;
UINT32 bfOffBits;
};
typedef struct _WINPR_BITMAP_FILE_HEADER WINPR_BITMAP_FILE_HEADER;
struct _WINPR_BITMAP_INFO_HEADER
{
UINT32 biSize;
INT32 biWidth;
INT32 biHeight;
UINT16 biPlanes;
UINT16 biBitCount;
UINT32 biCompression;
UINT32 biSizeImage;
INT32 biXPelsPerMeter;
INT32 biYPelsPerMeter;
UINT32 biClrUsed;
UINT32 biClrImportant;
};
typedef struct _WINPR_BITMAP_INFO_HEADER WINPR_BITMAP_INFO_HEADER;
struct _WINPR_BITMAP_CORE_HEADER
{
UINT32 bcSize;
UINT16 bcWidth;
UINT16 bcHeight;
UINT16 bcPlanes;
UINT16 bcBitCount;
};
typedef struct _WINPR_BITMAP_CORE_HEADER WINPR_BITMAP_CORE_HEADER;
#if defined(__APPLE__)
#pragma pack()
#else
#pragma pack(pop)
#endif
int winpr_bitmap_write(const char* filename, BYTE* data, int width, int height, int bpp)
{
FILE* fp;
WINPR_BITMAP_FILE_HEADER bf;
WINPR_BITMAP_INFO_HEADER bi;
fp = fopen(filename, "w+b");
if (!fp)
{
fprintf(stderr, "failed to open file %s\n", filename);
return -1;
}
bf.bfType[0] = 'B';
bf.bfType[1] = 'M';
bf.bfReserved1 = 0;
bf.bfReserved2 = 0;
bf.bfOffBits = sizeof(WINPR_BITMAP_FILE_HEADER) + sizeof(WINPR_BITMAP_INFO_HEADER);
bi.biSizeImage = width * height * (bpp / 8);
bf.bfSize = bf.bfOffBits + bi.biSizeImage;
bi.biWidth = width;
bi.biHeight = -1 * height;
bi.biPlanes = 1;
bi.biBitCount = bpp;
bi.biCompression = 0;
bi.biXPelsPerMeter = width;
bi.biYPelsPerMeter = height;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
bi.biSize = sizeof(WINPR_BITMAP_INFO_HEADER);
fwrite((void*) &bf, sizeof(WINPR_BITMAP_FILE_HEADER), 1, fp);
fwrite((void*) &bi, sizeof(WINPR_BITMAP_INFO_HEADER), 1, fp);
fwrite((void*) data, bi.biSizeImage, 1, fp);
fclose(fp);
return 1;
}
int winpr_image_write(wImage* image, const char* filename)
{
return winpr_bitmap_write(filename, image->data, image->width, image->height, image->bitsPerPixel);
}
int winpr_image_read(wImage* image, const char* filename)
{
FILE* fp;
int index;
BOOL vFlip;
BYTE* pDstData;
WINPR_BITMAP_FILE_HEADER bf;
WINPR_BITMAP_INFO_HEADER bi;
fp = fopen(filename, "r+b");
if (!fp)
{
fprintf(stderr, "failed to open file %s\n", filename);
return -1;
}
fread((void*) &bf, sizeof(WINPR_BITMAP_FILE_HEADER), 1, fp);
if ((bf.bfType[0] != 'B') || (bf.bfType[1] != 'M'))
return -1;
fread((void*) &bi, sizeof(WINPR_BITMAP_INFO_HEADER), 1, fp);
if (ftell(fp) != bf.bfOffBits)
{
fseek(fp, bf.bfOffBits, SEEK_SET);
}
image->width = bi.biWidth;
if (bi.biHeight < 0)
{
vFlip = FALSE;
image->height = -1 * bi.biHeight;
}
else
{
vFlip = TRUE;
image->height = bi.biHeight;
}
image->bitsPerPixel = bi.biBitCount;
image->bytesPerPixel = (image->bitsPerPixel / 8);
image->scanline = (bi.biSizeImage / bi.biHeight);
image->data = (BYTE*) malloc(bi.biSizeImage);
if (!image->data)
return -1;
if (!vFlip)
{
fread((void*) image->data, bi.biSizeImage, 1, fp);
}
else
{
pDstData = &(image->data[(image->height - 1) * image->scanline]);
for (index = 0; index < image->height; index++)
{
fread((void*) pDstData, image->scanline, 1, fp);
pDstData -= image->scanline;
}
}
fclose(fp);
return 1;
}
wImage* winpr_image_new()
{
wImage* image;
image = (wImage*) calloc(1, sizeof(wImage));
if (!image)
return NULL;
return image;
}
void winpr_image_free(wImage* image, BOOL bFreeBuffer)
{
if (!image)
return;
if (bFreeBuffer)
free(image->data);
free(image);
}

View File

@ -23,88 +23,18 @@
#include <winpr/wlog.h>
#include <winpr/image.h>
#include "wlog/ImageMessage.h"
#include <stdio.h>
#include <string.h>
typedef struct
{
BYTE magic[2];
} BITMAP_MAGIC;
typedef struct
{
UINT32 filesz;
UINT16 creator1;
UINT16 creator2;
UINT32 bmp_offset;
} BITMAP_CORE_HEADER;
typedef struct
{
UINT32 header_sz;
INT32 width;
INT32 height;
UINT16 nplanes;
UINT16 bitspp;
UINT32 compress_type;
UINT32 bmp_bytesz;
INT32 hres;
INT32 vres;
UINT32 ncolors;
UINT32 nimpcolors;
} BITMAP_INFO_HEADER;
int WLog_ImageMessage_Write(char* filename, void* data, int width, int height, int bpp)
{
FILE* fp;
BITMAP_MAGIC magic;
BITMAP_CORE_HEADER header;
BITMAP_INFO_HEADER info_header;
int status;
fp = fopen(filename, "w+b");
status = winpr_bitmap_write(filename, data, width, height, bpp);
if (!fp)
{
fprintf(stderr, "failed to open file %s\n", filename);
if (status < 0)
return -1;
}
magic.magic[0] = 'B';
magic.magic[1] = 'M';
header.creator1 = 0;
header.creator2 = 0;
header.bmp_offset =
sizeof(BITMAP_MAGIC) +
sizeof(BITMAP_CORE_HEADER) +
sizeof(BITMAP_INFO_HEADER);
info_header.bmp_bytesz = width * height * (bpp / 8);
header.filesz =
header.bmp_offset +
info_header.bmp_bytesz;
info_header.width = width;
info_header.height = (-1) * height;
info_header.nplanes = 1;
info_header.bitspp = bpp;
info_header.compress_type = 0;
info_header.hres = width;
info_header.vres = height;
info_header.ncolors = 0;
info_header.nimpcolors = 0;
info_header.header_sz = sizeof(BITMAP_INFO_HEADER);
fwrite((void*) &magic, sizeof(BITMAP_MAGIC), 1, fp);
fwrite((void*) &header, sizeof(BITMAP_CORE_HEADER), 1, fp);
fwrite((void*) &info_header, sizeof(BITMAP_INFO_HEADER), 1, fp);
fwrite((void*) data, info_header.bmp_bytesz, 1, fp);
fclose(fp);
return 0;
return 1;
}