ProgressiveDecoder: switch over loop rather than loop over switch
Duplicates some code but allows for tighter inner loops.
-- use early return.
-- Avoid some needless assignments to 0.
-- load dest_a before first store to help if src and dst are congruent.
Change-Id: I216d6a53c4d2d5f7678c3216586e922358135d89
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/81831
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcodec/progressive_decoder.cpp b/core/fxcodec/progressive_decoder.cpp
index 20844e2..f8649ce 100644
--- a/core/fxcodec/progressive_decoder.cpp
+++ b/core/fxcodec/progressive_decoder.cpp
@@ -322,72 +322,78 @@
NOTREACHED();
return false;
}
- if (line >= m_clipBox.top && line < m_clipBox.bottom) {
- double scale_y = static_cast<double>(m_sizeY) / m_clipBox.Height();
- int32_t row =
- static_cast<int32_t>((line - m_clipBox.top) * scale_y) + m_startY;
- const uint8_t* src_scan = pDIBitmap->GetScanline(row);
- uint8_t* dest_scan = m_pDecodeBuf.get();
- *pSrcBuf = m_pDecodeBuf.get();
- int32_t src_Bpp = pDIBitmap->GetBPP() >> 3;
- int32_t dest_Bpp = (m_SrcFormat & 0xff) >> 3;
- int32_t src_left = m_startX;
- int32_t dest_left = m_clipBox.left;
- src_scan += src_left * src_Bpp;
- dest_scan += dest_left * dest_Bpp;
- for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
- PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
- if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd) {
- continue;
- }
- switch (pDIBitmap->GetFormat()) {
- case FXDIB_Format::k1bppMask:
- case FXDIB_Format::k1bppRgb:
- NOTREACHED();
- return false;
- case FXDIB_Format::k8bppMask:
- case FXDIB_Format::k8bppRgb: {
- if (pDIBitmap->HasPalette())
- return false;
+ if (line < m_clipBox.top || line >= m_clipBox.bottom)
+ return true;
- uint32_t dest_g = 0;
- dest_g += pPixelWeights->m_Weights[0] * src_scan[src_col];
- dest_scan[pPixelWeights->m_SrcStart] = (uint8_t)(dest_g >> 16);
- } break;
- case FXDIB_Format::kRgb:
- case FXDIB_Format::kRgb32: {
- uint32_t dest_b = 0;
- uint32_t dest_g = 0;
- uint32_t dest_r = 0;
- const uint8_t* p = src_scan + src_col * src_Bpp;
- dest_b += pPixelWeights->m_Weights[0] * (*p++);
- dest_g += pPixelWeights->m_Weights[0] * (*p++);
- dest_r += pPixelWeights->m_Weights[0] * (*p);
- uint8_t* pDes = &dest_scan[pPixelWeights->m_SrcStart * dest_Bpp];
- *pDes++ = (uint8_t)((dest_b) >> 16);
- *pDes++ = (uint8_t)((dest_g) >> 16);
- *pDes = (uint8_t)((dest_r) >> 16);
- } break;
- case FXDIB_Format::kArgb: {
- uint32_t dest_r = 0;
- uint32_t dest_g = 0;
- uint32_t dest_b = 0;
- const uint8_t* p = src_scan + src_col * src_Bpp;
- dest_b += pPixelWeights->m_Weights[0] * (*p++);
- dest_g += pPixelWeights->m_Weights[0] * (*p++);
- dest_r += pPixelWeights->m_Weights[0] * (*p++);
- uint8_t* pDes = &dest_scan[pPixelWeights->m_SrcStart * dest_Bpp];
- *pDes++ = (uint8_t)((dest_b) >> 16);
- *pDes++ = (uint8_t)((dest_g) >> 16);
- *pDes++ = (uint8_t)((dest_r) >> 16);
- *pDes = *p;
- } break;
- default:
- return false;
+ double scale_y = static_cast<double>(m_sizeY) / m_clipBox.Height();
+ int32_t row =
+ static_cast<int32_t>((line - m_clipBox.top) * scale_y) + m_startY;
+ *pSrcBuf = m_pDecodeBuf.get();
+ int32_t src_Bpp = pDIBitmap->GetBPP() >> 3;
+ int32_t dest_Bpp = (m_SrcFormat & 0xff) >> 3;
+ int32_t src_left = m_startX;
+ int32_t dest_left = m_clipBox.left;
+ const uint8_t* src_scan = pDIBitmap->GetScanline(row) + src_left * src_Bpp;
+ uint8_t* dest_scan = m_pDecodeBuf.get() + dest_left * dest_Bpp;
+ switch (pDIBitmap->GetFormat()) {
+ case FXDIB_Format::k1bppMask:
+ case FXDIB_Format::k1bppRgb:
+ for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
+ if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd)
+ continue;
+ NOTREACHED();
+ return false;
}
- }
+ return true;
+ case FXDIB_Format::k8bppMask:
+ case FXDIB_Format::k8bppRgb:
+ if (pDIBitmap->HasPalette())
+ return false;
+ for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
+ if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd)
+ continue;
+ uint32_t dest_g = pPixelWeights->m_Weights[0] * src_scan[src_col];
+ dest_scan[pPixelWeights->m_SrcStart] = (uint8_t)(dest_g >> 16);
+ }
+ return true;
+ case FXDIB_Format::kRgb:
+ case FXDIB_Format::kRgb32:
+ for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
+ if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd)
+ continue;
+ const uint8_t* p = src_scan + src_col * src_Bpp;
+ uint32_t dest_b = pPixelWeights->m_Weights[0] * (*p++);
+ uint32_t dest_g = pPixelWeights->m_Weights[0] * (*p++);
+ uint32_t dest_r = pPixelWeights->m_Weights[0] * (*p);
+ uint8_t* pDes = &dest_scan[pPixelWeights->m_SrcStart * dest_Bpp];
+ *pDes++ = (uint8_t)((dest_b) >> 16);
+ *pDes++ = (uint8_t)((dest_g) >> 16);
+ *pDes = (uint8_t)((dest_r) >> 16);
+ }
+ return true;
+ case FXDIB_Format::kArgb:
+ for (int32_t src_col = 0; src_col < m_sizeX; src_col++) {
+ PixelWeight* pPixelWeights = m_WeightHorzOO.GetPixelWeight(src_col);
+ if (pPixelWeights->m_SrcStart != pPixelWeights->m_SrcEnd)
+ continue;
+ const uint8_t* p = src_scan + src_col * src_Bpp;
+ uint32_t dest_b = pPixelWeights->m_Weights[0] * (*p++);
+ uint32_t dest_g = pPixelWeights->m_Weights[0] * (*p++);
+ uint32_t dest_r = pPixelWeights->m_Weights[0] * (*p++);
+ uint8_t dest_a = *p;
+ uint8_t* pDes = &dest_scan[pPixelWeights->m_SrcStart * dest_Bpp];
+ *pDes++ = (uint8_t)((dest_b) >> 16);
+ *pDes++ = (uint8_t)((dest_g) >> 16);
+ *pDes++ = (uint8_t)((dest_r) >> 16);
+ *pDes = dest_a;
+ }
+ return true;
+ default:
+ return false;
}
- return true;
}
void ProgressiveDecoder::PngFillScanlineBufCompleted(int pass, int line) {