218 lines
4.7 KiB
C++
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;
|
|
}
|
|
}
|
|
|