Fixed progressive decoding without subbanddiff

(cherry picked from commit e3445eefab)
This commit is contained in:
akallabeth 2020-12-15 09:58:37 +01:00 committed by akallabeth
parent 84693e93b6
commit 1a4c1de6a8
11 changed files with 157 additions and 61 deletions

View File

@ -38,7 +38,10 @@ extern "C"
#endif
FREERDP_API int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData,
UINT32 SrcSize, BYTE** ppDstData, UINT32* pDstSize);
UINT32 SrcSize, UINT32 SrcFormat, UINT32 Width,
UINT32 Height, UINT32 ScanLine,
const REGION16* invalidRegion, BYTE** ppDstData,
UINT32* pDstSize);
FREERDP_API INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData,
UINT32 SrcSize, BYTE* pDstData, UINT32 DstFormat,

View File

@ -2466,7 +2466,7 @@ int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData,
RFX_RECT* rects = NULL;
RFX_MESSAGE* message;
if (!progressive || !pSrcData || !ppDstData || !pDstSize)
if (!progressive || !pSrcData || !ppDstData || !pDstSize || !invalidRegion)
{
return -1;
}
@ -2494,57 +2494,34 @@ int progressive_compress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData,
if (SrcSize < Height * ScanLine)
return -4;
if (!invalidRegion)
{
numRects = (Width + 63) / 64;
numRects *= (Height + 63) / 64;
}
else
numRects = region16_n_rects(invalidRegion);
if (numRects == 0)
return 0;
numRects = (Width + 63) / 64;
numRects *= (Height + 63) / 64;
if (!Stream_EnsureCapacity(progressive->rects, numRects * sizeof(RFX_RECT)))
return -5;
rects = (RFX_RECT*)Stream_Buffer(progressive->rects);
if (invalidRegion)
{
const RECTANGLE_16* r = region16_rects(invalidRegion, NULL);
for (x = 0; x < numRects; x++)
{
rects[x].x = r[x].left;
rects[x].y = r[x].top;
rects[x].width = r[x].right - r[x].left;
rects[x].height = r[x].bottom - r[x].top;
}
}
else
{
x = 0;
y = 0;
for (i = 0; i < numRects; i++)
{
RFX_RECT* r = &rects[i];
r->x = x;
r->y = y;
r->width = MIN(64, Width - x);
r->height = MIN(64, Height - y);
if (x + 64 >= Width)
{
y += 64;
x = 0;
}
else
x += 64;
}
}
s = progressive->buffer;
Stream_SetPosition(s, 0);
progressive->rfx_context->mode = RLGR1;
x = 0;
y = 0;
for (i = 0; i < numRects; i++)
{
RFX_RECT* r = &rects[i];
r->x = x;
r->y = y;
r->width = MIN(64, Width - x);
r->height = MIN(64, Height - y);
if (x + 64 >= Width)
{
y += 64;
x = 0;
}
else
x += 64;
}
message = rfx_encode_message(progressive->rfx_context, rects, numRects, pSrcData, Width, Height,
ScanLine);
if (!message)

View File

@ -37,8 +37,8 @@
#include "rfx_decode.h"
static void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantization_values,
const BYTE* data, int size, INT16* buffer)
void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantization_values, const BYTE* data,
int size, INT16* buffer)
{
INT16* dwt_buffer;
dwt_buffer = BufferPool_Take(context->priv->BufferPool, -1); /* dwt_buffer */

View File

@ -26,5 +26,6 @@
/* stride is bytes between rows in the output buffer. */
FREERDP_LOCAL BOOL rfx_decode_rgb(RFX_CONTEXT* context, const RFX_TILE* tile, BYTE* rgb_buffer,
UINT32 stride);
FREERDP_LOCAL void rfx_decode_component(RFX_CONTEXT* context, const UINT32* quantization_values,
const BYTE* data, int size, INT16* buffer);
#endif /* FREERDP_LIB_CODEC_RFX_DECODE_H */

View File

@ -27,7 +27,7 @@
#include "rfx_dwt.h"
void rfx_dwt_2d_decode_block(INT16* buffer, INT16* idwt, int subband_width)
static void rfx_dwt_2d_decode_block(INT16* buffer, INT16* idwt, int subband_width)
{
INT16 *dst, *l, *h;
INT16 *l_dst, *h_dst;

View File

@ -23,7 +23,6 @@
#include <freerdp/codec/rfx.h>
#include <freerdp/api.h>
FREERDP_LOCAL void rfx_dwt_2d_decode_block(INT16* buffer, INT16* idwt, int subband_width);
FREERDP_LOCAL void rfx_dwt_2d_decode(INT16* buffer, INT16* dwt_buffer);
FREERDP_LOCAL void rfx_dwt_2d_encode(INT16* buffer, INT16* dwt_buffer);

View File

@ -20,6 +20,8 @@ create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER}
${${MODULE_PREFIX}_TESTS})
add_definitions(-DCMAKE_CURRENT_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}")
add_definitions(-DCMAKE_CURRENT_BINARY_DIR="${CMAKE_CURRENT_BINARY_DIR}")
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
target_link_libraries(${MODULE_NAME} freerdp winpr)

View File

@ -4,6 +4,7 @@
#include <winpr/image.h>
#include <winpr/print.h>
#include <winpr/wlog.h>
#include <winpr/image.h>
#include <winpr/sysinfo.h>
#include <freerdp/codec/region.h>
@ -267,7 +268,7 @@ static int test_image_fill_unused_quarters(BYTE* pDstData, int nDstStep, int nWi
return 1;
}
static BYTE* test_progressive_load_file(char* path, char* file, size_t* size)
static BYTE* test_progressive_load_file(const char* path, const char* file, size_t* size)
{
FILE* fp;
BYTE* buffer;
@ -1017,30 +1018,141 @@ static int test_progressive_ms_sample(char* ms_sample_path)
return 0;
}
static BOOL diff(BYTE a, BYTE b)
{
BYTE big = MAX(a, b);
BYTE little = MIN(a, b);
if (big - little <= 0x25)
return TRUE;
return FALSE;
}
static BOOL colordiff(UINT32 format, UINT32 a, UINT32 b)
{
BYTE ar, ag, ab, aa;
BYTE br, bg, bb, ba;
SplitColor(a, format, &ar, &ag, &ab, &aa, NULL);
SplitColor(b, format, &br, &bg, &bb, &ba, NULL);
if (!diff(aa, ba) || !diff(ar, br) || !diff(ag, bg) || !diff(ab, bb))
return FALSE;
return TRUE;
}
static BOOL test_encode_decode(const char* path)
{
int x, y;
BOOL res = FALSE;
int rc;
BYTE* resultData = NULL;
BYTE* dstData = NULL;
UINT32 dstSize = 0;
UINT32 ColorFormat = PIXEL_FORMAT_BGRX32;
REGION16 invalidRegion = { 0 };
wImage* image = winpr_image_new();
wImage* dstImage = winpr_image_new();
char* name = GetCombinedPath(path, "progressive.bmp");
PROGRESSIVE_CONTEXT* progressiveEnc = progressive_context_new(TRUE);
PROGRESSIVE_CONTEXT* progressiveDec = progressive_context_new(FALSE);
region16_init(&invalidRegion);
if (!image || !dstImage || !name || !progressiveEnc || !progressiveDec)
goto fail;
rc = winpr_image_read(image, name);
if (rc <= 0)
goto fail;
resultData = calloc(image->scanline, image->height);
if (!resultData)
goto fail;
// Progressive encode
rc = progressive_compress(progressiveEnc, image->data, image->scanline * image->height,
ColorFormat, image->width, image->height, image->scanline,
&invalidRegion, &dstData, &dstSize);
// Progressive decode
rc = progressive_create_surface_context(progressiveDec, 0, image->width, image->height);
if (rc <= 0)
goto fail;
rc = progressive_decompress(progressiveDec, dstData, dstSize, resultData, ColorFormat,
image->scanline, 0, 0, &invalidRegion, 0);
if (rc < 0)
goto fail;
// Compare result
if (0) // Dump result image for manual inspection
{
*dstImage = *image;
dstImage->data = resultData;
winpr_image_write(dstImage, "/tmp/test.bmp");
}
for (y = 0; y < image->height; y++)
{
const BYTE* orig = &image->data[y * image->scanline];
const BYTE* dec = &resultData[y * image->scanline];
for (x = 0; x < image->width; x++)
{
const BYTE* po = &orig[x * 4];
const BYTE* pd = &dec[x * 4];
const DWORD a = ReadColor(po, ColorFormat);
const DWORD b = ReadColor(pd, ColorFormat);
if (!colordiff(ColorFormat, a, b))
{
printf("xxxxxxx [%u:%u] %08X != %08X\n", x, y, a, b);
goto fail;
}
}
}
res = TRUE;
fail:
region16_uninit(&invalidRegion);
progressive_context_free(progressiveEnc);
progressive_context_free(progressiveDec);
winpr_image_free(image, TRUE);
winpr_image_free(dstImage, FALSE);
free(resultData);
free(name);
return res;
}
int TestFreeRDPCodecProgressive(int argc, char* argv[])
{
int rc = -1;
char* ms_sample_path;
char name[8192];
SYSTEMTIME systemTime;
WINPR_UNUSED(argc);
WINPR_UNUSED(argv);
GetSystemTime(&systemTime);
sprintf_s(name, sizeof(name),
"EGFX_PROGRESSIVE_MS_SAMPLE-%04" PRIu16 "%02" PRIu16 "%02" PRIu16 "%02" PRIu16
"%02" PRIu16 "%02" PRIu16 "%04" PRIu16,
systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour,
systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
ms_sample_path = GetKnownSubPath(KNOWN_PATH_TEMP, name);
ms_sample_path = _strdup(CMAKE_CURRENT_SOURCE_DIR);
if (!ms_sample_path)
{
printf("Memory allocation failed\n");
return -1;
goto fail;
}
if (PathFileExistsA(ms_sample_path))
return test_progressive_ms_sample(ms_sample_path);
{
/*
if (test_progressive_ms_sample(ms_sample_path) < 0)
goto fail;
*/
if (!test_encode_decode(ms_sample_path))
goto fail;
rc = 0;
}
fail:
free(ms_sample_path);
return 0;
return rc;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

View File

@ -39,8 +39,9 @@ static wHashTable* create_channel_ids_map()
}
/* Proxy context initialization callback */
static BOOL client_to_proxy_context_new(freerdp_peer* client, pServerContext* context)
static BOOL client_to_proxy_context_new(freerdp_peer* client, rdpContext* ctx)
{
pServerContext* context = (pServerContext*)ctx;
proxyServer* server = (proxyServer*)client->ContextExtra;
proxyConfig* config = server->config;
@ -82,8 +83,9 @@ error:
}
/* Proxy context free callback */
static void client_to_proxy_context_free(freerdp_peer* client, pServerContext* context)
static void client_to_proxy_context_free(freerdp_peer* client, rdpContext* ctx)
{
pServerContext* context = (pServerContext*)ctx;
proxyServer* server;
if (!client || !context)
@ -106,8 +108,8 @@ static void client_to_proxy_context_free(freerdp_peer* client, pServerContext* c
BOOL pf_context_init_server_context(freerdp_peer* client)
{
client->ContextSize = sizeof(pServerContext);
client->ContextNew = (psPeerContextNew)client_to_proxy_context_new;
client->ContextFree = (psPeerContextFree)client_to_proxy_context_free;
client->ContextNew = client_to_proxy_context_new;
client->ContextFree = client_to_proxy_context_free;
return freerdp_peer_context_new(client);
}

View File

@ -927,11 +927,11 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcD
int nXSrc, int nYSrc, int nWidth, int nHeight)
{
BOOL ret = TRUE;
int i;
size_t i;
BOOL first;
BOOL last;
wStream* s;
int numMessages;
size_t numMessages;
UINT32 frameId = 0;
rdpUpdate* update;
rdpContext* context = (rdpContext*)client;