home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / win / tkWinImage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  7.4 KB  |  330 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tkWinImage.c --
  3.  *
  4.  *    This file contains routines for manipulation full-color images.
  5.  *
  6.  * Copyright (c) 1995 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * SCCS: @(#) tkWinImage.c 1.13 97/07/07 11:19:45
  12.  */
  13.  
  14. #include "tkWinInt.h"
  15.  
  16. static int        DestroyImage _ANSI_ARGS_((XImage* data));
  17. static unsigned long    ImageGetPixel _ANSI_ARGS_((XImage *image, int x, int y));
  18. static int        PutPixel _ANSI_ARGS_((XImage *image, int x, int y,
  19.                 unsigned long pixel));
  20.  
  21. /*
  22.  *----------------------------------------------------------------------
  23.  *
  24.  * DestroyImage --
  25.  *
  26.  *    This is a trivial wrapper around ckfree to make it possible to
  27.  *    pass ckfree as a pointer.
  28.  *
  29.  * Results:
  30.  *    None.
  31.  *
  32.  * Side effects:
  33.  *    Deallocates the image.
  34.  *
  35.  *----------------------------------------------------------------------
  36.  */
  37.  
  38. int
  39. DestroyImage(imagePtr)
  40.      XImage *imagePtr;        /* image to free */
  41. {
  42.     if (imagePtr) {
  43.     if (imagePtr->data) {
  44.         ckfree((char*)imagePtr->data);
  45.     }
  46.     ckfree((char*)imagePtr);
  47.     }
  48.     return 0;
  49. }
  50.  
  51. /*
  52.  *----------------------------------------------------------------------
  53.  *
  54.  * ImageGetPixel --
  55.  *
  56.  *    Get a single pixel from an image.
  57.  *
  58.  * Results:
  59.  *    Returns the 32 bit pixel value.
  60.  *
  61.  * Side effects:
  62.  *    None.
  63.  *
  64.  *----------------------------------------------------------------------
  65.  */
  66.  
  67. unsigned long
  68. ImageGetPixel(image, x, y)
  69.     XImage *image;
  70.     int x, y;
  71. {
  72.     unsigned long pixel = 0;
  73.     unsigned char *srcPtr = &(image->data[(y * image->bytes_per_line)
  74.         + ((x * image->bits_per_pixel) / NBBY)]);
  75.  
  76.     switch (image->bits_per_pixel) {
  77.     case 32:
  78.     case 24:
  79.         pixel = RGB(srcPtr[2], srcPtr[1], srcPtr[0]);
  80.         break;
  81.     case 16:
  82.         pixel = RGB(((((WORD*)srcPtr)[0]) >> 7) & 0xf8,
  83.             ((((WORD*)srcPtr)[0]) >> 2) & 0xf8,
  84.             ((((WORD*)srcPtr)[0]) << 3) & 0xf8);
  85.         break;
  86.     case 8:
  87.         pixel = srcPtr[0];
  88.         break;
  89.     case 4:
  90.         pixel = ((x%2) ? (*srcPtr) : ((*srcPtr) >> 4)) & 0x0f;
  91.         break;
  92.     case 1:
  93.         pixel = ((*srcPtr) & (0x80 >> (x%8))) ? 1 : 0;
  94.         break;
  95.     }
  96.     return pixel;
  97. }
  98.  
  99. /*
  100.  *----------------------------------------------------------------------
  101.  *
  102.  * PutPixel --
  103.  *
  104.  *    Set a single pixel in an image.
  105.  *
  106.  * Results:
  107.  *    None.
  108.  *
  109.  * Side effects:
  110.  *    None.
  111.  *
  112.  *----------------------------------------------------------------------
  113.  */
  114.  
  115. static int
  116. PutPixel(image, x, y, pixel)
  117.     XImage *image;
  118.     int x, y;
  119.     unsigned long pixel;
  120. {
  121.     unsigned char *destPtr = &(image->data[(y * image->bytes_per_line)
  122.         + ((x * image->bits_per_pixel) / NBBY)]);
  123.  
  124.     switch  (image->bits_per_pixel) {
  125.     case 32:
  126.         /*
  127.          * Pixel is DWORD: 0x00BBGGRR
  128.          */
  129.  
  130.         destPtr[3] = 0;
  131.     case 24:
  132.         /*
  133.          * Pixel is triplet: 0xBBGGRR.
  134.          */
  135.  
  136.         destPtr[0] = (unsigned char) GetBValue(pixel);
  137.         destPtr[1] = (unsigned char) GetGValue(pixel);
  138.         destPtr[2] = (unsigned char) GetRValue(pixel);
  139.         break;
  140.     case 16:
  141.         /*
  142.          * Pixel is WORD: 5-5-5 (R-G-B)
  143.          */
  144.  
  145.         (*(WORD*)destPtr) = 
  146.         ((GetRValue(pixel) & 0xf8) << 7)
  147.         | ((GetGValue(pixel) & 0xf8) <<2)
  148.         | ((GetBValue(pixel) & 0xf8) >> 3);
  149.         break;
  150.     case 8:
  151.         /*
  152.          * Pixel is 8-bit index into color table.
  153.          */
  154.  
  155.         (*destPtr) = (unsigned char) pixel;
  156.         break;
  157.     case 4:
  158.         /*
  159.          * Pixel is 4-bit index in MSBFirst order.
  160.          */
  161.         if (x%2) {
  162.         (*destPtr) = (unsigned char) (((*destPtr) & 0xf0)
  163.             | (pixel & 0x0f));
  164.         } else {
  165.         (*destPtr) = (unsigned char) (((*destPtr) & 0x0f)
  166.             | ((pixel << 4) & 0xf0));
  167.         }
  168.         break;
  169.     case 1: {
  170.         /*
  171.          * Pixel is bit in MSBFirst order.
  172.          */
  173.  
  174.         int mask = (0x80 >> (x%8));
  175.         if (pixel) {
  176.         (*destPtr) |= mask;
  177.         } else {
  178.         (*destPtr) &= ~mask;
  179.         }
  180.     }
  181.     break;
  182.     }
  183.     return 0;
  184. }
  185.  
  186. /*
  187.  *----------------------------------------------------------------------
  188.  *
  189.  * XCreateImage --
  190.  *
  191.  *    Allocates storage for a new XImage.
  192.  *
  193.  * Results:
  194.  *    Returns a newly allocated XImage.
  195.  *
  196.  * Side effects:
  197.  *    None.
  198.  *
  199.  *----------------------------------------------------------------------
  200.  */
  201.  
  202. XImage *
  203. XCreateImage(display, visual, depth, format, offset, data, width, height,
  204.     bitmap_pad, bytes_per_line)
  205.     Display* display;
  206.     Visual* visual;
  207.     unsigned int depth;
  208.     int format;
  209.     int offset;
  210.     char* data;
  211.     unsigned int width;
  212.     unsigned int height;
  213.     int bitmap_pad;
  214.     int bytes_per_line;
  215. {
  216.     XImage* imagePtr = (XImage *) ckalloc(sizeof(XImage));
  217.     imagePtr->width = width;
  218.     imagePtr->height = height;
  219.     imagePtr->xoffset = offset;
  220.     imagePtr->format = format;
  221.     imagePtr->data = data;
  222.     imagePtr->byte_order = LSBFirst;
  223.     imagePtr->bitmap_unit = 8;
  224.     imagePtr->bitmap_bit_order = MSBFirst;
  225.     imagePtr->bitmap_pad = bitmap_pad;
  226.     imagePtr->bits_per_pixel = depth;
  227.     imagePtr->depth = depth;
  228.  
  229.     /*
  230.      * Under Windows, bitmap_pad must be on an LONG data-type boundary.
  231.      */
  232.  
  233. #define LONGBITS    (sizeof(LONG) * 8)
  234.  
  235.     bitmap_pad = (bitmap_pad + LONGBITS - 1) / LONGBITS * LONGBITS;
  236.  
  237.     /*
  238.      * Round to the nearest bitmap_pad boundary.
  239.      */
  240.  
  241.     if (bytes_per_line) {
  242.     imagePtr->bytes_per_line = bytes_per_line;
  243.     } else {
  244.     imagePtr->bytes_per_line = (((depth * width)
  245.         + (bitmap_pad - 1)) >> 3) & ~((bitmap_pad >> 3) - 1);
  246.     }
  247.  
  248.     imagePtr->red_mask = 0;
  249.     imagePtr->green_mask = 0;
  250.     imagePtr->blue_mask = 0;
  251.  
  252.     imagePtr->f.put_pixel = PutPixel;
  253.     imagePtr->f.get_pixel = ImageGetPixel;
  254.     imagePtr->f.destroy_image = DestroyImage;
  255.     imagePtr->f.create_image = NULL;
  256.     imagePtr->f.sub_image = NULL;
  257.     imagePtr->f.add_pixel = NULL;
  258.     
  259.     return imagePtr;
  260. }
  261.  
  262. /*
  263.  *----------------------------------------------------------------------
  264.  *
  265.  * XGetImage --
  266.  *
  267.  *    This function copies data from a pixmap or window into an
  268.  *    XImage.
  269.  *
  270.  * Results:
  271.  *    Returns a newly allocated image containing the data from the
  272.  *    given rectangle of the given drawable.
  273.  *
  274.  * Side effects:
  275.  *    None.
  276.  *
  277.  *----------------------------------------------------------------------
  278.  */
  279.  
  280. XImage *
  281. XGetImage(display, d, x, y, width, height, plane_mask, format)
  282.     Display* display;
  283.     Drawable d;
  284.     int x;
  285.     int y;
  286.     unsigned int width;
  287.     unsigned int height;
  288.     unsigned long plane_mask;
  289.     int    format;
  290. {
  291.     TkWinDrawable *twdPtr = (TkWinDrawable *)d;
  292.     XImage *imagePtr;
  293.     HDC dc;
  294.     char infoBuf[sizeof(BITMAPINFO) + sizeof(RGBQUAD)];
  295.     BITMAPINFO *infoPtr = (BITMAPINFO*)infoBuf;
  296.  
  297.     if ((twdPtr->type != TWD_BITMAP) || (twdPtr->bitmap.handle == NULL)
  298.         || (format != XYPixmap) || (plane_mask != 1)) {
  299.     panic("XGetImage: not implemented");
  300.     }
  301.  
  302.  
  303.     imagePtr = XCreateImage(display, NULL, 1, XYBitmap, 0, NULL,
  304.         width, height, 32, 0);
  305.     imagePtr->data = ckalloc(imagePtr->bytes_per_line * imagePtr->height);
  306.  
  307.     dc = GetDC(NULL);
  308.  
  309.     GetDIBits(dc, twdPtr->bitmap.handle, 0, height, NULL,
  310.         infoPtr, DIB_RGB_COLORS);
  311.  
  312.     infoPtr->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  313.     infoPtr->bmiHeader.biWidth = width;
  314.     infoPtr->bmiHeader.biHeight = -(LONG)height;
  315.     infoPtr->bmiHeader.biPlanes = 1;
  316.     infoPtr->bmiHeader.biBitCount = 1;
  317.     infoPtr->bmiHeader.biCompression = BI_RGB;
  318.     infoPtr->bmiHeader.biCompression = 0;
  319.     infoPtr->bmiHeader.biXPelsPerMeter = 0;
  320.     infoPtr->bmiHeader.biYPelsPerMeter = 0;
  321.     infoPtr->bmiHeader.biClrUsed = 0;
  322.     infoPtr->bmiHeader.biClrImportant = 0;
  323.  
  324.     GetDIBits(dc, twdPtr->bitmap.handle, 0, height, imagePtr->data,
  325.         infoPtr, DIB_RGB_COLORS);
  326.     ReleaseDC(NULL, dc);
  327.  
  328.     return imagePtr;
  329. }
  330.