aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWilliam M. Perry1999-12-31 15:47:49 +0000
committerWilliam M. Perry1999-12-31 15:47:49 +0000
commit63448a4dc2fbe334435eeef39fa03e3b350a866a (patch)
treed53faca06956fc5e80299e2f76504e073e0bcca8 /src
parentc880678e3e327af3cd1d4230843a84bbe6303964 (diff)
downloademacs-63448a4dc2fbe334435eeef39fa03e3b350a866a.tar.gz
emacs-63448a4dc2fbe334435eeef39fa03e3b350a866a.zip
Changes to xfns.c to support reading images from a memory buffer instead of forcing them to be on disk. GIF/JPEG/PNG/TIFF currently support this.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog37
-rw-r--r--src/xfns.c493
2 files changed, 388 insertions, 142 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 079be7210c9..8992497582b 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,18 +1,37 @@
11999-12-31 William M. Perry <wmperry@aventail.com>
2
3 * xfns.c (jpeg_format): Added the :data keyword
4 (jpeg_image_p): JPEG is valid with :file _or_ :data
5 (jpeg_memory_src): Defined new JPEG image source to read from a
6 memory buffer.
7 (jpeg_load): Pay attention to the :data keyword if specified.
8 Instantiates a jpeg_memory_src instead of jpeg_stdio_src if
9 found.
10 (png_format): Added the :data keyword
11 (png_image_p): PNG is valid with :file _or_ :data
12 (png_read_from_memory): New PNG read function to read from a
13 memory buffer.
14 (png_load): Pay attention to the :data keyword if specified. Uses
15 png_set_read_fn() instead of png_init_io() if specified.
16 (tiff_format): Added the :data keyword for TIFF images.
17 (tiff_image_p): TIFF is valid with :file _or_ :data
18 (tiff_read_from_memory): Defined new TIFF I/O functions to read
19 from a memory buffer.
20 (tiff_load): Pay attention to the :data keyword if specified.
21 Uses TIFFClientOpen() instead of TIFFOpen() if specified.
22 (gif_format): Added the :data keyword
23 (gif_image_p): GIF is valid with :file _or_ :data
24 (gif_read_from_memory): New GIF input function to read from a
25 memory buffer.
26 (gif_load): Pay attention tot he :data keyword. Uses DGifOpen()
27 instead of DGifOpenFileName() if specified.
28
11999-12-31 Gerd Moellmann <gerd@gnu.org> 291999-12-31 Gerd Moellmann <gerd@gnu.org>
2 30
3 * xdisp.c (next_element_from_buffer): Change assertion at the end 31 * xdisp.c (next_element_from_buffer): Change assertion at the end
4 because it doesn't hold when there's an overlay string at the end 32 because it doesn't hold when there's an overlay string at the end
5 from which we deliver an image. 33 from which we deliver an image.
6 34
71999-12-31 William M. Perry <wmperry@gnu.org>
8
9 * xfns.c (enum jpeg_keyword_index): Add JPEG_DATA.
10 (jpeg_format): Add :data.
11 (jpeg_image_p): Handle :data.
12 (our_fill_input_buffer, our_skip_input_data, our_term_source)
13 (jpeg_memory_src): New functions.
14 (jpeg_load): Read image from string data.
15
161999-12-30 Eli Zaretskii <eliz@is.elta.co.il> 351999-12-30 Eli Zaretskii <eliz@is.elta.co.il>
17 36
18 * msdos.c (IT_update_begin): Don't dereference members of struct 37 * msdos.c (IT_update_begin): Don't dereference members of struct
diff --git a/src/xfns.c b/src/xfns.c
index 1752c13c7d3..f17455ef05a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -19,6 +19,9 @@ along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */ 20Boston, MA 02111-1307, USA. */
21 21
22/* Ability to read images from memory instead of a file added by
23 William Perry <wmperry@gnu.org> */
24
22/* Image support (XBM, XPM, PBM, JPEG, TIFF, GIF, PNG, GS). tooltips, 25/* Image support (XBM, XPM, PBM, JPEG, TIFF, GIF, PNG, GS). tooltips,
23 tool-bars, busy-cursor, file selection dialog added by Gerd 26 tool-bars, busy-cursor, file selection dialog added by Gerd
24 Moellmann <gerd@gnu.org>. */ 27 Moellmann <gerd@gnu.org>. */
@@ -7922,6 +7925,7 @@ Lisp_Object Qpng;
7922enum png_keyword_index 7925enum png_keyword_index
7923{ 7926{
7924 PNG_TYPE, 7927 PNG_TYPE,
7928 PNG_DATA,
7925 PNG_FILE, 7929 PNG_FILE,
7926 PNG_ASCENT, 7930 PNG_ASCENT,
7927 PNG_MARGIN, 7931 PNG_MARGIN,
@@ -7937,7 +7941,8 @@ enum png_keyword_index
7937static struct image_keyword png_format[PNG_LAST] = 7941static struct image_keyword png_format[PNG_LAST] =
7938{ 7942{
7939 {":type", IMAGE_SYMBOL_VALUE, 1}, 7943 {":type", IMAGE_SYMBOL_VALUE, 1},
7940 {":file", IMAGE_STRING_VALUE, 1}, 7944 {":data", IMAGE_STRING_VALUE, 0},
7945 {":file", IMAGE_STRING_VALUE, 0},
7941 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 7946 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
7942 {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, 7947 {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0},
7943 {":relief", IMAGE_INTEGER_VALUE, 0}, 7948 {":relief", IMAGE_INTEGER_VALUE, 0},
@@ -7970,6 +7975,13 @@ png_image_p (object)
7970 || (fmt[PNG_ASCENT].count 7975 || (fmt[PNG_ASCENT].count
7971 && XFASTINT (fmt[PNG_ASCENT].value) > 100)) 7976 && XFASTINT (fmt[PNG_ASCENT].value) > 100))
7972 return 0; 7977 return 0;
7978
7979 /* Must specify either the :data or :file keyword. This should
7980 ** probably be moved up into parse_image_spec, since it seems to be
7981 ** a general requirement.
7982 */
7983 if (!fmt[PNG_FILE].count && !fmt[PNG_DATA].count)
7984 return 0;
7973 return 1; 7985 return 1;
7974} 7986}
7975 7987
@@ -7997,6 +8009,28 @@ my_png_warning (png_ptr, msg)
7997 image_error ("PNG warning: %s", build_string (msg), Qnil); 8009 image_error ("PNG warning: %s", build_string (msg), Qnil);
7998} 8010}
7999 8011
8012/* Memory source for PNG decoding. Originally written for XEmacs by
8013 William Perry <wmperry@gnu.org>, who has paperwork on file, and so
8014 it is safe to use. */
8015struct png_memory_storage
8016{
8017 unsigned char *bytes; /* The data */
8018 size_t len; /* How big is it? */
8019 int index; /* Where are we? */
8020};
8021
8022static void
8023png_read_from_memory(png_structp png_ptr, png_bytep data,
8024 png_size_t length)
8025{
8026 struct png_memory_storage *tbr =
8027 (struct png_memory_storage *) png_get_io_ptr (png_ptr);
8028
8029 if (length > (tbr->len - tbr->index))
8030 png_error (png_ptr, (png_const_charp) "Read Error");
8031 memcpy (data,tbr->bytes + tbr->index,length);
8032 tbr->index = tbr->index + length;
8033}
8000 8034
8001/* Load PNG image IMG for use on frame F. Value is non-zero if 8035/* Load PNG image IMG for use on frame F. Value is non-zero if
8002 successful. */ 8036 successful. */
@@ -8007,12 +8041,13 @@ png_load (f, img)
8007 struct image *img; 8041 struct image *img;
8008{ 8042{
8009 Lisp_Object file, specified_file; 8043 Lisp_Object file, specified_file;
8044 Lisp_Object specified_data;
8010 int x, y, i; 8045 int x, y, i;
8011 XImage *ximg, *mask_img = NULL; 8046 XImage *ximg, *mask_img = NULL;
8012 struct gcpro gcpro1; 8047 struct gcpro gcpro1;
8013 png_struct *png_ptr = NULL; 8048 png_struct *png_ptr = NULL;
8014 png_info *info_ptr = NULL, *end_info = NULL; 8049 png_info *info_ptr = NULL, *end_info = NULL;
8015 FILE *fp; 8050 FILE *fp = NULL;
8016 png_byte sig[8]; 8051 png_byte sig[8];
8017 png_byte *pixels = NULL; 8052 png_byte *pixels = NULL;
8018 png_byte **rows = NULL; 8053 png_byte **rows = NULL;
@@ -8024,44 +8059,69 @@ png_load (f, img)
8024 char *gamma_str; 8059 char *gamma_str;
8025 double screen_gamma, image_gamma; 8060 double screen_gamma, image_gamma;
8026 int intent; 8061 int intent;
8062 struct png_memory_storage tbr; /* Data to be read */
8027 8063
8028 /* Find out what file to load. */ 8064 /* Find out what file to load. */
8029 specified_file = image_spec_value (img->spec, QCfile, NULL); 8065 specified_file = image_spec_value (img->spec, QCfile, NULL);
8030 file = x_find_image_file (specified_file); 8066 specified_data = image_spec_value (img->spec, QCdata, NULL);
8031 GCPRO1 (file);
8032 if (!STRINGP (file))
8033 {
8034 image_error ("Cannot find image file %s", specified_file, Qnil);
8035 UNGCPRO;
8036 return 0;
8037 }
8038 8067
8039 /* Open the image file. */ 8068 if (NILP (specified_data))
8040 fp = fopen (XSTRING (file)->data, "rb"); 8069 {
8041 if (!fp) 8070 file = x_find_image_file (specified_file);
8042 { 8071 GCPRO1 (file);
8043 image_error ("Cannot open image file %s", file, Qnil); 8072 if (!STRINGP (file))
8044 UNGCPRO; 8073 {
8045 fclose (fp); 8074 image_error ("Cannot find image file %s", specified_file, Qnil);
8046 return 0; 8075 UNGCPRO;
8047 } 8076 return 0;
8077 }
8048 8078
8049 /* Check PNG signature. */ 8079 /* Open the image file. */
8050 if (fread (sig, 1, sizeof sig, fp) != sizeof sig 8080 fp = fopen (XSTRING (file)->data, "rb");
8051 || !png_check_sig (sig, sizeof sig)) 8081 if (!fp)
8052 { 8082 {
8053 image_error ("Not a PNG file: %s", file, Qnil); 8083 image_error ("Cannot open image file %s", file, Qnil);
8054 UNGCPRO; 8084 UNGCPRO;
8055 fclose (fp); 8085 fclose (fp);
8056 return 0; 8086 return 0;
8057 } 8087 }
8088
8089 /* Check PNG signature. */
8090 if (fread (sig, 1, sizeof sig, fp) != sizeof sig
8091 || !png_check_sig (sig, sizeof sig))
8092 {
8093 image_error ("Not a PNG file: %s", file, Qnil);
8094 UNGCPRO;
8095 fclose (fp);
8096 return 0;
8097 }
8098 }
8099 else
8100 {
8101 /* Read from memory */
8102 tbr.bytes = XSTRING (specified_data)->data;
8103 tbr.len = STRING_BYTES (XSTRING (specified_data));
8104 tbr.index = 0;
8105
8106 /* Chekc PNG signature */
8107 if ((tbr.len < sizeof(sig)) ||
8108 !png_check_sig (tbr.bytes, sizeof(sig)))
8109 {
8110 image_error ("Not a PNG file: %s", file, Qnil);
8111 UNGCPRO;
8112 return 0;
8113 }
8114
8115 /* Need to skip past the signature */
8116 tbr.bytes += sizeof(sig);
8117 }
8058 8118
8059 /* Initialize read and info structs for PNG lib. */ 8119 /* Initialize read and info structs for PNG lib. */
8060 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, 8120 png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,
8061 my_png_error, my_png_warning); 8121 my_png_error, my_png_warning);
8062 if (!png_ptr) 8122 if (!png_ptr)
8063 { 8123 {
8064 fclose (fp); 8124 if (fp) fclose (fp);
8065 UNGCPRO; 8125 UNGCPRO;
8066 return 0; 8126 return 0;
8067 } 8127 }
@@ -8070,7 +8130,7 @@ png_load (f, img)
8070 if (!info_ptr) 8130 if (!info_ptr)
8071 { 8131 {
8072 png_destroy_read_struct (&png_ptr, NULL, NULL); 8132 png_destroy_read_struct (&png_ptr, NULL, NULL);
8073 fclose (fp); 8133 if (fp) fclose (fp);
8074 UNGCPRO; 8134 UNGCPRO;
8075 return 0; 8135 return 0;
8076 } 8136 }
@@ -8079,7 +8139,7 @@ png_load (f, img)
8079 if (!end_info) 8139 if (!end_info)
8080 { 8140 {
8081 png_destroy_read_struct (&png_ptr, &info_ptr, NULL); 8141 png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
8082 fclose (fp); 8142 if (fp) fclose (fp);
8083 UNGCPRO; 8143 UNGCPRO;
8084 return 0; 8144 return 0;
8085 } 8145 }
@@ -8093,14 +8153,17 @@ png_load (f, img)
8093 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info); 8153 png_destroy_read_struct (&png_ptr, &info_ptr, &end_info);
8094 xfree (pixels); 8154 xfree (pixels);
8095 xfree (rows); 8155 xfree (rows);
8096 if (fp) 8156 if (fp) fclose (fp);
8097 fclose (fp);
8098 UNGCPRO; 8157 UNGCPRO;
8099 return 0; 8158 return 0;
8100 } 8159 }
8101 8160
8102 /* Read image info. */ 8161 /* Read image info. */
8103 png_init_io (png_ptr, fp); 8162 if (!NILP (specified_data))
8163 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory);
8164 else
8165 png_init_io (png_ptr, fp);
8166
8104 png_set_sig_bytes (png_ptr, sizeof sig); 8167 png_set_sig_bytes (png_ptr, sizeof sig);
8105 png_read_info (png_ptr, info_ptr); 8168 png_read_info (png_ptr, info_ptr);
8106 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 8169 png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
@@ -8209,7 +8272,7 @@ png_load (f, img)
8209 /* Read the entire image. */ 8272 /* Read the entire image. */
8210 png_read_image (png_ptr, rows); 8273 png_read_image (png_ptr, rows);
8211 png_read_end (png_ptr, info_ptr); 8274 png_read_end (png_ptr, info_ptr);
8212 fclose (fp); 8275 if (fp) fclose (fp);
8213 fp = NULL; 8276 fp = NULL;
8214 8277
8215 BLOCK_INPUT; 8278 BLOCK_INPUT;
@@ -8391,7 +8454,7 @@ jpeg_image_p (object)
8391 8454
8392 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg) 8455 if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg)
8393 || (fmt[JPEG_ASCENT].count 8456 || (fmt[JPEG_ASCENT].count
8394 && XFASTINT (fmt[JPEG_ASCENT].value) > 100)) 8457 && XFASTINT (fmt[JPEG_ASCENT].value) > 100))
8395 return 0; 8458 return 0;
8396 8459
8397 /* Must specify either the :data or :file keyword. This should 8460 /* Must specify either the :data or :file keyword. This should
@@ -8415,7 +8478,6 @@ my_error_exit (cinfo)
8415 longjmp (mgr->setjmp_buffer, 1); 8478 longjmp (mgr->setjmp_buffer, 1);
8416} 8479}
8417 8480
8418
8419/* Init source method for JPEG data source manager. Called by 8481/* Init source method for JPEG data source manager. Called by
8420 jpeg_read_header() before any data is actually read. See 8482 jpeg_read_header() before any data is actually read. See
8421 libjpeg.doc from the JPEG lib distribution. */ 8483 libjpeg.doc from the JPEG lib distribution. */
@@ -8514,7 +8576,6 @@ jpeg_memory_src (cinfo, data, len)
8514 src->next_input_byte = data; 8576 src->next_input_byte = data;
8515} 8577}
8516 8578
8517
8518/* Load image IMG for use on frame F. Patterned after example.c 8579/* Load image IMG for use on frame F. Patterned after example.c
8519 from the JPEG lib. */ 8580 from the JPEG lib. */
8520 8581
@@ -8562,41 +8623,41 @@ jpeg_load (f, img)
8562 } 8623 }
8563 8624
8564 /* Customize libjpeg's error handling to call my_error_exit 8625 /* Customize libjpeg's error handling to call my_error_exit
8565 when an error is detected. This function will perform 8626 when an error is detected. This function will perform
8566 a longjmp. */ 8627 a longjmp. */
8567 mgr.pub.error_exit = my_error_exit; 8628 mgr.pub.error_exit = my_error_exit;
8568 cinfo.err = jpeg_std_error (&mgr.pub); 8629 cinfo.err = jpeg_std_error (&mgr.pub);
8569 8630
8570 if ((rc = setjmp (mgr.setjmp_buffer)) != 0) 8631 if ((rc = setjmp (mgr.setjmp_buffer)) != 0)
8571 { 8632 {
8572 if (rc == 1) 8633 if (rc == 1)
8573 { 8634 {
8574 /* Called from my_error_exit. Display a JPEG error. */ 8635 /* Called from my_error_exit. Display a JPEG error. */
8575 char buffer[JMSG_LENGTH_MAX]; 8636 char buffer[JMSG_LENGTH_MAX];
8576 cinfo.err->format_message ((j_common_ptr) &cinfo, buffer); 8637 cinfo.err->format_message ((j_common_ptr) &cinfo, buffer);
8577 image_error ("Error reading JPEG file `%s': %s", file, 8638 image_error ("Error reading JPEG file `%s': %s", file,
8578 build_string (buffer)); 8639 build_string (buffer));
8579 } 8640 }
8580 8641
8581 /* Close the input file and destroy the JPEG object. */ 8642 /* Close the input file and destroy the JPEG object. */
8582 if (fp) fclose (fp); 8643 if (fp) fclose (fp);
8583 jpeg_destroy_decompress (&cinfo); 8644 jpeg_destroy_decompress (&cinfo);
8584 8645
8585 BLOCK_INPUT; 8646 BLOCK_INPUT;
8586 8647
8587 /* If we already have an XImage, free that. */ 8648 /* If we already have an XImage, free that. */
8588 x_destroy_x_image (ximg); 8649 x_destroy_x_image (ximg);
8589 8650
8590 /* Free pixmap and colors. */ 8651 /* Free pixmap and colors. */
8591 x_clear_image (f, img); 8652 x_clear_image (f, img);
8592 8653
8593 UNBLOCK_INPUT; 8654 UNBLOCK_INPUT;
8594 UNGCPRO; 8655 UNGCPRO;
8595 return 0; 8656 return 0;
8596 } 8657 }
8597 8658
8598 /* Create the JPEG decompression object. Let it read from fp. 8659 /* Create the JPEG decompression object. Let it read from fp.
8599 Read the JPEG image header. */ 8660 Read the JPEG image header. */
8600 jpeg_create_decompress (&cinfo); 8661 jpeg_create_decompress (&cinfo);
8601 8662
8602 if (NILP (specified_data)) 8663 if (NILP (specified_data))
@@ -8604,11 +8665,11 @@ jpeg_load (f, img)
8604 else 8665 else
8605 jpeg_memory_src (&cinfo, XSTRING (specified_data)->data, 8666 jpeg_memory_src (&cinfo, XSTRING (specified_data)->data,
8606 STRING_BYTES (XSTRING (specified_data))); 8667 STRING_BYTES (XSTRING (specified_data)));
8607 8668
8608 jpeg_read_header (&cinfo, TRUE); 8669 jpeg_read_header (&cinfo, TRUE);
8609 8670
8610 /* Customize decompression so that color quantization will be used. 8671 /* Customize decompression so that color quantization will be used.
8611 Start decompression. */ 8672 Start decompression. */
8612 cinfo.quantize_colors = TRUE; 8673 cinfo.quantize_colors = TRUE;
8613 jpeg_start_decompress (&cinfo); 8674 jpeg_start_decompress (&cinfo);
8614 width = img->width = cinfo.output_width; 8675 width = img->width = cinfo.output_width;
@@ -8618,59 +8679,59 @@ jpeg_load (f, img)
8618 8679
8619 /* Create X image and pixmap. */ 8680 /* Create X image and pixmap. */
8620 if (!x_create_x_image_and_pixmap (f, file, width, height, 0, &ximg, 8681 if (!x_create_x_image_and_pixmap (f, file, width, height, 0, &ximg,
8621 &img->pixmap)) 8682 &img->pixmap))
8622 { 8683 {
8623 UNBLOCK_INPUT; 8684 UNBLOCK_INPUT;
8624 longjmp (mgr.setjmp_buffer, 2); 8685 longjmp (mgr.setjmp_buffer, 2);
8625 } 8686 }
8626 8687
8627 /* Allocate colors. When color quantization is used, 8688 /* Allocate colors. When color quantization is used,
8628 cinfo.actual_number_of_colors has been set with the number of 8689 cinfo.actual_number_of_colors has been set with the number of
8629 colors generated, and cinfo.colormap is a two-dimensional array 8690 colors generated, and cinfo.colormap is a two-dimensional array
8630 of color indices in the range 0..cinfo.actual_number_of_colors. 8691 of color indices in the range 0..cinfo.actual_number_of_colors.
8631 No more than 255 colors will be generated. */ 8692 No more than 255 colors will be generated. */
8632 { 8693 {
8633 int i, ir, ig, ib; 8694 int i, ir, ig, ib;
8634 8695
8635 if (cinfo.out_color_components > 2) 8696 if (cinfo.out_color_components > 2)
8636 ir = 0, ig = 1, ib = 2; 8697 ir = 0, ig = 1, ib = 2;
8637 else if (cinfo.out_color_components > 1) 8698 else if (cinfo.out_color_components > 1)
8638 ir = 0, ig = 1, ib = 0; 8699 ir = 0, ig = 1, ib = 0;
8639 else 8700 else
8640 ir = 0, ig = 0, ib = 0; 8701 ir = 0, ig = 0, ib = 0;
8641 8702
8642 /* Use the color table mechanism because it handles colors that 8703 /* Use the color table mechanism because it handles colors that
8643 cannot be allocated nicely. Such colors will be replaced with 8704 cannot be allocated nicely. Such colors will be replaced with
8644 a default color, and we don't have to care about which colors 8705 a default color, and we don't have to care about which colors
8645 can be freed safely, and which can't. */ 8706 can be freed safely, and which can't. */
8646 init_color_table (); 8707 init_color_table ();
8647 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors 8708 colors = (unsigned long *) alloca (cinfo.actual_number_of_colors
8648 * sizeof *colors); 8709 * sizeof *colors);
8649 8710
8650 for (i = 0; i < cinfo.actual_number_of_colors; ++i) 8711 for (i = 0; i < cinfo.actual_number_of_colors; ++i)
8651 { 8712 {
8652 /* Multiply RGB values with 255 because X expects RGB values 8713 /* Multiply RGB values with 255 because X expects RGB values
8653 in the range 0..0xffff. */ 8714 in the range 0..0xffff. */
8654 int r = cinfo.colormap[ir][i] << 8; 8715 int r = cinfo.colormap[ir][i] << 8;
8655 int g = cinfo.colormap[ig][i] << 8; 8716 int g = cinfo.colormap[ig][i] << 8;
8656 int b = cinfo.colormap[ib][i] << 8; 8717 int b = cinfo.colormap[ib][i] << 8;
8657 colors[i] = lookup_rgb_color (f, r, g, b); 8718 colors[i] = lookup_rgb_color (f, r, g, b);
8658 } 8719 }
8659 8720
8660 /* Remember those colors actually allocated. */ 8721 /* Remember those colors actually allocated. */
8661 img->colors = colors_in_color_table (&img->ncolors); 8722 img->colors = colors_in_color_table (&img->ncolors);
8662 free_color_table (); 8723 free_color_table ();
8663 } 8724 }
8664 8725
8665 /* Read pixels. */ 8726 /* Read pixels. */
8666 row_stride = width * cinfo.output_components; 8727 row_stride = width * cinfo.output_components;
8667 buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, 8728 buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE,
8668 row_stride, 1); 8729 row_stride, 1);
8669 for (y = 0; y < height; ++y) 8730 for (y = 0; y < height; ++y)
8670 { 8731 {
8671 jpeg_read_scanlines (&cinfo, buffer, 1); 8732 jpeg_read_scanlines (&cinfo, buffer, 1);
8672 for (x = 0; x < cinfo.output_width; ++x) 8733 for (x = 0; x < cinfo.output_width; ++x)
8673 XPutPixel (ximg, x, y, colors[buffer[0][x]]); 8734 XPutPixel (ximg, x, y, colors[buffer[0][x]]);
8674 } 8735 }
8675 8736
8676 /* Clean up. */ 8737 /* Clean up. */
@@ -8710,6 +8771,7 @@ Lisp_Object Qtiff;
8710enum tiff_keyword_index 8771enum tiff_keyword_index
8711{ 8772{
8712 TIFF_TYPE, 8773 TIFF_TYPE,
8774 TIFF_DATA,
8713 TIFF_FILE, 8775 TIFF_FILE,
8714 TIFF_ASCENT, 8776 TIFF_ASCENT,
8715 TIFF_MARGIN, 8777 TIFF_MARGIN,
@@ -8725,7 +8787,8 @@ enum tiff_keyword_index
8725static struct image_keyword tiff_format[TIFF_LAST] = 8787static struct image_keyword tiff_format[TIFF_LAST] =
8726{ 8788{
8727 {":type", IMAGE_SYMBOL_VALUE, 1}, 8789 {":type", IMAGE_SYMBOL_VALUE, 1},
8728 {":file", IMAGE_STRING_VALUE, 1}, 8790 {":data", IMAGE_STRING_VALUE, 0},
8791 {":file", IMAGE_STRING_VALUE, 0},
8729 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 8792 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
8730 {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, 8793 {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0},
8731 {":relief", IMAGE_INTEGER_VALUE, 0}, 8794 {":relief", IMAGE_INTEGER_VALUE, 0},
@@ -8758,9 +8821,92 @@ tiff_image_p (object)
8758 || (fmt[TIFF_ASCENT].count 8821 || (fmt[TIFF_ASCENT].count
8759 && XFASTINT (fmt[TIFF_ASCENT].value) > 100)) 8822 && XFASTINT (fmt[TIFF_ASCENT].value) > 100))
8760 return 0; 8823 return 0;
8824 /* Must specify either the :data or :file keyword. This should
8825 ** probably be moved up into parse_image_spec, since it seems to be
8826 ** a general requirement.
8827 */
8828 if (!fmt[TIFF_FILE].count && !fmt[TIFF_DATA].count)
8829 return 0;
8761 return 1; 8830 return 1;
8762} 8831}
8763 8832
8833/* Reading from a memory buffer for TIFF images
8834 Based on the PNG memory source, but we have to provide a lot of
8835 extra functions. Blah.
8836
8837 We really only need to implement read and seek, but I am not
8838 convinced that the TIFF library is smart enough not to destroy
8839 itself if we only hand it the function pointers we need to
8840 override. */
8841typedef struct {
8842 unsigned char *bytes;
8843 size_t len;
8844 int index;
8845} tiff_memory_source;
8846
8847static size_t tiff_read_from_memory(thandle_t data, tdata_t buf, tsize_t size)
8848{
8849 tiff_memory_source *src = (tiff_memory_source *)data;
8850
8851 if (size > src->len - src->index)
8852 return (size_t) -1;
8853 memcpy(buf, src->bytes + src->index, size);
8854 src->index += size;
8855 return size;
8856}
8857
8858static size_t tiff_write_from_memory(thandle_t data, tdata_t buf, tsize_t size)
8859{
8860 return (size_t) -1;
8861}
8862
8863static toff_t tiff_seek_in_memory(thandle_t data, toff_t off, int whence)
8864{
8865 tiff_memory_source *src = (tiff_memory_source *)data;
8866 int idx;
8867
8868 switch (whence)
8869 {
8870 case SEEK_SET: /* Go from beginning of source */
8871 idx = off;
8872 break;
8873 case SEEK_END: /* Go from end of source */
8874 idx = src->len + off;
8875 break;
8876 case SEEK_CUR: /* Go from current position */
8877 idx = src->index + off;
8878 break;
8879 default: /* Invalid `whence' */
8880 return(-1);
8881 }
8882 if ((idx > src->len) || (idx < 0))
8883 return -1;
8884 src->index = idx;
8885 return src->index;
8886}
8887
8888static int tiff_close_memory(thandle_t data)
8889{
8890 /* NOOP */
8891 return(0);
8892}
8893
8894static int tiff_mmap_memory(thandle_t data, tdata_t *pbase, toff_t *psize)
8895{
8896 /* It is already _IN_ memory. */
8897 return(0);
8898}
8899
8900static void tiff_unmap_memory(thandle_t data, tdata_t base, toff_t size)
8901{
8902 /* We don't need to do this. */
8903 return;
8904}
8905
8906static toff_t tiff_size_of_memory(thandle_t data)
8907{
8908 return(((tiff_memory_source *) data)->len);
8909}
8764 8910
8765/* Load TIFF image IMG for use on frame F. Value is non-zero if 8911/* Load TIFF image IMG for use on frame F. Value is non-zero if
8766 successful. */ 8912 successful. */
@@ -8771,31 +8917,62 @@ tiff_load (f, img)
8771 struct image *img; 8917 struct image *img;
8772{ 8918{
8773 Lisp_Object file, specified_file; 8919 Lisp_Object file, specified_file;
8920 Lisp_Object specified_data;
8774 TIFF *tiff; 8921 TIFF *tiff;
8775 int width, height, x, y; 8922 int width, height, x, y;
8776 uint32 *buf; 8923 uint32 *buf;
8777 int rc; 8924 int rc;
8778 XImage *ximg; 8925 XImage *ximg;
8779 struct gcpro gcpro1; 8926 struct gcpro gcpro1;
8927 tiff_memory_source memsrc;
8780 8928
8781 specified_file = image_spec_value (img->spec, QCfile, NULL); 8929 specified_file = image_spec_value (img->spec, QCfile, NULL);
8782 file = x_find_image_file (specified_file); 8930 specified_data = image_spec_value (img->spec, QCdata, NULL);
8783 GCPRO1 (file); 8931
8784 if (!STRINGP (file)) 8932 if (NILP (specified_data))
8785 { 8933 {
8786 image_error ("Cannot find image file %s", file, Qnil); 8934 /* Read from a file */
8787 UNGCPRO; 8935 file = x_find_image_file (specified_file);
8788 return 0; 8936 GCPRO1 (file);
8789 } 8937 if (!STRINGP (file))
8790 8938 {
8791 /* Try to open the image file. */ 8939 image_error ("Cannot find image file %s", file, Qnil);
8792 tiff = TIFFOpen (XSTRING (file)->data, "r"); 8940 UNGCPRO;
8793 if (tiff == NULL) 8941 return 0;
8794 { 8942 }
8795 image_error ("Cannot open `%s'", file, Qnil); 8943
8796 UNGCPRO; 8944 /* Try to open the image file. */
8797 return 0; 8945 tiff = TIFFOpen (XSTRING (file)->data, "r");
8798 } 8946 if (tiff == NULL)
8947 {
8948 image_error ("Cannot open `%s'", file, Qnil);
8949 UNGCPRO;
8950 return 0;
8951 }
8952 }
8953 else
8954 {
8955 /* Memory source! */
8956 memsrc.bytes = XSTRING (specified_data)->data;
8957 memsrc.len = STRING_BYTES (XSTRING (specified_data));
8958 memsrc.index = 0;
8959
8960 tiff = TIFFClientOpen ("memory_source", "r", &memsrc,
8961 (TIFFReadWriteProc)tiff_read_from_memory,
8962 (TIFFReadWriteProc)tiff_write_from_memory,
8963 tiff_seek_in_memory,
8964 tiff_close_memory,
8965 tiff_size_of_memory,
8966 tiff_mmap_memory,
8967 tiff_unmap_memory);
8968
8969 if (!tiff)
8970 {
8971 image_error ("Cannot open memory source `%s'. ", specified_data, Qnil);
8972 UNGCPRO;
8973 return 0;
8974 }
8975 }
8799 8976
8800 /* Get width and height of the image, and allocate a raster buffer 8977 /* Get width and height of the image, and allocate a raster buffer
8801 of width x height 32-bit values. */ 8978 of width x height 32-bit values. */
@@ -8884,6 +9061,7 @@ Lisp_Object Qgif;
8884enum gif_keyword_index 9061enum gif_keyword_index
8885{ 9062{
8886 GIF_TYPE, 9063 GIF_TYPE,
9064 GIF_DATA,
8887 GIF_FILE, 9065 GIF_FILE,
8888 GIF_ASCENT, 9066 GIF_ASCENT,
8889 GIF_MARGIN, 9067 GIF_MARGIN,
@@ -8900,7 +9078,8 @@ enum gif_keyword_index
8900static struct image_keyword gif_format[GIF_LAST] = 9078static struct image_keyword gif_format[GIF_LAST] =
8901{ 9079{
8902 {":type", IMAGE_SYMBOL_VALUE, 1}, 9080 {":type", IMAGE_SYMBOL_VALUE, 1},
8903 {":file", IMAGE_STRING_VALUE, 1}, 9081 {":data", IMAGE_STRING_VALUE, 0},
9082 {":file", IMAGE_STRING_VALUE, 0},
8904 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, 9083 {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0},
8905 {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, 9084 {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0},
8906 {":relief", IMAGE_INTEGER_VALUE, 0}, 9085 {":relief", IMAGE_INTEGER_VALUE, 0},
@@ -8934,9 +9113,35 @@ gif_image_p (object)
8934 || (fmt[GIF_ASCENT].count 9113 || (fmt[GIF_ASCENT].count
8935 && XFASTINT (fmt[GIF_ASCENT].value) > 100)) 9114 && XFASTINT (fmt[GIF_ASCENT].value) > 100))
8936 return 0; 9115 return 0;
9116 /* Must specify either the :data or :file keyword. This should
9117 ** probably be moved up into parse_image_spec, since it seems to be
9118 ** a general requirement.
9119 */
9120 if (!fmt[GIF_FILE].count && !fmt[GIF_DATA].count)
9121 return 0;
8937 return 1; 9122 return 1;
8938} 9123}
8939 9124
9125/* Reading a GIF image from memory
9126 Based on the PNG memory stuff to a certain extent. */
9127
9128typedef struct {
9129 unsigned char *bytes;
9130 size_t len;
9131 int index;
9132} gif_memory_source;
9133
9134static int gif_read_from_memory(GifFileType *file, GifByteType *buf, int len)
9135{
9136 gif_memory_source *src = (gif_memory_source *) file->UserData;
9137
9138 if (len > (src->len - src->index))
9139 return -1;
9140
9141 memcpy(buf, src->bytes + src->index, len);
9142 src->index += len;
9143 return len;
9144}
8940 9145
8941/* Load GIF image IMG for use on frame F. Value is non-zero if 9146/* Load GIF image IMG for use on frame F. Value is non-zero if
8942 successful. */ 9147 successful. */
@@ -8947,6 +9152,7 @@ gif_load (f, img)
8947 struct image *img; 9152 struct image *img;
8948{ 9153{
8949 Lisp_Object file, specified_file; 9154 Lisp_Object file, specified_file;
9155 Lisp_Object specified_data;
8950 int rc, width, height, x, y, i; 9156 int rc, width, height, x, y, i;
8951 XImage *ximg; 9157 XImage *ximg;
8952 ColorMapObject *gif_color_map; 9158 ColorMapObject *gif_color_map;
@@ -8955,25 +9161,46 @@ gif_load (f, img)
8955 struct gcpro gcpro1; 9161 struct gcpro gcpro1;
8956 Lisp_Object image; 9162 Lisp_Object image;
8957 int ino, image_left, image_top, image_width, image_height; 9163 int ino, image_left, image_top, image_width, image_height;
9164 gif_memory_source memsrc;
8958 9165
8959 specified_file = image_spec_value (img->spec, QCfile, NULL); 9166 specified_file = image_spec_value (img->spec, QCfile, NULL);
8960 file = x_find_image_file (specified_file); 9167 specified_data = image_spec_value (img->spec, QCdata, NULL);
8961 GCPRO1 (file); 9168
8962 if (!STRINGP (file)) 9169 if (NILP (specified_data))
8963 { 9170 {
8964 image_error ("Cannot find image file %s", specified_file, Qnil); 9171 file = x_find_image_file (specified_file);
8965 UNGCPRO; 9172 GCPRO1 (file);
8966 return 0; 9173 if (!STRINGP (file))
8967 } 9174 {
9175 image_error ("Cannot find image file %s", specified_file, Qnil);
9176 UNGCPRO;
9177 return 0;
9178 }
8968 9179
8969 /* Open the GIF file. */ 9180 /* Open the GIF file. */
8970 gif = DGifOpenFileName (XSTRING (file)->data); 9181 gif = DGifOpenFileName (XSTRING (file)->data);
8971 if (gif == NULL) 9182 if (gif == NULL)
8972 { 9183 {
8973 image_error ("Cannot open `%s'", file, Qnil); 9184 image_error ("Cannot open `%s'", file, Qnil);
8974 UNGCPRO; 9185 UNGCPRO;
8975 return 0; 9186 return 0;
8976 } 9187 }
9188 }
9189 else
9190 {
9191 /* Read from memory! */
9192 memsrc.bytes = XSTRING (specified_data)->data;
9193 memsrc.len = STRING_BYTES (XSTRING (specified_data));
9194 memsrc.index = 0;
9195
9196 gif = DGifOpen(&memsrc, gif_read_from_memory);
9197 if (!gif)
9198 {
9199 image_error ("Cannot open memory source `%s'",specified_data, Qnil);
9200 UNGCPRO;
9201 return 0;
9202 }
9203 }
8977 9204
8978 /* Read entire contents. */ 9205 /* Read entire contents. */
8979 rc = DGifSlurp (gif); 9206 rc = DGifSlurp (gif);