aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
authorJoakim Verona2012-09-19 01:09:51 +0200
committerJoakim Verona2012-09-19 01:09:51 +0200
commit6c86337db3f2b22977d7b94b054458a2d446c504 (patch)
tree04725c50cbd76c8ffd0faf4cdce895a89a506a58 /src/image.c
parentaac9139d11cf7f9ee84d931ada85be8fa0c90f21 (diff)
parentfefa299077c02a931e5e72f7646e3dfa28f5e8ff (diff)
downloademacs-6c86337db3f2b22977d7b94b054458a2d446c504.tar.gz
emacs-6c86337db3f2b22977d7b94b054458a2d446c504.zip
not compiling yet
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c217
1 files changed, 143 insertions, 74 deletions
diff --git a/src/image.c b/src/image.c
index cf01602050f..8fc1c8637eb 100644
--- a/src/image.c
+++ b/src/image.c
@@ -5514,6 +5514,15 @@ init_png_functions (Lisp_Object libraries)
5514 5514
5515#endif /* HAVE_NTGUI */ 5515#endif /* HAVE_NTGUI */
5516 5516
5517/* Possibly inefficient/inexact substitutes for _setjmp and _longjmp.
5518 Do not use sys_setjmp, as PNG supports only jmp_buf. The _longjmp
5519 substitute may munge the signal mask, but that should be OK here.
5520 MinGW (MS-Windows) uses _setjmp and defines setjmp to _setjmp in
5521 the system header setjmp.h; don't mess up that. */
5522#ifndef HAVE__SETJMP
5523# define _setjmp(j) setjmp (j)
5524# define _longjmp longjmp
5525#endif
5517 5526
5518#if (PNG_LIBPNG_VER < 10500) 5527#if (PNG_LIBPNG_VER < 10500)
5519#define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1)) 5528#define PNG_LONGJMP(ptr) (_longjmp ((ptr)->jmpbuf, 1))
@@ -5591,20 +5600,31 @@ png_read_from_file (png_structp png_ptr, png_bytep data, png_size_t length)
5591/* Load PNG image IMG for use on frame F. Value is non-zero if 5600/* Load PNG image IMG for use on frame F. Value is non-zero if
5592 successful. */ 5601 successful. */
5593 5602
5603struct png_load_context
5604{
5605 /* These are members so that longjmp doesn't munge local variables. */
5606 png_struct *png_ptr;
5607 png_info *info_ptr;
5608 png_info *end_info;
5609 FILE *fp;
5610 png_byte *pixels;
5611 png_byte **rows;
5612};
5613
5594static int 5614static int
5595png_load (struct frame *f, struct image *img) 5615png_load_body (struct frame *f, struct image *img, struct png_load_context *c)
5596{ 5616{
5597 Lisp_Object file, specified_file; 5617 Lisp_Object file, specified_file;
5598 Lisp_Object specified_data; 5618 Lisp_Object specified_data;
5599 int x, y; 5619 int x, y;
5600 ptrdiff_t i; 5620 ptrdiff_t i;
5601 XImagePtr ximg, mask_img = NULL; 5621 XImagePtr ximg, mask_img = NULL;
5602 png_struct *png_ptr = NULL; 5622 png_struct *png_ptr;
5603 png_info *info_ptr = NULL, *end_info = NULL; 5623 png_info *info_ptr = NULL, *end_info = NULL;
5604 FILE *volatile fp = NULL; 5624 FILE *fp = NULL;
5605 png_byte sig[8]; 5625 png_byte sig[8];
5606 png_byte * volatile pixels = NULL; 5626 png_byte *pixels = NULL;
5607 png_byte ** volatile rows = NULL; 5627 png_byte **rows = NULL;
5608 png_uint_32 width, height; 5628 png_uint_32 width, height;
5609 int bit_depth, color_type, interlace_type; 5629 int bit_depth, color_type, interlace_type;
5610 png_byte channels; 5630 png_byte channels;
@@ -5671,24 +5691,26 @@ png_load (struct frame *f, struct image *img)
5671 png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING, 5691 png_ptr = fn_png_create_read_struct (PNG_LIBPNG_VER_STRING,
5672 NULL, my_png_error, 5692 NULL, my_png_error,
5673 my_png_warning); 5693 my_png_warning);
5674 if (!png_ptr) 5694 if (png_ptr)
5675 { 5695 {
5676 if (fp) fclose (fp); 5696 info_ptr = fn_png_create_info_struct (png_ptr);
5677 return 0; 5697 end_info = fn_png_create_info_struct (png_ptr);
5678 } 5698 }
5679 5699
5680 info_ptr = fn_png_create_info_struct (png_ptr); 5700 c->png_ptr = png_ptr;
5681 if (!info_ptr) 5701 c->info_ptr = info_ptr;
5702 c->end_info = end_info;
5703 c->fp = fp;
5704 c->pixels = pixels;
5705 c->rows = rows;
5706
5707 if (! (info_ptr && end_info))
5682 { 5708 {
5683 fn_png_destroy_read_struct (&png_ptr, NULL, NULL); 5709 fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5684 if (fp) fclose (fp); 5710 png_ptr = 0;
5685 return 0;
5686 } 5711 }
5687 5712 if (! png_ptr)
5688 end_info = fn_png_create_info_struct (png_ptr);
5689 if (!end_info)
5690 { 5713 {
5691 fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
5692 if (fp) fclose (fp); 5714 if (fp) fclose (fp);
5693 return 0; 5715 return 0;
5694 } 5716 }
@@ -5698,14 +5720,18 @@ png_load (struct frame *f, struct image *img)
5698 if (_setjmp (PNG_JMPBUF (png_ptr))) 5720 if (_setjmp (PNG_JMPBUF (png_ptr)))
5699 { 5721 {
5700 error: 5722 error:
5701 if (png_ptr) 5723 if (c->png_ptr)
5702 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); 5724 fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5703 xfree (pixels); 5725 xfree (c->pixels);
5704 xfree (rows); 5726 xfree (c->rows);
5705 if (fp) fclose (fp); 5727 if (c->fp)
5728 fclose (c->fp);
5706 return 0; 5729 return 0;
5707 } 5730 }
5708 5731
5732 /* Silence a bogus diagnostic; see GCC bug 54561. */
5733 IF_LINT (fp = c->fp);
5734
5709 /* Read image info. */ 5735 /* Read image info. */
5710 if (!NILP (specified_data)) 5736 if (!NILP (specified_data))
5711 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); 5737 fn_png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory);
@@ -5821,8 +5847,8 @@ png_load (struct frame *f, struct image *img)
5821 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height 5847 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
5822 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes) 5848 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
5823 memory_full (SIZE_MAX); 5849 memory_full (SIZE_MAX);
5824 pixels = xmalloc (sizeof *pixels * row_bytes * height); 5850 c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height);
5825 rows = xmalloc (height * sizeof *rows); 5851 c->rows = rows = xmalloc (height * sizeof *rows);
5826 for (i = 0; i < height; ++i) 5852 for (i = 0; i < height; ++i)
5827 rows[i] = pixels + i * row_bytes; 5853 rows[i] = pixels + i * row_bytes;
5828 5854
@@ -5832,7 +5858,7 @@ png_load (struct frame *f, struct image *img)
5832 if (fp) 5858 if (fp)
5833 { 5859 {
5834 fclose (fp); 5860 fclose (fp);
5835 fp = NULL; 5861 c->fp = NULL;
5836 } 5862 }
5837 5863
5838 /* Create an image and pixmap serving as mask if the PNG image 5864 /* Create an image and pixmap serving as mask if the PNG image
@@ -5907,7 +5933,7 @@ png_load (struct frame *f, struct image *img)
5907#endif /* COLOR_TABLE_SUPPORT */ 5933#endif /* COLOR_TABLE_SUPPORT */
5908 5934
5909 /* Clean up. */ 5935 /* Clean up. */
5910 fn_png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); 5936 fn_png_destroy_read_struct (&c->png_ptr, &c->info_ptr, &c->end_info);
5911 xfree (rows); 5937 xfree (rows);
5912 xfree (pixels); 5938 xfree (pixels);
5913 5939
@@ -5936,6 +5962,13 @@ png_load (struct frame *f, struct image *img)
5936 return 1; 5962 return 1;
5937} 5963}
5938 5964
5965static int
5966png_load (struct frame *f, struct image *img)
5967{
5968 struct png_load_context c;
5969 return png_load_body (f, img, &c);
5970}
5971
5939#else /* HAVE_PNG */ 5972#else /* HAVE_PNG */
5940 5973
5941#ifdef HAVE_NS 5974#ifdef HAVE_NS
@@ -6105,7 +6138,20 @@ jpeg_resync_to_restart_wrapper (j_decompress_ptr cinfo, int desired)
6105struct my_jpeg_error_mgr 6138struct my_jpeg_error_mgr
6106{ 6139{
6107 struct jpeg_error_mgr pub; 6140 struct jpeg_error_mgr pub;
6108 jmp_buf setjmp_buffer; 6141 sys_jmp_buf setjmp_buffer;
6142
6143 /* The remaining members are so that longjmp doesn't munge local
6144 variables. */
6145 struct jpeg_decompress_struct cinfo;
6146 enum
6147 {
6148 MY_JPEG_ERROR_EXIT,
6149 MY_JPEG_INVALID_IMAGE_SIZE,
6150 MY_JPEG_CANNOT_CREATE_X
6151 } failure_code;
6152#ifdef lint
6153 FILE *fp;
6154#endif
6109}; 6155};
6110 6156
6111 6157
@@ -6113,7 +6159,8 @@ static _Noreturn void
6113my_error_exit (j_common_ptr cinfo) 6159my_error_exit (j_common_ptr cinfo)
6114{ 6160{
6115 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err; 6161 struct my_jpeg_error_mgr *mgr = (struct my_jpeg_error_mgr *) cinfo->err;
6116 _longjmp (mgr->setjmp_buffer, 1); 6162 mgr->failure_code = MY_JPEG_ERROR_EXIT;
6163 sys_longjmp (mgr->setjmp_buffer, 1);
6117} 6164}
6118 6165
6119 6166
@@ -6319,17 +6366,15 @@ jpeg_file_src (j_decompress_ptr cinfo, FILE *fp)
6319 from the JPEG lib. */ 6366 from the JPEG lib. */
6320 6367
6321static int 6368static int
6322jpeg_load (struct frame *f, struct image *img) 6369jpeg_load_body (struct frame *f, struct image *img,
6370 struct my_jpeg_error_mgr *mgr)
6323{ 6371{
6324 struct jpeg_decompress_struct cinfo;
6325 struct my_jpeg_error_mgr mgr;
6326 Lisp_Object file, specified_file; 6372 Lisp_Object file, specified_file;
6327 Lisp_Object specified_data; 6373 Lisp_Object specified_data;
6328 FILE * volatile fp = NULL; 6374 FILE *fp = NULL;
6329 JSAMPARRAY buffer; 6375 JSAMPARRAY buffer;
6330 int row_stride, x, y; 6376 int row_stride, x, y;
6331 XImagePtr ximg = NULL; 6377 XImagePtr ximg = NULL;
6332 int rc;
6333 unsigned long *colors; 6378 unsigned long *colors;
6334 int width, height; 6379 int width, height;
6335 6380
@@ -6359,26 +6404,37 @@ jpeg_load (struct frame *f, struct image *img)
6359 return 0; 6404 return 0;
6360 } 6405 }
6361 6406
6407 IF_LINT (mgr->fp = fp);
6408
6362 /* Customize libjpeg's error handling to call my_error_exit when an 6409 /* Customize libjpeg's error handling to call my_error_exit when an
6363 error is detected. This function will perform a longjmp. */ 6410 error is detected. This function will perform a longjmp. */
6364 cinfo.err = fn_jpeg_std_error (&mgr.pub); 6411 mgr->cinfo.err = fn_jpeg_std_error (&mgr->pub);
6365 mgr.pub.error_exit = my_error_exit; 6412 mgr->pub.error_exit = my_error_exit;
6366 6413 if (sys_setjmp (mgr->setjmp_buffer))
6367 if ((rc = _setjmp (mgr.setjmp_buffer)) != 0)
6368 { 6414 {
6369 if (rc == 1) 6415 switch (mgr->failure_code)
6370 { 6416 {
6371 /* Called from my_error_exit. Display a JPEG error. */ 6417 case MY_JPEG_ERROR_EXIT:
6372 char buf[JMSG_LENGTH_MAX]; 6418 {
6373 cinfo.err->format_message ((j_common_ptr) &cinfo, buf); 6419 char buf[JMSG_LENGTH_MAX];
6374 image_error ("Error reading JPEG image `%s': %s", img->spec, 6420 mgr->cinfo.err->format_message ((j_common_ptr) &mgr->cinfo, buf);
6375 build_string (buf)); 6421 image_error ("Error reading JPEG image `%s': %s", img->spec,
6422 build_string (buf));
6423 break;
6424 }
6425
6426 case MY_JPEG_INVALID_IMAGE_SIZE:
6427 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
6428 break;
6429
6430 case MY_JPEG_CANNOT_CREATE_X:
6431 break;
6376 } 6432 }
6377 6433
6378 /* Close the input file and destroy the JPEG object. */ 6434 /* Close the input file and destroy the JPEG object. */
6379 if (fp) 6435 if (fp)
6380 fclose ((FILE *) fp); 6436 fclose (fp);
6381 fn_jpeg_destroy_decompress (&cinfo); 6437 fn_jpeg_destroy_decompress (&mgr->cinfo);
6382 6438
6383 /* If we already have an XImage, free that. */ 6439 /* If we already have an XImage, free that. */
6384 x_destroy_x_image (ximg); 6440 x_destroy_x_image (ximg);
@@ -6388,46 +6444,52 @@ jpeg_load (struct frame *f, struct image *img)
6388 return 0; 6444 return 0;
6389 } 6445 }
6390 6446
6447 /* Silence a bogus diagnostic; see GCC bug 54561. */
6448 IF_LINT (fp = mgr->fp);
6449
6391 /* Create the JPEG decompression object. Let it read from fp. 6450 /* Create the JPEG decompression object. Let it read from fp.
6392 Read the JPEG image header. */ 6451 Read the JPEG image header. */
6393 fn_jpeg_CreateDecompress (&cinfo, JPEG_LIB_VERSION, sizeof (cinfo)); 6452 fn_jpeg_CreateDecompress (&mgr->cinfo, JPEG_LIB_VERSION, sizeof *&mgr->cinfo);
6394 6453
6395 if (NILP (specified_data)) 6454 if (NILP (specified_data))
6396 jpeg_file_src (&cinfo, (FILE *) fp); 6455 jpeg_file_src (&mgr->cinfo, fp);
6397 else 6456 else
6398 jpeg_memory_src (&cinfo, SDATA (specified_data), 6457 jpeg_memory_src (&mgr->cinfo, SDATA (specified_data),
6399 SBYTES (specified_data)); 6458 SBYTES (specified_data));
6400 6459
6401 fn_jpeg_read_header (&cinfo, 1); 6460 fn_jpeg_read_header (&mgr->cinfo, 1);
6402 6461
6403 /* Customize decompression so that color quantization will be used. 6462 /* Customize decompression so that color quantization will be used.
6404 Start decompression. */ 6463 Start decompression. */
6405 cinfo.quantize_colors = 1; 6464 mgr->cinfo.quantize_colors = 1;
6406 fn_jpeg_start_decompress (&cinfo); 6465 fn_jpeg_start_decompress (&mgr->cinfo);
6407 width = img->width = cinfo.output_width; 6466 width = img->width = mgr->cinfo.output_width;
6408 height = img->height = cinfo.output_height; 6467 height = img->height = mgr->cinfo.output_height;
6409 6468
6410 if (!check_image_size (f, width, height)) 6469 if (!check_image_size (f, width, height))
6411 { 6470 {
6412 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 6471 mgr->failure_code = MY_JPEG_INVALID_IMAGE_SIZE;
6413 _longjmp (mgr.setjmp_buffer, 2); 6472 sys_longjmp (mgr->setjmp_buffer, 1);
6414 } 6473 }
6415 6474
6416 /* Create X image and pixmap. */ 6475 /* Create X image and pixmap. */
6417 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 6476 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6418 _longjmp (mgr.setjmp_buffer, 2); 6477 {
6478 mgr->failure_code = MY_JPEG_CANNOT_CREATE_X;
6479 sys_longjmp (mgr->setjmp_buffer, 1);
6480 }
6419 6481
6420 /* Allocate colors. When color quantization is used, 6482 /* Allocate colors. When color quantization is used,
6421 cinfo.actual_number_of_colors has been set with the number of 6483 mgr->cinfo.actual_number_of_colors has been set with the number of
6422 colors generated, and cinfo.colormap is a two-dimensional array 6484 colors generated, and mgr->cinfo.colormap is a two-dimensional array
6423 of color indices in the range 0..cinfo.actual_number_of_colors. 6485 of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
6424 No more than 255 colors will be generated. */ 6486 No more than 255 colors will be generated. */
6425 { 6487 {
6426 int i, ir, ig, ib; 6488 int i, ir, ig, ib;
6427 6489
6428 if (cinfo.out_color_components > 2) 6490 if (mgr->cinfo.out_color_components > 2)
6429 ir = 0, ig = 1, ib = 2; 6491 ir = 0, ig = 1, ib = 2;
6430 else if (cinfo.out_color_components > 1) 6492 else if (mgr->cinfo.out_color_components > 1)
6431 ir = 0, ig = 1, ib = 0; 6493 ir = 0, ig = 1, ib = 0;
6432 else 6494 else
6433 ir = 0, ig = 0, ib = 0; 6495 ir = 0, ig = 0, ib = 0;
@@ -6437,15 +6499,15 @@ jpeg_load (struct frame *f, struct image *img)
6437 a default color, and we don't have to care about which colors 6499 a default color, and we don't have to care about which colors
6438 can be freed safely, and which can't. */ 6500 can be freed safely, and which can't. */
6439 init_color_table (); 6501 init_color_table ();
6440 colors = alloca (cinfo.actual_number_of_colors * sizeof *colors); 6502 colors = alloca (mgr->cinfo.actual_number_of_colors * sizeof *colors);
6441 6503
6442 for (i = 0; i < cinfo.actual_number_of_colors; ++i) 6504 for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
6443 { 6505 {
6444 /* Multiply RGB values with 255 because X expects RGB values 6506 /* Multiply RGB values with 255 because X expects RGB values
6445 in the range 0..0xffff. */ 6507 in the range 0..0xffff. */
6446 int r = cinfo.colormap[ir][i] << 8; 6508 int r = mgr->cinfo.colormap[ir][i] << 8;
6447 int g = cinfo.colormap[ig][i] << 8; 6509 int g = mgr->cinfo.colormap[ig][i] << 8;
6448 int b = cinfo.colormap[ib][i] << 8; 6510 int b = mgr->cinfo.colormap[ib][i] << 8;
6449 colors[i] = lookup_rgb_color (f, r, g, b); 6511 colors[i] = lookup_rgb_color (f, r, g, b);
6450 } 6512 }
6451 6513
@@ -6457,21 +6519,21 @@ jpeg_load (struct frame *f, struct image *img)
6457 } 6519 }
6458 6520
6459 /* Read pixels. */ 6521 /* Read pixels. */
6460 row_stride = width * cinfo.output_components; 6522 row_stride = width * mgr->cinfo.output_components;
6461 buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, 6523 buffer = mgr->cinfo.mem->alloc_sarray ((j_common_ptr) &mgr->cinfo,
6462 row_stride, 1); 6524 JPOOL_IMAGE, row_stride, 1);
6463 for (y = 0; y < height; ++y) 6525 for (y = 0; y < height; ++y)
6464 { 6526 {
6465 fn_jpeg_read_scanlines (&cinfo, buffer, 1); 6527 fn_jpeg_read_scanlines (&mgr->cinfo, buffer, 1);
6466 for (x = 0; x < cinfo.output_width; ++x) 6528 for (x = 0; x < mgr->cinfo.output_width; ++x)
6467 XPutPixel (ximg, x, y, colors[buffer[0][x]]); 6529 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
6468 } 6530 }
6469 6531
6470 /* Clean up. */ 6532 /* Clean up. */
6471 fn_jpeg_finish_decompress (&cinfo); 6533 fn_jpeg_finish_decompress (&mgr->cinfo);
6472 fn_jpeg_destroy_decompress (&cinfo); 6534 fn_jpeg_destroy_decompress (&mgr->cinfo);
6473 if (fp) 6535 if (fp)
6474 fclose ((FILE *) fp); 6536 fclose (fp);
6475 6537
6476 /* Maybe fill in the background field while we have ximg handy. */ 6538 /* Maybe fill in the background field while we have ximg handy. */
6477 if (NILP (image_spec_value (img->spec, QCbackground, NULL))) 6539 if (NILP (image_spec_value (img->spec, QCbackground, NULL)))
@@ -6484,6 +6546,13 @@ jpeg_load (struct frame *f, struct image *img)
6484 return 1; 6546 return 1;
6485} 6547}
6486 6548
6549static int
6550jpeg_load (struct frame *f, struct image *img)
6551{
6552 struct my_jpeg_error_mgr mgr;
6553 return jpeg_load_body (f, img, &mgr);
6554}
6555
6487#else /* HAVE_JPEG */ 6556#else /* HAVE_JPEG */
6488 6557
6489#ifdef HAVE_NS 6558#ifdef HAVE_NS