OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 return FXDIB_8bppMask; | 25 return FXDIB_8bppMask; |
26 if (format == FXDIB_1bppRgb) | 26 if (format == FXDIB_1bppRgb) |
27 return FXDIB_8bppRgb; | 27 return FXDIB_8bppRgb; |
28 if (format == FXDIB_8bppRgb && src.GetPalette()) | 28 if (format == FXDIB_8bppRgb && src.GetPalette()) |
29 return FXDIB_Rgb; | 29 return FXDIB_Rgb; |
30 return format; | 30 return format; |
31 } | 31 } |
32 | 32 |
33 } // namespace | 33 } // namespace |
34 | 34 |
35 void CWeightTable::Calc(int dest_len, | 35 CWeightTable::CWeightTable() |
| 36 : m_DestMin(0), |
| 37 m_ItemSize(0), |
| 38 m_pWeightTables(nullptr), |
| 39 m_dwWeightTablesSize(0) {} |
| 40 |
| 41 CWeightTable::~CWeightTable() { |
| 42 FX_Free(m_pWeightTables); |
| 43 } |
| 44 |
| 45 bool CWeightTable::Calc(int dest_len, |
36 int dest_min, | 46 int dest_min, |
37 int dest_max, | 47 int dest_max, |
38 int src_len, | 48 int src_len, |
39 int src_min, | 49 int src_min, |
40 int src_max, | 50 int src_max, |
41 int flags) { | 51 int flags) { |
42 FX_Free(m_pWeightTables); | 52 FX_Free(m_pWeightTables); |
43 m_pWeightTables = nullptr; | 53 m_pWeightTables = nullptr; |
44 double scale, base; | 54 m_dwWeightTablesSize = 0; |
45 scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len; | 55 const double scale = (FX_FLOAT)src_len / (FX_FLOAT)dest_len; |
46 if (dest_len < 0) { | 56 const double base = dest_len < 0 ? (FX_FLOAT)(src_len) : 0; |
47 base = (FX_FLOAT)(src_len); | 57 const int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; |
48 } else { | |
49 base = 0; | |
50 } | |
51 int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1; | |
52 m_ItemSize = | 58 m_ItemSize = |
53 sizeof(int) * 2 + | 59 sizeof(int) * 2 + |
54 (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); | 60 (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size)); |
55 m_DestMin = dest_min; | 61 m_DestMin = dest_min; |
56 if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) { | 62 if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) |
57 return; | 63 return false; |
58 } | 64 |
59 m_pWeightTables = | 65 m_dwWeightTablesSize = (dest_max - dest_min) * m_ItemSize + 4; |
60 FX_TryAlloc(uint8_t, (dest_max - dest_min) * m_ItemSize + 4); | 66 m_pWeightTables = FX_TryAlloc(uint8_t, m_dwWeightTablesSize); |
61 if (!m_pWeightTables) { | 67 if (!m_pWeightTables) |
62 return; | 68 return false; |
63 } | 69 |
64 if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { | 70 if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) { |
65 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { | 71 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { |
66 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); | 72 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); |
67 double src_pos = dest_pixel * scale + scale / 2 + base; | 73 double src_pos = dest_pixel * scale + scale / 2 + base; |
68 if (flags & FXDIB_INTERPOL) { | 74 if (flags & FXDIB_INTERPOL) { |
69 pixel_weights.m_SrcStart = | 75 pixel_weights.m_SrcStart = |
70 (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); | 76 (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2); |
71 pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); | 77 pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2); |
72 if (pixel_weights.m_SrcStart < src_min) { | 78 if (pixel_weights.m_SrcStart < src_min) { |
73 pixel_weights.m_SrcStart = src_min; | 79 pixel_weights.m_SrcStart = src_min; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 (int)FXSYS_floor((FX_FLOAT)src_pos); | 178 (int)FXSYS_floor((FX_FLOAT)src_pos); |
173 if (pixel_weights.m_SrcStart < src_min) { | 179 if (pixel_weights.m_SrcStart < src_min) { |
174 pixel_weights.m_SrcStart = src_min; | 180 pixel_weights.m_SrcStart = src_min; |
175 } | 181 } |
176 if (pixel_weights.m_SrcEnd >= src_max) { | 182 if (pixel_weights.m_SrcEnd >= src_max) { |
177 pixel_weights.m_SrcEnd = src_max - 1; | 183 pixel_weights.m_SrcEnd = src_max - 1; |
178 } | 184 } |
179 pixel_weights.m_Weights[0] = 65536; | 185 pixel_weights.m_Weights[0] = 65536; |
180 } | 186 } |
181 } | 187 } |
182 return; | 188 return true; |
183 } | 189 } |
| 190 |
184 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { | 191 for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel++) { |
185 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); | 192 PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel); |
186 double src_start = dest_pixel * scale + base; | 193 double src_start = dest_pixel * scale + base; |
187 double src_end = src_start + scale; | 194 double src_end = src_start + scale; |
188 int start_i, end_i; | 195 int start_i, end_i; |
189 if (src_start < src_end) { | 196 if (src_start < src_end) { |
190 start_i = (int)FXSYS_floor((FX_FLOAT)src_start); | 197 start_i = (int)FXSYS_floor((FX_FLOAT)src_start); |
191 end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); | 198 end_i = (int)FXSYS_ceil((FX_FLOAT)src_end); |
192 } else { | 199 } else { |
193 start_i = (int)FXSYS_floor((FX_FLOAT)src_end); | 200 start_i = (int)FXSYS_floor((FX_FLOAT)src_end); |
(...skipping 27 matching lines...) Expand all Loading... |
221 ? dest_start | 228 ? dest_start |
222 : (FX_FLOAT)(dest_pixel); | 229 : (FX_FLOAT)(dest_pixel); |
223 double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) | 230 double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) |
224 ? (FX_FLOAT)(dest_pixel + 1) | 231 ? (FX_FLOAT)(dest_pixel + 1) |
225 : dest_end; | 232 : dest_end; |
226 double weight = area_start >= area_end ? 0.0f : area_end - area_start; | 233 double weight = area_start >= area_end ? 0.0f : area_end - area_start; |
227 if (weight == 0 && j == end_i) { | 234 if (weight == 0 && j == end_i) { |
228 pixel_weights.m_SrcEnd--; | 235 pixel_weights.m_SrcEnd--; |
229 break; | 236 break; |
230 } | 237 } |
231 pixel_weights.m_Weights[j - start_i] = | 238 size_t idx = j - start_i; |
232 FXSYS_round((FX_FLOAT)(weight * 65536)); | 239 if (idx >= m_dwWeightTablesSize) |
| 240 return false; |
| 241 pixel_weights.m_Weights[idx] = FXSYS_round((FX_FLOAT)(weight * 65536)); |
233 } | 242 } |
234 } | 243 } |
| 244 return true; |
| 245 } |
| 246 |
| 247 PixelWeight* CWeightTable::GetPixelWeight(int pixel) const { |
| 248 ASSERT(pixel >= m_DestMin); |
| 249 return reinterpret_cast<PixelWeight*>(m_pWeightTables + |
| 250 (pixel - m_DestMin) * m_ItemSize); |
| 251 } |
| 252 |
| 253 int* CWeightTable::GetValueFromPixelWeight(PixelWeight* pWeight, |
| 254 int index) const { |
| 255 if (index < pWeight->m_SrcStart) |
| 256 return nullptr; |
| 257 |
| 258 size_t idx = index - pWeight->m_SrcStart; |
| 259 return idx < m_dwWeightTablesSize ? &pWeight->m_Weights[idx] : nullptr; |
235 } | 260 } |
236 CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, | 261 CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, |
237 FXDIB_Format dest_format, | 262 FXDIB_Format dest_format, |
238 int dest_width, | 263 int dest_width, |
239 int dest_height, | 264 int dest_height, |
240 const FX_RECT& clip_rect, | 265 const FX_RECT& clip_rect, |
241 const CFX_DIBSource* pSrcBitmap, | 266 const CFX_DIBSource* pSrcBitmap, |
242 int flags) { | 267 int flags) { |
243 m_State = 0; | 268 m_State = 0; |
244 m_DestFormat = dest_format; | 269 m_DestFormat = dest_format; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 397 } |
373 if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { | 398 if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) { |
374 m_pExtraAlphaBuf = | 399 m_pExtraAlphaBuf = |
375 FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); | 400 FX_Alloc2D(unsigned char, m_SrcClip.Height(), m_ExtraMaskPitch); |
376 uint32_t size = (m_DestClip.Width() * 8 + 31) / 32 * 4; | 401 uint32_t size = (m_DestClip.Width() * 8 + 31) / 32 * 4; |
377 m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); | 402 m_pDestMaskScanline = FX_TryAlloc(unsigned char, size); |
378 if (!m_pDestMaskScanline) { | 403 if (!m_pDestMaskScanline) { |
379 return FALSE; | 404 return FALSE; |
380 } | 405 } |
381 } | 406 } |
382 m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, | 407 bool ret = |
383 m_SrcClip.left, m_SrcClip.right, m_Flags); | 408 m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, |
384 if (!m_WeightTable.m_pWeightTables) { | 409 m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags); |
| 410 if (!ret) |
385 return FALSE; | 411 return FALSE; |
386 } | 412 |
387 m_CurRow = m_SrcClip.top; | 413 m_CurRow = m_SrcClip.top; |
388 m_State = 1; | 414 m_State = 1; |
389 return TRUE; | 415 return TRUE; |
390 } | 416 } |
391 #define FX_STRECH_PAUSE_ROWS 10 | 417 #define FX_STRECH_PAUSE_ROWS 10 |
392 FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { | 418 FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause) { |
393 if (!m_DestWidth) { | 419 if (!m_DestWidth) { |
394 return 0; | 420 return 0; |
395 } | 421 } |
396 if (m_pSource->SkipToScanline(m_CurRow, pPause)) { | 422 if (m_pSource->SkipToScanline(m_CurRow, pPause)) { |
(...skipping 19 matching lines...) Expand all Loading... |
416 m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch; | 442 m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch; |
417 } | 443 } |
418 switch (m_TransMethod) { | 444 switch (m_TransMethod) { |
419 case 1: | 445 case 1: |
420 case 2: { | 446 case 2: { |
421 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 447 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
422 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 448 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
423 int dest_a = 0; | 449 int dest_a = 0; |
424 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 450 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
425 j++) { | 451 j++) { |
426 int pixel_weight = | 452 int* pWeight = |
427 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 453 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 454 if (!pWeight) |
| 455 return FALSE; |
| 456 |
| 457 int pixel_weight = *pWeight; |
428 if (src_scan[j / 8] & (1 << (7 - j % 8))) { | 458 if (src_scan[j / 8] & (1 << (7 - j % 8))) { |
429 dest_a += pixel_weight * 255; | 459 dest_a += pixel_weight * 255; |
430 } | 460 } |
431 } | 461 } |
432 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 462 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
433 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; | 463 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; |
434 } | 464 } |
435 *dest_scan++ = (uint8_t)(dest_a >> 16); | 465 *dest_scan++ = (uint8_t)(dest_a >> 16); |
436 } | 466 } |
437 break; | 467 break; |
438 } | 468 } |
439 case 3: { | 469 case 3: { |
440 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 470 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
441 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 471 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
442 int dest_a = 0; | 472 int dest_a = 0; |
443 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 473 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
444 j++) { | 474 j++) { |
445 int pixel_weight = | 475 int* pWeight = |
446 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 476 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 477 if (!pWeight) |
| 478 return FALSE; |
| 479 |
| 480 int pixel_weight = *pWeight; |
447 dest_a += pixel_weight * src_scan[j]; | 481 dest_a += pixel_weight * src_scan[j]; |
448 } | 482 } |
449 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 483 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
450 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; | 484 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; |
451 } | 485 } |
452 *dest_scan++ = (uint8_t)(dest_a >> 16); | 486 *dest_scan++ = (uint8_t)(dest_a >> 16); |
453 } | 487 } |
454 break; | 488 break; |
455 } | 489 } |
456 case 4: { | 490 case 4: { |
457 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 491 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
458 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 492 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
459 int dest_a = 0, dest_r = 0; | 493 int dest_a = 0, dest_r = 0; |
460 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 494 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
461 j++) { | 495 j++) { |
462 int pixel_weight = | 496 int* pWeight = |
463 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 497 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 498 if (!pWeight) |
| 499 return FALSE; |
| 500 |
| 501 int pixel_weight = *pWeight; |
464 pixel_weight = pixel_weight * src_scan_mask[j] / 255; | 502 pixel_weight = pixel_weight * src_scan_mask[j] / 255; |
465 dest_r += pixel_weight * src_scan[j]; | 503 dest_r += pixel_weight * src_scan[j]; |
466 dest_a += pixel_weight; | 504 dest_a += pixel_weight; |
467 } | 505 } |
468 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 506 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
469 dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r; | 507 dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r; |
470 dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; | 508 dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a; |
471 } | 509 } |
472 *dest_scan++ = (uint8_t)(dest_r >> 16); | 510 *dest_scan++ = (uint8_t)(dest_r >> 16); |
473 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); | 511 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); |
474 } | 512 } |
475 break; | 513 break; |
476 } | 514 } |
477 case 5: { | 515 case 5: { |
478 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 516 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
479 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 517 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
480 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 518 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
481 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 519 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
482 j++) { | 520 j++) { |
483 int pixel_weight = | 521 int* pWeight = |
484 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 522 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 523 if (!pWeight) |
| 524 return FALSE; |
| 525 |
| 526 int pixel_weight = *pWeight; |
485 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; | 527 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; |
486 if (m_DestFormat == FXDIB_Rgb) { | 528 if (m_DestFormat == FXDIB_Rgb) { |
487 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 529 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
488 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); | 530 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); |
489 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; | 531 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; |
490 } else { | 532 } else { |
491 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); | 533 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); |
492 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 534 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
493 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); | 535 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); |
494 } | 536 } |
(...skipping 11 matching lines...) Expand all Loading... |
506 *dest_scan++ = (uint8_t)(dest_r_y >> 16); | 548 *dest_scan++ = (uint8_t)(dest_r_y >> 16); |
507 } | 549 } |
508 break; | 550 break; |
509 } | 551 } |
510 case 6: { | 552 case 6: { |
511 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 553 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
512 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 554 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
513 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 555 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
514 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 556 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
515 j++) { | 557 j++) { |
516 int pixel_weight = | 558 int* pWeight = |
517 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 559 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 560 if (!pWeight) |
| 561 return FALSE; |
| 562 |
| 563 int pixel_weight = *pWeight; |
518 pixel_weight = pixel_weight * src_scan_mask[j] / 255; | 564 pixel_weight = pixel_weight * src_scan_mask[j] / 255; |
519 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; | 565 unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]]; |
520 if (m_DestFormat == FXDIB_Rgba) { | 566 if (m_DestFormat == FXDIB_Rgba) { |
521 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 567 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
522 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); | 568 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 8); |
523 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; | 569 dest_b_c += pixel_weight * (uint8_t)argb_cmyk; |
524 } else { | 570 } else { |
525 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); | 571 dest_b_c += pixel_weight * (uint8_t)(argb_cmyk >> 24); |
526 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); | 572 dest_g_m += pixel_weight * (uint8_t)(argb_cmyk >> 16); |
527 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); | 573 dest_r_y += pixel_weight * (uint8_t)(argb_cmyk >> 8); |
(...skipping 15 matching lines...) Expand all Loading... |
543 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); | 589 *dest_scan_mask++ = (uint8_t)((dest_a * 255) >> 16); |
544 } | 590 } |
545 break; | 591 break; |
546 } | 592 } |
547 case 7: { | 593 case 7: { |
548 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 594 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
549 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 595 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
550 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 596 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
551 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 597 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
552 j++) { | 598 j++) { |
553 int pixel_weight = | 599 int* pWeight = |
554 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 600 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 601 if (!pWeight) |
| 602 return FALSE; |
| 603 |
| 604 int pixel_weight = *pWeight; |
555 const uint8_t* src_pixel = src_scan + j * Bpp; | 605 const uint8_t* src_pixel = src_scan + j * Bpp; |
556 dest_b_c += pixel_weight * (*src_pixel++); | 606 dest_b_c += pixel_weight * (*src_pixel++); |
557 dest_g_m += pixel_weight * (*src_pixel++); | 607 dest_g_m += pixel_weight * (*src_pixel++); |
558 dest_r_y += pixel_weight * (*src_pixel); | 608 dest_r_y += pixel_weight * (*src_pixel); |
559 } | 609 } |
560 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 610 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
561 dest_b_c = | 611 dest_b_c = |
562 dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; | 612 dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c; |
563 dest_g_m = | 613 dest_g_m = |
564 dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; | 614 dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m; |
565 dest_r_y = | 615 dest_r_y = |
566 dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; | 616 dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; |
567 } | 617 } |
568 *dest_scan++ = (uint8_t)((dest_b_c) >> 16); | 618 *dest_scan++ = (uint8_t)((dest_b_c) >> 16); |
569 *dest_scan++ = (uint8_t)((dest_g_m) >> 16); | 619 *dest_scan++ = (uint8_t)((dest_g_m) >> 16); |
570 *dest_scan++ = (uint8_t)((dest_r_y) >> 16); | 620 *dest_scan++ = (uint8_t)((dest_r_y) >> 16); |
571 dest_scan += Bpp - 3; | 621 dest_scan += Bpp - 3; |
572 } | 622 } |
573 break; | 623 break; |
574 } | 624 } |
575 case 8: { | 625 case 8: { |
576 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 626 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
577 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); | 627 PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col); |
578 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 628 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
579 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 629 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
580 j++) { | 630 j++) { |
581 int pixel_weight = | 631 int* pWeight = |
582 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 632 m_WeightTable.GetValueFromPixelWeight(pPixelWeights, j); |
| 633 if (!pWeight) |
| 634 return FALSE; |
| 635 |
| 636 int pixel_weight = *pWeight; |
583 const uint8_t* src_pixel = src_scan + j * Bpp; | 637 const uint8_t* src_pixel = src_scan + j * Bpp; |
584 if (m_DestFormat == FXDIB_Argb) { | 638 if (m_DestFormat == FXDIB_Argb) { |
585 pixel_weight = pixel_weight * src_pixel[3] / 255; | 639 pixel_weight = pixel_weight * src_pixel[3] / 255; |
586 } else { | 640 } else { |
587 pixel_weight = pixel_weight * src_scan_mask[j] / 255; | 641 pixel_weight = pixel_weight * src_scan_mask[j] / 255; |
588 } | 642 } |
589 dest_b_c += pixel_weight * (*src_pixel++); | 643 dest_b_c += pixel_weight * (*src_pixel++); |
590 dest_g_m += pixel_weight * (*src_pixel++); | 644 dest_g_m += pixel_weight * (*src_pixel++); |
591 dest_r_y += pixel_weight * (*src_pixel); | 645 dest_r_y += pixel_weight * (*src_pixel); |
592 dest_a += pixel_weight; | 646 dest_a += pixel_weight; |
(...skipping 23 matching lines...) Expand all Loading... |
616 } | 670 } |
617 rows_to_go--; | 671 rows_to_go--; |
618 } | 672 } |
619 return FALSE; | 673 return FALSE; |
620 } | 674 } |
621 void CStretchEngine::StretchVert() { | 675 void CStretchEngine::StretchVert() { |
622 if (m_DestHeight == 0) { | 676 if (m_DestHeight == 0) { |
623 return; | 677 return; |
624 } | 678 } |
625 CWeightTable table; | 679 CWeightTable table; |
626 table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, | 680 bool ret = table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, |
627 m_SrcClip.top, m_SrcClip.bottom, m_Flags); | 681 m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags); |
628 if (!table.m_pWeightTables) { | 682 if (!ret) |
629 return; | 683 return; |
630 } | 684 |
631 int DestBpp = m_DestBpp / 8; | 685 const int DestBpp = m_DestBpp / 8; |
632 for (int row = m_DestClip.top; row < m_DestClip.bottom; row++) { | 686 for (int row = m_DestClip.top; row < m_DestClip.bottom; row++) { |
633 unsigned char* dest_scan = m_pDestScanline; | 687 unsigned char* dest_scan = m_pDestScanline; |
634 unsigned char* dest_sacn_mask = m_pDestMaskScanline; | 688 unsigned char* dest_scan_mask = m_pDestMaskScanline; |
635 PixelWeight* pPixelWeights = table.GetPixelWeight(row); | 689 PixelWeight* pPixelWeights = table.GetPixelWeight(row); |
636 switch (m_TransMethod) { | 690 switch (m_TransMethod) { |
637 case 1: | 691 case 1: |
638 case 2: | 692 case 2: |
639 case 3: { | 693 case 3: { |
640 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 694 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
641 unsigned char* src_scan = | 695 unsigned char* src_scan = |
642 m_pInterBuf + (col - m_DestClip.left) * DestBpp; | 696 m_pInterBuf + (col - m_DestClip.left) * DestBpp; |
643 int dest_a = 0; | 697 int dest_a = 0; |
644 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 698 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
645 j++) { | 699 j++) { |
646 int pixel_weight = | 700 int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j); |
647 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 701 if (!pWeight) |
| 702 return; |
| 703 |
| 704 int pixel_weight = *pWeight; |
648 dest_a += | 705 dest_a += |
649 pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; | 706 pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; |
650 } | 707 } |
651 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 708 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
652 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; | 709 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; |
653 } | 710 } |
654 *dest_scan = (uint8_t)(dest_a >> 16); | 711 *dest_scan = (uint8_t)(dest_a >> 16); |
655 dest_scan += DestBpp; | 712 dest_scan += DestBpp; |
656 } | 713 } |
657 break; | 714 break; |
658 } | 715 } |
659 case 4: { | 716 case 4: { |
660 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 717 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
661 unsigned char* src_scan = | 718 unsigned char* src_scan = |
662 m_pInterBuf + (col - m_DestClip.left) * DestBpp; | 719 m_pInterBuf + (col - m_DestClip.left) * DestBpp; |
663 unsigned char* src_scan_mask = | 720 unsigned char* src_scan_mask = |
664 m_pExtraAlphaBuf + (col - m_DestClip.left); | 721 m_pExtraAlphaBuf + (col - m_DestClip.left); |
665 int dest_a = 0, dest_k = 0; | 722 int dest_a = 0, dest_k = 0; |
666 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 723 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
667 j++) { | 724 j++) { |
668 int pixel_weight = | 725 int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j); |
669 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 726 if (!pWeight) |
| 727 return; |
| 728 |
| 729 int pixel_weight = *pWeight; |
670 dest_k += | 730 dest_k += |
671 pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; | 731 pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch]; |
672 dest_a += pixel_weight * | 732 dest_a += pixel_weight * |
673 src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; | 733 src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; |
674 } | 734 } |
675 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 735 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
676 dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k; | 736 dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k; |
677 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; | 737 dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a; |
678 } | 738 } |
679 *dest_scan = (uint8_t)(dest_k >> 16); | 739 *dest_scan = (uint8_t)(dest_k >> 16); |
680 dest_scan += DestBpp; | 740 dest_scan += DestBpp; |
681 *dest_sacn_mask++ = (uint8_t)(dest_a >> 16); | 741 *dest_scan_mask++ = (uint8_t)(dest_a >> 16); |
682 } | 742 } |
683 break; | 743 break; |
684 } | 744 } |
685 case 5: | 745 case 5: |
686 case 7: { | 746 case 7: { |
687 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 747 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
688 unsigned char* src_scan = | 748 unsigned char* src_scan = |
689 m_pInterBuf + (col - m_DestClip.left) * DestBpp; | 749 m_pInterBuf + (col - m_DestClip.left) * DestBpp; |
690 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 750 int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
691 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 751 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
692 j++) { | 752 j++) { |
693 int pixel_weight = | 753 int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j); |
694 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 754 if (!pWeight) |
| 755 return; |
| 756 |
| 757 int pixel_weight = *pWeight; |
695 const uint8_t* src_pixel = | 758 const uint8_t* src_pixel = |
696 src_scan + (j - m_SrcClip.top) * m_InterPitch; | 759 src_scan + (j - m_SrcClip.top) * m_InterPitch; |
697 dest_b_c += pixel_weight * (*src_pixel++); | 760 dest_b_c += pixel_weight * (*src_pixel++); |
698 dest_g_m += pixel_weight * (*src_pixel++); | 761 dest_g_m += pixel_weight * (*src_pixel++); |
699 dest_r_y += pixel_weight * (*src_pixel); | 762 dest_r_y += pixel_weight * (*src_pixel); |
700 } | 763 } |
701 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { | 764 if (m_Flags & FXDIB_BICUBIC_INTERPOL) { |
702 dest_r_y = | 765 dest_r_y = |
703 dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; | 766 dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y; |
704 dest_g_m = | 767 dest_g_m = |
(...skipping 13 matching lines...) Expand all Loading... |
718 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { | 781 for (int col = m_DestClip.left; col < m_DestClip.right; col++) { |
719 unsigned char* src_scan = | 782 unsigned char* src_scan = |
720 m_pInterBuf + (col - m_DestClip.left) * DestBpp; | 783 m_pInterBuf + (col - m_DestClip.left) * DestBpp; |
721 unsigned char* src_scan_mask = nullptr; | 784 unsigned char* src_scan_mask = nullptr; |
722 if (m_DestFormat != FXDIB_Argb) { | 785 if (m_DestFormat != FXDIB_Argb) { |
723 src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left); | 786 src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left); |
724 } | 787 } |
725 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; | 788 int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0; |
726 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; | 789 for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; |
727 j++) { | 790 j++) { |
728 int pixel_weight = | 791 int* pWeight = table.GetValueFromPixelWeight(pPixelWeights, j); |
729 pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart]; | 792 if (!pWeight) |
| 793 return; |
| 794 |
| 795 int pixel_weight = *pWeight; |
730 const uint8_t* src_pixel = | 796 const uint8_t* src_pixel = |
731 src_scan + (j - m_SrcClip.top) * m_InterPitch; | 797 src_scan + (j - m_SrcClip.top) * m_InterPitch; |
732 int mask_v = 255; | 798 int mask_v = 255; |
733 if (src_scan_mask) { | 799 if (src_scan_mask) { |
734 mask_v = src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; | 800 mask_v = src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch]; |
735 } | 801 } |
736 dest_b_c += pixel_weight * (*src_pixel++); | 802 dest_b_c += pixel_weight * (*src_pixel++); |
737 dest_g_m += pixel_weight * (*src_pixel++); | 803 dest_g_m += pixel_weight * (*src_pixel++); |
738 dest_r_y += pixel_weight * (*src_pixel); | 804 dest_r_y += pixel_weight * (*src_pixel); |
739 if (m_DestFormat == FXDIB_Argb) { | 805 if (m_DestFormat == FXDIB_Argb) { |
(...skipping 15 matching lines...) Expand all Loading... |
755 int r = ((uint32_t)dest_r_y) * 255 / dest_a; | 821 int r = ((uint32_t)dest_r_y) * 255 / dest_a; |
756 int g = ((uint32_t)dest_g_m) * 255 / dest_a; | 822 int g = ((uint32_t)dest_g_m) * 255 / dest_a; |
757 int b = ((uint32_t)dest_b_c) * 255 / dest_a; | 823 int b = ((uint32_t)dest_b_c) * 255 / dest_a; |
758 dest_scan[0] = b > 255 ? 255 : b < 0 ? 0 : b; | 824 dest_scan[0] = b > 255 ? 255 : b < 0 ? 0 : b; |
759 dest_scan[1] = g > 255 ? 255 : g < 0 ? 0 : g; | 825 dest_scan[1] = g > 255 ? 255 : g < 0 ? 0 : g; |
760 dest_scan[2] = r > 255 ? 255 : r < 0 ? 0 : r; | 826 dest_scan[2] = r > 255 ? 255 : r < 0 ? 0 : r; |
761 } | 827 } |
762 if (m_DestFormat == FXDIB_Argb) { | 828 if (m_DestFormat == FXDIB_Argb) { |
763 dest_scan[3] = (uint8_t)((dest_a) >> 16); | 829 dest_scan[3] = (uint8_t)((dest_a) >> 16); |
764 } else { | 830 } else { |
765 *dest_sacn_mask = (uint8_t)((dest_a) >> 16); | 831 *dest_scan_mask = (uint8_t)((dest_a) >> 16); |
766 } | 832 } |
767 dest_scan += DestBpp; | 833 dest_scan += DestBpp; |
768 if (dest_sacn_mask) { | 834 if (dest_scan_mask) { |
769 dest_sacn_mask++; | 835 dest_scan_mask++; |
770 } | 836 } |
771 } | 837 } |
772 break; | 838 break; |
773 } | 839 } |
774 } | 840 } |
775 m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_pDestScanline, | 841 m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_pDestScanline, |
776 m_pDestMaskScanline); | 842 m_pDestMaskScanline); |
777 } | 843 } |
778 } | 844 } |
779 | 845 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 result_width); | 986 result_width); |
921 if (m_pMaskScanline) { | 987 if (m_pMaskScanline) { |
922 m_pSource->m_pAlphaMask->DownSampleScanline( | 988 m_pSource->m_pAlphaMask->DownSampleScanline( |
923 src_y, m_pMaskScanline.get(), 1, m_DestWidth, m_bFlipX, | 989 src_y, m_pMaskScanline.get(), 1, m_DestWidth, m_bFlipX, |
924 m_ClipRect.left, result_width); | 990 m_ClipRect.left, result_width); |
925 } | 991 } |
926 m_pDest->ComposeScanline(dest_y, m_pScanline.get(), m_pMaskScanline.get()); | 992 m_pDest->ComposeScanline(dest_y, m_pScanline.get(), m_pMaskScanline.get()); |
927 } | 993 } |
928 return FALSE; | 994 return FALSE; |
929 } | 995 } |
OLD | NEW |