@@ -28,170 +28,72 @@ extern "C" {
2828// These enable timing code that report milliseconds for an encoding
2929// #define TIME_ENCODE
3030
31- // this enables our rgb->yuv code, which is faster than libjpeg on ARM
32- #define WE_CONVERT_TO_YUV
33-
34- // /////////////////////////////////////////////////////////////////////////////
35-
36- #include " SkColorPriv.h"
37-
38- // taken from jcolor.c in libjpeg
39- #if 0 // 16bit - precise but slow
40- #define CYR 19595 // 0.299
41- #define CYG 38470 // 0.587
42- #define CYB 7471 // 0.114
43-
44- #define CUR -11059 // -0.16874
45- #define CUG -21709 // -0.33126
46- #define CUB 32768 // 0.5
47-
48- #define CVR 32768 // 0.5
49- #define CVG -27439 // -0.41869
50- #define CVB -5329 // -0.08131
51-
52- #define CSHIFT 16
53- #else // 8bit - fast, slightly less precise
54- #define CYR 77 // 0.299
55- #define CYG 150 // 0.587
56- #define CYB 29 // 0.114
57-
58- #define CUR -43 // -0.16874
59- #define CUG -85 // -0.33126
60- #define CUB 128 // 0.5
61-
62- #define CVR 128 // 0.5
63- #define CVG -107 // -0.41869
64- #define CVB -21 // -0.08131
65-
66- #define CSHIFT 8
67- #endif
68-
69- static void rgb2yuv_32 (uint8_t dst[], SkPMColor c) {
70- int r = SkGetPackedR32 (c);
71- int g = SkGetPackedG32 (c);
72- int b = SkGetPackedB32 (c);
73-
74- int y = ( CYR*r + CYG*g + CYB*b ) >> CSHIFT;
75- int u = ( CUR*r + CUG*g + CUB*b ) >> CSHIFT;
76- int v = ( CVR*r + CVG*g + CVB*b ) >> CSHIFT;
77-
78- dst[0 ] = SkToU8 (y);
79- dst[1 ] = SkToU8 (u + 128 );
80- dst[2 ] = SkToU8 (v + 128 );
81- }
82-
83- static void rgb2yuv_4444 (uint8_t dst[], U16CPU c) {
84- int r = SkGetPackedR4444 (c);
85- int g = SkGetPackedG4444 (c);
86- int b = SkGetPackedB4444 (c);
87-
88- int y = ( CYR*r + CYG*g + CYB*b ) >> (CSHIFT - 4 );
89- int u = ( CUR*r + CUG*g + CUB*b ) >> (CSHIFT - 4 );
90- int v = ( CVR*r + CVG*g + CVB*b ) >> (CSHIFT - 4 );
91-
92- dst[0 ] = SkToU8 (y);
93- dst[1 ] = SkToU8 (u + 128 );
94- dst[2 ] = SkToU8 (v + 128 );
95- }
96-
97- static void rgb2yuv_16 (uint8_t dst[], U16CPU c) {
98- int r = SkGetPackedR16 (c);
99- int g = SkGetPackedG16 (c);
100- int b = SkGetPackedB16 (c);
101-
102- int y = ( 2 *CYR*r + CYG*g + 2 *CYB*b ) >> (CSHIFT - 2 );
103- int u = ( 2 *CUR*r + CUG*g + 2 *CUB*b ) >> (CSHIFT - 2 );
104- int v = ( 2 *CVR*r + CVG*g + 2 *CVB*b ) >> (CSHIFT - 2 );
105-
106- dst[0 ] = SkToU8 (y);
107- dst[1 ] = SkToU8 (u + 128 );
108- dst[2 ] = SkToU8 (v + 128 );
109- }
110-
111- // /////////////////////////////////////////////////////////////////////////////
112-
11331typedef void (*WriteScanline)(uint8_t * SK_RESTRICT dst,
11432 const void * SK_RESTRICT src, int width,
11533 const SkPMColor* SK_RESTRICT ctable);
11634
117- static void Write_32_YUV (uint8_t * SK_RESTRICT dst,
35+ static void Write_32_RGB (uint8_t * SK_RESTRICT dst,
11836 const void * SK_RESTRICT srcRow, int width,
11937 const SkPMColor*) {
12038 const uint32_t * SK_RESTRICT src = (const uint32_t *)srcRow;
12139 while (--width >= 0 ) {
122- #ifdef WE_CONVERT_TO_YUV
123- rgb2yuv_32 (dst, *src++);
124- #else
12540 uint32_t c = *src++;
12641 dst[0 ] = SkGetPackedR32 (c);
12742 dst[1 ] = SkGetPackedG32 (c);
12843 dst[2 ] = SkGetPackedB32 (c);
129- #endif
13044 dst += 3 ;
13145 }
13246}
13347
134- static void Write_4444_YUV (uint8_t * SK_RESTRICT dst,
48+ static void Write_4444_RGB (uint8_t * SK_RESTRICT dst,
13549 const void * SK_RESTRICT srcRow, int width,
13650 const SkPMColor*) {
13751 const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow;
13852 while (--width >= 0 ) {
139- #ifdef WE_CONVERT_TO_YUV
140- rgb2yuv_4444 (dst, *src++);
141- #else
14253 SkPMColor16 c = *src++;
14354 dst[0 ] = SkPacked4444ToR32 (c);
14455 dst[1 ] = SkPacked4444ToG32 (c);
14556 dst[2 ] = SkPacked4444ToB32 (c);
146- #endif
14757 dst += 3 ;
14858 }
14959}
15060
151- static void Write_16_YUV (uint8_t * SK_RESTRICT dst,
61+ static void Write_16_RGB (uint8_t * SK_RESTRICT dst,
15262 const void * SK_RESTRICT srcRow, int width,
15363 const SkPMColor*) {
15464 const uint16_t * SK_RESTRICT src = (const uint16_t *)srcRow;
15565 while (--width >= 0 ) {
156- #ifdef WE_CONVERT_TO_YUV
157- rgb2yuv_16 (dst, *src++);
158- #else
15966 uint16_t c = *src++;
16067 dst[0 ] = SkPacked16ToR32 (c);
16168 dst[1 ] = SkPacked16ToG32 (c);
16269 dst[2 ] = SkPacked16ToB32 (c);
163- #endif
16470 dst += 3 ;
16571 }
16672}
16773
168- static void Write_Index_YUV (uint8_t * SK_RESTRICT dst,
74+ static void Write_Index_RGB (uint8_t * SK_RESTRICT dst,
16975 const void * SK_RESTRICT srcRow, int width,
17076 const SkPMColor* SK_RESTRICT ctable) {
17177 const uint8_t * SK_RESTRICT src = (const uint8_t *)srcRow;
17278 while (--width >= 0 ) {
173- #ifdef WE_CONVERT_TO_YUV
174- rgb2yuv_32 (dst, ctable[*src++]);
175- #else
17679 uint32_t c = ctable[*src++];
17780 dst[0 ] = SkGetPackedR32 (c);
17881 dst[1 ] = SkGetPackedG32 (c);
17982 dst[2 ] = SkGetPackedB32 (c);
180- #endif
18183 dst += 3 ;
18284 }
18385}
18486
18587static WriteScanline ChooseWriter (const SkBitmap& bm) {
18688 switch (bm.colorType ()) {
18789 case kN32_SkColorType :
188- return Write_32_YUV ;
90+ return Write_32_RGB ;
18991 case kRGB_565_SkColorType :
190- return Write_16_YUV ;
92+ return Write_16_RGB ;
19193 case kARGB_4444_SkColorType :
192- return Write_4444_YUV ;
94+ return Write_4444_RGB ;
19395 case kIndex_8_SkColorType :
194- return Write_Index_YUV ;
96+ return Write_Index_RGB ;
19597 default :
19698 return nullptr ;
19799 }
@@ -233,19 +135,20 @@ class SkJPEGImageEncoder : public SkImageEncoder {
233135 cinfo.image_width = bm.width ();
234136 cinfo.image_height = bm.height ();
235137 cinfo.input_components = 3 ;
236- #ifdef WE_CONVERT_TO_YUV
237- cinfo.in_color_space = JCS_YCbCr;
238- #else
138+
139+ // FIXME: Can we take advantage of other in_color_spaces in libjpeg-turbo?
239140 cinfo.in_color_space = JCS_RGB;
240- #endif
141+
142+ // The gamma value is ignored by libjpeg-turbo.
241143 cinfo.input_gamma = 1 ;
242144
243145 jpeg_set_defaults (&cinfo);
146+
147+ // Tells libjpeg-turbo to compute optimal Huffman coding tables
148+ // for the image. This improves compression at the cost of
149+ // slower encode performance.
244150 cinfo.optimize_coding = TRUE ;
245151 jpeg_set_quality (&cinfo, quality, TRUE /* limit to baseline-JPEG values */ );
246- #ifdef DCT_IFAST_SUPPORTED
247- cinfo.dct_method = JDCT_IFAST;
248- #endif
249152
250153 jpeg_start_compress (&cinfo, TRUE );
251154
0 commit comments