Chromium Code Reviews| 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 "SkBmpCodec.h" | 8 #include "SkBmpCodec.h" |
| 9 #include "SkCodec.h" | 9 #include "SkCodec.h" |
| 10 #include "SkData.h" | 10 #include "SkData.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 // startScanlineDecode will need to be called before decoding scanlines. | 104 // startScanlineDecode will need to be called before decoding scanlines. |
| 105 fCurrScanline = -1; | 105 fCurrScanline = -1; |
| 106 | 106 |
| 107 if (!fStream->rewind()) { | 107 if (!fStream->rewind()) { |
| 108 return false; | 108 return false; |
| 109 } | 109 } |
| 110 | 110 |
| 111 return this->onRewind(); | 111 return this->onRewind(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 bool SkCodec::getScaledSubsetDimensions(float desiredScale, const Options& optio ns) const { | |
| 115 // Negative and zero scales are errors. | |
| 116 SkASSERT(desiredScale > 0.0f); | |
| 117 if (desiredScale <= 0.0f) { | |
| 118 return false; | |
| 119 } | |
| 120 | |
| 121 // Upscaling is not supported. We will suggest a full decode if | |
| 122 // upscaling is requested. | |
| 123 if (desiredScale >= 1.0f) { | |
| 124 desiredScale = 1.0f; | |
| 125 } | |
| 126 | |
| 127 // If the client is not requesting a subset decode, | |
| 128 // getScaledDimensions() should be used. | |
| 129 if (!options.fSubset || !options.fScaledDimensions || !options.fScaledSubset ) { | |
| 130 return false; | |
| 131 } | |
| 132 | |
| 133 if (!is_valid_subset(*options.fSubset, this->getInfo().dimensions())) { | |
| 134 return false; | |
| 135 } | |
| 136 | |
| 137 return this->onGetScaledSubsetDimensions(desiredScale, options); | |
| 138 } | |
| 139 | |
| 140 bool SkCodec::subsetSupported(const SkIRect& subset, bool isScanlineDecode) { | |
| 141 if (!is_valid_subset(subset, this->getInfo().dimensions())) { | |
|
scroggo
2015/10/12 20:47:07
nit: fInfo.dimensions()
No need to call the acces
| |
| 142 return false; | |
| 143 } | |
| 144 | |
| 145 return this->onSubsetSupported(subset, isScanlineDecode); | |
| 146 } | |
| 147 | |
| 148 bool SkCodec::onSubsetSupported(const SkIRect& subset, bool isScanlineDecode) { | |
| 149 if (!isScanlineDecode) { | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 // We support subsetting in the x-dimension for the scanline decoder. | |
| 154 // Subsetting in the y-dimension can be accomplished using skipScanlines(). | |
| 155 return subset.top() == 0 && subset.height() == this->getInfo().height(); | |
| 156 } | |
| 157 | |
| 158 bool SkCodec::scaledSubsetSupported(const SkISize& dstSize, const Options& optio ns, | |
| 159 bool isScanlineDecode) { | |
| 160 SkIRect* subset = options.fSubset; | |
| 161 | |
| 162 // If there is no subsetting, we simply check if we can scale to dstSize | |
| 163 if (!subset) { | |
| 164 return this->dimensionsSupported(dstSize); | |
| 165 } | |
| 166 | |
| 167 SkISize* scaledDimensions = options.fScaledDimensions; | |
| 168 SkIRect* scaledSubset = options.fScaledSubset; | |
| 169 if (!scaledDimensions && !scaledSubset) { | |
| 170 // If there is no scaling, check if we support the subset requested | |
| 171 return this->subsetSupported(*subset, isScanlineDecode); | |
| 172 } | |
| 173 | |
| 174 if (!scaledDimensions || !scaledSubset) { | |
| 175 // Both scaledDimensions and scaledSubset must be non-NULL to perform | |
| 176 // a scaled subset decode. | |
| 177 return false; | |
| 178 } | |
| 179 | |
| 180 if (!is_valid_subset(*scaledSubset, *scaledDimensions)) { | |
| 181 return false; | |
| 182 } | |
| 183 | |
| 184 return this->onScaledSubsetSupported(options, isScanlineDecode); | |
| 185 } | |
| 186 | |
| 187 bool SkCodec::onScaledSubsetSupported(const Options& options, bool isScanlineDec ode) { | |
| 188 if (!isScanlineDecode) { | |
| 189 return false; | |
| 190 } | |
| 191 | |
| 192 if (!this->dimensionsSupported(*options.fScaledDimensions)) { | |
| 193 return false; | |
| 194 } | |
| 195 | |
| 196 // We support subsetting in the x-dimension for the scanline decoder. | |
| 197 // Subsetting in the y-dimension can be accomplished using skipScanlines(). | |
| 198 return options.fSubset->top() == 0 && | |
| 199 options.fSubset->height() == options.fScaledDimensions->height(); | |
| 200 } | |
| 201 | |
| 114 SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, | 202 SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, |
| 115 const Options* options, SkPMColor ctable[], i nt* ctableCount) { | 203 const Options* options, SkPMColor ctable[], i nt* ctableCount) { |
| 116 if (kUnknown_SkColorType == info.colorType()) { | 204 if (kUnknown_SkColorType == info.colorType()) { |
| 117 return kInvalidConversion; | 205 return kInvalidConversion; |
| 118 } | 206 } |
| 119 if (nullptr == pixels) { | 207 if (nullptr == pixels) { |
| 120 return kInvalidParameters; | 208 return kInvalidParameters; |
| 121 } | 209 } |
| 122 if (rowBytes < info.minRowBytes()) { | 210 if (rowBytes < info.minRowBytes()) { |
| 123 return kInvalidParameters; | 211 return kInvalidParameters; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 145 } | 233 } |
| 146 | 234 |
| 147 if (!this->rewindIfNeeded()) { | 235 if (!this->rewindIfNeeded()) { |
| 148 return kCouldNotRewind; | 236 return kCouldNotRewind; |
| 149 } | 237 } |
| 150 | 238 |
| 151 // Default options. | 239 // Default options. |
| 152 Options optsStorage; | 240 Options optsStorage; |
| 153 if (nullptr == options) { | 241 if (nullptr == options) { |
| 154 options = &optsStorage; | 242 options = &optsStorage; |
| 155 } else if (options->fSubset) { | |
| 156 SkIRect subset(*options->fSubset); | |
| 157 if (!this->onGetValidSubset(&subset) || subset != *options->fSubset) { | |
| 158 // FIXME: How to differentiate between not supporting subset at all | |
| 159 // and not supporting this particular subset? | |
| 160 return kUnimplemented; | |
| 161 } | |
| 162 } | 243 } |
| 163 | 244 |
| 164 // FIXME: Support subsets somehow? Note that this works for SkWebpCodec | 245 if (!this->scaledSubsetSupported(info.dimensions(), *options, false)) { |
| 165 // because it supports arbitrary scaling/subset combinations. | |
| 166 if (!this->dimensionsSupported(info.dimensions())) { | |
| 167 return kInvalidScale; | 246 return kInvalidScale; |
| 168 } | 247 } |
| 169 | 248 |
| 170 // On an incomplete decode, the subclass will specify the number of scanline s that it decoded | 249 // On an incomplete decode, the subclass will specify the number of scanline s that it decoded |
| 171 // successfully. | 250 // successfully. |
| 172 int rowsDecoded = 0; | 251 int rowsDecoded = 0; |
| 173 const Result result = this->onGetPixels(info, pixels, rowBytes, *options, ct able, ctableCount, | 252 const Result result = this->onGetPixels(info, pixels, rowBytes, *options, ct able, ctableCount, |
| 174 &rowsDecoded); | 253 &rowsDecoded); |
| 175 | 254 |
| 176 if ((kIncompleteInput == result || kSuccess == result) && ctableCount) { | 255 if ((kIncompleteInput == result || kSuccess == result) && ctableCount) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 } | 291 } |
| 213 | 292 |
| 214 if (!this->rewindIfNeeded()) { | 293 if (!this->rewindIfNeeded()) { |
| 215 return kCouldNotRewind; | 294 return kCouldNotRewind; |
| 216 } | 295 } |
| 217 | 296 |
| 218 // Set options. | 297 // Set options. |
| 219 Options optsStorage; | 298 Options optsStorage; |
| 220 if (nullptr == options) { | 299 if (nullptr == options) { |
| 221 options = &optsStorage; | 300 options = &optsStorage; |
| 222 } else if (options->fSubset) { | |
| 223 SkIRect size = SkIRect::MakeSize(dstInfo.dimensions()); | |
| 224 if (!size.contains(*options->fSubset)) { | |
| 225 return kInvalidInput; | |
| 226 } | |
| 227 | |
| 228 // We only support subsetting in the x-dimension for scanline decoder. | |
| 229 // Subsetting in the y-dimension can be accomplished using skipScanlines (). | |
| 230 if (options->fSubset->top() != 0 || options->fSubset->height() != dstInf o.height()) { | |
| 231 return kInvalidInput; | |
| 232 } | |
| 233 } | 301 } |
| 234 | 302 |
| 235 // FIXME: Support subsets somehow? | 303 if (!this->scaledSubsetSupported(dstInfo.dimensions(), *options, true)) { |
| 236 if (!this->dimensionsSupported(dstInfo.dimensions())) { | |
| 237 return kInvalidScale; | 304 return kInvalidScale; |
| 238 } | 305 } |
| 239 | 306 |
| 240 const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable, ctableCount); | 307 const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable, ctableCount); |
| 241 if (result != SkCodec::kSuccess) { | 308 if (result != SkCodec::kSuccess) { |
| 242 return result; | 309 return result; |
| 243 } | 310 } |
| 244 | 311 |
| 245 fCurrScanline = 0; | 312 fCurrScanline = 0; |
| 246 fDstInfo = dstInfo; | 313 fDstInfo = dstInfo; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 343 SkASSERT(1 == linesRequested || this->getInfo().height() == linesReq uested); | 410 SkASSERT(1 == linesRequested || this->getInfo().height() == linesReq uested); |
| 344 const SkImageInfo fillInfo = info.makeWH(info.width(), 1); | 411 const SkImageInfo fillInfo = info.makeWH(info.width(), 1); |
| 345 for (int srcY = linesDecoded; srcY < linesRequested; srcY++) { | 412 for (int srcY = linesDecoded; srcY < linesRequested; srcY++) { |
| 346 fillDst = SkTAddOffset<void>(dst, this->outputScanline(srcY) * r owBytes); | 413 fillDst = SkTAddOffset<void>(dst, this->outputScanline(srcY) * r owBytes); |
| 347 fill_proc(fillInfo, fillDst, rowBytes, fillValue, zeroInit, samp ler); | 414 fill_proc(fillInfo, fillDst, rowBytes, fillValue, zeroInit, samp ler); |
| 348 } | 415 } |
| 349 break; | 416 break; |
| 350 } | 417 } |
| 351 } | 418 } |
| 352 } | 419 } |
| OLD | NEW |