| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright 2015 Google Inc. |    2  * Copyright 2015 Google Inc. | 
|    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 #include "SkCodec.h" |    8 #include "SkCodec.h" | 
 |    9 #include "SkMSAN.h" | 
|    9 #include "SkJpegCodec.h" |   10 #include "SkJpegCodec.h" | 
|   10 #include "SkJpegDecoderMgr.h" |   11 #include "SkJpegDecoderMgr.h" | 
|   11 #include "SkJpegUtility_codec.h" |   12 #include "SkJpegUtility_codec.h" | 
|   12 #include "SkCodecPriv.h" |   13 #include "SkCodecPriv.h" | 
|   13 #include "SkColorPriv.h" |   14 #include "SkColorPriv.h" | 
|   14 #include "SkStream.h" |   15 #include "SkStream.h" | 
|   15 #include "SkTemplates.h" |   16 #include "SkTemplates.h" | 
|   16 #include "SkTypes.h" |   17 #include "SkTypes.h" | 
|   17  |   18  | 
|   18 // stdio is needed for libjpeg-turbo |   19 // stdio is needed for libjpeg-turbo | 
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  208                 // much faster than decoding to color and then converting |  209                 // much faster than decoding to color and then converting | 
|  209                 fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE; |  210                 fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE; | 
|  210             } |  211             } | 
|  211             return true; |  212             return true; | 
|  212         default: |  213         default: | 
|  213             return false; |  214             return false; | 
|  214     } |  215     } | 
|  215 } |  216 } | 
|  216  |  217  | 
|  217 /* |  218 /* | 
|  218  * Checks if we can natively scale to the requested dimensions and natively scal
     es the  |  219  * Checks if we can natively scale to the requested dimensions and natively scal
     es the | 
|  219  * dimensions if possible |  220  * dimensions if possible | 
|  220  */ |  221  */ | 
|  221 bool SkJpegCodec::onDimensionsSupported(const SkISize& size) { |  222 bool SkJpegCodec::onDimensionsSupported(const SkISize& size) { | 
|  222     if (setjmp(fDecoderMgr->getJmpBuf())) { |  223     if (setjmp(fDecoderMgr->getJmpBuf())) { | 
|  223         return fDecoderMgr->returnFalse("onDimensionsSupported/setjmp"); |  224         return fDecoderMgr->returnFalse("onDimensionsSupported/setjmp"); | 
|  224     } |  225     } | 
|  225  |  226  | 
|  226     const unsigned int dstWidth = size.width(); |  227     const unsigned int dstWidth = size.width(); | 
|  227     const unsigned int dstHeight = size.height(); |  228     const unsigned int dstHeight = size.height(); | 
|  228  |  229  | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  301         // write data to storage row, then sample using swizzler |  302         // write data to storage row, then sample using swizzler | 
|  302         dstRow = fSrcRow; |  303         dstRow = fSrcRow; | 
|  303     } else { |  304     } else { | 
|  304         // write data directly to dst |  305         // write data directly to dst | 
|  305         dstRow = (JSAMPLE*) dst; |  306         dstRow = (JSAMPLE*) dst; | 
|  306     } |  307     } | 
|  307  |  308  | 
|  308     for (uint32_t y = 0; y < dstHeight; y++) { |  309     for (uint32_t y = 0; y < dstHeight; y++) { | 
|  309         // Read rows of the image |  310         // Read rows of the image | 
|  310         uint32_t lines = jpeg_read_scanlines(dinfo, &dstRow, 1); |  311         uint32_t lines = jpeg_read_scanlines(dinfo, &dstRow, 1); | 
 |  312         sk_msan_mark_initialized(dstRow, dstRow + dstRowBytes, "skbug.com/4550")
     ; | 
|  311  |  313  | 
|  312         // If we cannot read enough rows, assume the input is incomplete |  314         // If we cannot read enough rows, assume the input is incomplete | 
|  313         if (lines != 1) { |  315         if (lines != 1) { | 
|  314             *rowsDecoded = y; |  316             *rowsDecoded = y; | 
|  315  |  317  | 
|  316             return fDecoderMgr->returnFailure("Incomplete image data", kIncomple
     teInput); |  318             return fDecoderMgr->returnFailure("Incomplete image data", kIncomple
     teInput); | 
|  317         } |  319         } | 
|  318  |  320  | 
|  319         if (fSwizzler) { |  321         if (fSwizzler) { | 
|  320             // use swizzler to sample row |  322             // use swizzler to sample row | 
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  392  |  394  | 
|  393     // We will need a swizzler if we are performing a subset decode or |  395     // We will need a swizzler if we are performing a subset decode or | 
|  394     // converting from CMYK. |  396     // converting from CMYK. | 
|  395     if (options.fSubset || JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { |  397     if (options.fSubset || JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) { | 
|  396         this->initializeSwizzler(dstInfo, options); |  398         this->initializeSwizzler(dstInfo, options); | 
|  397     } |  399     } | 
|  398  |  400  | 
|  399     return kSuccess; |  401     return kSuccess; | 
|  400 } |  402 } | 
|  401  |  403  | 
|  402 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) { |  404 int SkJpegCodec::onGetScanlines(void* dst, int count, size_t dstRowBytes) { | 
|  403     // Set the jump location for libjpeg errors |  405     // Set the jump location for libjpeg errors | 
|  404     if (setjmp(fDecoderMgr->getJmpBuf())) { |  406     if (setjmp(fDecoderMgr->getJmpBuf())) { | 
|  405         return fDecoderMgr->returnFailure("setjmp", kInvalidInput); |  407         return fDecoderMgr->returnFailure("setjmp", kInvalidInput); | 
|  406     } |  408     } | 
|  407     // Read rows one at a time |  409     // Read rows one at a time | 
|  408     JSAMPLE* dstRow; |  410     JSAMPLE* dstRow; | 
 |  411     size_t srcRowBytes = get_row_bytes(fDecoderMgr->dinfo()); | 
|  409     if (fSwizzler) { |  412     if (fSwizzler) { | 
|  410         // write data to storage row, then sample using swizzler |  413         // write data to storage row, then sample using swizzler | 
|  411         dstRow = fSrcRow; |  414         dstRow = fSrcRow; | 
|  412     } else { |  415     } else { | 
|  413         // write data directly to dst |  416         // write data directly to dst | 
 |  417         SkASSERT(count == 1 || dstRowBytes >= srcRowBytes); | 
|  414         dstRow = (JSAMPLE*) dst; |  418         dstRow = (JSAMPLE*) dst; | 
|  415     } |  419     } | 
|  416  |  420  | 
|  417     for (int y = 0; y < count; y++) { |  421     for (int y = 0; y < count; y++) { | 
|  418         // Read row of the image |  422         // Read row of the image | 
|  419         uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow
     , 1); |  423         uint32_t rowsDecoded = jpeg_read_scanlines(fDecoderMgr->dinfo(), &dstRow
     , 1); | 
 |  424         sk_msan_mark_initialized(dstRow, dstRow + srcRowBytes, "skbug.com/4550")
     ; | 
|  420         if (rowsDecoded != 1) { |  425         if (rowsDecoded != 1) { | 
|  421             fDecoderMgr->dinfo()->output_scanline = this->dstInfo().height(); |  426             fDecoderMgr->dinfo()->output_scanline = this->dstInfo().height(); | 
|  422             return y; |  427             return y; | 
|  423         } |  428         } | 
|  424  |  429  | 
|  425         if (fSwizzler) { |  430         if (fSwizzler) { | 
|  426             // use swizzler to sample row |  431             // use swizzler to sample row | 
|  427             fSwizzler->swizzle(dst, dstRow); |  432             fSwizzler->swizzle(dst, dstRow); | 
|  428             dst = SkTAddOffset<JSAMPLE>(dst, rowBytes); |  433             dst = SkTAddOffset<JSAMPLE>(dst, dstRowBytes); | 
|  429         } else { |  434         } else { | 
|  430             dstRow = SkTAddOffset<JSAMPLE>(dstRow, rowBytes); |  435             dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes); | 
|  431         } |  436         } | 
|  432     } |  437     } | 
|  433     return count; |  438     return count; | 
|  434 } |  439 } | 
|  435  |  440  | 
|  436 #ifndef TURBO_HAS_SKIP |  441 #ifndef TURBO_HAS_SKIP | 
|  437 // TODO (msarett): Avoid reallocating the memory buffer on each call to skip. |  442 // TODO (msarett): Avoid reallocating the memory buffer on each call to skip. | 
|  438 static uint32_t jpeg_skip_scanlines(jpeg_decompress_struct* dinfo, int count) { |  443 static uint32_t jpeg_skip_scanlines(jpeg_decompress_struct* dinfo, int count) { | 
|  439     SkAutoTMalloc<uint8_t> storage(get_row_bytes(dinfo)); |  444     SkAutoTMalloc<uint8_t> storage(get_row_bytes(dinfo)); | 
|  440     uint8_t* storagePtr = storage.get(); |  445     uint8_t* storagePtr = storage.get(); | 
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  641  |  646  | 
|  642         JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock); |  647         JDIMENSION linesRead = jpeg_read_raw_data(dinfo, yuv, numRowsPerBlock); | 
|  643         if (linesRead < remainingRows) { |  648         if (linesRead < remainingRows) { | 
|  644             // FIXME: Handle incomplete YUV decodes without signalling an error. |  649             // FIXME: Handle incomplete YUV decodes without signalling an error. | 
|  645             return kInvalidInput; |  650             return kInvalidInput; | 
|  646         } |  651         } | 
|  647     } |  652     } | 
|  648  |  653  | 
|  649     return kSuccess; |  654     return kSuccess; | 
|  650 } |  655 } | 
| OLD | NEW |