22 #ifndef QDENGINE_QDCORE_UTIL_2_PASS_SCALE_H 23 #define QDENGINE_QDCORE_UTIL_2_PASS_SCALE_H 25 #include "qdengine/qdcore/util/Filters.h" 45 template <
class FilterClass>
49 C2PassScale() : _temp_buffer(65536, 0), _weights_buffer(16384, 0.0), _contribution_buffer(500) { }
52 uint32 *scale(uint32 *pOrigImage, uint32 uOrigWidth, uint32 uOrigHeight, uint32 *pDstImage, uint32 uNewWidth, uint32 uNewHeight);
62 LineContribType *allocContributions(uint32 uLineLength, uint32 uWindowSize);
63 LineContribType *calcContributions(uint32 uLineSize, uint32 uSrcSize,
double dScale);
65 void scaleRow(uint32 *pSrc, uint32 uSrcWidth, uint32 *pRes, uint32 uResWidth, uint32 uRow,
LineContribType *Contrib);
66 void horizScale(uint32 *pSrc, uint32 uSrcWidth, uint32 uSrcHeight, uint32 *pDst, uint32 uResWidth, uint32 uResHeight);
67 void scaleCol(uint32 *pSrc, uint32 uSrcWidth, uint32 *pRes, uint32 uResWidth, uint32 uResHeight, uint32 uCol,
LineContribType *Contrib);
68 void vertScale(uint32 *pSrc, uint32 uSrcWidth, uint32 uSrcHeight, uint32 *pDst, uint32 uResWidth, uint32 uResHeight);
70 static inline byte make_r(uint32 col) {
71 return reinterpret_cast<byte *
>(&col)[2];
73 static inline byte make_g(uint32 col) {
74 return reinterpret_cast<byte *
>(&col)[1];
76 static inline byte make_b(uint32 col) {
77 return reinterpret_cast<byte *
>(&col)[0];
79 static inline byte make_a(uint32 col) {
80 return reinterpret_cast<byte *
>(&col)[3];
83 static inline uint32 make_rgba(byte r, byte g, byte b, byte a) {
84 return (r << 16) | (g << 8) | (b << 0) | (a << 24);
88 template<
class FilterClass>
92 line_ct.windowSize = uWindowSize;
93 line_ct.lineLength = uLineLength;
95 if (_contribution_buffer.size() < uLineLength)
96 _contribution_buffer.resize(uLineLength);
98 line_ct.contribRow = &*_contribution_buffer.begin();
100 if (_weights_buffer.
size() < uLineLength * uWindowSize)
101 _weights_buffer.
resize(uLineLength * uWindowSize);
103 double *p = &*_weights_buffer.
begin();
105 for (uint32 u = 0; u < uLineLength; u++) {
106 line_ct.contribRow[u].weights = p;
112 template <
class FilterClass>
114 FilterClass curFilter;
117 double dFScale = 1.0;
118 double dFilterWidth = curFilter.getWidth();
121 dWidth = dFilterWidth / dScale;
124 dWidth = dFilterWidth;
128 int iWindowSize = 2 * (int)ceil(dWidth) + 1;
133 for (uint32 u = 0; u < uLineSize; u++) {
135 double dCenter = (double)u / dScale;
137 int iLeft =
MAX(0, (
int)floor(dCenter - dWidth));
138 int iRight =
MIN((
int)ceil(dCenter + dWidth),
int(uSrcSize) - 1);
141 if (iRight - iLeft + 1 > iWindowSize) {
142 if (iLeft < (
int(uSrcSize) - 1 / 2)) {
149 res->contribRow[u].left = iLeft;
150 res->contribRow[u].right = iRight;
152 double dTotalWeight = 0.0;
153 for (
int iSrc = iLeft; iSrc <= iRight; iSrc++) {
155 dTotalWeight += (res->contribRow[u].weights[iSrc - iLeft] = dFScale * curFilter.filter(dFScale * (dCenter - (
double)iSrc)));
157 ASSERT(dTotalWeight >= 0.0);
158 if (dTotalWeight > 0.0) {
160 for (
int iSrc = iLeft; iSrc <= iRight; iSrc++) {
162 res->contribRow[u].weights[iSrc - iLeft] /= dTotalWeight;
169 template <
class FilterClass>
171 uint32 *pSrcRow = &(pSrc[uRow * uSrcWidth]);
172 uint32 *pDstRow = &(pRes[uRow * uResWidth]);
173 for (uint32 x = 0; x < uResWidth; x++) {
180 int iLeft = contrib->contribRow[x].left;
181 int iRight = contrib->contribRow[x].right;
182 for (
int i = iLeft; i <= iRight; i++) {
185 dr += contrib->contribRow[x].weights[i - iLeft] * (double)(make_r(pSrcRow[i]));
186 dg += contrib->contribRow[x].weights[i - iLeft] * (double)(make_g(pSrcRow[i]));
187 db += contrib->contribRow[x].weights[i - iLeft] * (double)(make_b(pSrcRow[i]));
188 da += contrib->contribRow[x].weights[i - iLeft] * (double)(make_a(pSrcRow[i]));
191 uint32 r = round(dr);
192 uint32 g = round(dg);
193 uint32 b = round(db);
194 uint32 a = round(da);
196 pDstRow[x] = make_rgba(r, g, b, a);
200 template <
class FilterClass>
202 TRACE(
"Performing horizontal scaling...\n");
203 if (uResWidth == uSrcWidth) {
205 memcpy(pDst, pSrc,
sizeof(uint32) * uSrcHeight * uSrcWidth);
209 LineContribType *contrib = calcContributions(uResWidth, uSrcWidth,
double(uResWidth) /
double(uSrcWidth));
210 for (uint32 u = 0; u < uResHeight; u++)
211 scaleRow(pSrc, uSrcWidth, pDst, uResWidth, u, contrib);
214 template <
class FilterClass>
216 for (uint32 y = 0; y < uResHeight; y++) {
223 int iLeft = contrib->contribRow[y].left;
224 int iRight = contrib->contribRow[y].right;
225 for (
int i = iLeft; i <= iRight; i++) {
228 uint32 pCurSrc = pSrc[i * uSrcWidth + uCol];
229 dr += contrib->contribRow[y].weights[i - iLeft] * (double)(make_r(pCurSrc));
230 dg += contrib->contribRow[y].weights[i - iLeft] * (double)(make_g(pCurSrc));
231 db += contrib->contribRow[y].weights[i - iLeft] * (double)(make_b(pCurSrc));
232 da += contrib->contribRow[y].weights[i - iLeft] * (double)(make_a(pCurSrc));
235 uint32 r = round(dr);
236 uint32 g = round(dg);
237 uint32 b = round(db);
238 uint32 a = round(da);
240 pRes[y * uResWidth + uCol] = make_rgba(r, g, b, a);
244 template <
class FilterClass>
246 TRACE(
"Performing vertical scaling...");
248 if (uSrcHeight == uResHeight) {
250 memcpy(pDst, pSrc,
sizeof(uint32) * uSrcHeight * uSrcWidth);
254 LineContribType *Contrib = calcContributions(uResHeight, uSrcHeight,
double(uResHeight) /
double(uSrcHeight));
255 for (uint32 u = 0; u < uResWidth; u++)
256 scaleCol(pSrc, uSrcWidth, pDst, uResWidth, uResHeight, u, Contrib);
259 template <
class FilterClass>
260 uint32 *
C2PassScale<FilterClass>::scale(uint32 *pOrigImage, uint32 uOrigWidth, uint32 uOrigHeight, uint32 *pDstImage, uint32 uNewWidth, uint32 uNewHeight) {
261 if (_temp_buffer.
size() < uNewWidth * uOrigHeight)
262 _temp_buffer.
resize(uNewWidth * uOrigHeight);
264 uint32 *pTemp =
reinterpret_cast<uint32 *
>(&*_temp_buffer.
begin());
265 horizScale(pOrigImage, uOrigWidth, uOrigHeight, pTemp, uNewWidth, uOrigHeight);
268 vertScale(pTemp, uNewWidth, uOrigHeight, pDstImage, uNewWidth, uNewHeight);
277 #endif // QDENGINE_QDCORE_UTIL_2_PASS_SCALE_H Definition: 2PassScale.h:34
Definition: 2PassScale.h:46
iterator begin()
Definition: array.h:374
Базовый класс для игровых ресурсов.
Definition: console.h:28
Definition: 2PassScale.h:39
size_type size() const
Definition: array.h:315
void resize(size_type newSize)
Definition: array.h:411
T MIN(T a, T b)
Definition: util.h:59
T MAX(T a, T b)
Definition: util.h:62