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 SkISize SkCodec::getScaledDimensions(float desiredScale) const { |
| 115 // Negative and zero scales are errors. |
| 116 SkASSERT(desiredScale > 0.0f); |
| 117 if (desiredScale <= 0.0f) { |
| 118 return SkISize::Make(0, 0); |
| 119 } |
| 120 |
| 121 // Upscaling is not supported. Return the original size if the client |
| 122 // requests an upscale. |
| 123 if (desiredScale >= 1.0f) { |
| 124 return this->getInfo().dimensions(); |
| 125 } |
| 126 return this->onGetScaledDimensions(desiredScale); |
| 127 } |
| 128 |
| 129 bool SkCodec::getValidSubset(SkIRect* desiredSubset) const { |
| 130 if (!desiredSubset) { |
| 131 return false; |
| 132 } |
| 133 |
| 134 if (!is_valid_subset(desiredSubset, this->getInfo().dimensions())) { |
| 135 return false; |
| 136 } |
| 137 |
| 138 return this->onGetValidSubset(desiredSubset); |
| 139 } |
| 140 |
| 141 bool SkCodec::getScaledSubsetDimensions(float desiredScale, Options* options) co
nst { |
| 142 // Negative and zero scales are errors. |
| 143 SkASSERT(desiredScale > 0.0f); |
| 144 if (desiredScale <= 0.0f) { |
| 145 return false; |
| 146 } |
| 147 |
| 148 // Upscaling is not supported. We will suggest a full decode if |
| 149 // upscaling is requested. |
| 150 if (desiredScale >= 1.0f) { |
| 151 desiredScale = 1.0f; |
| 152 } |
| 153 |
| 154 // If the client is not requesting a subset decode, |
| 155 // getScaledDimensions() should be used. |
| 156 if (nullptr == options->fSubset) { |
| 157 return false; |
| 158 } |
| 159 |
| 160 if (!is_valid_subset(options->fSubset, this->getInfo().dimensions())) { |
| 161 return false; |
| 162 } |
| 163 |
| 164 return this->onGetScaledSubsetDimensions(desiredScale, options); |
| 165 } |
| 166 |
114 SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
rowBytes, | 167 SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
rowBytes, |
115 const Options* options, SkPMColor ctable[], i
nt* ctableCount) { | 168 const Options* options, SkPMColor ctable[], i
nt* ctableCount) { |
116 if (kUnknown_SkColorType == info.colorType()) { | 169 if (kUnknown_SkColorType == info.colorType()) { |
117 return kInvalidConversion; | 170 return kInvalidConversion; |
118 } | 171 } |
119 if (nullptr == pixels) { | 172 if (nullptr == pixels) { |
120 return kInvalidParameters; | 173 return kInvalidParameters; |
121 } | 174 } |
122 if (rowBytes < info.minRowBytes()) { | 175 if (rowBytes < info.minRowBytes()) { |
123 return kInvalidParameters; | 176 return kInvalidParameters; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 } | 241 } |
189 | 242 |
190 return result; | 243 return result; |
191 } | 244 } |
192 | 245 |
193 SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
rowBytes) { | 246 SkCodec::Result SkCodec::getPixels(const SkImageInfo& info, void* pixels, size_t
rowBytes) { |
194 return this->getPixels(info, pixels, rowBytes, nullptr, nullptr, nullptr); | 247 return this->getPixels(info, pixels, rowBytes, nullptr, nullptr, nullptr); |
195 } | 248 } |
196 | 249 |
197 SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo, | 250 SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo, |
198 const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) { | 251 const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount, i
nt subsetLeft, |
| 252 int subsetWidth) { |
199 // Reset fCurrScanline in case of failure. | 253 // Reset fCurrScanline in case of failure. |
200 fCurrScanline = -1; | 254 fCurrScanline = -1; |
| 255 |
| 256 // Ensure that the subset parameters are valid |
| 257 if (0 > subsetLeft || subsetLeft >= dstInfo.width() || 0 > subsetWidth || |
| 258 subsetLeft + subsetWidth > dstInfo.width()) { |
| 259 return kInvalidParameters; |
| 260 } |
| 261 |
201 // Ensure that valid color ptrs are passed in for kIndex8 color type | 262 // Ensure that valid color ptrs are passed in for kIndex8 color type |
202 if (kIndex_8_SkColorType == dstInfo.colorType()) { | 263 if (kIndex_8_SkColorType == dstInfo.colorType()) { |
203 if (nullptr == ctable || nullptr == ctableCount) { | 264 if (nullptr == ctable || nullptr == ctableCount) { |
204 return SkCodec::kInvalidParameters; | 265 return SkCodec::kInvalidParameters; |
205 } | 266 } |
206 } else { | 267 } else { |
207 if (ctableCount) { | 268 if (ctableCount) { |
208 *ctableCount = 0; | 269 *ctableCount = 0; |
209 } | 270 } |
210 ctableCount = nullptr; | 271 ctableCount = nullptr; |
(...skipping 15 matching lines...) Expand all Loading... |
226 // and not supporting this particular subset? | 287 // and not supporting this particular subset? |
227 return kUnimplemented; | 288 return kUnimplemented; |
228 } | 289 } |
229 } | 290 } |
230 | 291 |
231 // FIXME: Support subsets somehow? | 292 // FIXME: Support subsets somehow? |
232 if (!this->dimensionsSupported(dstInfo.dimensions())) { | 293 if (!this->dimensionsSupported(dstInfo.dimensions())) { |
233 return kInvalidScale; | 294 return kInvalidScale; |
234 } | 295 } |
235 | 296 |
236 const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable,
ctableCount); | 297 const Result result = this->onStartScanlineDecode(dstInfo, *options, ctable,
ctableCount, |
| 298 subsetLeft, subsetWidth); |
237 if (result != SkCodec::kSuccess) { | 299 if (result != SkCodec::kSuccess) { |
238 return result; | 300 return result; |
239 } | 301 } |
240 | 302 |
241 fCurrScanline = 0; | 303 fCurrScanline = 0; |
242 fDstInfo = dstInfo; | 304 fDstInfo = dstInfo; |
243 fOptions = *options; | 305 fOptions = *options; |
244 return kSuccess; | 306 return kSuccess; |
245 } | 307 } |
246 | 308 |
| 309 SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo, |
| 310 const SkCodec::Options* options, SkPMColor ctable[], int* ctableCount) { |
| 311 return this->startScanlineDecode(dstInfo, options, ctable, ctableCount, 0, d
stInfo.width()); |
| 312 } |
| 313 |
247 SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo) { | 314 SkCodec::Result SkCodec::startScanlineDecode(const SkImageInfo& dstInfo) { |
248 return this->startScanlineDecode(dstInfo, nullptr, nullptr, nullptr); | 315 return this->startScanlineDecode(dstInfo, nullptr, nullptr, nullptr, 0, dstI
nfo.width()); |
249 } | 316 } |
250 | 317 |
251 int SkCodec::getScanlines(void* dst, int countLines, size_t rowBytes) { | 318 int SkCodec::getScanlines(void* dst, int countLines, size_t rowBytes) { |
252 if (fCurrScanline < 0) { | 319 if (fCurrScanline < 0) { |
253 return 0; | 320 return 0; |
254 } | 321 } |
255 | 322 |
256 SkASSERT(!fDstInfo.isEmpty()); | 323 SkASSERT(!fDstInfo.isEmpty()); |
257 if (countLines <= 0 || fCurrScanline + countLines > fDstInfo.height()) { | 324 if (countLines <= 0 || fCurrScanline + countLines > fDstInfo.height()) { |
258 return 0; | 325 return 0; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 break; | 400 break; |
334 case kOutOfOrder_SkScanlineOrder: | 401 case kOutOfOrder_SkScanlineOrder: |
335 SkASSERT(1 == linesRequested || this->getInfo().height() == linesReq
uested); | 402 SkASSERT(1 == linesRequested || this->getInfo().height() == linesReq
uested); |
336 for (int srcY = linesDecoded; srcY < linesRequested; srcY++) { | 403 for (int srcY = linesDecoded; srcY < linesRequested; srcY++) { |
337 fillDst = SkTAddOffset<void>(dst, this->outputScanline(srcY) * r
owBytes); | 404 fillDst = SkTAddOffset<void>(dst, this->outputScanline(srcY) * r
owBytes); |
338 SkSampler::Fill(fillDst, colorType, width, 1, rowBytes, fillValu
e, zeroInit); | 405 SkSampler::Fill(fillDst, colorType, width, 1, rowBytes, fillValu
e, zeroInit); |
339 } | 406 } |
340 break; | 407 break; |
341 } | 408 } |
342 } | 409 } |
OLD | NEW |