diff options
| author | Daniel Colascione | 2012-09-17 04:07:36 -0800 |
|---|---|---|
| committer | Daniel Colascione | 2012-09-17 04:07:36 -0800 |
| commit | 2ab329f3b5d52a39f0a45c3d9c129f1c19560142 (patch) | |
| tree | 6dd6784d63e54cb18071df8e28fbdbc27d418728 /src/image.c | |
| parent | f701ab72dd55460d23c8b029550aa4d7ecef3cfa (diff) | |
| parent | bb7dce392f6d9d5fc4b9d7de09ff920a52f07669 (diff) | |
| download | emacs-2ab329f3b5d52a39f0a45c3d9c129f1c19560142.tar.gz emacs-2ab329f3b5d52a39f0a45c3d9c129f1c19560142.zip | |
Merge from trunk
Diffstat (limited to 'src/image.c')
| -rw-r--r-- | src/image.c | 231 |
1 files changed, 149 insertions, 82 deletions
diff --git a/src/image.c b/src/image.c index b5a2e0328eb..a562868d94d 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -19,7 +19,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 19 | 19 | ||
| 20 | #include <config.h> | 20 | #include <config.h> |
| 21 | #include <stdio.h> | 21 | #include <stdio.h> |
| 22 | #include <math.h> | ||
| 23 | #include <unistd.h> | 22 | #include <unistd.h> |
| 24 | 23 | ||
| 25 | #ifdef HAVE_PNG | 24 | #ifdef HAVE_PNG |
| @@ -575,7 +574,6 @@ static int x_build_heuristic_mask (struct frame *, struct image *, | |||
| 575 | Lisp_Object); | 574 | Lisp_Object); |
| 576 | #ifdef WINDOWSNT | 575 | #ifdef WINDOWSNT |
| 577 | extern Lisp_Object Vlibrary_cache; | 576 | extern Lisp_Object Vlibrary_cache; |
| 578 | |||
| 579 | #define CACHE_IMAGE_TYPE(type, status) \ | 577 | #define CACHE_IMAGE_TYPE(type, status) \ |
| 580 | do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) | 578 | do { Vlibrary_cache = Fcons (Fcons (type, status), Vlibrary_cache); } while (0) |
| 581 | #else | 579 | #else |
| @@ -600,7 +598,7 @@ define_image_type (struct image_type *type, int loaded) | |||
| 600 | /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. | 598 | /* Make a copy of TYPE to avoid a bus error in a dumped Emacs. |
| 601 | The initialized data segment is read-only. */ | 599 | The initialized data segment is read-only. */ |
| 602 | struct image_type *p = xmalloc (sizeof *p); | 600 | struct image_type *p = xmalloc (sizeof *p); |
| 603 | memcpy (p, type, sizeof *p); | 601 | *p = *type; |
| 604 | p->next = image_types; | 602 | p->next = image_types; |
| 605 | image_types = p; | 603 | image_types = p; |
| 606 | success = Qt; | 604 | success = Qt; |
| @@ -847,7 +845,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords, | |||
| 847 | break; | 845 | break; |
| 848 | 846 | ||
| 849 | default: | 847 | default: |
| 850 | abort (); | 848 | emacs_abort (); |
| 851 | break; | 849 | break; |
| 852 | } | 850 | } |
| 853 | 851 | ||
| @@ -5528,15 +5526,24 @@ init_png_functions (Lisp_Object libraries) | |||
| 5528 | 5526 | ||
| 5529 | #endif /* WINDOWSNT */ | 5527 | #endif /* WINDOWSNT */ |
| 5530 | 5528 | ||
| 5529 | /* Possibly inefficient/inexact substitutes for _setjmp and _longjmp. | ||
| 5530 | Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp | ||
| 5531 | substitute may munge the signal mask, but that should be OK here. | ||
| 5532 | MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in | ||
| 5533 | the system header setjmp.h; don't mess up that. */ | ||
| 5534 | #ifndef HAVE__SETJMP | ||
| 5535 | # define _setjmp(j) setjmp (j) | ||
| 5536 | # define _longjmp longjmp | ||
| 5537 | #endif | ||
| 5531 | 5538 | ||
| 5532 | #if (PNG_LIBPNG_VER < 10500) | 5539 | #if (PNG_LIBPNG_VER < 10500) |
| 5533 | #define PNG_LONGJMP(ptr) (longjmp ((ptr)->jmpbuf, 1)) | 5540 | #define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1)) |
| 5534 | #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf) | 5541 | #define PNG_JMPBUF(ptr) ((ptr)->jmpbuf) |
| 5535 | #else | 5542 | #else |
| 5536 | /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */ | 5543 | /* In libpng version 1.5, the jmpbuf member is hidden. (Bug#7908) */ |
| 5537 | #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1)) | 5544 | #define PNG_LONGJMP(ptr) (fn_png_longjmp ((ptr), 1)) |
| 5538 | #define PNG_JMPBUF(ptr) \ | 5545 | #define PNG_JMPBUF(ptr) \ |
| 5539 | (*fn_png_set_longjmp_fn ((ptr), longjmp, sizeof (jmp_buf))) | 5546 | (*fn_png_set_longjmp_fn ((ptr), _longjmp, sizeof (jmp_buf))) |
| 5540 | #endif | 5547 | #endif |
| 5541 | 5548 | ||
| 5542 | /* Error and warning handlers installed when the PNG library | 5549 | /* Error and warning handlers installed when the PNG library |
| @@ -5605,20 +5612,31 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length) | |||
| 5605 | /* Load PNG image IMG for use on frame F. Value is non-zero if | 5612 | /* Load PNG image IMG for use on frame F. Value is non-zero if |
| 5606 | successful. */ | 5613 | successful. */ |
| 5607 | 5614 | ||
| 5615 | struct png_load_context | ||
| 5616 | { | ||
| 5617 | /* These are members so that longjmp doesn't munge local variables. */ | ||
| 5618 | png_struct *png_ptr; | ||
| 5619 | png_info *info_ptr; | ||
| 5620 | png_info *end_info; | ||
| 5621 | FILE *fp; | ||
| 5622 | png_byte *pixels; | ||
| 5623 | png_byte **rows; | ||
| 5624 | }; | ||
| 5625 | |||
| 5608 | static int | 5626 | static int |
| 5609 | png_load (struct frame *f, struct image *img) | 5627 | png_load_body (struct frame *f, struct image *img, struct png_load_context *c) |
| 5610 | { | 5628 | { |
| 5611 | Lisp_Object file, specified_file; | 5629 | Lisp_Object file, specified_file; |
| 5612 | Lisp_Object specified_data; | 5630 | Lisp_Object specified_data; |
| 5613 | int x, y; | 5631 | int x, y; |
| 5614 | ptrdiff_t i; | 5632 | ptrdiff_t i; |
| 5615 | XImagePtr ximg, mask_img = NULL; | 5633 | XImagePtr ximg, mask_img = NULL; |
| 5616 | png_struct *png_ptr = NULL; | 5634 | png_struct *png_ptr; |
| 5617 | png_info *info_ptr = NULL, *end_info = NULL; | 5635 | png_info *info_ptr = NULL, *end_info = NULL; |
| 5618 | FILE *volatile fp = NULL; | 5636 | FILE *fp = NULL; |
| 5619 | png_byte sig[8]; | 5637 | png_byte sig[8]; |
| 5620 | png_byte * volatile pixels = NULL; | 5638 | png_byte *pixels = NULL; |
| 5621 | png_byte ** volatile rows = NULL; | 5639 | png_byte **rows = NULL; |
| 5622 | png_uint_32 width, height; | 5640 | png_uint_32 width, height; |
| 5623 | int bit_depth, color_type, interlace_type; | 5641 | int bit_depth, color_type, interlace_type; |
| 5624 | png_byte channels; | 5642 | png_byte channels; |
| @@ -5685,41 +5703,47 @@ png_load (struct frame *f, struct image *img) | |||
| 5685 | png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, | 5703 | png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, |
| 5686 | NULL, my_png_error, | 5704 | NULL, my_png_error, |
| 5687 | my_png_warning); | 5705 | my_png_warning); |
| 5688 | if (!png_ptr) | 5706 | if (png_ptr) |
| 5689 | { | 5707 | { |
| 5690 | if (fp) fclose (fp); | 5708 | info_ptr = fn_png_create_info_struct (png_ptr); |
| 5691 | return 0; | 5709 | end_info = fn_png_create_info_struct (png_ptr); |
| 5692 | } | 5710 | } |
| 5693 | 5711 | ||
| 5694 | info_ptr = fn_png_create_info_struct (png_ptr); | 5712 | c->png_ptr = png_ptr; |
| 5695 | if (!info_ptr) | 5713 | c->info_ptr = info_ptr; |
| 5714 | c->end_info = end_info; | ||
| 5715 | c->fp = fp; | ||
| 5716 | c->pixels = pixels; | ||
| 5717 | c->rows = rows; | ||
| 5718 | |||
| 5719 | if (! (info_ptr && end_info)) | ||
| 5696 | { | 5720 | { |
| 5697 | fn_png_destroy_read_struct (&png_ptr, NULL, NULL); | 5721 | fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info); |
| 5698 | if (fp) fclose (fp); | 5722 | png_ptr = 0; |
| 5699 | return 0; | ||
| 5700 | } | 5723 | } |
| 5701 | 5724 | if (! png_ptr) | |
| 5702 | end_info = fn_png_create_info_struct (png_ptr); | ||
| 5703 | if (!end_info) | ||
| 5704 | { | 5725 | { |
| 5705 | fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL); | ||
| 5706 | if (fp) fclose (fp); | 5726 | if (fp) fclose (fp); |
| 5707 | return 0; | 5727 | return 0; |
| 5708 | } | 5728 | } |
| 5709 | 5729 | ||
| 5710 | /* Set error jump-back. We come back here when the PNG library | 5730 | /* Set error jump-back. We come back here when the PNG library |
| 5711 | detects an error. */ | 5731 | detects an error. */ |
| 5712 | if (setjmp (PNG_JMPBUF (png_ptr))) | 5732 | if (_setjmp (PNG_JMPBUF (png_ptr))) |
| 5713 | { | 5733 | { |
| 5714 | error: | 5734 | error: |
| 5715 | if (png_ptr) | 5735 | if (c->png_ptr) |
| 5716 | fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); | 5736 | fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info); |
| 5717 | xfree (pixels); | 5737 | xfree (c->pixels); |
| 5718 | xfree (rows); | 5738 | xfree (c->rows); |
| 5719 | if (fp) fclose (fp); | 5739 | if (c->fp) |
| 5740 | fclose (c->fp); | ||
| 5720 | return 0; | 5741 | return 0; |
| 5721 | } | 5742 | } |
| 5722 | 5743 | ||
| 5744 | /* Silence a bogus diagnostic; see GCC bug 54561. */ | ||
| 5745 | IF_LINT (fp = c->fp); | ||
| 5746 | |||
| 5723 | /* Read image info. */ | 5747 | /* Read image info. */ |
| 5724 | if (!NILP (specified_data)) | 5748 | if (!NILP (specified_data)) |
| 5725 | fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); | 5749 | fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); |
| @@ -5835,8 +5859,8 @@ png_load (struct frame *f, struct image *img) | |||
| 5835 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height | 5859 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height |
| 5836 | || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes) | 5860 | || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes) |
| 5837 | memory_full (SIZE_MAX); | 5861 | memory_full (SIZE_MAX); |
| 5838 | pixels = xmalloc (sizeof *pixels * row_bytes * height); | 5862 | c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height); |
| 5839 | rows = xmalloc (height * sizeof *rows); | 5863 | c->rows = rows = xmalloc (height * sizeof *rows); |
| 5840 | for (i = 0; i < height; ++i) | 5864 | for (i = 0; i < height; ++i) |
| 5841 | rows[i] = pixels + i * row_bytes; | 5865 | rows[i] = pixels + i * row_bytes; |
| 5842 | 5866 | ||
| @@ -5846,7 +5870,7 @@ png_load (struct frame *f, struct image *img) | |||
| 5846 | if (fp) | 5870 | if (fp) |
| 5847 | { | 5871 | { |
| 5848 | fclose (fp); | 5872 | fclose (fp); |
| 5849 | fp = NULL; | 5873 | c->fp = NULL; |
| 5850 | } | 5874 | } |
| 5851 | 5875 | ||
| 5852 | /* Create an image and pixmap serving as mask if the PNG image | 5876 | /* Create an image and pixmap serving as mask if the PNG image |
| @@ -5921,7 +5945,7 @@ png_load (struct frame *f, struct image *img) | |||
| 5921 | #endif /* COLOR_TABLE_SUPPORT */ | 5945 | #endif /* COLOR_TABLE_SUPPORT */ |
| 5922 | 5946 | ||
| 5923 | /* Clean up. */ | 5947 | /* Clean up. */ |
| 5924 | fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); | 5948 | fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info); |
| 5925 | xfree (rows); | 5949 | xfree (rows); |
| 5926 | xfree (pixels); | 5950 | xfree (pixels); |
| 5927 | 5951 | ||
| @@ -5950,6 +5974,13 @@ png_load (struct frame *f, struct image *img) | |||
| 5950 | return 1; | 5974 | return 1; |
| 5951 | } | 5975 | } |
| 5952 | 5976 | ||
| 5977 | static int | ||
| 5978 | png_load (struct frame *f, struct image *img) | ||
| 5979 | { | ||
| 5980 | struct png_load_context c; | ||
| 5981 | return png_load_body (f, img, &c); | ||
| 5982 | } | ||
| 5983 | |||
| 5953 | #else /* HAVE_PNG */ | 5984 | #else /* HAVE_PNG */ |
| 5954 | 5985 | ||
| 5955 | #ifdef HAVE_NS | 5986 | #ifdef HAVE_NS |
| @@ -6125,7 +6156,20 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired) | |||
| 6125 | struct my_jpeg_error_mgr | 6156 | struct my_jpeg_error_mgr |
| 6126 | { | 6157 | { |
| 6127 | struct jpeg_error_mgr pub; | 6158 | struct jpeg_error_mgr pub; |
| 6128 | jmp_buf setjmp_buffer; | 6159 | sys_jmp_buf setjmp_buffer; |
| 6160 | |||
| 6161 | /* The remaining members are so that longjmp doesn't munge local | ||
| 6162 | variables. */ | ||
| 6163 | struct jpeg_decompress_struct cinfo; | ||
| 6164 | enum | ||
| 6165 | { | ||
| 6166 | MY_JPEG_ERROR_EXIT, | ||
| 6167 | MY_JPEG_INVALID_IMAGE_SIZE, | ||
| 6168 | MY_JPEG_CANNOT_CREATE_X | ||
| 6169 | } failure_code; | ||
| 6170 | #ifdef lint | ||
| 6171 | FILE *fp; | ||
| 6172 | #endif | ||
| 6129 | }; | 6173 | }; |
| 6130 | 6174 | ||
| 6131 | 6175 | ||
| @@ -6133,7 +6177,8 @@ static _Noreturn void | |||
| 6133 | my_error_exit (j_common_ptr cinfo) | 6177 | my_error_exit (j_common_ptr cinfo) |
| 6134 | { | 6178 | { |
| 6135 | struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err; | 6179 | struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err; |
| 6136 | longjmp (mgr->setjmp_buffer, 1); | 6180 | mgr->failure_code = MY_JPEG_ERROR_EXIT; |
| 6181 | sys_longjmp (mgr->setjmp_buffer, 1); | ||
| 6137 | } | 6182 | } |
| 6138 | 6183 | ||
| 6139 | 6184 | ||
| @@ -6201,7 +6246,7 @@ our_memory_skip_input_data (j_decompress_ptr cinfo, long int num_bytes) | |||
| 6201 | reading the image. */ | 6246 | reading the image. */ |
| 6202 | 6247 | ||
| 6203 | static void | 6248 | static void |
| 6204 | jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, unsigned int len) | 6249 | jpeg_memory_src (j_decompress_ptr cinfo, JOCTET *data, ptrdiff_t len) |
| 6205 | { | 6250 | { |
| 6206 | struct jpeg_source_mgr *src; | 6251 | struct jpeg_source_mgr *src; |
| 6207 | 6252 | ||
| @@ -6339,17 +6384,15 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp) | |||
| 6339 | from the JPEG lib. */ | 6384 | from the JPEG lib. */ |
| 6340 | 6385 | ||
| 6341 | static int | 6386 | static int |
| 6342 | jpeg_load (struct frame *f, struct image *img) | 6387 | jpeg_load_body (struct frame *f, struct image *img, |
| 6388 | struct my_jpeg_error_mgr *mgr) | ||
| 6343 | { | 6389 | { |
| 6344 | struct jpeg_decompress_struct cinfo; | ||
| 6345 | struct my_jpeg_error_mgr mgr; | ||
| 6346 | Lisp_Object file, specified_file; | 6390 | Lisp_Object file, specified_file; |
| 6347 | Lisp_Object specified_data; | 6391 | Lisp_Object specified_data; |
| 6348 | FILE * volatile fp = NULL; | 6392 | FILE *fp = NULL; |
| 6349 | JSAMPARRAY buffer; | 6393 | JSAMPARRAY buffer; |
| 6350 | int row_stride, x, y; | 6394 | int row_stride, x, y; |
| 6351 | XImagePtr ximg = NULL; | 6395 | XImagePtr ximg = NULL; |
| 6352 | int rc; | ||
| 6353 | unsigned long *colors; | 6396 | unsigned long *colors; |
| 6354 | int width, height; | 6397 | int width, height; |
| 6355 | 6398 | ||
| @@ -6379,26 +6422,37 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6379 | return 0; | 6422 | return 0; |
| 6380 | } | 6423 | } |
| 6381 | 6424 | ||
| 6425 | IF_LINT (mgr->fp = fp); | ||
| 6426 | |||
| 6382 | /* Customize libjpeg's error handling to call my_error_exit when an | 6427 | /* Customize libjpeg's error handling to call my_error_exit when an |
| 6383 | error is detected. This function will perform a longjmp. */ | 6428 | error is detected. This function will perform a longjmp. */ |
| 6384 | cinfo.err = fn_jpeg_std_error (&mgr.pub); | 6429 | mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub); |
| 6385 | mgr.pub.error_exit = my_error_exit; | 6430 | mgr->pub.error_exit = my_error_exit; |
| 6386 | 6431 | if (sys_setjmp (mgr->setjmp_buffer)) | |
| 6387 | if ((rc = setjmp (mgr.setjmp_buffer)) != 0) | ||
| 6388 | { | 6432 | { |
| 6389 | if (rc == 1) | 6433 | switch (mgr->failure_code) |
| 6390 | { | 6434 | { |
| 6391 | /* Called from my_error_exit. Display a JPEG error. */ | 6435 | case MY_JPEG_ERROR_EXIT: |
| 6392 | char buf[JMSG_LENGTH_MAX]; | 6436 | { |
| 6393 | cinfo.err->format_message ((j_common_ptr) &cinfo, buf); | 6437 | char buf[JMSG_LENGTH_MAX]; |
| 6394 | image_error ("Error reading JPEG image `%s': %s", img->spec, | 6438 | mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf); |
| 6395 | build_string (buf)); | 6439 | image_error ("Error reading JPEG image `%s': %s", img->spec, |
| 6440 | build_string (buf)); | ||
| 6441 | break; | ||
| 6442 | } | ||
| 6443 | |||
| 6444 | case MY_JPEG_INVALID_IMAGE_SIZE: | ||
| 6445 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); | ||
| 6446 | break; | ||
| 6447 | |||
| 6448 | case MY_JPEG_CANNOT_CREATE_X: | ||
| 6449 | break; | ||
| 6396 | } | 6450 | } |
| 6397 | 6451 | ||
| 6398 | /* Close the input file and destroy the JPEG object. */ | 6452 | /* Close the input file and destroy the JPEG object. */ |
| 6399 | if (fp) | 6453 | if (fp) |
| 6400 | fclose ((FILE *) fp); | 6454 | fclose (fp); |
| 6401 | fn_jpeg_destroy_decompress (&cinfo); | 6455 | fn_jpeg_destroy_decompress (&mgr->cinfo); |
| 6402 | 6456 | ||
| 6403 | /* If we already have an XImage, free that. */ | 6457 | /* If we already have an XImage, free that. */ |
| 6404 | x_destroy_x_image (ximg); | 6458 | x_destroy_x_image (ximg); |
| @@ -6408,46 +6462,52 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6408 | return 0; | 6462 | return 0; |
| 6409 | } | 6463 | } |
| 6410 | 6464 | ||
| 6465 | /* Silence a bogus diagnostic; see GCC bug 54561. */ | ||
| 6466 | IF_LINT (fp = mgr->fp); | ||
| 6467 | |||
| 6411 | /* Create the JPEG decompression object. Let it read from fp. | 6468 | /* Create the JPEG decompression object. Let it read from fp. |
| 6412 | Read the JPEG image header. */ | 6469 | Read the JPEG image header. */ |
| 6413 | fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo)); | 6470 | fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo); |
| 6414 | 6471 | ||
| 6415 | if (NILP (specified_data)) | 6472 | if (NILP (specified_data)) |
| 6416 | jpeg_file_src (&cinfo, (FILE *) fp); | 6473 | jpeg_file_src (&mgr->cinfo, fp); |
| 6417 | else | 6474 | else |
| 6418 | jpeg_memory_src (&cinfo, SDATA (specified_data), | 6475 | jpeg_memory_src (&mgr->cinfo, SDATA (specified_data), |
| 6419 | SBYTES (specified_data)); | 6476 | SBYTES (specified_data)); |
| 6420 | 6477 | ||
| 6421 | fn_jpeg_read_header (&cinfo, 1); | 6478 | fn_jpeg_read_header (&mgr->cinfo, 1); |
| 6422 | 6479 | ||
| 6423 | /* Customize decompression so that color quantization will be used. | 6480 | /* Customize decompression so that color quantization will be used. |
| 6424 | Start decompression. */ | 6481 | Start decompression. */ |
| 6425 | cinfo.quantize_colors = 1; | 6482 | mgr->cinfo.quantize_colors = 1; |
| 6426 | fn_jpeg_start_decompress (&cinfo); | 6483 | fn_jpeg_start_decompress (&mgr->cinfo); |
| 6427 | width = img->width = cinfo.output_width; | 6484 | width = img->width = mgr->cinfo.output_width; |
| 6428 | height = img->height = cinfo.output_height; | 6485 | height = img->height = mgr->cinfo.output_height; |
| 6429 | 6486 | ||
| 6430 | if (!check_image_size (f, width, height)) | 6487 | if (!check_image_size (f, width, height)) |
| 6431 | { | 6488 | { |
| 6432 | image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); | 6489 | mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE; |
| 6433 | longjmp (mgr.setjmp_buffer, 2); | 6490 | sys_longjmp (mgr->setjmp_buffer, 1); |
| 6434 | } | 6491 | } |
| 6435 | 6492 | ||
| 6436 | /* Create X image and pixmap. */ | 6493 | /* Create X image and pixmap. */ |
| 6437 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) | 6494 | if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) |
| 6438 | longjmp (mgr.setjmp_buffer, 2); | 6495 | { |
| 6496 | mgr->failure_code = MY_JPEG_CANNOT_CREATE_X; | ||
| 6497 | sys_longjmp (mgr->setjmp_buffer, 1); | ||
| 6498 | } | ||
| 6439 | 6499 | ||
| 6440 | /* Allocate colors. When color quantization is used, | 6500 | /* Allocate colors. When color quantization is used, |
| 6441 | cinfo.actual_number_of_colors has been set with the number of | 6501 | mgr->cinfo.actual_number_of_colors has been set with the number of |
| 6442 | colors generated, and cinfo.colormap is a two-dimensional array | 6502 | colors generated, and mgr->cinfo.colormap is a two-dimensional array |
| 6443 | of color indices in the range 0..cinfo.actual_number_of_colors. | 6503 | of color indices in the range 0..mgr->cinfo.actual_number_of_colors. |
| 6444 | No more than 255 colors will be generated. */ | 6504 | No more than 255 colors will be generated. */ |
| 6445 | { | 6505 | { |
| 6446 | int i, ir, ig, ib; | 6506 | int i, ir, ig, ib; |
| 6447 | 6507 | ||
| 6448 | if (cinfo.out_color_components > 2) | 6508 | if (mgr->cinfo.out_color_components > 2) |
| 6449 | ir = 0, ig = 1, ib = 2; | 6509 | ir = 0, ig = 1, ib = 2; |
| 6450 | else if (cinfo.out_color_components > 1) | 6510 | else if (mgr->cinfo.out_color_components > 1) |
| 6451 | ir = 0, ig = 1, ib = 0; | 6511 | ir = 0, ig = 1, ib = 0; |
| 6452 | else | 6512 | else |
| 6453 | ir = 0, ig = 0, ib = 0; | 6513 | ir = 0, ig = 0, ib = 0; |
| @@ -6457,15 +6517,15 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6457 | a default color, and we don't have to care about which colors | 6517 | a default color, and we don't have to care about which colors |
| 6458 | can be freed safely, and which can't. */ | 6518 | can be freed safely, and which can't. */ |
| 6459 | init_color_table (); | 6519 | init_color_table (); |
| 6460 | colors = alloca (cinfo.actual_number_of_colors * sizeof *colors); | 6520 | colors = alloca (mgr->cinfo.actual_number_of_colors * sizeof *colors); |
| 6461 | 6521 | ||
| 6462 | for (i = 0; i < cinfo.actual_number_of_colors; ++i) | 6522 | for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i) |
| 6463 | { | 6523 | { |
| 6464 | /* Multiply RGB values with 255 because X expects RGB values | 6524 | /* Multiply RGB values with 255 because X expects RGB values |
| 6465 | in the range 0..0xffff. */ | 6525 | in the range 0..0xffff. */ |
| 6466 | int r = cinfo.colormap[ir][i] << 8; | 6526 | int r = mgr->cinfo.colormap[ir][i] << 8; |
| 6467 | int g = cinfo.colormap[ig][i] << 8; | 6527 | int g = mgr->cinfo.colormap[ig][i] << 8; |
| 6468 | int b = cinfo.colormap[ib][i] << 8; | 6528 | int b = mgr->cinfo.colormap[ib][i] << 8; |
| 6469 | colors[i] = lookup_rgb_color (f, r, g, b); | 6529 | colors[i] = lookup_rgb_color (f, r, g, b); |
| 6470 | } | 6530 | } |
| 6471 | 6531 | ||
| @@ -6477,21 +6537,21 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6477 | } | 6537 | } |
| 6478 | 6538 | ||
| 6479 | /* Read pixels. */ | 6539 | /* Read pixels. */ |
| 6480 | row_stride = width * cinfo.output_components; | 6540 | row_stride = width * mgr->cinfo.output_components; |
| 6481 | buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, | 6541 | buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo, |
| 6482 | row_stride, 1); | 6542 | JPOOL_IMAGE, row_stride, 1); |
| 6483 | for (y = 0; y < height; ++y) | 6543 | for (y = 0; y < height; ++y) |
| 6484 | { | 6544 | { |
| 6485 | fn_jpeg_read_scanlines (&cinfo, buffer, 1); | 6545 | fn_jpeg_read_scanlines (&mgr->cinfo, buffer, 1); |
| 6486 | for (x = 0; x < cinfo.output_width; ++x) | 6546 | for (x = 0; x < mgr->cinfo.output_width; ++x) |
| 6487 | XPutPixel (ximg, x, y, colors[buffer[0][x]]); | 6547 | XPutPixel (ximg, x, y, colors[buffer[0][x]]); |
| 6488 | } | 6548 | } |
| 6489 | 6549 | ||
| 6490 | /* Clean up. */ | 6550 | /* Clean up. */ |
| 6491 | fn_jpeg_finish_decompress (&cinfo); | 6551 | fn_jpeg_finish_decompress (&mgr->cinfo); |
| 6492 | fn_jpeg_destroy_decompress (&cinfo); | 6552 | fn_jpeg_destroy_decompress (&mgr->cinfo); |
| 6493 | if (fp) | 6553 | if (fp) |
| 6494 | fclose ((FILE *) fp); | 6554 | fclose (fp); |
| 6495 | 6555 | ||
| 6496 | /* Maybe fill in the background field while we have ximg handy. */ | 6556 | /* Maybe fill in the background field while we have ximg handy. */ |
| 6497 | if (NILP (image_spec_value (img->spec, QCbackground, NULL))) | 6557 | if (NILP (image_spec_value (img->spec, QCbackground, NULL))) |
| @@ -6504,6 +6564,13 @@ jpeg_load (struct frame *f, struct image *img) | |||
| 6504 | return 1; | 6564 | return 1; |
| 6505 | } | 6565 | } |
| 6506 | 6566 | ||
| 6567 | static int | ||
| 6568 | jpeg_load (struct frame *f, struct image *img) | ||
| 6569 | { | ||
| 6570 | struct my_jpeg_error_mgr mgr; | ||
| 6571 | return jpeg_load_body (f, img, &mgr); | ||
| 6572 | } | ||
| 6573 | |||
| 6507 | #else /* HAVE_JPEG */ | 6574 | #else /* HAVE_JPEG */ |
| 6508 | 6575 | ||
| 6509 | #ifdef HAVE_NS | 6576 | #ifdef HAVE_NS |