comparison src/glyphs-eimage.c @ 380:8626e4521993 r21-2-5

Import from CVS: tag r21-2-5
author cvs
date Mon, 13 Aug 2007 11:07:10 +0200
parents 6240c7796c7a
children aabb7f5b1c81
comparison
equal deleted inserted replaced
379:76b7d63099ad 380:8626e4521993
53 #include "glyphs.h" 53 #include "glyphs.h"
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 "insdel.h"
59 #include "opaque.h" 58 #include "opaque.h"
60 59
61 #include "imgproc.h"
62 #include "sysfile.h" 60 #include "sysfile.h"
63 61
64 #ifdef HAVE_PNG 62 #ifdef HAVE_PNG
65 #ifdef __cplusplus 63 #ifdef __cplusplus
66 extern "C" { 64 extern "C" {
72 #else 70 #else
73 #include <setjmp.h> 71 #include <setjmp.h>
74 #endif 72 #endif
75 #ifdef FILE_CODING 73 #ifdef FILE_CODING
76 #include "file-coding.h" 74 #include "file-coding.h"
77 #endif
78
79 #if INTBITS == 32
80 # define FOUR_BYTE_TYPE unsigned int
81 #elif LONGBITS == 32
82 # define FOUR_BYTE_TYPE unsigned long
83 #elif SHORTBITS == 32
84 # define FOUR_BYTE_TYPE unsigned short
85 #else
86 #error What kind of strange-ass system are we running on?
87 #endif 75 #endif
88 76
89 #ifdef HAVE_TIFF 77 #ifdef HAVE_TIFF
90 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff); 78 DEFINE_IMAGE_INSTANTIATOR_FORMAT (tiff);
91 Lisp_Object Qtiff; 79 Lisp_Object Qtiff;
417 } 405 }
418 else 406 else
419 { 407 {
420 /* we're relying on the jpeg driver to do any other conversions, 408 /* we're relying on the jpeg driver to do any other conversions,
421 or signal an error if the conversion isn't supported. */ 409 or signal an error if the conversion isn't supported. */
422 cinfo.out_color_space = JCS_RGB; 410 cinfo.out_color_space = JCS_RGB;
423 } 411 }
424 412
425 /* Step 5: Start decompressor */ 413 /* Step 5: Start decompressor */
426 jpeg_start_decompress (&cinfo); 414 jpeg_start_decompress (&cinfo);
427 415
463 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1); 451 (void) jpeg_read_scanlines (&cinfo, row_buffer, 1);
464 jp = row_buffer[0]; 452 jp = row_buffer[0];
465 for (i = 0; i < cinfo.output_width; i++) 453 for (i = 0; i < cinfo.output_width; i++)
466 { 454 {
467 int clr; 455 int clr;
468 if (jpeg_gray) 456 if (jpeg_gray)
469 { 457 {
470 unsigned char val; 458 unsigned char val;
471 #if (BITS_IN_JSAMPLE == 8) 459 #if (BITS_IN_JSAMPLE == 8)
472 val = (unsigned char)*jp++; 460 val = (unsigned char)*jp++;
473 #else /* other option is 12 */ 461 #else /* other option is 12 */
490 } 478 }
491 } 479 }
492 480
493 /* 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 */
494 /* now instantiate */ 482 /* now instantiate */
495 MAYBE_DEVMETH (XDEVICE (ii->device), 483 MAYBE_DEVMETH (XDEVICE (ii->device),
496 init_image_instance_from_eimage, 484 init_image_instance_from_eimage,
497 (ii, cinfo.output_width, cinfo.output_height, 485 (ii, cinfo.output_width, cinfo.output_height,
498 unwind.eimage, dest_mask, 486 unwind.eimage, dest_mask,
499 instantiator, domain)); 487 instantiator, domain));
500 488
501 /* Step 7: Finish decompression */ 489 /* Step 7: Finish decompression */
502 490
503 jpeg_finish_decompress (&cinfo); 491 jpeg_finish_decompress (&cinfo);
574 562
575 static size_t 563 static size_t
576 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data) 564 gif_read_from_memory(GifByteType *buf, size_t size, VoidPtr data)
577 { 565 {
578 gif_memory_storage *mem = (gif_memory_storage*)data; 566 gif_memory_storage *mem = (gif_memory_storage*)data;
579 567
580 if (size > (mem->len - mem->index)) 568 if (size > (mem->len - mem->index))
581 return -1; 569 return (size_t) -1;
582 memcpy(buf, mem->bytes + mem->index, size); 570 memcpy(buf, mem->bytes + mem->index, size);
583 mem->index = mem->index + size; 571 mem->index = mem->index + size;
584 return size; 572 return size;
585 } 573 }
586 574
621 struct gif_error_struct gif_err; 609 struct gif_error_struct gif_err;
622 Extbyte *bytes; 610 Extbyte *bytes;
623 Extcount len; 611 Extcount len;
624 int height = 0; 612 int height = 0;
625 int width = 0; 613 int width = 0;
626 614
627 xzero (unwind); 615 xzero (unwind);
628 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind)); 616 record_unwind_protect (gif_instantiate_unwind, make_opaque_ptr (&unwind));
629 617
630 /* 1. Now decode the data. */ 618 /* 1. Now decode the data. */
631 619
632 { 620 {
633 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data); 621 Lisp_Object data = find_keyword_in_vector (instantiator, Q_data);
634 622
635 assert (!NILP (data)); 623 assert (!NILP (data));
636 624
637 if (!(unwind.giffile = GifSetup())) 625 if (!(unwind.giffile = GifSetup()))
638 signal_image_error ("Insufficent memory to instantiate GIF image", instantiator); 626 signal_image_error ("Insufficent memory to instantiate GIF image", instantiator);
639 627
640 /* set up error facilities */ 628 /* set up error facilities */
641 if (setjmp(gif_err.setjmp_buffer)) 629 if (setjmp(gif_err.setjmp_buffer))
642 { 630 {
643 /* 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
644 for us. Just pass the error along. */ 632 for us. Just pass the error along. */
645 Lisp_Object errstring; 633 Lisp_Object errstring;
646 errstring = build_string (gif_err.err_str); 634 errstring = build_string (gif_err.err_str);
647 signal_image_error_2 ("GIF decoding error", errstring, instantiator); 635 signal_image_error_2 ("GIF decoding error", errstring, instantiator);
648 } 636 }
649 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);
650 638
651 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len); 639 GET_STRING_BINARY_DATA_ALLOCA (data, bytes, len);
652 mem_struct.bytes = bytes; 640 mem_struct.bytes = bytes;
653 mem_struct.len = len; 641 mem_struct.len = len;
654 mem_struct.index = 0; 642 mem_struct.index = 0;
655 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct); 643 GifSetReadFunc(unwind.giffile, gif_read_from_memory, (VoidPtr)&mem_struct);
656 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct); 644 GifSetCloseFunc(unwind.giffile, gif_memory_close, (VoidPtr)&mem_struct);
657 DGifInitRead(unwind.giffile); 645 DGifInitRead(unwind.giffile);
658 646
659 /* Then slurp the image into memory, decoding along the way. 647 /* Then slurp the image into memory, decoding along the way.
660 The result is the image in a simple one-byte-per-pixel 648 The result is the image in a simple one-byte-per-pixel
661 format (#### the GIF routines only support 8-bit GIFs, 649 format (#### the GIF routines only support 8-bit GIFs,
662 it appears). */ 650 it appears). */
663 DGifSlurp (unwind.giffile); 651 DGifSlurp (unwind.giffile);
664 } 652 }
665 653
666 /* 3. Now create the EImage */ 654 /* 3. Now create the EImage */
667 { 655 {
668 ColorMapObject *cmo = unwind.giffile->SColorMap; 656 ColorMapObject *cmo = unwind.giffile->SColorMap;
669 int i, j, row, pass, interlace; 657 int i, j, row, pass, interlace;
670 unsigned char *eip; 658 unsigned char *eip;
671 /* interlaced gifs have rows in this order: 659 /* interlaced gifs have rows in this order:
672 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, ... */
673 static int InterlacedOffset[] = { 0, 4, 2, 1 }; 661 static int InterlacedOffset[] = { 0, 4, 2, 1 };
674 static int InterlacedJumps[] = { 8, 8, 4, 2 }; 662 static int InterlacedJumps[] = { 8, 8, 4, 2 };
675 663
676 height = unwind.giffile->SHeight; 664 height = unwind.giffile->SHeight;
677 width = unwind.giffile->SWidth; 665 width = unwind.giffile->SWidth;
678 unwind.eimage = (unsigned char*) xmalloc (width * height * 3); 666 unwind.eimage = (unsigned char*) xmalloc (width * height * 3);
679 if (!unwind.eimage) 667 if (!unwind.eimage)
680 signal_image_error("Unable to allocate enough memory for image", instantiator); 668 signal_image_error("Unable to allocate enough memory for image", instantiator);
681 669
682 /* write the data in EImage format (8bit RGB triples) */ 670 /* write the data in EImage format (8bit RGB triples) */
683 671
684 /* Note: We just use the first image in the file and ignore the rest. 672 /* Note: We just use the first image in the file and ignore the rest.
685 We check here that that image covers the full "screen" size. 673 We check here that that image covers the full "screen" size.
686 I don't know whether that's always the case. 674 I don't know whether that's always the case.
687 -dkindred@cs.cmu.edu */ 675 -dkindred@cs.cmu.edu */
688 if (unwind.giffile->SavedImages[0].ImageDesc.Height != height 676 if (unwind.giffile->SavedImages[0].ImageDesc.Height != height
689 || unwind.giffile->SavedImages[0].ImageDesc.Width != width 677 || unwind.giffile->SavedImages[0].ImageDesc.Width != width
690 || unwind.giffile->SavedImages[0].ImageDesc.Left != 0 678 || unwind.giffile->SavedImages[0].ImageDesc.Left != 0
691 || unwind.giffile->SavedImages[0].ImageDesc.Top != 0) 679 || unwind.giffile->SavedImages[0].ImageDesc.Top != 0)
692 signal_image_error ("First image in GIF file is not full size", 680 signal_image_error ("First image in GIF file is not full size",
693 instantiator); 681 instantiator);
694 682
695 interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace; 683 interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace;
696 pass = 0; 684 pass = 0;
697 row = interlace ? InterlacedOffset[pass] : 0; 685 row = interlace ? InterlacedOffset[pass] : 0;
698 eip = unwind.eimage; 686 eip = unwind.eimage;
699 for (i = 0; i < height; i++) 687 for (i = 0; i < height; i++)
700 { 688 {
701 if (interlace) 689 if (interlace)
702 if (row >= height) { 690 if (row >= height) {
703 row = InterlacedOffset[++pass]; 691 row = InterlacedOffset[++pass];
704 while (row > height) 692 while (row > height)
705 row = InterlacedOffset[++pass]; 693 row = InterlacedOffset[++pass];
706 } 694 }
707 eip = unwind.eimage + (row * width * 3); 695 eip = unwind.eimage + (row * width * 3);
708 for (j = 0; j < width; j++) 696 for (j = 0; j < width; j++)
709 { 697 {
714 } 702 }
715 row += interlace ? InterlacedJumps[pass] : 1; 703 row += interlace ? InterlacedJumps[pass] : 1;
716 } 704 }
717 } 705 }
718 /* now instantiate */ 706 /* now instantiate */
719 MAYBE_DEVMETH (XDEVICE (ii->device), 707 MAYBE_DEVMETH (XDEVICE (ii->device),
720 init_image_instance_from_eimage, 708 init_image_instance_from_eimage,
721 (ii, width, height, unwind.eimage, dest_mask, 709 (ii, width, height, unwind.eimage, dest_mask,
722 instantiator, domain)); 710 instantiator, domain));
723 711
724 unbind_to (speccount, Qnil); 712 unbind_to (speccount, Qnil);
725 } 713 }
726 714
727 #endif /* HAVE_GIF */ 715 #endif /* HAVE_GIF */
728 716
776 jmp_buf setjmp_buffer; /* for return to caller */ 764 jmp_buf setjmp_buffer; /* for return to caller */
777 }; 765 };
778 766
779 /* 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
780 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
781 between inside the libarary, and inside the code! To do an end run 769 between inside the library, and inside the code! To do an end run
782 around this, use our own error functions, and don't rely on things 770 around this, use our own error functions, and don't rely on things
783 passed in the png_ptr to them. This is an ugly hack and must 771 passed in the png_ptr to them. This is an ugly hack and must
784 go away when the lisp engine is threaded! */ 772 go away when the lisp engine is threaded! */
785 static struct png_error_struct png_err_stct; 773 static struct png_error_struct png_err_stct;
786 774
846 if (!info_ptr) 834 if (!info_ptr)
847 { 835 {
848 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL); 836 png_destroy_read_struct (&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
849 signal_image_error ("Error obtaining memory for png_read", instantiator); 837 signal_image_error ("Error obtaining memory for png_read", instantiator);
850 } 838 }
851 839
852 xzero (unwind); 840 xzero (unwind);
853 unwind.png_ptr = png_ptr; 841 unwind.png_ptr = png_ptr;
854 unwind.info_ptr = info_ptr; 842 unwind.info_ptr = info_ptr;
855 843
856 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind)); 844 record_unwind_protect (png_instantiate_unwind, make_opaque_ptr (&unwind));
861 */ 849 */
862 /* It has been further modified to handle the API changes for 0.96, 850 /* It has been further modified to handle the API changes for 0.96,
863 and is no longer usable for previous versions. jh 851 and is no longer usable for previous versions. jh
864 */ 852 */
865 853
866 /* Set the jmp_buf reurn context for png_error ... if this returns !0, then 854 /* Set the jmp_buf return context for png_error ... if this returns !0, then
867 we ran into a problem somewhere, and need to clean up after ourselves. */ 855 we ran into a problem somewhere, and need to clean up after ourselves. */
868 if (setjmp (png_err_stct.setjmp_buffer)) 856 if (setjmp (png_err_stct.setjmp_buffer))
869 { 857 {
870 /* Something blew up: just display the error (cleanup happens in the unwind) */ 858 /* Something blew up: just display the error (cleanup happens in the unwind) */
871 signal_image_error_2 ("Error decoding PNG", 859 signal_image_error_2 ("Error decoding PNG",
901 /* Wow, allocate all the memory. Truly, exciting. */ 889 /* Wow, allocate all the memory. Truly, exciting. */
902 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3); 890 unwind.eimage = xnew_array_and_zero (unsigned char, width * height * 3);
903 /* libpng expects that the image buffer passed in contains a 891 /* libpng expects that the image buffer passed in contains a
904 picture to draw on top of if the png has any transparencies. 892 picture to draw on top of if the png has any transparencies.
905 This could be a good place to pass that in... */ 893 This could be a good place to pass that in... */
906 894
907 row_pointers = xnew_array (png_byte *, height); 895 row_pointers = xnew_array (png_byte *, height);
908 896
909 for (y = 0; y < height; y++) 897 for (y = 0; y < height; y++)
910 row_pointers[y] = unwind.eimage + (width * 3 * y); 898 row_pointers[y] = unwind.eimage + (width * 3 * y);
911 899
934 (c)); 922 (c));
935 my_background.red = XINT (XCAR (rgblist)); 923 my_background.red = XINT (XCAR (rgblist));
936 my_background.green = XINT (XCAR (XCDR (rgblist))); 924 my_background.green = XINT (XCAR (XCDR (rgblist)));
937 my_background.blue = XINT (XCAR (XCDR (XCDR (rgblist)))); 925 my_background.blue = XINT (XCAR (XCDR (XCDR (rgblist))));
938 } 926 }
939 927
940 if (png_get_bKGD (png_ptr, info_ptr, &image_background)) 928 if (png_get_bKGD (png_ptr, info_ptr, &image_background))
941 png_set_background (png_ptr, image_background, 929 png_set_background (png_ptr, image_background,
942 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); 930 PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
943 else 931 else
944 png_set_background (png_ptr, &my_background, 932 png_set_background (png_ptr, &my_background,
945 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); 933 PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
946 } 934 }
947 935
948 /* Now that we're using EImage, ask for 8bit RGB triples for any type 936 /* Now that we're using EImage, ask for 8bit RGB triples for any type
949 of image*/ 937 of image*/
950 /* convert palatte images to full RGB */ 938 /* convert palette images to full RGB */
951 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 939 if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
952 png_set_expand (png_ptr); 940 png_set_expand (png_ptr);
953 /* send grayscale images to RGB too */ 941 /* send grayscale images to RGB too */
954 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY || 942 if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
955 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 943 info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
969 png_set_packing (png_ptr); 957 png_set_packing (png_ptr);
970 } 958 }
971 959
972 png_read_image (png_ptr, row_pointers); 960 png_read_image (png_ptr, row_pointers);
973 png_read_end (png_ptr, info_ptr); 961 png_read_end (png_ptr, info_ptr);
974 962
975 #ifdef PNG_SHOW_COMMENTS 963 #ifdef PNG_SHOW_COMMENTS
976 /* #### 964 /* ####
977 * I turn this off by default now, because the !%^@#!% comments 965 * I turn this off by default now, because the !%^@#!% comments
978 * show up every time the image is instantiated, which can get 966 * show up every time the image is instantiated, which can get
979 * really really annoying. There should be some way to pass this 967 * really really annoying. There should be some way to pass this
998 986
999 xfree (row_pointers); 987 xfree (row_pointers);
1000 } 988 }
1001 989
1002 /* now instantiate */ 990 /* now instantiate */
1003 MAYBE_DEVMETH (XDEVICE (ii->device), 991 MAYBE_DEVMETH (XDEVICE (ii->device),
1004 init_image_instance_from_eimage, 992 init_image_instance_from_eimage,
1005 (ii, width, height, unwind.eimage, dest_mask, 993 (ii, width, height, unwind.eimage, dest_mask,
1006 instantiator, domain)); 994 instantiator, domain));
1007 995
1008 /* This will clean up everything else. */ 996 /* This will clean up everything else. */
1009 unbind_to (speccount, Qnil); 997 unbind_to (speccount, Qnil);
1010 } 998 }
1104 return -1; 1092 return -1;
1105 } 1093 }
1106 1094
1107 if ((newidx > mem->len) || (newidx < 0)) 1095 if ((newidx > mem->len) || (newidx < 0))
1108 return -1; 1096 return -1;
1109 1097
1110 mem->index = newidx; 1098 mem->index = newidx;
1111 return newidx; 1099 return newidx;
1112 } 1100 }
1113 1101
1114 static int 1102 static int
1204 int speccount = specpdl_depth (); 1192 int speccount = specpdl_depth ();
1205 uint32 width, height; 1193 uint32 width, height;
1206 1194
1207 xzero (unwind); 1195 xzero (unwind);
1208 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind)); 1196 record_unwind_protect (tiff_instantiate_unwind, make_opaque_ptr (&unwind));
1209 1197
1210 /* set up error facilities */ 1198 /* set up error facilities */
1211 if (setjmp (tiff_err_data.setjmp_buffer)) 1199 if (setjmp (tiff_err_data.setjmp_buffer))
1212 { 1200 {
1213 /* An error was signaled. No clean up is needed, as unwind handles that 1201 /* An error was signaled. No clean up is needed, as unwind handles that
1214 for us. Just pass the error along. */ 1202 for us. Just pass the error along. */
1246 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width); 1234 TIFFGetField (unwind.tiff, TIFFTAG_IMAGEWIDTH, &width);
1247 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height); 1235 TIFFGetField (unwind.tiff, TIFFTAG_IMAGELENGTH, &height);
1248 unwind.eimage = (unsigned char *) xmalloc (width * height * 3); 1236 unwind.eimage = (unsigned char *) xmalloc (width * height * 3);
1249 1237
1250 /* ### This is little more than proof-of-concept/function testing. 1238 /* ### This is little more than proof-of-concept/function testing.
1251 It needs to be reimplimented via scanline reads for both memory 1239 It needs to be reimplemented via scanline reads for both memory
1252 compactness. */ 1240 compactness. */
1253 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32)); 1241 raster = (uint32*) _TIFFmalloc (width * height * sizeof (uint32));
1254 if (raster != NULL) 1242 if (raster != NULL)
1255 { 1243 {
1256 int i,j; 1244 int i,j;
1278 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator); 1266 signal_image_error ("Unable to allocate memory for TIFFReadRGBA", instantiator);
1279 1267
1280 } 1268 }
1281 1269
1282 /* now instantiate */ 1270 /* now instantiate */
1283 MAYBE_DEVMETH (XDEVICE (ii->device), 1271 MAYBE_DEVMETH (XDEVICE (ii->device),
1284 init_image_instance_from_eimage, 1272 init_image_instance_from_eimage,
1285 (ii, width, height, unwind.eimage, dest_mask, 1273 (ii, width, height, unwind.eimage, dest_mask,
1286 instantiator, domain)); 1274 instantiator, domain));
1287 1275
1288 unbind_to (speccount, Qnil); 1276 unbind_to (speccount, Qnil);
1289 } 1277 }
1290 1278