Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Side by Side Diff: third_party/WebKit/Source/core/frame/ImageBitmap.cpp

Issue 2845193002: Refactor ImageBitmap constructor from ImageData to be color managed
Patch Set: local commit - all working except unpremultiply Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <memory> 7 #include <memory>
8 #include "core/html/HTMLCanvasElement.h" 8 #include "core/html/HTMLCanvasElement.h"
9 #include "core/html/HTMLVideoElement.h" 9 #include "core/html/HTMLVideoElement.h"
10 #include "core/html/ImageData.h" 10 #include "core/html/ImageData.h"
11 #include "core/offscreencanvas/OffscreenCanvas.h" 11 #include "core/offscreencanvas/OffscreenCanvas.h"
12 #include "platform/graphics/CanvasColorParams.h" 12 #include "platform/graphics/CanvasColorParams.h"
13 #include "platform/graphics/skia/SkiaUtils.h" 13 #include "platform/graphics/skia/SkiaUtils.h"
14 #include "platform/image-decoders/ImageDecoder.h" 14 #include "platform/image-decoders/ImageDecoder.h"
15 #include "platform/wtf/CheckedNumeric.h" 15 #include "platform/wtf/CheckedNumeric.h"
16 #include "platform/wtf/PtrUtil.h" 16 #include "platform/wtf/PtrUtil.h"
17 #include "platform/wtf/RefPtr.h" 17 #include "platform/wtf/RefPtr.h"
18 #include "third_party/skia/include/core/SkCanvas.h" 18 #include "third_party/skia/include/core/SkCanvas.h"
19 #include "third_party/skia/include/core/SkImageInfo.h" 19 #include "third_party/skia/include/core/SkImageInfo.h"
20 #include "third_party/skia/include/core/SkSurface.h" 20 #include "third_party/skia/include/core/SkSurface.h"
21 #include "third_party/skia/include/core/SkSwizzle.h"
21 22
22 namespace blink { 23 namespace blink {
23 24
24 constexpr const char* kImageOrientationFlipY = "flipY"; 25 constexpr const char* kImageOrientationFlipY = "flipY";
25 constexpr const char* kImageBitmapOptionNone = "none"; 26 constexpr const char* kImageBitmapOptionNone = "none";
26 constexpr const char* kImageBitmapOptionDefault = "default"; 27 constexpr const char* kImageBitmapOptionDefault = "default";
27 constexpr const char* kImageBitmapOptionPremultiply = "premultiply"; 28 constexpr const char* kImageBitmapOptionPremultiply = "premultiply";
28 constexpr const char* kImageBitmapOptionResizeQualityHigh = "high"; 29 constexpr const char* kImageBitmapOptionResizeQualityHigh = "high";
29 constexpr const char* kImageBitmapOptionResizeQualityMedium = "medium"; 30 constexpr const char* kImageBitmapOptionResizeQualityMedium = "medium";
30 constexpr const char* kImageBitmapOptionResizeQualityPixelated = "pixelated"; 31 constexpr const char* kImageBitmapOptionResizeQualityPixelated = "pixelated";
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 parsed_options.resize_quality = kHigh_SkFilterQuality; 146 parsed_options.resize_quality = kHigh_SkFilterQuality;
146 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityMedium) 147 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityMedium)
147 parsed_options.resize_quality = kMedium_SkFilterQuality; 148 parsed_options.resize_quality = kMedium_SkFilterQuality;
148 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityPixelated) 149 else if (options.resizeQuality() == kImageBitmapOptionResizeQualityPixelated)
149 parsed_options.resize_quality = kNone_SkFilterQuality; 150 parsed_options.resize_quality = kNone_SkFilterQuality;
150 else 151 else
151 parsed_options.resize_quality = kLow_SkFilterQuality; 152 parsed_options.resize_quality = kLow_SkFilterQuality;
152 return parsed_options; 153 return parsed_options;
153 } 154 }
154 155
156 // The function dstBufferSizeHasOverflow() is being called at the beginning of
157 // each ImageBitmap() constructor, which makes sure that doing
158 // width * height * bytesPerPixel will never overflow unsigned.
155 bool DstBufferSizeHasOverflow(const ParsedOptions& options) { 159 bool DstBufferSizeHasOverflow(const ParsedOptions& options) {
156 CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width(); 160 CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width();
157 total_bytes *= options.crop_rect.Height(); 161 total_bytes *= options.crop_rect.Height();
158 total_bytes *= 162 total_bytes *=
159 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType()); 163 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType());
160 if (!total_bytes.IsValid()) 164 if (!total_bytes.IsValid())
161 return true; 165 return true;
162 166
163 if (!options.should_scale_input) 167 if (!options.should_scale_input)
164 return false; 168 return false;
165 total_bytes = options.resize_width; 169 total_bytes = options.resize_width;
166 total_bytes *= options.resize_height; 170 total_bytes *= options.resize_height;
167 total_bytes *= 171 total_bytes *=
168 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType()); 172 SkColorTypeBytesPerPixel(options.color_params.GetSkColorType());
169 if (!total_bytes.IsValid()) 173 if (!total_bytes.IsValid())
170 return true; 174 return true;
171 175
172 return false; 176 return false;
173 } 177 }
174 178
175 } // namespace 179 } // namespace
176 180
181 static void PrintSkImage(sk_sp<SkImage> input) {
182 SkImageInfo info =
183 SkImageInfo::Make(input->width(), input->height(), kN32_SkColorType,
184 kPremul_SkAlphaType, input->refColorSpace());
185 LOG(ERROR) << "Printing SkImage:" << input->width() << "," << input->height();
186 std::stringstream str;
187 std::unique_ptr<uint8_t[]> read_pixels(
188 new uint8_t[input->width() * input->height() * 4]());
189 input->readPixels(info, read_pixels.get(), input->width() * 4, 0, 0);
190 for (int i = 0; i < input->width() * input->height(); i++) {
191 if (i % input->width() == 0)
192 str << "\n";
193 str << "[";
194 for (int j = 0; j < 4; j++)
195 str << (int)(read_pixels[i * 4 + j]) << ",";
196 str << "] ";
197 }
198 LOG(ERROR) << str.str();
199 }
200
177 static PassRefPtr<Uint8Array> CopySkImageData(SkImage* input, 201 static PassRefPtr<Uint8Array> CopySkImageData(SkImage* input,
178 const SkImageInfo& info) { 202 const SkImageInfo& info) {
179 // The function dstBufferSizeHasOverflow() is being called at the beginning of
180 // each ImageBitmap() constructor, which makes sure that doing
181 // width * height * bytesPerPixel will never overflow unsigned.
182 unsigned width = static_cast<unsigned>(input->width()); 203 unsigned width = static_cast<unsigned>(input->width());
183 RefPtr<ArrayBuffer> dst_buffer = 204 RefPtr<ArrayBuffer> dst_buffer =
184 ArrayBuffer::CreateOrNull(width * input->height(), info.bytesPerPixel()); 205 ArrayBuffer::CreateOrNull(width * input->height(), info.bytesPerPixel());
185 if (!dst_buffer) 206 if (!dst_buffer)
186 return nullptr; 207 return nullptr;
187 RefPtr<Uint8Array> dst_pixels = 208 RefPtr<Uint8Array> dst_pixels =
188 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength()); 209 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
189 input->readPixels(info, dst_pixels->Data(), width * info.bytesPerPixel(), 0, 210 input->readPixels(info, dst_pixels->Data(), width * info.bytesPerPixel(), 0,
190 0); 211 0);
191 return dst_pixels; 212 return dst_pixels;
192 } 213 }
193 214
194 static sk_sp<SkImage> NewSkImageFromRaster(const SkImageInfo& info, 215 static sk_sp<SkImage> NewSkImageFromRaster(const SkImageInfo& info,
195 PassRefPtr<Uint8Array> image_pixels, 216 PassRefPtr<Uint8Array> image_pixels,
196 unsigned image_row_bytes) { 217 unsigned image_row_bytes) {
197 SkPixmap pixmap(info, image_pixels->Data(), image_row_bytes); 218 SkPixmap pixmap(info, image_pixels->Data(), image_row_bytes);
198 return SkImage::MakeFromRaster(pixmap, 219 return SkImage::MakeFromRaster(pixmap,
199 [](const void*, void* pixels) { 220 [](const void*, void* pixels) {
200 static_cast<Uint8Array*>(pixels)->Deref(); 221 static_cast<Uint8Array*>(pixels)->Deref();
201 }, 222 },
202 image_pixels.LeakRef()); 223 image_pixels.LeakRef());
203 } 224 }
204 225
205 static void SwizzleImageData(unsigned char* src_addr,
206 unsigned height,
207 unsigned bytes_per_row,
208 bool flip_y) {
209 if (flip_y) {
210 for (unsigned i = 0; i < height / 2; i++) {
211 unsigned top_row_start_position = i * bytes_per_row;
212 unsigned bottom_row_start_position = (height - 1 - i) * bytes_per_row;
213 if (kN32_SkColorType == kBGRA_8888_SkColorType) { // needs to swizzle
214 for (unsigned j = 0; j < bytes_per_row; j += 4) {
215 std::swap(src_addr[top_row_start_position + j],
216 src_addr[bottom_row_start_position + j + 2]);
217 std::swap(src_addr[top_row_start_position + j + 1],
218 src_addr[bottom_row_start_position + j + 1]);
219 std::swap(src_addr[top_row_start_position + j + 2],
220 src_addr[bottom_row_start_position + j]);
221 std::swap(src_addr[top_row_start_position + j + 3],
222 src_addr[bottom_row_start_position + j + 3]);
223 }
224 } else {
225 std::swap_ranges(src_addr + top_row_start_position,
226 src_addr + top_row_start_position + bytes_per_row,
227 src_addr + bottom_row_start_position);
228 }
229 }
230 } else {
231 if (kN32_SkColorType == kBGRA_8888_SkColorType) // needs to swizzle
232 for (unsigned i = 0; i < height * bytes_per_row; i += 4)
233 std::swap(src_addr[i], src_addr[i + 2]);
234 }
235 }
236
237 enum AlphaPremultiplyEnforcement { 226 enum AlphaPremultiplyEnforcement {
238 kEnforceAlphaPremultiply, 227 kEnforceAlphaPremultiply,
239 kDontEnforceAlphaPremultiply, 228 kDontEnforceAlphaPremultiply,
240 }; 229 };
241 230
242 static sk_sp<SkImage> FlipSkImageVertically( 231 static sk_sp<SkImage> FlipSkImageVertically(
243 SkImage* input, 232 SkImage* input,
244 AlphaPremultiplyEnforcement premultiply_enforcement = 233 AlphaPremultiplyEnforcement premultiply_enforcement =
245 kDontEnforceAlphaPremultiply, 234 kDontEnforceAlphaPremultiply,
246 const ParsedOptions& options = DefaultOptions()) { 235 const ParsedOptions& options = DefaultOptions()) {
(...skipping 21 matching lines...) Expand all
268 image_pixels->Data() + bottom_first_element); 257 image_pixels->Data() + bottom_first_element);
269 } 258 }
270 return NewSkImageFromRaster(info, std::move(image_pixels), image_row_bytes); 259 return NewSkImageFromRaster(info, std::move(image_pixels), image_row_bytes);
271 } 260 }
272 261
273 static sk_sp<SkImage> PremulSkImageToUnPremul( 262 static sk_sp<SkImage> PremulSkImageToUnPremul(
274 SkImage* input, 263 SkImage* input,
275 const ParsedOptions& options = DefaultOptions()) { 264 const ParsedOptions& options = DefaultOptions()) {
276 SkImageInfo info = SkImageInfo::Make( 265 SkImageInfo info = SkImageInfo::Make(
277 input->width(), input->height(), options.color_params.GetSkColorType(), 266 input->width(), input->height(), options.color_params.GetSkColorType(),
278 kUnpremul_SkAlphaType, input->refColorSpace()); 267 kPremul_SkAlphaType, options.color_params.GetSkColorSpaceForSkSurfaces());
279 268
269 LOG(ERROR) << "Premul:";
270 std::stringstream str;
271 std::unique_ptr<uint8_t[]> read_pixels(new uint8_t[64]());
272 input->readPixels(info, read_pixels.get(), input->width() * 4, 0, 0);
273 for (int i = 0; i < 16; i++) {
274 str << "[";
275 for (int j = 0; j < 4; j++)
276 str << (int)(read_pixels[i * 4 + j]) << ",";
277 str << "] ";
278 }
279 LOG(ERROR) << str.str();
280
281 info = info.makeAlphaType(kUnpremul_SkAlphaType);
280 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); 282 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info);
283 LOG(ERROR) << "Unpremul:";
284 str.str("");
285 for (int i = 0; i < 16; i++) {
286 str << "[";
287 for (int j = 0; j < 4; j++)
288 str << (int)(dst_pixels->Data()[i * 4 + j]) << ",";
289 str << "] ";
290 }
291 LOG(ERROR) << str.str();
292
281 if (!dst_pixels) 293 if (!dst_pixels)
282 return nullptr; 294 return nullptr;
283 return NewSkImageFromRaster( 295 return NewSkImageFromRaster(
284 info, std::move(dst_pixels), 296 info, std::move(dst_pixels),
285 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); 297 static_cast<unsigned>(input->width()) * info.bytesPerPixel());
286 } 298 }
287 299
288 static sk_sp<SkImage> UnPremulSkImageToPremul( 300 static sk_sp<SkImage> UnPremulSkImageToPremul(
289 SkImage* input, 301 SkImage* input,
290 const ParsedOptions& options = DefaultOptions()) { 302 const ParsedOptions& options = DefaultOptions()) {
291 SkImageInfo info = SkImageInfo::Make( 303 SkImageInfo info = SkImageInfo::Make(
292 input->width(), input->height(), options.color_params.GetSkColorType(), 304 input->width(), input->height(), options.color_params.GetSkColorType(),
293 kPremul_SkAlphaType, input->refColorSpace()); 305 kPremul_SkAlphaType, input->refColorSpace());
294 306
295 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info); 307 RefPtr<Uint8Array> dst_pixels = CopySkImageData(input, info);
296 if (!dst_pixels) 308 if (!dst_pixels)
297 return nullptr; 309 return nullptr;
298 return NewSkImageFromRaster( 310 return NewSkImageFromRaster(
299 info, std::move(dst_pixels), 311 info, std::move(dst_pixels),
300 static_cast<unsigned>(input->width()) * info.bytesPerPixel()); 312 static_cast<unsigned>(input->width()) * info.bytesPerPixel());
301 } 313 }
302 314
303 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image, 315 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image,
304 ParsedOptions& options) { 316 ParsedOptions& options) {
305 if (!options.color_canvas_extensions_enabled) 317 if (!options.color_canvas_extensions_enabled)
306 return; 318 return;
307 319
308 sk_sp<SkColorSpace> dst_color_space = nullptr; 320 SkColorType dst_color_type = options.color_params.GetSkColorType();
309 SkColorType dst_color_type = kN32_SkColorType; 321 sk_sp<SkColorSpace> dst_color_space = options.color_params.GetSkColorSpace();
310 dst_color_space = options.color_params.GetSkColorSpace();
311 dst_color_type = options.color_params.GetSkColorType();
312 if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get())) 322 if (SkColorSpace::Equals(image->colorSpace(), dst_color_space.get()))
313 return; 323 return;
314 324
315 SkImageInfo dst_info = 325 SkImageInfo dst_info =
316 SkImageInfo::Make(image->width(), image->height(), dst_color_type, 326 SkImageInfo::Make(image->width(), image->height(), dst_color_type,
317 image->alphaType(), dst_color_space); 327 image->alphaType(), dst_color_space);
318 328
319 size_t size = image->width() * image->height() * dst_info.bytesPerPixel(); 329 size_t size = image->width() * image->height() * dst_info.bytesPerPixel();
320 sk_sp<SkData> dst_data = SkData::MakeUninitialized(size); 330 sk_sp<SkData> dst_data = SkData::MakeUninitialized(size);
321 if (dst_data->size() != size) 331 if (dst_data->size() != size)
322 return; 332 return;
323 sk_sp<SkImage> colored_image = nullptr; 333 sk_sp<SkImage> colored_image = nullptr;
334 // The desired way to apply color space conversion on a SkImage is to use
335 // SkImage::readPixels.
324 if (image->readPixels(dst_info, dst_data->writable_data(), 336 if (image->readPixels(dst_info, dst_data->writable_data(),
325 image->width() * dst_info.bytesPerPixel(), 0, 0)) { 337 image->width() * dst_info.bytesPerPixel(), 0, 0)) {
326 colored_image = SkImage::MakeRasterData( 338 colored_image = SkImage::MakeRasterData(
327 dst_info, dst_data, image->width() * dst_info.bytesPerPixel()); 339 dst_info, dst_data, image->width() * dst_info.bytesPerPixel());
328 } else { 340 } else {
329 // The desired way to apply color space conversion on a SkImage is to use 341 // However, if the SkImage is GPU-backed, readPixels might not work
330 // SkImage::readPixels. However, if the SkImage is GPU-backed, readPixels 342 // properly. In this case, we fall back to drawing the SkImage to a
331 // still might not work properly. In this case, we fall back to drawing 343 // canvas and reading back the result.
332 // the SkImage to a canvas and reading back the result.
333 // Skia does not support drawing to unpremul surfaces/canvases. 344 // Skia does not support drawing to unpremul surfaces/canvases.
334 sk_sp<SkImage> un_premul_image = nullptr; 345 sk_sp<SkImage> un_premul_image = nullptr;
335 if (image->alphaType() == kUnpremul_SkAlphaType) { 346 if (image->alphaType() == kUnpremul_SkAlphaType) {
336 un_premul_image = UnPremulSkImageToPremul(image.get(), options); 347 un_premul_image = UnPremulSkImageToPremul(image.get(), options);
337 dst_info = dst_info.makeAlphaType(kPremul_SkAlphaType); 348 dst_info = dst_info.makeAlphaType(kPremul_SkAlphaType);
338 } 349 }
339 350
340 // If the color space of the source SkImage is null, the following code 351 // If the color space of the source SkImage is null, the following code
341 // does not do any color conversion. This cannot be addressed here and 352 // does not do any color conversion. This cannot be addressed here and
342 // the code that creates the SkImage must tag the SkImage with proper 353 // the code that creates the SkImage must tag the SkImage with proper
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 // need to use the ImageDecoder to decode the image. 415 // need to use the ImageDecoder to decode the image.
405 static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion( 416 static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
406 Image* image, 417 Image* image,
407 ParsedOptions& parsed_options, 418 ParsedOptions& parsed_options,
408 AlphaDisposition image_format, 419 AlphaDisposition image_format,
409 ColorBehavior color_behavior) { 420 ColorBehavior color_behavior) {
410 DCHECK(image); 421 DCHECK(image);
411 IntRect img_rect(IntPoint(), IntSize(image->width(), image->height())); 422 IntRect img_rect(IntPoint(), IntSize(image->width(), image->height()));
412 const IntRect src_rect = Intersection(img_rect, parsed_options.crop_rect); 423 const IntRect src_rect = Intersection(img_rect, parsed_options.crop_rect);
413 424
414 // In the case when cropRect doesn't intersect the source image and it 425 // In the case when cropRect doesn't intersect the source image, we
415 // requires a umpremul image We immediately return a transparent black image 426 // return a transparent black image, respecting the color_params but
416 // with cropRect.size() 427 // ignoring premultiply_alpha.
417 if (src_rect.IsEmpty() && !parsed_options.premultiply_alpha) { 428 if (src_rect.IsEmpty()) {
418 SkImageInfo info = SkImageInfo::Make( 429 SkImageInfo info = SkImageInfo::Make(
419 parsed_options.resize_width, parsed_options.resize_height, 430 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(),
420 kN32_SkColorType, kUnpremul_SkAlphaType); 431 parsed_options.color_params.GetSkColorType(), kPremul_SkAlphaType,
421 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull( 432 parsed_options.color_params.GetSkColorSpace());
422 static_cast<unsigned>(info.width()) * info.height(), 433 if (parsed_options.should_scale_input) {
423 info.bytesPerPixel()); 434 info = info.makeWH(parsed_options.resize_width,
424 if (!dst_buffer) 435 parsed_options.resize_height);
436 }
437 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
438 if (!surface)
425 return nullptr; 439 return nullptr;
426 RefPtr<Uint8Array> dst_pixels = 440 return StaticBitmapImage::Create(surface->makeImageSnapshot());
427 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
428 return StaticBitmapImage::Create(NewSkImageFromRaster(
429 info, std::move(dst_pixels),
430 static_cast<unsigned>(info.width()) * info.bytesPerPixel()));
431 } 441 }
432 442
433 sk_sp<SkImage> skia_image = image->ImageForCurrentFrame(); 443 sk_sp<SkImage> skia_image = image->ImageForCurrentFrame();
434 // Attempt to get raw unpremultiplied image data, executed only when skiaImage 444 // Attempt to get raw unpremultiplied image data, executed only when
435 // is premultiplied. 445 // skia_image is premultiplied.
436 if ((((!parsed_options.premultiply_alpha && !skia_image->isOpaque()) || 446 if ((((!parsed_options.premultiply_alpha && !skia_image->isOpaque()) ||
437 !skia_image) && 447 !skia_image) &&
438 image->Data() && image_format == kPremultiplyAlpha) || 448 image->Data() && image_format == kPremultiplyAlpha) ||
439 color_behavior.IsIgnore()) { 449 color_behavior.IsIgnore()) {
450 LOG(ERROR) << "HERE...";
440 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create( 451 std::unique_ptr<ImageDecoder> decoder(ImageDecoder::Create(
441 image->Data(), true, 452 image->Data(), true,
442 parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied 453 parsed_options.premultiply_alpha ? ImageDecoder::kAlphaPremultiplied
443 : ImageDecoder::kAlphaNotPremultiplied, 454 : ImageDecoder::kAlphaNotPremultiplied,
444 color_behavior)); 455 color_behavior));
445 if (!decoder) 456 if (!decoder)
446 return nullptr; 457 return nullptr;
447 SkColorType color_type = parsed_options.color_params.GetSkColorType(); 458 SkColorType color_type = parsed_options.color_params.GetSkColorType();
448 sk_sp<SkColorSpace> color_space = 459 sk_sp<SkColorSpace> color_space =
449 parsed_options.color_params.GetSkColorSpace(); 460 parsed_options.color_params.GetSkColorSpace();
450 skia_image = ImageBitmap::GetSkImageFromDecoder( 461 skia_image = ImageBitmap::GetSkImageFromDecoder(
451 std::move(decoder), &color_type, &color_space, 462 std::move(decoder), &color_type, &color_space,
452 kUpdateColorSpaceInformation); 463 kUpdateColorSpaceInformation);
453 if (!skia_image) 464 if (!skia_image)
454 return nullptr; 465 return nullptr;
455 } 466 }
456 467
457 if (parsed_options.crop_rect == src_rect && 468 if (!parsed_options.should_scale_input) {
458 !parsed_options.should_scale_input) {
459 sk_sp<SkImage> cropped_sk_image = skia_image->makeSubset(src_rect); 469 sk_sp<SkImage> cropped_sk_image = skia_image->makeSubset(src_rect);
460 ApplyColorSpaceConversion(cropped_sk_image, parsed_options); 470 ApplyColorSpaceConversion(cropped_sk_image, parsed_options);
461 if (parsed_options.flip_y) { 471 if (parsed_options.flip_y) {
462 return StaticBitmapImage::Create( 472 return StaticBitmapImage::Create(
463 FlipSkImageVertically(cropped_sk_image.get(), 473 FlipSkImageVertically(cropped_sk_image.get(),
464 kDontEnforceAlphaPremultiply, parsed_options)); 474 kDontEnforceAlphaPremultiply, parsed_options));
465 } 475 }
466 // Special case: The first parameter image is unpremul but we need to turn 476 // Special case: The first parameter image is unpremul but we need to turn
467 // it into premul. 477 // it into premul.
468 if (parsed_options.premultiply_alpha && 478 if (parsed_options.premultiply_alpha &&
469 image_format == kDontPremultiplyAlpha) { 479 image_format == kDontPremultiplyAlpha) {
470 return StaticBitmapImage::Create( 480 return StaticBitmapImage::Create(
471 UnPremulSkImageToPremul(cropped_sk_image.get())); 481 UnPremulSkImageToPremul(cropped_sk_image.get()));
472 } 482 }
473 return StaticBitmapImage::Create(std::move(cropped_sk_image)); 483 return StaticBitmapImage::Create(std::move(cropped_sk_image));
474 } 484 }
475 485
476 sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul( 486 LOG(ERROR) << "HERE...";
477 parsed_options.resize_width, parsed_options.resize_height); 487 SkImageInfo info = SkImageInfo::Make(
488 parsed_options.resize_width, parsed_options.resize_height,
489 parsed_options.color_params.GetSkColorType(),
490 parsed_options.premultiply_alpha ? kPremul_SkAlphaType
491 : kUnpremul_SkAlphaType,
492 parsed_options.color_params.GetSkColorSpace());
493 sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
478 if (!surface) 494 if (!surface)
479 return nullptr; 495 return nullptr;
480 if (src_rect.IsEmpty())
481 return StaticBitmapImage::Create(surface->makeImageSnapshot());
482
483 SkScalar dst_left = std::min(0, -parsed_options.crop_rect.X());
484 SkScalar dst_top = std::min(0, -parsed_options.crop_rect.Y());
485 if (parsed_options.crop_rect.X() < 0)
486 dst_left = -parsed_options.crop_rect.X();
487 if (parsed_options.crop_rect.Y() < 0)
488 dst_top = -parsed_options.crop_rect.Y();
489 if (parsed_options.flip_y) { 496 if (parsed_options.flip_y) {
490 surface->getCanvas()->translate(0, surface->height()); 497 surface->getCanvas()->translate(0, surface->height());
491 surface->getCanvas()->scale(1, -1); 498 surface->getCanvas()->scale(1, -1);
492 } 499 }
493 if (parsed_options.should_scale_input) { 500
494 SkRect draw_src_rect = SkRect::MakeXYWH( 501 SkRect draw_src_rect(parsed_options.crop_rect);
495 parsed_options.crop_rect.X(), parsed_options.crop_rect.Y(), 502 SkRect draw_dst_rect =
496 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height()); 503 SkRect::MakeWH(parsed_options.resize_width, parsed_options.resize_height);
497 SkRect draw_dst_rect = SkRect::MakeXYWH(0, 0, parsed_options.resize_width, 504 SkPaint paint;
498 parsed_options.resize_height); 505 paint.setFilterQuality(parsed_options.resize_quality);
499 SkPaint paint; 506 surface->getCanvas()->drawImageRect(skia_image, draw_src_rect, draw_dst_rect,
500 paint.setFilterQuality(parsed_options.resize_quality); 507 &paint);
501 surface->getCanvas()->drawImageRect(skia_image, draw_src_rect, 508
502 draw_dst_rect, &paint);
503 } else {
504 surface->getCanvas()->drawImage(skia_image, dst_left, dst_top);
505 }
506 skia_image = surface->makeImageSnapshot(); 509 skia_image = surface->makeImageSnapshot();
510 PrintSkImage(skia_image);
507 ApplyColorSpaceConversion(skia_image, parsed_options); 511 ApplyColorSpaceConversion(skia_image, parsed_options);
512 PrintSkImage(skia_image);
508 513
509 if (parsed_options.premultiply_alpha) { 514 if (parsed_options.premultiply_alpha) {
515 LOG(ERROR) << "HERE";
510 if (image_format == kDontPremultiplyAlpha) 516 if (image_format == kDontPremultiplyAlpha)
511 return StaticBitmapImage::Create( 517 return StaticBitmapImage::Create(
512 UnPremulSkImageToPremul(skia_image.get())); 518 UnPremulSkImageToPremul(skia_image.get()));
513 return StaticBitmapImage::Create(std::move(skia_image)); 519 return StaticBitmapImage::Create(std::move(skia_image));
514 } 520 }
515 return StaticBitmapImage::Create(PremulSkImageToUnPremul(skia_image.get())); 521 LOG(ERROR) << "HERE";
522 return StaticBitmapImage::Create(std::move(skia_image));
523 // return StaticBitmapImage::Create(
524 // PremulSkImageToUnPremul(skia_image.get(), parsed_options));
516 } 525 }
517 526
518 ImageBitmap::ImageBitmap(ImageElementBase* image, 527 ImageBitmap::ImageBitmap(ImageElementBase* image,
519 Optional<IntRect> crop_rect, 528 Optional<IntRect> crop_rect,
520 Document* document, 529 Document* document,
521 const ImageBitmapOptions& options) { 530 const ImageBitmapOptions& options) {
531 LOG(ERROR) << "Entering...";
522 RefPtr<Image> input = image->CachedImage()->GetImage(); 532 RefPtr<Image> input = image->CachedImage()->GetImage();
523 ParsedOptions parsed_options = 533 ParsedOptions parsed_options =
524 ParseOptions(options, crop_rect, image->BitmapSourceSize()); 534 ParseOptions(options, crop_rect, image->BitmapSourceSize());
525 if (DstBufferSizeHasOverflow(parsed_options)) 535 if (DstBufferSizeHasOverflow(parsed_options))
526 return; 536 return;
527 537
528 if (options.colorSpaceConversion() == kImageBitmapOptionNone) { 538 if (options.colorSpaceConversion() == kImageBitmapOptionNone) {
529 image_ = CropImageAndApplyColorSpaceConversion(input.Get(), parsed_options, 539 image_ = CropImageAndApplyColorSpaceConversion(input.Get(), parsed_options,
530 kPremultiplyAlpha, 540 kPremultiplyAlpha,
531 ColorBehavior::Ignore()); 541 ColorBehavior::Ignore());
(...skipping 27 matching lines...) Expand all
559 return; 569 return;
560 image_->SetOriginClean( 570 image_->SetOriginClean(
561 !image->WouldTaintOrigin(document->GetSecurityOrigin())); 571 !image->WouldTaintOrigin(document->GetSecurityOrigin()));
562 image_->SetPremultiplied(parsed_options.premultiply_alpha); 572 image_->SetPremultiplied(parsed_options.premultiply_alpha);
563 } 573 }
564 574
565 ImageBitmap::ImageBitmap(HTMLVideoElement* video, 575 ImageBitmap::ImageBitmap(HTMLVideoElement* video,
566 Optional<IntRect> crop_rect, 576 Optional<IntRect> crop_rect,
567 Document* document, 577 Document* document,
568 const ImageBitmapOptions& options) { 578 const ImageBitmapOptions& options) {
579 LOG(ERROR) << "Entering...";
569 IntSize player_size; 580 IntSize player_size;
570 if (video->GetWebMediaPlayer()) 581 if (video->GetWebMediaPlayer())
571 player_size = video->GetWebMediaPlayer()->NaturalSize(); 582 player_size = video->GetWebMediaPlayer()->NaturalSize();
572 ParsedOptions parsed_options = 583 ParsedOptions parsed_options =
573 ParseOptions(options, crop_rect, video->BitmapSourceSize()); 584 ParseOptions(options, crop_rect, video->BitmapSourceSize());
574 if (DstBufferSizeHasOverflow(parsed_options)) 585 if (DstBufferSizeHasOverflow(parsed_options))
575 return; 586 return;
576 587
577 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::Create( 588 std::unique_ptr<ImageBuffer> buffer = ImageBuffer::Create(
578 IntSize(parsed_options.resize_width, parsed_options.resize_height), 589 IntSize(parsed_options.resize_width, parsed_options.resize_height),
(...skipping 18 matching lines...) Expand all
597 } 608 }
598 buffer->Canvas()->translate(dst_point.X(), dst_point.Y()); 609 buffer->Canvas()->translate(dst_point.X(), dst_point.Y());
599 video->PaintCurrentFrame( 610 video->PaintCurrentFrame(
600 buffer->Canvas(), 611 buffer->Canvas(),
601 IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())), 612 IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())),
602 parsed_options.should_scale_input ? &flags : nullptr); 613 parsed_options.should_scale_input ? &flags : nullptr);
603 614
604 sk_sp<SkImage> skia_image = 615 sk_sp<SkImage> skia_image =
605 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown); 616 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown);
606 if (!parsed_options.premultiply_alpha) 617 if (!parsed_options.premultiply_alpha)
607 skia_image = PremulSkImageToUnPremul(skia_image.get()); 618 skia_image = PremulSkImageToUnPremul(skia_image.get(), parsed_options);
608 if (!skia_image) 619 if (!skia_image)
609 return; 620 return;
610 image_ = StaticBitmapImage::Create(std::move(skia_image)); 621 image_ = StaticBitmapImage::Create(std::move(skia_image));
611 image_->SetOriginClean( 622 image_->SetOriginClean(
612 !video->WouldTaintOrigin(document->GetSecurityOrigin())); 623 !video->WouldTaintOrigin(document->GetSecurityOrigin()));
613 image_->SetPremultiplied(parsed_options.premultiply_alpha); 624 image_->SetPremultiplied(parsed_options.premultiply_alpha);
614 } 625 }
615 626
616 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, 627 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas,
617 Optional<IntRect> crop_rect, 628 Optional<IntRect> crop_rect,
618 const ImageBitmapOptions& options) { 629 const ImageBitmapOptions& options) {
630 LOG(ERROR) << "Entering...";
619 DCHECK(canvas->IsPaintable()); 631 DCHECK(canvas->IsPaintable());
620 RefPtr<Image> input; 632 RefPtr<Image> input;
621 if (canvas->PlaceholderFrame()) { 633 if (canvas->PlaceholderFrame()) {
622 input = canvas->PlaceholderFrame(); 634 input = canvas->PlaceholderFrame();
623 } else { 635 } else {
624 input = canvas->CopiedImage(kBackBuffer, kPreferAcceleration, 636 input = canvas->CopiedImage(kBackBuffer, kPreferAcceleration,
625 kSnapshotReasonCreateImageBitmap); 637 kSnapshotReasonCreateImageBitmap);
626 } 638 }
627 ParsedOptions parsed_options = ParseOptions( 639 ParsedOptions parsed_options = ParseOptions(
628 options, crop_rect, IntSize(input->width(), input->height())); 640 options, crop_rect, IntSize(input->width(), input->height()));
629 if (DstBufferSizeHasOverflow(parsed_options)) 641 if (DstBufferSizeHasOverflow(parsed_options))
630 return; 642 return;
631 643
632 bool is_premultiply_alpha_reverted = false; 644 bool is_premultiply_alpha_reverted = false;
633 if (!parsed_options.premultiply_alpha) { 645 if (!parsed_options.premultiply_alpha) {
634 parsed_options.premultiply_alpha = true; 646 parsed_options.premultiply_alpha = true;
635 is_premultiply_alpha_reverted = true; 647 is_premultiply_alpha_reverted = true;
636 } 648 }
637 image_ = CropImageAndApplyColorSpaceConversion( 649 image_ = CropImageAndApplyColorSpaceConversion(
638 input.Get(), parsed_options, kPremultiplyAlpha, 650 input.Get(), parsed_options, kPremultiplyAlpha,
639 ColorBehavior::TransformToGlobalTarget()); 651 ColorBehavior::TransformToGlobalTarget());
640 if (!image_) 652 if (!image_)
641 return; 653 return;
642 if (is_premultiply_alpha_reverted) { 654 if (is_premultiply_alpha_reverted) {
643 parsed_options.premultiply_alpha = false; 655 parsed_options.premultiply_alpha = false;
644 image_ = StaticBitmapImage::Create( 656 image_ = StaticBitmapImage::Create(PremulSkImageToUnPremul(
645 PremulSkImageToUnPremul(image_->ImageForCurrentFrame().get())); 657 image_->ImageForCurrentFrame().get(), parsed_options));
646 } 658 }
647 if (!image_) 659 if (!image_)
648 return; 660 return;
649 image_->SetOriginClean(canvas->OriginClean()); 661 image_->SetOriginClean(canvas->OriginClean());
650 image_->SetPremultiplied(parsed_options.premultiply_alpha); 662 image_->SetPremultiplied(parsed_options.premultiply_alpha);
651 } 663 }
652 664
653 ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas, 665 ImageBitmap::ImageBitmap(OffscreenCanvas* offscreen_canvas,
654 Optional<IntRect> crop_rect, 666 Optional<IntRect> crop_rect,
655 const ImageBitmapOptions& options) { 667 const ImageBitmapOptions& options) {
668 LOG(ERROR) << "Entering...";
656 SourceImageStatus status; 669 SourceImageStatus status;
657 RefPtr<Image> input = offscreen_canvas->GetSourceImageForCanvas( 670 RefPtr<Image> input = offscreen_canvas->GetSourceImageForCanvas(
658 &status, kPreferNoAcceleration, kSnapshotReasonCreateImageBitmap, 671 &status, kPreferNoAcceleration, kSnapshotReasonCreateImageBitmap,
659 FloatSize(offscreen_canvas->Size())); 672 FloatSize(offscreen_canvas->Size()));
660 if (status != kNormalSourceImageStatus) 673 if (status != kNormalSourceImageStatus)
661 return; 674 return;
662 ParsedOptions parsed_options = ParseOptions( 675 ParsedOptions parsed_options = ParseOptions(
663 options, crop_rect, IntSize(input->width(), input->height())); 676 options, crop_rect, IntSize(input->width(), input->height()));
664 if (DstBufferSizeHasOverflow(parsed_options)) 677 if (DstBufferSizeHasOverflow(parsed_options))
665 return; 678 return;
666 679
667 bool is_premultiply_alpha_reverted = false; 680 bool is_premultiply_alpha_reverted = false;
668 if (!parsed_options.premultiply_alpha) { 681 if (!parsed_options.premultiply_alpha) {
669 parsed_options.premultiply_alpha = true; 682 parsed_options.premultiply_alpha = true;
670 is_premultiply_alpha_reverted = true; 683 is_premultiply_alpha_reverted = true;
671 } 684 }
672 image_ = CropImageAndApplyColorSpaceConversion( 685 image_ = CropImageAndApplyColorSpaceConversion(
673 input.Get(), parsed_options, kPremultiplyAlpha, 686 input.Get(), parsed_options, kPremultiplyAlpha,
674 ColorBehavior::TransformToGlobalTarget()); 687 ColorBehavior::TransformToGlobalTarget());
675 if (!image_) 688 if (!image_)
676 return; 689 return;
677 if (is_premultiply_alpha_reverted) { 690 if (is_premultiply_alpha_reverted) {
678 parsed_options.premultiply_alpha = false; 691 parsed_options.premultiply_alpha = false;
679 image_ = StaticBitmapImage::Create( 692 image_ = StaticBitmapImage::Create(PremulSkImageToUnPremul(
680 PremulSkImageToUnPremul(image_->ImageForCurrentFrame().get())); 693 image_->ImageForCurrentFrame().get(), parsed_options));
681 } 694 }
682 if (!image_) 695 if (!image_)
683 return; 696 return;
684 image_->SetOriginClean(offscreen_canvas->OriginClean()); 697 image_->SetOriginClean(offscreen_canvas->OriginClean());
685 image_->SetPremultiplied(parsed_options.premultiply_alpha); 698 image_->SetPremultiplied(parsed_options.premultiply_alpha);
686 } 699 }
687 700
688 ImageBitmap::ImageBitmap(const void* pixel_data, 701 ImageBitmap::ImageBitmap(const void* pixel_data,
689 uint32_t width, 702 uint32_t width,
690 uint32_t height, 703 uint32_t height,
691 bool is_image_bitmap_premultiplied, 704 bool is_image_bitmap_premultiplied,
692 bool is_image_bitmap_origin_clean) { 705 bool is_image_bitmap_origin_clean) {
706 LOG(ERROR) << "Entering...";
693 SkImageInfo info = SkImageInfo::MakeN32(width, height, 707 SkImageInfo info = SkImageInfo::MakeN32(width, height,
694 is_image_bitmap_premultiplied 708 is_image_bitmap_premultiplied
695 ? kPremul_SkAlphaType 709 ? kPremul_SkAlphaType
696 : kUnpremul_SkAlphaType); 710 : kUnpremul_SkAlphaType);
697 SkPixmap pixmap(info, pixel_data, info.bytesPerPixel() * width); 711 SkPixmap pixmap(info, pixel_data, info.bytesPerPixel() * width);
698 image_ = StaticBitmapImage::Create(SkImage::MakeRasterCopy(pixmap)); 712 image_ = StaticBitmapImage::Create(SkImage::MakeRasterCopy(pixmap));
699 if (!image_) 713 if (!image_)
700 return; 714 return;
701 image_->SetPremultiplied(is_image_bitmap_premultiplied); 715 image_->SetPremultiplied(is_image_bitmap_premultiplied);
702 image_->SetOriginClean(is_image_bitmap_origin_clean); 716 image_->SetOriginClean(is_image_bitmap_origin_clean);
703 } 717 }
704 718
705 static sk_sp<SkImage> ScaleSkImage(sk_sp<SkImage> sk_image, 719 static sk_sp<SkImage> ScaleSkImage(sk_sp<SkImage> sk_image,
720 const SkImageInfo& sk_image_info,
706 unsigned resize_width, 721 unsigned resize_width,
707 unsigned resize_height, 722 unsigned resize_height,
708 SkFilterQuality resize_quality, 723 SkFilterQuality resize_quality) {
709 SkColorType color_type = kN32_SkColorType, 724 SkImageInfo resized_info = sk_image_info.makeWH(resize_width, resize_height);
710 sk_sp<SkColorSpace> color_space = nullptr) {
711 SkImageInfo resized_info =
712 SkImageInfo::Make(resize_width, resize_height, color_type,
713 kUnpremul_SkAlphaType, color_space);
714 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull( 725 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull(
715 resize_width * resize_height, resized_info.bytesPerPixel()); 726 resize_width * resize_height, resized_info.bytesPerPixel());
716 if (!dst_buffer) 727 if (!dst_buffer)
717 return nullptr; 728 return nullptr;
718 729
719 if (color_type == kN32_SkColorType) { 730 RefPtr<Uint8Array> resized_pixels =
720 RefPtr<Uint8Array> resized_pixels = 731 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
721 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
722 SkPixmap pixmap(
723 resized_info, resized_pixels->Data(),
724 static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel());
725 sk_image->scalePixels(pixmap, resize_quality);
726 return SkImage::MakeFromRaster(pixmap,
727 [](const void*, void* pixels) {
728 static_cast<Uint8Array*>(pixels)->Deref();
729 },
730 resized_pixels.LeakRef());
731 }
732
733 RefPtr<Float32Array> resized_pixels =
734 Float32Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
735 SkPixmap pixmap( 732 SkPixmap pixmap(
736 resized_info, resized_pixels->Data(), 733 resized_info, resized_pixels->Data(),
737 static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel()); 734 static_cast<unsigned>(resize_width) * resized_info.bytesPerPixel());
738 sk_image->scalePixels(pixmap, resize_quality); 735 sk_image->scalePixels(pixmap, resize_quality);
739 return SkImage::MakeFromRaster(pixmap, 736 return SkImage::MakeFromRaster(pixmap,
740 [](const void*, void* pixels) { 737 [](const void*, void* pixels) {
741 static_cast<Float32Array*>(pixels)->Deref(); 738 static_cast<Uint8Array*>(pixels)->Deref();
742 }, 739 },
743 resized_pixels.LeakRef()); 740 resized_pixels.LeakRef());
744 } 741 }
745 742
743 static void SwizzleImageData(ImageData* data, bool needs_swizzle) {
744 needs_swizzle = false;
745 if (data && needs_swizzle) {
746 SkSwapRB(reinterpret_cast<uint32_t*>(data->data()->Data()),
747 reinterpret_cast<uint32_t*>(data->data()->Data()),
748 data->Size().Height() * data->Size().Width());
749 }
750 }
751
746 ImageBitmap::ImageBitmap(ImageData* data, 752 ImageBitmap::ImageBitmap(ImageData* data,
747 Optional<IntRect> crop_rect, 753 Optional<IntRect> crop_rect,
748 const ImageBitmapOptions& options) { 754 const ImageBitmapOptions& options) {
749 // TODO(xidachen): implement the resize option 755 LOG(ERROR) << "Entering...";
750 IntRect data_src_rect = IntRect(IntPoint(), data->Size());
751 ParsedOptions parsed_options = 756 ParsedOptions parsed_options =
752 ParseOptions(options, crop_rect, data->BitmapSourceSize()); 757 ParseOptions(options, crop_rect, data->BitmapSourceSize());
753 if (DstBufferSizeHasOverflow(parsed_options)) 758 if (DstBufferSizeHasOverflow(parsed_options))
754 return; 759 return;
760
761 IntRect data_src_rect = IntRect(IntPoint(), data->Size());
755 IntRect src_rect = crop_rect 762 IntRect src_rect = crop_rect
756 ? Intersection(parsed_options.crop_rect, data_src_rect) 763 ? Intersection(parsed_options.crop_rect, data_src_rect)
757 : data_src_rect; 764 : data_src_rect;
765 SkImageInfo unpremul_info = SkImageInfo::Make(
766 src_rect.Width(), src_rect.Height(),
767 parsed_options.color_params.GetSkColorType(), kUnpremul_SkAlphaType,
768 parsed_options.color_params.GetSkColorSpaceForSkSurfaces());
769 // if src_rect is empty, create an empty image bitmap with the requested size
770 // and return
771 if (src_rect.IsEmpty()) {
772 SkImageInfo info = parsed_options.premultiply_alpha
773 ? unpremul_info.makeAlphaType(kPremul_SkAlphaType)
774 : unpremul_info;
775 if (parsed_options.should_scale_input) {
776 info = info.makeWH(parsed_options.resize_width,
777 parsed_options.resize_height);
778 } else if (crop_rect) {
779 info = info.makeWH(crop_rect->Width(), crop_rect->Height());
780 } else {
781 info = info.makeWH(data->Size().Width(), data->Size().Height());
782 }
783 unsigned bytes_per_row =
784 info.width() * parsed_options.color_params.BytesPerPixel();
785 std::unique_ptr<uint8_t[]> pixels(
786 new uint8_t[info.height() * bytes_per_row]);
787 memset(pixels.get(), 0, info.height() * bytes_per_row);
788 sk_sp<SkImage> sk_image =
789 SkImage::MakeRasterCopy(SkPixmap(info, pixels.get(), bytes_per_row));
790 image_ = StaticBitmapImage::Create(sk_image);
791 image_->SetPremultiplied(parsed_options.premultiply_alpha);
792 return;
793 }
794
795 // crop/flip the input and swizzle if needed. we swizzle back later if the
796 // input ImageData is swizzled here.
797 bool crop_or_flip = (src_rect != data_src_rect) || parsed_options.flip_y;
798 bool needs_swizzle =
799 parsed_options.color_params.GetSkColorType() == kBGRA_8888_SkColorType;
800 ImageData* cropped_data = data;
801 if (crop_or_flip)
802 cropped_data = data->CropRect(src_rect, parsed_options.flip_y);
803 SwizzleImageData(cropped_data, needs_swizzle);
804 unsigned bytes_per_row =
805 src_rect.Size().Width() * parsed_options.color_params.BytesPerPixel();
806 unsigned data_size = src_rect.Size().Height() * bytes_per_row;
807 // color convert the pixels if needed
808 unsigned char* color_corrected_pixels = cropped_data->data()->Data();
809 std::unique_ptr<uint8_t[]>* converted_pixels = nullptr;
810 if (!SkColorSpace::Equals(
811 cropped_data->GetCanvasColorParams()
812 .GetSkColorSpaceForSkSurfaces()
813 .get(),
814 parsed_options.color_params.GetSkColorSpaceForSkSurfaces().get()) ||
815 cropped_data->GetCanvasColorParams().GetSkColorType() ==
816 kRGBA_F16_SkColorType) {
817 converted_pixels = new std::unique_ptr<uint8_t[]>(new uint8_t[data_size]);
818 cropped_data->ImageDataInCanvasColorSettings(parsed_options.color_params,
819 *converted_pixels);
820 color_corrected_pixels = converted_pixels->get();
821 }
758 822
759 // treat non-premultiplyAlpha as a special case 823 // treat non-premultiplyAlpha as a special case
760 if (!parsed_options.premultiply_alpha) { 824 if (!parsed_options.premultiply_alpha) {
761 unsigned char* src_addr = data->data()->Data(); 825 SkImageInfo info = unpremul_info.makeColorType(kRGBA_8888_SkColorType);
826 sk_sp<SkImage> sk_image = SkImage::MakeRasterCopy(
827 SkPixmap(info, color_corrected_pixels, bytes_per_row));
762 828
763 // Using kN32 type, swizzle input if necessary.
764 SkImageInfo info = SkImageInfo::Make(
765 parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(),
766 kN32_SkColorType, kUnpremul_SkAlphaType, data->GetSkColorSpace());
767 unsigned bytes_per_pixel = static_cast<unsigned>(info.bytesPerPixel());
768 unsigned src_pixel_bytes_per_row = bytes_per_pixel * data->Size().Width();
769 unsigned dst_pixel_bytes_per_row =
770 bytes_per_pixel * parsed_options.crop_rect.Width();
771 sk_sp<SkImage> sk_image;
772 if (parsed_options.crop_rect == IntRect(IntPoint(), data->Size())) {
773 SwizzleImageData(src_addr, data->Size().Height(), src_pixel_bytes_per_row,
774 parsed_options.flip_y);
775 sk_image = SkImage::MakeRasterCopy(
776 SkPixmap(info, src_addr, dst_pixel_bytes_per_row));
777 // restore the original ImageData
778 SwizzleImageData(src_addr, data->Size().Height(), src_pixel_bytes_per_row,
779 parsed_options.flip_y);
780 } else {
781 RefPtr<ArrayBuffer> dst_buffer = ArrayBuffer::CreateOrNull(
782 static_cast<unsigned>(parsed_options.crop_rect.Height()) *
783 parsed_options.crop_rect.Width(),
784 bytes_per_pixel);
785 if (!dst_buffer)
786 return;
787 RefPtr<Uint8Array> copied_data_buffer =
788 Uint8Array::Create(dst_buffer, 0, dst_buffer->ByteLength());
789 if (!src_rect.IsEmpty()) {
790 IntPoint src_point = IntPoint(
791 (parsed_options.crop_rect.X() > 0) ? parsed_options.crop_rect.X()
792 : 0,
793 (parsed_options.crop_rect.Y() > 0) ? parsed_options.crop_rect.Y()
794 : 0);
795 IntPoint dst_point = IntPoint((parsed_options.crop_rect.X() >= 0)
796 ? 0
797 : -parsed_options.crop_rect.X(),
798 (parsed_options.crop_rect.Y() >= 0)
799 ? 0
800 : -parsed_options.crop_rect.Y());
801 int copy_height = data->Size().Height() - src_point.Y();
802 if (parsed_options.crop_rect.Height() < copy_height)
803 copy_height = parsed_options.crop_rect.Height();
804 int copy_width = data->Size().Width() - src_point.X();
805 if (parsed_options.crop_rect.Width() < copy_width)
806 copy_width = parsed_options.crop_rect.Width();
807 for (int i = 0; i < copy_height; i++) {
808 unsigned src_start_copy_position =
809 (i + src_point.Y()) * src_pixel_bytes_per_row +
810 src_point.X() * bytes_per_pixel;
811 unsigned src_end_copy_position =
812 src_start_copy_position + copy_width * bytes_per_pixel;
813 unsigned dst_start_copy_position;
814 if (parsed_options.flip_y)
815 dst_start_copy_position =
816 (parsed_options.crop_rect.Height() - 1 - dst_point.Y() - i) *
817 dst_pixel_bytes_per_row +
818 dst_point.X() * bytes_per_pixel;
819 else
820 dst_start_copy_position =
821 (dst_point.Y() + i) * dst_pixel_bytes_per_row +
822 dst_point.X() * bytes_per_pixel;
823 for (unsigned j = 0;
824 j < src_end_copy_position - src_start_copy_position; j++) {
825 // swizzle when necessary
826 if (kN32_SkColorType == kBGRA_8888_SkColorType) {
827 if (j % 4 == 0)
828 copied_data_buffer->Data()[dst_start_copy_position + j] =
829 src_addr[src_start_copy_position + j + 2];
830 else if (j % 4 == 2)
831 copied_data_buffer->Data()[dst_start_copy_position + j] =
832 src_addr[src_start_copy_position + j - 2];
833 else
834 copied_data_buffer->Data()[dst_start_copy_position + j] =
835 src_addr[src_start_copy_position + j];
836 } else {
837 copied_data_buffer->Data()[dst_start_copy_position + j] =
838 src_addr[src_start_copy_position + j];
839 }
840 }
841 }
842 }
843 sk_image = NewSkImageFromRaster(info, std::move(copied_data_buffer),
844 dst_pixel_bytes_per_row);
845 }
846 if (!sk_image)
847 return;
848 ApplyColorSpaceConversion(sk_image, parsed_options);
849 if (parsed_options.should_scale_input) { 829 if (parsed_options.should_scale_input) {
850 image_ = StaticBitmapImage::Create(ScaleSkImage( 830 image_ = StaticBitmapImage::Create(ScaleSkImage(
851 sk_image, parsed_options.resize_width, parsed_options.resize_height, 831 sk_image, info, parsed_options.resize_width,
852 parsed_options.resize_quality, 832 parsed_options.resize_height, parsed_options.resize_quality));
853 parsed_options.color_params.GetSkColorType(),
854 data->GetSkColorSpace()));
855 } else { 833 } else {
856 image_ = StaticBitmapImage::Create(sk_image); 834 image_ = StaticBitmapImage::Create(sk_image);
857 } 835 }
858 if (!image_) 836 if (!image_)
859 return; 837 return;
860 image_->SetPremultiplied(parsed_options.premultiply_alpha); 838 image_->SetPremultiplied(parsed_options.premultiply_alpha);
839 SwizzleImageData(cropped_data, needs_swizzle);
861 return; 840 return;
862 } 841 }
863 842
864 CanvasColorParams canvas_color_params; 843 IntSize buffer_size =
865 if (RuntimeEnabledFeatures::colorCanvasExtensionsEnabled()) { 844 src_rect.IsEmpty() ? parsed_options.crop_rect.Size() : src_rect.Size();
866 ImageDataColorSettings color_settings;
867 data->getColorSettings(color_settings);
868 CanvasColorSpace canvas_color_space =
869 ImageData::GetCanvasColorSpace(color_settings.colorSpace());
870 CanvasPixelFormat canvas_pixel_format = kRGBA8CanvasPixelFormat;
871 if (ImageData::GetImageDataStorageFormat(color_settings.storageFormat()) !=
872 kUint8ClampedArrayStorageFormat) {
873 canvas_pixel_format = kF16CanvasPixelFormat;
874 }
875 canvas_color_params =
876 CanvasColorParams(canvas_color_space, canvas_pixel_format);
877 }
878 std::unique_ptr<ImageBuffer> buffer = 845 std::unique_ptr<ImageBuffer> buffer =
879 ImageBuffer::Create(parsed_options.crop_rect.Size(), kNonOpaque, 846 ImageBuffer::Create(buffer_size, kNonOpaque, kDoNotInitializeImagePixels,
880 kDoNotInitializeImagePixels, canvas_color_params); 847 parsed_options.color_params);
881 if (!buffer) 848 if (!buffer)
882 return; 849 return;
883
884 if (src_rect.IsEmpty()) { 850 if (src_rect.IsEmpty()) {
885 image_ = StaticBitmapImage::Create(buffer->NewSkImageSnapshot( 851 image_ = StaticBitmapImage::Create(buffer->NewSkImageSnapshot(
886 kPreferNoAcceleration, kSnapshotReasonUnknown)); 852 kPreferNoAcceleration, kSnapshotReasonUnknown));
887 return; 853 return;
888 } 854 }
889 855
890 IntPoint dst_point = IntPoint(std::min(0, -parsed_options.crop_rect.X()), 856 buffer->PutByteArray(kUnmultiplied, color_corrected_pixels,
891 std::min(0, -parsed_options.crop_rect.Y())); 857 cropped_data->Size(),
892 if (parsed_options.crop_rect.X() < 0) 858 IntRect(IntPoint(), cropped_data->Size()), IntPoint());
893 dst_point.SetX(-parsed_options.crop_rect.X());
894 if (parsed_options.crop_rect.Y() < 0)
895 dst_point.SetY(-parsed_options.crop_rect.Y());
896 859
897 buffer->PutByteArray(kUnmultiplied, data->data()->Data(), data->Size(), 860 SwizzleImageData(cropped_data, needs_swizzle);
898 src_rect, dst_point);
899 sk_sp<SkImage> sk_image = 861 sk_sp<SkImage> sk_image =
900 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown); 862 buffer->NewSkImageSnapshot(kPreferNoAcceleration, kSnapshotReasonUnknown);
901 if (parsed_options.flip_y)
902 sk_image = FlipSkImageVertically(sk_image.get(), kEnforceAlphaPremultiply);
903 if (!sk_image) 863 if (!sk_image)
904 return; 864 return;
865
905 if (parsed_options.should_scale_input) { 866 if (parsed_options.should_scale_input) {
906 sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul( 867 sk_sp<SkSurface> surface = SkSurface::MakeRaster(SkImageInfo::MakeN32Premul(
907 parsed_options.resize_width, parsed_options.resize_height, 868 parsed_options.resize_width, parsed_options.resize_height,
908 data->GetSkColorSpace())); 869 data->GetCanvasColorParams().GetSkColorSpaceForSkSurfaces()));
909 if (!surface) 870 if (!surface)
910 return; 871 return;
911 SkPaint paint; 872 SkPaint paint;
912 paint.setFilterQuality(parsed_options.resize_quality); 873 paint.setFilterQuality(parsed_options.resize_quality);
913 SkRect dst_draw_rect = SkRect::MakeWH(parsed_options.resize_width, 874 SkRect dst_draw_rect = SkRect::MakeWH(parsed_options.resize_width,
914 parsed_options.resize_height); 875 parsed_options.resize_height);
915 surface->getCanvas()->drawImageRect(sk_image, dst_draw_rect, &paint); 876 surface->getCanvas()->drawImageRect(sk_image, dst_draw_rect, &paint);
916 sk_image = surface->makeImageSnapshot(); 877 sk_image = surface->makeImageSnapshot();
917 } 878 }
918 ApplyColorSpaceConversion(sk_image, parsed_options);
919 image_ = StaticBitmapImage::Create(std::move(sk_image)); 879 image_ = StaticBitmapImage::Create(std::move(sk_image));
920 } 880 }
921 881
922 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, 882 ImageBitmap::ImageBitmap(ImageBitmap* bitmap,
923 Optional<IntRect> crop_rect, 883 Optional<IntRect> crop_rect,
924 const ImageBitmapOptions& options) { 884 const ImageBitmapOptions& options) {
885 LOG(ERROR) << "Entering...";
925 RefPtr<Image> input = bitmap->BitmapImage(); 886 RefPtr<Image> input = bitmap->BitmapImage();
926 if (!input) 887 if (!input)
927 return; 888 return;
928 ParsedOptions parsed_options = 889 ParsedOptions parsed_options =
929 ParseOptions(options, crop_rect, input->Size()); 890 ParseOptions(options, crop_rect, input->Size());
930 if (DstBufferSizeHasOverflow(parsed_options)) 891 if (DstBufferSizeHasOverflow(parsed_options))
931 return; 892 return;
932 893
933 image_ = CropImageAndApplyColorSpaceConversion( 894 image_ = CropImageAndApplyColorSpaceConversion(
934 input.Get(), parsed_options, 895 input.Get(), parsed_options,
935 bitmap->IsPremultiplied() ? kPremultiplyAlpha : kDontPremultiplyAlpha, 896 bitmap->IsPremultiplied() ? kPremultiplyAlpha : kDontPremultiplyAlpha,
936 ColorBehavior::TransformToGlobalTarget()); 897 ColorBehavior::TransformToGlobalTarget());
937 if (!image_) 898 if (!image_)
938 return; 899 return;
939 image_->SetOriginClean(bitmap->OriginClean()); 900 image_->SetOriginClean(bitmap->OriginClean());
940 image_->SetPremultiplied(parsed_options.premultiply_alpha); 901 image_->SetPremultiplied(parsed_options.premultiply_alpha);
941 } 902 }
942 903
943 ImageBitmap::ImageBitmap(RefPtr<StaticBitmapImage> image, 904 ImageBitmap::ImageBitmap(RefPtr<StaticBitmapImage> image,
944 Optional<IntRect> crop_rect, 905 Optional<IntRect> crop_rect,
945 const ImageBitmapOptions& options) { 906 const ImageBitmapOptions& options) {
907 LOG(ERROR) << "Entering... ";
946 bool origin_clean = image->OriginClean(); 908 bool origin_clean = image->OriginClean();
947 ParsedOptions parsed_options = 909 ParsedOptions parsed_options =
948 ParseOptions(options, crop_rect, image->Size()); 910 ParseOptions(options, crop_rect, image->Size());
949 if (DstBufferSizeHasOverflow(parsed_options)) 911 if (DstBufferSizeHasOverflow(parsed_options))
950 return; 912 return;
951 913
914 LOG(ERROR) << "parsed_options.premultiply_alpha: "
915 << parsed_options.premultiply_alpha;
916 PrintSkImage(image.Get()->ImageForCurrentFrame());
917
952 image_ = CropImageAndApplyColorSpaceConversion( 918 image_ = CropImageAndApplyColorSpaceConversion(
953 image.Get(), parsed_options, kPremultiplyAlpha, 919 image.Get(), parsed_options, kPremultiplyAlpha,
954 ColorBehavior::TransformToGlobalTarget()); 920 ColorBehavior::TransformToGlobalTarget());
921 LOG(ERROR) << "HERE";
955 if (!image_) 922 if (!image_)
956 return; 923 return;
924 LOG(ERROR) << "HERE";
925
926 PrintSkImage(image_.Get()->ImageForCurrentFrame());
957 927
958 image_->SetOriginClean(origin_clean); 928 image_->SetOriginClean(origin_clean);
959 image_->SetPremultiplied(parsed_options.premultiply_alpha); 929 image_->SetPremultiplied(parsed_options.premultiply_alpha);
960 } 930 }
961 931
962 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) { 932 ImageBitmap::ImageBitmap(PassRefPtr<StaticBitmapImage> image) {
933 LOG(ERROR) << "Entering...";
963 image_ = std::move(image); 934 image_ = std::move(image);
964 } 935 }
965 936
966 PassRefPtr<StaticBitmapImage> ImageBitmap::Transfer() { 937 PassRefPtr<StaticBitmapImage> ImageBitmap::Transfer() {
967 DCHECK(!IsNeutered()); 938 DCHECK(!IsNeutered());
968 is_neutered_ = true; 939 is_neutered_ = true;
969 image_->Transfer(); 940 image_->Transfer();
970 return std::move(image_); 941 return std::move(image_);
971 } 942 }
972 943
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1037 is_neutered_ = true; 1008 is_neutered_ = true;
1038 } 1009 }
1039 1010
1040 // static 1011 // static
1041 ImageBitmap* ImageBitmap::Take(ScriptPromiseResolver*, sk_sp<SkImage> image) { 1012 ImageBitmap* ImageBitmap::Take(ScriptPromiseResolver*, sk_sp<SkImage> image) {
1042 return ImageBitmap::Create(StaticBitmapImage::Create(std::move(image))); 1013 return ImageBitmap::Create(StaticBitmapImage::Create(std::move(image)));
1043 } 1014 }
1044 1015
1045 PassRefPtr<Uint8Array> ImageBitmap::CopyBitmapData(AlphaDisposition alpha_op, 1016 PassRefPtr<Uint8Array> ImageBitmap::CopyBitmapData(AlphaDisposition alpha_op,
1046 DataColorFormat format) { 1017 DataColorFormat format) {
1018 LOG(ERROR) << "Entering...";
1047 SkImageInfo info = SkImageInfo::Make( 1019 SkImageInfo info = SkImageInfo::Make(
1048 width(), height(), 1020 width(), height(),
1049 (format == kRGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType, 1021 (format == kRGBAColorType) ? kRGBA_8888_SkColorType : kN32_SkColorType,
1050 (alpha_op == kPremultiplyAlpha) ? kPremul_SkAlphaType 1022 (alpha_op == kPremultiplyAlpha) ? kPremul_SkAlphaType
1051 : kUnpremul_SkAlphaType); 1023 : kUnpremul_SkAlphaType);
1052 RefPtr<Uint8Array> dst_pixels = 1024 RefPtr<Uint8Array> dst_pixels =
1053 CopySkImageData(image_->ImageForCurrentFrame().get(), info); 1025 CopySkImageData(image_->ImageForCurrentFrame().get(), info);
1054 return dst_pixels.Release(); 1026 return dst_pixels.Release();
1055 } 1027 }
1056 1028
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 return ScriptPromise(); 1065 return ScriptPromise();
1094 return ImageBitmapSource::FulfillImageBitmap( 1066 return ImageBitmapSource::FulfillImageBitmap(
1095 script_state, Create(this, crop_rect, options)); 1067 script_state, Create(this, crop_rect, options));
1096 } 1068 }
1097 1069
1098 PassRefPtr<Image> ImageBitmap::GetSourceImageForCanvas( 1070 PassRefPtr<Image> ImageBitmap::GetSourceImageForCanvas(
1099 SourceImageStatus* status, 1071 SourceImageStatus* status,
1100 AccelerationHint, 1072 AccelerationHint,
1101 SnapshotReason, 1073 SnapshotReason,
1102 const FloatSize&) { 1074 const FloatSize&) {
1075 LOG(ERROR) << "HERE too ...";
1103 *status = kNormalSourceImageStatus; 1076 *status = kNormalSourceImageStatus;
1104 if (!image_) 1077 if (!image_)
1105 return nullptr; 1078 return nullptr;
1106 if (image_->IsPremultiplied()) 1079 if (image_->IsPremultiplied())
1107 return image_; 1080 return image_;
1108 // Skia does not support drawing unpremul SkImage on SkCanvas. 1081 // Skia does not support drawing unpremul SkImage on SkCanvas.
1109 // Premultiply and return. 1082 // Premultiply and return.
1110 sk_sp<SkImage> premul_sk_image = 1083 sk_sp<SkImage> premul_sk_image =
1111 UnPremulSkImageToPremul(image_->ImageForCurrentFrame().get()); 1084 UnPremulSkImageToPremul(image_->ImageForCurrentFrame().get());
1112 return StaticBitmapImage::Create(premul_sk_image); 1085 return StaticBitmapImage::Create(premul_sk_image);
1113 } 1086 }
1114 1087
1115 void ImageBitmap::AdjustDrawRects(FloatRect* src_rect, 1088 void ImageBitmap::AdjustDrawRects(FloatRect* src_rect,
1116 FloatRect* dst_rect) const {} 1089 FloatRect* dst_rect) const {}
1117 1090
1118 FloatSize ImageBitmap::ElementSize(const FloatSize&) const { 1091 FloatSize ImageBitmap::ElementSize(const FloatSize&) const {
1119 return FloatSize(width(), height()); 1092 return FloatSize(width(), height());
1120 } 1093 }
1121 1094
1122 DEFINE_TRACE(ImageBitmap) {} 1095 DEFINE_TRACE(ImageBitmap) {}
1123 1096
1124 } // namespace blink 1097 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698