Chromium Code Reviews| 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 "core/fxcodec/jbig2/JBig2_Image.h" | 9 #include "core/fxcodec/jbig2/JBig2_Image.h" |
| 10 #include "core/fxcrt/include/fx_coordinates.h" | 10 #include "core/fxcrt/include/fx_coordinates.h" |
| 11 #include "core/fxcrt/include/fx_safe_types.h" | 11 #include "core/fxcrt/include/fx_safe_types.h" |
| 12 | 12 |
| 13 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h) { | 13 namespace { |
| 14 | |
| 15 const int kMaxImageBytes = 100 * 1024 * 1024; | |
| 16 const int kMaxImagePixels = 8 * kMaxImageBytes; | |
| 17 static_assert(kMaxImagePixels < INT_MAX - 31, | |
| 18 "Pixel calculatons will overflow"); | |
|
Lei Zhang
2016/08/01 22:49:50
Are calculatons cousins to Calculon?
Tom Sepez
2016/08/01 23:21:13
indeed. sadly this got removed and replaced by ju
| |
| 19 | |
| 20 } // namespace | |
| 21 | |
| 22 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h) | |
| 23 : m_pData(nullptr), | |
| 24 m_nWidth(0), | |
| 25 m_nHeight(0), | |
| 26 m_nStride(0), | |
| 27 m_bNeedFree(true) { | |
| 28 if (w < 0 || h < 0 || w > kMaxImagePixels) | |
| 29 return; | |
| 30 | |
| 31 int32_t stride_pixels = (w + 31) & ~31; | |
| 32 if (h > kMaxImagePixels / stride_pixels) | |
| 33 return; | |
| 34 | |
| 14 m_nWidth = w; | 35 m_nWidth = w; |
| 15 m_nHeight = h; | 36 m_nHeight = h; |
| 16 if (m_nWidth <= 0 || m_nHeight <= 0 || m_nWidth > INT_MAX - 31) { | 37 m_nStride = stride_pixels / 8; |
| 17 m_pData = nullptr; | 38 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight); |
| 18 m_bNeedFree = FALSE; | 39 } |
| 40 | |
| 41 CJBig2_Image::CJBig2_Image(int32_t w, int32_t h, int32_t stride, uint8_t* pBuf) | |
| 42 : m_pData(nullptr), | |
| 43 m_nWidth(0), | |
| 44 m_nHeight(0), | |
| 45 m_nStride(0), | |
| 46 m_bNeedFree(false) { | |
| 47 if (w < 0 || h < 0 || stride < 0 || stride > kMaxImageBytes) | |
| 19 return; | 48 return; |
| 20 } | 49 |
| 21 m_nStride = ((w + 31) >> 5) << 2; | 50 int32_t stride_pixels = 8 * stride; |
| 22 if (m_nStride * m_nHeight > 0 && 104857600 / (int)m_nStride > m_nHeight) { | 51 if (stride_pixels < w || h > kMaxImagePixels / stride_pixels) |
| 23 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight); | 52 return; |
| 24 } else { | 53 |
| 25 m_pData = nullptr; | |
| 26 } | |
| 27 m_bNeedFree = TRUE; | |
| 28 } | |
| 29 CJBig2_Image::CJBig2_Image(int32_t w, | |
| 30 int32_t h, | |
| 31 int32_t stride, | |
| 32 uint8_t* pBuf) { | |
| 33 m_nWidth = w; | 54 m_nWidth = w; |
| 34 m_nHeight = h; | 55 m_nHeight = h; |
| 35 m_nStride = stride; | 56 m_nStride = stride; |
| 36 m_pData = pBuf; | 57 m_pData = pBuf; |
| 37 m_bNeedFree = FALSE; | |
| 38 } | 58 } |
| 39 CJBig2_Image::CJBig2_Image(const CJBig2_Image& im) { | 59 |
| 40 m_nWidth = im.m_nWidth; | 60 CJBig2_Image::CJBig2_Image(const CJBig2_Image& other) |
| 41 m_nHeight = im.m_nHeight; | 61 : m_pData(nullptr), |
| 42 m_nStride = im.m_nStride; | 62 m_nWidth(other.m_nWidth), |
| 43 if (im.m_pData) { | 63 m_nHeight(other.m_nHeight), |
| 64 m_nStride(other.m_nStride), | |
| 65 m_bNeedFree(true) { | |
| 66 if (other.m_pData) { | |
| 44 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight); | 67 m_pData = FX_Alloc2D(uint8_t, m_nStride, m_nHeight); |
| 45 JBIG2_memcpy(m_pData, im.m_pData, m_nStride * m_nHeight); | 68 JBIG2_memcpy(m_pData, other.m_pData, m_nStride * m_nHeight); |
| 46 } else { | |
| 47 m_pData = nullptr; | |
| 48 } | 69 } |
| 49 m_bNeedFree = TRUE; | |
| 50 } | 70 } |
| 71 | |
| 51 CJBig2_Image::~CJBig2_Image() { | 72 CJBig2_Image::~CJBig2_Image() { |
| 52 if (m_bNeedFree) { | 73 if (m_bNeedFree) { |
| 53 FX_Free(m_pData); | 74 FX_Free(m_pData); |
| 54 } | 75 } |
| 55 } | 76 } |
| 56 FX_BOOL CJBig2_Image::getPixel(int32_t x, int32_t y) { | 77 FX_BOOL CJBig2_Image::getPixel(int32_t x, int32_t y) { |
| 57 if (!m_pData) { | 78 if (!m_pData) { |
| 58 return 0; | 79 return 0; |
| 59 } | 80 } |
| 60 int32_t m, n; | 81 int32_t m, n; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 pDst[1] = (uint8_t)(wTmp >> 16); | 223 pDst[1] = (uint8_t)(wTmp >> 16); |
| 203 pDst[2] = (uint8_t)(wTmp >> 8); | 224 pDst[2] = (uint8_t)(wTmp >> 8); |
| 204 pDst[3] = (uint8_t)wTmp; | 225 pDst[3] = (uint8_t)wTmp; |
| 205 } | 226 } |
| 206 pLineSrc += m_nStride; | 227 pLineSrc += m_nStride; |
| 207 pLineDst += pImage->m_nStride; | 228 pLineDst += pImage->m_nStride; |
| 208 } | 229 } |
| 209 } | 230 } |
| 210 return pImage; | 231 return pImage; |
| 211 } | 232 } |
| 233 | |
| 212 void CJBig2_Image::expand(int32_t h, FX_BOOL v) { | 234 void CJBig2_Image::expand(int32_t h, FX_BOOL v) { |
| 213 if (!m_pData || h <= m_nHeight) { | 235 if (!m_pData || h <= m_nHeight || h > kMaxImageBytes / m_nStride) { |
| 214 return; | 236 return; |
| 215 } | 237 } |
| 216 uint32_t dwH = pdfium::base::checked_cast<uint32_t>(h); | |
| 217 uint32_t dwStride = pdfium::base::checked_cast<uint32_t>(m_nStride); | |
| 218 uint32_t dwHeight = pdfium::base::checked_cast<uint32_t>(m_nHeight); | |
| 219 FX_SAFE_UINT32 safeMemSize = dwH; | |
| 220 safeMemSize *= dwStride; | |
| 221 if (!safeMemSize.IsValid()) { | |
| 222 return; | |
| 223 } | |
| 224 // The guaranteed reallocated memory is to be < 4GB (unsigned int). | |
| 225 m_pData = FX_Realloc(uint8_t, m_pData, safeMemSize.ValueOrDie()); | |
| 226 | 238 |
| 227 // The result of dwHeight * dwStride doesn't overflow after the | 239 m_pData = FX_Realloc(uint8_t, m_pData, h * m_nStride); |
| 228 // checking of safeMemSize. | 240 JBIG2_memset(m_pData + m_nHeight * m_nStride, v ? 0xff : 0, |
| 229 // The same as the result of (dwH - dwHeight) * dwStride) because | 241 (h - m_nHeight) * m_nStride); |
| 230 // dwH - dwHeight is always less than dwH(h) which is checked in | |
| 231 // the calculation of dwH * dwStride. | |
| 232 JBIG2_memset(m_pData + dwHeight * dwStride, v ? 0xff : 0, | |
| 233 (dwH - dwHeight) * dwStride); | |
| 234 m_nHeight = h; | 242 m_nHeight = h; |
| 235 } | 243 } |
| 244 | |
| 236 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst, | 245 FX_BOOL CJBig2_Image::composeTo_opt2(CJBig2_Image* pDst, |
| 237 int32_t x, | 246 int32_t x, |
| 238 int32_t y, | 247 int32_t y, |
| 239 JBig2ComposeOp op) { | 248 JBig2ComposeOp op) { |
| 240 int32_t xs0 = 0, ys0 = 0, xs1 = 0, ys1 = 0, xd0 = 0, yd0 = 0, xd1 = 0, | 249 int32_t xs0 = 0, ys0 = 0, xs1 = 0, ys1 = 0, xd0 = 0, yd0 = 0, xd1 = 0, |
| 241 yd1 = 0, xx = 0, yy = 0, w = 0, h = 0, middleDwords = 0, lineLeft = 0; | 250 yd1 = 0, xx = 0, yy = 0, w = 0, h = 0, middleDwords = 0, lineLeft = 0; |
| 242 | 251 |
| 243 uint32_t s1 = 0, d1 = 0, d2 = 0, shift = 0, shift1 = 0, shift2 = 0, tmp = 0, | 252 uint32_t s1 = 0, d1 = 0, d2 = 0, shift = 0, shift1 = 0, shift2 = 0, tmp = 0, |
| 244 tmp1 = 0, tmp2 = 0, maskL = 0, maskR = 0, maskM = 0; | 253 tmp1 = 0, tmp2 = 0, maskL = 0, maskR = 0, maskM = 0; |
| 245 | 254 |
| (...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1074 dp[2] = (uint8_t)(tmp >> 8); | 1083 dp[2] = (uint8_t)(tmp >> 8); |
| 1075 dp[3] = (uint8_t)tmp; | 1084 dp[3] = (uint8_t)tmp; |
| 1076 } | 1085 } |
| 1077 lineSrc += m_nStride; | 1086 lineSrc += m_nStride; |
| 1078 lineDst += pDst->m_nStride; | 1087 lineDst += pDst->m_nStride; |
| 1079 } | 1088 } |
| 1080 } | 1089 } |
| 1081 } | 1090 } |
| 1082 return 1; | 1091 return 1; |
| 1083 } | 1092 } |
| OLD | NEW |