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

Side by Side Diff: src/images/SkImageDecoder_libjpeg.cpp

Issue 1180983002: Switch SkJpegCode to libjpeg-turbo (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Rebase 2 Created 5 years, 6 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 2007 The Android Open Source Project 2 * Copyright 2007 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #include "SkImageDecoder.h" 9 #include "SkImageDecoder.h"
10 #include "SkImageEncoder.h" 10 #include "SkImageEncoder.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // attempt to delete this SkJPEGImageIndex, thus entering this 106 // attempt to delete this SkJPEGImageIndex, thus entering this
107 // destructor again. Setting fHuffmanCreated to false first 107 // destructor again. Setting fHuffmanCreated to false first
108 // prevents an infinite loop. 108 // prevents an infinite loop.
109 fHuffmanCreated = false; 109 fHuffmanCreated = false;
110 jpeg_destroy_huffman_index(&fHuffmanIndex); 110 jpeg_destroy_huffman_index(&fHuffmanIndex);
111 } 111 }
112 if (fDecompressStarted) { 112 if (fDecompressStarted) {
113 // Like fHuffmanCreated, set to false before calling libjpeg 113 // Like fHuffmanCreated, set to false before calling libjpeg
114 // function to prevent potential infinite loop. 114 // function to prevent potential infinite loop.
115 fDecompressStarted = false; 115 fDecompressStarted = false;
116 jpeg_finish_decompress(&fCInfo); 116 jFinDecompress(&fCInfo);
117 } 117 }
118 if (fInfoInitialized) { 118 if (fInfoInitialized) {
119 this->destroyInfo(); 119 this->destroyInfo();
120 } 120 }
121 } 121 }
122 122
123 /** 123 /**
124 * Destroy the cinfo struct. 124 * Destroy the cinfo struct.
125 * After this call, if a huffman index was already built, it 125 * After this call, if a huffman index was already built, it
126 * can be used after calling initializeInfoAndReadHeader 126 * can be used after calling initializeInfoAndReadHeader
127 * again. Must not be called after startTileDecompress except 127 * again. Must not be called after startTileDecompress except
128 * in the destructor. 128 * in the destructor.
129 */ 129 */
130 void destroyInfo() { 130 void destroyInfo() {
131 SkASSERT(fInfoInitialized); 131 SkASSERT(fInfoInitialized);
132 SkASSERT(!fDecompressStarted); 132 SkASSERT(!fDecompressStarted);
133 // Like fHuffmanCreated, set to false before calling libjpeg 133 // Like fHuffmanCreated, set to false before calling libjpeg
134 // function to prevent potential infinite loop. 134 // function to prevent potential infinite loop.
135 fInfoInitialized = false; 135 fInfoInitialized = false;
136 jpeg_destroy_decompress(&fCInfo); 136 jDestDecompress(&fCInfo);
137 SkDEBUGCODE(fReadHeaderSucceeded = false;) 137 SkDEBUGCODE(fReadHeaderSucceeded = false;)
138 } 138 }
139 139
140 /** 140 /**
141 * Initialize the cinfo struct. 141 * Initialize the cinfo struct.
142 * Calls jpeg_create_decompress, makes customizations, and 142 * Calls jpeg_create_decompress, makes customizations, and
143 * finally calls jpeg_read_header. Returns true if jpeg_read_header 143 * finally calls jReadHeader. Returns true if jReadHeader
144 * returns JPEG_HEADER_OK. 144 * returns JPEG_HEADER_OK.
145 * If cinfo was already initialized, destroyInfo must be called to 145 * If cinfo was already initialized, destroyInfo must be called to
146 * destroy the old one. Must not be called after startTileDecompress. 146 * destroy the old one. Must not be called after startTileDecompress.
147 */ 147 */
148 bool initializeInfoAndReadHeader() { 148 bool initializeInfoAndReadHeader() {
149 SkASSERT(!fInfoInitialized && !fDecompressStarted); 149 SkASSERT(!fInfoInitialized && !fDecompressStarted);
150 initialize_info(&fCInfo, &fSrcMgr); 150 initialize_info(&fCInfo, &fSrcMgr);
151 fInfoInitialized = true; 151 fInfoInitialized = true;
152 const bool success = (JPEG_HEADER_OK == jpeg_read_header(&fCInfo, true)) ; 152 const bool success = (JPEG_HEADER_OK == jReadHeader(&fCInfo, true));
153 SkDEBUGCODE(fReadHeaderSucceeded = success;) 153 SkDEBUGCODE(fReadHeaderSucceeded = success;)
154 return success; 154 return success;
155 } 155 }
156 156
157 jpeg_decompress_struct* cinfo() { return &fCInfo; } 157 jpeg_decompress_struct* cinfo() { return &fCInfo; }
158 158
159 huffman_index* huffmanIndex() { return &fHuffmanIndex; } 159 huffman_index* huffmanIndex() { return &fHuffmanIndex; }
160 160
161 /** 161 /**
162 * Build the index to be used for tile based decoding. 162 * Build the index to be used for tile based decoding.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 #ifdef SK_BUILD_FOR_ANDROID 233 #ifdef SK_BUILD_FOR_ANDROID
234 SkJPEGImageIndex* fImageIndex; 234 SkJPEGImageIndex* fImageIndex;
235 int fImageWidth; 235 int fImageWidth;
236 int fImageHeight; 236 int fImageHeight;
237 #endif 237 #endif
238 238
239 /** 239 /**
240 * Determine the appropriate bitmap colortype and out_color_space based on 240 * Determine the appropriate bitmap colortype and out_color_space based on
241 * both the preference of the caller and the jpeg_color_space on the 241 * both the preference of the caller and the jpeg_color_space on the
242 * jpeg_decompress_struct passed in. 242 * jpeg_decompress_struct passed in.
243 * Must be called after jpeg_read_header. 243 * Must be called after jReadHeader.
244 */ 244 */
245 SkColorType getBitmapColorType(jpeg_decompress_struct*); 245 SkColorType getBitmapColorType(jpeg_decompress_struct*);
246 246
247 typedef SkImageDecoder INHERITED; 247 typedef SkImageDecoder INHERITED;
248 }; 248 };
249 249
250 ////////////////////////////////////////////////////////////////////////// 250 //////////////////////////////////////////////////////////////////////////
251 251
252 /* Automatically clean up after throwing an exception */ 252 /* Automatically clean up after throwing an exception */
253 class JPEGAutoClean { 253 class JPEGAutoClean {
254 public: 254 public:
255 JPEGAutoClean(): cinfo_ptr(NULL) {} 255 JPEGAutoClean(): cinfo_ptr(NULL) {}
256 ~JPEGAutoClean() { 256 ~JPEGAutoClean() {
257 if (cinfo_ptr) { 257 if (cinfo_ptr) {
258 jpeg_destroy_decompress(cinfo_ptr); 258 jDestDecompress(cinfo_ptr);
259 } 259 }
260 } 260 }
261 void set(jpeg_decompress_struct* info) { 261 void set(jpeg_decompress_struct* info) {
262 cinfo_ptr = info; 262 cinfo_ptr = info;
263 } 263 }
264 private: 264 private:
265 jpeg_decompress_struct* cinfo_ptr; 265 jpeg_decompress_struct* cinfo_ptr;
266 }; 266 };
267 267
268 /////////////////////////////////////////////////////////////////////////////// 268 ///////////////////////////////////////////////////////////////////////////////
(...skipping 13 matching lines...) Expand all
282 static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) { 282 static bool valid_output_dimensions(const jpeg_decompress_struct& cinfo) {
283 /* These are initialized to 0, so if they have non-zero values, we assume 283 /* These are initialized to 0, so if they have non-zero values, we assume
284 they are "valid" (i.e. have been computed by libjpeg) 284 they are "valid" (i.e. have been computed by libjpeg)
285 */ 285 */
286 return 0 != cinfo.output_width && 0 != cinfo.output_height; 286 return 0 != cinfo.output_width && 0 != cinfo.output_height;
287 } 287 }
288 288
289 static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count ) { 289 static bool skip_src_rows(jpeg_decompress_struct* cinfo, void* buffer, int count ) {
290 for (int i = 0; i < count; i++) { 290 for (int i = 0; i < count; i++) {
291 JSAMPLE* rowptr = (JSAMPLE*)buffer; 291 JSAMPLE* rowptr = (JSAMPLE*)buffer;
292 int row_count = jpeg_read_scanlines(cinfo, &rowptr, 1); 292 int row_count = jReadScanlines(cinfo, &rowptr, 1);
293 if (1 != row_count) { 293 if (1 != row_count) {
294 return false; 294 return false;
295 } 295 }
296 } 296 }
297 return true; 297 return true;
298 } 298 }
299 299
300 #ifdef SK_BUILD_FOR_ANDROID 300 #ifdef SK_BUILD_FOR_ANDROID
301 static bool skip_src_rows_tile(jpeg_decompress_struct* cinfo, 301 static bool skip_src_rows_tile(jpeg_decompress_struct* cinfo,
302 huffman_index *index, void* buffer, int count) { 302 huffman_index *index, void* buffer, int count) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 scanline[3] = 255; 369 scanline[3] = 255;
370 } 370 }
371 } 371 }
372 372
373 /** 373 /**
374 * Common code for setting the error manager. 374 * Common code for setting the error manager.
375 */ 375 */
376 static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* error Manager) { 376 static void set_error_mgr(jpeg_decompress_struct* cinfo, skjpeg_error_mgr* error Manager) {
377 SkASSERT(cinfo != NULL); 377 SkASSERT(cinfo != NULL);
378 SkASSERT(errorManager != NULL); 378 SkASSERT(errorManager != NULL);
379 cinfo->err = jpeg_std_error(errorManager); 379 cinfo->err = jStdError(errorManager);
380 errorManager->error_exit = skjpeg_error_exit; 380 errorManager->error_exit = skjpeg_error_exit;
381 } 381 }
382 382
383 /** 383 /**
384 * Common code for turning off upsampling and smoothing. Turning these 384 * Common code for turning off upsampling and smoothing. Turning these
385 * off helps performance without showing noticable differences in the 385 * off helps performance without showing noticable differences in the
386 * resulting bitmap. 386 * resulting bitmap.
387 */ 387 */
388 static void turn_off_visual_optimizations(jpeg_decompress_struct* cinfo) { 388 static void turn_off_visual_optimizations(jpeg_decompress_struct* cinfo) {
389 SkASSERT(cinfo != NULL); 389 SkASSERT(cinfo != NULL);
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 555
556 // All objects need to be instantiated before this setjmp call so that 556 // All objects need to be instantiated before this setjmp call so that
557 // they will be cleaned up properly if an error occurs. 557 // they will be cleaned up properly if an error occurs.
558 if (setjmp(errorManager.fJmpBuf)) { 558 if (setjmp(errorManager.fJmpBuf)) {
559 return return_failure(cinfo, *bm, "setjmp"); 559 return return_failure(cinfo, *bm, "setjmp");
560 } 560 }
561 561
562 initialize_info(&cinfo, &srcManager); 562 initialize_info(&cinfo, &srcManager);
563 autoClean.set(&cinfo); 563 autoClean.set(&cinfo);
564 564
565 int status = jpeg_read_header(&cinfo, true); 565 int status = jReadHeader(&cinfo, true);
566 if (status != JPEG_HEADER_OK) { 566 if (status != JPEG_HEADER_OK) {
567 return return_failure(cinfo, *bm, "read_header"); 567 return return_failure(cinfo, *bm, "read_header");
568 } 568 }
569 569
570 /* Try to fulfill the requested sampleSize. Since jpeg can do it (when it 570 /* Try to fulfill the requested sampleSize. Since jpeg can do it (when it
571 can) much faster that we, just use their num/denom api to approximate 571 can) much faster that we, just use their num/denom api to approximate
572 the size. 572 the size.
573 */ 573 */
574 int sampleSize = this->getSampleSize(); 574 int sampleSize = this->getSampleSize();
575 575
(...skipping 14 matching lines...) Expand all
590 // Assume an A8 bitmap is not opaque to avoid the check of each 590 // Assume an A8 bitmap is not opaque to avoid the check of each
591 // individual pixel. It is very unlikely to be opaque, since 591 // individual pixel. It is very unlikely to be opaque, since
592 // an opaque A8 bitmap would not be very interesting. 592 // an opaque A8 bitmap would not be very interesting.
593 // Otherwise, a jpeg image is opaque. 593 // Otherwise, a jpeg image is opaque.
594 bool success = bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.im age_height, 594 bool success = bm->setInfo(SkImageInfo::Make(cinfo.image_width, cinfo.im age_height,
595 colorType, alphaType)); 595 colorType, alphaType));
596 return success ? kSuccess : kFailure; 596 return success ? kSuccess : kFailure;
597 } 597 }
598 598
599 /* image_width and image_height are the original dimensions, available 599 /* image_width and image_height are the original dimensions, available
600 after jpeg_read_header(). To see the scaled dimensions, we have to call 600 after jReadHeader(). To see the scaled dimensions, we have to call
601 jpeg_start_decompress(), and then read output_width and output_height. 601 jStrtDecompress(), and then read output_width and output_height.
602 */ 602 */
603 if (!jpeg_start_decompress(&cinfo)) { 603 if (!jStrtDecompress(&cinfo)) {
604 /* If we failed here, we may still have enough information to return 604 /* If we failed here, we may still have enough information to return
605 to the caller if they just wanted (subsampled bounds). If sampleSize 605 to the caller if they just wanted (subsampled bounds). If sampleSize
606 was 1, then we would have already returned. Thus we just check if 606 was 1, then we would have already returned. Thus we just check if
607 we're in kDecodeBounds_Mode, and that we have valid output sizes. 607 we're in kDecodeBounds_Mode, and that we have valid output sizes.
608 608
609 One reason to fail here is that we have insufficient stream data 609 One reason to fail here is that we have insufficient stream data
610 to complete the setup. However, output dimensions seem to get 610 to complete the setup. However, output dimensions seem to get
611 computed very early, which is why this special check can pay off. 611 computed very early, which is why this special check can pay off.
612 */ 612 */
613 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension s(cinfo)) { 613 if (SkImageDecoder::kDecodeBounds_Mode == mode && valid_output_dimension s(cinfo)) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 a significant performance boost. 647 a significant performance boost.
648 */ 648 */
649 if (sampleSize == 1 && 649 if (sampleSize == 1 &&
650 ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_888 8) || 650 ((kN32_SkColorType == colorType && cinfo.out_color_space == JCS_RGBA_888 8) ||
651 (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_ 565))) 651 (kRGB_565_SkColorType == colorType && cinfo.out_color_space == JCS_RGB_ 565)))
652 { 652 {
653 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels(); 653 JSAMPLE* rowptr = (JSAMPLE*)bm->getPixels();
654 INT32 const bpr = bm->rowBytes(); 654 INT32 const bpr = bm->rowBytes();
655 655
656 while (cinfo.output_scanline < cinfo.output_height) { 656 while (cinfo.output_scanline < cinfo.output_height) {
657 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); 657 int row_count = jReadScanlines(&cinfo, &rowptr, 1);
658 if (0 == row_count) { 658 if (0 == row_count) {
659 // if row_count == 0, then we didn't get a scanline, 659 // if row_count == 0, then we didn't get a scanline,
660 // so return early. We will return a partial image. 660 // so return early. We will return a partial image.
661 fill_below_level(cinfo.output_scanline, bm); 661 fill_below_level(cinfo.output_scanline, bm);
662 cinfo.output_scanline = cinfo.output_height; 662 cinfo.output_scanline = cinfo.output_height;
663 jpeg_finish_decompress(&cinfo); 663 jFinDecompress(&cinfo);
664 return kPartialSuccess; 664 return kPartialSuccess;
665 } 665 }
666 if (this->shouldCancelDecode()) { 666 if (this->shouldCancelDecode()) {
667 return return_failure(cinfo, *bm, "shouldCancelDecode"); 667 return return_failure(cinfo, *bm, "shouldCancelDecode");
668 } 668 }
669 rowptr += bpr; 669 rowptr += bpr;
670 } 670 }
671 jpeg_finish_decompress(&cinfo); 671 jFinDecompress(&cinfo);
672 return kSuccess; 672 return kSuccess;
673 } 673 }
674 #endif 674 #endif
675 675
676 // check for supported formats 676 // check for supported formats
677 SkScaledBitmapSampler::SrcConfig sc; 677 SkScaledBitmapSampler::SrcConfig sc;
678 int srcBytesPerPixel; 678 int srcBytesPerPixel;
679 679
680 if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) { 680 if (!get_src_config(cinfo, &sc, &srcBytesPerPixel)) {
681 return return_failure(cinfo, *bm, "jpeg colorspace"); 681 return return_failure(cinfo, *bm, "jpeg colorspace");
682 } 682 }
683 683
684 if (!sampler.begin(bm, sc, *this)) { 684 if (!sampler.begin(bm, sc, *this)) {
685 return return_failure(cinfo, *bm, "sampler.begin"); 685 return return_failure(cinfo, *bm, "sampler.begin");
686 } 686 }
687 687
688 SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel); 688 SkAutoMalloc srcStorage(cinfo.output_width * srcBytesPerPixel);
689 uint8_t* srcRow = (uint8_t*)srcStorage.get(); 689 uint8_t* srcRow = (uint8_t*)srcStorage.get();
690 690
691 // Possibly skip initial rows [sampler.srcY0] 691 // Possibly skip initial rows [sampler.srcY0]
692 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) { 692 if (!skip_src_rows(&cinfo, srcRow, sampler.srcY0())) {
693 return return_failure(cinfo, *bm, "skip rows"); 693 return return_failure(cinfo, *bm, "skip rows");
694 } 694 }
695 695
696 // now loop through scanlines until y == bm->height() - 1 696 // now loop through scanlines until y == bm->height() - 1
697 for (int y = 0;; y++) { 697 for (int y = 0;; y++) {
698 JSAMPLE* rowptr = (JSAMPLE*)srcRow; 698 JSAMPLE* rowptr = (JSAMPLE*)srcRow;
699 int row_count = jpeg_read_scanlines(&cinfo, &rowptr, 1); 699 int row_count = jReadScanlines(&cinfo, &rowptr, 1);
700 if (0 == row_count) { 700 if (0 == row_count) {
701 // if row_count == 0, then we didn't get a scanline, 701 // if row_count == 0, then we didn't get a scanline,
702 // so return early. We will return a partial image. 702 // so return early. We will return a partial image.
703 fill_below_level(y, bm); 703 fill_below_level(y, bm);
704 cinfo.output_scanline = cinfo.output_height; 704 cinfo.output_scanline = cinfo.output_height;
705 jpeg_finish_decompress(&cinfo); 705 jFinDecompress(&cinfo);
706 return kPartialSuccess; 706 return kPartialSuccess;
707 } 707 }
708 if (this->shouldCancelDecode()) { 708 if (this->shouldCancelDecode()) {
709 return return_failure(cinfo, *bm, "shouldCancelDecode"); 709 return return_failure(cinfo, *bm, "shouldCancelDecode");
710 } 710 }
711 711
712 if (JCS_CMYK == cinfo.out_color_space) { 712 if (JCS_CMYK == cinfo.out_color_space) {
713 convert_CMYK_to_RGB(srcRow, cinfo.output_width); 713 convert_CMYK_to_RGB(srcRow, cinfo.output_width);
714 } 714 }
715 715
716 sampler.next(srcRow); 716 sampler.next(srcRow);
717 if (bm->height() - 1 == y) { 717 if (bm->height() - 1 == y) {
718 // we're done 718 // we're done
719 break; 719 break;
720 } 720 }
721 721
722 if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) { 722 if (!skip_src_rows(&cinfo, srcRow, sampler.srcDY() - 1)) {
723 return return_failure(cinfo, *bm, "skip rows"); 723 return return_failure(cinfo, *bm, "skip rows");
724 } 724 }
725 } 725 }
726 726
727 // we formally skip the rest, so we don't get a complaint from libjpeg 727 // we formally skip the rest, so we don't get a complaint from libjpeg
728 if (!skip_src_rows(&cinfo, srcRow, 728 if (!skip_src_rows(&cinfo, srcRow,
729 cinfo.output_height - cinfo.output_scanline)) { 729 cinfo.output_height - cinfo.output_scanline)) {
730 return return_failure(cinfo, *bm, "skip rows"); 730 return return_failure(cinfo, *bm, "skip rows");
731 } 731 }
732 jpeg_finish_decompress(&cinfo); 732 jFinDecompress(&cinfo);
733 733
734 return kSuccess; 734 return kSuccess;
735 } 735 }
736 736
737 /////////////////////////////////////////////////////////////////////////////// 737 ///////////////////////////////////////////////////////////////////////////////
738 738
739 enum SizeType { 739 enum SizeType {
740 kSizeForMemoryAllocation_SizeType, 740 kSizeForMemoryAllocation_SizeType,
741 kActualSize_SizeType 741 kActualSize_SizeType
742 }; 742 };
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 bufferraw2[24 + i] = &outputV[scanline * rowBytesV]; 828 bufferraw2[24 + i] = &outputV[scanline * rowBytesV];
829 } else if (scanline == uvMaxH) { 829 } else if (scanline == uvMaxH) {
830 bufferraw2[16 + i] = uLastRow; 830 bufferraw2[16 + i] = uLastRow;
831 bufferraw2[24 + i] = vLastRow; 831 bufferraw2[24 + i] = vLastRow;
832 hasUVLastRow = true; 832 hasUVLastRow = true;
833 } else { 833 } else {
834 bufferraw2[16 + i] = dummyRow; 834 bufferraw2[16 + i] = dummyRow;
835 bufferraw2[24 + i] = dummyRow; 835 bufferraw2[24 + i] = dummyRow;
836 } 836 }
837 } 837 }
838 JDIMENSION scanlinesRead = jpeg_read_raw_data(&cinfo, bufferraw, yScanli nesToRead); 838 JDIMENSION scanlinesRead = jReadRawData(&cinfo, bufferraw, yScanlinesToR ead);
839 839
840 if (scanlinesRead == 0) { 840 if (scanlinesRead == 0) {
841 return false; 841 return false;
842 } 842 }
843 843
844 if (hasYLastRow) { 844 if (hasYLastRow) {
845 memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth); 845 memcpy(&outputY[yMaxH * rowBytesY], yLastRow, yWidth);
846 } 846 }
847 if (hasUVLastRow) { 847 if (hasUVLastRow) {
848 memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width()); 848 memcpy(&outputU[uvMaxH * rowBytesU], uLastRow, uvSize.width());
(...skipping 26 matching lines...) Expand all
875 875
876 // All objects need to be instantiated before this setjmp call so that 876 // All objects need to be instantiated before this setjmp call so that
877 // they will be cleaned up properly if an error occurs. 877 // they will be cleaned up properly if an error occurs.
878 if (setjmp(errorManager.fJmpBuf)) { 878 if (setjmp(errorManager.fJmpBuf)) {
879 return return_false(cinfo, "setjmp YUV8"); 879 return return_false(cinfo, "setjmp YUV8");
880 } 880 }
881 881
882 initialize_info(&cinfo, &srcManager); 882 initialize_info(&cinfo, &srcManager);
883 autoClean.set(&cinfo); 883 autoClean.set(&cinfo);
884 884
885 int status = jpeg_read_header(&cinfo, true); 885 int status = jReadHeader(&cinfo, true);
886 if (status != JPEG_HEADER_OK) { 886 if (status != JPEG_HEADER_OK) {
887 return return_false(cinfo, "read_header YUV8"); 887 return return_false(cinfo, "read_header YUV8");
888 } 888 }
889 889
890 if (!appears_to_be_yuv(cinfo)) { 890 if (!appears_to_be_yuv(cinfo)) {
891 // It's not an error to not be encoded in YUV, so no need to use return_ false() 891 // It's not an error to not be encoded in YUV, so no need to use return_ false()
892 return false; 892 return false;
893 } 893 }
894 894
895 cinfo.out_color_space = JCS_YCbCr; 895 cinfo.out_color_space = JCS_YCbCr;
896 cinfo.raw_data_out = TRUE; 896 cinfo.raw_data_out = TRUE;
897 897
898 if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size on ly 898 if (!planes || !planes[0] || !rowBytes || !rowBytes[0]) { // Compute size on ly
899 update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_ SizeType); 899 update_components_sizes(cinfo, componentSizes, kSizeForMemoryAllocation_ SizeType);
900 return true; 900 return true;
901 } 901 }
902 902
903 set_dct_method(*this, &cinfo); 903 set_dct_method(*this, &cinfo);
904 904
905 SkASSERT(1 == cinfo.scale_num); 905 SkASSERT(1 == cinfo.scale_num);
906 cinfo.scale_denom = 1; 906 cinfo.scale_denom = 1;
907 907
908 turn_off_visual_optimizations(&cinfo); 908 turn_off_visual_optimizations(&cinfo);
909 909
910 #ifdef ANDROID_RGB 910 #ifdef ANDROID_RGB
911 cinfo.dither_mode = JDITHER_NONE; 911 cinfo.dither_mode = JDITHER_NONE;
912 #endif 912 #endif
913 913
914 /* image_width and image_height are the original dimensions, available 914 /* image_width and image_height are the original dimensions, available
915 after jpeg_read_header(). To see the scaled dimensions, we have to call 915 after jReadHeader(). To see the scaled dimensions, we have to call
916 jpeg_start_decompress(), and then read output_width and output_height. 916 jStrtDecompress(), and then read output_width and output_height.
917 */ 917 */
918 if (!jpeg_start_decompress(&cinfo)) { 918 if (!jStrtDecompress(&cinfo)) {
919 return return_false(cinfo, "start_decompress YUV8"); 919 return return_false(cinfo, "start_decompress YUV8");
920 } 920 }
921 921
922 // Seems like jpeg_start_decompress is updating our opinion of whether cinfo represents YUV. 922 // Seems like jStrtDecompress is updating our opinion of whether cinfo repre sents YUV.
923 // Again, not really an error. 923 // Again, not really an error.
924 if (!appears_to_be_yuv(cinfo)) { 924 if (!appears_to_be_yuv(cinfo)) {
925 return false; 925 return false;
926 } 926 }
927 927
928 if (!output_raw_data(cinfo, planes, rowBytes)) { 928 if (!output_raw_data(cinfo, planes, rowBytes)) {
929 return return_false(cinfo, "output_raw_data"); 929 return return_false(cinfo, "output_raw_data");
930 } 930 }
931 931
932 update_components_sizes(cinfo, componentSizes, kActualSize_SizeType); 932 update_components_sizes(cinfo, componentSizes, kActualSize_SizeType);
933 jpeg_finish_decompress(&cinfo); 933 jFinDecompress(&cinfo);
934 934
935 if (NULL != colorSpace) { 935 if (NULL != colorSpace) {
936 *colorSpace = kJPEG_SkYUVColorSpace; 936 *colorSpace = kJPEG_SkYUVColorSpace;
937 } 937 }
938 938
939 return true; 939 return true;
940 } 940 }
941 941
942 /////////////////////////////////////////////////////////////////////////////// 942 ///////////////////////////////////////////////////////////////////////////////
943 943
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 set_error_mgr(cinfo, &sk_err); 977 set_error_mgr(cinfo, &sk_err);
978 978
979 // FIXME: This sets cinfo->out_color_space, which we may change later 979 // FIXME: This sets cinfo->out_color_space, which we may change later
980 // based on the config in onDecodeSubset. This should be fine, since 980 // based on the config in onDecodeSubset. This should be fine, since
981 // jpeg_init_read_tile_scanline will check out_color_space again after 981 // jpeg_init_read_tile_scanline will check out_color_space again after
982 // that change (when it calls jinit_color_deconverter). 982 // that change (when it calls jinit_color_deconverter).
983 (void) this->getBitmapColorType(cinfo); 983 (void) this->getBitmapColorType(cinfo);
984 984
985 turn_off_visual_optimizations(cinfo); 985 turn_off_visual_optimizations(cinfo);
986 986
987 // instead of jpeg_start_decompress() we start a tiled decompress 987 // instead of jStrtDecompress() we start a tiled decompress
988 if (!imageIndex->startTileDecompress()) { 988 if (!imageIndex->startTileDecompress()) {
989 return false; 989 return false;
990 } 990 }
991 991
992 SkASSERT(1 == cinfo->scale_num); 992 SkASSERT(1 == cinfo->scale_num);
993 fImageWidth = cinfo->output_width; 993 fImageWidth = cinfo->output_width;
994 fImageHeight = cinfo->output_height; 994 fImageHeight = cinfo->output_height;
995 995
996 if (width) { 996 if (width) {
997 *width = fImageWidth; 997 *width = fImageWidth;
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 return false; 1352 return false;
1353 } 1353 }
1354 1354
1355 jpeg_compress_struct cinfo; 1355 jpeg_compress_struct cinfo;
1356 skjpeg_error_mgr sk_err; 1356 skjpeg_error_mgr sk_err;
1357 skjpeg_destination_mgr sk_wstream(stream); 1357 skjpeg_destination_mgr sk_wstream(stream);
1358 1358
1359 // allocate these before set call setjmp 1359 // allocate these before set call setjmp
1360 SkAutoMalloc oneRow; 1360 SkAutoMalloc oneRow;
1361 1361
1362 cinfo.err = jpeg_std_error(&sk_err); 1362 cinfo.err = jStdError(&sk_err);
1363 sk_err.error_exit = skjpeg_error_exit; 1363 sk_err.error_exit = skjpeg_error_exit;
1364 if (setjmp(sk_err.fJmpBuf)) { 1364 if (setjmp(sk_err.fJmpBuf)) {
1365 return false; 1365 return false;
1366 } 1366 }
1367 1367
1368 // Keep after setjmp or mark volatile. 1368 // Keep after setjmp or mark volatile.
1369 const WriteScanline writer = ChooseWriter(bm); 1369 const WriteScanline writer = ChooseWriter(bm);
1370 if (NULL == writer) { 1370 if (NULL == writer) {
1371 return false; 1371 return false;
1372 } 1372 }
1373 1373
1374 jpeg_create_compress(&cinfo); 1374 jpeg_create_compress(&cinfo);
1375 cinfo.dest = &sk_wstream; 1375 cinfo.dest = &sk_wstream;
1376 cinfo.image_width = bm.width(); 1376 cinfo.image_width = bm.width();
1377 cinfo.image_height = bm.height(); 1377 cinfo.image_height = bm.height();
1378 cinfo.input_components = 3; 1378 cinfo.input_components = 3;
1379 #ifdef WE_CONVERT_TO_YUV 1379 #ifdef WE_CONVERT_TO_YUV
1380 cinfo.in_color_space = JCS_YCbCr; 1380 cinfo.in_color_space = JCS_YCbCr;
1381 #else 1381 #else
1382 cinfo.in_color_space = JCS_RGB; 1382 cinfo.in_color_space = JCS_RGB;
1383 #endif 1383 #endif
1384 cinfo.input_gamma = 1; 1384 cinfo.input_gamma = 1;
1385 1385
1386 jpeg_set_defaults(&cinfo); 1386 jSetDefaults(&cinfo);
1387 jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); 1387 jSetQuality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
1388 #ifdef DCT_IFAST_SUPPORTED 1388 #ifdef DCT_IFAST_SUPPORTED
1389 cinfo.dct_method = JDCT_IFAST; 1389 cinfo.dct_method = JDCT_IFAST;
1390 #endif 1390 #endif
1391 1391
1392 jpeg_start_compress(&cinfo, TRUE); 1392 jStrtCompress(&cinfo, TRUE);
1393 1393
1394 const int width = bm.width(); 1394 const int width = bm.width();
1395 uint8_t* oneRowP = (uint8_t*)oneRow.reset(width * 3); 1395 uint8_t* oneRowP = (uint8_t*)oneRow.reset(width * 3);
1396 1396
1397 const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readC olors() : NULL; 1397 const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readC olors() : NULL;
1398 const void* srcRow = bm.getPixels(); 1398 const void* srcRow = bm.getPixels();
1399 1399
1400 while (cinfo.next_scanline < cinfo.image_height) { 1400 while (cinfo.next_scanline < cinfo.image_height) {
1401 JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ 1401 JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
1402 1402
1403 writer(oneRowP, srcRow, width, colors); 1403 writer(oneRowP, srcRow, width, colors);
1404 row_pointer[0] = oneRowP; 1404 row_pointer[0] = oneRowP;
1405 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); 1405 (void) jWrtScanlines(&cinfo, row_pointer, 1);
1406 srcRow = (const void*)((const char*)srcRow + bm.rowBytes()); 1406 srcRow = (const void*)((const char*)srcRow + bm.rowBytes());
1407 } 1407 }
1408 1408
1409 jpeg_finish_compress(&cinfo); 1409 jFinCompress(&cinfo);
1410 jpeg_destroy_compress(&cinfo); 1410 jDestCompress(&cinfo);
1411 1411
1412 return true; 1412 return true;
1413 } 1413 }
1414 }; 1414 };
1415 1415
1416 /////////////////////////////////////////////////////////////////////////////// 1416 ///////////////////////////////////////////////////////////////////////////////
1417 DEFINE_DECODER_CREATOR(JPEGImageDecoder); 1417 DEFINE_DECODER_CREATOR(JPEGImageDecoder);
1418 DEFINE_ENCODER_CREATOR(JPEGImageEncoder); 1418 DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
1419 /////////////////////////////////////////////////////////////////////////////// 1419 ///////////////////////////////////////////////////////////////////////////////
1420 1420
(...skipping 28 matching lines...) Expand all
1449 return SkImageDecoder::kUnknown_Format; 1449 return SkImageDecoder::kUnknown_Format;
1450 } 1450 }
1451 1451
1452 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) { 1452 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
1453 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL; 1453 return (SkImageEncoder::kJPEG_Type == t) ? SkNEW(SkJPEGImageEncoder) : NULL;
1454 } 1454 }
1455 1455
1456 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory); 1456 static SkImageDecoder_DecodeReg gDReg(sk_libjpeg_dfactory);
1457 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg); 1457 static SkImageDecoder_FormatReg gFormatReg(get_format_jpeg);
1458 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory); 1458 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698