Chromium Code Reviews| Index: third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp |
| diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp |
| index b940a89422b145bc6945c61eb426658016c51d68..069a8768d0d1a050646e9c5ea4e26c8d9222cff2 100644 |
| --- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp |
| +++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp |
| @@ -233,14 +233,16 @@ static void readColorProfile(jpeg_decompress_struct* info, ColorProfile& colorPr |
| } |
| #endif |
| -static IntSize computeYUVSize(const jpeg_decompress_struct* info, int component, ImageDecoder::SizeType sizeType) |
| +static IntSize computeYUVSize(const jpeg_decompress_struct* info, int component) |
| { |
| - if (sizeType == ImageDecoder::SizeForMemoryAllocation) { |
| - return IntSize(info->cur_comp_info[component]->width_in_blocks * DCTSIZE, info->cur_comp_info[component]->height_in_blocks * DCTSIZE); |
| - } |
| return IntSize(info->cur_comp_info[component]->downsampled_width, info->cur_comp_info[component]->downsampled_height); |
| } |
| +static size_t computeYUVWidthBytes(const jpeg_decompress_struct* info, int component) |
| +{ |
| + return info->cur_comp_info[component]->width_in_blocks * DCTSIZE; |
| +} |
| + |
| static yuv_subsampling yuvSubsampling(const jpeg_decompress_struct& info) |
| { |
| if ((DCTSIZE == 8) |
| @@ -494,7 +496,7 @@ public: |
| if (overrideColorSpace == JCS_YCbCr) { |
| m_info.out_color_space = JCS_YCbCr; |
| m_info.raw_data_out = TRUE; |
| - m_uvSize = computeYUVSize(&m_info, 1, ImageDecoder::SizeForMemoryAllocation); // U size and V size have to be the same if we got here |
| + m_uvSize = computeYUVSize(&m_info, 1); // U size and V size have to be the same if we got here |
| } |
| // Don't allocate a giant and superfluous memory buffer when the |
| @@ -674,14 +676,17 @@ private: |
| if (turboSwizzled(m_info.out_color_space)) |
| return nullptr; |
| #endif |
| - int width; |
| + int width, bpp; |
| - if (m_info.out_color_space == JCS_YCbCr) |
| - width = computeYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAllocation).width(); |
| - else |
| + if (m_info.out_color_space == JCS_YCbCr) { |
| + width = computeYUVWidthBytes(&m_info, 0); |
| + bpp = 1; |
| + } else { |
| width = m_info.output_width; |
| + bpp = 4; |
|
msarett
2016/02/22 20:56:31
I suspect that this can/should be 3. But that is
scroggo_chromium
2016/02/24 13:09:43
According to a comment at the call site [1], it sh
|
| + } |
| - return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, width * 4, 1); |
| + return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m_info), JPOOL_IMAGE, width * bpp, 1); |
| } |
| void updateRestartPosition() |
| @@ -802,13 +807,22 @@ void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height) |
| m_decodedSize = IntSize(width, height); |
| } |
| -IntSize JPEGImageDecoder::decodedYUVSize(int component, ImageDecoder::SizeType sizeType) const |
| +IntSize JPEGImageDecoder::decodedYUVSize(int component) const |
| +{ |
| + ASSERT((component >= 0) && (component <= 2) && m_reader); |
| + const jpeg_decompress_struct* info = m_reader->info(); |
| + |
| + ASSERT(info->out_color_space == JCS_YCbCr); |
| + return computeYUVSize(info, component); |
| +} |
| + |
| +size_t JPEGImageDecoder::decodedYUVWidthBytes(int component) const |
| { |
| ASSERT((component >= 0) && (component <= 2) && m_reader); |
| const jpeg_decompress_struct* info = m_reader->info(); |
| ASSERT(info->out_color_space == JCS_YCbCr); |
| - return computeYUVSize(info, component, sizeType); |
| + return computeYUVWidthBytes(info, component); |
| } |
| unsigned JPEGImageDecoder::desiredScaleNumerator() const |
| @@ -913,7 +927,6 @@ static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) |
| bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16) |
| bufferraw[1] = &bufferraw2[16]; // U channel rows (8) |
| bufferraw[2] = &bufferraw2[24]; // V channel rows (8) |
| - int yWidth = info->output_width; |
| int yHeight = info->output_height; |
| int yMaxH = yHeight - 1; |
| int v = info->cur_comp_info[0]->v_samp_factor; |
| @@ -928,38 +941,26 @@ static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) |
| // Request 8 or 16 scanlines: returns 0 or more scanlines. |
| int yScanlinesToRead = DCTSIZE * v; |
| - JSAMPROW yLastRow = *samples; |
|
msarett
2016/02/22 20:56:31
No need to track the last row and perform a memcpy
|
| - JSAMPROW uLastRow = yLastRow + rowBytesY; |
| - JSAMPROW vLastRow = uLastRow + rowBytesY; |
| - JSAMPROW dummyRow = vLastRow + rowBytesY; |
| + JSAMPROW dummyRow = *samples; |
|
msarett
2016/02/22 20:56:31
Notice that we use a dummy row when the height of
|
| while (info->output_scanline < info->output_height) { |
| // Assign 8 or 16 rows of memory to read the Y channel. |
| - bool hasYLastRow = false; |
| for (int i = 0; i < yScanlinesToRead; ++i) { |
| int scanline = info->output_scanline + i; |
| if (scanline < yMaxH) { |
| bufferraw2[i] = &outputY[scanline * rowBytesY]; |
| - } else if (scanline == yMaxH) { |
| - bufferraw2[i] = yLastRow; |
| - hasYLastRow = true; |
| } else { |
| bufferraw2[i] = dummyRow; |
| } |
| } |
| // Assign 8 rows of memory to read the U and V channels. |
| - bool hasUVLastRow = false; |
| int scaledScanline = info->output_scanline / v; |
| for (int i = 0; i < 8; ++i) { |
| int scanline = scaledScanline + i; |
| if (scanline < uvMaxH) { |
| bufferraw2[16 + i] = &outputU[scanline * rowBytesU]; |
| bufferraw2[24 + i] = &outputV[scanline * rowBytesV]; |
| - } else if (scanline == uvMaxH) { |
| - bufferraw2[16 + i] = uLastRow; |
| - bufferraw2[24 + i] = vLastRow; |
| - hasUVLastRow = true; |
| } else { |
| bufferraw2[16 + i] = dummyRow; |
| bufferraw2[24 + i] = dummyRow; |
| @@ -969,14 +970,6 @@ static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) |
| JDIMENSION scanlinesRead = jpeg_read_raw_data(info, bufferraw, yScanlinesToRead); |
| if (!scanlinesRead) |
| return false; |
| - |
| - if (hasYLastRow) |
| - memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth); |
| - |
| - if (hasUVLastRow) { |
| - memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width()); |
| - memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width()); |
| - } |
| } |
| info->output_scanline = std::min(info->output_scanline, info->output_height); |