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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

Issue 1719533002: Modify YUV codecs to match Skia's API change (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Response to Patch Set 3 Created 4 years, 9 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2006 Apple Computer, Inc. 2 * Copyright (C) 2006 Apple Computer, Inc.
3 * 3 *
4 * Portions are Copyright (C) 2001-6 mozilla.org 4 * Portions are Copyright (C) 2001-6 mozilla.org
5 * 5 *
6 * Other contributors: 6 * Other contributors:
7 * Stuart Parmenter <stuart@mozilla.com> 7 * Stuart Parmenter <stuart@mozilla.com>
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public 10 * modify it under the terms of the GNU Lesser General Public
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 ignoreProfile = true; 226 ignoreProfile = true;
227 227
228 ASSERT(colorProfile.isEmpty()); 228 ASSERT(colorProfile.isEmpty());
229 if (!ignoreProfile) 229 if (!ignoreProfile)
230 colorProfile.append(profileData, profileLength); 230 colorProfile.append(profileData, profileLength);
231 free(profile); 231 free(profile);
232 #endif 232 #endif
233 } 233 }
234 #endif 234 #endif
235 235
236 static IntSize computeYUVSize(const jpeg_decompress_struct* info, int component, ImageDecoder::SizeType sizeType) 236 static IntSize computeYUVSize(const jpeg_decompress_struct* info, int component)
237 { 237 {
238 if (sizeType == ImageDecoder::SizeForMemoryAllocation) {
239 return IntSize(info->cur_comp_info[component]->width_in_blocks * DCTSIZE , info->cur_comp_info[component]->height_in_blocks * DCTSIZE);
240 }
241 return IntSize(info->cur_comp_info[component]->downsampled_width, info->cur_ comp_info[component]->downsampled_height); 238 return IntSize(info->cur_comp_info[component]->downsampled_width, info->cur_ comp_info[component]->downsampled_height);
242 } 239 }
243 240
241 static size_t computeYUVWidthBytes(const jpeg_decompress_struct* info, int compo nent)
242 {
243 return info->cur_comp_info[component]->width_in_blocks * DCTSIZE;
244 }
245
244 static yuv_subsampling yuvSubsampling(const jpeg_decompress_struct& info) 246 static yuv_subsampling yuvSubsampling(const jpeg_decompress_struct& info)
245 { 247 {
246 if ((DCTSIZE == 8) 248 if ((DCTSIZE == 8)
247 && (info.num_components == 3) 249 && (info.num_components == 3)
248 && (info.comps_in_scan >= info.num_components) 250 && (info.comps_in_scan >= info.num_components)
249 && (info.scale_denom <= 8) 251 && (info.scale_denom <= 8)
250 && (info.cur_comp_info[0]) 252 && (info.cur_comp_info[0])
251 && (info.cur_comp_info[1]) 253 && (info.cur_comp_info[1])
252 && (info.cur_comp_info[2]) 254 && (info.cur_comp_info[2])
253 && (info.cur_comp_info[1]->h_samp_factor == 1) 255 && (info.cur_comp_info[1]->h_samp_factor == 1)
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 if (m_info.out_color_space == JCS_EXT_BGRA) 489 if (m_info.out_color_space == JCS_EXT_BGRA)
488 m_info.out_color_space = JCS_EXT_RGBA; 490 m_info.out_color_space = JCS_EXT_RGBA;
489 #endif 491 #endif
490 } 492 }
491 m_decoder->setHasColorProfile(!!m_transform); 493 m_decoder->setHasColorProfile(!!m_transform);
492 } 494 }
493 #endif 495 #endif
494 if (overrideColorSpace == JCS_YCbCr) { 496 if (overrideColorSpace == JCS_YCbCr) {
495 m_info.out_color_space = JCS_YCbCr; 497 m_info.out_color_space = JCS_YCbCr;
496 m_info.raw_data_out = TRUE; 498 m_info.raw_data_out = TRUE;
497 m_uvSize = computeYUVSize(&m_info, 1, ImageDecoder::SizeForMemor yAllocation); // U size and V size have to be the same if we got here 499 m_uvSize = computeYUVSize(&m_info, 1); // U size and V size have to be the same if we got here
498 } 500 }
499 501
500 // Don't allocate a giant and superfluous memory buffer when the 502 // Don't allocate a giant and superfluous memory buffer when the
501 // image is a sequential JPEG. 503 // image is a sequential JPEG.
502 m_info.buffered_image = jpeg_has_multiple_scans(&m_info); 504 m_info.buffered_image = jpeg_has_multiple_scans(&m_info);
503 if (m_info.buffered_image) { 505 if (m_info.buffered_image) {
504 m_err.pub.emit_message = emit_message; 506 m_err.pub.emit_message = emit_message;
505 m_err.num_corrupt_warnings = 0; 507 m_err.num_corrupt_warnings = 0;
506 } 508 }
507 509
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 #endif 669 #endif
668 670
669 private: 671 private:
670 JSAMPARRAY allocateSampleArray() 672 JSAMPARRAY allocateSampleArray()
671 { 673 {
672 // Some output color spaces don't need the sample array: don't allocate in that case. 674 // Some output color spaces don't need the sample array: don't allocate in that case.
673 #if defined(TURBO_JPEG_RGB_SWIZZLE) 675 #if defined(TURBO_JPEG_RGB_SWIZZLE)
674 if (turboSwizzled(m_info.out_color_space)) 676 if (turboSwizzled(m_info.out_color_space))
675 return nullptr; 677 return nullptr;
676 #endif 678 #endif
677 int width;
678 679
679 if (m_info.out_color_space == JCS_YCbCr) 680 if (m_info.out_color_space == JCS_YCbCr) {
680 width = computeYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAlloca tion).width(); 681 // Compute the width of the Y plane in bytes. This may be larger th an the output
681 else 682 // width, since the jpeg library requires that the allocated width b e a multiple of
682 width = m_info.output_width; 683 // DCTSIZE. Note that this buffer will be used as garbage memory fo r rows that
684 // extend below the actual height of the image. We can reuse the sa me memory for
685 // the U and V planes, since we are guaranteed that the Y plane widt h is at least
686 // as large as the U and V plane widths.
Noel Gordon 2016/03/03 01:25:28 Thanks for this. Where Blink code is very tricky,
msarett 2016/03/04 19:49:08 Done.
687 int widthBytes = computeYUVWidthBytes(&m_info, 0);
688 return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr >(&m_info), JPOOL_IMAGE, widthBytes, 1);
689 }
683 690
684 return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m _info), JPOOL_IMAGE, width * 4, 1); 691 return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m _info), JPOOL_IMAGE, 4 * m_info.output_width, 1);
685 } 692 }
686 693
687 void updateRestartPosition() 694 void updateRestartPosition()
688 { 695 {
689 if (m_lastSetByte != m_info.src->next_input_byte) { 696 if (m_lastSetByte != m_info.src->next_input_byte) {
690 // next_input_byte was updated by jpeg, meaning that it found a rest art position. 697 // next_input_byte was updated by jpeg, meaning that it found a rest art position.
691 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer ; 698 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer ;
692 } 699 }
693 } 700 }
694 701
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 { 802 {
796 if (m_reader) 803 if (m_reader)
797 m_reader->setData(data); 804 m_reader->setData(data);
798 } 805 }
799 806
800 void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height) 807 void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height)
801 { 808 {
802 m_decodedSize = IntSize(width, height); 809 m_decodedSize = IntSize(width, height);
803 } 810 }
804 811
805 IntSize JPEGImageDecoder::decodedYUVSize(int component, ImageDecoder::SizeType s izeType) const 812 IntSize JPEGImageDecoder::decodedYUVSize(int component) const
806 { 813 {
807 ASSERT((component >= 0) && (component <= 2) && m_reader); 814 ASSERT((component >= 0) && (component <= 2) && m_reader);
808 const jpeg_decompress_struct* info = m_reader->info(); 815 const jpeg_decompress_struct* info = m_reader->info();
809 816
810 ASSERT(info->out_color_space == JCS_YCbCr); 817 ASSERT(info->out_color_space == JCS_YCbCr);
811 return computeYUVSize(info, component, sizeType); 818 return computeYUVSize(info, component);
819 }
820
821 size_t JPEGImageDecoder::decodedYUVWidthBytes(int component) const
822 {
823 ASSERT((component >= 0) && (component <= 2) && m_reader);
824 const jpeg_decompress_struct* info = m_reader->info();
825
826 ASSERT(info->out_color_space == JCS_YCbCr);
827 return computeYUVWidthBytes(info, component);
812 } 828 }
813 829
814 unsigned JPEGImageDecoder::desiredScaleNumerator() const 830 unsigned JPEGImageDecoder::desiredScaleNumerator() const
815 { 831 {
816 size_t originalBytes = size().width() * size().height() * 4; 832 size_t originalBytes = size().width() * size().height() * 4;
817 833
818 if (originalBytes <= m_maxDecodedBytes) 834 if (originalBytes <= m_maxDecodedBytes)
819 return scaleDenominator; 835 return scaleDenominator;
820 836
821 // Downsample according to the maximum decoded size. 837 // Downsample according to the maximum decoded size.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes) 922 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes)
907 { 923 {
908 JSAMPARRAY samples = reader->samples(); 924 JSAMPARRAY samples = reader->samples();
909 jpeg_decompress_struct* info = reader->info(); 925 jpeg_decompress_struct* info = reader->info();
910 926
911 JSAMPARRAY bufferraw[3]; 927 JSAMPARRAY bufferraw[3];
912 JSAMPROW bufferraw2[32]; 928 JSAMPROW bufferraw2[32];
913 bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16) 929 bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16)
914 bufferraw[1] = &bufferraw2[16]; // U channel rows (8) 930 bufferraw[1] = &bufferraw2[16]; // U channel rows (8)
915 bufferraw[2] = &bufferraw2[24]; // V channel rows (8) 931 bufferraw[2] = &bufferraw2[24]; // V channel rows (8)
916 int yWidth = info->output_width;
917 int yHeight = info->output_height; 932 int yHeight = info->output_height;
918 int yMaxH = yHeight - 1;
919 int v = info->cur_comp_info[0]->v_samp_factor; 933 int v = info->cur_comp_info[0]->v_samp_factor;
920 IntSize uvSize = reader->uvSize(); 934 IntSize uvSize = reader->uvSize();
921 int uvMaxH = uvSize.height() - 1; 935 int uvHeight = uvSize.height();
922 JSAMPROW outputY = static_cast<JSAMPROW>(imagePlanes->plane(0)); 936 JSAMPROW outputY = static_cast<JSAMPROW>(imagePlanes->plane(0));
923 JSAMPROW outputU = static_cast<JSAMPROW>(imagePlanes->plane(1)); 937 JSAMPROW outputU = static_cast<JSAMPROW>(imagePlanes->plane(1));
924 JSAMPROW outputV = static_cast<JSAMPROW>(imagePlanes->plane(2)); 938 JSAMPROW outputV = static_cast<JSAMPROW>(imagePlanes->plane(2));
925 size_t rowBytesY = imagePlanes->rowBytes(0); 939 size_t rowBytesY = imagePlanes->rowBytes(0);
926 size_t rowBytesU = imagePlanes->rowBytes(1); 940 size_t rowBytesU = imagePlanes->rowBytes(1);
927 size_t rowBytesV = imagePlanes->rowBytes(2); 941 size_t rowBytesV = imagePlanes->rowBytes(2);
928 942
929 // Request 8 or 16 scanlines: returns 0 or more scanlines. 943 // Request 8 or 16 scanlines: returns 0 or more scanlines.
930 int yScanlinesToRead = DCTSIZE * v; 944 int yScanlinesToRead = DCTSIZE * v;
931 JSAMPROW yLastRow = *samples; 945 JSAMPROW dummyRow = *samples;
932 JSAMPROW uLastRow = yLastRow + rowBytesY;
933 JSAMPROW vLastRow = uLastRow + rowBytesY;
934 JSAMPROW dummyRow = vLastRow + rowBytesY;
935 946
936 while (info->output_scanline < info->output_height) { 947 while (info->output_scanline < info->output_height) {
937 // Assign 8 or 16 rows of memory to read the Y channel. 948 // Assign 8 or 16 rows of memory to read the Y channel.
938 bool hasYLastRow = false;
939 for (int i = 0; i < yScanlinesToRead; ++i) { 949 for (int i = 0; i < yScanlinesToRead; ++i) {
940 int scanline = info->output_scanline + i; 950 int scanline = info->output_scanline + i;
941 if (scanline < yMaxH) { 951 if (scanline < yHeight) {
942 bufferraw2[i] = &outputY[scanline * rowBytesY]; 952 bufferraw2[i] = &outputY[scanline * rowBytesY];
943 } else if (scanline == yMaxH) {
944 bufferraw2[i] = yLastRow;
945 hasYLastRow = true;
946 } else { 953 } else {
947 bufferraw2[i] = dummyRow; 954 bufferraw2[i] = dummyRow;
948 } 955 }
949 } 956 }
950 957
951 // Assign 8 rows of memory to read the U and V channels. 958 // Assign 8 rows of memory to read the U and V channels.
952 bool hasUVLastRow = false;
953 int scaledScanline = info->output_scanline / v; 959 int scaledScanline = info->output_scanline / v;
954 for (int i = 0; i < 8; ++i) { 960 for (int i = 0; i < 8; ++i) {
955 int scanline = scaledScanline + i; 961 int scanline = scaledScanline + i;
956 if (scanline < uvMaxH) { 962 if (scanline < uvHeight) {
957 bufferraw2[16 + i] = &outputU[scanline * rowBytesU]; 963 bufferraw2[16 + i] = &outputU[scanline * rowBytesU];
958 bufferraw2[24 + i] = &outputV[scanline * rowBytesV]; 964 bufferraw2[24 + i] = &outputV[scanline * rowBytesV];
959 } else if (scanline == uvMaxH) {
960 bufferraw2[16 + i] = uLastRow;
961 bufferraw2[24 + i] = vLastRow;
962 hasUVLastRow = true;
963 } else { 965 } else {
964 bufferraw2[16 + i] = dummyRow; 966 bufferraw2[16 + i] = dummyRow;
965 bufferraw2[24 + i] = dummyRow; 967 bufferraw2[24 + i] = dummyRow;
966 } 968 }
967 } 969 }
968 970
969 JDIMENSION scanlinesRead = jpeg_read_raw_data(info, bufferraw, yScanline sToRead); 971 JDIMENSION scanlinesRead = jpeg_read_raw_data(info, bufferraw, yScanline sToRead);
970 if (!scanlinesRead) 972 if (!scanlinesRead)
971 return false; 973 return false;
972
973 if (hasYLastRow)
974 memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth);
975
976 if (hasUVLastRow) {
977 memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width());
978 memcpy(&outputV[uvMaxH * rowBytesV], vLastRow, uvSize.width());
979 }
980 } 974 }
981 975
982 info->output_scanline = std::min(info->output_scanline, info->output_height) ; 976 info->output_scanline = std::min(info->output_scanline, info->output_height) ;
983 return true; 977 return true;
984 } 978 }
985 979
986 bool JPEGImageDecoder::outputScanlines() 980 bool JPEGImageDecoder::outputScanlines()
987 { 981 {
988 if (hasImagePlanes()) 982 if (hasImagePlanes())
989 return outputRawData(m_reader.get(), m_imagePlanes.get()); 983 return outputRawData(m_reader.get(), m_imagePlanes.get());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // has failed. 1064 // has failed.
1071 if (!m_reader->decode(onlySize) && isAllDataReceived()) 1065 if (!m_reader->decode(onlySize) && isAllDataReceived())
1072 setFailed(); 1066 setFailed();
1073 1067
1074 // If decoding is done or failed, we don't need the JPEGImageReader anymore. 1068 // If decoding is done or failed, we don't need the JPEGImageReader anymore.
1075 if (isComplete(this, onlySize) || failed()) 1069 if (isComplete(this, onlySize) || failed())
1076 m_reader.clear(); 1070 m_reader.clear();
1077 } 1071 }
1078 1072
1079 } // namespace blink 1073 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698