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