Doxygen Source Code Documentation
gifx.c File Reference
#include "gifx.h"
#include <X11/Xutil.h>
#include <assert.h>
#include <string.h>
Go to the source code of this file.
Define Documentation
|
Definition at line 264 of file gifx.c. Referenced by Gif_XSubMask(), and put_sub_image_colormap(). |
|
Definition at line 25 of file gifx.c. Referenced by put_sub_image_colormap(). |
Function Documentation
|
Definition at line 82 of file gifx.c. References Gif_Color::blue, c, Gif_XContext::closest, Gif_XContext::colormap, Gif_XContext::display, distance(), Gif_Color::green, Gif_Color::haspixel, i, load_closest(), Gif_XContext::nclosest, Gif_Color::pixel, Gif_Color::red, and u_int32_t. Referenced by allocate_colors().
00083 { 00084 Gif_Color *closer; 00085 Gif_Color *got = 0; 00086 u_int32_t distance = 0x4000000; 00087 int i; 00088 00089 load_closest(gfx); 00090 00091 for (i = 0, closer = gfx->closest; i < gfx->nclosest; i++, closer++) { 00092 int redd = c->red - closer->red; 00093 int greend = c->green - closer->green; 00094 int blued = c->blue - closer->blue; 00095 u_int32_t d = redd * redd + greend * greend + blued * blued; 00096 if (d < distance) { 00097 distance = d; 00098 got = closer; 00099 } 00100 } 00101 00102 if (!got) return 0; 00103 if (!got->haspixel) { 00104 XColor xcol; 00105 xcol.red = got->red | (got->red << 8); 00106 xcol.green = got->green | (got->green << 8); 00107 xcol.blue = got->blue | (got->blue << 8); 00108 if (XAllocColor(gfx->display, gfx->colormap, &xcol) == 0) { 00109 /* Probably was a read/write color cell. Get rid of it!! */ 00110 *got = gfx->closest[gfx->nclosest - 1]; 00111 gfx->nclosest--; 00112 return allocate_closest(gfx, c); 00113 } 00114 got->pixel = xcol.pixel; 00115 got->haspixel = 1; 00116 } 00117 00118 return got->pixel; 00119 } |
|
Definition at line 123 of file gifx.c. References allocate_closest(), Gif_XColormap::allocated, Gif_Color::blue, c, Gif_XColormap::claimed, Gif_Colormap::col, Gif_XContext::colormap, Gif_XColormap::colormap, Gif_XContext::display, Gif_Color::green, i, Gif_Colormap::ncol, Gif_XColormap::npixels, Gif_XColormap::pixels, pixels, Gif_Color::red, u_int16_t, and Gif_XColormap::x_context. Referenced by Gif_XAllocateColors(), Gif_XNextImage(), and put_sub_image_colormap().
00124 { 00125 Gif_XContext *gfx = gfxc->x_context; 00126 u_int16_t size = gfxc->colormap->ncol; 00127 Gif_Color *c = gfxc->colormap->col; 00128 unsigned long *pixels = gfxc->pixels; 00129 XColor xcol; 00130 int i; 00131 if (!gfxc->allocated) { 00132 if (size > gfxc->npixels) size = gfxc->npixels; 00133 for (i = 0; i < size; i++, c++) { 00134 xcol.red = c->red | (c->red << 8); 00135 xcol.green = c->green | (c->green << 8); 00136 xcol.blue = c->blue | (c->blue << 8); 00137 if (XAllocColor(gfx->display, gfx->colormap, &xcol)) 00138 pixels[i] = xcol.pixel; 00139 else 00140 pixels[i] = allocate_closest(gfx, c); 00141 } 00142 gfxc->allocated = 1; 00143 gfxc->claimed = 0; 00144 } 00145 } |
|
Definition at line 159 of file gifx.c. References Gif_XColormap::allocated, Gif_XColormap::colormap, Gif_Delete, Gif_DeleteArray, Gif_New, Gif_NewArray, Gif_Colormap::ncol, Gif_XColormap::next, Gif_XColormap::npixels, Gif_XColormap::pixels, pixels, Gif_XColormap::x_context, and Gif_XContext::xcolormap. Referenced by find_x_colormap_extension().
00160 { 00161 Gif_XColormap *gfxc; 00162 unsigned long *pixels; 00163 if (!gfcm) return 0; 00164 gfxc = Gif_New(Gif_XColormap); 00165 pixels = gfxc ? Gif_NewArray(unsigned long, 256) : 0; 00166 if (pixels) { 00167 gfxc->x_context = gfx; 00168 gfxc->colormap = gfcm; 00169 gfxc->allocated = 0; 00170 gfxc->npixels = gfcm->ncol; 00171 gfxc->pixels = pixels; 00172 gfxc->next = gfx->xcolormap; 00173 gfx->xcolormap = gfxc; 00174 return gfxc; 00175 } else { 00176 Gif_Delete(gfxc); 00177 Gif_DeleteArray(pixels); 00178 return 0; 00179 } 00180 } |
|
Definition at line 148 of file gifx.c. References Gif_XColormap::allocated, Gif_XColormap::claimed, Gif_XContext::colormap, Gif_XContext::display, Gif_XColormap::npixels, Gif_XColormap::pixels, and Gif_XColormap::x_context. Referenced by delete_xcolormap(), and Gif_XDeallocateColors().
|
|
Definition at line 671 of file gifx.c. References Gif_XColormap::colormap, delete_xcolormap(), dummy, Gif_XColormap::next, and Gif_XContext::xcolormap. Referenced by Gif_DeleteXContext(), and Gif_NewXContextFromVisual().
00672 { 00673 Gif_Colormap *gfcm = (Gif_Colormap *)colormap_x; 00674 Gif_XContext *gfx = (Gif_XContext *)callback_x; 00675 Gif_XColormap *gfxc; 00676 for (gfxc = gfx->xcolormap; gfxc; gfxc = gfxc->next) 00677 if (gfxc->colormap == gfcm) { 00678 delete_xcolormap(gfxc); 00679 return; 00680 } 00681 } |
|
CREATING AND DESTROYING XCONTEXTS * Definition at line 654 of file gifx.c. References deallocate_colors(), Gif_XContext::free_deleted_colormap_pixels, Gif_Delete, Gif_DeleteArray, Gif_XColormap::next, Gif_XColormap::pixels, Gif_XColormap::x_context, and Gif_XContext::xcolormap. Referenced by delete_colormap_hook(), and Gif_DeleteXContext().
00655 { 00656 Gif_XContext *gfx = gfxc->x_context; 00657 Gif_XColormap *prev = 0, *trav = gfx->xcolormap; 00658 while (trav != gfxc && trav) { 00659 prev = trav; 00660 trav = trav->next; 00661 } 00662 if (gfx->free_deleted_colormap_pixels) 00663 deallocate_colors(gfxc); 00664 if (prev) prev->next = gfxc->next; 00665 else gfx->xcolormap = gfxc->next; 00666 Gif_DeleteArray(gfxc->pixels); 00667 Gif_Delete(gfxc); 00668 } |
|
Definition at line 183 of file gifx.c. References Gif_XColormap::colormap, create_x_colormap_extension(), Gif_XColormap::next, and Gif_XContext::xcolormap. Referenced by Gif_XAllocateColors(), Gif_XClaimStreamColors(), Gif_XDeallocateColors(), Gif_XNextImage(), and put_sub_image_colormap().
00184 { 00185 Gif_XColormap *gfxc = gfx->xcolormap; 00186 if (!gfcm) return 0; 00187 while (gfxc) { 00188 if (gfxc->colormap == gfcm) 00189 return gfxc; 00190 gfxc = gfxc->next; 00191 } 00192 if (create) 00193 return create_x_colormap_extension(gfx, gfcm); 00194 else 00195 return 0; 00196 } |
|
Definition at line 729 of file gifx.c. References Gif_XContext::closest, delete_colormap_hook(), delete_xcolormap(), Gif_XContext::display, Gif_Delete, Gif_DeleteArray, Gif_RemoveDeletionHook(), GIF_T_COLORMAP, Gif_XContext::image_gc, Gif_XContext::mask_gc, Gif_XContext::refcount, and Gif_XContext::xcolormap. Referenced by delete_viewer().
00730 { 00731 if (!gfx) return; 00732 if (--gfx->refcount > 0) return; 00733 while (gfx->xcolormap) 00734 delete_xcolormap(gfx->xcolormap); 00735 if (gfx->image_gc) 00736 XFreeGC(gfx->display, gfx->image_gc); 00737 if (gfx->mask_gc) 00738 XFreeGC(gfx->display, gfx->mask_gc); 00739 Gif_DeleteArray(gfx->closest); 00740 Gif_Delete(gfx); 00741 Gif_RemoveDeletionHook(GIF_T_COLORMAP, delete_colormap_hook, gfx); 00742 } |
|
Definition at line 719 of file gifx.c. References display, and Gif_NewXContextFromVisual().
00720 { 00721 XWindowAttributes attr; 00722 XGetWindowAttributes(display, window, &attr); 00723 return Gif_NewXContextFromVisual(display, XScreenNumberOfScreen(attr.screen), 00724 attr.visual, attr.depth, attr.colormap); 00725 } |
|
|
Definition at line 199 of file gifx.c. References allocate_colors(), and find_x_colormap_extension().
00200 { 00201 Gif_XColormap *gfxc = find_x_colormap_extension(gfx, gfcm, 1); 00202 if (gfxc) { 00203 allocate_colors(gfxc); 00204 return 1; 00205 } else 00206 return 0; 00207 } |
|
Definition at line 219 of file gifx.c. References Gif_XColormap::allocated, Gif_XColormap::claimed, find_x_colormap_extension(), Gif_NewArray, global, Gif_Stream::global, i, Gif_Stream::images, Gif_Image::local, Gif_Stream::nimages, Gif_XColormap::npixels, pixels, and Gif_XColormap::pixels.
00220 { 00221 int i; 00222 int npixels = 0; 00223 unsigned long *pixels; 00224 Gif_Colormap *global = gfs->global; 00225 *np_store = 0; 00226 00227 for (i = 0; i < gfs->nimages; i++) { 00228 Gif_Image *gfi = gfs->images[i]; 00229 Gif_Colormap *gfcm = (gfi->local ? gfi->local : global); 00230 Gif_XColormap *gfxc = find_x_colormap_extension(gfx, gfcm, 0); 00231 if (gfxc && gfxc->allocated && gfxc->claimed == 0) { 00232 gfxc->claimed = 2; 00233 npixels += gfxc->npixels; 00234 if (gfcm == global) global = 0; 00235 } 00236 } 00237 00238 if (!npixels) return 0; 00239 00240 pixels = Gif_NewArray(unsigned long, npixels); 00241 if (!pixels) return 0; 00242 *np_store = npixels; 00243 00244 npixels = 0; 00245 global = gfs->global; 00246 for (i = 0; i < gfs->nimages; i++) { 00247 Gif_Image *gfi = gfs->images[i]; 00248 Gif_Colormap *gfcm = (gfi->local ? gfi->local : global); 00249 Gif_XColormap *gfxc = find_x_colormap_extension(gfx, gfcm, 0); 00250 if (gfxc && gfxc->allocated && gfxc->claimed == 2) { 00251 memcpy(pixels + npixels, gfxc->pixels, gfxc->npixels); 00252 npixels += gfxc->npixels; 00253 gfxc->claimed = 1; 00254 if (gfcm == global) global = 0; 00255 } 00256 } 00257 00258 return pixels; 00259 } |
|
Definition at line 210 of file gifx.c. References deallocate_colors(), and find_x_colormap_extension().
00211 { 00212 Gif_XColormap *gfxc = find_x_colormap_extension(gfx, gfcm, 0); 00213 if (gfxc) 00214 deallocate_colors(gfxc); 00215 } |
|
Definition at line 422 of file gifx.c. References Gif_XSubImageColormap(), Gif_Stream::global, Gif_Image::height, Gif_Stream::images, Gif_Image::local, Gif_Stream::nimages, and Gif_Image::width. Referenced by Gif_XNextImage(), and view_frame().
00423 { 00424 Gif_Colormap *gfcm; 00425 if (!gfi && gfs->nimages) gfi = gfs->images[0]; 00426 if (!gfi) return None; 00427 gfcm = gfi->local; 00428 if (!gfcm) gfcm = gfs->global; 00429 return Gif_XSubImageColormap(gfx, gfi, gfcm, 00430 0, 0, gfi->width, gfi->height); 00431 } |
|
Definition at line 434 of file gifx.c. References Gif_XSubImageColormap(), Gif_Image::height, Gif_Stream::images, Gif_Stream::nimages, and Gif_Image::width.
00436 { 00437 if (!gfi && gfs->nimages) gfi = gfs->images[0]; 00438 if (!gfi) return None; 00439 return Gif_XSubImageColormap(gfx, gfi, gfcm, 00440 0, 0, gfi->width, gfi->height); 00441 } |
|
Definition at line 543 of file gifx.c. References Gif_XSubMask(), Gif_Image::height, Gif_Stream::images, Gif_Stream::nimages, and Gif_Image::width. Referenced by Gif_XNextImage().
00544 { 00545 if (!gfi && gfs->nimages) gfi = gfs->images[0]; 00546 if (!gfi) return None; 00547 return Gif_XSubMask(gfx, gfi, 0, 0, gfi->width, gfi->height); 00548 } |
|
Definition at line 552 of file gifx.c. References allocate_colors(), Gif_Stream::background, Gif_XContext::depth, Gif_XContext::display, Gif_Image::disposal, Gif_XContext::drawable, error_exit(), find_x_colormap_extension(), GIF_DISPOSAL_BACKGROUND, GIF_DISPOSAL_PREVIOUS, Gif_XImage(), Gif_XMask(), Gif_Stream::global, Gif_Image::height, Gif_XContext::image_gc, Gif_Stream::images, Gif_Image::left, Gif_Image::local, Gif_Colormap::ncol, Gif_XColormap::pixels, put_sub_image_colormap(), Gif_Stream::screen_height, Gif_Stream::screen_width, Gif_Image::top, Gif_Image::transparent, Gif_XContext::transparent_pixel, and Gif_Image::width. Referenced by unoptimized_frame().
00554 { 00555 Pixmap pixmap = None, image = None, mask = None; 00556 Gif_Image *gfi = gfs->images[n]; 00557 Gif_Image *last_gfi = (n > 0 ? gfs->images[n-1] : 0); 00558 Gif_Colormap *gfcm = (gfi->local ? gfi->local : gfs->global); 00559 unsigned long bg_pixel; 00560 unsigned long old_transparent = gfx->transparent_pixel; 00561 00562 if (gfs->screen_width == 0 || gfs->screen_height == 0) 00563 return None; 00564 00565 if (gfi->width == gfs->screen_width && gfi->height == gfs->screen_height 00566 && gfi->left == 0 && gfi->top == 0 && gfi->transparent < 0) 00567 return Gif_XImage(gfx, gfs, gfi); 00568 00569 /* create the pixmap */ 00570 pixmap = XCreatePixmap(gfx->display, gfx->drawable, 00571 gfs->screen_width, gfs->screen_height, gfx->depth); 00572 if (!pixmap) goto error_exit; 00573 00574 /* find background color if necessary */ 00575 if (last == None 00576 || (last_gfi && last_gfi->disposal == GIF_DISPOSAL_BACKGROUND)) { 00577 /* find bg_pixel */ 00578 if (gfs->global && gfs->background < gfs->global->ncol 00579 && gfs->images[0]->transparent < 0) { 00580 Gif_XColormap *gfxc = find_x_colormap_extension(gfx, gfcm, 1); 00581 if (!gfxc) 00582 return None; 00583 allocate_colors(gfxc); 00584 bg_pixel = gfxc->pixels[gfs->background]; 00585 } else 00586 bg_pixel = old_transparent; 00587 /* install it as the foreground color on gfx->image_gc */ 00588 if (!gfx->image_gc) 00589 gfx->image_gc = XCreateGC(gfx->display, pixmap, 0, 0); 00590 if (!gfx->image_gc) goto error_exit; 00591 XSetForeground(gfx->display, gfx->image_gc, bg_pixel); 00592 gfx->transparent_pixel = bg_pixel; 00593 } 00594 00595 /* if there is no `last' then we need special handling */ 00596 if (last == None 00597 || (last_gfi && last_gfi->width == gfs->screen_width 00598 && last_gfi->height == gfs->screen_height 00599 && last_gfi->left == 0 && last_gfi->top == 0 00600 && last_gfi->disposal == GIF_DISPOSAL_BACKGROUND)) { 00601 XFillRectangle(gfx->display, pixmap, gfx->image_gc, 0, 0, 00602 gfs->screen_width, gfs->screen_height); 00603 if (!put_sub_image_colormap(gfx, gfi, gfcm, 0, 0, gfi->width, gfi->height, 00604 pixmap, gfi->left, gfi->top)) 00605 goto error_exit; 00606 return pixmap; 00607 } 00608 00609 /* use the disposal to create the intermediate image */ 00610 XCopyArea(gfx->display, last, pixmap, gfx->image_gc, 00611 0, 0, gfs->screen_width, gfs->screen_height, 0, 0); 00612 if (last_last != None && last_gfi->disposal == GIF_DISPOSAL_PREVIOUS) 00613 XCopyArea(gfx->display, last_last, pixmap, gfx->image_gc, 00614 last_gfi->left, last_gfi->top, last_gfi->width, last_gfi->height, 00615 last_gfi->left, last_gfi->top); 00616 else if (last_gfi->disposal == GIF_DISPOSAL_BACKGROUND) 00617 XFillRectangle(gfx->display, pixmap, gfx->image_gc, 00618 last_gfi->left, last_gfi->top, 00619 last_gfi->width, last_gfi->height); 00620 00621 /* apply image */ 00622 if (gfi->transparent < 0) { 00623 if (!put_sub_image_colormap(gfx, gfi, gfcm, 0, 0, gfi->width, gfi->height, 00624 pixmap, gfi->left, gfi->top)) 00625 goto error_exit; 00626 } else { 00627 image = Gif_XImage(gfx, gfs, gfi); 00628 mask = Gif_XMask(gfx, gfs, gfi); 00629 if (image == None || mask == None) goto error_exit; 00630 XSetClipMask(gfx->display, gfx->image_gc, mask); 00631 XSetClipOrigin(gfx->display, gfx->image_gc, gfi->left, gfi->top); 00632 XCopyArea(gfx->display, image, pixmap, gfx->image_gc, 00633 0, 0, gfi->width, gfi->height, gfi->left, gfi->top); 00634 XSetClipMask(gfx->display, gfx->image_gc, None); 00635 XFreePixmap(gfx->display, image); 00636 XFreePixmap(gfx->display, mask); 00637 } 00638 00639 gfx->transparent_pixel = old_transparent; 00640 return pixmap; 00641 00642 error_exit: 00643 if (pixmap) XFreePixmap(gfx->display, pixmap); 00644 if (image) XFreePixmap(gfx->display, image); 00645 if (mask) XFreePixmap(gfx->display, mask); 00646 gfx->transparent_pixel = old_transparent; 00647 return None; 00648 } |
|
Definition at line 444 of file gifx.c. References Gif_XSubImageColormap(), Gif_Stream::global, Gif_Stream::images, left, Gif_Image::local, Gif_Stream::nimages, and top.
00446 { 00447 Gif_Colormap *gfcm; 00448 if (!gfi && gfs->nimages) gfi = gfs->images[0]; 00449 if (!gfi) return None; 00450 gfcm = gfi->local; 00451 if (!gfcm) gfcm = gfs->global; 00452 return Gif_XSubImageColormap(gfx, gfi, gfcm, 00453 left, top, width, height); 00454 } |
|
Definition at line 406 of file gifx.c. References Gif_XContext::depth, Gif_XContext::display, Gif_XContext::drawable, left, put_sub_image_colormap(), and top. Referenced by Gif_XImage(), Gif_XImageColormap(), and Gif_XSubImage().
00408 { 00409 Pixmap pixmap = 00410 XCreatePixmap(gfx->display, gfx->drawable, width, height, gfx->depth); 00411 if (pixmap) { 00412 if (put_sub_image_colormap(gfx, gfi, gfcm, left, top, width, height, 00413 pixmap, 0, 0)) 00414 return pixmap; 00415 else 00416 XFreePixmap(gfx->display, pixmap); 00417 } 00418 return None; 00419 } |
|
Definition at line 458 of file gifx.c. References BYTESIZE, Gif_Image::compressed, Gif_XContext::display, Gif_XContext::drawable, Gif_DeleteArray, Gif_NewArray, Gif_ReleaseUncompressedImage(), Gif_UncompressImage, Gif_Image::height, i, Gif_Image::image_data, Gif_Image::img, left, Gif_XContext::mask_gc, top, Gif_Image::transparent, u_int32_t, Gif_XContext::visual, and Gif_Image::width. Referenced by Gif_XMask().
00460 { 00461 Pixmap pixmap = None; 00462 XImage *ximage; 00463 byte *xdata; 00464 00465 int i, j; 00466 int transparent; 00467 int bytes_per_line; 00468 int release_uncompressed = 0; 00469 00470 /* Find the correct image */ 00471 if (!gfi) return None; 00472 00473 /* Check subimage dimensions */ 00474 if (width <= 0 || height <= 0 || left < 0 || top < 0 00475 || left+width <= 0 || top+height <= 0 00476 || left+width > gfi->width || top+height > gfi->height) 00477 return None; 00478 00479 /* Make sure the image is uncompressed */ 00480 if (!gfi->img && !gfi->image_data && gfi->compressed) { 00481 Gif_UncompressImage(gfi); 00482 release_uncompressed = 1; 00483 } 00484 00485 /* Create the X image */ 00486 ximage = 00487 XCreateImage(gfx->display, gfx->visual, 1, 00488 XYBitmap, 0, NULL, 00489 width, height, 00490 8, 0); 00491 00492 ximage->bitmap_bit_order = ximage->byte_order = LSBFirst; 00493 bytes_per_line = ximage->bytes_per_line; 00494 xdata = Gif_NewArray(byte, bytes_per_line * height); 00495 ximage->data = (char *)xdata; 00496 00497 transparent = gfi->transparent; 00498 00499 /* The main loop */ 00500 for (j = 0; j < height; j++) { 00501 int imshift = 0; 00502 u_int32_t impixel = 0; 00503 byte *line = gfi->img[top + j] + left; 00504 byte *writer = xdata + bytes_per_line * j; 00505 00506 for (i = 0; i < width; i++) { 00507 if (line[i] == transparent) 00508 impixel |= 1 << imshift; 00509 00510 if (++imshift >= BYTESIZE) { 00511 *writer++ = impixel; 00512 imshift = 0; 00513 impixel = 0; 00514 } 00515 } 00516 00517 if (imshift) 00518 *writer++ = impixel; 00519 } 00520 00521 /* Create the pixmap */ 00522 pixmap = 00523 XCreatePixmap(gfx->display, gfx->drawable, width, height, 1); 00524 if (!gfx->mask_gc) 00525 gfx->mask_gc = XCreateGC(gfx->display, pixmap, 0, 0); 00526 00527 if (pixmap && gfx->mask_gc) 00528 XPutImage(gfx->display, pixmap, gfx->mask_gc, ximage, 0, 0, 0, 0, 00529 width, height); 00530 00531 Gif_DeleteArray(xdata); 00532 ximage->data = 0; /* avoid freeing it again in XDestroyImage */ 00533 XDestroyImage(ximage); 00534 00535 if (release_uncompressed) 00536 Gif_ReleaseUncompressedImage(gfi); 00537 00538 return pixmap; 00539 } |
|
Definition at line 45 of file gifx.c. References Gif_Color::blue, c, Gif_XContext::closest, color, Gif_XContext::colormap, Gif_XContext::display, Gif_DeleteArray, Gif_NewArray, Gif_Color::green, Gif_Color::haspixel, i, Gif_XContext::nclosest, ncolor, Gif_XContext::ncolormap, Gif_Color::pixel, Gif_Color::red, and u_int16_t. Referenced by allocate_closest().
00046 { 00047 XColor *color; 00048 u_int16_t ncolor; 00049 u_int16_t ncolormap; 00050 int i; 00051 00052 if (gfx->closest) return; 00053 00054 ncolormap = ncolor = gfx->ncolormap; 00055 if (ncolor > 256) ncolor = 256; 00056 color = Gif_NewArray(XColor, ncolor); 00057 00058 if (ncolormap > 256) 00059 for (i = 0; i < ncolor; i++) 00060 color[i].pixel = (rand() >> 4) % ncolormap; 00061 else 00062 for (i = 0; i < ncolor; i++) 00063 color[i].pixel = i; 00064 XQueryColors(gfx->display, gfx->colormap, color, ncolor); 00065 00066 gfx->closest = Gif_NewArray(Gif_Color, ncolor); 00067 for (i = 0; i < ncolor; i++) { 00068 Gif_Color *c = &gfx->closest[i]; 00069 c->haspixel = 1; 00070 c->red = color[i].red >> 8; 00071 c->green = color[i].green >> 8; 00072 c->blue = color[i].blue >> 8; 00073 c->pixel = color[i].pixel; 00074 } 00075 gfx->nclosest = ncolor; 00076 00077 Gif_DeleteArray(color); 00078 } |
|
Definition at line 267 of file gifx.c. References allocate_colors(), BYTESIZE, Gif_Image::compressed, crap_pixels, Gif_XContext::depth, Gif_XContext::display, find_x_colormap_extension(), Gif_XContext::foreground_pixel, Gif_DeleteArray, Gif_NewArray, Gif_ReleaseUncompressedImage(), Gif_UncompressImage, Gif_Image::height, i, Gif_Image::image_data, Gif_XContext::image_gc, Gif_Image::img, left, Gif_XColormap::npixels, Gif_XColormap::pixels, pixels, SAFELS, top, Gif_Image::transparent, Gif_XContext::transparent_pixel, u_int16_t, u_int32_t, Gif_XContext::visual, and Gif_Image::width. Referenced by Gif_XNextImage(), and Gif_XSubImageColormap().
00270 { 00271 XImage *ximage; 00272 byte *xdata; 00273 00274 int i, j, k; 00275 int bytes_per_line; 00276 00277 unsigned long saved_transparent = 0; 00278 int release_uncompressed = 0; 00279 u_int16_t nct; 00280 unsigned long *pixels; 00281 00282 /* Find the correct image and colormap */ 00283 if (!gfi) return 0; 00284 if (!gfx->image_gc) 00285 gfx->image_gc = XCreateGC(gfx->display, pixmap, 0, 0); 00286 if (!gfx->image_gc) 00287 return 0; 00288 00289 /* Make sure the image is uncompressed */ 00290 if (!gfi->img && !gfi->image_data && gfi->compressed) { 00291 Gif_UncompressImage(gfi); 00292 release_uncompressed = 1; 00293 } 00294 00295 /* Check subimage dimensions */ 00296 if (width <= 0 || height <= 0 || left < 0 || top < 0 00297 || left+width <= 0 || top+height <= 0 00298 || left+width > gfi->width || top+height > gfi->height) 00299 return 0; 00300 00301 /* Allocate colors from the colormap; make sure the transparent color 00302 * has the given pixel value */ 00303 if (gfcm) { 00304 Gif_XColormap *gfxc = find_x_colormap_extension(gfx, gfcm, 1); 00305 if (!gfxc) return 0; 00306 allocate_colors(gfxc); 00307 pixels = gfxc->pixels; 00308 nct = gfxc->npixels; 00309 } else { 00310 for (i = 0; i < 256; i++) crap_pixels[i] = gfx->foreground_pixel; 00311 pixels = crap_pixels; 00312 nct = 256; 00313 } 00314 if (gfi->transparent >= 0 && gfi->transparent < 256) { 00315 saved_transparent = pixels[ gfi->transparent ]; 00316 pixels[ gfi->transparent ] = gfx->transparent_pixel; 00317 } 00318 00319 /* Set up the X image */ 00320 if (gfx->depth <= 8) i = 8; 00321 else if (gfx->depth <= 16) i = 16; 00322 else i = 32; 00323 ximage = 00324 XCreateImage(gfx->display, gfx->visual, gfx->depth, 00325 gfx->depth == 1 ? XYBitmap : ZPixmap, 0, NULL, 00326 width, height, i, 0); 00327 00328 ximage->bitmap_bit_order = ximage->byte_order = LSBFirst; 00329 bytes_per_line = ximage->bytes_per_line; 00330 xdata = Gif_NewArray(byte, bytes_per_line * height); 00331 ximage->data = (char *)xdata; 00332 00333 /* The main loop */ 00334 if (ximage->bits_per_pixel % 8 == 0) { 00335 /* Optimize for cases where a pixel is exactly one or more bytes */ 00336 int bytes_per_pixel = ximage->bits_per_pixel / 8; 00337 00338 for (j = 0; j < height; j++) { 00339 byte *line = gfi->img[top + j] + left; 00340 byte *writer = xdata + bytes_per_line * j; 00341 for (i = 0; i < width; i++) { 00342 unsigned long pixel; 00343 if (line[i] < nct) 00344 pixel = pixels[line[i]]; 00345 else 00346 pixel = pixels[0]; 00347 for (k = 0; k < bytes_per_pixel; k++) { 00348 *writer++ = pixel; 00349 pixel >>= 8; 00350 } 00351 } 00352 } 00353 00354 } else { 00355 /* Other bits-per-pixel */ 00356 int bits_per_pixel = ximage->bits_per_pixel; 00357 u_int32_t bits_per_pixel_mask = (1UL << bits_per_pixel) - 1; 00358 00359 for (j = 0; j < height; j++) { 00360 int imshift = 0; 00361 u_int32_t impixel = 0; 00362 byte *line = gfi->img[top + j] + left; 00363 byte *writer = xdata + bytes_per_line * j; 00364 00365 for (i = 0; i < width; i++) { 00366 unsigned long pixel; 00367 if (line[i] < nct) 00368 pixel = pixels[line[i]]; 00369 else 00370 pixel = pixels[0]; 00371 00372 impixel |= SAFELS(pixel & bits_per_pixel_mask, imshift); 00373 while (imshift + bits_per_pixel >= BYTESIZE) { 00374 *writer++ = impixel; 00375 imshift -= BYTESIZE; 00376 impixel = SAFELS(pixel, imshift); 00377 } 00378 imshift += bits_per_pixel; 00379 } 00380 00381 if (imshift) 00382 *writer++ = impixel; 00383 } 00384 } 00385 00386 /* Restore saved transparent pixel value */ 00387 if (gfi->transparent >= 0 && gfi->transparent < 256) 00388 pixels[ gfi->transparent ] = saved_transparent; 00389 00390 /* Put it onto the pixmap */ 00391 XPutImage(gfx->display, pixmap, gfx->image_gc, ximage, 0, 0, 00392 pixmap_x, pixmap_y, width, height); 00393 00394 Gif_DeleteArray(xdata); 00395 ximage->data = 0; /* avoid freeing it again in XDestroyImage */ 00396 XDestroyImage(ximage); 00397 00398 if (release_uncompressed) 00399 Gif_ReleaseUncompressedImage(gfi); 00400 00401 return 1; 00402 } |
Variable Documentation
|
Definition at line 41 of file gifx.c. Referenced by put_sub_image_colormap(). |