Mercurial > hg > xemacs-beta
comparison src/glyphs-eimage.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | 501cfd01ee6d |
children | 11054d720c21 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
54 #include "objects.h" | 54 #include "objects.h" |
55 | 55 |
56 #include "buffer.h" | 56 #include "buffer.h" |
57 #include "frame.h" | 57 #include "frame.h" |
58 #include "opaque.h" | 58 #include "opaque.h" |
59 #include "window.h" | |
60 | 59 |
61 #include "sysfile.h" | 60 #include "sysfile.h" |
62 | 61 |
63 #ifdef HAVE_PNG | 62 #ifdef HAVE_PNG |
64 #ifdef __cplusplus | 63 #ifdef __cplusplus |
313 static void | 312 static void |
314 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 313 jpeg_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
315 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 314 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
316 int dest_mask, Lisp_Object domain) | 315 int dest_mask, Lisp_Object domain) |
317 { | 316 { |
318 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 317 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
319 /* It is OK for the unwind data to be local to this function, | 318 /* It is OK for the unwind data to be local to this function, |
320 because the unwind-protect is always executed when this | 319 because the unwind-protect is always executed when this |
321 stack frame is still valid. */ | 320 stack frame is still valid. */ |
322 struct jpeg_unwind_data unwind; | 321 struct jpeg_unwind_data unwind; |
323 int speccount = specpdl_depth (); | 322 int speccount = specpdl_depth (); |
371 | 370 |
372 /* Step 2: specify data source (eg, a file) */ | 371 /* Step 2: specify data source (eg, a file) */ |
373 | 372 |
374 { | 373 { |
375 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | 374 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); |
376 const Extbyte *bytes; | 375 CONST Extbyte *bytes; |
377 Extcount len; | 376 Extcount len; |
378 | 377 |
379 /* #### This is a definite problem under Mule due to the amount of | 378 /* #### This is a definite problem under Mule due to the amount of |
380 stack data it might allocate. Need to be able to convert and | 379 stack data it might allocate. Need to be able to convert and |
381 write out to a file. */ | 380 write out to a file. */ |
382 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary); | 381 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); |
383 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len); | 382 jpeg_memory_src (&cinfo, (JOCTET *) bytes, len); |
384 } | 383 } |
385 | 384 |
386 /* Step 3: read file parameters with jpeg_read_header() */ | 385 /* Step 3: read file parameters with jpeg_read_header() */ |
387 | 386 |
479 } | 478 } |
480 } | 479 } |
481 | 480 |
482 /* Step 6.5: Create the pixmap and set up the image instance */ | 481 /* Step 6.5: Create the pixmap and set up the image instance */ |
483 /* now instantiate */ | 482 /* now instantiate */ |
484 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), | 483 MAYBE_DEVMETH (XDEVICE (ii->device), |
485 init_image_instance_from_eimage, | 484 init_image_instance_from_eimage, |
486 (ii, cinfo.output_width, cinfo.output_height, 1, | 485 (ii, cinfo.output_width, cinfo.output_height, |
487 unwind.eimage, dest_mask, | 486 unwind.eimage, dest_mask, |
488 instantiator, domain)); | 487 instantiator, domain)); |
489 | 488 |
490 /* Step 7: Finish decompression */ | 489 /* Step 7: Finish decompression */ |
491 | 490 |
579 return 0; | 578 return 0; |
580 } | 579 } |
581 | 580 |
582 struct gif_error_struct | 581 struct gif_error_struct |
583 { | 582 { |
584 const char *err_str; /* return the error string */ | 583 CONST char *err_str; /* return the error string */ |
585 jmp_buf setjmp_buffer; /* for return to caller */ | 584 jmp_buf setjmp_buffer; /* for return to caller */ |
586 }; | 585 }; |
587 | 586 |
588 static void | 587 static void |
589 gif_error_func(const char *err_str, VoidPtr error_ptr) | 588 gif_error_func(CONST char *err_str, VoidPtr error_ptr) |
590 { | 589 { |
591 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr; | 590 struct gif_error_struct *error_data = (struct gif_error_struct*)error_ptr; |
592 | 591 |
593 /* return to setjmp point */ | 592 /* return to setjmp point */ |
594 error_data->err_str = err_str; | 593 error_data->err_str = err_str; |
598 static void | 597 static void |
599 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 598 gif_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
600 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 599 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
601 int dest_mask, Lisp_Object domain) | 600 int dest_mask, Lisp_Object domain) |
602 { | 601 { |
603 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 602 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
604 /* It is OK for the unwind data to be local to this function, | 603 /* It is OK for the unwind data to be local to this function, |
605 because the unwind-protect is always executed when this | 604 because the unwind-protect is always executed when this |
606 stack frame is still valid. */ | 605 stack frame is still valid. */ |
607 struct gif_unwind_data unwind; | 606 struct gif_unwind_data unwind; |
608 int speccount = specpdl_depth (); | 607 int speccount = specpdl_depth (); |
622 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | 621 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); |
623 | 622 |
624 assert (!NILP (data)); | 623 assert (!NILP (data)); |
625 | 624 |
626 if (!(unwind.giffile = GifSetup())) | 625 if (!(unwind.giffile = GifSetup())) |
627 signal_image_error ("Insufficient memory to instantiate GIF image", instantiator); | 626 signal_image_error ("Insufficent memory to instantiate GIF image", instantiator); |
628 | 627 |
629 /* set up error facilities */ | 628 /* set up error facilities */ |
630 if (setjmp(gif_err.setjmp_buffer)) | 629 if (setjmp(gif_err.setjmp_buffer)) |
631 { | 630 { |
632 /* An error was signaled. No clean up is needed, as unwind handles that | 631 /* An error was signaled. No clean up is needed, as unwind handles that |
635 errstring = build_string (gif_err.err_str); | 634 errstring = build_string (gif_err.err_str); |
636 signal_image_error_2 ("GIF decoding error", errstring, instantiator); | 635 signal_image_error_2 ("GIF decoding error", errstring, instantiator); |
637 } | 636 } |
638 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err); | 637 GifSetErrorFunc(unwind.giffile, (Gif_error_func)gif_error_func, (VoidPtr)&gif_err); |
639 | 638 |
640 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary); | 639 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); |
641 mem_struct.bytes = bytes; | 640 mem_struct.bytes = bytes; |
642 mem_struct.len = len; | 641 mem_struct.len = len; |
643 mem_struct.index = 0; | 642 mem_struct.index = 0; |
644 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct); | 643 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct); |
645 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct); | 644 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct); |
650 format (#### the GIF routines only support 8-bit GIFs, | 649 format (#### the GIF routines only support 8-bit GIFs, |
651 it appears). */ | 650 it appears). */ |
652 DGifSlurp (unwind.giffile); | 651 DGifSlurp (unwind.giffile); |
653 } | 652 } |
654 | 653 |
655 /* 3. Now create the EImage(s) */ | 654 /* 3. Now create the EImage */ |
656 { | 655 { |
657 ColorMapObject *cmo = unwind.giffile->SColorMap; | 656 ColorMapObject *cmo = unwind.giffile->SColorMap; |
658 int i, j, row, pass, interlace, slice; | 657 int i, j, row, pass, interlace; |
659 unsigned char *eip; | 658 unsigned char *eip; |
660 /* interlaced gifs have rows in this order: | 659 /* interlaced gifs have rows in this order: |
661 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ | 660 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ |
662 static int InterlacedOffset[] = { 0, 4, 2, 1 }; | 661 static int InterlacedOffset[] = { 0, 4, 2, 1 }; |
663 static int InterlacedJumps[] = { 8, 8, 4, 2 }; | 662 static int InterlacedJumps[] = { 8, 8, 4, 2 }; |
664 | 663 |
665 height = unwind.giffile->SHeight; | 664 height = unwind.giffile->SHeight; |
666 width = unwind.giffile->SWidth; | 665 width = unwind.giffile->SWidth; |
667 unwind.eimage = (unsigned char*) | 666 unwind.eimage = (unsigned char*) xmalloc (width * height * 3); |
668 xmalloc (width * height * 3 * unwind.giffile->ImageCount); | |
669 if (!unwind.eimage) | 667 if (!unwind.eimage) |
670 signal_image_error("Unable to allocate enough memory for image", instantiator); | 668 signal_image_error("Unable to allocate enough memory for image", instantiator); |
671 | 669 |
672 /* write the data in EImage format (8bit RGB triples) */ | 670 /* write the data in EImage format (8bit RGB triples) */ |
673 | 671 |
674 for (slice = 0; slice < unwind.giffile->ImageCount; slice++) | 672 /* Note: We just use the first image in the file and ignore the rest. |
673 We check here that that image covers the full "screen" size. | |
674 I don't know whether that's always the case. | |
675 -dkindred@cs.cmu.edu */ | |
676 if (unwind.giffile->SavedImages[0].ImageDesc.Height != height | |
677 || unwind.giffile->SavedImages[0].ImageDesc.Width != width | |
678 || unwind.giffile->SavedImages[0].ImageDesc.Left != 0 | |
679 || unwind.giffile->SavedImages[0].ImageDesc.Top != 0) | |
680 signal_image_error ("First image in GIF file is not full size", | |
681 instantiator); | |
682 | |
683 interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace; | |
684 pass = 0; | |
685 row = interlace ? InterlacedOffset[pass] : 0; | |
686 eip = unwind.eimage; | |
687 for (i = 0; i < height; i++) | |
675 { | 688 { |
676 /* We check here that that the current image covers the full "screen" size. */ | 689 if (interlace) |
677 if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height | 690 if (row >= height) { |
678 || unwind.giffile->SavedImages[slice].ImageDesc.Width != width | 691 row = InterlacedOffset[++pass]; |
679 || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0 | 692 while (row >= height) |
680 || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0) | 693 row = InterlacedOffset[++pass]; |
681 signal_image_error ("Image in GIF file is not full size", | 694 } |
682 instantiator); | 695 eip = unwind.eimage + (row * width * 3); |
683 | 696 for (j = 0; j < width; j++) |
684 interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace; | |
685 pass = 0; | |
686 row = interlace ? InterlacedOffset[pass] : 0; | |
687 eip = unwind.eimage + (width * height * 3 * slice); | |
688 for (i = 0; i < height; i++) | |
689 { | 697 { |
690 if (interlace) | 698 unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j]; |
691 if (row >= height) { | 699 *eip++ = cmo->Colors[pixel].Red; |
692 row = InterlacedOffset[++pass]; | 700 *eip++ = cmo->Colors[pixel].Green; |
693 while (row >= height) | 701 *eip++ = cmo->Colors[pixel].Blue; |
694 row = InterlacedOffset[++pass]; | |
695 } | |
696 eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3); | |
697 for (j = 0; j < width; j++) | |
698 { | |
699 unsigned char pixel = | |
700 unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j]; | |
701 *eip++ = cmo->Colors[pixel].Red; | |
702 *eip++ = cmo->Colors[pixel].Green; | |
703 *eip++ = cmo->Colors[pixel].Blue; | |
704 } | |
705 row += interlace ? InterlacedJumps[pass] : 1; | |
706 } | 702 } |
703 row += interlace ? InterlacedJumps[pass] : 1; | |
707 } | 704 } |
708 | |
709 /* now instantiate */ | |
710 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), | |
711 init_image_instance_from_eimage, | |
712 (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask, | |
713 instantiator, domain)); | |
714 } | 705 } |
715 | 706 /* now instantiate */ |
716 /* We read the gif successfully. If we have more than one slice then | 707 MAYBE_DEVMETH (XDEVICE (ii->device), |
717 animate the gif. */ | 708 init_image_instance_from_eimage, |
718 if (unwind.giffile->ImageCount > 1) | 709 (ii, width, height, unwind.eimage, dest_mask, |
719 { | 710 instantiator, domain)); |
720 /* See if there is a timeout value. In theory there could be one | |
721 for every image - but that makes the implementation way to | |
722 complicated for now so we just take the first. */ | |
723 unsigned short timeout = 0; | |
724 Lisp_Object tid; | |
725 | |
726 if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE | |
727 && | |
728 unwind.giffile->SavedImages[0].ExtensionBlockCount) | |
729 { | |
730 timeout = (unsigned short) | |
731 ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) + | |
732 unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10; | |
733 } | |
734 | |
735 /* Too short a timeout will crucify us performance-wise. */ | |
736 tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance); | |
737 | |
738 if (!NILP (tid)) | |
739 IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid); | |
740 } | |
741 | 711 |
742 unbind_to (speccount, Qnil); | 712 unbind_to (speccount, Qnil); |
743 } | 713 } |
744 | 714 |
745 #endif /* HAVE_GIF */ | 715 #endif /* HAVE_GIF */ |
768 return IMAGE_COLOR_PIXMAP_MASK; | 738 return IMAGE_COLOR_PIXMAP_MASK; |
769 } | 739 } |
770 | 740 |
771 struct png_memory_storage | 741 struct png_memory_storage |
772 { | 742 { |
773 const Extbyte *bytes; /* The data */ | 743 CONST Extbyte *bytes; /* The data */ |
774 Extcount len; /* How big is it? */ | 744 Extcount len; /* How big is it? */ |
775 int index; /* Where are we? */ | 745 int index; /* Where are we? */ |
776 }; | 746 }; |
777 | 747 |
778 static void | 748 static void |
788 tbr->index = tbr->index + length; | 758 tbr->index = tbr->index + length; |
789 } | 759 } |
790 | 760 |
791 struct png_error_struct | 761 struct png_error_struct |
792 { | 762 { |
793 const char *err_str; | 763 CONST char *err_str; |
794 jmp_buf setjmp_buffer; /* for return to caller */ | 764 jmp_buf setjmp_buffer; /* for return to caller */ |
795 }; | 765 }; |
796 | 766 |
797 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own | 767 /* jh 98/03/12 - #### AARRRGH! libpng includes jmp_buf inside its own |
798 structure, and there are cases where the size can be different from | 768 structure, and there are cases where the size can be different from |
843 static void | 813 static void |
844 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 814 png_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
845 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 815 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
846 int dest_mask, Lisp_Object domain) | 816 int dest_mask, Lisp_Object domain) |
847 { | 817 { |
848 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 818 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
849 struct png_unwind_data unwind; | 819 struct png_unwind_data unwind; |
850 int speccount = specpdl_depth (); | 820 int speccount = specpdl_depth (); |
851 int height, width; | 821 int height, width; |
852 struct png_memory_storage tbr; /* Data to be read */ | 822 struct png_memory_storage tbr; /* Data to be read */ |
853 | 823 |
892 } | 862 } |
893 | 863 |
894 /* Initialize the IO layer and read in header information */ | 864 /* Initialize the IO layer and read in header information */ |
895 { | 865 { |
896 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); | 866 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); |
897 const Extbyte *bytes; | 867 CONST Extbyte *bytes; |
898 Extcount len; | 868 Extcount len; |
899 | 869 |
900 assert (!NILP (data)); | 870 assert (!NILP (data)); |
901 | 871 |
902 /* #### This is a definite problem under Mule due to the amount of | 872 /* #### This is a definite problem under Mule due to the amount of |
903 stack data it might allocate. Need to think about using Lstreams */ | 873 stack data it might allocate. Need to think about using Lstreams */ |
904 TO_EXTERNAL_FORMAT (LISP_STRING, data, ALLOCA, (bytes, len), Qbinary); | 874 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); |
905 tbr.bytes = bytes; | 875 tbr.bytes = bytes; |
906 tbr.len = len; | 876 tbr.len = len; |
907 tbr.index = 0; | 877 tbr.index = 0; |
908 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory); | 878 png_set_read_fn (png_ptr,(void *) &tbr, png_read_from_memory); |
909 } | 879 } |
941 { | 911 { |
942 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!"); | 912 warn_when_safe (Qpng, Qinfo, "Couldn't get background color!"); |
943 } | 913 } |
944 else | 914 else |
945 { | 915 { |
946 Lisp_Color_Instance *c; | 916 struct Lisp_Color_Instance *c; |
947 Lisp_Object rgblist; | 917 Lisp_Object rgblist; |
948 | 918 |
949 c = XCOLOR_INSTANCE (bkgd); | 919 c = XCOLOR_INSTANCE (bkgd); |
950 rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device), | 920 rgblist = MAYBE_LISP_DEVMETH (XDEVICE (c->device), |
951 color_instance_rgb_components, | 921 color_instance_rgb_components, |
952 (c)); | 922 (c)); |
953 my_background.red = (unsigned short) XINT (XCAR (rgblist)); | 923 my_background.red = XINT (XCAR (rgblist)); |
954 my_background.green = (unsigned short) XINT (XCAR (XCDR (rgblist))); | 924 my_background.green = XINT (XCAR (XCDR (rgblist))); |
955 my_background.blue = (unsigned short) XINT (XCAR (XCDR (XCDR (rgblist)))); | 925 my_background.blue = XINT (XCAR (XCDR (XCDR (rgblist)))); |
956 } | 926 } |
957 | 927 |
958 if (png_get_bKGD (png_ptr, info_ptr, &image_background)) | 928 if (png_get_bKGD (png_ptr, info_ptr, &image_background)) |
959 png_set_background (png_ptr, image_background, | 929 png_set_background (png_ptr, image_background, |
960 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); | 930 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); |
1016 | 986 |
1017 xfree (row_pointers); | 987 xfree (row_pointers); |
1018 } | 988 } |
1019 | 989 |
1020 /* now instantiate */ | 990 /* now instantiate */ |
1021 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), | 991 MAYBE_DEVMETH (XDEVICE (ii->device), |
1022 init_image_instance_from_eimage, | 992 init_image_instance_from_eimage, |
1023 (ii, width, height, 1, unwind.eimage, dest_mask, | 993 (ii, width, height, unwind.eimage, dest_mask, |
1024 instantiator, domain)); | 994 instantiator, domain)); |
1025 | 995 |
1026 /* This will clean up everything else. */ | 996 /* This will clean up everything else. */ |
1027 unbind_to (speccount, Qnil); | 997 unbind_to (speccount, Qnil); |
1028 } | 998 } |
1154 return mem->len; | 1124 return mem->len; |
1155 } | 1125 } |
1156 | 1126 |
1157 struct tiff_error_struct | 1127 struct tiff_error_struct |
1158 { | 1128 { |
1159 #ifdef HAVE_VSNPRINTF | 1129 #if HAVE_VSNPRINTF |
1160 char err_str[256]; | 1130 char err_str[256]; |
1161 #else | 1131 #else |
1162 char err_str[1024]; /* return the error string */ | 1132 char err_str[1024]; /* return the error string */ |
1163 #endif | 1133 #endif |
1164 jmp_buf setjmp_buffer; /* for return to caller */ | 1134 jmp_buf setjmp_buffer; /* for return to caller */ |
1169 have any place to store error func data. This should be rectified | 1139 have any place to store error func data. This should be rectified |
1170 before XEmacs gets threads! */ | 1140 before XEmacs gets threads! */ |
1171 static struct tiff_error_struct tiff_err_data; | 1141 static struct tiff_error_struct tiff_err_data; |
1172 | 1142 |
1173 static void | 1143 static void |
1174 tiff_error_func(const char *module, const char *fmt, ...) | 1144 tiff_error_func(CONST char *module, CONST char *fmt, ...) |
1175 { | 1145 { |
1176 va_list vargs; | 1146 va_list vargs; |
1177 | 1147 |
1178 va_start (vargs, fmt); | 1148 va_start (vargs, fmt); |
1179 #ifdef HAVE_VSNPRINTF | 1149 #if HAVE_VSNPRINTF |
1180 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs); | 1150 vsnprintf (tiff_err_data.err_str, 255, fmt, vargs); |
1181 #else | 1151 #else |
1182 /* pray this doesn't overflow... */ | 1152 /* pray this doesn't overflow... */ |
1183 vsprintf (tiff_err_data.err_str, fmt, vargs); | 1153 vsprintf (tiff_err_data.err_str, fmt, vargs); |
1184 #endif | 1154 #endif |
1186 /* return to setjmp point */ | 1156 /* return to setjmp point */ |
1187 longjmp (tiff_err_data.setjmp_buffer, 1); | 1157 longjmp (tiff_err_data.setjmp_buffer, 1); |
1188 } | 1158 } |
1189 | 1159 |
1190 static void | 1160 static void |
1191 tiff_warning_func(const char *module, const char *fmt, ...) | 1161 tiff_warning_func(CONST char *module, CONST char *fmt, ...) |
1192 { | 1162 { |
1193 va_list vargs; | 1163 va_list vargs; |
1194 #ifdef HAVE_VSNPRINTF | 1164 #if HAVE_VSNPRINTF |
1195 char warn_str[256]; | 1165 char warn_str[256]; |
1196 #else | 1166 #else |
1197 char warn_str[1024]; | 1167 char warn_str[1024]; |
1198 #endif | 1168 #endif |
1199 | 1169 |
1200 va_start (vargs, fmt); | 1170 va_start (vargs, fmt); |
1201 #ifdef HAVE_VSNPRINTF | 1171 #if HAVE_VSNPRINTF |
1202 vsnprintf (warn_str, 255, fmt, vargs); | 1172 vsnprintf (warn_str, 255, fmt, vargs); |
1203 #else | 1173 #else |
1204 vsprintf (warn_str, fmt, vargs); | 1174 vsprintf (warn_str, fmt, vargs); |
1205 #endif | 1175 #endif |
1206 va_end (vargs); | 1176 va_end (vargs); |
1211 static void | 1181 static void |
1212 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, | 1182 tiff_instantiate (Lisp_Object image_instance, Lisp_Object instantiator, |
1213 Lisp_Object pointer_fg, Lisp_Object pointer_bg, | 1183 Lisp_Object pointer_fg, Lisp_Object pointer_bg, |
1214 int dest_mask, Lisp_Object domain) | 1184 int dest_mask, Lisp_Object domain) |
1215 { | 1185 { |
1216 Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); | 1186 struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance); |
1217 tiff_memory_storage mem_struct; | 1187 tiff_memory_storage mem_struct; |
1218 /* It is OK for the unwind data to be local to this function, | 1188 /* It is OK for the unwind data to be local to this function, |
1219 because the unwind-protect is always executed when this | 1189 because the unwind-protect is always executed when this |
1220 stack frame is still valid. */ | 1190 stack frame is still valid. */ |
1221 struct tiff_unwind_data unwind; | 1191 struct tiff_unwind_data unwind; |
1246 | 1216 |
1247 assert (!NILP (data)); | 1217 assert (!NILP (data)); |
1248 | 1218 |
1249 /* #### This is a definite problem under Mule due to the amount of | 1219 /* #### This is a definite problem under Mule due to the amount of |
1250 stack data it might allocate. Think about Lstreams... */ | 1220 stack data it might allocate. Think about Lstreams... */ |
1251 TO_EXTERNAL_FORMAT (LISP_STRING, data, | 1221 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); |
1252 ALLOCA, (bytes, len), | |
1253 Qbinary); | |
1254 mem_struct.bytes = bytes; | 1222 mem_struct.bytes = bytes; |
1255 mem_struct.len = len; | 1223 mem_struct.len = len; |
1256 mem_struct.index = 0; | 1224 mem_struct.index = 0; |
1257 | 1225 |
1258 unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct, | 1226 unwind.tiff = TIFFClientOpen ("memfile", "r", &mem_struct, |
1259 (TIFFReadWriteProc)tiff_memory_read, | 1227 (TIFFReadWriteProc)tiff_memory_read, |
1260 (TIFFReadWriteProc)tiff_memory_write, | 1228 (TIFFReadWriteProc)tiff_memory_write, |
1261 tiff_memory_seek, tiff_memory_close, tiff_memory_size, | 1229 tiff_memory_seek, tiff_memory_close, tiff_memory_size, |
1262 tiff_map_noop, tiff_unmap_noop); | 1230 tiff_map_noop, tiff_unmap_noop); |
1263 if (!unwind.tiff) | 1231 if (!unwind.tiff) |
1264 signal_image_error ("Insufficient memory to instantiate TIFF image", instantiator); | 1232 signal_image_error ("Insufficent memory to instantiate TIFF image", instantiator); |
1265 | 1233 |
1266 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); | 1234 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); |
1267 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); | 1235 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); |
1268 unwind.eimage = (unsigned char *) xmalloc (width * height * 3); | 1236 unwind.eimage = (unsigned char *) xmalloc (width * height * 3); |
1269 | 1237 |
1270 /* #### This is little more than proof-of-concept/function testing. | 1238 /* ### This is little more than proof-of-concept/function testing. |
1271 It needs to be reimplemented via scanline reads for both memory | 1239 It needs to be reimplemented via scanline reads for both memory |
1272 compactness. */ | 1240 compactness. */ |
1273 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); | 1241 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); |
1274 if (raster != NULL) | 1242 if (raster != NULL) |
1275 { | 1243 { |
1298 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator); | 1266 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator); |
1299 | 1267 |
1300 } | 1268 } |
1301 | 1269 |
1302 /* now instantiate */ | 1270 /* now instantiate */ |
1303 MAYBE_DEVMETH (DOMAIN_XDEVICE (ii->domain), | 1271 MAYBE_DEVMETH (XDEVICE (ii->device), |
1304 init_image_instance_from_eimage, | 1272 init_image_instance_from_eimage, |
1305 (ii, width, height, 1, unwind.eimage, dest_mask, | 1273 (ii, width, height, unwind.eimage, dest_mask, |
1306 instantiator, domain)); | 1274 instantiator, domain)); |
1307 | 1275 |
1308 unbind_to (speccount, Qnil); | 1276 unbind_to (speccount, Qnil); |
1309 } | 1277 } |
1310 | 1278 |