diff options
Diffstat (limited to 'gfx/2d')
-rw-r--r-- | gfx/2d/image_operations.cpp | 25 | ||||
-rw-r--r-- | gfx/2d/ssse3-scaler.c | 16 | ||||
-rw-r--r-- | gfx/2d/ssse3-scaler.h | 4 |
3 files changed, 28 insertions, 17 deletions
diff --git a/gfx/2d/image_operations.cpp b/gfx/2d/image_operations.cpp index 62215f007..79fa879d9 100644 --- a/gfx/2d/image_operations.cpp +++ b/gfx/2d/image_operations.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2006-2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2018 Mark Straver BASc. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions @@ -107,7 +108,7 @@ void ComputeFilters(ImageOperations::ResizeMethod method, // Compute the unnormalized filter value at each location of the source // it covers. - float filter_sum = 0.0f; // Sub of the filter values for normalizing. + float filter_sum = 0.0f; // Sum of the filter values for normalizing. for (int cur_filter_pixel = src_begin; cur_filter_pixel <= src_end; cur_filter_pixel++) { // Distance from the center of the filter, this is the filter coordinate @@ -158,28 +159,22 @@ void ComputeFilters(ImageOperations::ResizeMethod method, ImageOperations::ResizeMethod ResizeMethodToAlgorithmMethod( ImageOperations::ResizeMethod method) { - // Convert any "Quality Method" into an "Algorithm Method" + // If we already have an "Algorithm Method", just return that. if (method >= ImageOperations::RESIZE_FIRST_ALGORITHM_METHOD && method <= ImageOperations::RESIZE_LAST_ALGORITHM_METHOD) { return method; } - // The call to ImageOperationsGtv::Resize() above took care of - // GPU-acceleration in the cases where it is possible. So now we just - // pick the appropriate software method for each resize quality. + // Convert any "Quality Method" into an "Algorithm Method" switch (method) { - // Users of RESIZE_GOOD are willing to trade a lot of quality to - // get speed, allowing the use of linear resampling to get hardware - // acceleration (SRB). Hence any of our "good" software filters - // will be acceptable, and we use the fastest one, Hamming-1. case ImageOperations::RESIZE_GOOD: - // Users of RESIZE_BETTER are willing to trade some quality in order - // to improve performance, but are guaranteed not to devolve to a linear - // resampling. In visual tests we see that Hamming-1 is not as good as - // Lanczos-2, however it is about 40% faster and Lanczos-2 itself is + // Users of RESIZE_GOOD are willing to trade quality to get speed. + // In visual tests we see that Hamming-1 is not as good as + // Lanczos-2, however it is about 40% faster, and Lanczos-2 itself is // about 30% faster than Lanczos-3. The use of Hamming-1 has been deemed - // an acceptable trade-off between quality and speed. + // an unacceptable trade-off between quality and speed due to the limited + // pixel space it operates in, so we pick Lanczos-2 here. case ImageOperations::RESIZE_BETTER: - return ImageOperations::RESIZE_HAMMING1; + return ImageOperations::RESIZE_LANCZOS2; default: return ImageOperations::RESIZE_LANCZOS3; } diff --git a/gfx/2d/ssse3-scaler.c b/gfx/2d/ssse3-scaler.c index 345844b84..745f58f6f 100644 --- a/gfx/2d/ssse3-scaler.c +++ b/gfx/2d/ssse3-scaler.c @@ -37,6 +37,7 @@ #include <tmmintrin.h> #include <stdint.h> #include <assert.h> +#include "ssse3-scaler.h" typedef int32_t pixman_fixed_16_16_t; typedef pixman_fixed_16_16_t pixman_fixed_t; @@ -44,6 +45,8 @@ typedef pixman_fixed_16_16_t pixman_fixed_t; #define pixman_fixed_to_int(f) ((int) ((f) >> 16)) #define pixman_int_to_fixed(i) ((pixman_fixed_t) ((i) << 16)) #define pixman_double_to_fixed(d) ((pixman_fixed_t) ((d) * 65536.0)) +#define PIXMAN_FIXED_INT_MAX 32767 +#define PIXMAN_FIXED_INT_MIN -32768 typedef struct pixman_vector pixman_vector_t; typedef int pixman_bool_t; @@ -463,6 +466,12 @@ ssse3_bilinear_cover_iter_init (pixman_iter_t *iter) bilinear_info_t *info; pixman_vector_t v; + if (iter->x > PIXMAN_FIXED_INT_MAX || + iter->x < PIXMAN_FIXED_INT_MIN || + iter->y > PIXMAN_FIXED_INT_MAX || + iter->y < PIXMAN_FIXED_INT_MIN) + goto fail; + /* Reference point is the center of the pixel */ v.vector[0] = pixman_int_to_fixed (iter->x) + pixman_fixed_1 / 2; v.vector[1] = pixman_int_to_fixed (iter->y) + pixman_fixed_1 / 2; @@ -505,7 +514,7 @@ fail: /* scale the src from src_width/height to dest_width/height drawn * into the rectangle x,y width,height * src_stride and dst_stride are 4 byte units */ -void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride, +bool ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride, uint32_t *dest, int dest_width, int dest_height, int dest_stride, int x, int y, @@ -551,6 +560,10 @@ void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stri iter.data = NULL; ssse3_bilinear_cover_iter_init(&iter); + + if (!iter.fini) + return false; + if (iter.data) { for (int iy = 0; iy < height; iy++) { ssse3_fetch_bilinear_cover(&iter, NULL); @@ -558,4 +571,5 @@ void ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stri } ssse3_bilinear_cover_iter_fini(&iter); } + return true; } diff --git a/gfx/2d/ssse3-scaler.h b/gfx/2d/ssse3-scaler.h index b3b53ed64..ea8d8a066 100644 --- a/gfx/2d/ssse3-scaler.h +++ b/gfx/2d/ssse3-scaler.h @@ -6,10 +6,12 @@ #ifndef MOZILLA_GFX_2D_SSSE3_SCALER_H_ #define MOZILLA_GFX_2D_SSSE3_SCALER_H_ +#include <stdbool.h> + #ifdef __cplusplus extern "C" { #endif -void ssse3_scale_data(uint32_t *src, int src_width, int src_height, +bool ssse3_scale_data(uint32_t *src, int src_width, int src_height, int src_stride, uint32_t *dest, int dest_width, int dest_height, int dest_rowstride, |