WindowsXP-SP1/windows/advcore/gdiplus/engine/render/soquantize.cpp
2020-09-30 16:53:49 +02:00

218 lines
4.7 KiB
C++

/**************************************************************************\
*
* Copyright (c) 1999-2000 Microsoft Corporation
*
* Module name:
*
* The "Quantize" scan operation.
*
* Abstract:
*
* See Gdiplus\Specs\ScanOperation.doc for an overview.
*
* This module implements scan operations for converting pixels from
* one format, to another of less color precision.
* "Quantize" uses a simple, fixed mapping, which maps each source color
* level to a particular destination color level.
*
* Notes:
*
* The "Quantize" operation is fast but can cause Mach banding.
* An alternative is the "Halftone" operation, in SOHalftone.cpp.
*
* Revision History:
*
* 05/13/1999 davidx
* Created it.
* 12/01/1999 agodfrey
* Moved to it from Imaging\Api\convertfmt.cpp.
*
\**************************************************************************/
#include "precomp.hpp"
/**************************************************************************\
*
* Operation Description:
*
* Quantize: Quickly convert format down from 32bpp ARGB.
*
* Arguments:
*
* dst - The destination scan
* src - The source scan (32bpp ARGB)
* count - The length of the scan, in pixels
* otherParams - Additional data. (Ignored.)
*
* Return Value:
*
* None
*
* History:
*
* 05/13/1999 davidx
* Created it.
* 12/02/1999 agodfrey
* Moved & reorganized it.
*
\**************************************************************************/
// Quantize from sRGB to 16bpp RGB555
VOID FASTCALL
ScanOperation::Quantize_sRGB_555(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, WORD)
while (count--)
{
ARGB argb = *s++;
*d++ = (WORD) ((((argb >> (RED_SHIFT+3)) & 0x1f) << 10) |
(((argb >> (GREEN_SHIFT+3)) & 0x1f) << 5) |
((argb >> (BLUE_SHIFT+3)) & 0x1f));
}
}
// Quantize from sRGB to 16bpp RGB565
VOID FASTCALL
ScanOperation::Quantize_sRGB_565(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, WORD)
while (count--)
{
ARGB argb = *s++;
*d++ = (WORD) ((((argb >> (RED_SHIFT+3)) & 0x1f) << 11) |
(((argb >> (GREEN_SHIFT+2)) & 0x3f) << 5) |
((argb >> (BLUE_SHIFT+3)) & 0x1f));
}
}
// Quantize from sRGB to 16bpp RGB1555
VOID FASTCALL
ScanOperation::Quantize_sRGB_1555(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, WORD)
while (count--)
{
ARGB argb = *s++;
// NOTE: Very crude conversion of alpha data
// from 8bpp down to 1bpp
*d++ = (WORD) ((((argb >> ALPHA_SHIFT) >= 128) ? 0x8000 : 0) |
(((argb >> (RED_SHIFT+3)) & 0x1f) << 10) |
(((argb >> (GREEN_SHIFT+3)) & 0x1f) << 5) |
((argb >> (BLUE_SHIFT+3)) & 0x1f));
}
}
// Quantize from sRGB to 24bpp RGB
VOID FASTCALL
ScanOperation::Quantize_sRGB_24(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, BYTE)
while (count--)
{
ARGB argb = *s++;
d[0] = (BYTE) (argb >> BLUE_SHIFT);
d[1] = (BYTE) (argb >> GREEN_SHIFT);
d[2] = (BYTE) (argb >> RED_SHIFT);
d += 3;
}
}
// Quantize from sRGB to 24bpp BGR
VOID FASTCALL
ScanOperation::Quantize_sRGB_24BGR(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, BYTE)
while (count--)
{
ARGB argb = *s++;
d[0] = (BYTE) (argb >> RED_SHIFT);
d[1] = (BYTE) (argb >> GREEN_SHIFT);
d[2] = (BYTE) (argb >> BLUE_SHIFT);
d += 3;
}
}
// Quantize from sRGB to 32bpp RGB
VOID FASTCALL
ScanOperation::Quantize_sRGB_32RGB(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB, ARGB)
while (count--)
{
*d++ = *s++ | ALPHA_MASK;
}
}
// Quantize from sRGB64 to 48bpp RGB
VOID FASTCALL
ScanOperation::Quantize_sRGB64_48(
VOID *dst,
const VOID *src,
INT count,
const OtherParams *otherParams
)
{
DEFINE_POINTERS(ARGB64, INT16)
while (count--)
{
sRGB::sRGB64Color c;
c.argb = *s++;
d[0] = c.b;
d[1] = c.g;
d[2] = c.r;
d += 3;
}
}