diff options
Diffstat (limited to 'avscamera/sys/Synthesizer.cpp')
| -rw-r--r-- | avscamera/sys/Synthesizer.cpp | 1282 |
1 files changed, 1282 insertions, 0 deletions
diff --git a/avscamera/sys/Synthesizer.cpp b/avscamera/sys/Synthesizer.cpp new file mode 100644 index 00000000..fbb0147f --- /dev/null +++ b/avscamera/sys/Synthesizer.cpp @@ -0,0 +1,1282 @@ +/************************************************************************** + + A/V Stream Camera Sample + + Copyright (c) 2014, Microsoft Corporation. + + File: + + Synthesizer.cpp + + Abstract: + + This file contains the implementation of CSynthesizer. + + The base image synthesis and overlay class. These classes provide + image synthesis (pixel, color-bar, etc...) onto buffers of various + formats. + + Internally, all CSynthesizer objects represent a pixel as a 32 bit + quantity with 8 bits per sample. The base CSynthesizer implements + all rendering functionality with this assumption in mind. It + simplifies rendering substantially and means we do not need to re- + implement rendering functions for each format. + + Most end formats can be synthesized from this uncompressed format + with overhead that is slightly worse than a copy. Color spaces are + handled by using a rendering palette that is unique for each. + + History: + + created 04/14/2014 + +**************************************************************************/ + +#include "Common.h" + +/************************************************************************** + + PAGED CODE + +**************************************************************************/ + +#ifdef ALLOC_PRAGMA +#pragma code_seg("PAGE") +#endif // ALLOC_PRAGMA + +/************************************************************************** + + Constants + +**************************************************************************/ + +// +// Standard definition of EIA-189-A color bars. The actual color definitions +// are either in CRGB24Synthesizer or CYUVSynthesizer. +// + +const COLOR CSynthesizer::m_ColorBars[8] = +{MAGENTA, BLUE, GREEN, BLACK, WHITE, YELLOW, RED, CYAN }; + + +// +// Corner registration block colors. +// +const COLOR g_TopLeft = GREY; +const COLOR g_TopRight = BLUE; +const COLOR g_BotLeft = RED; +const COLOR g_BotRight = GREEN; + +// +// Persistent stats. +// +LONGLONG CSynthesizer::m_RelPts=0; +LONGLONG CSynthesizer::m_QpcTime=0; +ULONG CSynthesizer::m_Frame=0; + +// +// The following is an 8x8 bitmapped font for use in the text overlay +// code. +// +const UCHAR +CSynthesizer:: +m_FontData [256][8] = +{ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e}, + {0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e}, + {0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00}, + {0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00}, + {0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c}, + {0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c}, + {0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00}, + {0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff}, + {0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00}, + {0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff}, + {0x0f, 0x07, 0x0f, 0x7d, 0xcc, 0xcc, 0xcc, 0x78}, + {0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18}, + {0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0}, + {0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0}, + {0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99}, + {0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00}, + {0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00}, + {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18}, + {0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x00}, + {0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x00}, + {0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78}, + {0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x00}, + {0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff}, + {0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00}, + {0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00}, + {0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00}, + {0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00}, + {0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00}, + {0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00}, + {0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x00, 0x00}, + {0x00, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x78, 0x78, 0x30, 0x30, 0x00, 0x30, 0x00}, + {0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x00}, + {0x30, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x30, 0x00}, + {0x00, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x00}, + {0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x00}, + {0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x00}, + {0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x00}, + {0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00}, + {0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x60}, + {0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00}, + {0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00}, + {0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x00}, + {0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x00}, + {0x78, 0xcc, 0x0c, 0x38, 0x60, 0xcc, 0xfc, 0x00}, + {0x78, 0xcc, 0x0c, 0x38, 0x0c, 0xcc, 0x78, 0x00}, + {0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x1e, 0x00}, + {0xfc, 0xc0, 0xf8, 0x0c, 0x0c, 0xcc, 0x78, 0x00}, + {0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x00}, + {0xfc, 0xcc, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x00}, + {0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x00}, + {0x78, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0x70, 0x00}, + {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x00}, + {0x00, 0x30, 0x30, 0x00, 0x00, 0x30, 0x30, 0x60}, + {0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x00}, + {0x00, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00}, + {0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00}, + {0x78, 0xcc, 0x0c, 0x18, 0x30, 0x00, 0x30, 0x00}, + {0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x00}, + {0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x00}, + {0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00}, + {0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x00}, + {0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00}, + {0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00}, + {0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x00}, + {0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x00}, + {0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x00}, + {0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78, 0x00}, + {0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x00}, + {0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00}, + {0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00}, + {0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x00}, + {0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00}, + {0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00}, + {0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x00}, + {0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00}, + {0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x00}, + {0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x00}, + {0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00}, + {0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x00}, + {0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x00}, + {0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x00}, + {0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x00}, + {0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x00}, + {0xc0, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x02, 0x00}, + {0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00}, + {0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + {0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x76, 0x00}, + {0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x00}, + {0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x00}, + {0x1c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0x76, 0x00}, + {0x00, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00}, + {0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x00}, + {0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8}, + {0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x00}, + {0x30, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0x0c, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0x78}, + {0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x00}, + {0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0x00, 0x00, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x00}, + {0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x00}, + {0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00}, + {0x00, 0x00, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0}, + {0x00, 0x00, 0x76, 0xcc, 0xcc, 0x7c, 0x0c, 0x1e}, + {0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x00}, + {0x00, 0x00, 0x7c, 0xc0, 0x78, 0x0c, 0xf8, 0x00}, + {0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x00}, + {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00}, + {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x00}, + {0x00, 0x00, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x00}, + {0x00, 0x00, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x00}, + {0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8}, + {0x00, 0x00, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x00}, + {0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x00}, + {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, + {0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x00}, + {0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x00}, + {0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x18, 0x0c, 0x78}, + {0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00}, + {0x1c, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00}, + {0x7e, 0xc3, 0x3c, 0x06, 0x3e, 0x66, 0x3f, 0x00}, + {0xcc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00}, + {0xe0, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00}, + {0x30, 0x30, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00}, + {0x00, 0x00, 0x78, 0xc0, 0xc0, 0x78, 0x0c, 0x38}, + {0x7e, 0xc3, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00}, + {0xcc, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00}, + {0xe0, 0x00, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x00}, + {0xcc, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0x7c, 0xc6, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x00}, + {0xe0, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0xc6, 0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00}, + {0x30, 0x30, 0x00, 0x78, 0xcc, 0xfc, 0xcc, 0x00}, + {0x1c, 0x00, 0xfc, 0x60, 0x78, 0x60, 0xfc, 0x00}, + {0x00, 0x00, 0x7f, 0x0c, 0x7f, 0xcc, 0x7f, 0x00}, + {0x3e, 0x6c, 0xcc, 0xfe, 0xcc, 0xcc, 0xce, 0x00}, + {0x78, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00}, + {0x00, 0xcc, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00}, + {0x00, 0xe0, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00}, + {0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00}, + {0x00, 0xe0, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00}, + {0x00, 0xcc, 0x00, 0xcc, 0xcc, 0x7c, 0x0c, 0xf8}, + {0xc3, 0x18, 0x3c, 0x66, 0x66, 0x3c, 0x18, 0x00}, + {0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00}, + {0x18, 0x18, 0x7e, 0xc0, 0xc0, 0x7e, 0x18, 0x18}, + {0x38, 0x6c, 0x64, 0xf0, 0x60, 0xe6, 0xfc, 0x00}, + {0xcc, 0xcc, 0x78, 0xfc, 0x30, 0xfc, 0x30, 0x30}, + {0xf8, 0xcc, 0xcc, 0xfa, 0xc6, 0xcf, 0xc6, 0xc7}, + {0x0e, 0x1b, 0x18, 0x3c, 0x18, 0x18, 0xd8, 0x70}, + {0x1c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0x7e, 0x00}, + {0x38, 0x00, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00}, + {0x00, 0x1c, 0x00, 0x78, 0xcc, 0xcc, 0x78, 0x00}, + {0x00, 0x1c, 0x00, 0xcc, 0xcc, 0xcc, 0x7e, 0x00}, + {0x00, 0xf8, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0x00}, + {0xfc, 0x00, 0xcc, 0xec, 0xfc, 0xdc, 0xcc, 0x00}, + {0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00}, + {0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00}, + {0x30, 0x00, 0x30, 0x60, 0xc0, 0xcc, 0x78, 0x00}, + {0x00, 0x00, 0x00, 0xfc, 0xc0, 0xc0, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x00, 0x00}, + {0xc3, 0xc6, 0xcc, 0xde, 0x33, 0x66, 0xcc, 0x0f}, + {0xc3, 0xc6, 0xcc, 0xdb, 0x37, 0x6f, 0xcf, 0x03}, + {0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00}, + {0x00, 0x33, 0x66, 0xcc, 0x66, 0x33, 0x00, 0x00}, + {0x00, 0xcc, 0x66, 0x33, 0x66, 0xcc, 0x00, 0x00}, + {0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88}, + {0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa}, + {0xdb, 0x77, 0xdb, 0xee, 0xdb, 0x77, 0xdb, 0xee}, + {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18}, + {0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36}, + {0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36}, + {0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18}, + {0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}, + {0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00}, + {0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00}, + {0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00}, + {0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18}, + {0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00}, + {0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18}, + {0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36}, + {0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00}, + {0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36}, + {0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00}, + {0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18}, + {0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00}, + {0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18}, + {0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36}, + {0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36}, + {0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff}, + {0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0}, + {0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f}, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x76, 0xdc, 0xc8, 0xdc, 0x76, 0x00}, + {0x00, 0x78, 0xcc, 0xf8, 0xcc, 0xf8, 0xc0, 0xc0}, + {0x00, 0xfc, 0xcc, 0xc0, 0xc0, 0xc0, 0xc0, 0x00}, + {0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00}, + {0xfc, 0xcc, 0x60, 0x30, 0x60, 0xcc, 0xfc, 0x00}, + {0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0x70, 0x00}, + {0x00, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xc0}, + {0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x00}, + {0xfc, 0x30, 0x78, 0xcc, 0xcc, 0x78, 0x30, 0xfc}, + {0x38, 0x6c, 0xc6, 0xfe, 0xc6, 0x6c, 0x38, 0x00}, + {0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x6c, 0xee, 0x00}, + {0x1c, 0x30, 0x18, 0x7c, 0xcc, 0xcc, 0x78, 0x00}, + {0x00, 0x00, 0x7e, 0xdb, 0xdb, 0x7e, 0x00, 0x00}, + {0x06, 0x0c, 0x7e, 0xdb, 0xdb, 0x7e, 0x60, 0xc0}, + {0x38, 0x60, 0xc0, 0xf8, 0xc0, 0x60, 0x38, 0x00}, + {0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x00}, + {0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00}, + {0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0xfc, 0x00}, + {0x60, 0x30, 0x18, 0x30, 0x60, 0x00, 0xfc, 0x00}, + {0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0xfc, 0x00}, + {0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18}, + {0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x70}, + {0x30, 0x30, 0x00, 0xfc, 0x00, 0x30, 0x30, 0x00}, + {0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00}, + {0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00}, + {0x0f, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x3c, 0x1c}, + {0x78, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00}, + {0x70, 0x18, 0x30, 0x60, 0x78, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +}; + +BOOLEAN +CSynthesizer:: +Initialize() +/*++ + +Routine Description: + + Class initialization. + + Set the buffer the synthesizer generates images to. + Override to do any additional processing you think is needed. + +Arguments: + + none + +Return Value: + + TRUE - success. + +--*/ +{ + PAGED_CODE(); + + // Capture the working palette. + // Recast it to a point to an array of primaries. + if( !(m_Colors = GetPalette()) ) + { + return FALSE; + } + + // Clear the globals. This occurs redundantly, but hey ... + // ... test output doesn't make sense if we don't do this. + m_RelPts=0; + m_QpcTime=0; + m_Frame=0; + + // + // Allocate a scratch buffer for the synthesizer. + // + NT_ASSERT(m_Length); + if( !m_Length ) + { + return FALSE; + } + + m_Buffer = new (PagedPool) UCHAR[m_Length]; + NT_ASSERT(m_Buffer); + if( !m_Buffer ) + { + return FALSE; + } + + // + // Allocate a scratch buffer for the Gradient. + // + m_GradientBmp = new (PagedPool) CKsRgbQuad[m_Width * MAX_COLOR]; + NT_ASSERT(m_GradientBmp); + if( !m_GradientBmp ) + { + SAFE_DELETE_ARRAY( m_Buffer ); + return FALSE; + } + + return TRUE; +} + +LONGLONG +ConvertPerfTime( + _In_ LONGLONG Freq, + _In_ LONGLONG Time +) +{ + PAGED_CODE(); + + LARGE_INTEGER tL ; + tL.QuadPart = Time; + return KSCONVERT_PERFORMANCE_TIME( Freq, tL ); +} + +void +CSynthesizer:: +Destroy() +/*++ + +Routine Description: + + Clean up from initialize. + + Note: A good place to generate synthesis stats. + +Arguments: + + none + +Return Value: + + void. + +--*/ +{ + PAGED_CODE(); + + SAFE_DELETE_ARRAY( m_Buffer ); + SAFE_DELETE_ARRAY( m_GradientBmp ); + + // Report rendering times. + DBG_TRACE( "Synthesis Time - Total = %lld", ConvertPerfTime( m_Frequency.QuadPart, m_SynthesisTime ) ); + DBG_TRACE( " Count = %d", m_SynthesisCount ); + DBG_TRACE( " Avg = %lld", ConvertPerfTime( m_Frequency.QuadPart, m_SynthesisCount ? m_SynthesisTime / m_SynthesisCount : 0 ) ); + DBG_TRACE( " Commit Time - Total = %lld", ConvertPerfTime( m_Frequency.QuadPart, m_CommitTime ) ); + DBG_TRACE( " Count = %d", m_CommitCount ); + DBG_TRACE( " Avg = %lld", ConvertPerfTime( m_Frequency.QuadPart, m_CommitCount ? m_CommitTime / m_CommitCount : 0 ) ); +} + +NTSTATUS +CSynthesizer:: +SynthesizeBars() +/*++ + +Routine Description: + + Synthesize EIA-189-A standard color bars onto the Image. The image + in question is the current synthesis buffer. + +Arguments: + + None + +Return Value: + + success / failure + +--*/ +{ + PAGED_CODE(); + + if( !m_Buffer ) + { + return STATUS_INVALID_DEVICE_STATE; + } + + const COLOR *CurColor = m_ColorBars; + ULONG ColorCount = SIZEOF_ARRAY (m_ColorBars); + + // + // Set the default cursor... + // + GetImageLocation (0, 0); + + // + // Synthesize a single line. + // + PUCHAR ImageStart = m_Cursor; + for (ULONG x = 0; x < m_Width; x++) + { + PutPixel (m_ColorBars [((x * ColorCount) / m_Width)]); + } + + PUCHAR ImageEnd = m_Cursor; + + // + // Copy the synthesized line to all subsequent lines. + // + for (ULONG line = 0; line < m_Height; line++) + { + GetImageLocation (0, line); + + RtlCopyMemory ( + m_Cursor, + ImageStart, + ImageEnd - ImageStart + ); + } + + // Paint the top left and top right registrations boxes. + GetImageLocation(0,0); + + ImageStart = m_Cursor; + for(ULONG x =0; x < m_Width; x++) + { + if(x < (m_Height/16)) + { + PutPixel(g_TopLeft); + } + else if(x > (m_Width - (m_Height / 16))) + { + PutPixel(g_TopRight); + } + else + { + PutPixel (m_ColorBars [((x * ColorCount) / m_Width)]); + } + } + + ImageEnd = m_Cursor; + + for (ULONG line = 0; line < m_Height/16; line++) + { + GetImageLocation (0, line); + + RtlCopyMemory ( + m_Cursor, + ImageStart, + ImageEnd - ImageStart + ); + } + + // Paint the bottom left and bottom right registrations boxes. + GetImageLocation(0, (15*m_Height) / 16); + ImageStart = m_Cursor; + for(ULONG x =0; x < m_Width; x++) + { + if(x < (m_Height/16)) + { + PutPixel(g_BotLeft); + } + else if(x > (m_Width - (m_Height / 16))) + { + PutPixel(g_BotRight); + } + else + { + PutPixel (m_ColorBars [((x * ColorCount) / m_Width)]); + } + } + + ImageEnd = m_Cursor; + + for (ULONG line = 0; line < m_Height/16; line++) + { + GetImageLocation (0, line+(15*m_Height) / 16); + + RtlCopyMemory ( + m_Cursor, + ImageStart, + ImageEnd - ImageStart + ); + } + + return STATUS_SUCCESS; +} + +void +CSynthesizer:: +EncodeNumber( + _In_ ULONG LocY, + _In_ UINT32 Number, + _In_ COLOR LowColor, + _In_ COLOR HighColor +) +/* +Routine Description: + + Overlays an encoded number over the synthesized image. The image buffer + used is the set synthesis buffer. The pattern is scaled to fit the image. + +Arguments: + + LocY - + The row on the image to begin the overlay. This must + be inside the image. + + Number - + The number to encode + + LowColor - + The color to represent 0 (a clear bit) + + HighColor - + The color to represent 1 (a set bit) + +Return Value: + + void + +*/ +{ + PAGED_CODE(); + + if( !m_Buffer ) + { + return; + } + + NT_ASSERT(LocY <= m_Height); + + GetImageLocation(0, LocY); + UINT32 mask = 0x1; + + PUCHAR ImageStart = m_Cursor; + for(ULONG i = 0; i < 32; i++) + { + for(ULONG j = 0; j < m_Width/32; j++) + { + if(Number & mask) + { + PutPixel(HighColor); + } + else + { + PutPixel(LowColor); + } + } + mask = mask << 1; + } + PUCHAR ImageEnd = m_Cursor; + + // + // Copy the synthesized line to all subsequent lines. + // + for (ULONG line = 1; line < m_Height/16; line++) + { + RtlCopyMemory ( + GetImageLocation (0, line + LocY), + ImageStart, + ImageEnd - ImageStart + ); + } +} + +void +CSynthesizer:: +OverlayText ( + _In_ ULONG LocX, + _In_ ULONG LocY, + _In_ ULONG Scaling, + _In_ LPSTR Text, + _In_ COLOR BgColor, + _In_ COLOR FgColor +) +/*++ + +Routine Description: + + Overlay text onto the synthesized image. Clip to fit the image + if the overlay does not fit. The image buffer used is the set + synthesis buffer. + +Arguments: + + LocX - + The X location on the image to begin the overlay. This MUST + be inside the image or no text will be rendered. + POSITION_CENTER may be used to indicate horizontal centering. + + LocY - + The Y location on the image to begin the overlay. This MUST + be inside the image or no text will be rendered. + POSITION_CENTER may be used to indicate vertical centering. + + Scaling - + Normally, the overlay is done in an 8x8 font. A scaling of + 2 indicates 16x16, 3 indicates 24x24 and so forth. + + Text - + A null terminated character string containing the information to + overlay + + BgColor - + The background color of the overlay window. For transparency, + indicate TRANSPARENT here. + + FgColor - + The foreground color for the text overlay. + +Return Value: + + None + +--*/ + +{ + PAGED_CODE(); + + // Validate internal state. + if( !m_Buffer ) + { + return; + } + + NT_ASSERT( (LocX <= m_Width || LocX == POSITION_CENTER) && + (LocY <= m_Height || LocY == POSITION_CENTER) && + Text !=nullptr && + (BgColor < MAX_COLOR || BgColor == TRANSPARENT) && + (FgColor < MAX_COLOR || FgColor == TRANSPARENT) + ); + + // Validate parameters. + if( !( (LocX <= m_Width || LocX == POSITION_CENTER) && + (LocY <= m_Height || LocY == POSITION_CENTER) && + Text !=nullptr && + (BgColor < MAX_COLOR || BgColor == TRANSPARENT) && + (FgColor < MAX_COLOR || FgColor == TRANSPARENT) ) ) + { + return; + } + + size_t StrLen = 0; + PCHAR CurChar; + + // + // Determine the character length of the string. + // + if( !NT_SUCCESS( RtlStringCchLengthA( Text, m_Width, &StrLen ) ) ) + { + // Invalid parameter. + return; + } + + // + // Determine the physical size of the string plus border. There is + // a definable NO_CHARACTER_SEPARATION. If this is defined, there will + // be no added space between font characters. Otherwise, one empty pixel + // column is added between characters. + // +#ifndef NO_CHARACTER_SEPARATION + ULONG LenX = (ULONG) ((StrLen * (((size_t)Scaling) << 3)) + 1 + StrLen); +#else // NO_CHARACTER_SEPARATION + ULONG LenX = (ULONG) ((StrLen * (((size_t_)Scaling) << 3)) + 2); +#endif // NO_CHARACTER_SEPARATION + + ULONG LenY = 2 + (Scaling << 3); + + // + // Adjust for center overlays. + // + // NOTE: If the overlay doesn't fit into the synthesis buffer, this + // merely left aligns the overlay and clips off the right side. + // + if (LocX == POSITION_CENTER) + { + //LocX = min( 0, ((LONG)m_Width - (LONG)LenX) >> 1); + if (LenX >= m_Width) + { + LocX = 0; + } + else + { + LocX = (m_Width - LenX) >> 1; + } + } + + if (LocY == POSITION_CENTER) + { + //LocY = min( 0, ((LONG)m_Width - (LONG)LenY) >> 1); + if (LenY >= m_Height) + { + LocY = 0; + } + else + { + LocY = (m_Height - LenY) >> 1; + } + } + + // + // Determine the amount of space available on the synthesis buffer. + // We will clip anything that finds itself outside the synthesis buffer. + // + ULONG SpaceX = m_Width - LocX; + ULONG SpaceY = m_Height - LocY; + + // + // Set the default cursor position. + // + GetImageLocation (LocX, LocY); + + // + // Overlay a background color row. + // + if( SpaceY ) + { + if( BgColor != TRANSPARENT ) + { + for (ULONG x = 0; x < LenX && x < SpaceX; x++) + { + PutPixel (BgColor); + } + } + SpaceY--; + } + LocY++; + + // + // Loop across each row of the image. + // + for (ULONG row = 0; row < 8 && SpaceY; row++) + { + // + // Generate a line. + // + GetImageLocation (LocX, LocY++); + + PUCHAR ImageStart = m_Cursor; + + ULONG CurSpaceX = SpaceX; + if (CurSpaceX) + { + PutPixel (BgColor); + CurSpaceX--; + } + + // + // Generate the row'th row of the overlay. + // + CurChar = Text; + while( *CurChar ) + { + UCHAR CharBase = m_FontData [*CurChar++][row]; + for (ULONG mask = 0x80; mask && CurSpaceX; mask >>= 1) + { + for (ULONG scale = 0; scale < Scaling && CurSpaceX; scale++) + { + if (CharBase & mask) + { + PutPixel (FgColor); + } + else + { + PutPixel (BgColor); + } + CurSpaceX--; + } + } + + // + // Separate each character by one space. Account for the border + // space at the end by placing the separator after the last + // character also. + // +#ifndef NO_CHARACTER_SEPARATION + if (CurSpaceX) + { + PutPixel (BgColor); + CurSpaceX--; + } +#endif // NO_CHARACTER_SEPARATION + } + + // + // If there is no separation character defined, account for the + // border. + // +#ifdef NO_CHARACTER_SEPARATION + if (CurSpaceX) + { + PutPixel (BgColor); + CurSpaceX--; + } +#endif // NO_CHARACTER_SEPARATION + + + PUCHAR ImageEnd = m_Cursor; + // + // Copy the line downward scale times. + // + for (ULONG scale = 1; scale < Scaling && SpaceY; scale++) + { + GetImageLocation (LocX, LocY++); + RtlCopyMemory (m_Cursor, ImageStart, ImageEnd - ImageStart); + SpaceY--; + } + } + + // + // Add the bottom section of the overlay. + // + GetImageLocation (LocX, LocY); + if (BgColor != TRANSPARENT && SpaceY) + { + for (ULONG x = 0; x < LenX && x < SpaceX; x++) + { + PutPixel (BgColor); + } + } +} + +void +CSynthesizer::ApplyGradient( + _In_ ULONG LocY, + _In_ COLOR Gradient +) +/*++ + +Routine Description: + + Synthesize a horizontal gradient bar from a given color + +Arguments: + + LocY - + row + + Gradient - + A starting color + +Return Value: + + void + +--*/ +{ + PAGED_CODE(); + + if( !m_Buffer ) + { + return; + } + + NT_ASSERT(LocY <= m_Height); + + PUCHAR Image = GetImageLocation(0, LocY); + PUCHAR RowBmp = reinterpret_cast<PUCHAR>(&m_GradientBmp[Gradient*m_Width]); + ULONG Stride = m_Width * sizeof(CKsRgbQuad); + + // + // Copy the synthesized line to all lines. + // + for (ULONG line = 0; line < m_Height/16; line++) + { + RtlCopyMemory ( + Image, + RowBmp, + Stride + ); + Image += Stride; + } +} + +// +// Synthesize +// +// Fill the image buffer with some base image. All h/w simulations will +// call this function to generate a base image - even for jpeg. +// +NTSTATUS +CSynthesizer:: +Synthesize() +/*++ + +Routine Description: + + Fill the image buffer with some base image. All h/w simulations will + call this function to generate a base image. + +Arguments: + + None + +Return Value: + + Success / failure + +--*/ +{ + PAGED_CODE(); + + if( !m_Buffer ) + { + return STATUS_INVALID_DEVICE_STATE; + } + + // + // Generate a "time stamp" just to overlay it onto the capture image. + // It makes it more exciting than bars that do nothing. + // + SynthesizeBars(); + + ApplyGradient( (m_Height)/16, RED); + ApplyGradient( (2*m_Height)/16, GREEN); + ApplyGradient( (3*m_Height)/16, BLUE); + ApplyGradient( (4*m_Height)/16, WHITE); + + EncodeNumber((5*m_Height)/16, (UINT32)m_Frame, BLACK, WHITE); + EncodeNumber((6*m_Height)/16, (UINT32)(m_QpcTime), BLACK, WHITE); + + CHAR Text [256]; + RtlStringCbPrintfA(Text, sizeof(Text), "Frame: %ld", m_Frame); + + // + // Overlay the frame # onto the scratch space image. + // + OverlayText ( + POSITION_CENTER, + (m_Height - 28), + 1, + Text, + BLACK, + WHITE + ); + + // + // Add a description of the frame type/width/height. + // + RtlStringCbPrintfA(Text, sizeof(Text), "%s (%dx%d)", m_FormatName, m_Width, m_Height); + OverlayText ( + 0, + (m_Height - 28), + 1, + Text, + BLACK, + WHITE + ); + return STATUS_SUCCESS; +} + +void +CSynthesizer::PutPixel ( + COLOR Color +) +/*++ + +Routine Description: + + Place a pixel at the default cursor location. The cursor location + must be set via GetImageLocation(x, y). + +Arguments: + + Color - + The pixel color to render + +Return Value: + + void + +--*/ +{ + PAGED_CODE(); + + PKS_RGBQUAD &pPixel = (PKS_RGBQUAD &) m_Cursor; + + if (Color != TRANSPARENT) + { + *pPixel = CKsRgbQuad( m_Colors[Color][2], m_Colors[Color][1], m_Colors[Color][0] ); + } + + // Next pixel + pPixel++; +} + +// +// PutPixel(): +// +// Place a pixel at the default cursor location. The cursor location +// must be set via GetImageLocation(x, y). +// +void +CSynthesizer::PutPixel ( + UCHAR colorR, + UCHAR colorB, + UCHAR colorG +) +/*++ + +Routine Description: + + Place a pixel at the default cursor location. The cursor location + must be set via GetImageLocation(x, y). + + TODO: Remove. This function appears to be dead code. + +Arguments: + + colorR - + The first color primary of the pixel. + + colorB - + The third color primary of the pixel. + + colorG - + The second color primary of the pixel. + + +Return Value: + + void + +--*/ +{ + PAGED_CODE(); + + PKS_RGBQUAD &pPixel = (PKS_RGBQUAD &) m_Cursor; + + *pPixel++ = CKsRgbQuad( colorR, colorG, colorB ); +} + + +// +// Synthesize +// +// Fill the image buffer with some base image. All h/w simulations will +// call this function to generate a base image - even for jpeg. +// +NTSTATUS +CSynthesizer:: +DoSynthesize() +{ + PAGED_CODE(); + + LARGE_INTEGER StartTime = {0}; + LARGE_INTEGER EndTime = {0}; + + StartTime = KeQueryPerformanceCounter(NULL); + + NTSTATUS Status = Synthesize(); + + m_SynthesisTime += KeQueryPerformanceCounter(NULL).QuadPart - StartTime.QuadPart; + m_SynthesisCount++; + + return Status; +} + +// +// Commit +// +// Copy (and reformat, if necessary) pixels from the internal scratch +// buffer. If the output format decimates chrominance, do it here. +// +_Success_(return > 0) +ULONG +CSynthesizer:: +DoCommit( + _Out_writes_bytes_(Size) + PUCHAR Buffer, + _In_ ULONG Size, + _In_ ULONG Stride +) +{ + PAGED_CODE(); + + LARGE_INTEGER StartTime = KeQueryPerformanceCounter(NULL); + + ULONG n = Commit( Buffer, Size, Stride ); + + m_CommitTime += KeQueryPerformanceCounter(NULL).QuadPart - StartTime.QuadPart; + m_CommitCount++; + + return n; +} + +// +// DoCommit +// +// Note: The stride needs to be a function of the bits per pixel of the +// OUTPUT format - not the format we store it in. The class ctor +// must initialize m_OutputStride to a default stride value. +// +_Success_(return > 0) +ULONG +CSynthesizer:: +DoCommit( + _Out_writes_bytes_(Size) + PUCHAR Buffer, + _In_ ULONG Size +) +{ + PAGED_CODE(); + + LARGE_INTEGER StartTime = KeQueryPerformanceCounter(NULL); + + ULONG n = Commit( Buffer, Size ); + + m_CommitTime += KeQueryPerformanceCounter(NULL).QuadPart - StartTime.QuadPart; + m_CommitCount++; + + return n; +} + +#define CLEAR_HISTOGRAM( H ) \ + if( H ) \ + { \ + RtlZeroMemory( H, 256*sizeof(*H) ); \ + } + +#define BUMP_HISTOGRAM_PRIMARY( H, C ) \ + if( H ) \ + { \ + H[C]++; \ + } + +// +// Histogram +// +// Fill an array with histogram data. +// +void +CSynthesizer:: +Histogram( + _Out_writes_opt_(256) + PULONG HistogramP0, // rgbRed + _Out_writes_opt_(256) + PULONG HistogramP1, // rgbGreen + _Out_writes_opt_(256) + PULONG HistogramP2 // rgbBlue +) +/*++ + +Routine Description: + + Fill array(s) with histogram data. + +Arguments: + + HistogramP0 - + Stats on the first primary. + + HistogramP1 - + Stats on the second primary. + + HistogramP2 - + Stats on the third primary. + +Return Value: + + void + +--*/ +{ + PAGED_CODE(); + + CLEAR_HISTOGRAM( HistogramP0 ); + CLEAR_HISTOGRAM( HistogramP1 ); + CLEAR_HISTOGRAM( HistogramP2 ); + + ULONG row, col; + + for( row=0; row<m_Height; row++ ) + { + PKS_RGBQUAD pPixel = (PKS_RGBQUAD) GetImageLocation(0, row); + + for( col=0; col<m_Width; col++ ) + { + BUMP_HISTOGRAM_PRIMARY( HistogramP0, pPixel->rgbRed ); + BUMP_HISTOGRAM_PRIMARY( HistogramP1, pPixel->rgbGreen ); + BUMP_HISTOGRAM_PRIMARY( HistogramP2, pPixel->rgbBlue ); + } + } +} |
