diff options
| author | Gerd Moellmann | 1999-12-31 16:47:13 +0000 |
|---|---|---|
| committer | Gerd Moellmann | 1999-12-31 16:47:13 +0000 |
| commit | 5ad6a5fb896e298052f0d08480933336833b986f (patch) | |
| tree | 1833ce96327acab7f5b5039a2f3e28e2d6470545 /src | |
| parent | bc28370787eb85b1df6dfa89b015750b60fb69d5 (diff) | |
| download | emacs-5ad6a5fb896e298052f0d08480933336833b986f.tar.gz emacs-5ad6a5fb896e298052f0d08480933336833b986f.zip | |
New image functions adapted to Emacs conventions.
(png_load, tiff_load, jpeg_load, gif_load): Always GCPRO local
variable `file'.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/xfns.c | 554 |
2 files changed, 306 insertions, 254 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 8992497582b..ea19bf734eb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 1999-12-31 Gerd Moellmann <gerd@gnu.org> | ||
| 2 | |||
| 3 | * xfns.c: New image functions adapted to Emacs conventions. | ||
| 4 | (png_load, tiff_load, jpeg_load, gif_load): Always GCPRO local | ||
| 5 | variable `file'. | ||
| 6 | |||
| 1 | 1999-12-31 William M. Perry <wmperry@aventail.com> | 7 | 1999-12-31 William M. Perry <wmperry@aventail.com> |
| 2 | 8 | ||
| 3 | * xfns.c (jpeg_format): Added the :data keyword | 9 | * xfns.c (jpeg_format): Added the :data keyword |
diff --git a/src/xfns.c b/src/xfns.c index f17455ef05a..c1c1eaf5c75 100644 --- a/src/xfns.c +++ b/src/xfns.c | |||
| @@ -7941,7 +7941,7 @@ enum png_keyword_index | |||
| 7941 | static struct image_keyword png_format[PNG_LAST] = | 7941 | static struct image_keyword png_format[PNG_LAST] = |
| 7942 | { | 7942 | { |
| 7943 | {":type", IMAGE_SYMBOL_VALUE, 1}, | 7943 | {":type", IMAGE_SYMBOL_VALUE, 1}, |
| 7944 | {":data", IMAGE_STRING_VALUE, 0}, | 7944 | {":data", IMAGE_STRING_VALUE, 0}, |
| 7945 | {":file", IMAGE_STRING_VALUE, 0}, | 7945 | {":file", IMAGE_STRING_VALUE, 0}, |
| 7946 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, | 7946 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
| 7947 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, | 7947 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, |
| @@ -7977,12 +7977,9 @@ png_image_p (object) | |||
| 7977 | return 0; | 7977 | return 0; |
| 7978 | 7978 | ||
| 7979 | /* Must specify either the :data or :file keyword. This should | 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 | 7980 | probably be moved up into parse_image_spec, since it seems to be |
| 7981 | ** a general requirement. | 7981 | a general requirement. */ |
| 7982 | */ | 7982 | return fmt[PNG_FILE].count || fmt[PNG_DATA].count; |
| 7983 | if (!fmt[PNG_FILE].count && !fmt[PNG_DATA].count) | ||
| 7984 | return 0; | ||
| 7985 | return 1; | ||
| 7986 | } | 7983 | } |
| 7987 | 7984 | ||
| 7988 | 7985 | ||
| @@ -8009,27 +8006,34 @@ my_png_warning (png_ptr, msg) | |||
| 8009 | image_error ("PNG warning: %s", build_string (msg), Qnil); | 8006 | image_error ("PNG warning: %s", build_string (msg), Qnil); |
| 8010 | } | 8007 | } |
| 8011 | 8008 | ||
| 8012 | /* Memory source for PNG decoding. Originally written for XEmacs by | 8009 | /* Memory source for PNG decoding. */ |
| 8013 | William Perry <wmperry@gnu.org>, who has paperwork on file, and so | 8010 | |
| 8014 | it is safe to use. */ | ||
| 8015 | struct png_memory_storage | 8011 | struct png_memory_storage |
| 8016 | { | 8012 | { |
| 8017 | unsigned char *bytes; /* The data */ | 8013 | unsigned char *bytes; /* The data */ |
| 8018 | size_t len; /* How big is it? */ | 8014 | size_t len; /* How big is it? */ |
| 8019 | int index; /* Where are we? */ | 8015 | int index; /* Where are we? */ |
| 8020 | }; | 8016 | }; |
| 8021 | 8017 | ||
| 8018 | |||
| 8019 | /* Function set as reader function when reading PNG image from memory. | ||
| 8020 | PNG_PTR is a pointer to the PNG control structure. Copy LENGTH | ||
| 8021 | bytes from the input to DATA. */ | ||
| 8022 | |||
| 8022 | static void | 8023 | static void |
| 8023 | png_read_from_memory(png_structp png_ptr, png_bytep data, | 8024 | png_read_from_memory (png_ptr, data, length) |
| 8024 | png_size_t length) | 8025 | png_structp png_ptr; |
| 8026 | png_bytep data; | ||
| 8027 | png_size_t length; | ||
| 8025 | { | 8028 | { |
| 8026 | struct png_memory_storage *tbr = | 8029 | struct png_memory_storage *tbr |
| 8027 | (struct png_memory_storage *) png_get_io_ptr (png_ptr); | 8030 | = (struct png_memory_storage *) png_get_io_ptr (png_ptr); |
| 8028 | 8031 | ||
| 8029 | if (length > (tbr->len - tbr->index)) | 8032 | if (length > tbr->len - tbr->index) |
| 8030 | png_error (png_ptr, (png_const_charp) "Read Error"); | 8033 | png_error (png_ptr, "Read error"); |
| 8031 | memcpy (data,tbr->bytes + tbr->index,length); | 8034 | |
| 8032 | tbr->index = tbr->index + length; | 8035 | bcopy (tbr->bytes + tbr->index, data, length); |
| 8036 | tbr->index = tbr->index + length; | ||
| 8033 | } | 8037 | } |
| 8034 | 8038 | ||
| 8035 | /* Load PNG image IMG for use on frame F. Value is non-zero if | 8039 | /* Load PNG image IMG for use on frame F. Value is non-zero if |
| @@ -8064,58 +8068,59 @@ png_load (f, img) | |||
| 8064 | /* Find out what file to load. */ | 8068 | /* Find out what file to load. */ |
| 8065 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 8069 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 8066 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 8070 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 8071 | file = Qnil; | ||
| 8072 | GCPRO1 (file); | ||
| 8067 | 8073 | ||
| 8068 | if (NILP (specified_data)) | 8074 | if (NILP (specified_data)) |
| 8075 | { | ||
| 8076 | file = x_find_image_file (specified_file); | ||
| 8077 | if (!STRINGP (file)) | ||
| 8069 | { | 8078 | { |
| 8070 | file = x_find_image_file (specified_file); | 8079 | image_error ("Cannot find image file %s", specified_file, Qnil); |
| 8071 | GCPRO1 (file); | 8080 | UNGCPRO; |
| 8072 | if (!STRINGP (file)) | 8081 | return 0; |
| 8073 | { | 8082 | } |
| 8074 | image_error ("Cannot find image file %s", specified_file, Qnil); | ||
| 8075 | UNGCPRO; | ||
| 8076 | return 0; | ||
| 8077 | } | ||
| 8078 | 8083 | ||
| 8079 | /* Open the image file. */ | 8084 | /* Open the image file. */ |
| 8080 | fp = fopen (XSTRING (file)->data, "rb"); | 8085 | fp = fopen (XSTRING (file)->data, "rb"); |
| 8081 | if (!fp) | 8086 | if (!fp) |
| 8082 | { | 8087 | { |
| 8083 | image_error ("Cannot open image file %s", file, Qnil); | 8088 | image_error ("Cannot open image file %s", file, Qnil); |
| 8084 | UNGCPRO; | 8089 | UNGCPRO; |
| 8085 | fclose (fp); | 8090 | fclose (fp); |
| 8086 | return 0; | 8091 | return 0; |
| 8087 | } | 8092 | } |
| 8088 | 8093 | ||
| 8089 | /* Check PNG signature. */ | 8094 | /* Check PNG signature. */ |
| 8090 | if (fread (sig, 1, sizeof sig, fp) != sizeof sig | 8095 | if (fread (sig, 1, sizeof sig, fp) != sizeof sig |
| 8091 | || !png_check_sig (sig, sizeof sig)) | 8096 | || !png_check_sig (sig, sizeof sig)) |
| 8092 | { | 8097 | { |
| 8093 | image_error ("Not a PNG file: %s", file, Qnil); | 8098 | image_error ("Not a PNG file: %s", file, Qnil); |
| 8094 | UNGCPRO; | 8099 | UNGCPRO; |
| 8095 | fclose (fp); | 8100 | fclose (fp); |
| 8096 | return 0; | 8101 | return 0; |
| 8097 | } | ||
| 8098 | } | 8102 | } |
| 8103 | } | ||
| 8099 | else | 8104 | else |
| 8100 | { | 8105 | { |
| 8101 | /* Read from memory */ | 8106 | /* Read from memory. */ |
| 8102 | tbr.bytes = XSTRING (specified_data)->data; | 8107 | tbr.bytes = XSTRING (specified_data)->data; |
| 8103 | tbr.len = STRING_BYTES (XSTRING (specified_data)); | 8108 | tbr.len = STRING_BYTES (XSTRING (specified_data)); |
| 8104 | tbr.index = 0; | 8109 | 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 | 8110 | ||
| 8115 | /* Need to skip past the signature */ | 8111 | /* Check PNG signature. */ |
| 8116 | tbr.bytes += sizeof(sig); | 8112 | if (tbr.len < sizeof sig |
| 8113 | || !png_check_sig (tbr.bytes, sizeof sig)) | ||
| 8114 | { | ||
| 8115 | image_error ("Not a PNG file: %s", file, Qnil); | ||
| 8116 | UNGCPRO; | ||
| 8117 | return 0; | ||
| 8117 | } | 8118 | } |
| 8118 | 8119 | ||
| 8120 | /* Need to skip past the signature. */ | ||
| 8121 | tbr.bytes += sizeof (sig); | ||
| 8122 | } | ||
| 8123 | |||
| 8119 | /* Initialize read and info structs for PNG lib. */ | 8124 | /* Initialize read and info structs for PNG lib. */ |
| 8120 | png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, | 8125 | png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, |
| 8121 | my_png_error, my_png_warning); | 8126 | my_png_error, my_png_warning); |
| @@ -8160,9 +8165,9 @@ png_load (f, img) | |||
| 8160 | 8165 | ||
| 8161 | /* Read image info. */ | 8166 | /* Read image info. */ |
| 8162 | if (!NILP (specified_data)) | 8167 | if (!NILP (specified_data)) |
| 8163 | png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory); | 8168 | png_set_read_fn (png_ptr, (void *) &tbr, png_read_from_memory); |
| 8164 | else | 8169 | else |
| 8165 | png_init_io (png_ptr, fp); | 8170 | png_init_io (png_ptr, fp); |
| 8166 | 8171 | ||
| 8167 | png_set_sig_bytes (png_ptr, sizeof sig); | 8172 | png_set_sig_bytes (png_ptr, sizeof sig); |
| 8168 | png_read_info (png_ptr, info_ptr); | 8173 | png_read_info (png_ptr, info_ptr); |
| @@ -8272,8 +8277,11 @@ png_load (f, img) | |||
| 8272 | /* Read the entire image. */ | 8277 | /* Read the entire image. */ |
| 8273 | png_read_image (png_ptr, rows); | 8278 | png_read_image (png_ptr, rows); |
| 8274 | png_read_end (png_ptr, info_ptr); | 8279 | png_read_end (png_ptr, info_ptr); |
| 8275 | if (fp) fclose (fp); | 8280 | if (fp) |
| 8276 | fp = NULL; | 8281 | { |
| 8282 | fclose (fp); | ||
| 8283 | fp = NULL; | ||
| 8284 | } | ||
| 8277 | 8285 | ||
| 8278 | BLOCK_INPUT; | 8286 | BLOCK_INPUT; |
| 8279 | 8287 | ||
| @@ -8421,7 +8429,7 @@ enum jpeg_keyword_index | |||
| 8421 | static struct image_keyword jpeg_format[JPEG_LAST] = | 8429 | static struct image_keyword jpeg_format[JPEG_LAST] = |
| 8422 | { | 8430 | { |
| 8423 | {":type", IMAGE_SYMBOL_VALUE, 1}, | 8431 | {":type", IMAGE_SYMBOL_VALUE, 1}, |
| 8424 | {":data", IMAGE_STRING_VALUE, 0}, | 8432 | {":data", IMAGE_STRING_VALUE, 0}, |
| 8425 | {":file", IMAGE_STRING_VALUE, 0}, | 8433 | {":file", IMAGE_STRING_VALUE, 0}, |
| 8426 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, | 8434 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
| 8427 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, | 8435 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, |
| @@ -8454,7 +8462,7 @@ jpeg_image_p (object) | |||
| 8454 | 8462 | ||
| 8455 | if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg) | 8463 | if (!parse_image_spec (object, fmt, JPEG_LAST, Qjpeg) |
| 8456 | || (fmt[JPEG_ASCENT].count | 8464 | || (fmt[JPEG_ASCENT].count |
| 8457 | && XFASTINT (fmt[JPEG_ASCENT].value) > 100)) | 8465 | && XFASTINT (fmt[JPEG_ASCENT].value) > 100)) |
| 8458 | return 0; | 8466 | return 0; |
| 8459 | 8467 | ||
| 8460 | /* Must specify either the :data or :file keyword. This should | 8468 | /* Must specify either the :data or :file keyword. This should |
| @@ -8523,10 +8531,7 @@ our_skip_input_data (cinfo, num_bytes) | |||
| 8523 | if (src) | 8531 | if (src) |
| 8524 | { | 8532 | { |
| 8525 | if (num_bytes > src->bytes_in_buffer) | 8533 | if (num_bytes > src->bytes_in_buffer) |
| 8526 | { | 8534 | ERREXIT (cinfo, JERR_INPUT_EOF); |
| 8527 | ERREXIT (cinfo, JERR_INPUT_EOF); | ||
| 8528 | /*NOTREACHED*/ | ||
| 8529 | } | ||
| 8530 | 8535 | ||
| 8531 | src->bytes_in_buffer -= num_bytes; | 8536 | src->bytes_in_buffer -= num_bytes; |
| 8532 | src->next_input_byte += num_bytes; | 8537 | src->next_input_byte += num_bytes; |
| @@ -8576,6 +8581,7 @@ jpeg_memory_src (cinfo, data, len) | |||
| 8576 | src->next_input_byte = data; | 8581 | src->next_input_byte = data; |
| 8577 | } | 8582 | } |
| 8578 | 8583 | ||
| 8584 | |||
| 8579 | /* Load image IMG for use on frame F. Patterned after example.c | 8585 | /* Load image IMG for use on frame F. Patterned after example.c |
| 8580 | from the JPEG lib. */ | 8586 | from the JPEG lib. */ |
| 8581 | 8587 | ||
| @@ -8600,12 +8606,13 @@ jpeg_load (f, img) | |||
| 8600 | /* Open the JPEG file. */ | 8606 | /* Open the JPEG file. */ |
| 8601 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 8607 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 8602 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 8608 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 8609 | file = Qnil; | ||
| 8610 | GCPRO1 (file); | ||
| 8603 | 8611 | ||
| 8604 | /* Reading from :data takes precedence. */ | 8612 | /* Reading from :data takes precedence. */ |
| 8605 | if (NILP (specified_data)) | 8613 | if (NILP (specified_data)) |
| 8606 | { | 8614 | { |
| 8607 | file = x_find_image_file (specified_file); | 8615 | file = x_find_image_file (specified_file); |
| 8608 | GCPRO1 (file); | ||
| 8609 | if (!STRINGP (file)) | 8616 | if (!STRINGP (file)) |
| 8610 | { | 8617 | { |
| 8611 | image_error ("Cannot find image file %s", specified_file, Qnil); | 8618 | image_error ("Cannot find image file %s", specified_file, Qnil); |
| @@ -8622,38 +8629,38 @@ jpeg_load (f, img) | |||
| 8622 | } | 8629 | } |
| 8623 | } | 8630 | } |
| 8624 | 8631 | ||
| 8625 | /* Customize libjpeg's error handling to call my_error_exit | 8632 | /* Customize libjpeg's error handling to call my_error_exit when an |
| 8626 | when an error is detected. This function will perform | 8633 | error is detected. This function will perform a longjmp. */ |
| 8627 | a longjmp. */ | ||
| 8628 | mgr.pub.error_exit = my_error_exit; | 8634 | mgr.pub.error_exit = my_error_exit; |
| 8629 | cinfo.err = jpeg_std_error (&mgr.pub); | 8635 | cinfo.err = jpeg_std_error (&mgr.pub); |
| 8630 | 8636 | ||
| 8631 | if ((rc = setjmp (mgr.setjmp_buffer)) != 0) | 8637 | if ((rc = setjmp (mgr.setjmp_buffer)) != 0) |
| 8632 | { | 8638 | { |
| 8633 | if (rc == 1) | 8639 | if (rc == 1) |
| 8634 | { | 8640 | { |
| 8635 | /* Called from my_error_exit. Display a JPEG error. */ | 8641 | /* Called from my_error_exit. Display a JPEG error. */ |
| 8636 | char buffer[JMSG_LENGTH_MAX]; | 8642 | char buffer[JMSG_LENGTH_MAX]; |
| 8637 | cinfo.err->format_message ((j_common_ptr) &cinfo, buffer); | 8643 | cinfo.err->format_message ((j_common_ptr) &cinfo, buffer); |
| 8638 | image_error ("Error reading JPEG file `%s': %s", file, | 8644 | image_error ("Error reading JPEG file `%s': %s", file, |
| 8639 | build_string (buffer)); | 8645 | build_string (buffer)); |
| 8640 | } | 8646 | } |
| 8641 | 8647 | ||
| 8642 | /* Close the input file and destroy the JPEG object. */ | 8648 | /* Close the input file and destroy the JPEG object. */ |
| 8643 | if (fp) fclose (fp); | 8649 | if (fp) |
| 8650 | fclose (fp); | ||
| 8644 | jpeg_destroy_decompress (&cinfo); | 8651 | jpeg_destroy_decompress (&cinfo); |
| 8645 | 8652 | ||
| 8646 | BLOCK_INPUT; | 8653 | BLOCK_INPUT; |
| 8647 | 8654 | ||
| 8648 | /* If we already have an XImage, free that. */ | 8655 | /* If we already have an XImage, free that. */ |
| 8649 | x_destroy_x_image (ximg); | 8656 | x_destroy_x_image (ximg); |
| 8650 | 8657 | ||
| 8651 | /* Free pixmap and colors. */ | 8658 | /* Free pixmap and colors. */ |
| 8652 | x_clear_image (f, img); | 8659 | x_clear_image (f, img); |
| 8653 | 8660 | ||
| 8654 | UNBLOCK_INPUT; | 8661 | UNBLOCK_INPUT; |
| 8655 | UNGCPRO; | 8662 | UNGCPRO; |
| 8656 | return 0; | 8663 | return 0; |
| 8657 | } | 8664 | } |
| 8658 | 8665 | ||
| 8659 | /* Create the JPEG decompression object. Let it read from fp. | 8666 | /* Create the JPEG decompression object. Let it read from fp. |
| @@ -8681,63 +8688,64 @@ jpeg_load (f, img) | |||
| 8681 | if (!x_create_x_image_and_pixmap (f, file, width, height, 0, &ximg, | 8688 | if (!x_create_x_image_and_pixmap (f, file, width, height, 0, &ximg, |
| 8682 | &img->pixmap)) | 8689 | &img->pixmap)) |
| 8683 | { | 8690 | { |
| 8684 | UNBLOCK_INPUT; | 8691 | UNBLOCK_INPUT; |
| 8685 | longjmp (mgr.setjmp_buffer, 2); | 8692 | longjmp (mgr.setjmp_buffer, 2); |
| 8686 | } | 8693 | } |
| 8687 | 8694 | ||
| 8688 | /* Allocate colors. When color quantization is used, | 8695 | /* Allocate colors. When color quantization is used, |
| 8689 | cinfo.actual_number_of_colors has been set with the number of | 8696 | cinfo.actual_number_of_colors has been set with the number of |
| 8690 | colors generated, and cinfo.colormap is a two-dimensional array | 8697 | colors generated, and cinfo.colormap is a two-dimensional array |
| 8691 | of color indices in the range 0..cinfo.actual_number_of_colors. | 8698 | of color indices in the range 0..cinfo.actual_number_of_colors. |
| 8692 | No more than 255 colors will be generated. */ | 8699 | No more than 255 colors will be generated. */ |
| 8693 | { | 8700 | { |
| 8694 | int i, ir, ig, ib; | 8701 | int i, ir, ig, ib; |
| 8695 | 8702 | ||
| 8696 | if (cinfo.out_color_components > 2) | 8703 | if (cinfo.out_color_components > 2) |
| 8697 | ir = 0, ig = 1, ib = 2; | 8704 | ir = 0, ig = 1, ib = 2; |
| 8698 | else if (cinfo.out_color_components > 1) | 8705 | else if (cinfo.out_color_components > 1) |
| 8699 | ir = 0, ig = 1, ib = 0; | 8706 | ir = 0, ig = 1, ib = 0; |
| 8700 | else | 8707 | else |
| 8701 | ir = 0, ig = 0, ib = 0; | 8708 | ir = 0, ig = 0, ib = 0; |
| 8702 | 8709 | ||
| 8703 | /* Use the color table mechanism because it handles colors that | 8710 | /* Use the color table mechanism because it handles colors that |
| 8704 | cannot be allocated nicely. Such colors will be replaced with | 8711 | cannot be allocated nicely. Such colors will be replaced with |
| 8705 | a default color, and we don't have to care about which colors | 8712 | a default color, and we don't have to care about which colors |
| 8706 | can be freed safely, and which can't. */ | 8713 | can be freed safely, and which can't. */ |
| 8707 | init_color_table (); | 8714 | init_color_table (); |
| 8708 | colors = (unsigned long *) alloca (cinfo.actual_number_of_colors | 8715 | colors = (unsigned long *) alloca (cinfo.actual_number_of_colors |
| 8709 | * sizeof *colors); | 8716 | * sizeof *colors); |
| 8710 | 8717 | ||
| 8711 | for (i = 0; i < cinfo.actual_number_of_colors; ++i) | 8718 | for (i = 0; i < cinfo.actual_number_of_colors; ++i) |
| 8712 | { | 8719 | { |
| 8713 | /* Multiply RGB values with 255 because X expects RGB values | 8720 | /* Multiply RGB values with 255 because X expects RGB values |
| 8714 | in the range 0..0xffff. */ | 8721 | in the range 0..0xffff. */ |
| 8715 | int r = cinfo.colormap[ir][i] << 8; | 8722 | int r = cinfo.colormap[ir][i] << 8; |
| 8716 | int g = cinfo.colormap[ig][i] << 8; | 8723 | int g = cinfo.colormap[ig][i] << 8; |
| 8717 | int b = cinfo.colormap[ib][i] << 8; | 8724 | int b = cinfo.colormap[ib][i] << 8; |
| 8718 | colors[i] = lookup_rgb_color (f, r, g, b); | 8725 | colors[i] = lookup_rgb_color (f, r, g, b); |
| 8719 | } | 8726 | } |
| 8720 | 8727 | ||
| 8721 | /* Remember those colors actually allocated. */ | 8728 | /* Remember those colors actually allocated. */ |
| 8722 | img->colors = colors_in_color_table (&img->ncolors); | 8729 | img->colors = colors_in_color_table (&img->ncolors); |
| 8723 | free_color_table (); | 8730 | free_color_table (); |
| 8724 | } | 8731 | } |
| 8725 | 8732 | ||
| 8726 | /* Read pixels. */ | 8733 | /* Read pixels. */ |
| 8727 | row_stride = width * cinfo.output_components; | 8734 | row_stride = width * cinfo.output_components; |
| 8728 | buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, | 8735 | buffer = cinfo.mem->alloc_sarray ((j_common_ptr) &cinfo, JPOOL_IMAGE, |
| 8729 | row_stride, 1); | 8736 | row_stride, 1); |
| 8730 | for (y = 0; y < height; ++y) | 8737 | for (y = 0; y < height; ++y) |
| 8731 | { | 8738 | { |
| 8732 | jpeg_read_scanlines (&cinfo, buffer, 1); | 8739 | jpeg_read_scanlines (&cinfo, buffer, 1); |
| 8733 | for (x = 0; x < cinfo.output_width; ++x) | 8740 | for (x = 0; x < cinfo.output_width; ++x) |
| 8734 | XPutPixel (ximg, x, y, colors[buffer[0][x]]); | 8741 | XPutPixel (ximg, x, y, colors[buffer[0][x]]); |
| 8735 | } | 8742 | } |
| 8736 | 8743 | ||
| 8737 | /* Clean up. */ | 8744 | /* Clean up. */ |
| 8738 | jpeg_finish_decompress (&cinfo); | 8745 | jpeg_finish_decompress (&cinfo); |
| 8739 | jpeg_destroy_decompress (&cinfo); | 8746 | jpeg_destroy_decompress (&cinfo); |
| 8740 | if (fp) fclose (fp); | 8747 | if (fp) |
| 8748 | fclose (fp); | ||
| 8741 | 8749 | ||
| 8742 | /* Put the image into the pixmap. */ | 8750 | /* Put the image into the pixmap. */ |
| 8743 | x_put_x_image (f, ximg, img->pixmap, width, height); | 8751 | x_put_x_image (f, ximg, img->pixmap, width, height); |
| @@ -8787,7 +8795,7 @@ enum tiff_keyword_index | |||
| 8787 | static struct image_keyword tiff_format[TIFF_LAST] = | 8795 | static struct image_keyword tiff_format[TIFF_LAST] = |
| 8788 | { | 8796 | { |
| 8789 | {":type", IMAGE_SYMBOL_VALUE, 1}, | 8797 | {":type", IMAGE_SYMBOL_VALUE, 1}, |
| 8790 | {":data", IMAGE_STRING_VALUE, 0}, | 8798 | {":data", IMAGE_STRING_VALUE, 0}, |
| 8791 | {":file", IMAGE_STRING_VALUE, 0}, | 8799 | {":file", IMAGE_STRING_VALUE, 0}, |
| 8792 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, | 8800 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
| 8793 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, | 8801 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, |
| @@ -8821,91 +8829,121 @@ tiff_image_p (object) | |||
| 8821 | || (fmt[TIFF_ASCENT].count | 8829 | || (fmt[TIFF_ASCENT].count |
| 8822 | && XFASTINT (fmt[TIFF_ASCENT].value) > 100)) | 8830 | && XFASTINT (fmt[TIFF_ASCENT].value) > 100)) |
| 8823 | return 0; | 8831 | return 0; |
| 8832 | |||
| 8824 | /* Must specify either the :data or :file keyword. This should | 8833 | /* Must specify either the :data or :file keyword. This should |
| 8825 | ** probably be moved up into parse_image_spec, since it seems to be | 8834 | probably be moved up into parse_image_spec, since it seems to be |
| 8826 | ** a general requirement. | 8835 | a general requirement. */ |
| 8827 | */ | 8836 | return fmt[TIFF_FILE].count || fmt[TIFF_DATA].count; |
| 8828 | if (!fmt[TIFF_FILE].count && !fmt[TIFF_DATA].count) | ||
| 8829 | return 0; | ||
| 8830 | return 1; | ||
| 8831 | } | 8837 | } |
| 8832 | 8838 | ||
| 8833 | /* Reading from a memory buffer for TIFF images | 8839 | |
| 8834 | Based on the PNG memory source, but we have to provide a lot of | 8840 | /* Reading from a memory buffer for TIFF images Based on the PNG |
| 8835 | extra functions. Blah. | 8841 | memory source, but we have to provide a lot of extra functions. |
| 8842 | Blah. | ||
| 8836 | 8843 | ||
| 8837 | We really only need to implement read and seek, but I am not | 8844 | 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 | 8845 | convinced that the TIFF library is smart enough not to destroy |
| 8839 | itself if we only hand it the function pointers we need to | 8846 | itself if we only hand it the function pointers we need to |
| 8840 | override. */ | 8847 | override. */ |
| 8841 | typedef struct { | 8848 | |
| 8849 | typedef struct | ||
| 8850 | { | ||
| 8842 | unsigned char *bytes; | 8851 | unsigned char *bytes; |
| 8843 | size_t len; | 8852 | size_t len; |
| 8844 | int index; | 8853 | int index; |
| 8845 | } tiff_memory_source; | 8854 | } |
| 8855 | tiff_memory_source; | ||
| 8846 | 8856 | ||
| 8847 | static size_t tiff_read_from_memory(thandle_t data, tdata_t buf, tsize_t size) | 8857 | static size_t |
| 8858 | tiff_read_from_memory (data, buf, size) | ||
| 8859 | thandle_t data; | ||
| 8860 | tdata_t buf; | ||
| 8861 | tsize_t size; | ||
| 8848 | { | 8862 | { |
| 8849 | tiff_memory_source *src = (tiff_memory_source *)data; | 8863 | tiff_memory_source *src = (tiff_memory_source *) data; |
| 8850 | 8864 | ||
| 8851 | if (size > src->len - src->index) | 8865 | if (size > src->len - src->index) |
| 8852 | return (size_t) -1; | 8866 | return (size_t) -1; |
| 8853 | memcpy(buf, src->bytes + src->index, size); | 8867 | bcopy (src->bytes + src->index, buf, size); |
| 8854 | src->index += size; | 8868 | src->index += size; |
| 8855 | return size; | 8869 | return size; |
| 8856 | } | 8870 | } |
| 8857 | 8871 | ||
| 8858 | static size_t tiff_write_from_memory(thandle_t data, tdata_t buf, tsize_t size) | 8872 | static size_t |
| 8873 | tiff_write_from_memory (data, buf, size) | ||
| 8874 | thandle_t data; | ||
| 8875 | tdata_t buf; | ||
| 8876 | tsize_t size; | ||
| 8859 | { | 8877 | { |
| 8860 | return (size_t) -1; | 8878 | return (size_t) -1; |
| 8861 | } | 8879 | } |
| 8862 | 8880 | ||
| 8863 | static toff_t tiff_seek_in_memory(thandle_t data, toff_t off, int whence) | 8881 | static toff_t |
| 8882 | tiff_seek_in_memory (data, off, whence) | ||
| 8883 | thandle_t data; | ||
| 8884 | toff_t off; | ||
| 8885 | int whence; | ||
| 8864 | { | 8886 | { |
| 8865 | tiff_memory_source *src = (tiff_memory_source *)data; | 8887 | tiff_memory_source *src = (tiff_memory_source *) data; |
| 8866 | int idx; | 8888 | int idx; |
| 8867 | 8889 | ||
| 8868 | switch (whence) | 8890 | switch (whence) |
| 8869 | { | 8891 | { |
| 8870 | case SEEK_SET: /* Go from beginning of source */ | 8892 | case SEEK_SET: /* Go from beginning of source. */ |
| 8871 | idx = off; | 8893 | idx = off; |
| 8872 | break; | 8894 | break; |
| 8873 | case SEEK_END: /* Go from end of source */ | 8895 | |
| 8874 | idx = src->len + off; | 8896 | case SEEK_END: /* Go from end of source. */ |
| 8875 | break; | 8897 | idx = src->len + off; |
| 8876 | case SEEK_CUR: /* Go from current position */ | 8898 | break; |
| 8877 | idx = src->index + off; | 8899 | |
| 8878 | break; | 8900 | case SEEK_CUR: /* Go from current position. */ |
| 8879 | default: /* Invalid `whence' */ | 8901 | idx = src->index + off; |
| 8880 | return(-1); | 8902 | break; |
| 8881 | } | 8903 | |
| 8882 | if ((idx > src->len) || (idx < 0)) | 8904 | default: /* Invalid `whence'. */ |
| 8883 | return -1; | 8905 | return -1; |
| 8906 | } | ||
| 8907 | |||
| 8908 | if (idx > src->len || idx < 0) | ||
| 8909 | return -1; | ||
| 8910 | |||
| 8884 | src->index = idx; | 8911 | src->index = idx; |
| 8885 | return src->index; | 8912 | return src->index; |
| 8886 | } | 8913 | } |
| 8887 | 8914 | ||
| 8888 | static int tiff_close_memory(thandle_t data) | 8915 | static int |
| 8916 | tiff_close_memory (data) | ||
| 8917 | thandle_t data; | ||
| 8889 | { | 8918 | { |
| 8890 | /* NOOP */ | 8919 | /* NOOP */ |
| 8891 | return(0); | 8920 | return 0; |
| 8892 | } | 8921 | } |
| 8893 | 8922 | ||
| 8894 | static int tiff_mmap_memory(thandle_t data, tdata_t *pbase, toff_t *psize) | 8923 | static int |
| 8924 | tiff_mmap_memory (data, pbase, psize) | ||
| 8925 | thandle_t data; | ||
| 8926 | tdata_t *pbase; | ||
| 8927 | toff_t *psize; | ||
| 8895 | { | 8928 | { |
| 8896 | /* It is already _IN_ memory. */ | 8929 | /* It is already _IN_ memory. */ |
| 8897 | return(0); | 8930 | return 0; |
| 8898 | } | 8931 | } |
| 8899 | 8932 | ||
| 8900 | static void tiff_unmap_memory(thandle_t data, tdata_t base, toff_t size) | 8933 | static void |
| 8934 | tiff_unmap_memory (data, base, size) | ||
| 8935 | thandle_t data; | ||
| 8936 | tdata_t base; | ||
| 8937 | toff_t size; | ||
| 8901 | { | 8938 | { |
| 8902 | /* We don't need to do this. */ | 8939 | /* We don't need to do this. */ |
| 8903 | return; | ||
| 8904 | } | 8940 | } |
| 8905 | 8941 | ||
| 8906 | static toff_t tiff_size_of_memory(thandle_t data) | 8942 | static toff_t |
| 8943 | tiff_size_of_memory (data) | ||
| 8944 | thandle_t data; | ||
| 8907 | { | 8945 | { |
| 8908 | return(((tiff_memory_source *) data)->len); | 8946 | return ((tiff_memory_source *) data)->len; |
| 8909 | } | 8947 | } |
| 8910 | 8948 | ||
| 8911 | /* Load TIFF image IMG for use on frame F. Value is non-zero if | 8949 | /* Load TIFF image IMG for use on frame F. Value is non-zero if |
| @@ -8928,51 +8966,53 @@ tiff_load (f, img) | |||
| 8928 | 8966 | ||
| 8929 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 8967 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 8930 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 8968 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 8969 | file = Qnil; | ||
| 8970 | GCPRO1 (file); | ||
| 8931 | 8971 | ||
| 8932 | if (NILP (specified_data)) | 8972 | if (NILP (specified_data)) |
| 8973 | { | ||
| 8974 | /* Read from a file */ | ||
| 8975 | file = x_find_image_file (specified_file); | ||
| 8976 | if (!STRINGP (file)) | ||
| 8933 | { | 8977 | { |
| 8934 | /* Read from a file */ | 8978 | image_error ("Cannot find image file %s", file, Qnil); |
| 8935 | file = x_find_image_file (specified_file); | 8979 | UNGCPRO; |
| 8936 | GCPRO1 (file); | 8980 | return 0; |
| 8937 | if (!STRINGP (file)) | 8981 | } |
| 8938 | { | ||
| 8939 | image_error ("Cannot find image file %s", file, Qnil); | ||
| 8940 | UNGCPRO; | ||
| 8941 | return 0; | ||
| 8942 | } | ||
| 8943 | 8982 | ||
| 8944 | /* Try to open the image file. */ | 8983 | /* Try to open the image file. */ |
| 8945 | tiff = TIFFOpen (XSTRING (file)->data, "r"); | 8984 | tiff = TIFFOpen (XSTRING (file)->data, "r"); |
| 8946 | if (tiff == NULL) | 8985 | if (tiff == NULL) |
| 8947 | { | 8986 | { |
| 8948 | image_error ("Cannot open `%s'", file, Qnil); | 8987 | image_error ("Cannot open `%s'", file, Qnil); |
| 8949 | UNGCPRO; | 8988 | UNGCPRO; |
| 8950 | return 0; | 8989 | return 0; |
| 8951 | } | ||
| 8952 | } | 8990 | } |
| 8991 | } | ||
| 8953 | else | 8992 | else |
| 8993 | { | ||
| 8994 | /* Memory source! */ | ||
| 8995 | memsrc.bytes = XSTRING (specified_data)->data; | ||
| 8996 | memsrc.len = STRING_BYTES (XSTRING (specified_data)); | ||
| 8997 | memsrc.index = 0; | ||
| 8998 | |||
| 8999 | tiff = TIFFClientOpen ("memory_source", "r", &memsrc, | ||
| 9000 | (TIFFReadWriteProc) tiff_read_from_memory, | ||
| 9001 | (TIFFReadWriteProc) tiff_write_from_memory, | ||
| 9002 | tiff_seek_in_memory, | ||
| 9003 | tiff_close_memory, | ||
| 9004 | tiff_size_of_memory, | ||
| 9005 | tiff_mmap_memory, | ||
| 9006 | tiff_unmap_memory); | ||
| 9007 | |||
| 9008 | if (!tiff) | ||
| 8954 | { | 9009 | { |
| 8955 | /* Memory source! */ | 9010 | image_error ("Cannot open memory source `%s'. ", |
| 8956 | memsrc.bytes = XSTRING (specified_data)->data; | 9011 | specified_data, Qnil); |
| 8957 | memsrc.len = STRING_BYTES (XSTRING (specified_data)); | 9012 | UNGCPRO; |
| 8958 | memsrc.index = 0; | 9013 | return 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 | } | 9014 | } |
| 9015 | } | ||
| 8976 | 9016 | ||
| 8977 | /* Get width and height of the image, and allocate a raster buffer | 9017 | /* Get width and height of the image, and allocate a raster buffer |
| 8978 | of width x height 32-bit values. */ | 9018 | of width x height 32-bit values. */ |
| @@ -9078,7 +9118,7 @@ enum gif_keyword_index | |||
| 9078 | static struct image_keyword gif_format[GIF_LAST] = | 9118 | static struct image_keyword gif_format[GIF_LAST] = |
| 9079 | { | 9119 | { |
| 9080 | {":type", IMAGE_SYMBOL_VALUE, 1}, | 9120 | {":type", IMAGE_SYMBOL_VALUE, 1}, |
| 9081 | {":data", IMAGE_STRING_VALUE, 0}, | 9121 | {":data", IMAGE_STRING_VALUE, 0}, |
| 9082 | {":file", IMAGE_STRING_VALUE, 0}, | 9122 | {":file", IMAGE_STRING_VALUE, 0}, |
| 9083 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, | 9123 | {":ascent", IMAGE_NON_NEGATIVE_INTEGER_VALUE, 0}, |
| 9084 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, | 9124 | {":margin", IMAGE_POSITIVE_INTEGER_VALUE, 0}, |
| @@ -9113,36 +9153,41 @@ gif_image_p (object) | |||
| 9113 | || (fmt[GIF_ASCENT].count | 9153 | || (fmt[GIF_ASCENT].count |
| 9114 | && XFASTINT (fmt[GIF_ASCENT].value) > 100)) | 9154 | && XFASTINT (fmt[GIF_ASCENT].value) > 100)) |
| 9115 | return 0; | 9155 | return 0; |
| 9156 | |||
| 9116 | /* Must specify either the :data or :file keyword. This should | 9157 | /* Must specify either the :data or :file keyword. This should |
| 9117 | ** probably be moved up into parse_image_spec, since it seems to be | 9158 | probably be moved up into parse_image_spec, since it seems to be |
| 9118 | ** a general requirement. | 9159 | a general requirement. */ |
| 9119 | */ | 9160 | return fmt[GIF_FILE].count || fmt[GIF_DATA].count; |
| 9120 | if (!fmt[GIF_FILE].count && !fmt[GIF_DATA].count) | ||
| 9121 | return 0; | ||
| 9122 | return 1; | ||
| 9123 | } | 9161 | } |
| 9124 | 9162 | ||
| 9125 | /* Reading a GIF image from memory | 9163 | /* Reading a GIF image from memory |
| 9126 | Based on the PNG memory stuff to a certain extent. */ | 9164 | Based on the PNG memory stuff to a certain extent. */ |
| 9127 | 9165 | ||
| 9128 | typedef struct { | 9166 | typedef struct |
| 9167 | { | ||
| 9129 | unsigned char *bytes; | 9168 | unsigned char *bytes; |
| 9130 | size_t len; | 9169 | size_t len; |
| 9131 | int index; | 9170 | int index; |
| 9132 | } gif_memory_source; | 9171 | } |
| 9172 | gif_memory_source; | ||
| 9133 | 9173 | ||
| 9134 | static int gif_read_from_memory(GifFileType *file, GifByteType *buf, int len) | 9174 | static int |
| 9175 | gif_read_from_memory (file, buf, len) | ||
| 9176 | GifFileType *file; | ||
| 9177 | GifByteType *buf; | ||
| 9178 | int len; | ||
| 9135 | { | 9179 | { |
| 9136 | gif_memory_source *src = (gif_memory_source *) file->UserData; | 9180 | gif_memory_source *src = (gif_memory_source *) file->UserData; |
| 9137 | 9181 | ||
| 9138 | if (len > (src->len - src->index)) | 9182 | if (len > src->len - src->index) |
| 9139 | return -1; | 9183 | return -1; |
| 9140 | 9184 | ||
| 9141 | memcpy(buf, src->bytes + src->index, len); | 9185 | bcopy (src->bytes + src->index, buf, len); |
| 9142 | src->index += len; | 9186 | src->index += len; |
| 9143 | return len; | 9187 | return len; |
| 9144 | } | 9188 | } |
| 9145 | 9189 | ||
| 9190 | |||
| 9146 | /* Load GIF image IMG for use on frame F. Value is non-zero if | 9191 | /* Load GIF image IMG for use on frame F. Value is non-zero if |
| 9147 | successful. */ | 9192 | successful. */ |
| 9148 | 9193 | ||
| @@ -9165,42 +9210,43 @@ gif_load (f, img) | |||
| 9165 | 9210 | ||
| 9166 | specified_file = image_spec_value (img->spec, QCfile, NULL); | 9211 | specified_file = image_spec_value (img->spec, QCfile, NULL); |
| 9167 | specified_data = image_spec_value (img->spec, QCdata, NULL); | 9212 | specified_data = image_spec_value (img->spec, QCdata, NULL); |
| 9213 | file = Qnil; | ||
| 9214 | GCPRO1 (file); | ||
| 9168 | 9215 | ||
| 9169 | if (NILP (specified_data)) | 9216 | if (NILP (specified_data)) |
| 9217 | { | ||
| 9218 | file = x_find_image_file (specified_file); | ||
| 9219 | if (!STRINGP (file)) | ||
| 9170 | { | 9220 | { |
| 9171 | file = x_find_image_file (specified_file); | 9221 | image_error ("Cannot find image file %s", specified_file, Qnil); |
| 9172 | GCPRO1 (file); | 9222 | UNGCPRO; |
| 9173 | if (!STRINGP (file)) | 9223 | return 0; |
| 9174 | { | 9224 | } |
| 9175 | image_error ("Cannot find image file %s", specified_file, Qnil); | ||
| 9176 | UNGCPRO; | ||
| 9177 | return 0; | ||
| 9178 | } | ||
| 9179 | 9225 | ||
| 9180 | /* Open the GIF file. */ | 9226 | /* Open the GIF file. */ |
| 9181 | gif = DGifOpenFileName (XSTRING (file)->data); | 9227 | gif = DGifOpenFileName (XSTRING (file)->data); |
| 9182 | if (gif == NULL) | 9228 | if (gif == NULL) |
| 9183 | { | 9229 | { |
| 9184 | image_error ("Cannot open `%s'", file, Qnil); | 9230 | image_error ("Cannot open `%s'", file, Qnil); |
| 9185 | UNGCPRO; | 9231 | UNGCPRO; |
| 9186 | return 0; | 9232 | return 0; |
| 9187 | } | ||
| 9188 | } | 9233 | } |
| 9234 | } | ||
| 9189 | else | 9235 | else |
| 9190 | { | 9236 | { |
| 9191 | /* Read from memory! */ | 9237 | /* Read from memory! */ |
| 9192 | memsrc.bytes = XSTRING (specified_data)->data; | 9238 | memsrc.bytes = XSTRING (specified_data)->data; |
| 9193 | memsrc.len = STRING_BYTES (XSTRING (specified_data)); | 9239 | memsrc.len = STRING_BYTES (XSTRING (specified_data)); |
| 9194 | memsrc.index = 0; | 9240 | memsrc.index = 0; |
| 9195 | 9241 | ||
| 9196 | gif = DGifOpen(&memsrc, gif_read_from_memory); | 9242 | gif = DGifOpen(&memsrc, gif_read_from_memory); |
| 9197 | if (!gif) | 9243 | if (!gif) |
| 9198 | { | 9244 | { |
| 9199 | image_error ("Cannot open memory source `%s'",specified_data, Qnil); | 9245 | image_error ("Cannot open memory source `%s'",specified_data, Qnil); |
| 9200 | UNGCPRO; | 9246 | UNGCPRO; |
| 9201 | return 0; | 9247 | return 0; |
| 9202 | } | ||
| 9203 | } | 9248 | } |
| 9249 | } | ||
| 9204 | 9250 | ||
| 9205 | /* Read entire contents. */ | 9251 | /* Read entire contents. */ |
| 9206 | rc = DGifSlurp (gif); | 9252 | rc = DGifSlurp (gif); |