コード例 #1
0
ファイル: shadow_client.c プロジェクト: Graf3x/FreeRDP
int shadow_client_send_bitmap_update(rdpShadowClient* client, rdpShadowSurface* surface, int nXSrc, int nYSrc, int nWidth, int nHeight)
{
	BYTE* data;
	BYTE* buffer;
	int yIdx, xIdx, k;
	int rows, cols;
	int nSrcStep;
	BYTE* pSrcData;
	UINT32 DstSize;
	UINT32 SrcFormat;
	BITMAP_DATA* bitmap;
	rdpUpdate* update;
	rdpContext* context;
	rdpSettings* settings;
	UINT32 maxUpdateSize;
	UINT32 totalBitmapSize;
	UINT32 updateSizeEstimate;
	BITMAP_DATA* bitmapData;
	BITMAP_UPDATE bitmapUpdate;
	rdpShadowServer* server;
	rdpShadowEncoder* encoder;

	context = (rdpContext*) client;
	update = context->update;
	settings = context->settings;

	server = client->server;
	encoder = client->encoder;

	maxUpdateSize = settings->MultifragMaxRequestSize;

	if (settings->ColorDepth < 32)
		shadow_encoder_prepare(encoder, FREERDP_CODEC_INTERLEAVED);
	else
		shadow_encoder_prepare(encoder, FREERDP_CODEC_PLANAR);

	pSrcData = surface->data;
	nSrcStep = surface->scanline;
	SrcFormat = PIXEL_FORMAT_RGB32;

	if (server->shareSubRect)
	{
		int subX, subY;
		int subWidth, subHeight;

		subX = server->subRect.left;
		subY = server->subRect.top;
		subWidth = server->subRect.right - server->subRect.left;
		subHeight = server->subRect.bottom - server->subRect.top;

		nXSrc -= subX;
		nYSrc -= subY;
		pSrcData = &pSrcData[(subY * nSrcStep) + (subX * 4)];
	}

	if ((nXSrc % 4) != 0)
	{
		nWidth += (nXSrc % 4);
		nXSrc -= (nXSrc % 4);
	}

	if ((nYSrc % 4) != 0)
	{
		nHeight += (nYSrc % 4);
		nYSrc -= (nYSrc % 4);
	}

	rows = (nHeight / 64) + ((nHeight % 64) ? 1 : 0);
	cols = (nWidth / 64) + ((nWidth % 64) ? 1 : 0);

	k = 0;
	totalBitmapSize = 0;

	bitmapUpdate.count = bitmapUpdate.number = rows * cols;
	if (!(bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number)))
		return -1;
	bitmapUpdate.rectangles = bitmapData;

	if ((nWidth % 4) != 0)
	{
		nWidth += (4 - (nWidth % 4));
	}

	if ((nHeight % 4) != 0)
	{
		nHeight += (4 - (nHeight % 4));
	}

	for (yIdx = 0; yIdx < rows; yIdx++)
	{
		for (xIdx = 0; xIdx < cols; xIdx++)
		{
			bitmap = &bitmapData[k];

			bitmap->width = 64;
			bitmap->height = 64;
			bitmap->destLeft = nXSrc + (xIdx * 64);
			bitmap->destTop = nYSrc + (yIdx * 64);

			if ((bitmap->destLeft + bitmap->width) > (nXSrc + nWidth))
				bitmap->width = (nXSrc + nWidth) - bitmap->destLeft;

			if ((bitmap->destTop + bitmap->height) > (nYSrc + nHeight))
				bitmap->height = (nYSrc + nHeight) - bitmap->destTop;

			bitmap->destRight = bitmap->destLeft + bitmap->width - 1;
			bitmap->destBottom = bitmap->destTop + bitmap->height - 1;
			bitmap->compressed = TRUE;

			if ((bitmap->width < 4) || (bitmap->height < 4))
				continue;

			if (settings->ColorDepth < 32)
			{
				int bitsPerPixel = settings->ColorDepth;
				int bytesPerPixel = (bitsPerPixel + 7) / 8;

				DstSize = 64 * 64 * 4;
				buffer = encoder->grid[k];

				interleaved_compress(encoder->interleaved, buffer, &DstSize, bitmap->width, bitmap->height,
						pSrcData, SrcFormat, nSrcStep, bitmap->destLeft, bitmap->destTop, NULL, bitsPerPixel);

				bitmap->bitmapDataStream = buffer;
				bitmap->bitmapLength = DstSize;
				bitmap->bitsPerPixel = bitsPerPixel;
				bitmap->cbScanWidth = bitmap->width * bytesPerPixel;
				bitmap->cbUncompressedSize = bitmap->width * bitmap->height * bytesPerPixel;
			}
			else
			{
				int dstSize;

				buffer = encoder->grid[k];
				data = &pSrcData[(bitmap->destTop * nSrcStep) + (bitmap->destLeft * 4)];

				buffer = freerdp_bitmap_compress_planar(encoder->planar, data, SrcFormat,
						bitmap->width, bitmap->height, nSrcStep, buffer, &dstSize);

				bitmap->bitmapDataStream = buffer;
				bitmap->bitmapLength = dstSize;
				bitmap->bitsPerPixel = 32;
				bitmap->cbScanWidth = bitmap->width * 4;
				bitmap->cbUncompressedSize = bitmap->width * bitmap->height * 4;
			}

			bitmap->cbCompFirstRowSize = 0;
			bitmap->cbCompMainBodySize = bitmap->bitmapLength;

			totalBitmapSize += bitmap->bitmapLength;
			k++;
		}
	}

	bitmapUpdate.count = bitmapUpdate.number = k;

	updateSizeEstimate = totalBitmapSize + (k * bitmapUpdate.count) + 16;

	if (updateSizeEstimate > maxUpdateSize)
	{
		UINT32 i, j;
		UINT32 updateSize;
		UINT32 newUpdateSize;
		BITMAP_DATA* fragBitmapData = NULL;

		if (k > 0)
			fragBitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * k);

		if (!fragBitmapData)
		{
			free(bitmapData);
			return -1;
		}
		bitmapUpdate.rectangles = fragBitmapData;

		i = j = 0;
		updateSize = 1024;

		while (i < k)
		{
			newUpdateSize = updateSize + (bitmapData[i].bitmapLength + 16);

			if ((newUpdateSize < maxUpdateSize) && ((i + 1) < k))
			{
				CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA));
				updateSize = newUpdateSize;
			}
			else
			{
				if ((i + 1) >= k)
				{
					CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA));
					updateSize = newUpdateSize;
				}
				
				bitmapUpdate.count = bitmapUpdate.number = j;
				IFCALL(update->BitmapUpdate, context, &bitmapUpdate);
				updateSize = 1024;
				j = 0;
			}
		}

		free(fragBitmapData);
	}
	else
	{
		IFCALL(update->BitmapUpdate, context, &bitmapUpdate);
	}

	free(bitmapData);

	return 1;
}
コード例 #2
0
ファイル: core.c プロジェクト: vworkspace/FreeRDS
int freerds_send_bitmap_update(rdsConnection* connection, int bpp, RDS_MSG_PAINT_RECT* msg)
{
    int nXSrc;
    int nYSrc;
    int nWidth;
    int nHeight;
    BYTE* data;
    BYTE* buffer;
    int yIdx, xIdx, k;
    int rows, cols, extra;
    int nSrcStep;
    BYTE* pSrcData;
    UINT32 DstSize;
    UINT32 SrcFormat;
    BITMAP_DATA* bitmap;
    rdpUpdate* update;
    rdsEncoder* encoder;
    rdpContext* context;
    rdpSettings* settings;
    UINT32 maxUpdateSize;
    UINT32 totalBitmapSize;
    UINT32 updateSizeEstimate;
    BITMAP_DATA* bitmapData;
    BITMAP_UPDATE bitmapUpdate;

    WLog_VRB(TAG, "%s", __FUNCTION__);

    nXSrc = msg->nLeftRect;
    nYSrc = msg->nTopRect;
    nWidth = msg->nWidth;
    nHeight = msg->nHeight;

    context = (rdpContext*) connection;
    update = context->update;

    settings = connection->settings;
    encoder = connection->encoder;

    maxUpdateSize = settings->MultifragMaxRequestSize;

    if (settings->ColorDepth < 32)
        freerds_encoder_prepare(encoder, FREERDP_CODEC_INTERLEAVED);
    else
        freerds_encoder_prepare(encoder, FREERDP_CODEC_PLANAR);

    pSrcData = msg->framebuffer->fbSharedMemory;
    nSrcStep = msg->framebuffer->fbScanline;
    SrcFormat = PIXEL_FORMAT_RGB32;

    if ((nXSrc % 4) != 0)
    {
        nWidth += (nXSrc % 4);
        nXSrc -= (nXSrc % 4);
    }

    if ((nYSrc % 4) != 0)
    {
        nHeight += (nYSrc % 4);
        nYSrc -= (nYSrc % 4);
    }

    rows = (nHeight / 64) + ((nHeight % 64) ? 1 : 0);
    cols = (nWidth / 64) + ((nWidth % 64) ? 1 : 0);

    k = 0;
    totalBitmapSize = 0;

    bitmapUpdate.count = bitmapUpdate.number = rows * cols;
    bitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * bitmapUpdate.number);
    bitmapUpdate.rectangles = bitmapData;

    if (!bitmapData)
        return -1;

    if ((nWidth % 4) != 0)
    {
        nXSrc -= (nWidth % 4);
        nWidth += (nWidth % 4);
    }

    if ((nHeight % 4) != 0)
    {
        nYSrc -= (nHeight % 4);
        nHeight += (nHeight % 4);
    }

    /* Clip the rectangle to the confines of the frame buffer. */
    if (nXSrc < 0)
    {
        nWidth += nXSrc;
        nXSrc = 0;
    }

    if (nYSrc < 0)
    {
        nHeight += nYSrc;
        nYSrc = 0;
    }

    extra = (nXSrc + nWidth) - msg->framebuffer->fbWidth;
    if (extra > 0)
    {
        nWidth -= extra;
    }

    extra = (nYSrc + nHeight) - msg->framebuffer->fbHeight;
    if (extra > 0)
    {
        nHeight -= extra;
    }

    if ((nWidth <= 0) || (nHeight <= 0))
    {
        /* Nothing to do. */
        return 1;
    }

    for (yIdx = 0; yIdx < rows; yIdx++)
    {
        for (xIdx = 0; xIdx < cols; xIdx++)
        {
            bitmap = &bitmapData[k];

            bitmap->width = 64;
            bitmap->height = 64;
            bitmap->destLeft = nXSrc + (xIdx * 64);
            bitmap->destTop = nYSrc + (yIdx * 64);

            if ((bitmap->destLeft + bitmap->width) > (nXSrc + nWidth))
                bitmap->width = (nXSrc + nWidth) - bitmap->destLeft;

            if ((bitmap->destTop + bitmap->height) > (nYSrc + nHeight))
                bitmap->height = (nYSrc + nHeight) - bitmap->destTop;

            bitmap->destRight = bitmap->destLeft + bitmap->width - 1;
            bitmap->destBottom = bitmap->destTop + bitmap->height - 1;
            bitmap->compressed = TRUE;

            if ((bitmap->width < 4) || (bitmap->height < 4))
                continue;

            if (settings->ColorDepth < 32)
            {
                int bitsPerPixel = settings->ColorDepth;
                int bytesPerPixel = (bitsPerPixel + 7) / 8;

                DstSize = 64 * 64 * 4;
                buffer = encoder->grid[k];

                interleaved_compress(encoder->interleaved, buffer, &DstSize, bitmap->width, bitmap->height,
                                     pSrcData, SrcFormat, nSrcStep, bitmap->destLeft, bitmap->destTop, NULL, bitsPerPixel);

                bitmap->bitmapDataStream = buffer;
                bitmap->bitmapLength = DstSize;
                bitmap->bitsPerPixel = bitsPerPixel;
                bitmap->cbScanWidth = bitmap->width * bytesPerPixel;
                bitmap->cbUncompressedSize = bitmap->width * bitmap->height * bytesPerPixel;
            }
            else
            {
                int dstSize;

                buffer = encoder->grid[k];
                data = &pSrcData[(bitmap->destTop * nSrcStep) + (bitmap->destLeft * 4)];

                buffer = freerdp_bitmap_compress_planar(encoder->planar, data, SrcFormat,
                                                        bitmap->width, bitmap->height, nSrcStep, buffer, &dstSize);

                bitmap->bitmapDataStream = buffer;
                bitmap->bitmapLength = dstSize;
                bitmap->bitsPerPixel = 32;
                bitmap->cbScanWidth = bitmap->width * 4;
                bitmap->cbUncompressedSize = bitmap->width * bitmap->height * 4;
            }

            bitmap->cbCompFirstRowSize = 0;
            bitmap->cbCompMainBodySize = bitmap->bitmapLength;

            totalBitmapSize += bitmap->bitmapLength;
            k++;
        }
    }

    bitmapUpdate.count = bitmapUpdate.number = k;

    updateSizeEstimate = totalBitmapSize + (k * bitmapUpdate.count) + 16;

    if (updateSizeEstimate > maxUpdateSize)
    {
        UINT32 i, j;
        UINT32 updateSize;
        UINT32 newUpdateSize;
        BITMAP_DATA* fragBitmapData;

        fragBitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * k);
        bitmapUpdate.rectangles = fragBitmapData;

        i = j = 0;
        updateSize = 1024;

        while (i < k)
        {
            newUpdateSize = updateSize + (bitmapData[i].bitmapLength + 16);

            if ((newUpdateSize < maxUpdateSize) && ((i + 1) < k))
            {
                CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA));
                updateSize = newUpdateSize;
            }
            else
            {
                if ((i + 1) >= k)
                {
                    CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA));
                    updateSize = newUpdateSize;
                }

                bitmapUpdate.count = bitmapUpdate.number = j;
                IFCALL(update->BitmapUpdate, context, &bitmapUpdate);
                updateSize = 1024;
                j = 0;
            }
        }

        free(fragBitmapData);
    }
    else
    {
        IFCALL(update->BitmapUpdate, context, &bitmapUpdate);
    }

    free(bitmapData);

    return 1;
}