| 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::GammaAndColorProfileIgnored) { | 310 colorSpaceOp == ImageDecoder::GammaAndColorProfileIgnored) { |
| 311 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( | 311 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::create( |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 SkImageInfo resizedInfo = SkImageInfo::Make( | 516 SkImageInfo resizedInfo = SkImageInfo::Make( |
| 517 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); | 517 resizeWidth, resizeHeight, kN32_SkColorType, kUnpremul_SkAlphaType); |
| 518 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 518 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
| 519 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); | 519 resizeWidth * resizeHeight, resizedInfo.bytesPerPixel()); |
| 520 if (!dstBuffer) | 520 if (!dstBuffer) |
| 521 return nullptr; | 521 return nullptr; |
| 522 RefPtr<Uint8Array> resizedPixels = | 522 RefPtr<Uint8Array> resizedPixels = |
| 523 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 523 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
| 524 SkPixmap pixmap( | 524 SkPixmap pixmap( |
| 525 resizedInfo, resizedPixels->data(), | 525 resizedInfo, resizedPixels->data(), |
| 526 static_cast<size_t>(resizeWidth) * resizedInfo.bytesPerPixel()); | 526 static_cast<unsigned>(resizeWidth) * resizedInfo.bytesPerPixel()); |
| 527 skImage->scalePixels(pixmap, resizeQuality); | 527 skImage->scalePixels(pixmap, resizeQuality); |
| 528 return SkImage::MakeFromRaster(pixmap, | 528 return SkImage::MakeFromRaster(pixmap, |
| 529 [](const void*, void* pixels) { | 529 [](const void*, void* pixels) { |
| 530 static_cast<Uint8Array*>(pixels)->deref(); | 530 static_cast<Uint8Array*>(pixels)->deref(); |
| 531 }, | 531 }, |
| 532 resizedPixels.release().leakRef()); | 532 resizedPixels.release().leakRef()); |
| 533 } | 533 } |
| 534 | 534 |
| 535 ImageBitmap::ImageBitmap(ImageData* data, | 535 ImageBitmap::ImageBitmap(ImageData* data, |
| 536 Optional<IntRect> cropRect, | 536 Optional<IntRect> cropRect, |
| 537 const ImageBitmapOptions& options) { | 537 const ImageBitmapOptions& options) { |
| 538 // TODO(xidachen): implement the resize option | 538 // TODO(xidachen): implement the resize option |
| 539 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); | 539 IntRect dataSrcRect = IntRect(IntPoint(), data->size()); |
| 540 ParsedOptions parsedOptions = | 540 ParsedOptions parsedOptions = |
| 541 parseOptions(options, cropRect, data->bitmapSourceSize()); | 541 parseOptions(options, cropRect, data->bitmapSourceSize()); |
| 542 if (dstBufferSizeHasOverflow(parsedOptions)) | 542 if (dstBufferSizeHasOverflow(parsedOptions)) |
| 543 return; | 543 return; |
| 544 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) | 544 IntRect srcRect = cropRect ? intersection(parsedOptions.cropRect, dataSrcRect) |
| 545 : dataSrcRect; | 545 : dataSrcRect; |
| 546 | 546 |
| 547 // treat non-premultiplyAlpha as a special case | 547 // treat non-premultiplyAlpha as a special case |
| 548 if (!parsedOptions.premultiplyAlpha) { | 548 if (!parsedOptions.premultiplyAlpha) { |
| 549 unsigned char* srcAddr = data->data()->data(); | 549 unsigned char* srcAddr = data->data()->data(); |
| 550 | 550 |
| 551 // Using kN32 type, swizzle input if necessary. | 551 // Using kN32 type, swizzle input if necessary. |
| 552 SkImageInfo info = SkImageInfo::Make( | 552 SkImageInfo info = SkImageInfo::Make( |
| 553 parsedOptions.cropRect.width(), parsedOptions.cropRect.height(), | 553 parsedOptions.cropRect.width(), parsedOptions.cropRect.height(), |
| 554 kN32_SkColorType, kUnpremul_SkAlphaType); | 554 kN32_SkColorType, kUnpremul_SkAlphaType); |
| 555 size_t bytesPerPixel = static_cast<size_t>(info.bytesPerPixel()); | 555 unsigned bytesPerPixel = static_cast<unsigned>(info.bytesPerPixel()); |
| 556 size_t srcPixelBytesPerRow = bytesPerPixel * data->size().width(); | 556 unsigned srcPixelBytesPerRow = bytesPerPixel * data->size().width(); |
| 557 size_t dstPixelBytesPerRow = bytesPerPixel * parsedOptions.cropRect.width(); | 557 unsigned dstPixelBytesPerRow = |
| 558 bytesPerPixel * parsedOptions.cropRect.width(); |
| 558 sk_sp<SkImage> skImage; | 559 sk_sp<SkImage> skImage; |
| 559 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { | 560 if (parsedOptions.cropRect == IntRect(IntPoint(), data->size())) { |
| 560 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, | 561 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, |
| 561 parsedOptions.flipY); | 562 parsedOptions.flipY); |
| 562 skImage = | 563 skImage = |
| 563 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); | 564 SkImage::MakeRasterCopy(SkPixmap(info, srcAddr, dstPixelBytesPerRow)); |
| 564 // restore the original ImageData | 565 // restore the original ImageData |
| 565 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, | 566 swizzleImageData(srcAddr, data->size().height(), srcPixelBytesPerRow, |
| 566 parsedOptions.flipY); | 567 parsedOptions.flipY); |
| 567 } else { | 568 } else { |
| 568 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( | 569 RefPtr<ArrayBuffer> dstBuffer = ArrayBuffer::createOrNull( |
| 569 static_cast<size_t>(parsedOptions.cropRect.height()) * | 570 static_cast<unsigned>(parsedOptions.cropRect.height()) * |
| 570 parsedOptions.cropRect.width(), | 571 parsedOptions.cropRect.width(), |
| 571 bytesPerPixel); | 572 bytesPerPixel); |
| 572 if (!dstBuffer) | 573 if (!dstBuffer) |
| 573 return; | 574 return; |
| 574 RefPtr<Uint8Array> copiedDataBuffer = | 575 RefPtr<Uint8Array> copiedDataBuffer = |
| 575 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); | 576 Uint8Array::create(dstBuffer, 0, dstBuffer->byteLength()); |
| 576 if (!srcRect.isEmpty()) { | 577 if (!srcRect.isEmpty()) { |
| 577 IntPoint srcPoint = IntPoint( | 578 IntPoint srcPoint = IntPoint( |
| 578 (parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, | 579 (parsedOptions.cropRect.x() > 0) ? parsedOptions.cropRect.x() : 0, |
| 579 (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0); | 580 (parsedOptions.cropRect.y() > 0) ? parsedOptions.cropRect.y() : 0); |
| 580 IntPoint dstPoint = IntPoint( | 581 IntPoint dstPoint = IntPoint( |
| 581 (parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), | 582 (parsedOptions.cropRect.x() >= 0) ? 0 : -parsedOptions.cropRect.x(), |
| 582 (parsedOptions.cropRect.y() >= 0) ? 0 | 583 (parsedOptions.cropRect.y() >= 0) ? 0 |
| 583 : -parsedOptions.cropRect.y()); | 584 : -parsedOptions.cropRect.y()); |
| 584 int copyHeight = data->size().height() - srcPoint.y(); | 585 int copyHeight = data->size().height() - srcPoint.y(); |
| 585 if (parsedOptions.cropRect.height() < copyHeight) | 586 if (parsedOptions.cropRect.height() < copyHeight) |
| 586 copyHeight = parsedOptions.cropRect.height(); | 587 copyHeight = parsedOptions.cropRect.height(); |
| 587 int copyWidth = data->size().width() - srcPoint.x(); | 588 int copyWidth = data->size().width() - srcPoint.x(); |
| 588 if (parsedOptions.cropRect.width() < copyWidth) | 589 if (parsedOptions.cropRect.width() < copyWidth) |
| 589 copyWidth = parsedOptions.cropRect.width(); | 590 copyWidth = parsedOptions.cropRect.width(); |
| 590 for (int i = 0; i < copyHeight; i++) { | 591 for (int i = 0; i < copyHeight; i++) { |
| 591 size_t srcStartCopyPosition = | 592 unsigned srcStartCopyPosition = |
| 592 (i + srcPoint.y()) * srcPixelBytesPerRow + | 593 (i + srcPoint.y()) * srcPixelBytesPerRow + |
| 593 srcPoint.x() * bytesPerPixel; | 594 srcPoint.x() * bytesPerPixel; |
| 594 size_t srcEndCopyPosition = | 595 unsigned srcEndCopyPosition = |
| 595 srcStartCopyPosition + copyWidth * bytesPerPixel; | 596 srcStartCopyPosition + copyWidth * bytesPerPixel; |
| 596 size_t dstStartCopyPosition; | 597 unsigned dstStartCopyPosition; |
| 597 if (parsedOptions.flipY) | 598 if (parsedOptions.flipY) |
| 598 dstStartCopyPosition = | 599 dstStartCopyPosition = |
| 599 (parsedOptions.cropRect.height() - 1 - dstPoint.y() - i) * | 600 (parsedOptions.cropRect.height() - 1 - dstPoint.y() - i) * |
| 600 dstPixelBytesPerRow + | 601 dstPixelBytesPerRow + |
| 601 dstPoint.x() * bytesPerPixel; | 602 dstPoint.x() * bytesPerPixel; |
| 602 else | 603 else |
| 603 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + | 604 dstStartCopyPosition = (dstPoint.y() + i) * dstPixelBytesPerRow + |
| 604 dstPoint.x() * bytesPerPixel; | 605 dstPoint.x() * bytesPerPixel; |
| 605 for (size_t j = 0; j < srcEndCopyPosition - srcStartCopyPosition; | 606 for (unsigned j = 0; j < srcEndCopyPosition - srcStartCopyPosition; |
| 606 j++) { | 607 j++) { |
| 607 // swizzle when necessary | 608 // swizzle when necessary |
| 608 if (kN32_SkColorType == kBGRA_8888_SkColorType) { | 609 if (kN32_SkColorType == kBGRA_8888_SkColorType) { |
| 609 if (j % 4 == 0) | 610 if (j % 4 == 0) |
| 610 copiedDataBuffer->data()[dstStartCopyPosition + j] = | 611 copiedDataBuffer->data()[dstStartCopyPosition + j] = |
| 611 srcAddr[srcStartCopyPosition + j + 2]; | 612 srcAddr[srcStartCopyPosition + j + 2]; |
| 612 else if (j % 4 == 2) | 613 else if (j % 4 == 2) |
| 613 copiedDataBuffer->data()[dstStartCopyPosition + j] = | 614 copiedDataBuffer->data()[dstStartCopyPosition + j] = |
| 614 srcAddr[srcStartCopyPosition + j - 2]; | 615 srcAddr[srcStartCopyPosition + j - 2]; |
| 615 else | 616 else |
| (...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, | 857 void ImageBitmap::adjustDrawRects(FloatRect* srcRect, |
| 857 FloatRect* dstRect) const {} | 858 FloatRect* dstRect) const {} |
| 858 | 859 |
| 859 FloatSize ImageBitmap::elementSize(const FloatSize&) const { | 860 FloatSize ImageBitmap::elementSize(const FloatSize&) const { |
| 860 return FloatSize(width(), height()); | 861 return FloatSize(width(), height()); |
| 861 } | 862 } |
| 862 | 863 |
| 863 DEFINE_TRACE(ImageBitmap) {} | 864 DEFINE_TRACE(ImageBitmap) {} |
| 864 | 865 |
| 865 } // namespace blink | 866 } // namespace blink |
| OLD | NEW |