| 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 "SkCodecPriv.h" | 8 #include "SkCodecPriv.h" | 
| 9 #include "SkScaledCodec.h" | 9 #include "SkScaledCodec.h" | 
| 10 #include "SkStream.h" | 10 #include "SkStream.h" | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 37     return NewFromStream(new SkMemoryStream(data)); | 37     return NewFromStream(new SkMemoryStream(data)); | 
| 38 } | 38 } | 
| 39 | 39 | 
| 40 SkScaledCodec::SkScaledCodec(SkScanlineDecoder* scanlineDecoder) | 40 SkScaledCodec::SkScaledCodec(SkScanlineDecoder* scanlineDecoder) | 
| 41     : INHERITED(scanlineDecoder->getInfo(), nullptr) | 41     : INHERITED(scanlineDecoder->getInfo(), nullptr) | 
| 42     , fScanlineDecoder(scanlineDecoder) | 42     , fScanlineDecoder(scanlineDecoder) | 
| 43 {} | 43 {} | 
| 44 | 44 | 
| 45 SkScaledCodec::~SkScaledCodec() {} | 45 SkScaledCodec::~SkScaledCodec() {} | 
| 46 | 46 | 
|  | 47 // returns a scaled dimension based on the original dimension and the sampleSize | 
|  | 48 // NOTE: we round down here for scaled dimension to match the behavior of SkImag
     eDecoder | 
|  | 49 static int get_scaled_dimension(int srcDimension, int sampleSize) { | 
|  | 50     if (sampleSize > srcDimension) { | 
|  | 51         return 1; | 
|  | 52     } | 
|  | 53     return srcDimension / sampleSize; | 
|  | 54 } | 
|  | 55 | 
| 47 static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& na
     tiveDims, | 56 static SkISize best_scaled_dimensions(const SkISize& origDims, const SkISize& na
     tiveDims, | 
| 48                                       const SkISize& scaledCodecDims, float desi
     redScale) { | 57                                       const SkISize& scaledCodecDims, float desi
     redScale) { | 
| 49     if (nativeDims == scaledCodecDims) { | 58     if (nativeDims == scaledCodecDims) { | 
| 50         // does not matter which to return if equal. Return here to skip below c
     alculations | 59         // does not matter which to return if equal. Return here to skip below c
     alculations | 
| 51         return nativeDims; | 60         return nativeDims; | 
| 52     } | 61     } | 
| 53     float idealWidth = origDims.width() * desiredScale; | 62     float idealWidth = origDims.width() * desiredScale; | 
| 54     float idealHeight = origDims.height() * desiredScale; | 63     float idealHeight = origDims.height() * desiredScale; | 
| 55 | 64 | 
| 56     // calculate difference between native dimensions and ideal dimensions | 65     // calculate difference between native dimensions and ideal dimensions | 
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 181                                            SkPMColor ctable[], int* ctableCount)
      { | 190                                            SkPMColor ctable[], int* ctableCount)
      { | 
| 182 | 191 | 
| 183     if (options.fSubset) { | 192     if (options.fSubset) { | 
| 184         // Subsets are not supported. | 193         // Subsets are not supported. | 
| 185         return kUnimplemented; | 194         return kUnimplemented; | 
| 186     } | 195     } | 
| 187 | 196 | 
| 188     Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, cta
     bleCount); | 197     Result result = fScanlineDecoder->start(requestedInfo, &options, ctable, cta
     bleCount); | 
| 189     if (kSuccess == result) { | 198     if (kSuccess == result) { | 
| 190         // native decode supported | 199         // native decode supported | 
| 191         switch (fScanlineDecoder->getScanlineOrder()) { | 200         return fScanlineDecoder->getScanlines(dst, requestedInfo.height(), rowBy
     tes); | 
| 192             case SkScanlineDecoder::kTopDown_SkScanlineOrder: |  | 
| 193             case SkScanlineDecoder::kBottomUp_SkScanlineOrder: |  | 
| 194             case SkScanlineDecoder::kNone_SkScanlineOrder: |  | 
| 195                 return fScanlineDecoder->getScanlines(dst, requestedInfo.height(
     ), rowBytes); |  | 
| 196             case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { |  | 
| 197                 for (int y = 0; y < requestedInfo.height(); y++) { |  | 
| 198                     int dstY = fScanlineDecoder->getY(); |  | 
| 199                     void* dstPtr = SkTAddOffset<void>(dst, rowBytes * dstY); |  | 
| 200                     result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes)
     ; |  | 
| 201                     // FIXME (msarett): Make the SkCodec base class take care of
      filling |  | 
| 202                     // uninitialized pixels so we can return immediately on kInc
     ompleteInput. |  | 
| 203                     if (kSuccess != result && kIncompleteInput != result) { |  | 
| 204                         return result; |  | 
| 205                     } |  | 
| 206                 } |  | 
| 207                 return result; |  | 
| 208             } |  | 
| 209         } |  | 
| 210     } | 201     } | 
| 211 | 202 | 
| 212     if (kInvalidScale != result) { | 203     if (kInvalidScale != result) { | 
| 213         // no scaling requested | 204         // no scaling requested | 
| 214         return result; | 205         return result; | 
| 215     } | 206     } | 
| 216 | 207 | 
| 217     // scaling requested | 208     // scaling requested | 
| 218     int sampleX; | 209     int sampleX; | 
| 219     int sampleY; | 210     int sampleY; | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 248                     return result; | 239                     return result; | 
| 249                 } | 240                 } | 
| 250                 if (y < dstHeight - 1) { | 241                 if (y < dstHeight - 1) { | 
| 251                     result = fScanlineDecoder->skipScanlines(sampleY - 1); | 242                     result = fScanlineDecoder->skipScanlines(sampleY - 1); | 
| 252                     if (kSuccess != result && kIncompleteInput != result) { | 243                     if (kSuccess != result && kIncompleteInput != result) { | 
| 253                         return result; | 244                         return result; | 
| 254                     } | 245                     } | 
| 255                 } | 246                 } | 
| 256                 dst = SkTAddOffset<void>(dst, rowBytes); | 247                 dst = SkTAddOffset<void>(dst, rowBytes); | 
| 257             } | 248             } | 
| 258             return result; | 249             return kSuccess; | 
| 259         } | 250         } | 
| 260         case SkScanlineDecoder::kBottomUp_SkScanlineOrder: | 251         case SkScanlineDecoder::kBottomUp_SkScanlineOrder: | 
| 261         case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { | 252         case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { | 
| 262             for (int y = 0; y < srcHeight; y++) { | 253             for (int y = 0; y < srcHeight; y++) { | 
| 263                 int srcY = fScanlineDecoder->getY(); | 254                 int srcY = fScanlineDecoder->getY(); | 
| 264                 if (is_coord_necessary(srcY, sampleY, dstHeight)) { | 255                 if (is_coord_necessary(srcY, sampleY, dstHeight)) { | 
| 265                     void* dstPtr = SkTAddOffset<void>(dst, rowBytes * get_dst_co
     ord(srcY, sampleY)); | 256                     void* dstPtr = SkTAddOffset<void>(dst, rowBytes * get_dst_co
     ord(srcY, sampleY)); | 
| 266                     result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes)
     ; | 257                     result = fScanlineDecoder->getScanlines(dstPtr, 1, rowBytes)
     ; | 
| 267                     if (kSuccess != result && kIncompleteInput != result) { | 258                     if (kSuccess != result && kIncompleteInput != result) { | 
| 268                         return result; | 259                         return result; | 
| 269                     } | 260                     } | 
| 270                 } else { | 261                 } else { | 
| 271                     result = fScanlineDecoder->skipScanlines(1); | 262                     result = fScanlineDecoder->skipScanlines(1); | 
| 272                     if (kSuccess != result && kIncompleteInput != result) { | 263                     if (kSuccess != result && kIncompleteInput != result) { | 
| 273                         return result; | 264                         return result; | 
| 274                     } | 265                     } | 
| 275                 } | 266                 } | 
| 276             } | 267             } | 
| 277             return result; | 268             return kSuccess; | 
| 278         } | 269         } | 
| 279         case SkScanlineDecoder::kNone_SkScanlineOrder: { | 270         case SkScanlineDecoder::kNone_SkScanlineOrder: { | 
| 280             SkAutoMalloc storage(srcHeight * rowBytes); | 271             SkAutoMalloc storage(srcHeight * rowBytes); | 
| 281             uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); | 272             uint8_t* storagePtr = static_cast<uint8_t*>(storage.get()); | 
| 282             result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBy
     tes); | 273             result = fScanlineDecoder->getScanlines(storagePtr, srcHeight, rowBy
     tes); | 
| 283             if (kSuccess != result && kIncompleteInput != result) { | 274             if (kSuccess != result) { | 
| 284                 return result; | 275                 return result; | 
| 285             } | 276             } | 
| 286             storagePtr += Y0 * rowBytes; | 277             storagePtr += Y0 * rowBytes; | 
| 287             for (int y = 0; y < dstHeight; y++) { | 278             for (int y = 0; y < dstHeight; y++) { | 
| 288                 memcpy(dst, storagePtr, rowBytes); | 279                 memcpy(dst, storagePtr, rowBytes); | 
| 289                 storagePtr += sampleY * rowBytes; | 280                 storagePtr += sampleY * rowBytes; | 
| 290                 dst = SkTAddOffset<void>(dst, rowBytes); | 281                 dst = SkTAddOffset<void>(dst, rowBytes); | 
| 291             } | 282             } | 
| 292             return result; | 283             return kSuccess; | 
| 293         } | 284         } | 
| 294         default: | 285         default: | 
| 295             SkASSERT(false); | 286             SkASSERT(false); | 
| 296             return kUnimplemented; | 287             return kUnimplemented; | 
| 297     } | 288     } | 
| 298 } | 289 } | 
| OLD | NEW | 
|---|