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