Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/src/glyphs-eimage.c Mon Aug 13 11:25:03 2007 +0200 +++ b/src/glyphs-eimage.c Mon Aug 13 11:26:11 2007 +0200 @@ -482,7 +482,7 @@ /* now instantiate */ MAYBE_DEVMETH (XDEVICE (ii->device), init_image_instance_from_eimage, - (ii, cinfo.output_width, cinfo.output_height, + (ii, cinfo.output_width, cinfo.output_height, 1, unwind.eimage, dest_mask, instantiator, domain)); @@ -651,10 +651,10 @@ DGifSlurp (unwind.giffile); } - /* 3. Now create the EImage */ + /* 3. Now create the EImage(s) */ { ColorMapObject *cmo = unwind.giffile->SColorMap; - int i, j, row, pass, interlace; + int i, j, row, pass, interlace, slice; unsigned char *eip; /* interlaced gifs have rows in this order: 0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */ @@ -663,52 +663,81 @@ height = unwind.giffile->SHeight; width = unwind.giffile->SWidth; - unwind.eimage = (unsigned char*) xmalloc (width * height * 3); + unwind.eimage = (unsigned char*) + xmalloc (width * height * 3 * unwind.giffile->ImageCount); if (!unwind.eimage) signal_image_error("Unable to allocate enough memory for image", instantiator); /* write the data in EImage format (8bit RGB triples) */ - /* Note: We just use the first image in the file and ignore the rest. - We check here that that image covers the full "screen" size. - I don't know whether that's always the case. - -dkindred@cs.cmu.edu */ - if (unwind.giffile->SavedImages[0].ImageDesc.Height != height - || unwind.giffile->SavedImages[0].ImageDesc.Width != width - || unwind.giffile->SavedImages[0].ImageDesc.Left != 0 - || unwind.giffile->SavedImages[0].ImageDesc.Top != 0) - signal_image_error ("First image in GIF file is not full size", - instantiator); - - interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace; - pass = 0; - row = interlace ? InterlacedOffset[pass] : 0; - eip = unwind.eimage; - for (i = 0; i < height; i++) + for (slice = 0; slice < unwind.giffile->ImageCount; slice++) { - if (interlace) - if (row >= height) { - row = InterlacedOffset[++pass]; - while (row >= height) - row = InterlacedOffset[++pass]; - } - eip = unwind.eimage + (row * width * 3); - for (j = 0; j < width; j++) + /* We check here that that the current image covers the full "screen" size. */ + if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height + || unwind.giffile->SavedImages[slice].ImageDesc.Width != width + || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0 + || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0) + signal_image_error ("Image in GIF file is not full size", + instantiator); + + interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace; + pass = 0; + row = interlace ? InterlacedOffset[pass] : 0; + eip = unwind.eimage + (width * height * 3 * slice); + for (i = 0; i < height; i++) { - unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j]; - *eip++ = cmo->Colors[pixel].Red; - *eip++ = cmo->Colors[pixel].Green; - *eip++ = cmo->Colors[pixel].Blue; + if (interlace) + if (row >= height) { + row = InterlacedOffset[++pass]; + while (row >= height) + row = InterlacedOffset[++pass]; + } + eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3); + for (j = 0; j < width; j++) + { + unsigned char pixel = + unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j]; + *eip++ = cmo->Colors[pixel].Red; + *eip++ = cmo->Colors[pixel].Green; + *eip++ = cmo->Colors[pixel].Blue; + } + row += interlace ? InterlacedJumps[pass] : 1; } - row += interlace ? InterlacedJumps[pass] : 1; } + + /* now instantiate */ + MAYBE_DEVMETH (XDEVICE (ii->device), + init_image_instance_from_eimage, + (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask, + instantiator, domain)); } - /* now instantiate */ - MAYBE_DEVMETH (XDEVICE (ii->device), - init_image_instance_from_eimage, - (ii, width, height, unwind.eimage, dest_mask, - instantiator, domain)); + + /* We read the gif successfully. If we have more than one slice then + animate the gif. */ + if (unwind.giffile->ImageCount > 1) + { + /* See if there is a timeout value. In theory there could be one + for every image - but that makes the implementation way to + complicated for now so we just take the first. */ + unsigned short timeout = 0; + Lisp_Object tid; + if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE + && + unwind.giffile->SavedImages[0].ExtensionBlockCount) + { + timeout = (unsigned short) + ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) + + unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10; + } + + /* Too short a timeout will crucify us performance-wise. */ + tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance); + + if (!NILP (tid)) + IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid); + } + unbind_to (speccount, Qnil); } @@ -990,7 +1019,7 @@ /* now instantiate */ MAYBE_DEVMETH (XDEVICE (ii->device), init_image_instance_from_eimage, - (ii, width, height, unwind.eimage, dest_mask, + (ii, width, height, 1, unwind.eimage, dest_mask, instantiator, domain)); /* This will clean up everything else. */ @@ -1270,7 +1299,7 @@ /* now instantiate */ MAYBE_DEVMETH (XDEVICE (ii->device), init_image_instance_from_eimage, - (ii, width, height, unwind.eimage, dest_mask, + (ii, width, height, 1, unwind.eimage, dest_mask, instantiator, domain)); unbind_to (speccount, Qnil);