Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(855)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.cpp

Issue 1566283003: Upgrade blink side ReadPixels size validation to consider ES3 pack parameters. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium 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 #include "platform/graphics/gpu/WebGLImageConversion.h" 5 #include "platform/graphics/gpu/WebGLImageConversion.h"
6 6
7 #include "platform/CheckedInt.h" 7 #include "platform/CheckedInt.h"
8 #include "platform/graphics/ImageObserver.h" 8 #include "platform/graphics/ImageObserver.h"
9 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h" 9 #include "platform/graphics/cpu/arm/WebGLImageConversionNEON.h"
10 #include "platform/graphics/cpu/x86/WebGLImageConversionSSE.h" 10 #include "platform/graphics/cpu/x86/WebGLImageConversionSSE.h"
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermType*>(m_unpac kedIntermediateSrcData.get()), m_width); 1916 unpack<SrcFormat>(srcRowStart, reinterpret_cast<IntermType*>(m_unpac kedIntermediateSrcData.get()), m_width);
1917 pack<DstFormat, alphaOp>(reinterpret_cast<IntermType*>(m_unpackedInt ermediateSrcData.get()), dstRowStart, m_width); 1917 pack<DstFormat, alphaOp>(reinterpret_cast<IntermType*>(m_unpackedInt ermediateSrcData.get()), dstRowStart, m_width);
1918 srcRowStart += srcStrideInElements; 1918 srcRowStart += srcStrideInElements;
1919 dstRowStart += dstStrideInElements; 1919 dstRowStart += dstStrideInElements;
1920 } 1920 }
1921 } 1921 }
1922 m_success = true; 1922 m_success = true;
1923 return; 1923 return;
1924 } 1924 }
1925 1925
1926 bool frameIsValid(const SkBitmap& frameBitmap)
1927 {
1928 return !frameBitmap.isNull()
1929 && !frameBitmap.empty()
1930 && frameBitmap.isImmutable()
1931 && frameBitmap.colorType() == kN32_SkColorType;
1932 }
1933
1926 } // anonymous namespace 1934 } // anonymous namespace
1927 1935
1936 WebGLImageConversion::PixelStoreParams::PixelStoreParams()
1937 : alignment(4)
1938 , rowLength(0)
1939 , imageHeight(0)
1940 , skipPixels(0)
1941 , skipRows(0)
1942 , skipImages(0)
1943 {
1944 }
1945
1928 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent) 1946 bool WebGLImageConversion::computeFormatAndTypeParameters(GLenum format, GLenum type, unsigned* componentsPerPixel, unsigned* bytesPerComponent)
1929 { 1947 {
1930 switch (format) { 1948 switch (format) {
1931 case GL_ALPHA: 1949 case GL_ALPHA:
1932 case GL_LUMINANCE: 1950 case GL_LUMINANCE:
1933 case GL_RED: 1951 case GL_RED:
1934 case GL_RED_INTEGER: 1952 case GL_RED_INTEGER:
1935 case GL_DEPTH_COMPONENT: 1953 case GL_DEPTH_COMPONENT:
1936 case GL_DEPTH_STENCIL: // Treat it as one component. 1954 case GL_DEPTH_STENCIL: // Treat it as one component.
1937 *componentsPerPixel = 1; 1955 *componentsPerPixel = 1;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1993 case GL_HALF_FLOAT: 2011 case GL_HALF_FLOAT:
1994 case GL_HALF_FLOAT_OES: // OES_texture_half_float 2012 case GL_HALF_FLOAT_OES: // OES_texture_half_float
1995 *bytesPerComponent = sizeof(GLushort); 2013 *bytesPerComponent = sizeof(GLushort);
1996 break; 2014 break;
1997 default: 2015 default:
1998 return false; 2016 return false;
1999 } 2017 }
2000 return true; 2018 return true;
2001 } 2019 }
2002 2020
2003 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, GLint alignment, unsigned* imageS izeInBytes, unsigned* paddingInBytes) 2021 GLenum WebGLImageConversion::computeImageSizeInBytes(GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth, const PixelStoreParams& params, u nsigned* imageSizeInBytes, unsigned* paddingInBytes, unsigned* skipSizeInBytes)
2004 { 2022 {
2005 ASSERT(imageSizeInBytes); 2023 ASSERT(imageSizeInBytes);
2006 ASSERT(alignment == 1 || alignment == 2 || alignment == 4 || alignment == 8) ; 2024 ASSERT(params.alignment == 1 || params.alignment == 2 || params.alignment == 4 || params.alignment == 8);
2025 ASSERT(params.rowLength >= 0 && params.imageHeight >= 0);
2026 ASSERT(params.skipPixels >= 0 && params.skipRows >= 0 && params.skipImages > = 0);
2007 if (width < 0 || height < 0 || depth < 0) 2027 if (width < 0 || height < 0 || depth < 0)
2008 return GL_INVALID_VALUE; 2028 return GL_INVALID_VALUE;
2009 unsigned bytesPerComponent, componentsPerPixel;
2010 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo nentsPerPixel))
2011 return GL_INVALID_ENUM;
2012 if (!width || !height || !depth) { 2029 if (!width || !height || !depth) {
2013 *imageSizeInBytes = 0; 2030 *imageSizeInBytes = 0;
2014 if (paddingInBytes) 2031 if (paddingInBytes)
2015 *paddingInBytes = 0; 2032 *paddingInBytes = 0;
2033 if (skipSizeInBytes)
2034 *skipSizeInBytes = 0;
2016 return GL_NO_ERROR; 2035 return GL_NO_ERROR;
2017 } 2036 }
2018 CheckedInt<uint32_t> checkedValue(bytesPerComponent * componentsPerPixel); 2037
2019 checkedValue *= width; 2038 int rowLength = params.rowLength > 0 ? params.rowLength : width;
2039 int imageHeight = params.imageHeight > 0 ? params.imageHeight : height;
2040
2041 unsigned bytesPerComponent, componentsPerPixel;
2042 if (!computeFormatAndTypeParameters(format, type, &bytesPerComponent, &compo nentsPerPixel))
2043 return GL_INVALID_ENUM;
2044 unsigned bytesPerGroup = bytesPerComponent * componentsPerPixel;
2045 CheckedInt<uint32_t> checkedValue = static_cast<uint32_t>(rowLength);
2046 checkedValue *= bytesPerGroup;
2020 if (!checkedValue.isValid()) 2047 if (!checkedValue.isValid())
2021 return GL_INVALID_VALUE; 2048 return GL_INVALID_VALUE;
2022 unsigned validRowSize = checkedValue.value(); 2049
2050 unsigned lastRowSize;
2051 if (params.rowLength > 0 && params.rowLength != width) {
2052 CheckedInt<uint32_t> tmp = width;
2053 tmp *= bytesPerGroup;
2054 if (!tmp.isValid())
2055 return GL_INVALID_VALUE;
2056 lastRowSize = tmp.value();
2057 } else {
2058 lastRowSize = checkedValue.value();
2059 }
2060
2023 unsigned padding = 0; 2061 unsigned padding = 0;
2024 unsigned residual = validRowSize % alignment; 2062 unsigned residual = checkedValue.value() % params.alignment;
2025 if (residual) { 2063 if (residual) {
2026 padding = alignment - residual; 2064 padding = params.alignment - residual;
2027 checkedValue += padding; 2065 checkedValue += padding;
2028 } 2066 }
2029 // Last row needs no padding. 2067 if (!checkedValue.isValid())
2030 checkedValue *= (height * depth - 1); 2068 return GL_INVALID_VALUE;
2031 checkedValue += validRowSize; 2069 unsigned paddedRowSize = checkedValue.value();
2070
2071 CheckedInt<uint32_t> rows = imageHeight;
2072 rows *= (depth - 1);
2073 // Last image is not affected by IMAGE_HEIGHT parameter.
2074 rows += height;
2075 if (!rows.isValid())
2076 return GL_INVALID_VALUE;
2077 checkedValue *= (rows.value() - 1);
2078 // Last row is not affected by ROW_LENGTH parameter.
2079 checkedValue += lastRowSize;
2032 if (!checkedValue.isValid()) 2080 if (!checkedValue.isValid())
2033 return GL_INVALID_VALUE; 2081 return GL_INVALID_VALUE;
2034 *imageSizeInBytes = checkedValue.value(); 2082 *imageSizeInBytes = checkedValue.value();
2035 if (paddingInBytes) 2083 if (paddingInBytes)
2036 *paddingInBytes = padding; 2084 *paddingInBytes = padding;
2085
2086 CheckedInt<uint32_t> skipSize = 0;
2087 if (params.skipImages > 0) {
2088 CheckedInt<uint32_t> tmp = paddedRowSize;
2089 tmp *= imageHeight;
2090 tmp *= params.skipImages;
2091 if (!tmp.isValid())
2092 return GL_INVALID_VALUE;
2093 skipSize += tmp.value();
2094 }
2095 if (params.skipRows > 0) {
2096 CheckedInt<uint32_t> tmp = paddedRowSize;
2097 tmp *= params.skipRows;
2098 if (!tmp.isValid())
2099 return GL_INVALID_VALUE;
2100 skipSize += tmp.value();
2101 }
2102 if (params.skipPixels > 0) {
2103 CheckedInt<uint32_t> tmp = bytesPerGroup;
2104 tmp *= params.skipPixels;
2105 if (!tmp.isValid())
2106 return GL_INVALID_VALUE;
2107 skipSize += tmp.value();
2108 }
2109 if (!skipSize.isValid())
2110 return GL_INVALID_VALUE;
2111 if (skipSizeInBytes)
2112 *skipSizeInBytes = skipSize.value();
2113
2114 checkedValue += skipSize.value();
2115 if (!checkedValue.isValid())
2116 return GL_INVALID_VALUE;
2037 return GL_NO_ERROR; 2117 return GL_NO_ERROR;
2038 } 2118 }
2039 2119
2040 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS ource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile ) 2120 WebGLImageConversion::ImageExtractor::ImageExtractor(Image* image, ImageHtmlDomS ource imageHtmlDomSource, bool premultiplyAlpha, bool ignoreGammaAndColorProfile )
2041 { 2121 {
2042 m_image = image; 2122 m_image = image;
2043 m_imageHtmlDomSource = imageHtmlDomSource; 2123 m_imageHtmlDomSource = imageHtmlDomSource;
2044 extractImage(premultiplyAlpha, ignoreGammaAndColorProfile); 2124 extractImage(premultiplyAlpha, ignoreGammaAndColorProfile);
2045 } 2125 }
2046 2126
2047 namespace {
2048
2049 bool frameIsValid(const SkBitmap& frameBitmap)
2050 {
2051 return !frameBitmap.isNull()
2052 && !frameBitmap.empty()
2053 && frameBitmap.isImmutable()
2054 && frameBitmap.colorType() == kN32_SkColorType;
2055 }
2056
2057 } // anonymous namespace
2058
2059 void WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, b ool ignoreGammaAndColorProfile) 2127 void WebGLImageConversion::ImageExtractor::extractImage(bool premultiplyAlpha, b ool ignoreGammaAndColorProfile)
2060 { 2128 {
2061 ASSERT(!m_imagePixelLocker); 2129 ASSERT(!m_imagePixelLocker);
2062 2130
2063 if (!m_image) 2131 if (!m_image)
2064 return; 2132 return;
2065 2133
2066 RefPtr<SkImage> skiaImage = m_image->imageForCurrentFrame(); 2134 RefPtr<SkImage> skiaImage = m_image->imageForCurrentFrame();
2067 SkImageInfo info = skiaImage 2135 SkImageInfo info = skiaImage
2068 ? SkImageInfo::MakeN32Premul(m_image->width(), m_image->height()) 2136 ? SkImageInfo::MakeN32Premul(m_image->width(), m_image->height())
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2223 unsigned width, 2291 unsigned width,
2224 unsigned height, 2292 unsigned height,
2225 unsigned sourceUnpackAlignment, 2293 unsigned sourceUnpackAlignment,
2226 Vector<uint8_t>& data) 2294 Vector<uint8_t>& data)
2227 { 2295 {
2228 if (!pixels) 2296 if (!pixels)
2229 return false; 2297 return false;
2230 2298
2231 unsigned packedSize; 2299 unsigned packedSize;
2232 // Output data is tightly packed (alignment == 1). 2300 // Output data is tightly packed (alignment == 1).
2233 if (computeImageSizeInBytes(format, type, width, height, 1, 1, &packedSize, 0) != GL_NO_ERROR) 2301 PixelStoreParams params;
2302 params.alignment = 1;
2303 if (computeImageSizeInBytes(format, type, width, height, 1, params, &packedS ize, 0, 0) != GL_NO_ERROR)
2234 return false; 2304 return false;
2235 data.resize(packedSize); 2305 data.resize(packedSize);
2236 2306
2237 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY)) 2307 if (!packPixels(reinterpret_cast<const uint8_t*>(pixels), sourceFormat, widt h, height, sourceUnpackAlignment, format, type, alphaOp, data.data(), flipY))
2238 return false; 2308 return false;
2239 if (ImageObserver *observer = image->imageObserver()) 2309 if (ImageObserver *observer = image->imageObserver())
2240 observer->didDraw(image); 2310 observer->didDraw(image);
2241 return true; 2311 return true;
2242 } 2312 }
2243 2313
2244 bool WebGLImageConversion::extractImageData( 2314 bool WebGLImageConversion::extractImageData(
2245 const uint8_t* imageData, 2315 const uint8_t* imageData,
2246 const IntSize& imageDataSize, 2316 const IntSize& imageDataSize,
2247 GLenum format, 2317 GLenum format,
2248 GLenum type, 2318 GLenum type,
2249 bool flipY, 2319 bool flipY,
2250 bool premultiplyAlpha, 2320 bool premultiplyAlpha,
2251 Vector<uint8_t>& data) 2321 Vector<uint8_t>& data)
2252 { 2322 {
2253 if (!imageData) 2323 if (!imageData)
2254 return false; 2324 return false;
2255 int width = imageDataSize.width(); 2325 int width = imageDataSize.width();
2256 int height = imageDataSize.height(); 2326 int height = imageDataSize.height();
2257 2327
2258 unsigned packedSize; 2328 unsigned packedSize;
2259 // Output data is tightly packed (alignment == 1). 2329 // Output data is tightly packed (alignment == 1).
2260 if (computeImageSizeInBytes(format, type, width, height, 1, 1, &packedSize, 0) != GL_NO_ERROR) 2330 PixelStoreParams params;
2331 params.alignment = 1;
2332 if (computeImageSizeInBytes(format, type, width, height, 1, params, &packedS ize, 0, 0) != GL_NO_ERROR)
2261 return false; 2333 return false;
2262 data.resize(packedSize); 2334 data.resize(packedSize);
2263 2335
2264 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY)) 2336 if (!packPixels(imageData, DataFormatRGBA8, width, height, 0, format, type, premultiplyAlpha ? AlphaDoPremultiply : AlphaDoNothing, data.data(), flipY))
2265 return false; 2337 return false;
2266 2338
2267 return true; 2339 return true;
2268 } 2340 }
2269 2341
2270 bool WebGLImageConversion::extractTextureData( 2342 bool WebGLImageConversion::extractTextureData(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 } 2403 }
2332 2404
2333 FormatConverter converter(width, height, sourceData, destinationData, srcStr ide, dstStride); 2405 FormatConverter converter(width, height, sourceData, destinationData, srcStr ide, dstStride);
2334 converter.convert(sourceDataFormat, dstDataFormat, alphaOp); 2406 converter.convert(sourceDataFormat, dstDataFormat, alphaOp);
2335 if (!converter.Success()) 2407 if (!converter.Success())
2336 return false; 2408 return false;
2337 return true; 2409 return true;
2338 } 2410 }
2339 2411
2340 } // namespace blink 2412 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/WebGLImageConversion.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698