Mercurial > hg > xemacs-beta
comparison src/glyphs-eimage.c @ 424:11054d720c21 r21-2-20
Import from CVS: tag r21-2-20
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:26:11 +0200 |
parents | 697ef44129c6 |
children |
comparison
equal
deleted
inserted
replaced
423:28d9c139be4c | 424:11054d720c21 |
---|---|
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 |
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 { |
711 | 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 } | |
740 | |
712 unbind_to (speccount, Qnil); | 741 unbind_to (speccount, Qnil); |
713 } | 742 } |
714 | 743 |
715 #endif /* HAVE_GIF */ | 744 #endif /* HAVE_GIF */ |
716 | 745 |
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 } |
1268 } | 1297 } |
1269 | 1298 |
1270 /* now instantiate */ | 1299 /* now instantiate */ |
1271 MAYBE_DEVMETH (XDEVICE (ii->device), | 1300 MAYBE_DEVMETH (XDEVICE (ii->device), |
1272 init_image_instance_from_eimage, | 1301 init_image_instance_from_eimage, |
1273 (ii, width, height, unwind.eimage, dest_mask, | 1302 (ii, width, height, 1, unwind.eimage, dest_mask, |
1274 instantiator, domain)); | 1303 instantiator, domain)); |
1275 | 1304 |
1276 unbind_to (speccount, Qnil); | 1305 unbind_to (speccount, Qnil); |
1277 } | 1306 } |
1278 | 1307 |