|
Packit |
1fb8d4 |
/* FreeRDP: A Remote Desktop Protocol Client
|
|
Packit |
1fb8d4 |
* Color conversion operations.
|
|
Packit |
1fb8d4 |
* vi:ts=4 sw=4:
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Copyright 2011 Stephen Erisman
|
|
Packit |
1fb8d4 |
* Copyright 2011 Norbert Federa <norbert.federa@thincast.com>
|
|
Packit |
1fb8d4 |
* Copyright 2011 Martin Fleisz <martin.fleisz@thincast.com>
|
|
Packit |
1fb8d4 |
* (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
Packit |
1fb8d4 |
* not use this file except in compliance with the License. You may obtain
|
|
Packit |
1fb8d4 |
* a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
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
|
|
Packit |
1fb8d4 |
* or implied. See the License for the specific language governing
|
|
Packit |
1fb8d4 |
* permissions and 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 <freerdp/types.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/primitives.h>
|
|
Packit |
1fb8d4 |
#include <freerdp/codec/color.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include "prim_internal.h"
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#ifndef MINMAX
|
|
Packit |
1fb8d4 |
#define MINMAX(_v_, _l_, _h_) \
|
|
Packit |
1fb8d4 |
((_v_) < (_l_) ? (_l_) : ((_v_) > (_h_) ? (_h_) : (_v_)))
|
|
Packit |
1fb8d4 |
#endif /* !MINMAX */
|
|
Packit |
1fb8d4 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
1fb8d4 |
static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_BGRX(
|
|
Packit |
1fb8d4 |
const INT16* pSrc[3], UINT32 srcStep,
|
|
Packit |
1fb8d4 |
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 x, y;
|
|
Packit |
1fb8d4 |
BYTE* pRGB = pDst;
|
|
Packit |
1fb8d4 |
const INT16* pY = pSrc[0];
|
|
Packit |
1fb8d4 |
const INT16* pCb = pSrc[1];
|
|
Packit |
1fb8d4 |
const INT16* pCr = pSrc[2];
|
|
Packit |
1fb8d4 |
int srcPad = (srcStep - (roi->width * 2)) / 2;
|
|
Packit |
1fb8d4 |
int dstPad = (dstStep - (roi->width * 4)) / 4;
|
|
Packit |
1fb8d4 |
const DWORD formatSize = GetBytesPerPixel(DstFormat);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (y = 0; y < roi->height; y++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
for (x = 0; x < roi->width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
INT16 R, G, B;
|
|
Packit |
1fb8d4 |
const INT32 divisor = 16;
|
|
Packit |
1fb8d4 |
const INT32 Y = ((*pY++) + 4096) << divisor;
|
|
Packit |
1fb8d4 |
const INT32 Cb = (*pCb++);
|
|
Packit |
1fb8d4 |
const INT32 Cr = (*pCr++);
|
|
Packit |
1fb8d4 |
const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor));
|
|
Packit |
1fb8d4 |
const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor));
|
|
Packit |
1fb8d4 |
const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor));
|
|
Packit |
1fb8d4 |
const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor));
|
|
Packit |
1fb8d4 |
R = ((INT16)((CrR + Y) >> divisor) >> 5);
|
|
Packit |
1fb8d4 |
G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5);
|
|
Packit |
1fb8d4 |
B = ((INT16)((CbB + Y) >> divisor) >> 5);
|
|
Packit |
1fb8d4 |
pRGB = writePixelBGRX(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G),
|
|
Packit |
1fb8d4 |
CLIP(B), 0xFF);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
pY += srcPad;
|
|
Packit |
1fb8d4 |
pCb += srcPad;
|
|
Packit |
1fb8d4 |
pCr += srcPad;
|
|
Packit |
1fb8d4 |
pRGB += dstPad;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return PRIMITIVES_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_general(
|
|
Packit |
1fb8d4 |
const INT16* pSrc[3], UINT32 srcStep,
|
|
Packit |
1fb8d4 |
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 x, y;
|
|
Packit |
1fb8d4 |
BYTE* pRGB = pDst;
|
|
Packit |
1fb8d4 |
const INT16* pY = pSrc[0];
|
|
Packit |
1fb8d4 |
const INT16* pCb = pSrc[1];
|
|
Packit |
1fb8d4 |
const INT16* pCr = pSrc[2];
|
|
Packit |
1fb8d4 |
int srcPad = (srcStep - (roi->width * 2)) / 2;
|
|
Packit |
1fb8d4 |
int dstPad = (dstStep - (roi->width * 4)) / 4;
|
|
Packit |
1fb8d4 |
fkt_writePixel writePixel = getPixelWriteFunction(DstFormat);
|
|
Packit |
1fb8d4 |
const DWORD formatSize = GetBytesPerPixel(DstFormat);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (y = 0; y < roi->height; y++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
for (x = 0; x < roi->width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
INT16 R, G, B;
|
|
Packit |
1fb8d4 |
const INT32 divisor = 16;
|
|
Packit |
1fb8d4 |
const INT32 Y = ((*pY++) + 4096) << divisor;
|
|
Packit |
1fb8d4 |
const INT32 Cb = (*pCb++);
|
|
Packit |
1fb8d4 |
const INT32 Cr = (*pCr++);
|
|
Packit |
1fb8d4 |
const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor));
|
|
Packit |
1fb8d4 |
const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor));
|
|
Packit |
1fb8d4 |
const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor));
|
|
Packit |
1fb8d4 |
const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor));
|
|
Packit |
1fb8d4 |
R = ((INT16)((CrR + Y) >> divisor) >> 5);
|
|
Packit |
1fb8d4 |
G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5);
|
|
Packit |
1fb8d4 |
B = ((INT16)((CbB + Y) >> divisor) >> 5);
|
|
Packit |
1fb8d4 |
pRGB = (*writePixel)(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G),
|
|
Packit |
1fb8d4 |
CLIP(B), 0xFF);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
pY += srcPad;
|
|
Packit |
1fb8d4 |
pCb += srcPad;
|
|
Packit |
1fb8d4 |
pCr += srcPad;
|
|
Packit |
1fb8d4 |
pRGB += dstPad;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return PRIMITIVES_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(
|
|
Packit |
1fb8d4 |
const INT16* pSrc[3], UINT32 srcStep,
|
|
Packit |
1fb8d4 |
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
switch (DstFormat)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGRA32:
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGRX32:
|
|
Packit |
1fb8d4 |
return general_yCbCrToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
default:
|
|
Packit |
1fb8d4 |
return general_yCbCrToRGB_16s8u_P3AC4R_general(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static pstatus_t general_yCbCrToRGB_16s16s_P3P3(
|
|
Packit |
1fb8d4 |
const INT16* pSrc[3], INT32 srcStep,
|
|
Packit |
1fb8d4 |
INT16* pDst[3], INT32 dstStep,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi) /* region of interest */
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
/**
|
|
Packit |
1fb8d4 |
* The decoded YCbCr coeffectients are represented as 11.5 fixed-point
|
|
Packit |
1fb8d4 |
* numbers:
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* 1 sign bit + 10 integer bits + 5 fractional bits
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* However only 7 integer bits will be actually used since the value range
|
|
Packit |
1fb8d4 |
* is [-128.0, 127.0]. In other words, the decoded coefficients are scaled
|
|
Packit |
1fb8d4 |
* by << 5 when interpreted as INT16.
|
|
Packit |
1fb8d4 |
* It was scaled in the quantization phase, so we must scale it back here.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
const INT16* yptr = pSrc[0];
|
|
Packit |
1fb8d4 |
const INT16* cbptr = pSrc[1];
|
|
Packit |
1fb8d4 |
const INT16* crptr = pSrc[2];
|
|
Packit |
1fb8d4 |
INT16* rptr = pDst[0];
|
|
Packit |
1fb8d4 |
INT16* gptr = pDst[1];
|
|
Packit |
1fb8d4 |
INT16* bptr = pDst[2];
|
|
Packit |
1fb8d4 |
UINT32 srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16);
|
|
Packit |
1fb8d4 |
UINT32 dstbump = (dstStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16);
|
|
Packit |
1fb8d4 |
UINT32 y;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (y = 0; y < roi->height; y++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < roi->width; ++x)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
/* INT32 is used intentionally because we calculate
|
|
Packit |
1fb8d4 |
* with shifted factors!
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
INT32 y = (INT32)(*yptr++);
|
|
Packit |
1fb8d4 |
INT32 cb = (INT32)(*cbptr++);
|
|
Packit |
1fb8d4 |
INT32 cr = (INT32)(*crptr++);
|
|
Packit |
1fb8d4 |
INT32 r, g, b;
|
|
Packit |
1fb8d4 |
/*
|
|
Packit |
1fb8d4 |
* This is the slow floating point version kept here for reference.
|
|
Packit |
1fb8d4 |
* y = y + 4096; // 128<<5=4096 so that we can scale the sum by>>5
|
|
Packit |
1fb8d4 |
* r = y + cr*1.403f;
|
|
Packit |
1fb8d4 |
* g = y - cb*0.344f - cr*0.714f;
|
|
Packit |
1fb8d4 |
* b = y + cb*1.770f;
|
|
Packit |
1fb8d4 |
* y_r_buf[i] = CLIP(r>>5);
|
|
Packit |
1fb8d4 |
* cb_g_buf[i] = CLIP(g>>5);
|
|
Packit |
1fb8d4 |
* cr_b_buf[i] = CLIP(b>>5);
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
/*
|
|
Packit |
1fb8d4 |
* We scale the factors by << 16 into 32-bit integers in order to
|
|
Packit |
1fb8d4 |
* avoid slower floating point multiplications. Since the final
|
|
Packit |
1fb8d4 |
* result needs to be scaled by >> 5 we will extract only the
|
|
Packit |
1fb8d4 |
* upper 11 bits (>> 21) from the final sum.
|
|
Packit |
1fb8d4 |
* Hence we also have to scale the other terms of the sum by << 16.
|
|
Packit |
1fb8d4 |
* R: 1.403 << 16 = 91947
|
|
Packit |
1fb8d4 |
* G: 0.344 << 16 = 22544, 0.714 << 16 = 46792
|
|
Packit |
1fb8d4 |
* B: 1.770 << 16 = 115998
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
y = (y + 4096) << 16;
|
|
Packit |
1fb8d4 |
r = y + cr * 91947;
|
|
Packit |
1fb8d4 |
g = y - cb * 22544 - cr * 46792;
|
|
Packit |
1fb8d4 |
b = y + cb * 115998;
|
|
Packit |
1fb8d4 |
*rptr++ = CLIP(r >> 21);
|
|
Packit |
1fb8d4 |
*gptr++ = CLIP(g >> 21);
|
|
Packit |
1fb8d4 |
*bptr++ = CLIP(b >> 21);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
yptr += srcbump;
|
|
Packit |
1fb8d4 |
cbptr += srcbump;
|
|
Packit |
1fb8d4 |
crptr += srcbump;
|
|
Packit |
1fb8d4 |
rptr += dstbump;
|
|
Packit |
1fb8d4 |
gptr += dstbump;
|
|
Packit |
1fb8d4 |
bptr += dstbump;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return PRIMITIVES_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
1fb8d4 |
static pstatus_t general_RGBToYCbCr_16s16s_P3P3(
|
|
Packit |
1fb8d4 |
const INT16* pSrc[3], INT32 srcStep,
|
|
Packit |
1fb8d4 |
INT16* pDst[3], INT32 dstStep,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi) /* region of interest */
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
/* The encoded YCbCr coefficients are represented as 11.5 fixed-point
|
|
Packit |
1fb8d4 |
* numbers:
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* 1 sign bit + 10 integer bits + 5 fractional bits
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* However only 7 integer bits will be actually used since the value
|
|
Packit |
1fb8d4 |
* range is [-128.0, 127.0]. In other words, the encoded coefficients
|
|
Packit |
1fb8d4 |
* is scaled by << 5 when interpreted as INT16.
|
|
Packit |
1fb8d4 |
* It will be scaled down to original during the quantization phase.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
const INT16* rptr = pSrc[0];
|
|
Packit |
1fb8d4 |
const INT16* gptr = pSrc[1];
|
|
Packit |
1fb8d4 |
const INT16* bptr = pSrc[2];
|
|
Packit |
1fb8d4 |
INT16* yptr = pDst[0];
|
|
Packit |
1fb8d4 |
INT16* cbptr = pDst[1];
|
|
Packit |
1fb8d4 |
INT16* crptr = pDst[2];
|
|
Packit |
1fb8d4 |
UINT32 srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16);
|
|
Packit |
1fb8d4 |
UINT32 dstbump = (dstStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16);
|
|
Packit |
1fb8d4 |
UINT32 y;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (y = 0; y < roi->height; y++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
UINT32 x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < roi->width; ++x)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
/* INT32 is used intentionally because we calculate with
|
|
Packit |
1fb8d4 |
* shifted factors!
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
INT32 r = (INT32)(*rptr++);
|
|
Packit |
1fb8d4 |
INT32 g = (INT32)(*gptr++);
|
|
Packit |
1fb8d4 |
INT32 b = (INT32)(*bptr++);
|
|
Packit |
1fb8d4 |
/* We scale the factors by << 15 into 32-bit integers in order
|
|
Packit |
1fb8d4 |
* to avoid slower floating point multiplications. Since the
|
|
Packit |
1fb8d4 |
* terms need to be scaled by << 5 we simply scale the final
|
|
Packit |
1fb8d4 |
* sum by >> 10
|
|
Packit |
1fb8d4 |
*
|
|
Packit |
1fb8d4 |
* Y: 0.299000 << 15 = 9798, 0.587000 << 15 = 19235,
|
|
Packit |
1fb8d4 |
* 0.114000 << 15 = 3735
|
|
Packit |
1fb8d4 |
* Cb: 0.168935 << 15 = 5535, 0.331665 << 15 = 10868,
|
|
Packit |
1fb8d4 |
* 0.500590 << 15 = 16403
|
|
Packit |
1fb8d4 |
* Cr: 0.499813 << 15 = 16377, 0.418531 << 15 = 13714,
|
|
Packit |
1fb8d4 |
* 0.081282 << 15 = 2663
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
INT32 y = (r * 9798 + g * 19235 + b * 3735) >> 10;
|
|
Packit |
1fb8d4 |
INT32 cb = (r * -5535 + g * -10868 + b * 16403) >> 10;
|
|
Packit |
1fb8d4 |
INT32 cr = (r * 16377 + g * -13714 + b * -2663) >> 10;
|
|
Packit |
1fb8d4 |
*yptr++ = (INT16) MINMAX(y - 4096, -4096, 4095);
|
|
Packit |
1fb8d4 |
*cbptr++ = (INT16) MINMAX(cb, -4096, 4095);
|
|
Packit |
1fb8d4 |
*crptr++ = (INT16) MINMAX(cr, -4096, 4095);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
yptr += srcbump;
|
|
Packit |
1fb8d4 |
cbptr += srcbump;
|
|
Packit |
1fb8d4 |
crptr += srcbump;
|
|
Packit |
1fb8d4 |
rptr += dstbump;
|
|
Packit |
1fb8d4 |
gptr += dstbump;
|
|
Packit |
1fb8d4 |
bptr += dstbump;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return PRIMITIVES_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineGeneric(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
fkt_writePixel writePixel = getPixelWriteFunction(DstFormat);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
dst = (*writePixel)(dst, formatSize, DstFormat, *r++, *g++, *b++, 0xFF);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineRGB(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const BYTE R = CLIP(*r++);
|
|
Packit |
1fb8d4 |
const BYTE G = CLIP(*g++);
|
|
Packit |
1fb8d4 |
const BYTE B = CLIP(*b++);
|
|
Packit |
1fb8d4 |
*dst++ = R;
|
|
Packit |
1fb8d4 |
*dst++ = G;
|
|
Packit |
1fb8d4 |
*dst++ = B;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineBGR(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const BYTE R = CLIP(*r++);
|
|
Packit |
1fb8d4 |
const BYTE G = CLIP(*g++);
|
|
Packit |
1fb8d4 |
const BYTE B = CLIP(*b++);
|
|
Packit |
1fb8d4 |
*dst++ = B;
|
|
Packit |
1fb8d4 |
*dst++ = G;
|
|
Packit |
1fb8d4 |
*dst++ = R;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineBGRX(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const BYTE R = CLIP(*r++);
|
|
Packit |
1fb8d4 |
const BYTE G = CLIP(*g++);
|
|
Packit |
1fb8d4 |
const BYTE B = CLIP(*b++);
|
|
Packit |
1fb8d4 |
*dst++ = B;
|
|
Packit |
1fb8d4 |
*dst++ = G;
|
|
Packit |
1fb8d4 |
*dst++ = R;
|
|
Packit |
1fb8d4 |
*dst++ = 0xFF;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineRGBX(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const BYTE R = CLIP(*r++);
|
|
Packit |
1fb8d4 |
const BYTE G = CLIP(*g++);
|
|
Packit |
1fb8d4 |
const BYTE B = CLIP(*b++);
|
|
Packit |
1fb8d4 |
*dst++ = R;
|
|
Packit |
1fb8d4 |
*dst++ = G;
|
|
Packit |
1fb8d4 |
*dst++ = B;
|
|
Packit |
1fb8d4 |
*dst++ = 0xFF;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineXBGR(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const BYTE R = CLIP(*r++);
|
|
Packit |
1fb8d4 |
const BYTE G = CLIP(*g++);
|
|
Packit |
1fb8d4 |
const BYTE B = CLIP(*b++);
|
|
Packit |
1fb8d4 |
*dst++ = 0xFF;
|
|
Packit |
1fb8d4 |
*dst++ = B;
|
|
Packit |
1fb8d4 |
*dst++ = G;
|
|
Packit |
1fb8d4 |
*dst++ = R;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE void writeScanlineXRGB(BYTE* dst, DWORD formatSize, UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const INT16* r, const INT16* g, const INT16* b, DWORD width)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
DWORD x;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (x = 0; x < width; x++)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const BYTE R = CLIP(*r++);
|
|
Packit |
1fb8d4 |
const BYTE G = CLIP(*g++);
|
|
Packit |
1fb8d4 |
const BYTE B = CLIP(*b++);
|
|
Packit |
1fb8d4 |
*dst++ = 0xFF;
|
|
Packit |
1fb8d4 |
*dst++ = R;
|
|
Packit |
1fb8d4 |
*dst++ = G;
|
|
Packit |
1fb8d4 |
*dst++ = B;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
typedef void (*fkt_writeScanline)(BYTE*, DWORD, UINT32, const INT16*,
|
|
Packit |
1fb8d4 |
const INT16*, const INT16*, DWORD);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static INLINE fkt_writeScanline getScanlineWriteFunction(DWORD format)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
switch (format)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_ARGB32:
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_XRGB32:
|
|
Packit |
1fb8d4 |
return writeScanlineXRGB;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_ABGR32:
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_XBGR32:
|
|
Packit |
1fb8d4 |
return writeScanlineXBGR;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_RGBA32:
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_RGBX32:
|
|
Packit |
1fb8d4 |
return writeScanlineRGBX;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGRA32:
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGRX32:
|
|
Packit |
1fb8d4 |
return writeScanlineBGRX;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGR24:
|
|
Packit |
1fb8d4 |
return writeScanlineBGR;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_RGB24:
|
|
Packit |
1fb8d4 |
return writeScanlineRGB;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
default:
|
|
Packit |
1fb8d4 |
return writeScanlineGeneric;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
1fb8d4 |
static pstatus_t general_RGBToRGB_16s8u_P3AC4R_general(
|
|
Packit |
1fb8d4 |
const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */
|
|
Packit |
1fb8d4 |
UINT32 srcStep, /* bytes between rows in source data */
|
|
Packit |
1fb8d4 |
BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */
|
|
Packit |
1fb8d4 |
UINT32 dstStep, /* bytes between rows in dest data */
|
|
Packit |
1fb8d4 |
UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi) /* region of interest */
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const INT16* r = pSrc[0];
|
|
Packit |
1fb8d4 |
const INT16* g = pSrc[1];
|
|
Packit |
1fb8d4 |
const INT16* b = pSrc[2];
|
|
Packit |
1fb8d4 |
UINT32 y;
|
|
Packit |
1fb8d4 |
const DWORD srcAdd = srcStep / sizeof(INT16);
|
|
Packit |
1fb8d4 |
fkt_writeScanline writeScanline = getScanlineWriteFunction(DstFormat);
|
|
Packit |
1fb8d4 |
const DWORD formatSize = GetBytesPerPixel(DstFormat);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (y = 0; y < roi->height; ++y)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
(*writeScanline)(pDst, formatSize, DstFormat, r, g, b, roi->width);
|
|
Packit |
1fb8d4 |
pDst += dstStep;
|
|
Packit |
1fb8d4 |
r += srcAdd;
|
|
Packit |
1fb8d4 |
g += srcAdd;
|
|
Packit |
1fb8d4 |
b += srcAdd;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return PRIMITIVES_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static pstatus_t general_RGBToRGB_16s8u_P3AC4R_BGRX(
|
|
Packit |
1fb8d4 |
const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */
|
|
Packit |
1fb8d4 |
UINT32 srcStep, /* bytes between rows in source data */
|
|
Packit |
1fb8d4 |
BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */
|
|
Packit |
1fb8d4 |
UINT32 dstStep, /* bytes between rows in dest data */
|
|
Packit |
1fb8d4 |
UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi) /* region of interest */
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
const INT16* r = pSrc[0];
|
|
Packit |
1fb8d4 |
const INT16* g = pSrc[1];
|
|
Packit |
1fb8d4 |
const INT16* b = pSrc[2];
|
|
Packit |
1fb8d4 |
UINT32 y;
|
|
Packit |
1fb8d4 |
const DWORD srcAdd = srcStep / sizeof(INT16);
|
|
Packit |
1fb8d4 |
const DWORD formatSize = GetBytesPerPixel(DstFormat);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
for (y = 0; y < roi->height; ++y)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
writeScanlineBGRX(pDst, formatSize, DstFormat, r, g, b, roi->width);
|
|
Packit |
1fb8d4 |
pDst += dstStep;
|
|
Packit |
1fb8d4 |
r += srcAdd;
|
|
Packit |
1fb8d4 |
g += srcAdd;
|
|
Packit |
1fb8d4 |
b += srcAdd;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return PRIMITIVES_SUCCESS;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
static pstatus_t general_RGBToRGB_16s8u_P3AC4R(
|
|
Packit |
1fb8d4 |
const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */
|
|
Packit |
1fb8d4 |
UINT32 srcStep, /* bytes between rows in source data */
|
|
Packit |
1fb8d4 |
BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */
|
|
Packit |
1fb8d4 |
UINT32 dstStep, /* bytes between rows in dest data */
|
|
Packit |
1fb8d4 |
UINT32 DstFormat,
|
|
Packit |
1fb8d4 |
const prim_size_t* roi) /* region of interest */
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
switch (DstFormat)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGRA32:
|
|
Packit |
1fb8d4 |
case PIXEL_FORMAT_BGRX32:
|
|
Packit |
1fb8d4 |
return general_RGBToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
default:
|
|
Packit |
1fb8d4 |
return general_RGBToRGB_16s8u_P3AC4R_general(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
/* ------------------------------------------------------------------------- */
|
|
Packit |
1fb8d4 |
void primitives_init_colors(primitives_t* prims)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
prims->yCbCrToRGB_16s8u_P3AC4R = general_yCbCrToRGB_16s8u_P3AC4R;
|
|
Packit |
1fb8d4 |
prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3;
|
|
Packit |
1fb8d4 |
prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3;
|
|
Packit |
1fb8d4 |
prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
|
|
Packit |
1fb8d4 |
}
|