mirror of https://github.com/FreeRDP/FreeRDP
commit
763410a66d
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
prim_test
|
||||
TestPrimitives.c
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ set(MODULE_PREFIX "FREERDP_UTILS")
|
|||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
event.c
|
||||
bitmap.c
|
||||
passphrase.c
|
||||
pcap.c
|
||||
profiler.c
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
|
@ -75,6 +75,7 @@ set(${MODULE_PREFIX}_SRCS
|
|||
ini.c
|
||||
sam.c
|
||||
ntlm.c
|
||||
image.c
|
||||
print.c
|
||||
stream.c
|
||||
debug.c
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue