| 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 |