OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "core/frame/ImageBitmap.h" | 5 #include "core/frame/ImageBitmap.h" |
6 | 6 |
7 #include "core/html/HTMLCanvasElement.h" | 7 #include "core/html/HTMLCanvasElement.h" |
8 #include "core/html/HTMLVideoElement.h" | 8 #include "core/html/HTMLVideoElement.h" |
9 #include "core/html/ImageData.h" | 9 #include "core/html/ImageData.h" |
10 #include "platform/graphics/skia/SkiaUtils.h" | 10 #include "platform/graphics/skia/SkiaUtils.h" |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 else if (options.resizeQuality() == "medium") | 101 else if (options.resizeQuality() == "medium") |
102 parsedOptions.resizeQuality = kMedium_SkFilterQuality; | 102 parsedOptions.resizeQuality = kMedium_SkFilterQuality; |
103 else if (options.resizeQuality() == "pixelated") | 103 else if (options.resizeQuality() == "pixelated") |
104 parsedOptions.resizeQuality = kNone_SkFilterQuality; | 104 parsedOptions.resizeQuality = kNone_SkFilterQuality; |
105 else | 105 else |
106 parsedOptions.resizeQuality = kLow_SkFilterQuality; | 106 parsedOptions.resizeQuality = kLow_SkFilterQuality; |
107 return parsedOptions; | 107 return parsedOptions; |
108 } | 108 } |
109 | 109 |
110 bool dstBufferSizeHasOverflow(ParsedOptions options) { | 110 bool dstBufferSizeHasOverflow(ParsedOptions options) { |
111 CheckedNumeric<size_t> totalBytes = options.cropRect.width(); | 111 CheckedNumeric<unsigned> totalBytes = options.cropRect.width(); |
112 totalBytes *= options.cropRect.height(); | 112 totalBytes *= options.cropRect.height(); |
113 totalBytes *= options.bytesPerPixel; | 113 totalBytes *= options.bytesPerPixel; |
114 if (!totalBytes.IsValid()) | 114 if (!totalBytes.IsValid()) |
115 return true; | 115 return true; |
116 | 116 |
117 if (!options.shouldScaleInput) | 117 if (!options.shouldScaleInput) |
118 return false; | 118 return false; |
119 totalBytes = options.resizeWidth; | 119 totalBytes = options.resizeWidth; |
120 totalBytes *= options.resizeHeight; | 120 totalBytes *= options.resizeHeight; |
121 totalBytes *= options.bytesPerPixel; | 121 totalBytes *= options.bytesPerPixel; |
122 if (!totalBytes.IsValid()) | 122 if (!totalBytes.IsValid()) |
123 return true; | 123 return true; |
124 | 124 |
125 return false; | 125 return false; |
126 } | 126 } |
127 | 127 |
128 } // namespace | 128 } // namespace |
129 | 129 |
130 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, | 130 static PassRefPtr<Uint8Array> copySkImageData(SkImage* input, |
131 const SkImageInfo& info) { | 131 const SkImageInfo& info) { |
132 // The function dstBufferSizeHasOverflow() is being called at the beginning of | 132 // The function dstBufferSizeHasOverflow() is being called at the beginning of |
133 // each ImageBitmap() constructor, which makes sure that doing | 133 // each ImageBitmap() constructor, which makes sure that doing |
134 // width * height * bytesPerPixel will never overflow size_t. | 134 // width * height * bytesPerPixel will never overflow unsigned. |
135 size_t width = static_cast<size_t>(input->width()); | 135 unsigned width = static_cast<unsigned>(input->width()); |
136 RefPtr<ArrayBuffer> dstBuffer = | 136 RefPtr<ArrayBuffer> dstBuffer = |
137 ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel()); | 137 ArrayBuffer::createOrNull(width * input->height(), info.bytesPerPixel()); |
138 if (!dstBuffer) | 138 if (!dstBuffer) |
139 return nullptr; | 139 return nullptr; |
140 RefPtr<Uint8Array> dstPixels = | 140 RefPtr<Uint8Array> dstPixels = |
141 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 141 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
142 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, | 142 input->readPixels(info, dstPixels->data(), width * info.bytesPerPixel(), 0, |
143 0); | 143 0); |
144 return dstPixels; | 144 return dstPixels; |
145 } | 145 } |
146 | 146 |
147 static sk_sp<SkImage> newSkImageFromRaster(const SkImageInfo& info, | 147 static sk_sp<SkImage> newSkImageFromRaster(const SkImageInfo& info, |
148 PassRefPtr<Uint8Array> imagePixels, | 148 PassRefPtr<Uint8Array> imagePixels, |
149 size_t imageRowBytes) { | 149 unsigned imageRowBytes) { |
150 SkPixmap pixmap(info, imagePixels->data(), imageRowBytes); | 150 SkPixmap pixmap(info, imagePixels->data(), imageRowBytes); |
151 return SkImage::MakeFromRaster(pixmap, | 151 return SkImage::MakeFromRaster(pixmap, |
152 [](const void*, void* pixels) { | 152 [](const void*, void* pixels) { |
153 static_cast<Uint8Array*>(pixels)->deref(); | 153 static_cast<Uint8Array*>(pixels)->deref(); |
154 }, | 154 }, |
155 imagePixels.leakRef()); | 155 imagePixels.leakRef()); |
156 } | 156 } |
157 | 157 |
158 static void swizzleImageData(unsigned char* srcAddr, | 158 static void swizzleImageData(unsigned char* srcAddr, |
159 size_t height, | 159 unsigned height, |
160 size_t bytesPerRow, | 160 unsigned bytesPerRow, |
161 bool flipY) { | 161 bool flipY) { |
162 if (flipY) { | 162 if (flipY) { |
163 for (size_t i = 0; i < height / 2; i++) { | 163 for (unsigned i = 0; i < height / 2; i++) { |
164 size_t topRowStartPosition = i * bytesPerRow; | 164 unsigned topRowStartPosition = i * bytesPerRow; |
165 size_t bottomRowStartPosition = (height - 1 - i) * bytesPerRow; | 165 unsigned bottomRowStartPosition = (height - 1 - i) * bytesPerRow; |
166 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzle | 166 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzle |
167 for (size_t j = 0; j < bytesPerRow; j += 4) { | 167 for (unsigned j = 0; j < bytesPerRow; j += 4) { |
168 std::swap(srcAddr[topRowStartPosition + j], | 168 std::swap(srcAddr[topRowStartPosition + j], |
169 srcAddr[bottomRowStartPosition + j + 2]); | 169 srcAddr[bottomRowStartPosition + j + 2]); |
170 std::swap(srcAddr[topRowStartPosition + j + 1], | 170 std::swap(srcAddr[topRowStartPosition + j + 1], |
171 srcAddr[bottomRowStartPosition + j + 1]); | 171 srcAddr[bottomRowStartPosition + j + 1]); |
172 std::swap(srcAddr[topRowStartPosition + j + 2], | 172 std::swap(srcAddr[topRowStartPosition + j + 2], |
173 srcAddr[bottomRowStartPosition + j]); | 173 srcAddr[bottomRowStartPosition + j]); |
174 std::swap(srcAddr[topRowStartPosition + j + 3], | 174 std::swap(srcAddr[topRowStartPosition + j + 3], |
175 srcAddr[bottomRowStartPosition + j + 3]); | 175 srcAddr[bottomRowStartPosition + j + 3]); |
176 } | 176 } |
177 } else { | 177 } else { |
178 std::swap_ranges(srcAddr + topRowStartPosition, | 178 std::swap_ranges(srcAddr + topRowStartPosition, |
179 srcAddr + topRowStartPosition + bytesPerRow, | 179 srcAddr + topRowStartPosition + bytesPerRow, |
180 srcAddr + bottomRowStartPosition); | 180 srcAddr + bottomRowStartPosition); |
181 } | 181 } |
182 } | 182 } |
183 } else { | 183 } else { |
184 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle | 184 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle |
185 for (size_t i = 0; i < height * bytesPerRow; i += 4) | 185 for (unsigned i = 0; i < height * bytesPerRow; i += 4) |
186 std::swap(srcAddr[i], srcAddr[i + 2]); | 186 std::swap(srcAddr[i], srcAddr[i + 2]); |
187 } | 187 } |
188 } | 188 } |
189 | 189 |
190 static sk_sp<SkImage> flipSkImageVertically(SkImage* input, | 190 static sk_sp<SkImage> flipSkImageVertically(SkImage* input, |
191 AlphaDisposition alphaOp) { | 191 AlphaDisposition alphaOp) { |
192 size_t width = static_cast<size_t>(input->width()); | 192 unsigned width = static_cast<unsigned>(input->width()); |
193 size_t height = static_cast<size_t>(input->height()); | 193 unsigned height = static_cast<unsigned>(input->height()); |
194 SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(), | 194 SkImageInfo info = SkImageInfo::MakeN32(input->width(), input->height(), |
195 (alphaOp == PremultiplyAlpha) | 195 (alphaOp == PremultiplyAlpha) |
196 ? kPremul_SkAlphaType | 196 ? kPremul_SkAlphaType |
197 : kUnpremul_SkAlphaType); | 197 : kUnpremul_SkAlphaType); |
198 size_t imageRowBytes = width * info.bytesPerPixel(); | 198 unsigned imageRowBytes = width * info.bytesPerPixel(); |
199 RefPtr<Uint8Array> imagePixels = copySkImageData(input, info); | 199 RefPtr<Uint8Array> imagePixels = copySkImageData(input, info); |
200 if (!imagePixels) | 200 if (!imagePixels) |
201 return nullptr; | 201 return nullptr; |
202 for (size_t i = 0; i < height / 2; i++) { | 202 for (unsigned i = 0; i < height / 2; i++) { |
203 size_t topFirstElement = i * imageRowBytes; | 203 unsigned topFirstElement = i * imageRowBytes; |
204 size_t topLastElement = (i + 1) * imageRowBytes; | 204 unsigned topLastElement = (i + 1) * imageRowBytes; |
205 size_t bottomFirstElement = (height - 1 - i) * imageRowBytes; | 205 unsigned bottomFirstElement = (height - 1 - i) * imageRowBytes; |
206 std::swap_ranges(imagePixels->data() + topFirstElement, | 206 std::swap_ranges(imagePixels->data() + topFirstElement, |
207 imagePixels->data() + topLastElement, | 207 imagePixels->data() + topLastElement, |
208 imagePixels->data() + bottomFirstElement); | 208 imagePixels->data() + bottomFirstElement); |
209 } | 209 } |
210 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); | 210 return newSkImageFromRaster(info, std::move(imagePixels), imageRowBytes); |
211 } | 211 } |
212 | 212 |
213 static sk_sp<SkImage> premulSkImageToUnPremul(SkImage* input) { | 213 static sk_sp<SkImage> premulSkImageToUnPremul(SkImage* input) { |
214 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), | 214 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), |
215 kN32_SkColorType, kUnpremul_SkAlphaType); | 215 kN32_SkColorType, kUnpremul_SkAlphaType); |
216 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); | 216 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); |
217 if (!dstPixels) | 217 if (!dstPixels) |
218 return nullptr; | 218 return nullptr; |
219 return newSkImageFromRaster( | 219 return newSkImageFromRaster( |
220 info, std::move(dstPixels), | 220 info, std::move(dstPixels), |
221 static_cast<size_t>(input->width()) * info.bytesPerPixel()); | 221 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); |
222 } | 222 } |
223 | 223 |
224 static sk_sp<SkImage> unPremulSkImageToPremul(SkImage* input) { | 224 static sk_sp<SkImage> unPremulSkImageToPremul(SkImage* input) { |
225 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), | 225 SkImageInfo info = SkImageInfo::Make(input->width(), input->height(), |
226 kN32_SkColorType, kPremul_SkAlphaType); | 226 kN32_SkColorType, kPremul_SkAlphaType); |
227 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); | 227 RefPtr<Uint8Array> dstPixels = copySkImageData(input, info); |
228 if (!dstPixels) | 228 if (!dstPixels) |
229 return nullptr; | 229 return nullptr; |
230 return newSkImageFromRaster( | 230 return newSkImageFromRaster( |
231 info, std::move(dstPixels), | 231 info, std::move(dstPixels), |
232 static_cast<size_t>(input->width()) * info.bytesPerPixel()); | 232 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); |
233 } | 233 } |
234 | 234 |
235 sk_sp<SkImage> ImageBitmap::getSkImageFromDecoder( | 235 sk_sp<SkImage> ImageBitmap::getSkImageFromDecoder( |
236 std::unique_ptr<ImageDecoder> decoder) { | 236 std::unique_ptr<ImageDecoder> decoder) { |
237 if (!decoder->frameCount()) | 237 if (!decoder->frameCount()) |
238 return nullptr; | 238 return nullptr; |
239 ImageFrame* frame = decoder->frameBufferAtIndex(0); | 239 ImageFrame* frame = decoder->frameBufferAtIndex(0); |
240 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) | 240 if (!frame || frame->getStatus() != ImageFrame::FrameComplete) |
241 return nullptr; | 241 return nullptr; |
242 DCHECK(!frame->bitmap().isNull() && !frame->bitmap().empty()); | 242 DCHECK(!frame->bitmap().isNull() && !frame->bitmap().empty()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); | 283 const IntRect srcRect = intersection(imgRect, parsedOptions.cropRect); |
284 | 284 |
285 // In the case when cropRect doesn't intersect the source image and it | 285 // In the case when cropRect doesn't intersect the source image and it |
286 // requires a umpremul image We immediately return a transparent black image | 286 // requires a umpremul image We immediately return a transparent black image |
287 // with cropRect.size() | 287 // with cropRect.size() |
288 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { | 288 if (srcRect.isEmpty() && !parsedOptions.premultiplyAlpha) { |
289 SkImageInfo info = | 289 SkImageInfo info = |
290 SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight, | 290 SkImageInfo::Make(parsedOptions.resizeWidth, parsedOptions.resizeHeight, |
291 kN32_SkColorType, kUnpremul_SkAlphaType); | 291 kN32_SkColorType, kUnpremul_SkAlphaType); |
292 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 292 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
293 static_cast<size_t>(info.width()) * info.height(), | 293 static_cast<unsigned>(info.width()) * info.height(), |
294 info.bytesPerPixel()); | 294 info.bytesPerPixel()); |
295 if (!dstBuffer) | 295 if (!dstBuffer) |
296 return nullptr; | 296 return nullptr; |
297 RefPtr<Uint8Array> dstPixels = | 297 RefPtr<Uint8Array> dstPixels = |
298 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 298 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
299 return StaticBitmapImage::create(newSkImageFromRaster( | 299 return StaticBitmapImage::create(newSkImageFromRaster( |
300 info, std::move(dstPixels), | 300 info, std::move(dstPixels), |
301 static_cast<size_t>(info.width()) * info.bytesPerPixel())); | 301 static_cast<unsigned>(info.width()) * info.bytesPerPixel())); |
302 } | 302 } |
303 | 303 |
304 sk_sp<SkImage> skiaImage = image->imageForCurrentFrame(); | 304 sk_sp<SkImage> skiaImage = image->imageForCurrentFrame(); |
305 // Attempt to get raw unpremultiplied image data, executed only when skiaImage | 305 // Attempt to get raw unpremultiplied image data, executed only when skiaImage |
306 // is premultiplied. | 306 // is premultiplied. |
307 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || | 307 if ((((!parsedOptions.premultiplyAlpha && !skiaImage->isOpaque()) || |
308 !skiaImage) && | 308 !skiaImage) && |
309 image->data() && imageFormat == PremultiplyAlpha) || | 309 image->data() && imageFormat == PremultiplyAlpha) || |
310 colorSpaceOp == ImageDecoder::ColorSpaceIgnored) { | 310 colorSpaceOp == ImageDecoder::ColorSpaceIgnored) { |
311 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( | 311 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 SkImageInfo resizedInfo = SkImageInfo::Make( | 517 SkImageInfo resizedInfo = SkImageInfo::Make( |
518 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); | 518 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); |
519 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 519 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
520 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); | 520 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); |
521 if (!dstBuffer) | 521 if (!dstBuffer) |
522 return nullptr; | 522 return nullptr; |
523 RefPtr<Uint8Array> resizedPixels = | 523 RefPtr<Uint8Array> resizedPixels = |
524 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 524 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
525 SkPixmap pixmap( | 525 SkPixmap pixmap( |
526 resizedInfo, resizedPixels->data(), | 526 resizedInfo, resizedPixels->data(), |
527 static_cast<size_t>(resizeWidth) * resizedInfo.bytesPerPixel()); | 527 static_cast<unsigned>(resizeWidth) * resizedInfo.bytesPerPixel()); |
528 skImage->scalePixels(pixmap, resizeQuality); | 528 skImage->scalePixels(pixmap, resizeQuality); |
529 return SkImage::MakeFromRaster(pixmap, | 529 return SkImage::MakeFromRaster(pixmap, |
530 [](const void*, void* pixels) { | 530 [](const void*, void* pixels) { |
531 static_cast<Uint8Array*>(pixels)->deref(); | 531 static_cast<Uint8Array*>(pixels)->deref(); |
532 }, | 532 }, |
533 resizedPixels.release().leakRef()); | 533 resizedPixels.release().leakRef()); |
534 } | 534 } |
535 | 535 |
536 ImageBitmap::ImageBitmap(ImageData* data, | 536 ImageBitmap::ImageBitmap(ImageData* data, |
537 Optional<IntRect> cropRect, | 537 Optional<IntRect> cropRect, |
538 const ImageBitmapOptions& options) { | 538 const ImageBitmapOptions& options) { |
539 // TODO(xidachen): implement the resize option | 539 // TODO(xidachen): implement the resize option |
540 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); | 540 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
541 ParsedOptions parsedOptions = | 541 ParsedOptions parsedOptions = |
542 parseOptions(options, cropRect, data->bitmapSourceSize()); | 542 parseOptions(options, cropRect, data->bitmapSourceSize()); |
543 if (dstBufferSizeHasOverflow(parsedOptions)) | 543 if (dstBufferSizeHasOverflow(parsedOptions)) |
544 return; | 544 return; |
545 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) | 545 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) |
546 : dataSrcRect; | 546 : dataSrcRect; |
547 | 547 |
548 // treat non-premultiplyAlpha as a special case | 548 // treat non-premultiplyAlpha as a special case |
549 if (!parsedOptions.premultiplyAlpha) { | 549 if (!parsedOptions.premultiplyAlpha) { |
550 unsigned char* srcAddr = data->data()->data(); | 550 unsigned char* srcAddr = data->data()->data(); |
551 | 551 |
552 // Using kN32 type, swizzle input if necessary. | 552 // Using kN32 type, swizzle input if necessary. |
553 SkImageInfo info = SkImageInfo::Make( | 553 SkImageInfo info = SkImageInfo::Make( |
554 parsedOptions.cropRect.width(), parsedOptions.cropRect.height(), | 554 parsedOptions.cropRect.width(), parsedOptions.cropRect.height(), |
555 kN32_SkColorType, kUnpremul_SkAlphaType); | 555 kN32_SkColorType, kUnpremul_SkAlphaType); |
556 size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel()); | 556 unsigned bytesPerPixel = static_cast<unsigned>(info.bytesPerPixel()); |
557 size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width(); | 557 unsigned srcPixelBytesPerRow = bytesPerPixel * data->size().width(); |
558 size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.width(); | 558 unsigned dstPixelBytesPerRow = |
| 559 bytesPerPixel * parsedOptions.cropRect.width(); |
559 sk_sp<SkImage> skImage; | 560 sk_sp<SkImage> skImage; |
560 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { | 561 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
561 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, | 562 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, |
562 parsedOptions.flipY); | 563 parsedOptions.flipY); |
563 skImage = | 564 skImage = |
564 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); | 565 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); |
565 // restore the original ImageData | 566 // restore the original ImageData |
566 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, | 567 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, |
567 parsedOptions.flipY); | 568 parsedOptions.flipY); |
568 } else { | 569 } else { |
569 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 570 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
570 static_cast<size_t>(parsedOptions.cropRect.height()) * | 571 static_cast<unsigned>(parsedOptions.cropRect.height()) * |
571 parsedOptions.cropRect.width(), | 572 parsedOptions.cropRect.width(), |
572 bytesPerPixel); | 573 bytesPerPixel); |
573 if (!dstBuffer) | 574 if (!dstBuffer) |
574 return; | 575 return; |
575 RefPtr<Uint8Array> copiedDataBuffer = | 576 RefPtr<Uint8Array> copiedDataBuffer = |
576 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 577 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
577 if (!srcRect.isEmpty()) { | 578 if (!srcRect.isEmpty()) { |
578 IntPoint srcPoint = IntPoint( | 579 IntPoint srcPoint = IntPoint( |
579 (parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, | 580 (parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, |
580 (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0); | 581 (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0); |
581 IntPoint dstPoint = IntPoint( | 582 IntPoint dstPoint = IntPoint( |
582 (parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), | 583 (parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), |
583 (parsedOptions.cropRect.y() >= 0) ? 0 | 584 (parsedOptions.cropRect.y() >= 0) ? 0 |
584 : -parsedOptions.cropRect.y()); | 585 : -parsedOptions.cropRect.y()); |
585 int copyHeight = data->size().height() - srcPoint.y(); | 586 int copyHeight = data->size().height() - srcPoint.y(); |
586 if (parsedOptions.cropRect.height() < copyHeight) | 587 if (parsedOptions.cropRect.height() < copyHeight) |
587 copyHeight = parsedOptions.cropRect.height(); | 588 copyHeight = parsedOptions.cropRect.height(); |
588 int copyWidth = data->size().width() - srcPoint.x(); | 589 int copyWidth = data->size().width() - srcPoint.x(); |
589 if (parsedOptions.cropRect.width() < copyWidth) | 590 if (parsedOptions.cropRect.width() < copyWidth) |
590 copyWidth = parsedOptions.cropRect.width(); | 591 copyWidth = parsedOptions.cropRect.width(); |
591 for (int i = 0; i < copyHeight; i++) { | 592 for (int i = 0; i < copyHeight; i++) { |
592 size_t srcStartCopyPosition = | 593 unsigned srcStartCopyPosition = |
593 (i + srcPoint.y()) * srcPixelBytesPerRow + | 594 (i + srcPoint.y()) * srcPixelBytesPerRow + |
594 srcPoint.x() * bytesPerPixel; | 595 srcPoint.x() * bytesPerPixel; |
595 size_t srcEndCopyPosition = | 596 unsigned srcEndCopyPosition = |
596 srcStartCopyPosition + copyWidth * bytesPerPixel; | 597 srcStartCopyPosition + copyWidth * bytesPerPixel; |
597 size_t dstStartCopyPosition; | 598 unsigned dstStartCopyPosition; |
598 if (parsedOptions.flipY) | 599 if (parsedOptions.flipY) |
599 dstStartCopyPosition = | 600 dstStartCopyPosition = |
600 (parsedOptions.cropRect.height() - 1 - dstPoint.y() - i) * | 601 (parsedOptions.cropRect.height() - 1 - dstPoint.y() - i) * |
601 dstPixelBytesPerRow + | 602 dstPixelBytesPerRow + |
602 dstPoint.x() * bytesPerPixel; | 603 dstPoint.x() * bytesPerPixel; |
603 else | 604 else |
604 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + | 605 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + |
605 dstPoint.x() * bytesPerPixel; | 606 dstPoint.x() * bytesPerPixel; |
606 for (size_t j = 0; j < srcEndCopyPosition - srcStartCopyPosition; | 607 for (unsigned j = 0; j < srcEndCopyPosition - srcStartCopyPosition; |
607 j++) { | 608 j++) { |
608 // swizzle when necessary | 609 // swizzle when necessary |
609 if (kN32_SkColorType == kBGRA_8888_SkColorType) { | 610 if (kN32_SkColorType == kBGRA_8888_SkColorType) { |
610 if (j % 4 == 0) | 611 if (j % 4 == 0) |
611 copiedDataBuffer->data()[dstStartCopyPosition + j] = | 612 copiedDataBuffer->data()[dstStartCopyPosition + j] = |
612 srcAddr[srcStartCopyPosition + j + 2]; | 613 srcAddr[srcStartCopyPosition + j + 2]; |
613 else if (j % 4 == 2) | 614 else if (j % 4 == 2) |
614 copiedDataBuffer->data()[dstStartCopyPosition + j] = | 615 copiedDataBuffer->data()[dstStartCopyPosition + j] = |
615 srcAddr[srcStartCopyPosition + j - 2]; | 616 srcAddr[srcStartCopyPosition + j - 2]; |
616 else | 617 else |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, | 858 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, |
858 FloatRect* dstRect) const {} | 859 FloatRect* dstRect) const {} |
859 | 860 |
860 FloatSize ImageBitmap::elementSize(const FloatSize&) const { | 861 FloatSize ImageBitmap::elementSize(const FloatSize&) const { |
861 return FloatSize(width(), height()); | 862 return FloatSize(width(), height()); |
862 } | 863 } |
863 | 864 |
864 DEFINE_TRACE(ImageBitmap) {} | 865 DEFINE_TRACE(ImageBitmap) {} |
865 | 866 |
866 } // namespace blink | 867 } // namespace blink |
OLD | NEW |