2011-07-01 05:23:36 +04:00
|
|
|
/**
|
|
|
|
* FreeRDP: A Remote Desktop Protocol Client
|
2011-09-14 00:30:16 +04:00
|
|
|
* Color Conversion Routines
|
2011-07-01 05:23:36 +04:00
|
|
|
*
|
|
|
|
* Copyright 2010 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <freerdp/freerdp.h>
|
2011-10-03 04:28:20 +04:00
|
|
|
#include <freerdp/codec/color.h>
|
2011-07-01 05:23:36 +04:00
|
|
|
|
2011-09-29 08:33:16 +04:00
|
|
|
int freerdp_get_pixel(uint8 * data, int x, int y, int width, int height, int bpp)
|
|
|
|
{
|
|
|
|
int start;
|
|
|
|
int shift;
|
|
|
|
uint16 *src16;
|
|
|
|
uint32 *src32;
|
|
|
|
int red, green, blue;
|
|
|
|
|
|
|
|
switch (bpp)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
width = (width + 7) / 8;
|
|
|
|
start = (y * width) + x / 8;
|
|
|
|
shift = x % 8;
|
|
|
|
return (data[start] & (0x80 >> shift)) != 0;
|
|
|
|
case 8:
|
|
|
|
return data[y * width + x];
|
|
|
|
case 15:
|
|
|
|
case 16:
|
|
|
|
src16 = (uint16*) data;
|
|
|
|
return src16[y * width + x];
|
|
|
|
case 24:
|
|
|
|
data += y * width * 3;
|
|
|
|
data += x * 3;
|
|
|
|
red = data[0];
|
|
|
|
green = data[1];
|
|
|
|
blue = data[2];
|
|
|
|
return RGB24(red, green, blue);
|
|
|
|
case 32:
|
|
|
|
src32 = (uint32*) data;
|
|
|
|
return src32[y * width + x];
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void freerdp_set_pixel(uint8* data, int x, int y, int width, int height, int bpp, int pixel)
|
|
|
|
{
|
|
|
|
int start;
|
|
|
|
int shift;
|
|
|
|
int *dst32;
|
|
|
|
|
|
|
|
if (bpp == 1)
|
|
|
|
{
|
|
|
|
width = (width + 7) / 8;
|
|
|
|
start = (y * width) + x / 8;
|
|
|
|
shift = x % 8;
|
|
|
|
if (pixel)
|
|
|
|
data[start] = data[start] | (0x80 >> shift);
|
|
|
|
else
|
|
|
|
data[start] = data[start] & ~(0x80 >> shift);
|
|
|
|
}
|
|
|
|
else if (bpp == 32)
|
|
|
|
{
|
|
|
|
dst32 = (int*) data;
|
|
|
|
dst32[y * width + x] = pixel;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint32 freerdp_color_convert_rgb(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
uint8 red = 0;
|
|
|
|
uint8 green = 0;
|
|
|
|
uint8 blue = 0;
|
|
|
|
uint8 alpha = 0xFF;
|
|
|
|
int dstColor = 0;
|
|
|
|
|
|
|
|
switch (srcBpp)
|
|
|
|
{
|
|
|
|
case 32:
|
|
|
|
if (clrconv->alpha)
|
|
|
|
{
|
2011-10-25 06:12:57 +04:00
|
|
|
GetARGB32(alpha, red, green, blue, srcColor);
|
2011-07-01 05:23:36 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetBGR32(red, green, blue, srcColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
GetBGR24(red, green, blue, srcColor);
|
|
|
|
break;
|
|
|
|
case 16:
|
2011-10-25 06:12:57 +04:00
|
|
|
GetBGR16(red, green, blue, srcColor);
|
2011-07-01 05:23:36 +04:00
|
|
|
break;
|
|
|
|
case 15:
|
2011-10-25 06:12:57 +04:00
|
|
|
GetBGR15(red, green, blue, srcColor);
|
2011-07-01 05:23:36 +04:00
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
srcColor &= 0xFF;
|
|
|
|
red = clrconv->palette->entries[srcColor].red;
|
|
|
|
green = clrconv->palette->entries[srcColor].green;
|
|
|
|
blue = clrconv->palette->entries[srcColor].blue;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (srcColor != 0)
|
|
|
|
{
|
|
|
|
red = 0xFF;
|
|
|
|
green = 0xFF;
|
|
|
|
blue = 0xFF;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (dstBpp)
|
|
|
|
{
|
|
|
|
case 32:
|
2011-10-25 06:12:57 +04:00
|
|
|
dstColor = ABGR32(alpha, red, green, blue);
|
2011-07-01 05:23:36 +04:00
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
dstColor = BGR24(red, green, blue);
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if(clrconv->rgb555)
|
|
|
|
{
|
|
|
|
dstColor = RGB15(red, green, blue);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dstColor = RGB16(red, green, blue);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
dstColor = RGB15(red, green, blue);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
srcColor &= 0xFF;
|
|
|
|
red = clrconv->palette->entries[srcColor].red;
|
|
|
|
green = clrconv->palette->entries[srcColor].green;
|
|
|
|
blue = clrconv->palette->entries[srcColor].blue;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if ((red != 0) || (green != 0) || (blue != 0))
|
|
|
|
dstColor = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dstColor;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint32 freerdp_color_convert_bgr(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
uint8 red = 0;
|
|
|
|
uint8 green = 0;
|
|
|
|
uint8 blue = 0;
|
|
|
|
uint8 alpha = 0xFF;
|
|
|
|
int dstColor = 0;
|
|
|
|
|
|
|
|
switch (srcBpp)
|
|
|
|
{
|
|
|
|
case 32:
|
|
|
|
if (clrconv->alpha)
|
|
|
|
{
|
|
|
|
GetABGR32(alpha, red, green, blue, srcColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GetBGR32(red, green, blue, srcColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
GetBGR24(red, green, blue, srcColor);
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
GetRGB16(red, green, blue, srcColor);
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
GetRGB15(red, green, blue, srcColor);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
srcColor &= 0xFF;
|
|
|
|
red = clrconv->palette->entries[srcColor].red;
|
|
|
|
green = clrconv->palette->entries[srcColor].green;
|
|
|
|
blue = clrconv->palette->entries[srcColor].blue;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if (srcColor != 0)
|
|
|
|
{
|
|
|
|
red = 0xFF;
|
|
|
|
green = 0xFF;
|
|
|
|
blue = 0xFF;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (dstBpp)
|
|
|
|
{
|
|
|
|
case 32:
|
|
|
|
dstColor = ABGR32(alpha, red, green, blue);
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
dstColor = BGR24(red, green, blue);
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
if(clrconv->rgb555)
|
|
|
|
{
|
|
|
|
dstColor = BGR15(red, green, blue);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dstColor = BGR16(red, green, blue);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
dstColor = BGR15(red, green, blue);
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
srcColor &= 0xFF;
|
|
|
|
red = clrconv->palette->entries[srcColor].red;
|
|
|
|
green = clrconv->palette->entries[srcColor].green;
|
|
|
|
blue = clrconv->palette->entries[srcColor].blue;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
if ((red != 0) || (green != 0) || (blue != 0))
|
|
|
|
dstColor = 1;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dstColor;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint32 freerdp_color_convert(uint32 srcColor, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
if (clrconv->invert)
|
2011-09-14 03:03:06 +04:00
|
|
|
return freerdp_color_convert_bgr(srcColor, srcBpp, dstBpp, clrconv);
|
2011-07-01 05:23:36 +04:00
|
|
|
else
|
2011-09-14 03:03:06 +04:00
|
|
|
return freerdp_color_convert_rgb(srcColor, srcBpp, dstBpp, clrconv);
|
2011-07-01 05:23:36 +04:00
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_image_convert_8bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint8 red;
|
|
|
|
uint8 green;
|
|
|
|
uint8 blue;
|
|
|
|
uint32 pixel;
|
|
|
|
uint8 *src8;
|
|
|
|
uint16 *dst16;
|
|
|
|
uint32 *dst32;
|
|
|
|
|
|
|
|
if (dstBpp == 8)
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height);
|
|
|
|
|
|
|
|
memcpy(dstData, srcData, width * height);
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 15 || (dstBpp == 16 && clrconv->rgb555))
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
|
|
|
|
dst16 = (uint16 *) dstData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
pixel = *srcData;
|
|
|
|
srcData++;
|
|
|
|
red = clrconv->palette->entries[pixel].red;
|
|
|
|
green = clrconv->palette->entries[pixel].green;
|
|
|
|
blue = clrconv->palette->entries[pixel].blue;
|
|
|
|
pixel = RGB15(red, green, blue);
|
|
|
|
*dst16 = pixel;
|
|
|
|
dst16++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 16)
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
|
|
|
|
dst16 = (uint16 *) dstData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
pixel = *srcData;
|
|
|
|
srcData++;
|
|
|
|
red = clrconv->palette->entries[pixel].red;
|
|
|
|
green = clrconv->palette->entries[pixel].green;
|
|
|
|
blue = clrconv->palette->entries[pixel].blue;
|
|
|
|
pixel = RGB16(red, green, blue);
|
|
|
|
*dst16 = pixel;
|
|
|
|
dst16++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 32)
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
|
|
|
|
src8 = (uint8*) srcData;
|
|
|
|
dst32 = (uint32*) dstData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
pixel = *src8;
|
|
|
|
src8++;
|
|
|
|
red = clrconv->palette->entries[pixel].red;
|
|
|
|
green = clrconv->palette->entries[pixel].green;
|
|
|
|
blue = clrconv->palette->entries[pixel].blue;
|
|
|
|
pixel = BGR32(red, green, blue);
|
|
|
|
*dst32 = pixel;
|
|
|
|
dst32++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_image_convert_15bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint8 red;
|
|
|
|
uint8 green;
|
|
|
|
uint8 blue;
|
|
|
|
uint32 pixel;
|
|
|
|
uint16 *src16;
|
|
|
|
uint16 *dst16;
|
|
|
|
uint32 *dst32;
|
|
|
|
|
|
|
|
if (dstBpp == 15 || (dstBpp == 16 && clrconv->rgb555))
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
|
|
|
|
memcpy(dstData, srcData, width * height * 2);
|
|
|
|
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 32)
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
|
|
|
|
src16 = (uint16 *) srcData;
|
|
|
|
dst32 = (uint32 *) dstData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
pixel = *src16;
|
|
|
|
src16++;
|
2011-10-25 06:12:57 +04:00
|
|
|
GetBGR15(red, green, blue, pixel);
|
2011-07-01 05:23:36 +04:00
|
|
|
pixel = BGR32(red, green, blue);
|
|
|
|
*dst32 = pixel;
|
|
|
|
dst32++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 16)
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
|
|
|
|
src16 = (uint16 *) srcData;
|
|
|
|
dst16 = (uint16 *) dstData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
pixel = *src16;
|
|
|
|
src16++;
|
|
|
|
GetRGB_555(red, green, blue, pixel);
|
|
|
|
RGB_555_565(red, green, blue);
|
|
|
|
pixel = RGB565(red, green, blue);
|
|
|
|
*dst16 = pixel;
|
|
|
|
dst16++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_image_convert_16bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
if (srcBpp == 15)
|
2011-09-14 03:03:06 +04:00
|
|
|
return freerdp_image_convert_15bpp(srcData, dstData, width, height, srcBpp, dstBpp, clrconv);
|
2011-07-01 05:23:36 +04:00
|
|
|
|
|
|
|
if (dstBpp == 16)
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
|
|
|
|
if(clrconv->rgb555)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint8 red, green, blue;
|
|
|
|
uint16* src16 = (uint16 *) srcData;
|
|
|
|
uint16* dst16 = (uint16 *) dstData;
|
|
|
|
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
GetRGB_565(red, green, blue, (*src16));
|
|
|
|
RGB_565_555(red, green, blue);
|
|
|
|
(*dst16) = RGB555(red, green, blue);
|
|
|
|
src16++;
|
|
|
|
dst16++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
memcpy(dstData, srcData, width * height * 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 24)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint8 *dst8;
|
|
|
|
uint16 *src16;
|
|
|
|
uint8 red, green, blue;
|
|
|
|
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 3);
|
|
|
|
|
|
|
|
dst8 = (uint8 *) dstData;
|
|
|
|
src16 = (uint16 *) srcData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
GetBGR16(red, green, blue, *src16);
|
|
|
|
src16++;
|
|
|
|
|
|
|
|
if (clrconv->invert)
|
|
|
|
{
|
|
|
|
*dst8++ = blue;
|
|
|
|
*dst8++ = green;
|
|
|
|
*dst8++ = red;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*dst8++ = red;
|
|
|
|
*dst8++ = green;
|
|
|
|
*dst8++ = blue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 32)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint32 pixel;
|
|
|
|
uint16 *src16;
|
|
|
|
uint32 *dst32;
|
|
|
|
uint8 red, green, blue;
|
|
|
|
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
|
|
|
|
src16 = (uint16 *) srcData;
|
|
|
|
dst32 = (uint32 *) dstData;
|
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
|
|
|
pixel = *src16;
|
|
|
|
src16++;
|
|
|
|
GetBGR16(red, green, blue, pixel);
|
|
|
|
pixel = BGR32(red, green, blue);
|
|
|
|
*dst32 = pixel;
|
|
|
|
dst32++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_image_convert_24bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (dstBpp == 32)
|
|
|
|
{
|
2011-11-24 05:15:14 +04:00
|
|
|
uint8 *dstp;
|
2011-07-01 05:23:36 +04:00
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
|
2011-11-24 05:15:14 +04:00
|
|
|
dstp = dstData;
|
2011-07-01 05:23:36 +04:00
|
|
|
for (i = width * height; i > 0; i--)
|
|
|
|
{
|
2011-11-24 05:15:14 +04:00
|
|
|
*(dstp++) = *(srcData++);
|
|
|
|
*(dstp++) = *(srcData++);
|
|
|
|
*(dstp++) = *(srcData++);
|
|
|
|
*(dstp++) = 0xFF;
|
2011-07-01 05:23:36 +04:00
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_image_convert_32bpp(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
if (dstBpp == 16)
|
|
|
|
{
|
|
|
|
int index;
|
|
|
|
uint16 *dst16;
|
|
|
|
uint32 *src32;
|
|
|
|
uint8 red, green, blue;
|
|
|
|
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
|
|
|
|
dst16 = (uint16*) dstData;
|
|
|
|
src32 = (uint32*) srcData;
|
|
|
|
|
|
|
|
for (index = 0; index < width * height; index++)
|
|
|
|
{
|
|
|
|
GetBGR32(blue, green, red, *src32);
|
|
|
|
*dst16 = RGB16(red, green, blue);
|
|
|
|
src32++;
|
|
|
|
dst16++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 24)
|
|
|
|
{
|
2011-11-24 05:15:14 +04:00
|
|
|
uint8 *dstp;
|
2011-07-01 05:23:36 +04:00
|
|
|
int index;
|
|
|
|
uint8 red, green, blue;
|
|
|
|
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 3);
|
|
|
|
|
2011-11-24 05:15:14 +04:00
|
|
|
dstp = dstData;
|
2011-07-01 05:23:36 +04:00
|
|
|
for (index = 0; index < width * height; index++)
|
|
|
|
{
|
|
|
|
red = *(srcData++);
|
|
|
|
green = *(srcData++);
|
|
|
|
blue = *(srcData++);
|
|
|
|
|
|
|
|
if (clrconv->invert)
|
|
|
|
{
|
2011-11-24 05:15:14 +04:00
|
|
|
*dstp++ = blue;
|
|
|
|
*dstp++ = green;
|
|
|
|
*dstp++ = red;
|
2011-07-01 05:23:36 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-11-24 05:15:14 +04:00
|
|
|
*dstp++ = red;
|
|
|
|
*dstp++ = green;
|
|
|
|
*dstp++ = blue;
|
2011-07-01 05:23:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
srcData++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if (dstBpp == 32)
|
|
|
|
{
|
|
|
|
if (clrconv->alpha)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
uint8 *dstp;
|
|
|
|
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
|
|
|
|
memcpy(dstData, srcData, width * height * 4);
|
|
|
|
|
|
|
|
dstp = dstData;
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < width * 4; x += 4)
|
|
|
|
{
|
|
|
|
dstp += 3;
|
|
|
|
*dstp = 0xFF;
|
|
|
|
dstp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
|
|
|
|
memcpy(dstData, srcData, width * height * 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
p_freerdp_image_convert freerdp_image_convert_[5] =
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
NULL,
|
2011-09-14 03:03:06 +04:00
|
|
|
freerdp_image_convert_8bpp,
|
|
|
|
freerdp_image_convert_16bpp,
|
|
|
|
freerdp_image_convert_24bpp,
|
|
|
|
freerdp_image_convert_32bpp
|
2011-07-01 05:23:36 +04:00
|
|
|
};
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_image_convert(uint8* srcData, uint8* dstData, int width, int height, int srcBpp, int dstBpp, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
2011-09-14 03:03:06 +04:00
|
|
|
p_freerdp_image_convert _p_freerdp_image_convert = freerdp_image_convert_[IBPP(srcBpp)];
|
2011-07-01 05:23:36 +04:00
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
if (_p_freerdp_image_convert != NULL)
|
|
|
|
return _p_freerdp_image_convert(srcData, dstData, width, height, srcBpp, dstBpp, clrconv);
|
2011-07-01 05:23:36 +04:00
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-10-05 05:29:01 +04:00
|
|
|
uint8* freerdp_image_flip(uint8* srcData, uint8* dstData, int width, int height, int bpp)
|
2011-08-22 06:30:49 +04:00
|
|
|
{
|
|
|
|
int y;
|
|
|
|
uint8* srcp;
|
|
|
|
uint8* dstp;
|
|
|
|
int scanline;
|
|
|
|
|
|
|
|
scanline = width * (bpp / 8);
|
|
|
|
|
|
|
|
if (dstData == NULL)
|
|
|
|
dstData = (uint8*) malloc(width * height * (bpp / 8));
|
|
|
|
|
|
|
|
dstp = dstData;
|
|
|
|
srcp = &srcData[scanline * (height - 1)];
|
|
|
|
|
|
|
|
for (y = height - 1; y >= 0; y--)
|
|
|
|
{
|
|
|
|
memcpy(dstp, srcp, scanline);
|
|
|
|
dstp += scanline;
|
|
|
|
srcp -= scanline;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_icon_convert(uint8* srcData, uint8* dstData, uint8* mask, int width, int height, int bpp, HCLRCONV clrconv)
|
2011-08-22 06:30:49 +04:00
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
int pixel;
|
|
|
|
uint8* data;
|
|
|
|
uint8 bmask;
|
|
|
|
uint32 pmask;
|
|
|
|
uint32* icon;
|
|
|
|
|
|
|
|
pixel = 0;
|
2011-10-05 05:29:01 +04:00
|
|
|
data = freerdp_image_flip(srcData, dstData, width, height, bpp);
|
2011-09-14 03:03:06 +04:00
|
|
|
dstData = freerdp_image_convert(data, NULL, width, height, bpp, 32, clrconv);
|
2011-08-22 06:30:49 +04:00
|
|
|
|
|
|
|
free(data);
|
|
|
|
bmask = mask[pixel];
|
|
|
|
icon = (uint32*) dstData;
|
|
|
|
|
|
|
|
if (bpp < 32)
|
|
|
|
{
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{
|
|
|
|
if (pixel % 8 == 0)
|
|
|
|
bmask = mask[pixel / 8];
|
|
|
|
else
|
|
|
|
bmask <<= 1;
|
|
|
|
|
|
|
|
pmask = (bmask & 0x80) ? 0x00000000 : 0xFF000000;
|
|
|
|
|
|
|
|
*icon++ |= pmask;
|
|
|
|
|
|
|
|
pixel++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
free(mask);
|
|
|
|
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_glyph_convert(int width, int height, uint8* data)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
uint8 *srcp;
|
|
|
|
uint8 *dstp;
|
|
|
|
uint8 *dstData;
|
|
|
|
int scanline;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* converts a 1-bit-per-pixel glyph to a one-byte-per-pixel glyph:
|
|
|
|
* this approach uses a little more memory, but provides faster
|
|
|
|
* means of accessing individual pixels in blitting operations
|
|
|
|
*/
|
|
|
|
|
|
|
|
scanline = (width + 7) / 8;
|
|
|
|
dstData = (uint8*) malloc(width * height);
|
|
|
|
memset(dstData, 0, width * height);
|
|
|
|
dstp = dstData;
|
|
|
|
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
srcp = data + (y * scanline);
|
|
|
|
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{
|
|
|
|
if ((*srcp & (0x80 >> (x % 8))) != 0)
|
|
|
|
*dstp = 0xFF;
|
|
|
|
dstp++;
|
|
|
|
|
|
|
|
if (((x + 1) % 8 == 0) && x != 0)
|
|
|
|
srcp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
2011-09-14 03:03:06 +04:00
|
|
|
uint8* freerdp_mono_image_convert(uint8* srcData, int width, int height, int srcBpp, int dstBpp, uint32 bgcolor, uint32 fgcolor, HCLRCONV clrconv)
|
2011-07-01 05:23:36 +04:00
|
|
|
{
|
|
|
|
int index;
|
|
|
|
uint16* dst16;
|
|
|
|
uint32* dst32;
|
|
|
|
uint8* dstData;
|
|
|
|
uint8 bitMask;
|
|
|
|
int bitIndex;
|
|
|
|
uint8 redBg, greenBg, blueBg;
|
|
|
|
uint8 redFg, greenFg, blueFg;
|
|
|
|
|
|
|
|
switch (srcBpp)
|
|
|
|
{
|
|
|
|
case 8:
|
|
|
|
bgcolor &= 0xFF;
|
|
|
|
redBg = clrconv->palette->entries[bgcolor].red;
|
|
|
|
greenBg = clrconv->palette->entries[bgcolor].green;
|
|
|
|
blueBg = clrconv->palette->entries[bgcolor].blue;
|
|
|
|
|
|
|
|
fgcolor &= 0xFF;
|
|
|
|
redFg = clrconv->palette->entries[fgcolor].red;
|
|
|
|
greenFg = clrconv->palette->entries[fgcolor].green;
|
|
|
|
blueFg = clrconv->palette->entries[fgcolor].blue;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
GetRGB16(redBg, greenBg, blueBg, bgcolor);
|
|
|
|
GetRGB16(redFg, greenFg, blueFg, fgcolor);
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
GetRGB15(redBg, greenBg, blueBg, bgcolor);
|
|
|
|
GetRGB15(redFg, greenFg, blueFg, fgcolor);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
GetRGB32(redBg, greenBg, blueBg, bgcolor);
|
|
|
|
GetRGB32(redFg, greenFg, blueFg, fgcolor);
|
2011-07-07 19:27:24 +04:00
|
|
|
break;
|
2011-07-01 05:23:36 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if(dstBpp == 16)
|
|
|
|
{
|
|
|
|
if(clrconv->rgb555)
|
|
|
|
{
|
|
|
|
if(srcBpp == 16)
|
|
|
|
{
|
|
|
|
/* convert 15-bit colors to 16-bit colors */
|
|
|
|
RGB16_RGB15(redBg, greenBg, blueBg, bgcolor);
|
|
|
|
RGB16_RGB15(redFg, greenFg, blueFg, fgcolor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(srcBpp == 15)
|
|
|
|
{
|
|
|
|
/* convert 15-bit colors to 16-bit colors */
|
|
|
|
RGB15_RGB16(redBg, greenBg, blueBg, bgcolor);
|
|
|
|
RGB15_RGB16(redFg, greenFg, blueFg, fgcolor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dstData = (uint8*) malloc(width * height * 2);
|
|
|
|
dst16 = (uint16*) dstData;
|
|
|
|
for(index = height; index > 0; index--)
|
|
|
|
{
|
|
|
|
/* each bit encodes a pixel */
|
|
|
|
bitMask = *srcData;
|
|
|
|
for(bitIndex = 7; bitIndex >= 0; bitIndex--)
|
|
|
|
{
|
|
|
|
if((bitMask >> bitIndex) & 0x01)
|
|
|
|
{
|
|
|
|
*dst16 = bgcolor;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*dst16 = fgcolor;
|
|
|
|
}
|
|
|
|
dst16++;
|
|
|
|
}
|
|
|
|
srcData++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
else if(dstBpp == 32)
|
|
|
|
{
|
|
|
|
dstData = (uint8*) malloc(width * height * 4);
|
|
|
|
dst32 = (uint32*) dstData;
|
|
|
|
for(index = height; index > 0; index--)
|
|
|
|
{
|
|
|
|
/* each bit encodes a pixel */
|
|
|
|
bitMask = *srcData;
|
|
|
|
for(bitIndex = 7; bitIndex >= 0; bitIndex--)
|
|
|
|
{
|
|
|
|
if((bitMask >> bitIndex) & 0x01)
|
|
|
|
{
|
|
|
|
*dst32 = RGB32(redBg, greenBg, blueBg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*dst32 = RGB32(redFg, greenFg, blueFg);
|
|
|
|
}
|
|
|
|
dst32++;
|
|
|
|
}
|
|
|
|
srcData++;
|
|
|
|
}
|
|
|
|
return dstData;
|
|
|
|
}
|
|
|
|
|
|
|
|
return srcData;
|
|
|
|
}
|
2011-09-29 08:33:16 +04:00
|
|
|
|
|
|
|
void freerdp_alpha_cursor_convert(uint8* alphaData, uint8* xorMask, uint8* andMask, int width, int height, int bpp, HCLRCONV clrconv)
|
|
|
|
{
|
|
|
|
int xpixel;
|
|
|
|
int apixel;
|
|
|
|
int i, j, jj;
|
|
|
|
|
|
|
|
for (j = 0; j < height; j++)
|
|
|
|
{
|
|
|
|
jj = (bpp == 1) ? j : (height - 1) - j;
|
|
|
|
for (i = 0; i < width; i++)
|
|
|
|
{
|
|
|
|
xpixel = freerdp_get_pixel(xorMask, i, jj, width, height, bpp);
|
|
|
|
xpixel = freerdp_color_convert(xpixel, bpp, 32, clrconv);
|
|
|
|
apixel = freerdp_get_pixel(andMask, i, jj, width, height, 1);
|
|
|
|
|
|
|
|
if (apixel != 0)
|
|
|
|
{
|
|
|
|
if ((xpixel & 0xffffff) == 0xffffff)
|
|
|
|
{
|
|
|
|
/* use pattern (not solid black) for xor area */
|
|
|
|
xpixel = (i & 1) == (j & 1);
|
2011-09-30 06:31:13 +04:00
|
|
|
xpixel = xpixel ? 0xFFFFFF : 0;
|
|
|
|
xpixel |= 0xFF000000;
|
2011-09-29 08:33:16 +04:00
|
|
|
}
|
2011-09-30 06:31:13 +04:00
|
|
|
else if (xpixel == 0xFF000000)
|
2011-09-29 08:33:16 +04:00
|
|
|
{
|
|
|
|
xpixel = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
freerdp_set_pixel(alphaData, i, j, width, height, 32, xpixel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-30 06:31:13 +04:00
|
|
|
void freerdp_image_swap_color_order(uint8* data, int width, int height)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
uint32* pixel;
|
|
|
|
uint8 a, r, g, b;
|
|
|
|
|
|
|
|
pixel = (uint32*) data;
|
|
|
|
|
|
|
|
for (y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
for (x = 0; x < width; x++)
|
|
|
|
{
|
|
|
|
GetARGB32(a, r, g, b, *pixel);
|
|
|
|
*pixel = ABGR32(a, r, g, b);
|
|
|
|
pixel++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|