OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/gfx/jpeg_codec.h" | 5 #include "base/gfx/jpeg_codec.h" |
6 | 6 |
7 #include <setjmp.h> | 7 #include <setjmp.h> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 jpeg_compress_struct* cinfo_; | 177 jpeg_compress_struct* cinfo_; |
178 }; | 178 }; |
179 | 179 |
180 } // namespace | 180 } // namespace |
181 | 181 |
182 bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format, | 182 bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format, |
183 int w, int h, int row_byte_width, | 183 int w, int h, int row_byte_width, |
184 int quality, std::vector<unsigned char>* output) { | 184 int quality, std::vector<unsigned char>* output) { |
185 jpeg_compress_struct cinfo; | 185 jpeg_compress_struct cinfo; |
186 CompressDestroyer destroyer; | 186 CompressDestroyer destroyer; |
| 187 destroyer.SetManagedObject(&cinfo); |
187 output->clear(); | 188 output->clear(); |
188 | 189 |
189 // We set up the normal JPEG error routines, then override error_exit. | 190 // We set up the normal JPEG error routines, then override error_exit. |
190 // This must be done before the call to create_compress. | 191 // This must be done before the call to create_compress. |
191 CoderErrorMgr errmgr; | 192 CoderErrorMgr errmgr; |
192 cinfo.err = jpeg_std_error(&errmgr.pub); | 193 cinfo.err = jpeg_std_error(&errmgr.pub); |
193 errmgr.pub.error_exit = ErrorExit; | 194 errmgr.pub.error_exit = ErrorExit; |
194 // Establish the setjmp return context for ErrorExit to use. | 195 // Establish the setjmp return context for ErrorExit to use. |
195 if (setjmp(errmgr.setjmp_buffer)) { | 196 if (setjmp(errmgr.setjmp_buffer)) { |
196 // If we get here, the JPEG code has signaled an error. | 197 // If we get here, the JPEG code has signaled an error. |
197 // MSDN notes: "if you intend your code to be portable, do not rely on | 198 // MSDN notes: "if you intend your code to be portable, do not rely on |
198 // correct destruction of frame-based objects when executing a nonlocal | 199 // correct destruction of frame-based objects when executing a nonlocal |
199 // goto using a call to longjmp." So we delete the CompressDestroyer's | 200 // goto using a call to longjmp." So we delete the CompressDestroyer's |
200 // object manually instead. | 201 // object manually instead. |
201 destroyer.DestroyManagedObject(); | 202 destroyer.DestroyManagedObject(); |
202 return false; | 203 return false; |
203 } | 204 } |
204 | 205 |
205 // The destroyer will destroy() cinfo on exit. | 206 // The destroyer will destroy() cinfo on exit. |
206 jpeg_create_compress(&cinfo); | 207 jpeg_create_compress(&cinfo); |
207 destroyer.SetManagedObject(&cinfo); | |
208 | 208 |
209 cinfo.image_width = w; | 209 cinfo.image_width = w; |
210 cinfo.image_height = h; | 210 cinfo.image_height = h; |
211 cinfo.input_components = 3; | 211 cinfo.input_components = 3; |
212 cinfo.in_color_space = JCS_RGB; | 212 cinfo.in_color_space = JCS_RGB; |
213 cinfo.data_precision = 8; | 213 cinfo.data_precision = 8; |
214 | 214 |
215 jpeg_set_defaults(&cinfo); | 215 jpeg_set_defaults(&cinfo); |
216 jpeg_set_quality(&cinfo, quality, 1); // quality here is 0-100 | 216 jpeg_set_quality(&cinfo, quality, 1); // quality here is 0-100 |
217 | 217 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 jpeg_decompress_struct* cinfo_; | 388 jpeg_decompress_struct* cinfo_; |
389 }; | 389 }; |
390 | 390 |
391 } // namespace | 391 } // namespace |
392 | 392 |
393 bool JPEGCodec::Decode(const unsigned char* input, size_t input_size, | 393 bool JPEGCodec::Decode(const unsigned char* input, size_t input_size, |
394 ColorFormat format, std::vector<unsigned char>* output, | 394 ColorFormat format, std::vector<unsigned char>* output, |
395 int* w, int* h) { | 395 int* w, int* h) { |
396 jpeg_decompress_struct cinfo; | 396 jpeg_decompress_struct cinfo; |
397 DecompressDestroyer destroyer; | 397 DecompressDestroyer destroyer; |
| 398 destroyer.SetManagedObject(&cinfo); |
398 output->clear(); | 399 output->clear(); |
399 | 400 |
400 // We set up the normal JPEG error routines, then override error_exit. | 401 // We set up the normal JPEG error routines, then override error_exit. |
401 // This must be done before the call to create_decompress. | 402 // This must be done before the call to create_decompress. |
402 CoderErrorMgr errmgr; | 403 CoderErrorMgr errmgr; |
403 cinfo.err = jpeg_std_error(&errmgr.pub); | 404 cinfo.err = jpeg_std_error(&errmgr.pub); |
404 errmgr.pub.error_exit = ErrorExit; | 405 errmgr.pub.error_exit = ErrorExit; |
405 // Establish the setjmp return context for ErrorExit to use. | 406 // Establish the setjmp return context for ErrorExit to use. |
406 if (setjmp(errmgr.setjmp_buffer)) { | 407 if (setjmp(errmgr.setjmp_buffer)) { |
407 // If we get here, the JPEG code has signaled an error. | 408 // If we get here, the JPEG code has signaled an error. |
408 // See note in JPEGCodec::Encode() for why we need to destroy the cinfo | 409 // See note in JPEGCodec::Encode() for why we need to destroy the cinfo |
409 // manually here. | 410 // manually here. |
410 destroyer.DestroyManagedObject(); | 411 destroyer.DestroyManagedObject(); |
411 return false; | 412 return false; |
412 } | 413 } |
413 | 414 |
414 // The destroyer will destroy() cinfo on exit. We don't want to set the | 415 // The destroyer will destroy() cinfo on exit. We don't want to set the |
415 // destroyer's object until cinfo is initialized. | 416 // destroyer's object until cinfo is initialized. |
416 jpeg_create_decompress(&cinfo); | 417 jpeg_create_decompress(&cinfo); |
417 destroyer.SetManagedObject(&cinfo); | |
418 | 418 |
419 // set up the source manager | 419 // set up the source manager |
420 jpeg_source_mgr srcmgr; | 420 jpeg_source_mgr srcmgr; |
421 srcmgr.init_source = InitSource; | 421 srcmgr.init_source = InitSource; |
422 srcmgr.fill_input_buffer = FillInputBuffer; | 422 srcmgr.fill_input_buffer = FillInputBuffer; |
423 srcmgr.skip_input_data = SkipInputData; | 423 srcmgr.skip_input_data = SkipInputData; |
424 srcmgr.resync_to_restart = jpeg_resync_to_restart; // use default routine | 424 srcmgr.resync_to_restart = jpeg_resync_to_restart; // use default routine |
425 srcmgr.term_source = TermSource; | 425 srcmgr.term_source = TermSource; |
426 cinfo.src = &srcmgr; | 426 cinfo.src = &srcmgr; |
427 | 427 |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 // Skia only handles 32 bit images. | 514 // Skia only handles 32 bit images. |
515 int data_length = w * h * 4; | 515 int data_length = w * h * 4; |
516 | 516 |
517 SkBitmap* bitmap = new SkBitmap(); | 517 SkBitmap* bitmap = new SkBitmap(); |
518 bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h); | 518 bitmap->setConfig(SkBitmap::kARGB_8888_Config, w, h); |
519 bitmap->allocPixels(); | 519 bitmap->allocPixels(); |
520 memcpy(bitmap->getAddr32(0, 0), &data_vector[0], data_length); | 520 memcpy(bitmap->getAddr32(0, 0), &data_vector[0], data_length); |
521 | 521 |
522 return bitmap; | 522 return bitmap; |
523 } | 523 } |
OLD | NEW |