mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-codec: start work on progressive inverse DWT
This commit is contained in:
@@ -477,10 +477,21 @@ 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 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);
|
||||
|
||||
@@ -500,17 +511,51 @@ int xf_SurfaceCommand_Progressive(xfContext* xfc, RdpgfxClientContext* context,
|
||||
|
||||
printf("xf_SurfaceCommand_Progressive: status: %d\n", status);
|
||||
|
||||
/* fill with blue for now to distinguish from the rest */
|
||||
region = &(xfc->progressive->region);
|
||||
|
||||
freerdp_image_fill(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
|
||||
cmd->left, cmd->top, cmd->width, cmd->height, 0x0000FF);
|
||||
region16_init(&clippingRects);
|
||||
|
||||
invalidRect.left = cmd->left;
|
||||
invalidRect.top = cmd->top;
|
||||
invalidRect.right = cmd->right;
|
||||
invalidRect.bottom = cmd->bottom;
|
||||
for (i = 0; i < region->numRects; i++)
|
||||
{
|
||||
rect = &(region->rects[i]);
|
||||
|
||||
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &invalidRect);
|
||||
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(&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;
|
||||
|
||||
freerdp_image_copy(surface->data, PIXEL_FORMAT_XRGB32, surface->scanline,
|
||||
nXDst, nYDst, nWidth, nHeight,
|
||||
tile->data, PIXEL_FORMAT_XRGB32, 64 * 4, 0, 0);
|
||||
|
||||
region16_union_rect(&(xfc->invalidRegion), &(xfc->invalidRegion), &updateRects[j]);
|
||||
}
|
||||
|
||||
region16_uninit(&updateRegion);
|
||||
}
|
||||
|
||||
if (!xfc->inGfxFrame)
|
||||
xf_OutputUpdate(xfc);
|
||||
|
||||
@@ -205,6 +205,12 @@ struct _RFX_PROGRESSIVE_TILE
|
||||
BYTE* cbRawData;
|
||||
BYTE* crSrlData;
|
||||
BYTE* crRawData;
|
||||
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
BYTE* data;
|
||||
};
|
||||
typedef struct _RFX_PROGRESSIVE_TILE RFX_PROGRESSIVE_TILE;
|
||||
|
||||
|
||||
@@ -94,10 +94,106 @@ const char* progressive_get_block_type_string(UINT16 blockType)
|
||||
* LL3 4015 9x9 81
|
||||
*/
|
||||
|
||||
static void progressive_rfx_dwt_2d_decode_block(INT16* buffer, INT16* dwt, int N)
|
||||
{
|
||||
int N2;
|
||||
int x, y, k;
|
||||
INT16 *dst, *l, *h;
|
||||
INT16 *l_dst, *h_dst;
|
||||
INT16 *HL, *LH, *HH, *LL;
|
||||
|
||||
N2 = N << 1;
|
||||
|
||||
/* Inverse DWT in horizontal direction, results in 2 sub-bands in L, H order in tmp buffer idwt. */
|
||||
/* The 4 sub-bands are stored in HL(0), LH(1), HH(2), LL(3) order. */
|
||||
/* The lower part L uses LL(3) and HL(0). */
|
||||
/* The higher part H uses LH(1) and HH(2). */
|
||||
|
||||
LL = &buffer[(N * N) * 3];
|
||||
HL = &buffer[0];
|
||||
l_dst = &dwt[0];
|
||||
|
||||
LH = &buffer[N * N];
|
||||
HH = &buffer[(N * N) * 2];
|
||||
h_dst = &dwt[(N * N) * 2];
|
||||
|
||||
for (y = 0; y < N; y++)
|
||||
{
|
||||
/* Even coefficients */
|
||||
l_dst[0] = LL[0] - ((HL[0] + HL[0] + 1) >> 1);
|
||||
h_dst[0] = LH[0] - ((HH[0] + HH[0] + 1) >> 1);
|
||||
|
||||
for (k = 1; k < N; k++)
|
||||
{
|
||||
x = k << 1;
|
||||
l_dst[x] = LL[k] - ((HL[k-1] + HL[k] + 1) >> 1);
|
||||
h_dst[x] = LH[k] - ((HH[k-1] + HH[k] + 1) >> 1);
|
||||
}
|
||||
|
||||
/* Odd coefficients */
|
||||
for (k = 0; k < N-1; k++)
|
||||
{
|
||||
x = k << 1;
|
||||
l_dst[x + 1] = (HL[k] << 1) + ((l_dst[x] + l_dst[x + 2]) >> 1);
|
||||
h_dst[x + 1] = (HH[k] << 1) + ((h_dst[x] + h_dst[x + 2]) >> 1);
|
||||
}
|
||||
|
||||
x = k << 1;
|
||||
l_dst[x + 1] = (HL[k] << 1) + (l_dst[x]);
|
||||
h_dst[x + 1] = (HH[k] << 1) + (h_dst[x]);
|
||||
|
||||
LL += N;
|
||||
HL += N;
|
||||
l_dst += N2;
|
||||
|
||||
LH += N;
|
||||
HH += N;
|
||||
h_dst += N2;
|
||||
}
|
||||
|
||||
/* Inverse DWT in vertical direction, results are stored in original buffer. */
|
||||
for (x = 0; x < N2; x++)
|
||||
{
|
||||
/* Even coefficients */
|
||||
for (k = 0; k < N; k++)
|
||||
{
|
||||
y = k << 1;
|
||||
dst = buffer + y * N2 + x;
|
||||
l = dwt + k * N2 + x;
|
||||
h = l + N * N2;
|
||||
dst[0] = *l - (((k > 0 ? *(h - N2) : *h) + (*h) + 1) >> 1);
|
||||
}
|
||||
|
||||
/* Odd coefficients */
|
||||
for (k = 0; k < N; k++)
|
||||
{
|
||||
y = k << 1;
|
||||
dst = buffer + y * N2 + x;
|
||||
l = dwt + k * N2 + x;
|
||||
h = l + N * N2;
|
||||
dst[N2] = (*h << 1) + ((dst[0] + dst[k < N - 1 ? 2 * N2 : 0]) >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void progressive_rfx_dwt_2d_decode(INT16* buffer, INT16* dwt)
|
||||
{
|
||||
#if 0
|
||||
progressive_rfx_dwt_2d_decode_block(&buffer[3807], dwt, 8);
|
||||
progressive_rfx_dwt_2d_decode_block(&buffer[3007], dwt, 16);
|
||||
//progressive_rfx_dwt_2d_decode_block(&buffer[0], dwt, 32);
|
||||
#else
|
||||
progressive_rfx_dwt_2d_decode_block(&buffer[3840], dwt, 8);
|
||||
progressive_rfx_dwt_2d_decode_block(&buffer[3072], dwt, 16);
|
||||
progressive_rfx_dwt_2d_decode_block(&buffer[0], dwt, 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
int progressive_rfx_decode_component(PROGRESSIVE_CONTEXT* progressive,
|
||||
RFX_COMPONENT_CODEC_QUANT* quant, const BYTE* data, int length, INT16* buffer)
|
||||
{
|
||||
int status;
|
||||
INT16* dwt;
|
||||
const primitives_t* prims = primitives_get();
|
||||
|
||||
status = rfx_rlgr_decode(data, length, buffer, 4096, 1);
|
||||
@@ -118,6 +214,12 @@ int progressive_rfx_decode_component(PROGRESSIVE_CONTEXT* progressive,
|
||||
rfx_quantization_decode_block(prims, &buffer[3951], 64, (quant->HH3 - 1)); /* HH3 */
|
||||
rfx_quantization_decode_block(prims, &buffer[4015], 81, (quant->LL3 - 1)); /* LL3 */
|
||||
|
||||
dwt = (INT16*) BufferPool_Take(progressive->bufferPool, -1); /* DWT buffer */
|
||||
|
||||
progressive_rfx_dwt_2d_decode(buffer, dwt);
|
||||
|
||||
BufferPool_Return(progressive->bufferPool, dwt);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -130,6 +232,8 @@ int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROG
|
||||
RFX_COMPONENT_CODEC_QUANT* quantCb;
|
||||
RFX_COMPONENT_CODEC_QUANT* quantCr;
|
||||
RFX_PROGRESSIVE_CODEC_QUANT* quantProgVal;
|
||||
static const prim_size_t roi_64x64 = { 64, 64 };
|
||||
const primitives_t* prims = primitives_get();
|
||||
|
||||
printf("ProgressiveTileFirst: quantIdx Y: %d Cb: %d Cr: %d xIdx: %d yIdx: %d flags: %d quality: %d yLen: %d cbLen: %d crLen: %d tailLen: %d\n",
|
||||
tile->quantIdxY, tile->quantIdxCb, tile->quantIdxCr, tile->xIdx, tile->yIdx, tile->flags, tile->quality, tile->yLen, tile->cbLen, tile->crLen, tile->tailLen);
|
||||
@@ -164,6 +268,7 @@ int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROG
|
||||
}
|
||||
|
||||
pBuffer = (BYTE*) BufferPool_Take(progressive->bufferPool, -1);
|
||||
|
||||
pSrcDst[0] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 0) + 16])); /* Y/R buffer */
|
||||
pSrcDst[1] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 1) + 16])); /* Cb/G buffer */
|
||||
pSrcDst[2] = (INT16*)((BYTE*)(&pBuffer[((8192 + 32) * 2) + 16])); /* Cr/B buffer */
|
||||
@@ -172,6 +277,17 @@ int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progressive, RFX_PROG
|
||||
progressive_rfx_decode_component(progressive, quantCb, tile->cbData, tile->cbLen, pSrcDst[1]); /* Cb */
|
||||
progressive_rfx_decode_component(progressive, quantCr, tile->crData, tile->crLen, pSrcDst[2]); /* Cr */
|
||||
|
||||
prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16),
|
||||
pSrcDst, 64 * sizeof(INT16), &roi_64x64);
|
||||
|
||||
if (!tile->data)
|
||||
{
|
||||
tile->data = _aligned_malloc(64 * 64 * 4, 16);
|
||||
}
|
||||
|
||||
prims->RGBToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * sizeof(INT16),
|
||||
tile->data, 64 * 4, &roi_64x64);
|
||||
|
||||
BufferPool_Return(progressive->bufferPool, pBuffer);
|
||||
|
||||
return 1;
|
||||
@@ -296,6 +412,11 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI
|
||||
tile->tailData = &block[boffset];
|
||||
boffset += tile->tailLen;
|
||||
|
||||
tile->width = 64;
|
||||
tile->height = 64;
|
||||
tile->x = tile->xIdx * 64;
|
||||
tile->y = tile->yIdx * 64;
|
||||
|
||||
break;
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_FIRST:
|
||||
@@ -340,6 +461,11 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI
|
||||
tile->tailData = &block[boffset];
|
||||
boffset += tile->tailLen;
|
||||
|
||||
tile->width = 64;
|
||||
tile->height = 64;
|
||||
tile->x = tile->xIdx * 64;
|
||||
tile->y = tile->yIdx * 64;
|
||||
|
||||
break;
|
||||
|
||||
case PROGRESSIVE_WBT_TILE_UPGRADE:
|
||||
@@ -397,6 +523,11 @@ int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, BYTE* blocks, UI
|
||||
tile->crRawData = &block[boffset];
|
||||
boffset += tile->crRawLen;
|
||||
|
||||
tile->width = 64;
|
||||
tile->height = 64;
|
||||
tile->x = tile->xIdx * 64;
|
||||
tile->y = tile->yIdx * 64;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -340,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))
|
||||
|
||||
Reference in New Issue
Block a user