aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images
diff options
context:
space:
mode:
authorGravatar msarett <msarett@google.com>2016-04-18 14:21:55 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-04-18 14:21:55 -0700
commitc7d01d3e1d3621907c27b283fb7f8b6e177c629d (patch)
tree4f75460495716877754337d3a476b52cce1e262d /src/images
parentb4b83dc4dff8b117fe535656c7d994cac3a9329b (diff)
Use libjpeg-turbo for YUV->RGB conversion in jpeg encoder
This remove the previous codepath, which performed a less accurate conversion to YUV. It actually faster to use the more accurate conversion, now that we have updated to libjpeg-turbo. z620 Performance Speed-Up: mandrill.jpg (512x512): 1.13x color_wheel.jpg (128x128): 1.12x This should fix: https://buganizer.corp.google.com/u/0/issues/28161384 https://buganizer.corp.google.com/u/0/issues/21891795 BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1886183002 Review URL: https://codereview.chromium.org/1886183002
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkJPEGImageEncoder.cpp129
1 files changed, 16 insertions, 113 deletions
diff --git a/src/images/SkJPEGImageEncoder.cpp b/src/images/SkJPEGImageEncoder.cpp
index e3e7600ade..1051aec205 100644
--- a/src/images/SkJPEGImageEncoder.cpp
+++ b/src/images/SkJPEGImageEncoder.cpp
@@ -28,156 +28,58 @@ extern "C" {
// These enable timing code that report milliseconds for an encoding
//#define TIME_ENCODE
-// this enables our rgb->yuv code, which is faster than libjpeg on ARM
-#define WE_CONVERT_TO_YUV
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkColorPriv.h"
-
-// taken from jcolor.c in libjpeg
-#if 0 // 16bit - precise but slow
- #define CYR 19595 // 0.299
- #define CYG 38470 // 0.587
- #define CYB 7471 // 0.114
-
- #define CUR -11059 // -0.16874
- #define CUG -21709 // -0.33126
- #define CUB 32768 // 0.5
-
- #define CVR 32768 // 0.5
- #define CVG -27439 // -0.41869
- #define CVB -5329 // -0.08131
-
- #define CSHIFT 16
-#else // 8bit - fast, slightly less precise
- #define CYR 77 // 0.299
- #define CYG 150 // 0.587
- #define CYB 29 // 0.114
-
- #define CUR -43 // -0.16874
- #define CUG -85 // -0.33126
- #define CUB 128 // 0.5
-
- #define CVR 128 // 0.5
- #define CVG -107 // -0.41869
- #define CVB -21 // -0.08131
-
- #define CSHIFT 8
-#endif
-
-static void rgb2yuv_32(uint8_t dst[], SkPMColor c) {
- int r = SkGetPackedR32(c);
- int g = SkGetPackedG32(c);
- int b = SkGetPackedB32(c);
-
- int y = ( CYR*r + CYG*g + CYB*b ) >> CSHIFT;
- int u = ( CUR*r + CUG*g + CUB*b ) >> CSHIFT;
- int v = ( CVR*r + CVG*g + CVB*b ) >> CSHIFT;
-
- dst[0] = SkToU8(y);
- dst[1] = SkToU8(u + 128);
- dst[2] = SkToU8(v + 128);
-}
-
-static void rgb2yuv_4444(uint8_t dst[], U16CPU c) {
- int r = SkGetPackedR4444(c);
- int g = SkGetPackedG4444(c);
- int b = SkGetPackedB4444(c);
-
- int y = ( CYR*r + CYG*g + CYB*b ) >> (CSHIFT - 4);
- int u = ( CUR*r + CUG*g + CUB*b ) >> (CSHIFT - 4);
- int v = ( CVR*r + CVG*g + CVB*b ) >> (CSHIFT - 4);
-
- dst[0] = SkToU8(y);
- dst[1] = SkToU8(u + 128);
- dst[2] = SkToU8(v + 128);
-}
-
-static void rgb2yuv_16(uint8_t dst[], U16CPU c) {
- int r = SkGetPackedR16(c);
- int g = SkGetPackedG16(c);
- int b = SkGetPackedB16(c);
-
- int y = ( 2*CYR*r + CYG*g + 2*CYB*b ) >> (CSHIFT - 2);
- int u = ( 2*CUR*r + CUG*g + 2*CUB*b ) >> (CSHIFT - 2);
- int v = ( 2*CVR*r + CVG*g + 2*CVB*b ) >> (CSHIFT - 2);
-
- dst[0] = SkToU8(y);
- dst[1] = SkToU8(u + 128);
- dst[2] = SkToU8(v + 128);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
typedef void (*WriteScanline)(uint8_t* SK_RESTRICT dst,
const void* SK_RESTRICT src, int width,
const SkPMColor* SK_RESTRICT ctable);
-static void Write_32_YUV(uint8_t* SK_RESTRICT dst,
+static void Write_32_RGB(uint8_t* SK_RESTRICT dst,
const void* SK_RESTRICT srcRow, int width,
const SkPMColor*) {
const uint32_t* SK_RESTRICT src = (const uint32_t*)srcRow;
while (--width >= 0) {
-#ifdef WE_CONVERT_TO_YUV
- rgb2yuv_32(dst, *src++);
-#else
uint32_t c = *src++;
dst[0] = SkGetPackedR32(c);
dst[1] = SkGetPackedG32(c);
dst[2] = SkGetPackedB32(c);
-#endif
dst += 3;
}
}
-static void Write_4444_YUV(uint8_t* SK_RESTRICT dst,
+static void Write_4444_RGB(uint8_t* SK_RESTRICT dst,
const void* SK_RESTRICT srcRow, int width,
const SkPMColor*) {
const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow;
while (--width >= 0) {
-#ifdef WE_CONVERT_TO_YUV
- rgb2yuv_4444(dst, *src++);
-#else
SkPMColor16 c = *src++;
dst[0] = SkPacked4444ToR32(c);
dst[1] = SkPacked4444ToG32(c);
dst[2] = SkPacked4444ToB32(c);
-#endif
dst += 3;
}
}
-static void Write_16_YUV(uint8_t* SK_RESTRICT dst,
+static void Write_16_RGB(uint8_t* SK_RESTRICT dst,
const void* SK_RESTRICT srcRow, int width,
const SkPMColor*) {
const uint16_t* SK_RESTRICT src = (const uint16_t*)srcRow;
while (--width >= 0) {
-#ifdef WE_CONVERT_TO_YUV
- rgb2yuv_16(dst, *src++);
-#else
uint16_t c = *src++;
dst[0] = SkPacked16ToR32(c);
dst[1] = SkPacked16ToG32(c);
dst[2] = SkPacked16ToB32(c);
-#endif
dst += 3;
}
}
-static void Write_Index_YUV(uint8_t* SK_RESTRICT dst,
+static void Write_Index_RGB(uint8_t* SK_RESTRICT dst,
const void* SK_RESTRICT srcRow, int width,
const SkPMColor* SK_RESTRICT ctable) {
const uint8_t* SK_RESTRICT src = (const uint8_t*)srcRow;
while (--width >= 0) {
-#ifdef WE_CONVERT_TO_YUV
- rgb2yuv_32(dst, ctable[*src++]);
-#else
uint32_t c = ctable[*src++];
dst[0] = SkGetPackedR32(c);
dst[1] = SkGetPackedG32(c);
dst[2] = SkGetPackedB32(c);
-#endif
dst += 3;
}
}
@@ -185,13 +87,13 @@ static void Write_Index_YUV(uint8_t* SK_RESTRICT dst,
static WriteScanline ChooseWriter(const SkBitmap& bm) {
switch (bm.colorType()) {
case kN32_SkColorType:
- return Write_32_YUV;
+ return Write_32_RGB;
case kRGB_565_SkColorType:
- return Write_16_YUV;
+ return Write_16_RGB;
case kARGB_4444_SkColorType:
- return Write_4444_YUV;
+ return Write_4444_RGB;
case kIndex_8_SkColorType:
- return Write_Index_YUV;
+ return Write_Index_RGB;
default:
return nullptr;
}
@@ -233,19 +135,20 @@ protected:
cinfo.image_width = bm.width();
cinfo.image_height = bm.height();
cinfo.input_components = 3;
-#ifdef WE_CONVERT_TO_YUV
- cinfo.in_color_space = JCS_YCbCr;
-#else
+
+ // FIXME: Can we take advantage of other in_color_spaces in libjpeg-turbo?
cinfo.in_color_space = JCS_RGB;
-#endif
+
+ // The gamma value is ignored by libjpeg-turbo.
cinfo.input_gamma = 1;
jpeg_set_defaults(&cinfo);
+
+ // Tells libjpeg-turbo to compute optimal Huffman coding tables
+ // for the image. This improves compression at the cost of
+ // slower encode performance.
cinfo.optimize_coding = TRUE;
jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
-#ifdef DCT_IFAST_SUPPORTED
- cinfo.dct_method = JDCT_IFAST;
-#endif
jpeg_start_compress(&cinfo, TRUE);