Blame libfreerdp/codec/color.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Color Conversion Routines
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2010 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2016 Armin Novak <armin.novak@thincast.com>
Packit 1fb8d4
 * Copyright 2016 Thincast Technologies GmbH
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <stdio.h>
Packit 1fb8d4
#include <string.h>
Packit 1fb8d4
#include <stdlib.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/log.h>
Packit 1fb8d4
#include <freerdp/freerdp.h>
Packit 1fb8d4
#include <freerdp/primitives.h>
Packit 1fb8d4
Packit 1fb8d4
#define TAG FREERDP_TAG("color")
Packit 1fb8d4
Packit 1fb8d4
BYTE* freerdp_glyph_convert(UINT32 width, UINT32 height, const BYTE* data)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 x, y;
Packit 1fb8d4
	const BYTE* srcp;
Packit 1fb8d4
	BYTE* dstp;
Packit 1fb8d4
	BYTE* dstData;
Packit 1fb8d4
	UINT32 scanline;
Packit 1fb8d4
	/*
Packit 1fb8d4
	 * converts a 1-bit-per-pixel glyph to a one-byte-per-pixel glyph:
Packit 1fb8d4
	 * this approach uses a little more memory, but provides faster
Packit 1fb8d4
	 * means of accessing individual pixels in blitting operations
Packit 1fb8d4
	 */
Packit 1fb8d4
	scanline = (width + 7) / 8;
Packit 1fb8d4
	dstData = (BYTE*) _aligned_malloc(width * height, 16);
Packit 1fb8d4
Packit 1fb8d4
	if (!dstData)
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit 1fb8d4
	ZeroMemory(dstData, width * height);
Packit 1fb8d4
	dstp = dstData;
Packit 1fb8d4
Packit 1fb8d4
	for (y = 0; y < height; y++)
Packit 1fb8d4
	{
Packit 1fb8d4
		srcp = data + (y * scanline);
Packit 1fb8d4
Packit 1fb8d4
		for (x = 0; x < width; x++)
Packit 1fb8d4
		{
Packit 1fb8d4
			if ((*srcp & (0x80 >> (x % 8))) != 0)
Packit 1fb8d4
				*dstp = 0xFF;
Packit 1fb8d4
Packit 1fb8d4
			dstp++;
Packit 1fb8d4
Packit 1fb8d4
			if (((x + 1) % 8 == 0) && x != 0)
Packit 1fb8d4
				srcp++;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return dstData;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_image_copy_from_monochrome(BYTE* pDstData, UINT32 DstFormat,
Packit 1fb8d4
                                        UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
Packit 1fb8d4
                                        UINT32 nWidth, UINT32 nHeight,
Packit 1fb8d4
                                        const BYTE* pSrcData,
Packit 1fb8d4
                                        UINT32 backColor, UINT32 foreColor,
Packit 1fb8d4
                                        const gdiPalette* palette)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 x, y;
Packit 1fb8d4
	BOOL vFlip;
Packit 1fb8d4
	UINT32 monoStep;
Packit 1fb8d4
	const UINT32 dstBytesPerPixel = GetBytesPerPixel(DstFormat);
Packit 1fb8d4
Packit 1fb8d4
	if (!pDstData || !pSrcData || !palette)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (nDstStep == 0)
Packit 1fb8d4
		nDstStep = dstBytesPerPixel * nWidth;
Packit 1fb8d4
Packit 1fb8d4
	vFlip = FALSE;
Packit 1fb8d4
	monoStep = (nWidth + 7) / 8;
Packit 1fb8d4
Packit 1fb8d4
	for (y = 0; y < nHeight; y++)
Packit 1fb8d4
	{
Packit 1fb8d4
		const BYTE* monoBits;
Packit 1fb8d4
		BYTE* pDstLine = &pDstData[((nYDst + y) * nDstStep)];
Packit 1fb8d4
		UINT32 monoBit = 0x80;
Packit 1fb8d4
Packit 1fb8d4
		if (!vFlip)
Packit 1fb8d4
			monoBits = &pSrcData[monoStep * y];
Packit 1fb8d4
		else
Packit 1fb8d4
			monoBits = &pSrcData[monoStep * (nHeight - y - 1)];
Packit 1fb8d4
Packit 1fb8d4
		for (x = 0; x < nWidth; x++)
Packit 1fb8d4
		{
Packit 1fb8d4
			BYTE* pDstPixel = &pDstLine[((nXDst + x) * GetBytesPerPixel(DstFormat))];
Packit 1fb8d4
			BOOL monoPixel = (*monoBits & monoBit) ? TRUE : FALSE;
Packit 1fb8d4
Packit 1fb8d4
			if (!(monoBit >>= 1))
Packit 1fb8d4
			{
Packit 1fb8d4
				monoBits++;
Packit 1fb8d4
				monoBit = 0x80;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			if (monoPixel)
Packit 1fb8d4
				WriteColor(pDstPixel, DstFormat, backColor);
Packit 1fb8d4
			else
Packit 1fb8d4
				WriteColor(pDstPixel, DstFormat, foreColor);
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static INLINE UINT32 freerdp_image_inverted_pointer_color(UINT32 x, UINT32 y,
Packit 1fb8d4
        UINT32 format)
Packit 1fb8d4
{
Packit 1fb8d4
#if 1
Packit 1fb8d4
	/**
Packit 1fb8d4
	 * Inverted pointer colors (where individual pixels can change their
Packit 1fb8d4
	 * color to accommodate the background behind them) only seem to be
Packit 1fb8d4
	 * supported on Windows.
Packit 1fb8d4
	 * Using a static replacement color for these pixels (e.g. black)
Packit 1fb8d4
	 * might result in invisible pointers depending on the background.
Packit 1fb8d4
	 * This function returns either black or white, depending on the
Packit 1fb8d4
	 * pixel's position.
Packit 1fb8d4
	 */
Packit 1fb8d4
	BYTE fill = (x + y) & 1 ? 0x00 : 0xFF;
Packit 1fb8d4
#else
Packit 1fb8d4
	BYTE fill = 0x00;
Packit 1fb8d4
#endif
Packit 1fb8d4
	return FreeRDPGetColor(format, fill, fill, fill, 0xFF);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
/**
Packit 1fb8d4
 * Drawing Monochrome Pointers:
Packit 1fb8d4
 * http://msdn.microsoft.com/en-us/library/windows/hardware/ff556143/
Packit 1fb8d4
 *
Packit 1fb8d4
 * Drawing Color Pointers:
Packit 1fb8d4
 * http://msdn.microsoft.com/en-us/library/windows/hardware/ff556138/
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_image_copy_from_pointer_data(
Packit 1fb8d4
    BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep,
Packit 1fb8d4
    UINT32 nXDst, UINT32 nYDst, UINT32 nWidth, UINT32 nHeight,
Packit 1fb8d4
    const BYTE* xorMask, UINT32 xorMaskLength,
Packit 1fb8d4
    const BYTE* andMask, UINT32 andMaskLength,
Packit 1fb8d4
    UINT32 xorBpp, const gdiPalette* palette)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 x, y;
Packit 1fb8d4
	BOOL vFlip;
Packit 1fb8d4
	UINT32 xorStep;
Packit 1fb8d4
	UINT32 andStep;
Packit 1fb8d4
	UINT32 xorBit;
Packit 1fb8d4
	UINT32 andBit;
Packit 1fb8d4
	UINT32 xorPixel;
Packit 1fb8d4
	UINT32 andPixel;
Packit 1fb8d4
	UINT32 dstBitsPerPixel;
Packit 1fb8d4
	UINT32 dstBytesPerPixel;
Packit 1fb8d4
	dstBitsPerPixel = GetBitsPerPixel(DstFormat);
Packit 1fb8d4
	dstBytesPerPixel = GetBytesPerPixel(DstFormat);
Packit 1fb8d4
Packit 1fb8d4
	if (nDstStep <= 0)
Packit 1fb8d4
		nDstStep = dstBytesPerPixel * nWidth;
Packit 1fb8d4
Packit 1fb8d4
	vFlip = (xorBpp == 1) ? FALSE : TRUE;
Packit 1fb8d4
	andStep = (nWidth + 7) / 8;
Packit 1fb8d4
	andStep += (andStep % 2);
Packit 1fb8d4
Packit 1fb8d4
	if (!xorMask || (xorMaskLength == 0))
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	switch (xorBpp)
Packit 1fb8d4
	{
Packit 1fb8d4
		case 1:
Packit 1fb8d4
			if (!andMask || (andMaskLength == 0))
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
Packit 1fb8d4
			xorStep = (nWidth + 7) / 8;
Packit 1fb8d4
			xorStep += (xorStep % 2);
Packit 1fb8d4
Packit 1fb8d4
			if (xorStep * nHeight > xorMaskLength)
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
Packit 1fb8d4
			if (andStep * nHeight > andMaskLength)
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
Packit 1fb8d4
			for (y = 0; y < nHeight; y++)
Packit 1fb8d4
			{
Packit 1fb8d4
				const BYTE* andBits;
Packit 1fb8d4
				const BYTE* xorBits;
Packit 1fb8d4
				BYTE* pDstPixel = &pDstData[((nYDst + y) * nDstStep) +
Packit 1fb8d4
				                                         (nXDst * GetBytesPerPixel(DstFormat))];
Packit 1fb8d4
				xorBit = andBit = 0x80;
Packit 1fb8d4
Packit 1fb8d4
				if (!vFlip)
Packit 1fb8d4
				{
Packit 1fb8d4
					xorBits = &xorMask[xorStep * y];
Packit 1fb8d4
					andBits = &andMask[andStep * y];
Packit 1fb8d4
				}
Packit 1fb8d4
				else
Packit 1fb8d4
				{
Packit 1fb8d4
					xorBits = &xorMask[xorStep * (nHeight - y - 1)];
Packit 1fb8d4
					andBits = &andMask[andStep * (nHeight - y - 1)];
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				for (x = 0; x < nWidth; x++)
Packit 1fb8d4
				{
Packit 1fb8d4
					UINT32 color = 0;
Packit 1fb8d4
					xorPixel = (*xorBits & xorBit) ? 1 : 0;
Packit 1fb8d4
Packit 1fb8d4
					if (!(xorBit >>= 1))
Packit 1fb8d4
					{
Packit 1fb8d4
						xorBits++;
Packit 1fb8d4
						xorBit = 0x80;
Packit 1fb8d4
					}
Packit 1fb8d4
Packit 1fb8d4
					andPixel = (*andBits & andBit) ? 1 : 0;
Packit 1fb8d4
Packit 1fb8d4
					if (!(andBit >>= 1))
Packit 1fb8d4
					{
Packit 1fb8d4
						andBits++;
Packit 1fb8d4
						andBit = 0x80;
Packit 1fb8d4
					}
Packit 1fb8d4
Packit 1fb8d4
					if (!andPixel && !xorPixel)
Packit 1fb8d4
						color = FreeRDPGetColor(DstFormat, 0, 0, 0, 0xFF); /* black */
Packit 1fb8d4
					else if (!andPixel && xorPixel)
Packit 1fb8d4
						color = FreeRDPGetColor(DstFormat, 0xFF, 0xFF, 0xFF, 0xFF); /* white */
Packit 1fb8d4
					else if (andPixel && !xorPixel)
Packit 1fb8d4
						color = FreeRDPGetColor(DstFormat, 0, 0, 0, 0); /* transparent */
Packit 1fb8d4
					else if (andPixel && xorPixel)
Packit 1fb8d4
						color = freerdp_image_inverted_pointer_color(x, y, DstFormat); /* inverted */
Packit 1fb8d4
Packit 1fb8d4
					WriteColor(pDstPixel, DstFormat, color);
Packit 1fb8d4
					pDstPixel += GetBytesPerPixel(DstFormat);
Packit 1fb8d4
				}
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			return TRUE;
Packit 1fb8d4
Packit 1fb8d4
		case 8:
Packit 1fb8d4
		case 16:
Packit 1fb8d4
		case 24:
Packit 1fb8d4
		case 32:
Packit 1fb8d4
			{
Packit 1fb8d4
				UINT32 xorBytesPerPixel = xorBpp >> 3;
Packit 1fb8d4
				xorStep = nWidth * xorBytesPerPixel;
Packit 1fb8d4
Packit 1fb8d4
				if (xorBpp == 8 && !palette)
Packit 1fb8d4
				{
Packit 1fb8d4
					WLog_ERR(TAG, "null palette in conversion from %"PRIu32" bpp to %"PRIu32" bpp",
Packit 1fb8d4
					         xorBpp, dstBitsPerPixel);
Packit 1fb8d4
					return FALSE;
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				if (xorStep * nHeight > xorMaskLength)
Packit 1fb8d4
					return FALSE;
Packit 1fb8d4
Packit 1fb8d4
				if (andMask)
Packit 1fb8d4
				{
Packit 1fb8d4
					if (andStep * nHeight > andMaskLength)
Packit 1fb8d4
						return FALSE;
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				for (y = 0; y < nHeight; y++)
Packit 1fb8d4
				{
Packit 1fb8d4
					const BYTE* xorBits;
Packit 1fb8d4
					const BYTE* andBits = NULL;
Packit 1fb8d4
					BYTE* pDstPixel = &pDstData[((nYDst + y) * nDstStep) +
Packit 1fb8d4
					                                         (nXDst * GetBytesPerPixel(DstFormat))];
Packit 1fb8d4
					andBit = 0x80;
Packit 1fb8d4
Packit 1fb8d4
					if (!vFlip)
Packit 1fb8d4
					{
Packit 1fb8d4
						if (andMask)
Packit 1fb8d4
							andBits = &andMask[andStep * y];
Packit 1fb8d4
Packit 1fb8d4
						xorBits = &xorMask[xorStep * y];
Packit 1fb8d4
					}
Packit 1fb8d4
					else
Packit 1fb8d4
					{
Packit 1fb8d4
						if (andMask)
Packit 1fb8d4
							andBits = &andMask[andStep * (nHeight - y - 1)];
Packit 1fb8d4
Packit 1fb8d4
						xorBits = &xorMask[xorStep * (nHeight - y - 1)];
Packit 1fb8d4
					}
Packit 1fb8d4
Packit 1fb8d4
					for (x = 0; x < nWidth; x++)
Packit 1fb8d4
					{
Packit 1fb8d4
						UINT32 pixelFormat;
Packit 1fb8d4
						UINT32 color;
Packit 1fb8d4
Packit 1fb8d4
						if (xorBpp == 32)
Packit 1fb8d4
						{
Packit 1fb8d4
							pixelFormat = PIXEL_FORMAT_BGRA32;
Packit 1fb8d4
							xorPixel = ReadColor(xorBits, pixelFormat);
Packit 1fb8d4
						}
Packit 1fb8d4
						else if (xorBpp == 16)
Packit 1fb8d4
						{
Packit 1fb8d4
							pixelFormat = PIXEL_FORMAT_RGB15;
Packit 1fb8d4
							xorPixel = ReadColor(xorBits, pixelFormat);
Packit 1fb8d4
						}
Packit 1fb8d4
						else if (xorBpp == 8)
Packit 1fb8d4
						{
Packit 1fb8d4
							pixelFormat = palette->format;
Packit 1fb8d4
							xorPixel = palette->palette[xorBits[0]];
Packit 1fb8d4
						}
Packit 1fb8d4
						else
Packit 1fb8d4
						{
Packit 1fb8d4
							pixelFormat = PIXEL_FORMAT_BGR24;
Packit 1fb8d4
							xorPixel = ReadColor(xorBits, pixelFormat);
Packit 1fb8d4
						}
Packit 1fb8d4
Packit 1fb8d4
						xorPixel = FreeRDPConvertColor(xorPixel,
Packit 1fb8d4
						                               pixelFormat,
Packit 1fb8d4
						                               PIXEL_FORMAT_ARGB32,
Packit 1fb8d4
						                               palette);
Packit 1fb8d4
						xorBits += xorBytesPerPixel;
Packit 1fb8d4
						andPixel = 0;
Packit 1fb8d4
Packit 1fb8d4
						if (andMask)
Packit 1fb8d4
						{
Packit 1fb8d4
							andPixel = (*andBits & andBit) ? 1 : 0;
Packit 1fb8d4
Packit 1fb8d4
							if (!(andBit >>= 1))
Packit 1fb8d4
							{
Packit 1fb8d4
								andBits++;
Packit 1fb8d4
								andBit = 0x80;
Packit 1fb8d4
							}
Packit 1fb8d4
						}
Packit 1fb8d4
Packit 1fb8d4
						if (andPixel)
Packit 1fb8d4
						{
Packit 1fb8d4
							if (xorPixel == 0xFF000000) /* black -> transparent */
Packit 1fb8d4
								xorPixel = 0x00000000;
Packit 1fb8d4
							else if (xorPixel == 0xFFFFFFFF) /* white -> inverted */
Packit 1fb8d4
								xorPixel = freerdp_image_inverted_pointer_color(x, y, PIXEL_FORMAT_ARGB32);
Packit 1fb8d4
						}
Packit 1fb8d4
Packit 1fb8d4
						color = FreeRDPConvertColor(xorPixel, PIXEL_FORMAT_ARGB32,
Packit 1fb8d4
						                            DstFormat, palette);
Packit 1fb8d4
						WriteColor(pDstPixel, DstFormat, color);
Packit 1fb8d4
						pDstPixel += GetBytesPerPixel(DstFormat);
Packit 1fb8d4
					}
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				return TRUE;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
		default:
Packit 1fb8d4
			WLog_ERR(TAG, "failed to convert from %"PRIu32" bpp to %"PRIu32" bpp",
Packit 1fb8d4
			         xorBpp, dstBitsPerPixel);
Packit 1fb8d4
			return FALSE;
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
static INLINE BOOL overlapping(const BYTE* pDstData, UINT32 nXDst, UINT32 nYDst,
Packit 1fb8d4
                               UINT32 nDstStep, UINT32 dstBytesPerPixel,
Packit 1fb8d4
                               const BYTE* pSrcData, UINT32 nXSrc, UINT32 nYSrc,
Packit 1fb8d4
                               UINT32 nSrcStep, UINT32 srcBytesPerPixel,
Packit 1fb8d4
                               UINT32 nWidth, UINT32 nHeight)
Packit 1fb8d4
{
Packit 1fb8d4
	const BYTE* pDstStart = &pDstData[nXDst * dstBytesPerPixel + nYDst * nDstStep];
Packit 1fb8d4
	const BYTE* pDstEnd = pDstStart + nHeight * nDstStep;
Packit 1fb8d4
	const BYTE* pSrcStart = &pSrcData[nXSrc * srcBytesPerPixel + nYSrc * nSrcStep];
Packit 1fb8d4
	const BYTE* pSrcEnd = pSrcStart + nHeight * nSrcStep;
Packit 1fb8d4
Packit 1fb8d4
	if ((pDstStart >= pSrcStart) && (pDstStart <= pSrcEnd))
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
	if ((pDstEnd >= pSrcStart) && (pDstEnd <= pSrcEnd))
Packit 1fb8d4
		return TRUE;
Packit 1fb8d4
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_image_copy(BYTE* pDstData, DWORD DstFormat,
Packit 1fb8d4
                        UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
Packit 1fb8d4
                        UINT32 nWidth, UINT32 nHeight,
Packit 1fb8d4
                        const BYTE* pSrcData, DWORD SrcFormat,
Packit 1fb8d4
                        UINT32 nSrcStep, UINT32 nXSrc, UINT32 nYSrc,
Packit 1fb8d4
                        const gdiPalette* palette, UINT32 flags)
Packit 1fb8d4
{
Packit 1fb8d4
	const UINT32 dstByte = GetBytesPerPixel(DstFormat);
Packit 1fb8d4
	const UINT32 srcByte = GetBytesPerPixel(SrcFormat);
Packit 1fb8d4
	const UINT32 copyDstWidth = nWidth * dstByte;
Packit 1fb8d4
	const UINT32 xSrcOffset = nXSrc * srcByte;
Packit 1fb8d4
	const UINT32 xDstOffset = nXDst * dstByte;
Packit 1fb8d4
	const BOOL vSrcVFlip = flags & FREERDP_FLIP_VERTICAL;
Packit 1fb8d4
	UINT32 srcVOffset = 0;
Packit 1fb8d4
	INT32 srcVMultiplier = 1;
Packit 1fb8d4
	UINT32 dstVOffset = 0;
Packit 1fb8d4
	INT32 dstVMultiplier = 1;
Packit 1fb8d4
Packit 1fb8d4
	if (!pDstData || !pSrcData)
Packit 1fb8d4
		return FALSE;
Packit 1fb8d4
Packit 1fb8d4
	if (nDstStep == 0)
Packit 1fb8d4
		nDstStep = nWidth * GetBytesPerPixel(DstFormat);
Packit 1fb8d4
Packit 1fb8d4
	if (nSrcStep == 0)
Packit 1fb8d4
		nSrcStep = nWidth * GetBytesPerPixel(SrcFormat);
Packit 1fb8d4
Packit 1fb8d4
	if (vSrcVFlip)
Packit 1fb8d4
	{
Packit 1fb8d4
		srcVOffset = (nHeight - 1) * nSrcStep;
Packit 1fb8d4
		srcVMultiplier = -1;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (AreColorFormatsEqualNoAlpha(SrcFormat, DstFormat))
Packit 1fb8d4
	{
Packit 1fb8d4
		INT32 y;
Packit 1fb8d4
Packit 1fb8d4
		if (overlapping(pDstData, nXDst, nYDst, nDstStep, dstByte,
Packit 1fb8d4
		                pSrcData, nXSrc, nYSrc, nSrcStep, srcByte,
Packit 1fb8d4
		                nWidth, nHeight))
Packit 1fb8d4
		{
Packit 1fb8d4
			/* Copy down */
Packit 1fb8d4
			if (nYDst < nYSrc)
Packit 1fb8d4
			{
Packit 1fb8d4
				for (y = 0; y < nHeight; y++)
Packit 1fb8d4
				{
Packit 1fb8d4
					const BYTE* srcLine = &pSrcData[(y + nYSrc) *
Packit 1fb8d4
					                                            nSrcStep * srcVMultiplier +
Packit 1fb8d4
					                                            srcVOffset];
Packit 1fb8d4
					BYTE* dstLine = &pDstData[(y + nYDst) *
Packit 1fb8d4
					                                      nDstStep * dstVMultiplier +
Packit 1fb8d4
					                                      dstVOffset];
Packit 1fb8d4
					memcpy(&dstLine[xDstOffset],
Packit 1fb8d4
					       &srcLine[xSrcOffset], copyDstWidth);
Packit 1fb8d4
				}
Packit 1fb8d4
			}
Packit 1fb8d4
			/* Copy up */
Packit 1fb8d4
			else if (nYDst > nYSrc)
Packit 1fb8d4
			{
Packit 1fb8d4
				for (y = nHeight - 1; y >= 0; y--)
Packit 1fb8d4
				{
Packit 1fb8d4
					const BYTE* srcLine = &pSrcData[(y + nYSrc) *
Packit 1fb8d4
					                                            nSrcStep * srcVMultiplier +
Packit 1fb8d4
					                                            srcVOffset];
Packit 1fb8d4
					BYTE* dstLine = &pDstData[(y + nYDst) *
Packit 1fb8d4
					                                      nDstStep * dstVMultiplier +
Packit 1fb8d4
					                                      dstVOffset];
Packit 1fb8d4
					memcpy(&dstLine[xDstOffset],
Packit 1fb8d4
					       &srcLine[xSrcOffset], copyDstWidth);
Packit 1fb8d4
				}
Packit 1fb8d4
			}
Packit 1fb8d4
			/* Copy left */
Packit 1fb8d4
			else if (nXSrc > nXDst)
Packit 1fb8d4
			{
Packit 1fb8d4
				for (y = 0; y < nHeight; y++)
Packit 1fb8d4
				{
Packit 1fb8d4
					const BYTE* srcLine = &pSrcData[(y + nYSrc) *
Packit 1fb8d4
					                                            nSrcStep * srcVMultiplier +
Packit 1fb8d4
					                                            srcVOffset];
Packit 1fb8d4
					BYTE* dstLine = &pDstData[(y + nYDst) *
Packit 1fb8d4
					                                      nDstStep * dstVMultiplier +
Packit 1fb8d4
					                                      dstVOffset];
Packit 1fb8d4
					memmove(&dstLine[xDstOffset],
Packit 1fb8d4
					        &srcLine[xSrcOffset], copyDstWidth);
Packit 1fb8d4
				}
Packit 1fb8d4
			}
Packit 1fb8d4
			/* Copy right */
Packit 1fb8d4
			else if (nXSrc < nXDst)
Packit 1fb8d4
			{
Packit 1fb8d4
				for (y = nHeight - 1; y >= 0; y--)
Packit 1fb8d4
				{
Packit 1fb8d4
					const BYTE* srcLine = &pSrcData[(y + nYSrc) *
Packit 1fb8d4
					                                            nSrcStep * srcVMultiplier +
Packit 1fb8d4
					                                            srcVOffset];
Packit 1fb8d4
					BYTE* dstLine = &pDstData[(y + nYDst) *
Packit 1fb8d4
					                                      nDstStep * dstVMultiplier +
Packit 1fb8d4
					                                      dstVOffset];
Packit 1fb8d4
					memmove(&dstLine[xDstOffset],
Packit 1fb8d4
					        &srcLine[xSrcOffset], copyDstWidth);
Packit 1fb8d4
				}
Packit 1fb8d4
			}
Packit 1fb8d4
			/* Source and destination are equal... */
Packit 1fb8d4
			else
Packit 1fb8d4
			{
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			for (y = 0; y < nHeight; y++)
Packit 1fb8d4
			{
Packit 1fb8d4
				const BYTE* srcLine = &pSrcData[(y + nYSrc) *
Packit 1fb8d4
				                                            nSrcStep * srcVMultiplier +
Packit 1fb8d4
				                                            srcVOffset];
Packit 1fb8d4
				BYTE* dstLine = &pDstData[(y + nYDst) *
Packit 1fb8d4
				                                      nDstStep * dstVMultiplier +
Packit 1fb8d4
				                                      dstVOffset];
Packit 1fb8d4
				memcpy(&dstLine[xDstOffset],
Packit 1fb8d4
				       &srcLine[xSrcOffset], copyDstWidth);
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		UINT32 x, y;
Packit 1fb8d4
Packit 1fb8d4
		for (y = 0; y < nHeight; y++)
Packit 1fb8d4
		{
Packit 1fb8d4
			const BYTE* srcLine = &pSrcData[(y + nYSrc) *
Packit 1fb8d4
			                                            nSrcStep * srcVMultiplier +
Packit 1fb8d4
			                                            srcVOffset];
Packit 1fb8d4
			BYTE* dstLine = &pDstData[(y + nYDst) *
Packit 1fb8d4
			                                      nDstStep * dstVMultiplier + dstVOffset];
Packit 1fb8d4
Packit 1fb8d4
			for (x = 0; x < nWidth; x++)
Packit 1fb8d4
			{
Packit 1fb8d4
				UINT32 dstColor;
Packit 1fb8d4
				UINT32 color = ReadColor(&srcLine[(x + nXSrc) * srcByte],
Packit 1fb8d4
				                         SrcFormat);
Packit 1fb8d4
				dstColor = FreeRDPConvertColor(color, SrcFormat, DstFormat, palette);
Packit 1fb8d4
				WriteColor(&dstLine[(x + nXDst) * dstByte], DstFormat, dstColor);
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL freerdp_image_fill(BYTE* pDstData, DWORD DstFormat,
Packit 1fb8d4
                        UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst,
Packit 1fb8d4
                        UINT32 nWidth, UINT32 nHeight, UINT32 color)
Packit 1fb8d4
{
Packit 1fb8d4
	UINT32 x, y;
Packit 1fb8d4
	const UINT32 bpp = GetBytesPerPixel(DstFormat);
Packit 1fb8d4
	BYTE* pFirstDstLine = &pDstData[nYDst * nDstStep];
Packit 1fb8d4
	BYTE* pFirstDstLineXOffset = &pFirstDstLine[nXDst * bpp];
Packit 1fb8d4
Packit 1fb8d4
	for (x = 0; x < nWidth; x++)
Packit 1fb8d4
	{
Packit 1fb8d4
		BYTE* pDst = &pFirstDstLine[(x + nXDst) * bpp];
Packit 1fb8d4
		WriteColor(pDst, DstFormat, color);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	for (y = 1; y < nHeight; y++)
Packit 1fb8d4
	{
Packit 1fb8d4
		BYTE* pDstLine = &pDstData[(y + nYDst) * nDstStep + nXDst * bpp];
Packit 1fb8d4
		memcpy(pDstLine, pFirstDstLineXOffset, nWidth * bpp);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return TRUE;
Packit 1fb8d4
}