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

Side by Side Diff: src/images/SkImageDecoder_libjpeg.cpp

Issue 1836493002: Rename encoders to Sk*ImageEncoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 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
« no previous file with comments | « src/images/SkImageDecoder_ktx.cpp ('k') | src/images/SkImageDecoder_libpng.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2007 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8
9 #include "SkImageEncoder.h"
10 #include "SkJpegUtility.h"
11 #include "SkColorPriv.h"
12 #include "SkDither.h"
13 #include "SkStream.h"
14 #include "SkTemplates.h"
15 #include "SkTime.h"
16 #include "SkUtils.h"
17 #include "SkRTConf.h"
18 #include "SkRect.h"
19 #include "SkCanvas.h"
20
21
22 #include <stdio.h>
23 extern "C" {
24 #include "jpeglib.h"
25 #include "jerror.h"
26 }
27
28 // These enable timing code that report milliseconds for an encoding
29 //#define TIME_ENCODE
30
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
113 typedef void (*WriteScanline)(uint8_t* SK_RESTRICT dst,
114 const void* SK_RESTRICT src, int width,
115 const SkPMColor* SK_RESTRICT ctable);
116
117 static void Write_32_YUV(uint8_t* SK_RESTRICT dst,
118 const void* SK_RESTRICT srcRow, int width,
119 const SkPMColor*) {
120 const uint32_t* SK_RESTRICT src = (const uint32_t*)srcRow;
121 while (--width >= 0) {
122 #ifdef WE_CONVERT_TO_YUV
123 rgb2yuv_32(dst, *src++);
124 #else
125 uint32_t c = *src++;
126 dst[0] = SkGetPackedR32(c);
127 dst[1] = SkGetPackedG32(c);
128 dst[2] = SkGetPackedB32(c);
129 #endif
130 dst += 3;
131 }
132 }
133
134 static void Write_4444_YUV(uint8_t* SK_RESTRICT dst,
135 const void* SK_RESTRICT srcRow, int width,
136 const SkPMColor*) {
137 const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)srcRow;
138 while (--width >= 0) {
139 #ifdef WE_CONVERT_TO_YUV
140 rgb2yuv_4444(dst, *src++);
141 #else
142 SkPMColor16 c = *src++;
143 dst[0] = SkPacked4444ToR32(c);
144 dst[1] = SkPacked4444ToG32(c);
145 dst[2] = SkPacked4444ToB32(c);
146 #endif
147 dst += 3;
148 }
149 }
150
151 static void Write_16_YUV(uint8_t* SK_RESTRICT dst,
152 const void* SK_RESTRICT srcRow, int width,
153 const SkPMColor*) {
154 const uint16_t* SK_RESTRICT src = (const uint16_t*)srcRow;
155 while (--width >= 0) {
156 #ifdef WE_CONVERT_TO_YUV
157 rgb2yuv_16(dst, *src++);
158 #else
159 uint16_t c = *src++;
160 dst[0] = SkPacked16ToR32(c);
161 dst[1] = SkPacked16ToG32(c);
162 dst[2] = SkPacked16ToB32(c);
163 #endif
164 dst += 3;
165 }
166 }
167
168 static void Write_Index_YUV(uint8_t* SK_RESTRICT dst,
169 const void* SK_RESTRICT srcRow, int width,
170 const SkPMColor* SK_RESTRICT ctable) {
171 const uint8_t* SK_RESTRICT src = (const uint8_t*)srcRow;
172 while (--width >= 0) {
173 #ifdef WE_CONVERT_TO_YUV
174 rgb2yuv_32(dst, ctable[*src++]);
175 #else
176 uint32_t c = ctable[*src++];
177 dst[0] = SkGetPackedR32(c);
178 dst[1] = SkGetPackedG32(c);
179 dst[2] = SkGetPackedB32(c);
180 #endif
181 dst += 3;
182 }
183 }
184
185 static WriteScanline ChooseWriter(const SkBitmap& bm) {
186 switch (bm.colorType()) {
187 case kN32_SkColorType:
188 return Write_32_YUV;
189 case kRGB_565_SkColorType:
190 return Write_16_YUV;
191 case kARGB_4444_SkColorType:
192 return Write_4444_YUV;
193 case kIndex_8_SkColorType:
194 return Write_Index_YUV;
195 default:
196 return nullptr;
197 }
198 }
199
200 class SkJPEGImageEncoder : public SkImageEncoder {
201 protected:
202 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) {
203 #ifdef TIME_ENCODE
204 SkAutoTime atm("JPEG Encode");
205 #endif
206
207 SkAutoLockPixels alp(bm);
208 if (nullptr == bm.getPixels()) {
209 return false;
210 }
211
212 jpeg_compress_struct cinfo;
213 skjpeg_error_mgr sk_err;
214 skjpeg_destination_mgr sk_wstream(stream);
215
216 // allocate these before set call setjmp
217 SkAutoTMalloc<uint8_t> oneRow;
218
219 cinfo.err = jpeg_std_error(&sk_err);
220 sk_err.error_exit = skjpeg_error_exit;
221 if (setjmp(sk_err.fJmpBuf)) {
222 return false;
223 }
224
225 // Keep after setjmp or mark volatile.
226 const WriteScanline writer = ChooseWriter(bm);
227 if (nullptr == writer) {
228 return false;
229 }
230
231 jpeg_create_compress(&cinfo);
232 cinfo.dest = &sk_wstream;
233 cinfo.image_width = bm.width();
234 cinfo.image_height = bm.height();
235 cinfo.input_components = 3;
236 #ifdef WE_CONVERT_TO_YUV
237 cinfo.in_color_space = JCS_YCbCr;
238 #else
239 cinfo.in_color_space = JCS_RGB;
240 #endif
241 cinfo.input_gamma = 1;
242
243 jpeg_set_defaults(&cinfo);
244 cinfo.optimize_coding = TRUE;
245 jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
246 #ifdef DCT_IFAST_SUPPORTED
247 cinfo.dct_method = JDCT_IFAST;
248 #endif
249
250 jpeg_start_compress(&cinfo, TRUE);
251
252 const int width = bm.width();
253 uint8_t* oneRowP = oneRow.reset(width * 3);
254
255 const SkPMColor* colors = bm.getColorTable() ? bm.getColorTable()->readC olors() : nullptr;
256 const void* srcRow = bm.getPixels();
257
258 while (cinfo.next_scanline < cinfo.image_height) {
259 JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */
260
261 writer(oneRowP, srcRow, width, colors);
262 row_pointer[0] = oneRowP;
263 (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
264 srcRow = (const void*)((const char*)srcRow + bm.rowBytes());
265 }
266
267 jpeg_finish_compress(&cinfo);
268 jpeg_destroy_compress(&cinfo);
269
270 return true;
271 }
272 };
273
274 ///////////////////////////////////////////////////////////////////////////////
275 DEFINE_ENCODER_CREATOR(JPEGImageEncoder);
276 ///////////////////////////////////////////////////////////////////////////////
277
278 static SkImageEncoder* sk_libjpeg_efactory(SkImageEncoder::Type t) {
279 return (SkImageEncoder::kJPEG_Type == t) ? new SkJPEGImageEncoder : nullptr;
280 }
281
282 static SkImageEncoder_EncodeReg gEReg(sk_libjpeg_efactory);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_ktx.cpp ('k') | src/images/SkImageDecoder_libpng.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698