- add sources.
[platform/framework/web/crosswalk.git] / src / ui / gfx / codec / jpeg_codec.cc
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/gfx/codec/jpeg_codec.h"
6
7 #include <setjmp.h>
8
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "third_party/skia/include/core/SkBitmap.h"
12 #include "third_party/skia/include/core/SkColorPriv.h"
13
14 extern "C" {
15 #if defined(USE_SYSTEM_LIBJPEG)
16 #include <jpeglib.h>
17 #elif defined(USE_LIBJPEG_TURBO)
18 #include "third_party/libjpeg_turbo/jpeglib.h"
19 #else
20 #include "third_party/libjpeg/jpeglib.h"
21 #endif
22 }
23
24 namespace gfx {
25
26 // Encoder/decoder shared stuff ------------------------------------------------
27
28 namespace {
29
30 // used to pass error info through the JPEG library
31 struct CoderErrorMgr {
32   jpeg_error_mgr pub;
33   jmp_buf setjmp_buffer;
34 };
35
36 void ErrorExit(jpeg_common_struct* cinfo) {
37   CoderErrorMgr *err = reinterpret_cast<CoderErrorMgr*>(cinfo->err);
38
39   // Return control to the setjmp point.
40   longjmp(err->setjmp_buffer, false);
41 }
42
43 }  // namespace
44
45 // This method helps identify at run time which library chromium is using.
46 JPEGCodec::LibraryVariant JPEGCodec::JpegLibraryVariant() {
47 #if defined(USE_SYSTEM_LIBJPEG)
48   return SYSTEM_LIBJPEG;
49 #elif defined(USE_LIBJPEG_TURBO)
50   return LIBJPEG_TURBO;
51 #else
52   return IJG_LIBJPEG;
53 #endif
54 }
55
56 // Encoder ---------------------------------------------------------------------
57 //
58 // This code is based on nsJPEGEncoder from Mozilla.
59 // Copyright 2005 Google Inc. (Brett Wilson, contributor)
60
61 namespace {
62
63 // Initial size for the output buffer in the JpegEncoderState below.
64 static const int initial_output_buffer_size = 8192;
65
66 struct JpegEncoderState {
67   explicit JpegEncoderState(std::vector<unsigned char>* o)
68       : out(o),
69         image_buffer_used(0) {
70   }
71
72   // Output buffer, of which 'image_buffer_used' bytes are actually used (this
73   // will often be less than the actual size of the vector because we size it
74   // so that libjpeg can write directly into it.
75   std::vector<unsigned char>* out;
76
77   // Number of bytes in the 'out' buffer that are actually used (see above).
78   size_t image_buffer_used;
79 };
80
81 // Initializes the JpegEncoderState for encoding, and tells libjpeg about where
82 // the output buffer is.
83 //
84 // From the JPEG library:
85 //  "Initialize destination. This is called by jpeg_start_compress() before
86 //   any data is actually written. It must initialize next_output_byte and
87 //   free_in_buffer. free_in_buffer must be initialized to a positive value."
88 void InitDestination(jpeg_compress_struct* cinfo) {
89   JpegEncoderState* state = static_cast<JpegEncoderState*>(cinfo->client_data);
90   DCHECK(state->image_buffer_used == 0) << "initializing after use";
91
92   state->out->resize(initial_output_buffer_size);
93   state->image_buffer_used = 0;
94
95   cinfo->dest->next_output_byte = &(*state->out)[0];
96   cinfo->dest->free_in_buffer = initial_output_buffer_size;
97 }
98
99 // Resize the buffer that we give to libjpeg and update our and its state.
100 //
101 // From the JPEG library:
102 //  "Callback used by libjpeg whenever the buffer has filled (free_in_buffer
103 //   reaches zero). In typical applications, it should write out the *entire*
104 //   buffer (use the saved start address and buffer length; ignore the current
105 //   state of next_output_byte and free_in_buffer). Then reset the pointer &
106 //   count to the start of the buffer, and return TRUE indicating that the
107 //   buffer has been dumped. free_in_buffer must be set to a positive value
108 //   when TRUE is returned. A FALSE return should only be used when I/O
109 //   suspension is desired (this operating mode is discussed in the next
110 //   section)."
111 boolean EmptyOutputBuffer(jpeg_compress_struct* cinfo) {
112   JpegEncoderState* state = static_cast<JpegEncoderState*>(cinfo->client_data);
113
114   // note the new size, the buffer is full
115   state->image_buffer_used = state->out->size();
116
117   // expand buffer, just double size each time
118   state->out->resize(state->out->size() * 2);
119
120   // tell libjpeg where to write the next data
121   cinfo->dest->next_output_byte = &(*state->out)[state->image_buffer_used];
122   cinfo->dest->free_in_buffer = state->out->size() - state->image_buffer_used;
123   return 1;
124 }
125
126 // Cleans up the JpegEncoderState to prepare for returning in the final form.
127 //
128 // From the JPEG library:
129 //  "Terminate destination --- called by jpeg_finish_compress() after all data
130 //   has been written. In most applications, this must flush any data
131 //   remaining in the buffer. Use either next_output_byte or free_in_buffer to
132 //   determine how much data is in the buffer."
133 void TermDestination(jpeg_compress_struct* cinfo) {
134   JpegEncoderState* state = static_cast<JpegEncoderState*>(cinfo->client_data);
135   DCHECK(state->out->size() >= state->image_buffer_used);
136
137   // update the used byte based on the next byte libjpeg would write to
138   state->image_buffer_used = cinfo->dest->next_output_byte - &(*state->out)[0];
139   DCHECK(state->image_buffer_used < state->out->size()) <<
140     "JPEG library busted, got a bad image buffer size";
141
142   // update our buffer so that it exactly encompases the desired data
143   state->out->resize(state->image_buffer_used);
144 }
145
146 #if !defined(JCS_EXTENSIONS)
147 // Converts RGBA to RGB (removing the alpha values) to prepare to send data to
148 // libjpeg. This converts one row of data in rgba with the given width in
149 // pixels the the given rgb destination buffer (which should have enough space
150 // reserved for the final data).
151 void StripAlpha(const unsigned char* rgba, int pixel_width, unsigned char* rgb)
152 {
153   for (int x = 0; x < pixel_width; x++) {
154     const unsigned char* pixel_in = &rgba[x * 4];
155     unsigned char* pixel_out = &rgb[x * 3];
156     pixel_out[0] = pixel_in[0];
157     pixel_out[1] = pixel_in[1];
158     pixel_out[2] = pixel_in[2];
159   }
160 }
161
162 // Converts BGRA to RGB by reordering the color components and dropping the
163 // alpha. This converts  one row of data in rgba with the given width in
164 // pixels the the given rgb destination buffer (which should have enough space
165 // reserved for the final data).
166 void BGRAtoRGB(const unsigned char* bgra, int pixel_width, unsigned char* rgb)
167 {
168   for (int x = 0; x < pixel_width; x++) {
169     const unsigned char* pixel_in = &bgra[x * 4];
170     unsigned char* pixel_out = &rgb[x * 3];
171     pixel_out[0] = pixel_in[2];
172     pixel_out[1] = pixel_in[1];
173     pixel_out[2] = pixel_in[0];
174   }
175 }
176 #endif  // !defined(JCS_EXTENSIONS)
177
178 // This class destroys the given jpeg_compress object when it goes out of
179 // scope. It simplifies the error handling in Encode (and even applies to the
180 // success case).
181 class CompressDestroyer {
182  public:
183   CompressDestroyer() : cinfo_(NULL) {
184   }
185   ~CompressDestroyer() {
186     DestroyManagedObject();
187   }
188   void SetManagedObject(jpeg_compress_struct* ci) {
189     DestroyManagedObject();
190     cinfo_ = ci;
191   }
192   void DestroyManagedObject() {
193     if (cinfo_) {
194       jpeg_destroy_compress(cinfo_);
195       cinfo_ = NULL;
196     }
197   }
198  private:
199   jpeg_compress_struct* cinfo_;
200 };
201
202 }  // namespace
203
204 bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format,
205                        int w, int h, int row_byte_width,
206                        int quality, std::vector<unsigned char>* output) {
207   jpeg_compress_struct cinfo;
208   CompressDestroyer destroyer;
209   destroyer.SetManagedObject(&cinfo);
210   output->clear();
211 #if !defined(JCS_EXTENSIONS)
212   unsigned char* row_buffer = NULL;
213 #endif
214
215   // We set up the normal JPEG error routines, then override error_exit.
216   // This must be done before the call to create_compress.
217   CoderErrorMgr errmgr;
218   cinfo.err = jpeg_std_error(&errmgr.pub);
219   errmgr.pub.error_exit = ErrorExit;
220
221   // Establish the setjmp return context for ErrorExit to use.
222   if (setjmp(errmgr.setjmp_buffer)) {
223     // If we get here, the JPEG code has signaled an error.
224     // MSDN notes: "if you intend your code to be portable, do not rely on
225     // correct destruction of frame-based objects when executing a nonlocal
226     // goto using a call to longjmp."  So we delete the CompressDestroyer's
227     // object manually instead.
228     destroyer.DestroyManagedObject();
229 #if !defined(JCS_EXTENSIONS)
230     delete[] row_buffer;
231 #endif
232     return false;
233   }
234
235   // The destroyer will destroy() cinfo on exit.
236   jpeg_create_compress(&cinfo);
237
238   cinfo.image_width = w;
239   cinfo.image_height = h;
240   cinfo.input_components = 3;
241 #ifdef JCS_EXTENSIONS
242   // Choose an input colorspace and return if it is an unsupported one. Since
243   // libjpeg-turbo supports all input formats used by Chromium (i.e. RGB, RGBA,
244   // and BGRA), we just map the input parameters to a colorspace used by
245   // libjpeg-turbo.
246   if (format == FORMAT_RGB) {
247     cinfo.input_components = 3;
248     cinfo.in_color_space = JCS_RGB;
249   } else if (format == FORMAT_RGBA ||
250              (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
251     cinfo.input_components = 4;
252     cinfo.in_color_space = JCS_EXT_RGBX;
253   } else if (format == FORMAT_BGRA ||
254              (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) {
255     cinfo.input_components = 4;
256     cinfo.in_color_space = JCS_EXT_BGRX;
257   } else {
258     // We can exit this function without calling jpeg_destroy_compress() because
259     // CompressDestroyer automaticaly calls it.
260     NOTREACHED() << "Invalid pixel format";
261     return false;
262   }
263 #else
264   cinfo.in_color_space = JCS_RGB;
265 #endif
266   cinfo.data_precision = 8;
267
268   jpeg_set_defaults(&cinfo);
269   jpeg_set_quality(&cinfo, quality, 1);  // quality here is 0-100
270
271   // set up the destination manager
272   jpeg_destination_mgr destmgr;
273   destmgr.init_destination = InitDestination;
274   destmgr.empty_output_buffer = EmptyOutputBuffer;
275   destmgr.term_destination = TermDestination;
276   cinfo.dest = &destmgr;
277
278   JpegEncoderState state(output);
279   cinfo.client_data = &state;
280
281   jpeg_start_compress(&cinfo, 1);
282
283   // feed it the rows, doing necessary conversions for the color format
284 #ifdef JCS_EXTENSIONS
285   // This function already returns when the input format is not supported by
286   // libjpeg-turbo and needs conversion. Therefore, we just encode lines without
287   // conversions.
288   while (cinfo.next_scanline < cinfo.image_height) {
289     const unsigned char* row = &input[cinfo.next_scanline * row_byte_width];
290     jpeg_write_scanlines(&cinfo, const_cast<unsigned char**>(&row), 1);
291   }
292 #else
293   if (format == FORMAT_RGB) {
294     // no conversion necessary
295     while (cinfo.next_scanline < cinfo.image_height) {
296       const unsigned char* row = &input[cinfo.next_scanline * row_byte_width];
297       jpeg_write_scanlines(&cinfo, const_cast<unsigned char**>(&row), 1);
298     }
299   } else {
300     // get the correct format converter
301     void (*converter)(const unsigned char* in, int w, unsigned char* rgb);
302     if (format == FORMAT_RGBA ||
303         (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
304       converter = StripAlpha;
305     } else if (format == FORMAT_BGRA ||
306                (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) {
307       converter = BGRAtoRGB;
308     } else {
309       NOTREACHED() << "Invalid pixel format";
310       return false;
311     }
312
313     // output row after converting
314     row_buffer = new unsigned char[w * 3];
315
316     while (cinfo.next_scanline < cinfo.image_height) {
317       converter(&input[cinfo.next_scanline * row_byte_width], w, row_buffer);
318       jpeg_write_scanlines(&cinfo, &row_buffer, 1);
319     }
320     delete[] row_buffer;
321   }
322 #endif
323
324   jpeg_finish_compress(&cinfo);
325   return true;
326 }
327
328 // Decoder --------------------------------------------------------------------
329
330 namespace {
331
332 struct JpegDecoderState {
333   JpegDecoderState(const unsigned char* in, size_t len)
334       : input_buffer(in), input_buffer_length(len) {
335   }
336
337   const unsigned char* input_buffer;
338   size_t input_buffer_length;
339 };
340
341 // Callback to initialize the source.
342 //
343 // From the JPEG library:
344 //  "Initialize source. This is called by jpeg_read_header() before any data is
345 //   actually read. May leave bytes_in_buffer set to 0 (in which case a
346 //   fill_input_buffer() call will occur immediately)."
347 void InitSource(j_decompress_ptr cinfo) {
348   JpegDecoderState* state = static_cast<JpegDecoderState*>(cinfo->client_data);
349   cinfo->src->next_input_byte = state->input_buffer;
350   cinfo->src->bytes_in_buffer = state->input_buffer_length;
351 }
352
353 // Callback to fill the buffer. Since our buffer already contains all the data,
354 // we should never need to provide more data. If libjpeg thinks it needs more
355 // data, our input is probably corrupt.
356 //
357 // From the JPEG library:
358 //  "This is called whenever bytes_in_buffer has reached zero and more data is
359 //   wanted. In typical applications, it should read fresh data into the buffer
360 //   (ignoring the current state of next_input_byte and bytes_in_buffer), reset
361 //   the pointer & count to the start of the buffer, and return TRUE indicating
362 //   that the buffer has been reloaded. It is not necessary to fill the buffer
363 //   entirely, only to obtain at least one more byte. bytes_in_buffer MUST be
364 //   set to a positive value if TRUE is returned. A FALSE return should only
365 //   be used when I/O suspension is desired."
366 boolean FillInputBuffer(j_decompress_ptr cinfo) {
367   return false;
368 }
369
370 // Skip data in the buffer. Since we have all the data at once, this operation
371 // is easy. It is not clear if this ever gets called because the JPEG library
372 // should be able to do the skip itself (it has all the data).
373 //
374 // From the JPEG library:
375 //  "Skip num_bytes worth of data. The buffer pointer and count should be
376 //   advanced over num_bytes input bytes, refilling the buffer as needed. This
377 //   is used to skip over a potentially large amount of uninteresting data
378 //   (such as an APPn marker). In some applications it may be possible to
379 //   optimize away the reading of the skipped data, but it's not clear that
380 //   being smart is worth much trouble; large skips are uncommon.
381 //   bytes_in_buffer may be zero on return. A zero or negative skip count
382 //   should be treated as a no-op."
383 void SkipInputData(j_decompress_ptr cinfo, long num_bytes) {
384   if (num_bytes > static_cast<long>(cinfo->src->bytes_in_buffer)) {
385     // Since all our data should be in the buffer, trying to skip beyond it
386     // means that there is some kind of error or corrupt input data. A 0 for
387     // bytes left means it will call FillInputBuffer which will then fail.
388     cinfo->src->next_input_byte += cinfo->src->bytes_in_buffer;
389     cinfo->src->bytes_in_buffer = 0;
390   } else if (num_bytes > 0) {
391     cinfo->src->bytes_in_buffer -= static_cast<size_t>(num_bytes);
392     cinfo->src->next_input_byte += num_bytes;
393   }
394 }
395
396 // Our source doesn't need any cleanup, so this is a NOP.
397 //
398 // From the JPEG library:
399 //  "Terminate source --- called by jpeg_finish_decompress() after all data has
400 //   been read to clean up JPEG source manager. NOT called by jpeg_abort() or
401 //   jpeg_destroy()."
402 void TermSource(j_decompress_ptr cinfo) {
403 }
404
405 #if !defined(JCS_EXTENSIONS)
406 // Converts one row of rgb data to rgba data by adding a fully-opaque alpha
407 // value.
408 void AddAlpha(const unsigned char* rgb, int pixel_width, unsigned char* rgba) {
409   for (int x = 0; x < pixel_width; x++) {
410     const unsigned char* pixel_in = &rgb[x * 3];
411     unsigned char* pixel_out = &rgba[x * 4];
412     pixel_out[0] = pixel_in[0];
413     pixel_out[1] = pixel_in[1];
414     pixel_out[2] = pixel_in[2];
415     pixel_out[3] = 0xff;
416   }
417 }
418
419 // Converts one row of RGB data to BGRA by reordering the color components and
420 // adding alpha values of 0xff.
421 void RGBtoBGRA(const unsigned char* bgra, int pixel_width, unsigned char* rgb)
422 {
423   for (int x = 0; x < pixel_width; x++) {
424     const unsigned char* pixel_in = &bgra[x * 3];
425     unsigned char* pixel_out = &rgb[x * 4];
426     pixel_out[0] = pixel_in[2];
427     pixel_out[1] = pixel_in[1];
428     pixel_out[2] = pixel_in[0];
429     pixel_out[3] = 0xff;
430   }
431 }
432 #endif  // !defined(JCS_EXTENSIONS)
433
434 // This class destroys the given jpeg_decompress object when it goes out of
435 // scope. It simplifies the error handling in Decode (and even applies to the
436 // success case).
437 class DecompressDestroyer {
438  public:
439   DecompressDestroyer() : cinfo_(NULL) {
440   }
441   ~DecompressDestroyer() {
442     DestroyManagedObject();
443   }
444   void SetManagedObject(jpeg_decompress_struct* ci) {
445     DestroyManagedObject();
446     cinfo_ = ci;
447   }
448   void DestroyManagedObject() {
449     if (cinfo_) {
450       jpeg_destroy_decompress(cinfo_);
451       cinfo_ = NULL;
452     }
453   }
454  private:
455   jpeg_decompress_struct* cinfo_;
456 };
457
458 }  // namespace
459
460 bool JPEGCodec::Decode(const unsigned char* input, size_t input_size,
461                        ColorFormat format, std::vector<unsigned char>* output,
462                        int* w, int* h) {
463   jpeg_decompress_struct cinfo;
464   DecompressDestroyer destroyer;
465   destroyer.SetManagedObject(&cinfo);
466   output->clear();
467
468   // We set up the normal JPEG error routines, then override error_exit.
469   // This must be done before the call to create_decompress.
470   CoderErrorMgr errmgr;
471   cinfo.err = jpeg_std_error(&errmgr.pub);
472   errmgr.pub.error_exit = ErrorExit;
473   // Establish the setjmp return context for ErrorExit to use.
474   if (setjmp(errmgr.setjmp_buffer)) {
475     // If we get here, the JPEG code has signaled an error.
476     // See note in JPEGCodec::Encode() for why we need to destroy the cinfo
477     // manually here.
478     destroyer.DestroyManagedObject();
479     return false;
480   }
481
482   // The destroyer will destroy() cinfo on exit.  We don't want to set the
483   // destroyer's object until cinfo is initialized.
484   jpeg_create_decompress(&cinfo);
485
486   // set up the source manager
487   jpeg_source_mgr srcmgr;
488   srcmgr.init_source = InitSource;
489   srcmgr.fill_input_buffer = FillInputBuffer;
490   srcmgr.skip_input_data = SkipInputData;
491   srcmgr.resync_to_restart = jpeg_resync_to_restart;  // use default routine
492   srcmgr.term_source = TermSource;
493   cinfo.src = &srcmgr;
494
495   JpegDecoderState state(input, input_size);
496   cinfo.client_data = &state;
497
498   // fill the file metadata into our buffer
499   if (jpeg_read_header(&cinfo, true) != JPEG_HEADER_OK)
500     return false;
501
502   // we want to always get RGB data out
503   switch (cinfo.jpeg_color_space) {
504     case JCS_GRAYSCALE:
505     case JCS_RGB:
506     case JCS_YCbCr:
507 #ifdef JCS_EXTENSIONS
508       // Choose an output colorspace and return if it is an unsupported one.
509       // Same as JPEGCodec::Encode(), libjpeg-turbo supports all input formats
510       // used by Chromium (i.e. RGB, RGBA, and BGRA) and we just map the input
511       // parameters to a colorspace.
512       if (format == FORMAT_RGB) {
513         cinfo.out_color_space = JCS_RGB;
514         cinfo.output_components = 3;
515       } else if (format == FORMAT_RGBA ||
516                  (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
517         cinfo.out_color_space = JCS_EXT_RGBX;
518         cinfo.output_components = 4;
519       } else if (format == FORMAT_BGRA ||
520                  (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) {
521         cinfo.out_color_space = JCS_EXT_BGRX;
522         cinfo.output_components = 4;
523       } else {
524         // We can exit this function without calling jpeg_destroy_decompress()
525         // because DecompressDestroyer automaticaly calls it.
526         NOTREACHED() << "Invalid pixel format";
527         return false;
528       }
529 #else
530       cinfo.out_color_space = JCS_RGB;
531 #endif
532       break;
533     case JCS_CMYK:
534     case JCS_YCCK:
535     default:
536       // Mozilla errors out on these color spaces, so I presume that the jpeg
537       // library can't do automatic color space conversion for them. We don't
538       // care about these anyway.
539       return false;
540   }
541 #ifndef JCS_EXTENSIONS
542   cinfo.output_components = 3;
543 #endif
544
545   jpeg_calc_output_dimensions(&cinfo);
546   *w = cinfo.output_width;
547   *h = cinfo.output_height;
548
549   jpeg_start_decompress(&cinfo);
550
551   // FIXME(brettw) we may want to allow the capability for callers to request
552   // how to align row lengths as we do for the compressor.
553   int row_read_stride = cinfo.output_width * cinfo.output_components;
554
555 #ifdef JCS_EXTENSIONS
556   // Create memory for a decoded image and write decoded lines to the memory
557   // without conversions same as JPEGCodec::Encode().
558   int row_write_stride = row_read_stride;
559   output->resize(row_write_stride * cinfo.output_height);
560
561   for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) {
562     unsigned char* rowptr = &(*output)[row * row_write_stride];
563     if (!jpeg_read_scanlines(&cinfo, &rowptr, 1))
564       return false;
565   }
566 #else
567   if (format == FORMAT_RGB) {
568     // easy case, row needs no conversion
569     int row_write_stride = row_read_stride;
570     output->resize(row_write_stride * cinfo.output_height);
571
572     for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) {
573       unsigned char* rowptr = &(*output)[row * row_write_stride];
574       if (!jpeg_read_scanlines(&cinfo, &rowptr, 1))
575         return false;
576     }
577   } else {
578     // Rows need conversion to output format: read into a temporary buffer and
579     // expand to the final one. Performance: we could avoid the extra
580     // allocation by doing the expansion in-place.
581     int row_write_stride;
582     void (*converter)(const unsigned char* rgb, int w, unsigned char* out);
583     if (format == FORMAT_RGBA ||
584         (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
585       row_write_stride = cinfo.output_width * 4;
586       converter = AddAlpha;
587     } else if (format == FORMAT_BGRA ||
588                (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) {
589       row_write_stride = cinfo.output_width * 4;
590       converter = RGBtoBGRA;
591     } else {
592       NOTREACHED() << "Invalid pixel format";
593       jpeg_destroy_decompress(&cinfo);
594       return false;
595     }
596
597     output->resize(row_write_stride * cinfo.output_height);
598
599     scoped_ptr<unsigned char[]> row_data(new unsigned char[row_read_stride]);
600     unsigned char* rowptr = row_data.get();
601     for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) {
602       if (!jpeg_read_scanlines(&cinfo, &rowptr, 1))
603         return false;
604       converter(rowptr, *w, &(*output)[row * row_write_stride]);
605     }
606   }
607 #endif
608
609   jpeg_finish_decompress(&cinfo);
610   jpeg_destroy_decompress(&cinfo);
611   return true;
612 }
613
614 // static
615 SkBitmap* JPEGCodec::Decode(const unsigned char* input, size_t input_size) {
616   int w, h;
617   std::vector<unsigned char> data_vector;
618   if (!Decode(input, input_size, FORMAT_SkBitmap, &data_vector, &w, &h))
619     return NULL;
620
621   // Skia only handles 32 bit images.
622   int data_length = w * h * 4;
623
624   SkBitmap* bitmap = new SkBitmap();
625   bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h);
626   bitmap->allocPixels();
627   memcpy(bitmap->getAddr32(0, 0), &data_vector[0], data_length);
628
629   return bitmap;
630 }
631
632 }  // namespace gfx