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

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: ASSERT in base class YUV implementations, Use ArrayBuffer Created 4 years, 10 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; 679 int width, bpp;
678 680
Noel Gordon 2016/03/01 02:27:49 abbrv: what is bpp?
msarett 2016/03/01 18:00:38 bytesPer(Pixel/YSample/USample/VSample). I've rew
679 if (m_info.out_color_space == JCS_YCbCr) 681 if (m_info.out_color_space == JCS_YCbCr) {
680 width = computeYUVSize(&m_info, 0, ImageDecoder::SizeForMemoryAlloca tion).width(); 682 width = computeYUVWidthBytes(&m_info, 0);
681 else 683 bpp = 1;
Noel Gordon 2016/03/01 02:27:49 We seem to be allocating less memory for the YCbCr
msarett 2016/03/01 18:00:38 The jpeg library requires that the memory widths a
684 } else {
682 width = m_info.output_width; 685 width = m_info.output_width;
686 bpp = 4;
687 }
683 688
684 return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m _info), JPOOL_IMAGE, width * 4, 1); 689 return (*m_info.mem->alloc_sarray)(reinterpret_cast_ptr<j_common_ptr>(&m _info), JPOOL_IMAGE, width * bpp, 1);
685 } 690 }
686 691
687 void updateRestartPosition() 692 void updateRestartPosition()
688 { 693 {
689 if (m_lastSetByte != m_info.src->next_input_byte) { 694 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. 695 // 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 ; 696 m_restartPosition = m_nextReadPosition - m_info.src->bytes_in_buffer ;
692 } 697 }
693 } 698 }
694 699
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 { 800 {
796 if (m_reader) 801 if (m_reader)
797 m_reader->setData(data); 802 m_reader->setData(data);
798 } 803 }
799 804
800 void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height) 805 void JPEGImageDecoder::setDecodedSize(unsigned width, unsigned height)
801 { 806 {
802 m_decodedSize = IntSize(width, height); 807 m_decodedSize = IntSize(width, height);
803 } 808 }
804 809
805 IntSize JPEGImageDecoder::decodedYUVSize(int component, ImageDecoder::SizeType s izeType) const 810 IntSize JPEGImageDecoder::decodedYUVSize(int component) const
806 { 811 {
807 ASSERT((component >= 0) && (component <= 2) && m_reader); 812 ASSERT((component >= 0) && (component <= 2) && m_reader);
808 const jpeg_decompress_struct* info = m_reader->info(); 813 const jpeg_decompress_struct* info = m_reader->info();
809 814
810 ASSERT(info->out_color_space == JCS_YCbCr); 815 ASSERT(info->out_color_space == JCS_YCbCr);
811 return computeYUVSize(info, component, sizeType); 816 return computeYUVSize(info, component);
817 }
818
819 size_t JPEGImageDecoder::decodedYUVWidthBytes(int component) const
820 {
821 ASSERT((component >= 0) && (component <= 2) && m_reader);
822 const jpeg_decompress_struct* info = m_reader->info();
823
824 ASSERT(info->out_color_space == JCS_YCbCr);
825 return computeYUVWidthBytes(info, component);
812 } 826 }
813 827
814 unsigned JPEGImageDecoder::desiredScaleNumerator() const 828 unsigned JPEGImageDecoder::desiredScaleNumerator() const
815 { 829 {
816 size_t originalBytes = size().width() * size().height() * 4; 830 size_t originalBytes = size().width() * size().height() * 4;
817 831
818 if (originalBytes <= m_maxDecodedBytes) 832 if (originalBytes <= m_maxDecodedBytes)
819 return scaleDenominator; 833 return scaleDenominator;
820 834
821 // Downsample according to the maximum decoded size. 835 // 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) 920 static bool outputRawData(JPEGImageReader* reader, ImagePlanes* imagePlanes)
907 { 921 {
908 JSAMPARRAY samples = reader->samples(); 922 JSAMPARRAY samples = reader->samples();
909 jpeg_decompress_struct* info = reader->info(); 923 jpeg_decompress_struct* info = reader->info();
910 924
911 JSAMPARRAY bufferraw[3]; 925 JSAMPARRAY bufferraw[3];
912 JSAMPROW bufferraw2[32]; 926 JSAMPROW bufferraw2[32];
913 bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16) 927 bufferraw[0] = &bufferraw2[0]; // Y channel rows (8 or 16)
914 bufferraw[1] = &bufferraw2[16]; // U channel rows (8) 928 bufferraw[1] = &bufferraw2[16]; // U channel rows (8)
915 bufferraw[2] = &bufferraw2[24]; // V channel rows (8) 929 bufferraw[2] = &bufferraw2[24]; // V channel rows (8)
916 int yWidth = info->output_width;
917 int yHeight = info->output_height; 930 int yHeight = info->output_height;
918 int yMaxH = yHeight - 1; 931 int yMaxH = yHeight - 1;
919 int v = info->cur_comp_info[0]->v_samp_factor; 932 int v = info->cur_comp_info[0]->v_samp_factor;
920 IntSize uvSize = reader->uvSize(); 933 IntSize uvSize = reader->uvSize();
921 int uvMaxH = uvSize.height() - 1; 934 int uvMaxH = uvSize.height() - 1;
922 JSAMPROW outputY = static_cast<JSAMPROW>(imagePlanes->plane(0)); 935 JSAMPROW outputY = static_cast<JSAMPROW>(imagePlanes->plane(0));
923 JSAMPROW outputU = static_cast<JSAMPROW>(imagePlanes->plane(1)); 936 JSAMPROW outputU = static_cast<JSAMPROW>(imagePlanes->plane(1));
924 JSAMPROW outputV = static_cast<JSAMPROW>(imagePlanes->plane(2)); 937 JSAMPROW outputV = static_cast<JSAMPROW>(imagePlanes->plane(2));
925 size_t rowBytesY = imagePlanes->rowBytes(0); 938 size_t rowBytesY = imagePlanes->rowBytes(0);
926 size_t rowBytesU = imagePlanes->rowBytes(1); 939 size_t rowBytesU = imagePlanes->rowBytes(1);
927 size_t rowBytesV = imagePlanes->rowBytes(2); 940 size_t rowBytesV = imagePlanes->rowBytes(2);
928 941
929 // Request 8 or 16 scanlines: returns 0 or more scanlines. 942 // Request 8 or 16 scanlines: returns 0 or more scanlines.
930 int yScanlinesToRead = DCTSIZE * v; 943 int yScanlinesToRead = DCTSIZE * v;
931 JSAMPROW yLastRow = *samples; 944 JSAMPROW dummyRow = *samples;
932 JSAMPROW uLastRow = yLastRow + rowBytesY;
933 JSAMPROW vLastRow = uLastRow + rowBytesY;
934 JSAMPROW dummyRow = vLastRow + rowBytesY;
935 945
936 while (info->output_scanline < info->output_height) { 946 while (info->output_scanline < info->output_height) {
937 // Assign 8 or 16 rows of memory to read the Y channel. 947 // Assign 8 or 16 rows of memory to read the Y channel.
938 bool hasYLastRow = false;
939 for (int i = 0; i < yScanlinesToRead; ++i) { 948 for (int i = 0; i < yScanlinesToRead; ++i) {
940 int scanline = info->output_scanline + i; 949 int scanline = info->output_scanline + i;
941 if (scanline < yMaxH) { 950 if (scanline < yMaxH) {
942 bufferraw2[i] = &outputY[scanline * rowBytesY]; 951 bufferraw2[i] = &outputY[scanline * rowBytesY];
943 } else if (scanline == yMaxH) {
944 bufferraw2[i] = yLastRow;
945 hasYLastRow = true;
946 } else { 952 } else {
947 bufferraw2[i] = dummyRow; 953 bufferraw2[i] = dummyRow;
948 } 954 }
949 } 955 }
950 956
951 // Assign 8 rows of memory to read the U and V channels. 957 // Assign 8 rows of memory to read the U and V channels.
952 bool hasUVLastRow = false;
953 int scaledScanline = info->output_scanline / v; 958 int scaledScanline = info->output_scanline / v;
954 for (int i = 0; i < 8; ++i) { 959 for (int i = 0; i < 8; ++i) {
955 int scanline = scaledScanline + i; 960 int scanline = scaledScanline + i;
956 if (scanline < uvMaxH) { 961 if (scanline < uvMaxH) {
957 bufferraw2[16 + i] = &outputU[scanline * rowBytesU]; 962 bufferraw2[16 + i] = &outputU[scanline * rowBytesU];
958 bufferraw2[24 + i] = &outputV[scanline * rowBytesV]; 963 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 { 964 } else {
964 bufferraw2[16 + i] = dummyRow; 965 bufferraw2[16 + i] = dummyRow;
965 bufferraw2[24 + i] = dummyRow; 966 bufferraw2[24 + i] = dummyRow;
966 } 967 }
967 } 968 }
968 969
969 JDIMENSION scanlinesRead = jpeg_read_raw_data(info, bufferraw, yScanline sToRead); 970 JDIMENSION scanlinesRead = jpeg_read_raw_data(info, bufferraw, yScanline sToRead);
970 if (!scanlinesRead) 971 if (!scanlinesRead)
971 return false; 972 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 } 973 }
981 974
982 info->output_scanline = std::min(info->output_scanline, info->output_height) ; 975 info->output_scanline = std::min(info->output_scanline, info->output_height) ;
983 return true; 976 return true;
984 } 977 }
985 978
986 bool JPEGImageDecoder::outputScanlines() 979 bool JPEGImageDecoder::outputScanlines()
987 { 980 {
988 if (hasImagePlanes()) 981 if (hasImagePlanes())
989 return outputRawData(m_reader.get(), m_imagePlanes.get()); 982 return outputRawData(m_reader.get(), m_imagePlanes.get());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 // has failed. 1063 // has failed.
1071 if (!m_reader->decode(onlySize) && isAllDataReceived()) 1064 if (!m_reader->decode(onlySize) && isAllDataReceived())
1072 setFailed(); 1065 setFailed();
1073 1066
1074 // If decoding is done or failed, we don't need the JPEGImageReader anymore. 1067 // If decoding is done or failed, we don't need the JPEGImageReader anymore.
1075 if (isComplete(this, onlySize) || failed()) 1068 if (isComplete(this, onlySize) || failed())
1076 m_reader.clear(); 1069 m_reader.clear();
1077 } 1070 }
1078 1071
1079 } // namespace blink 1072 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698