home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / lib / map_scan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-19  |  45.6 KB  |  1,970 lines

  1. /*
  2. * This software is copyrighted as noted below.  It may be freely copied,
  3. * modified, and redistributed, provided that the copyright notices are
  4. * preserved on all copies.
  5. *
  6. * There is no warranty or other guarantee of fitness for this software,
  7. * it is provided solely "as is".  Bug reports or fixes may be sent
  8. * to the author, who may or may not act on them as he desires.
  9. *
  10. * You may not include this software in a program or other software product
  11. * without supplying the source, or without informing the end-user that the
  12. * source is available for no extra charge.
  13. *
  14. * If you modify this software, you should include a notice giving the
  15. * name of the person performing the modification, the date of modification,
  16. * and the reason for such modification.
  17. */
  18. /*
  19. * map_scan.c - Put RLE images on X display.
  20. *
  21. * Author:    Spencer W. Thomas  (x10)
  22. *        Computer Science Dept.
  23. *        University of Utah
  24. * Date:    Thu Feb 20 1986
  25. * Copyright (c) 1986, University of Utah
  26. *
  27. * Modified:    Andrew F. Vesper (x 11)
  28. *        High Performance Workstations
  29. *        Digital Equipment Corp
  30. * Date:    Fri, Aug 7, 1987
  31. *        Thu, Jan 14, 1988
  32. * Copyright (c) 1987,1988, Digital Equipment Corporation
  33. *
  34. * Modified:    Martin R. Friedmann (better X11, flipbook, MAG, info)
  35. *         Dept of Electrical Engineering and Computer Science
  36. *        University of Michigan
  37. * Date:    Tue, Nov 14, 1989
  38. * Copyright (c) 1989, University of Michigan
  39. *
  40. * Modified:    Jin, Guojun (x11)
  41. *        IMAGE Technology Group
  42. *        Lawrence Berkeley Laboratory
  43. * Date: Mon, Oct 1, 1990
  44. #        change dpy from global to local.
  45. #        It is also made in entire libpanel.
  46. $    Thu, Feb 6, 1992
  47. #        Add start_col {x} in all map_XXX_??dither_??table_#()
  48. #        routines for fast painting in small region.
  49. #        Add shrink (-MAG)
  50. * Copyright (c)    1990, 1992, Lawrence Berkeley Laboratory
  51. */
  52.  
  53. #include "panel.h"
  54.  
  55. #ifndef    DEFAULT_GAMMA
  56. #define    DEFAULT_GAMMA    1.0    /*    no gamma correction    */
  57. #endif
  58.  
  59. double    display_gamma = DEFAULT_GAMMA;    /* 2.5 fits most NTSC monitors    */
  60. int    red_shift,
  61.     green_shift,
  62.     blue_shift;
  63. Pixel    red_mask,
  64.     green_mask,
  65.     blue_mask;
  66.  
  67. static void    map_scanline_generic();
  68. static void    map_1_dither_table_1(),
  69.         map_1_dither_table_8(),
  70.         map_1_nodither_table_8(),
  71.         map_2or3_dither_table_8(),
  72.         map_1_nodither_notable_32(),
  73.         map_2or3_nodither_table_8(),
  74.         map_2or3_dither_notable_32(),
  75.         map_2or3_nodither_notable_32();
  76. static void    map_1_mono_color_8(),
  77.         map_1_mono_color_32();
  78. static void    MAG_scanline_generic();
  79. static void    MAG_1_dither_table_1(),
  80.         MAG_1_dither_table_8(),
  81.         MAG_1_nodither_table_8(),
  82.         MAG_1_nodither_notable_32();
  83. static void    MAG_2or3_dither_table_8(),
  84.         MAG_2or3_nodither_table_8(),
  85.         MAG_2or3_dither_notable_32(),
  86.         MAG_2or3_nodither_notable_32();
  87. static void    MAG_1_mono_color_8(),
  88.         MAG_1_mono_color_32();
  89.  
  90. static byte    LSBMask[9] = {    0x0, 0x1, 0x3, 0x7,
  91.                 0xf, 0x1f, 0x3f, 0x7f, 0xff };
  92. #if EVEN_NEVER_CALLED    /* Not actually used    */
  93. static byte    MSBMask[9] = {    0x00, 0x80, 0xc0, 0xe0,
  94.                 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
  95. #endif    EVEN_NEVER_CALLED
  96.  
  97.  
  98. /*
  99. * Figure out which scan line routine to use.
  100. */
  101.  
  102. void
  103. choose_scanline_converter(img)
  104. image_information *img;
  105. {
  106. register int    i;
  107. register Boolean table_present;
  108. static struct {
  109.     Boolean    one_color;
  110.     Boolean    dither;
  111.     Boolean    table_present;
  112.     int    bpp;
  113.     void    (*routine)();
  114.     void    (*mag_routine)();
  115. } map_scanline_table[] =
  116.   {
  117.     /* 1 color, dithr, Table, b/p, routine ptr */
  118.  
  119.     {    True, True, True, 1, map_1_dither_table_1,    MAG_1_dither_table_1},
  120.     {    True, True, True, 8, map_1_dither_table_8,    MAG_1_dither_table_8},
  121.     {    True, False,True, 8, map_1_nodither_table_8,    MAG_1_nodither_table_8},
  122.     {    True, False,False,32,map_1_nodither_notable_32,    MAG_1_nodither_notable_32},
  123.     {    False,True, True, 8, map_2or3_dither_table_8,    MAG_2or3_dither_table_8},
  124.     {    False,False,True, 8, map_2or3_nodither_table_8,    MAG_2or3_nodither_table_8},
  125.     {    False,True, False,32,map_2or3_dither_notable_32,MAG_2or3_dither_notable_32},
  126.     {    False,False,False,32,map_2or3_nodither_notable_32,MAG_2or3_nodither_notable_32}
  127.   };
  128.  
  129.     img->map_scanline = map_scanline_generic;
  130.     img->MAG_scanline = MAG_scanline_generic;
  131.  
  132.     if (img->pixel_table == NULL)
  133.     table_present = False;
  134.     else table_present = True;
  135.  
  136.     if (img->mono_color)
  137.     switch (img->image->bits_per_pixel) {
  138.     case 32:
  139.         img->map_scanline = map_1_mono_color_32;
  140.         img->MAG_scanline = MAG_1_mono_color_32;
  141.         break;
  142.     case 8:
  143.         img->map_scanline = map_1_mono_color_8;
  144.         img->MAG_scanline = MAG_1_mono_color_8;
  145.         break;
  146.     default:
  147.         message("%s: Warning: Bits per pixel = %d\n",
  148.             progname, img->image->bits_per_pixel);
  149.     } else
  150.         for (i = 0; i < COUNT_OF (map_scanline_table); i++) {
  151.         if (map_scanline_table[i].one_color == img->mono_img &&
  152.             map_scanline_table[i].dither == img->dither_img &&
  153.             map_scanline_table[i].table_present == table_present &&
  154.             map_scanline_table[i].bpp == img->image->bits_per_pixel) {
  155.             img->map_scanline = map_scanline_table[i].routine;
  156.             img->MAG_scanline = map_scanline_table[i].mag_routine;
  157.  
  158.             if (DEBUGANY) {
  159.             message("Special map_scanline routine used: map_");
  160.  
  161.             if (img->mono_img)
  162.                 fputs ("1_", stderr);
  163.             else    fputs ("2or3_", stderr);
  164.  
  165.             if (!img->dither_img)
  166.                 fputs ("no", stderr);
  167.             fputs ("dither_", stderr);
  168.  
  169.             if (! table_present) fputs ("no", stderr);
  170.                 message("table_%d (index %d)\n",
  171.                     img->image->bits_per_pixel, i);
  172.             }
  173.             break;
  174.         }
  175.        }
  176. }
  177.  
  178. /*
  179.  * Map a scanline through the dither matrix.
  180.  *
  181.  * Inputs:
  182.  *    rgb:        Pointers to buffers containing the red, green,
  183.  *            and blue color rows.
  184.  *    n:        Length of row.
  185.  *    s:        Skip between pixels in original image.
  186.  *    y:        Y position of row (necessary for dither)
  187.  *    line:        Pointer to output buffer for dithered color data.
  188.  */
  189.  
  190. #define DMAP(v,x,y)    (divN[v] + (modN[v]>dm16[x][y] ? 1 : 0))
  191. #define NDMAP(v)    (divN[v])
  192.  
  193. #define DMAP_SETUP(img) \
  194.     register int *divN = img->divN;\
  195.     register int *modN = img->modN;\
  196.     register array16 *dm16 = img->dm16
  197.  
  198. #define NDMAP_SETUP(img)    register int *divN = img->divN
  199.  
  200. #define IN_CMAP_SETUP(img)    register rle_pixel **in_cmap = img->in_cmap
  201.  
  202. #define LEVELS_SETUP(img) \
  203.     register int levels = img->lvls; \
  204.     register int levels_squared = img->lvls_squared
  205.  
  206.  
  207. static void
  208. map_scanline_generic (img, rgb, ncolors, given_width, stride, y, x, image)
  209. image_information *img;
  210. byte    *rgb[3];
  211. int    ncolors,
  212.     given_width,
  213.     stride, y;
  214. register int    x;
  215. XImage    *image;
  216. {
  217. register Pixel *pixel_table = img->pixel_table;
  218. DMAP_SETUP(img);
  219. LEVELS_SETUP(img);
  220. register int    col, row;
  221. register byte *r;
  222. register long    pixel;
  223. register int    width = given_width;
  224.  
  225.     row = y & 0xF;
  226.     r = rgb[col=0];
  227.  
  228.     if (ncolors == 1) {
  229.  
  230.     if (img->dither_img) {
  231.         for (; width-- > 0; r += stride, col = ((col + 1) & 15), x++) {
  232.         pixel = pixel_table [DMAP(*r, col, row)];
  233.         if (pixel) pixel = 0xffffffff;
  234.         XPutPixel (image, x, y, pixel);
  235.         }
  236.     }
  237.     else {
  238.         for (; width--; r += stride, x++) {
  239.         pixel = pixel_table [NDMAP(*r)];
  240.         XPutPixel (image, x, y, pixel);
  241.         }
  242.     }
  243.     }
  244.  
  245.     else {
  246.     register byte *g, *b;
  247.  
  248.     g = b = rgb[1];
  249.     if (ncolors >= 3) b = rgb[2];
  250.  
  251.     if (img->dither_img) {
  252.         for (; width-- > 0; r += stride, g += stride, b += stride,
  253.          col = ((col + 1) & 15), x++)
  254.         {
  255.         if (pixel_table != NULL)
  256.             pixel = pixel_table
  257.             [DMAP(*r, col, row) +
  258.              DMAP(*g, col, row) * levels +
  259.              DMAP(*b, col, row) * levels_squared];
  260.  
  261.         else pixel = SHIFT_MASK_PIXEL (DMAP(*r, col, row),
  262.                            DMAP(*g, col, row),
  263.                            DMAP(*b, col, row));
  264.  
  265.         XPutPixel (image, x, y, pixel);
  266.         }
  267.  
  268.     }
  269.     else {
  270.  
  271.         for (; width-- > 0; r += stride, g += stride, b += stride, x++) {
  272.         if (pixel_table != NULL) {
  273.             pixel = pixel_table
  274.             [NDMAP(*r) +
  275.              NDMAP(*g) * levels +
  276.              NDMAP(*b) * levels_squared];
  277.         }
  278.         else {
  279.             pixel = SHIFT_MASK_PIXEL (NDMAP(*r), NDMAP(*g), NDMAP(*b));
  280.         }
  281.         XPutPixel (image, x, y, pixel);
  282.         }
  283.     }
  284.     }    
  285. }
  286.  
  287. static void
  288. MAG_scanline_generic(img, rle_x, rle_y, mag_size, x, y, width, height, image)
  289. image_information *img;
  290. int    rle_x, rle_y,
  291.     width, height,
  292.     mag_size,
  293.     x, y;
  294. XImage    *image;
  295.  
  296. {
  297. register Pixel *pixel_table = img->pixel_table;
  298. DMAP_SETUP(img);
  299. LEVELS_SETUP(img);
  300. register int     col;
  301. register byte    *r;
  302. int    save_x = x,
  303.     mag_y, mag_f = abs(mag_size),
  304.     x_mod_16 = (mag_f * rle_x) & 0xF,
  305.     rgb_line_stride = img->w * img->dpy_channels;
  306. register int     mag_x, w, row = (mag_f * rle_y - 1) & 0xF;
  307. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x;
  308. register unsigned long    pixel;
  309.     while (height-- > 0) {
  310.     x = save_x;
  311.     w = width;
  312.     row = (row + 1) & 0xF;    /* = % 16; change through this file */
  313.     col = x_mod_16;
  314.     r = rgb_line;
  315.     mag_x = mag_f;
  316.  
  317.     if (img->dpy_channels == 1) {
  318.  
  319.         if (img->dither_img)
  320.         while (w-- > 0)    {
  321.             pixel = pixel_table [DMAP(*r, col++, row)];
  322.             XPutPixel (image, x, y, pixel);
  323.             if (mag_size < 0)
  324.             r += mag_x,    w -= mag_x - 1;
  325.             else if (--mag_x == 0)
  326.             r++,    mag_x = mag_f;
  327.             col &= 15;    x++;
  328.         }
  329.         else while (w-- > 0)    {
  330.             pixel = pixel_table [NDMAP(*r)];
  331.             XPutPixel (image, x, y, pixel);
  332.             if (mag_size < 0)
  333.             r += mag_x,    w -= mag_x - 1;
  334.             else if (--mag_x == 0)
  335.             r++,    mag_x = mag_f;
  336.             x++;
  337.         }
  338.     } else    {
  339.     register byte    *g, *b;
  340.  
  341.         g = b = r + img->w;
  342.         if (img->dpy_channels >= 3)    b += img->w;
  343.  
  344.         if (img->dither_img)
  345.         while (w-- > 0)
  346.         {
  347.             if (pixel_table != NULL)
  348.             pixel = pixel_table
  349.                 [DMAP(*r, col, row) +
  350.                  DMAP(*g, col, row) * levels +
  351.                  DMAP(*b, col, row) * levels_squared];
  352.  
  353.             else pixel =
  354.             SHIFT_MASK_PIXEL (DMAP(*r, col, row),
  355.                       DMAP(*g, col, row),
  356.                       DMAP(*b, col, row));
  357.             XPutPixel (image, x++, y, pixel);
  358.             if (mag_size < 0)
  359.             r += mag_x,    g += mag_x,    b += mag_x,
  360.             w -= mag_x - 1;
  361.             else if (--mag_x == 0)    {
  362.             r++, g++, b++;
  363.             mag_x = mag_f;
  364.             }
  365.             col++;
  366.             col &= 15;
  367.         }
  368.         else while (w-- > 0)    {
  369.             if (pixel_table != NULL)
  370.             pixel = pixel_table
  371.                 [NDMAP(*r) +
  372.                  NDMAP(*g) * levels +
  373.                  NDMAP(*b) * levels_squared];
  374.             else pixel = SHIFT_MASK_PIXEL (NDMAP(*r),
  375.                            NDMAP(*g),
  376.                            NDMAP(*b));
  377.  
  378.             XPutPixel (image, x++, y, pixel);
  379.             if (mag_size < 0)
  380.             r += mag_x,    g += mag_x,    b += mag_x,
  381.             w -= mag_x - 1;
  382.             else if (--mag_x == 0)
  383.             {
  384.             r++, g++, b++;
  385.             mag_x = mag_f;
  386.             }
  387.         }
  388.     }
  389.     if (mag_size < 0)
  390.         rgb_line += rgb_line_stride * mag_x,
  391.         height -= mag_x - 1;
  392.     else if (--mag_y == 0)    {
  393.         rgb_line += rgb_line_stride;
  394.         mag_y = mag_f;
  395.     }
  396.     y++;
  397.     }
  398. }
  399.  
  400. /*
  401.  * map_1_dither_table_8
  402.  *
  403.  * Inputs:
  404.  *    rgb:        Pointers to buffers containing the red, green,
  405.  *            and blue color rows.
  406.  *    n:        Length of row.
  407.  *    s:        Skip between pixels in original image.
  408.  *    y:        Y position of row (necessary for dither)
  409.  *    line:        Pointer to output buffer for dithered color data.
  410.  */
  411.  
  412. static    void
  413. map_1_dither_table_8(img, rgb, ncolors, given_width, stride, y, start_col, image)
  414. image_information *img;
  415. byte    *rgb[3];
  416. int    ncolors,
  417.     given_width,
  418.     stride, y, start_col;
  419. XImage    *image;
  420. {
  421. register Pixel    *pixel_table = img->pixel_table;
  422. DMAP_SETUP(img);
  423. register int    col, row;
  424. register byte    *r, *pixel_ptr;
  425. register int    width = given_width;
  426.  
  427.     row = y & 0xF;
  428.     col = 0;
  429.     r = rgb[0];
  430.  
  431.     pixel_ptr = ((byte *) image->data) + y * image->bytes_per_line + start_col;
  432.  
  433.     while (width-- > 0) {
  434.     *pixel_ptr++ = pixel_table [ DMAP(*r, col, row) ];
  435.     
  436.     r += stride;
  437.     col = ((col + 1) & 15);
  438.     }
  439. }
  440.  
  441. static    void
  442. MAG_1_dither_table_8(img, rle_x, rle_y, mag_size, x, y, width, height, image)
  443. image_information *img;
  444. int    rle_x, rle_y,
  445.     width, height,
  446.     mag_size,
  447.     x, y;
  448. XImage    *image;
  449. {
  450. register Pixel    *pixel_table = img->pixel_table;
  451. DMAP_SETUP(img);
  452. register int     col;
  453. register byte    *r, *pixel_ptr;
  454. register int     mag, w;
  455. int         mag_f = abs(mag_size), wd = width / mag_f;
  456. register int     row = (mag_f * rle_y - 1) & 0xF;
  457. int     x_mod_16 = (mag_f * rle_x) & 0xF,
  458.     rgb_line_stride = img->w * img->dpy_channels;
  459. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  460.     *line_ptr = ((byte *) image->data)+(y * image->bytes_per_line) + x;
  461.  
  462.     height /= mag_f;
  463.  
  464.     while (height--) {
  465.     pixel_ptr = line_ptr;
  466.     w = wd;
  467.     row = (row + 1) & 0xF;
  468.     col = x_mod_16;
  469.     r = rgb_line;
  470.  
  471.     while (w--) {
  472.         *pixel_ptr++ = pixel_table [DMAP(*r, col, row) ];
  473.         mag = mag_f;
  474.         if (mag_size > 0)    {
  475.             r++;
  476.             while (--mag)
  477.                 *pixel_ptr++ = pixel_ptr[-1];
  478.         } else    r += mag;
  479.         col = (col + mag_f) & 0xF;
  480.     }
  481.     mag = mag_f;
  482.     while (--mag)
  483.         if (mag_size < 0)
  484.         rgb_line += rgb_line_stride;
  485.         else    {
  486.         line_ptr += image->bytes_per_line;
  487.         memcpy(line_ptr, line_ptr - image->bytes_per_line, width);
  488.         }
  489.     rgb_line += rgb_line_stride;
  490.     line_ptr += image->bytes_per_line;
  491.     }
  492. }
  493.  
  494. /*
  495.  * map_2or3_dither_table_8
  496.  *
  497.  * Dither three colors into an eight bit table...  This is faster than the
  498.  * map_scanline_generic routine.
  499.  *
  500.  * Inputs:
  501.  *    rgb:        Pointers to buffers containing the red, green,
  502.  *            and blue color rows.
  503.  *    n:        Length of row.
  504.  *    s:        Skip between pixels in original image.
  505.  *    y:        Y position of row (necessary for dither)
  506.  *    line:        Pointer to output buffer for dithered color data.
  507.  */
  508.  
  509. static    void
  510. map_2or3_dither_table_8 (img, rgb, ncolors, given_width, stride, y, x, image)
  511. image_information *img;
  512. byte    *rgb[3];
  513. int    ncolors,
  514.     given_width,
  515.     stride, y, x;
  516. XImage    *image;
  517.  
  518. {
  519. register Pixel *pixel_table = img->pixel_table;
  520. DMAP_SETUP(img);
  521. LEVELS_SETUP(img);
  522. register int    col, row;
  523. register byte    *r, *g, *b;
  524. register byte    *pixel_ptr;
  525. register int    width = given_width;
  526.  
  527.     row = y & 0xF;
  528.     r = rgb[col=0];
  529.     g = b = rgb[1];
  530.     if (ncolors >= 3) b = rgb[2];
  531.  
  532.     pixel_ptr = (byte *) image->data + y * image->bytes_per_line + x;
  533.  
  534.     while (width-- > 0) {
  535.     *pixel_ptr++ = pixel_table[DMAP(*r, col, row) +
  536.                 DMAP(*g, col, row) * levels +
  537.                 DMAP(*b, col, row) * levels_squared];
  538.     r += stride;
  539.     g += stride;
  540.     b += stride;
  541.     col++;     col &= 0xF;
  542.     }
  543. }
  544.  
  545. static    void
  546. MAG_2or3_dither_table_8 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  547. image_information *img;
  548. int    rle_x, rle_y,
  549.     width, height,
  550.     mag_size,
  551.     x, y;
  552. XImage    *image;
  553.  
  554. {
  555. register Pixel    *pixel_table = img->pixel_table;
  556. DMAP_SETUP(img);
  557. LEVELS_SETUP(img);
  558. int    mag_y, mag_f = abs(mag_size),
  559.     x_mod_16 = (mag_f * rle_x) & 0xF,
  560.     rgb_line_stride = img->w * img->dpy_channels;
  561. register byte    *r, *g, *b, *pixel_ptr;
  562. register int     col, mag_x, w, row = (mag_f * rle_y - 1) & 0xF;
  563. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  564.     *line_ptr = (byte *) image->data + y * image->bytes_per_line + x;
  565.  
  566.     width /= (mag_y = mag_f);
  567.     if (mag_size < 0)
  568.         height /= mag_f;
  569.  
  570.     while (height--) {
  571.     pixel_ptr = line_ptr;
  572.     w = width;
  573.     row = (row + 1) & 0xF;
  574.     col = x_mod_16;
  575.  
  576.     r = rgb_line;
  577.     g = b = r + img->w;
  578.     if (img->dpy_channels >= 3) b += img->w;
  579.  
  580.     while (w--) {
  581.         *pixel_ptr++ = pixel_table [DMAP(*r, col, row) +
  582.                     DMAP(*g, col, row) * levels +
  583.                     DMAP(*b, col, row) * levels_squared];
  584.         col++;    col &= 0xF;
  585.         mag_x = mag_f;
  586.         if (mag_size < 0)    {
  587.         r += mag_x,    g += mag_x,    b += mag_x;
  588.         } else    {
  589.         while (--mag_x)    {
  590.             *pixel_ptr++ = pixel_table [DMAP(*r, col, row) +
  591.                     DMAP(*g, col, row) * levels +
  592.                     DMAP(*b, col, row) * levels_squared];
  593.             col++;
  594.             col &= 0xF;
  595.         }
  596.         r++, g++, b++;
  597.         }
  598.     }
  599.     line_ptr += image->bytes_per_line;
  600.     if (mag_size < 0)
  601.         rgb_line += rgb_line_stride * mag_x;    /* mag_x = mag_f */
  602.     else if (--mag_y == 0)    {
  603.         rgb_line += rgb_line_stride;
  604.         mag_y = mag_f;
  605.     }
  606.     }
  607. }
  608.  
  609. /*
  610.  * map_1_dither_table_1
  611.  *
  612.  * Dither three colors into an eight bit table...  This is faster than the
  613.  * map_scanline_generic routine.
  614.  *
  615.  * Inputs:
  616.  *    rgb:        Pointers to buffers containing the red, green,
  617.  *            and blue color rows.
  618.  *    n:        Length of row.
  619.  *    s:        Skip between pixels in original image.
  620.  *    y:        Y position of row (necessary for dither)
  621.  *    line:        Pointer to output buffer for dithered color data.
  622.  */
  623.  
  624. static    void
  625. map_1_dither_table_1 (img, rgb, ncolors, given_width, stride, y, x, image)
  626. image_information *img;
  627. byte    *rgb[3];
  628. int    ncolors, given_width;
  629. register int    stride;
  630. int        y, x;
  631. XImage        *image;
  632.  
  633. {
  634. register Pixel *pixel_table = img->pixel_table;
  635. DMAP_SETUP(img);
  636. register int    col, row;
  637. register byte    *r;
  638. register byte    *pixel_ptr;
  639. register int    width = given_width;
  640. int    bit;
  641.     row = y & 0xF;
  642.     col = bit = 0;
  643.     r = rgb[0];
  644.  
  645.     pixel_ptr = ((byte *) image->data) + y * image->bytes_per_line + x;
  646.  
  647.     if (BitmapBitOrder(img->dpy) == MSBFirst) {
  648.         /* we don't want to trash those good bits */
  649.         *pixel_ptr >>= (8 - bit) & 7;
  650.  
  651.         /* do first byte fragment */
  652.         while (col & 7)
  653.         {
  654.         *pixel_ptr <<= 1;
  655.         if (pixel_table[DMAP(*r, col++, row)])
  656.             *pixel_ptr |= (byte) 0x1;
  657.         width--;
  658.         r += stride;
  659.         }
  660.         if (bit)
  661.  
  662.         pixel_ptr++, col &= 15;
  663.  
  664.         while ((width -= 8) >= 0) {
  665.         *pixel_ptr = 0;
  666.         if (pixel_table[DMAP(*r, col++, row)])
  667.             *pixel_ptr = (byte) 0x80;
  668.         r += stride;
  669.         if (pixel_table[DMAP(*r, col++, row)])
  670.             *pixel_ptr |= (byte) 0x40;
  671.         r += stride;
  672.         if (pixel_table[DMAP(*r, col++, row)])
  673.             *pixel_ptr |= (byte) 0x20;
  674.         r += stride;
  675.         if (pixel_table[DMAP(*r, col++, row)])
  676.             *pixel_ptr |= (byte) 0x10;
  677.         r += stride;
  678.         if (pixel_table[DMAP(*r, col++, row)])
  679.             *pixel_ptr |= (byte) 0x8;
  680.         r += stride;
  681.         if (pixel_table[DMAP(*r, col++, row)])
  682.             *pixel_ptr |= (byte) 0x4;
  683.         r += stride;
  684.         if (pixel_table[DMAP(*r, col++, row)])
  685.             *pixel_ptr |= (byte) 0x2;
  686.         r += stride;
  687.         if (pixel_table[DMAP(*r, col++, row)])
  688.             *pixel_ptr |= (byte) 0x1;
  689.         r += stride;
  690.         col &= 15;
  691.         pixel_ptr++;
  692.         }
  693.  
  694.         /* if w is non-zero then we have to finish up... */
  695.         width = 8 + width;
  696.         if (width)
  697.         {
  698.         byte savebits;
  699.  
  700.         savebits = *pixel_ptr & LSBMask[8-width];
  701.         bit = width;
  702.         
  703.         while (--width >= 0) {
  704.             *pixel_ptr <<= 1;
  705.             if (pixel_table [DMAP(*r, col++, row)])
  706.             *pixel_ptr |= (byte) 0x1;
  707.             r += stride;
  708.         }
  709.         *pixel_ptr <<= 8 - bit;
  710.         *pixel_ptr |= savebits;
  711.         }
  712.     }
  713.     else
  714.     while (--width >= 0) {
  715.         *pixel_ptr = (byte)(*pixel_ptr >> 1) | (byte)
  716.         ((pixel_table[DMAP(*r, col, row)]!= 0) ? 0x80: 0);
  717.         
  718.         r += stride;
  719.         col = ((col + 1) & 15);
  720.         bit = ((bit + 1) & 7);
  721.         if (!bit) pixel_ptr++;
  722.     }
  723. }
  724.  
  725. #define INC_RGB(stmt)    if (mag_size < 0)    { r += mag_x; w -= mag_x-1; }\
  726.         else    if (--mag_x == 0) {stmt; mag_x = mag_f; }
  727. static    void
  728. MAG_1_dither_table_1 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  729. image_information *img;
  730. int    rle_x, rle_y,
  731.     width, height,
  732.     mag_size,
  733.     x, y;
  734. XImage    *image;
  735. {
  736. register Pixel *pixel_table = img->pixel_table;
  737. DMAP_SETUP(img);
  738. int    mag_f = abs(mag_size);
  739. register int    col, bit;
  740. register byte    *r;
  741. register byte    *pixel_ptr;
  742. register int    mag_x, w;
  743. register int    row = (mag_f * rle_y - 1) & 0xF;
  744. int    rgb_line_stride = img->w * img->dpy_channels,
  745.     x_mod_16 = (mag_f * rle_x) & 0xF,
  746.     x_mod_8 = x & 0x7,
  747.     mag_y = mag_f,
  748.     byte_order = BitmapBitOrder(img->dpy);
  749. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  750.     *line_ptr = (byte *) image->data + y * image->bytes_per_line + (x>>3);
  751.  
  752.     while (height-- > 0) {
  753.     pixel_ptr = line_ptr;
  754.     w = width;
  755.     r = rgb_line;
  756.     mag_x = mag_f;
  757.  
  758.     row = (row + 1) & 0xF;
  759.     col = x_mod_16;
  760.     bit = x_mod_8;
  761.  
  762.     if (byte_order == MSBFirst) {
  763.         /* we don't want to trash those good bits */
  764.         *pixel_ptr >>= (8 - bit) & 7;
  765.  
  766.         /* do first byte fragment */
  767.         while (bit & 7)
  768.         {
  769.         *pixel_ptr <<= 1;
  770.         *pixel_ptr |= pixel_table[DMAP(*r, col++, row)] != 0;
  771.         w--;
  772.         INC_RGB(r++);
  773.         bit++;
  774.         col &= 15;
  775.         }
  776.         if (x_mod_8)
  777.         pixel_ptr++;
  778.  
  779.         /* do the bulk of the line fast in eight bit chunks Gee I hope all
  780.          * this fits into your instruction cache...  Or else we are
  781.          * forked..   You can get rid of 7 (col &= 15)'s if you make dm16
  782.          * a 32x16 array with duplicates in the second half of the columns.
  783.          * Then we don't have to worry about col overflowing in 8 ++'s
  784.          */
  785.         while ((w -= 8) >= 0) {
  786.         *pixel_ptr = (byte) 0;
  787.         if (pixel_table[DMAP(*r, col++, row)])
  788.             *pixel_ptr = (byte) 0x80;
  789.         INC_RGB(r++);    col &= 15;
  790.         if (pixel_table[DMAP(*r, col++, row)])
  791.             *pixel_ptr |= (byte) 0x40;
  792.         INC_RGB(r++);    col &= 15;
  793.         if (pixel_table[DMAP(*r, col++, row)])
  794.             *pixel_ptr |= (byte) 0x20;
  795.         INC_RGB(r++);    col &= 15;
  796.         if (pixel_table[DMAP(*r, col++, row)])
  797.             *pixel_ptr |= (byte) 0x10;
  798.         INC_RGB(r++);    col &= 15;
  799.         if (pixel_table[DMAP(*r, col++, row)])
  800.             *pixel_ptr |= (byte) 0x8;
  801.         INC_RGB(r++);    col &= 15;
  802.         if (pixel_table[DMAP(*r, col++, row)])
  803.             *pixel_ptr |= (byte) 0x4;
  804.         INC_RGB(r++);    col &= 15;
  805.         if (pixel_table[DMAP(*r, col++, row)])
  806.             *pixel_ptr |= (byte) 0x2;
  807.         INC_RGB(r++);    col &= 15;
  808.         if (pixel_table[DMAP(*r, col++, row)])
  809.             *pixel_ptr |= (byte) 0x1;
  810.         INC_RGB(r++);    col &= 15;
  811.         pixel_ptr++;
  812.         }
  813.  
  814.         /* if w is non-zero then we have to finish up... */
  815.         w = 8 + w;
  816.         if (w)
  817.         {
  818.         byte    savebits;
  819.  
  820.         savebits = *pixel_ptr & LSBMask[8-w];
  821.         bit = w;
  822.  
  823.         while (w-- > 0) {
  824.             *pixel_ptr <<= 1;
  825.             *pixel_ptr |= (byte) pixel_table
  826.             [DMAP(*r, col++, row)] ? 0x1 : 0;
  827.             INC_RGB(r++); col &= 15;
  828.         }
  829.         *pixel_ptr <<= 8 - bit;
  830.         *pixel_ptr |= savebits;
  831.         }
  832.     }
  833.     else {
  834.         /* we don't want to trash those good bits */
  835.         *pixel_ptr <<= (8 - bit) & 7;
  836.  
  837.         /* do first byte fragment */
  838.         while (col & 7) {
  839.         *pixel_ptr >>= 1;
  840.         if (pixel_table[DMAP(*r, col++, row)])
  841.             *pixel_ptr |= (byte) 0x80;
  842.         w--;
  843.         INC_RGB(r++);    col &= 15;
  844.         }
  845.         if (x_mod_8)
  846.         pixel_ptr++;
  847.  
  848.         /* do the bulk of the line fast in eight bit chunks.. */
  849.         while ((w -= 8) >= 0) {
  850.         *pixel_ptr = (byte) 0x0;
  851.         if (pixel_table[DMAP(*r, col++, row)])
  852.             *pixel_ptr = (byte) 0x1;
  853.         INC_RGB(r++);    col &= 15;
  854.         if (pixel_table[DMAP(*r, col++, row)])
  855.             *pixel_ptr |= (byte) 0x2;
  856.         INC_RGB(r++);    col &= 15;
  857.         if (pixel_table[DMAP(*r, col++, row)])
  858.             *pixel_ptr |= (byte) 0x4;
  859.         INC_RGB(r++);    col &= 15;
  860.         if (pixel_table[DMAP(*r, col++, row)])
  861.             *pixel_ptr |= (byte) 0x8;
  862.         INC_RGB(r++);    col &= 15;
  863.         if (pixel_table[DMAP(*r, col++, row)])
  864.             *pixel_ptr |= (byte) 0x10;
  865.         INC_RGB(r++);    col &= 15;
  866.         if (pixel_table[DMAP(*r, col++, row)])
  867.             *pixel_ptr |= (byte) 0x20;
  868.         INC_RGB(r++);    col &= 15;
  869.         if (pixel_table[DMAP(*r, col++, row)])
  870.             *pixel_ptr |= (byte) 0x40;
  871.         INC_RGB(r++);    col &= 15;
  872.         if (pixel_table[DMAP(*r, col++, row)])
  873.             *pixel_ptr |= (byte) 0x80;
  874.         INC_RGB(r++);    col &= 15;
  875.         pixel_ptr++;
  876.         }
  877.  
  878.         /* if w is negative then we have to finish up... */
  879.         w = 0 - w;
  880.  
  881.         if (w)
  882.         {
  883.         byte    savebits = (byte)(*pixel_ptr >> 8 - w);
  884.         savebits <<= (byte)8 - w;
  885.         bit = w;
  886.  
  887.         while (w-- > 0) {
  888.             *pixel_ptr >>= 1;
  889.             if (pixel_table[DMAP(*r, col++, row)])
  890.             *pixel_ptr |= (byte) 0x80;
  891.             INC_RGB(r++); col &= 15;
  892.         }
  893.         *pixel_ptr >>= 8 - bit;
  894.         *pixel_ptr |= savebits;
  895.         }
  896.     }
  897.     if (mag_size < 0)
  898.         rgb_line += rgb_line_stride * mag_y,
  899.         height -= mag_y - 1;
  900.     else if (--mag_y == 0)    {
  901.         rgb_line += rgb_line_stride;
  902.         mag_y = mag_f;
  903.     }
  904.     line_ptr += image->bytes_per_line;
  905.     }
  906. }
  907.  
  908. /*
  909.  * map_2or3_nodither_table_8
  910.  *
  911.  * Dither three colors into an eight bit table...  This is faster than the
  912.  * map_scanline_generic routine.
  913.  *
  914.  * Inputs:
  915.  *    rgb:        Pointers to buffers containing the red, green,
  916.  *            and blue color rows.
  917.  *    n:        Length of row.
  918.  *    s:        Skip between pixels in original image.
  919.  *    y:        Y position of row (necessary for dither)
  920.  *    line:        Pointer to output buffer for dithered color data.
  921.  */
  922.  
  923. static    void
  924. map_2or3_nodither_table_8 (img, rgb, ncolors, given_width, stride, y, x, image)
  925. image_information *img;
  926. byte    *rgb[3];
  927. int    ncolors,
  928.     given_width,
  929.     stride,
  930.     y, x;
  931. XImage    *image;
  932.  
  933. {
  934. register Pixel    *pixel_table = img->pixel_table;
  935. NDMAP_SETUP(img);
  936. LEVELS_SETUP(img);
  937. register byte    *r, *g, *b;
  938. register byte    *pixel_ptr;
  939. register int    width = given_width;
  940.  
  941.     r = rgb[0];
  942.     g = b = rgb[1];
  943.     if (ncolors >= 3) b = rgb[2];
  944.  
  945.     pixel_ptr = ((byte *) image->data) + y * image->bytes_per_line + x;
  946.     
  947.     while (width-- > 0) {
  948.     *pixel_ptr++ = pixel_table [  NDMAP(*r)
  949.                     + NDMAP(*g) * levels
  950.                     + NDMAP(*b) * levels_squared];
  951.     r += stride;
  952.     g += stride;
  953.     b += stride;
  954.     }
  955. }
  956. static    void
  957. MAG_2or3_nodither_table_8(img, rle_x, rle_y, mag_size, x, y, width, height, image)
  958. image_information *img;
  959. int    rle_x, rle_y,
  960.     width, height,
  961.     mag_size,
  962.     x, y;
  963. XImage    *image;
  964.  
  965. {
  966. register Pixel    *pixel_table = img->pixel_table;
  967. NDMAP_SETUP(img);
  968. LEVELS_SETUP(img);
  969. register byte    *r, *g, *b;
  970. register byte    *pixel_ptr;
  971. register byte    table_value;
  972. register int    mag, w;
  973. int    mag_f = abs(mag_size), wd = width / mag_f,
  974.     rgb_line_stride = img->w * img->dpy_channels;
  975. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  976.     *line_ptr = (byte *) image->data + y * image->bytes_per_line + x;
  977.  
  978.     height /= mag_f;
  979.     while (height--) {
  980.     pixel_ptr = line_ptr;
  981.     w = wd;
  982.     r = rgb_line;
  983.  
  984.     g = b = r + img->w;
  985.     if (img->dpy_channels >= 3) b += img->w;
  986.  
  987.     while (w--) {
  988.         *pixel_ptr++ =
  989.         table_value = pixel_table[NDMAP(*r)
  990.                     + NDMAP(*g) * levels
  991.                     + NDMAP(*b) * levels_squared];
  992.         mag = mag_f;
  993.         if (mag_size < 0)
  994.             r += mag,    g += mag,    b += mag;
  995.         else    {
  996.             while (--mag)
  997.                 *pixel_ptr++ = table_value;
  998.             r++, g++, b++;
  999.         }
  1000.     }
  1001.     mag = mag_f;
  1002.     if (mag_size < 0)
  1003.         rgb_line += rgb_line_stride * mag;
  1004.     else    {
  1005.         while (--mag)    {
  1006.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width);
  1007.         line_ptr += image->bytes_per_line;
  1008.         }    rgb_line += rgb_line_stride;
  1009.     }
  1010.     line_ptr += image->bytes_per_line;
  1011.     }
  1012. }
  1013.  
  1014. /*
  1015.  * map_1_nodither_table_8
  1016.  *
  1017.  * Inputs:
  1018.  *    rgb:        Pointers to buffers containing the red, green,
  1019.  *            and blue color rows.
  1020.  *    n:        Length of row.
  1021.  *    s:        Skip between pixels in original image.
  1022.  *    y:        Y position of row (necessary for dither)
  1023.  *    line:        Pointer to output buffer for dithered color data.
  1024.  */
  1025.  
  1026. static    void
  1027. map_1_nodither_table_8 (img, rgb, ncolors, given_width, stride, y, x, image)
  1028. image_information *img;
  1029. byte    *rgb[3];
  1030. int    ncolors,
  1031.     given_width,
  1032.     stride, y, x;
  1033. XImage    *image;
  1034.  
  1035. {
  1036. register Pixel    *pixel_table = img->pixel_table;
  1037. NDMAP_SETUP(img);
  1038. register byte     *r;
  1039. register byte    *pixel_ptr;
  1040. register int    width = given_width;
  1041.  
  1042.     r = rgb[0];
  1043.  
  1044.     pixel_ptr = (byte *)image->data + y * image->bytes_per_line + x;
  1045.  
  1046.     while (width-- > 0) {
  1047.     *pixel_ptr++ = pixel_table [ NDMAP(*r) ];
  1048.     r += stride;
  1049.     }
  1050.  
  1051. }
  1052. static    void
  1053. MAG_1_nodither_table_8(img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1054. image_information *img;
  1055. int    rle_x, rle_y,
  1056.     width, height,
  1057.     mag_size,
  1058.     x, y;
  1059. XImage    *image;
  1060. {
  1061. register Pixel    *pixel_table = img->pixel_table;
  1062. NDMAP_SETUP(img);
  1063. register byte    *r;
  1064. register byte    *pixel_ptr;
  1065. register byte    table_value;
  1066. register int    mag, w;
  1067. int        mag_f = abs(mag_size), wd = width / mag_f;
  1068. byte    *line_ptr, *rgb_line;
  1069. int    rgb_line_stride = img->w * img->dpy_channels;
  1070.  
  1071.     height /= mag_f;
  1072.     rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x;
  1073.     line_ptr = ((byte *) image->data) + y * image->bytes_per_line + x;
  1074.  
  1075.     while (height--) {
  1076.     pixel_ptr = line_ptr;
  1077.     w = wd;
  1078.     r = rgb_line;
  1079.  
  1080.     while (w-- > 0) {
  1081.         *pixel_ptr++ = table_value = pixel_table[NDMAP(*r)];
  1082.         mag = mag_f;
  1083.         if (mag_size < 0)
  1084.             r += mag;
  1085.         else for (r++; --mag;)
  1086.                 *pixel_ptr++ = table_value;
  1087.     }
  1088.     mag = mag_f;
  1089.     if (mag_size < 0)
  1090.         rgb_line += rgb_line_stride * mag;
  1091.     else    {
  1092.         while (--mag)    {
  1093.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width);
  1094.         line_ptr += image->bytes_per_line;
  1095.         }    rgb_line += rgb_line_stride;
  1096.     }
  1097.     line_ptr += image->bytes_per_line;
  1098.     }
  1099. }
  1100.  
  1101. /*
  1102.  * map_1_mono_color_8
  1103.  *
  1104.  * Inputs:
  1105.  *    rgb:        Pointers to buffers containing the red, green,
  1106.  *            and blue color rows.
  1107.  *    n:        Length of row.
  1108.  *    s:        Skip between pixels in original image.
  1109.  *    y:        Y position of row (necessary for dither)
  1110.  *    line:        Pointer to output buffer for dithered color data.
  1111.  */
  1112.  
  1113. static    void
  1114. map_1_mono_color_8 (img, rgb, ncolors, given_width, stride, y, x, image)
  1115. image_information *img;
  1116. byte    *rgb[3];
  1117. int    ncolors,
  1118.     given_width,
  1119.     stride, y, x;
  1120. XImage    *image;
  1121.  
  1122. {
  1123. register Pixel    *pixel_table = img->pixel_table;
  1124. register byte     *r;
  1125. register byte    *pixel_ptr;
  1126. register int    width = given_width;
  1127.  
  1128.     r = rgb[0];
  1129.  
  1130.     pixel_ptr = ((byte *) image->data) + y * image->bytes_per_line + x;
  1131.  
  1132.     while (width-- > 0) {
  1133.     *pixel_ptr++ = pixel_table [ *r ];
  1134.     r += stride;
  1135.     }
  1136.  
  1137. }
  1138. static    void
  1139. MAG_1_mono_color_8 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1140. image_information *img;
  1141. int    rle_x, rle_y,
  1142.     width, height,
  1143.     mag_size,
  1144.     x, y;
  1145. XImage    *image;
  1146. {
  1147. byte    *line_ptr, *rgb_line;
  1148. int    mag_f = abs(mag_size), wd = width / mag_f,
  1149.     rgb_line_stride = img->w * img->dpy_channels;
  1150. register Pixel    *pixel_table = img->pixel_table;
  1151. register byte    *r, *pixel_ptr;
  1152. register byte    table_value;
  1153. register int    mag=mag_f, w;
  1154.  
  1155.     height /= mag;
  1156.     rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x;
  1157.     line_ptr = ((byte *) image->data)+(y * image->bytes_per_line) + x;
  1158.  
  1159.     while (height--) {
  1160.     pixel_ptr = line_ptr;
  1161.     w = wd;
  1162.     r = rgb_line;
  1163.  
  1164.     while (w--)    {
  1165.         *pixel_ptr++ = table_value = pixel_table [ *r ];
  1166.         if (mag_size < 0)
  1167.             r += mag;
  1168.         else for (r++, mag=mag_f; --mag;)
  1169.             *pixel_ptr++ = table_value;
  1170.     }
  1171.     mag = mag_f;
  1172.     if (mag_size < 0)
  1173.         rgb_line += rgb_line_stride * mag;
  1174.     else    {
  1175.         while (--mag)    {
  1176.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width);
  1177.         line_ptr += image->bytes_per_line;
  1178.         }    rgb_line += rgb_line_stride;
  1179.     }
  1180.     line_ptr += image->bytes_per_line;
  1181.     }
  1182. }
  1183.  
  1184. /*
  1185. * map_2or3_dither_table_32
  1186. *
  1187. * Inputs:
  1188. *    rgb:        Pointers to buffers containing the red, green,
  1189. *            and blue color rows.
  1190. *    n:        Length of row.
  1191. *    s:        Skip between pixels in original image.
  1192. *    y:        Y position of row (necessary for dither)
  1193. *    line:        Pointer to output buffer for dithered color data.
  1194. */
  1195.  
  1196. #if EVEN_NEVER_CALLED                /* Never called. */
  1197. static    void
  1198. map_2or3_dither_table_32 (img, rgb, ncolors, given_width, stride, y, x, image)
  1199. image_information *img;
  1200. byte    *rgb[3];
  1201. int    ncolors,
  1202.     given_width,
  1203.     stride, y;
  1204. XImage    *image;
  1205.  
  1206. {
  1207. register Pixel *pixel_table = img->pixel_table;
  1208. DMAP_SETUP(img);
  1209. LEVELS_SETUP(img);
  1210. register int    col, row;
  1211. register byte    *r, *g, *b;
  1212. register unsigned long    pixval;
  1213. register byte    *pixel_ptr;
  1214. register int    width = given_width;
  1215. int    byte_order = ImageByteOrder(img->dpy);
  1216.  
  1217.     row = y & 0xF;
  1218.     r = rgb[col=0];
  1219.  
  1220.     g = b = rgb[1];
  1221.     if (ncolors >= 3) b = rgb[2];
  1222.  
  1223.     pixel_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1224.  
  1225.     while (width-- > 0) {
  1226.  
  1227.     pixval = pixel_table [DMAP(*r, col, row) +
  1228.                 DMAP(*g, col, row) * levels +
  1229.                 DMAP(*b, col, row) * levels_squared];
  1230.     if (byte_order == MSBFirst)
  1231.     {
  1232.         pixel_ptr += 3;
  1233.         *pixel_ptr-- = pixval & 0xff;
  1234.         pixval >>= 8;
  1235.         *pixel_ptr-- = pixval & 0xff;
  1236.         pixval >>= 8;
  1237.         *pixel_ptr-- = pixval & 0xff;
  1238.         pixval >>= 8;
  1239.         *pixel_ptr = pixval & 0xff;
  1240.         pixel_ptr += 4;
  1241.     }
  1242.     else
  1243.     {
  1244.         *pixel_ptr++ = pixval & 0xff;
  1245.         pixval >>= 8;
  1246.         *pixel_ptr++ = pixval & 0xff;
  1247.         pixval >>= 8;
  1248.         *pixel_ptr++ = pixval & 0xff;
  1249.         pixval >>= 8;
  1250.         *pixel_ptr++ = pixval & 0xff;
  1251.     }
  1252.     r += stride;
  1253.     g += stride;
  1254.     b += stride;
  1255.     col = ((col + 1) & 15);
  1256.     }
  1257. }
  1258.  
  1259. /*    #if EVEN_NEVER_CALLED        Never called. */
  1260. static    void
  1261. MAG_2or3_dither_table_32 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1262. image_information *img;
  1263. int    rle_x, rle_y,
  1264.     width, height,
  1265.     mag_size,
  1266.     x, y;
  1267. XImage    *image;
  1268. {
  1269. register Pixel    *pixel_table = img->pixel_table;
  1270. DMAP_SETUP(img);
  1271. LEVELS_SETUP(img);
  1272. int    mag_y, mag_f = abs(mag_size),    x_mod_16 = (mag_f * rle_x) & 0xF,
  1273.     rgb_line_stride = img->w * img->dpy_channels,
  1274.     byte_order = ImageByteOrder(img->dpy);
  1275. register int     col, mag_x;
  1276. register unsigned long    pixval;
  1277. register byte    *pixel_ptr;
  1278. register byte    *r, *g, *b;
  1279. register int    w, row = (mag_f * rle_y - 1) & 0xF;
  1280. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  1281.     *line_ptr = (byte *)image->data + y * image->bytes_per_line + (x << 2);
  1282.  
  1283.     while (height-- > 0) {
  1284.     pixel_ptr = line_ptr;
  1285.     w = width;
  1286.     row = (row + 1) & 0xF;
  1287.     col = x_mod_16;
  1288.     r = rgb_line;
  1289.     mag_x = mag_f;
  1290.  
  1291.     g = b = r + img->w;
  1292.     if (img->dpy_channels >= 3) b += img->w;
  1293.  
  1294.     while (w-- > 0) {
  1295.         pixval = pixel_table [DMAP(*r, col, row) +
  1296.                     DMAP(*g, col, row) * levels +
  1297.                     DMAP(*b, col, row) * levels_squared];
  1298.         if (byte_order == MSBFirst)
  1299.         {
  1300.         pixel_ptr += 3;
  1301.         *pixel_ptr-- = pixval & 0xff;
  1302.         pixval >>= 8;
  1303.         *pixel_ptr-- = pixval & 0xff;
  1304.         pixval >>= 8;
  1305.         *pixel_ptr-- = pixval & 0xff;
  1306.         pixval >>= 8;
  1307.         *pixel_ptr = pixval & 0xff;
  1308.         pixel_ptr += 4;
  1309.         }
  1310.         else
  1311.         {
  1312.         *pixel_ptr++ = pixval & 0xff;
  1313.         pixval >>= 8;
  1314.         *pixel_ptr++ = pixval & 0xff;
  1315.         pixval >>= 8;
  1316.         *pixel_ptr++ = pixval & 0xff;
  1317.         pixval >>= 8;
  1318.         *pixel_ptr++ = pixval & 0xff;
  1319.         }
  1320.         if (mag_size < 0)
  1321.         r += mag_x,    g += mag_x,    b += mag_x,    w -= mag_x - 1;
  1322.         else if (--mag_x == 0)    {
  1323.         r++, g++, b++;
  1324.         mag_x = mag_f;
  1325.         }
  1326.         col++;
  1327.         col &= 15;
  1328.     }
  1329.     if (mag_size < 0)
  1330.         rgb_line += rgb_line_stride * mag_x,
  1331.         height -= mag_x;
  1332.     else if (--mag_y == 0)    {
  1333.         rgb_line += rgb_line_stride;
  1334.         mag_y = mag_f;
  1335.     }
  1336.     line_ptr += image->bytes_per_line;
  1337.     }
  1338. }
  1339. #endif    EVEN_NEVER_CALLED
  1340.  
  1341. /*
  1342. * map_2or3_dither_notable_32
  1343. *
  1344. * Inputs:
  1345. *    rgb:        Pointers to buffers containing the red, green,
  1346. *            and blue color rows.
  1347. *    n:        Length of row.
  1348. *    s:        Skip between pixels in original image.
  1349. *    y:        Y position of row (necessary for dither)
  1350. *    line:        Pointer to output buffer for dithered color data.
  1351. */
  1352. static    void
  1353. map_2or3_dither_notable_32 (img, rgb, ncolors, given_width, stride, y, x, image)
  1354. image_information *img;
  1355. byte    *rgb[3];
  1356. int    ncolors,
  1357.     given_width,
  1358.     stride, y;
  1359. XImage    *image;
  1360.  
  1361. {
  1362. DMAP_SETUP(img);
  1363. register int    col, row;
  1364. register byte    *r, *g, *b;
  1365. register unsigned long    pixval;
  1366. register byte    *pixel_ptr;
  1367. register int    width = given_width;
  1368. int    byte_order = ImageByteOrder(img->dpy);
  1369.  
  1370.     row = y & 0xF;
  1371.     col = 0;
  1372.     r = rgb[0];
  1373.     g = rgb[1];
  1374.     if (ncolors > 2) b = rgb[2];
  1375.     else b = rgb[1];
  1376.  
  1377.     pixel_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1378.  
  1379.     while (width-- > 0) {
  1380.  
  1381.     pixval = SHIFT_MASK_PIXEL_32 (DMAP(*r, col, row),
  1382.                     DMAP(*g, col, row),
  1383.                     DMAP(*b, col, row));
  1384.     if (byte_order == MSBFirst)
  1385.     {
  1386.         pixel_ptr += 3;
  1387.         *pixel_ptr-- = pixval & 0xff;
  1388.         pixval >>= 8;
  1389.         *pixel_ptr-- = pixval & 0xff;
  1390.         pixval >>= 8;
  1391.         *pixel_ptr-- = pixval & 0xff;
  1392.         pixval >>= 8;
  1393.         *pixel_ptr = pixval & 0xff;
  1394.         pixel_ptr += 4;
  1395.     }
  1396.     else    {
  1397.         *pixel_ptr++ = pixval & 0xff;
  1398.         pixval >>= 8;
  1399.         *pixel_ptr++ = pixval & 0xff;
  1400.         pixval >>= 8;
  1401.         *pixel_ptr++ = pixval & 0xff;
  1402.         pixval >>= 8;
  1403.         *pixel_ptr++ = pixval & 0xff;
  1404.     }
  1405.     r += stride;
  1406.     g += stride;
  1407.     b += stride;
  1408.     col = ((col + 1) & 15);
  1409.     }
  1410. }
  1411. static    void
  1412. MAG_2or3_dither_notable_32 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1413. image_information *img;
  1414. int    rle_x, rle_y,
  1415.     width, height,
  1416.     mag_size,
  1417.     x, y;
  1418. XImage    *image;
  1419. {
  1420. DMAP_SETUP(img);
  1421. int    mag_f = abs(mag_size), wd = width / mag_f,
  1422.     x_mod_16 = (mag_f * rle_x) & 0xF,
  1423.     rgb_line_stride = img->w * img->dpy_channels,
  1424.     byte_order = ImageByteOrder(img->dpy);
  1425. register byte    *r, *g, *b;
  1426. register unsigned long    pixval, *pixel_ptr;
  1427. register int    col, row = (mag_f * rle_y - 1) & 0xF;
  1428. register int     mag=mag_f, w;
  1429. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  1430.     *line_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1431.  
  1432.     height /= mag;
  1433.     while (height-- > 0) {
  1434.     pixel_ptr = line_ptr;
  1435.     w = wd;
  1436.     row = (row + 1) & 0xF;
  1437.     col = x_mod_16;
  1438.     r = rgb_line;
  1439.     g = b = r + img->w;
  1440.     if (img->dpy_channels > 2)    b += img->w;
  1441.  
  1442.     while (w-- > 0) {
  1443.         *pixel_ptr++ = pixval = SHIFT_MASK_PIXEL_32 (DMAP(*r, col, row),
  1444.                              DMAP(*g, col, row),
  1445.                              DMAP(*b, col, row));
  1446.         if (mag_size < 0)
  1447.         r += mag,    g += mag,    b += mag;
  1448.         else for (r++, g++, b++, mag=mag_f; --mag;)
  1449.             *pixel_ptr++ = pixval;
  1450.         col++;
  1451.         col &= 15;
  1452.     }
  1453.     mag = mag_f;
  1454.     if (mag_size < 0)
  1455.         rgb_line += rgb_line_stride * mag;
  1456.     else    {
  1457.         while (--mag)    {
  1458.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width << 2);
  1459.         line_ptr += image->bytes_per_line;
  1460.         }    rgb_line += rgb_line_stride;
  1461.     }
  1462.     line_ptr += image->bytes_per_line;
  1463.     }
  1464. }
  1465.  
  1466.  
  1467. /*
  1468. * map_2or3_nodither_notable_32
  1469. *
  1470. * Inputs:
  1471. *    rgb:        Pointers to buffers containing the red, green,
  1472. *            and blue color rows.
  1473. *    n:        Length of row.
  1474. *    s:        Skip between pixels in original image.
  1475. *    y:        Y position of row (necessary for dither)
  1476. *    line:        Pointer to output buffer for dithered color data.
  1477. */
  1478.  
  1479. static    void
  1480. map_2or3_nodither_notable_32 (img, rgb, ncolors, given_width, stride, y, x, image)
  1481. image_information *img;
  1482. byte    *rgb[3];
  1483. int    ncolors,
  1484.     given_width,
  1485.     stride, y;
  1486. XImage    *image;
  1487.  
  1488. {
  1489. NDMAP_SETUP(img);
  1490. register byte    *r, *g, *b;
  1491. register unsigned long    pixval;
  1492. register byte    *pixel_ptr;
  1493. register int    width = given_width;
  1494. int    byte_order = ImageByteOrder(img->dpy);
  1495.  
  1496.     r = rgb[0];
  1497.     g = rgb[1];
  1498.     if (ncolors > 2)    b = rgb[2];
  1499.     else b = rgb[1];
  1500.  
  1501.     pixel_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1502.  
  1503.     while (width-- > 0) {
  1504.  
  1505.     pixval = SHIFT_MASK_PIXEL_32(NDMAP(*r), NDMAP(*g), NDMAP(*b));
  1506.     if (byte_order == MSBFirst)
  1507.     {
  1508.         pixel_ptr += 3;
  1509.         *pixel_ptr-- = pixval & 0xff;
  1510.         pixval >>= 8;
  1511.         *pixel_ptr-- = pixval & 0xff;
  1512.         pixval >>= 8;
  1513.         *pixel_ptr-- = pixval & 0xff;
  1514.         pixval >>= 8;
  1515.         *pixel_ptr = pixval & 0xff;
  1516.         pixel_ptr += 4;
  1517.     }
  1518.     else
  1519.     {
  1520.         *pixel_ptr++ = pixval & 0xff;
  1521.         pixval >>= 8;
  1522.         *pixel_ptr++ = pixval & 0xff;
  1523.         pixval >>= 8;
  1524.         *pixel_ptr++ = pixval & 0xff;
  1525.         pixval >>= 8;
  1526.         *pixel_ptr++ = pixval & 0xff;
  1527.     }
  1528.  
  1529.     r += stride;
  1530.     g += stride;
  1531.     b += stride;
  1532.  
  1533.     }
  1534.     
  1535. }
  1536. static    void
  1537. MAG_2or3_nodither_notable_32 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1538. image_information *img;
  1539. int    rle_x, rle_y,
  1540.     width, height,
  1541.     mag_size,
  1542.     x, y;
  1543. XImage    *image;
  1544. {
  1545. NDMAP_SETUP(img);
  1546. int    mag_f = abs(mag_size), wd = width / mag_f,
  1547.     rgb_line_stride = img->w * img->dpy_channels,
  1548.     byte_order = ImageByteOrder(img->dpy);
  1549. register byte    *r, *g, *b;
  1550. register unsigned long    pixval, *pixel_ptr;
  1551. register int    mag=mag_f, w;
  1552. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  1553.     *line_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1554.  
  1555.     height /= mag;
  1556.     while (height-- > 0) {
  1557.     pixel_ptr = (unsigned long*)line_ptr;
  1558.     w = wd;
  1559.     r = rgb_line;
  1560.     g = b = r + img->w;
  1561.     if (img->dpy_channels > 2)    b += img->w;
  1562.  
  1563.     while (w-- > 0) {
  1564.         *pixel_ptr++ = pixval =
  1565.             SHIFT_MASK_PIXEL_32(NDMAP(*r), NDMAP(*g), NDMAP(*b));
  1566.         if (mag_size < 0)
  1567.         r += mag,    g += mag,    b += mag;
  1568.         else for (r++, g++, b++, mag=mag_f; --mag;)
  1569.             *pixel_ptr++ = pixval;
  1570.     }
  1571.     mag = mag_f;
  1572.     if (mag_size < 0)
  1573.         rgb_line += rgb_line_stride * mag;
  1574.     else    {
  1575.         while (--mag)    {
  1576.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width << 2);
  1577.         line_ptr += image->bytes_per_line;
  1578.         }    rgb_line += rgb_line_stride;
  1579.     }
  1580.     line_ptr += image->bytes_per_line;
  1581.     }
  1582. }
  1583.  
  1584. /*
  1585. * map_1_nodither_notable_32
  1586. *
  1587. * Inputs:
  1588. *    rgb:        Pointers to buffers containing the red, green,
  1589. *            and blue color rows.
  1590. *    n:        Length of row.
  1591. *    s:        Skip between pixels in original image.
  1592. *    y:        Y position of row (necessary for dither)
  1593. *    line:        Pointer to output buffer for dithered color data.
  1594. */
  1595.  
  1596. static    void
  1597. map_1_nodither_notable_32 (img, rgb, ncolors, given_width, stride, y, x, image)
  1598. image_information *img;
  1599. byte    *rgb[3];
  1600. int    ncolors, given_width;
  1601. register int    stride;
  1602. int    y;
  1603. XImage    *image;
  1604.  
  1605. {
  1606. NDMAP_SETUP(img);
  1607. register byte    *r;
  1608. register unsigned long    pixval;
  1609. register byte    *pixel_ptr;
  1610. register int    width = given_width;
  1611. int    byte_order = ImageByteOrder(img->dpy);
  1612.  
  1613.     r = rgb[0];
  1614.  
  1615.     pixel_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1616.  
  1617.     while (width-- > 0) {
  1618.     register int bw_value = NDMAP(*r);
  1619.  
  1620.     pixval = SHIFT_MASK_PIXEL_32(bw_value, bw_value, bw_value);
  1621.     if (byte_order == MSBFirst)
  1622.     {
  1623.         pixel_ptr += 3;
  1624.         *pixel_ptr-- = pixval & 0xff;
  1625.         pixval >>= 8;
  1626.         *pixel_ptr-- = pixval & 0xff;
  1627.         pixval >>= 8;
  1628.         *pixel_ptr-- = pixval & 0xff;
  1629.         pixval >>= 8;
  1630.         *pixel_ptr = pixval & 0xff;
  1631.         pixel_ptr += 4;
  1632.     }
  1633.     else
  1634.     {
  1635.         *pixel_ptr++ = pixval & 0xff;
  1636.         pixval >>= 8;
  1637.         *pixel_ptr++ = pixval & 0xff;
  1638.         pixval >>= 8;
  1639.         *pixel_ptr++ = pixval & 0xff;
  1640.         pixval >>= 8;
  1641.         *pixel_ptr++ = pixval & 0xff;
  1642.     }
  1643.  
  1644.     r += stride;
  1645.     }
  1646.  
  1647. }
  1648. static    void
  1649. MAG_1_nodither_notable_32 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1650. image_information *img;
  1651. int    rle_x, rle_y,
  1652.     width, height,
  1653.     mag_size,
  1654.     x, y;
  1655. XImage    *image;
  1656.  
  1657. {
  1658. NDMAP_SETUP(img);
  1659. int    mag_f = abs(mag_size), wd = width / mag_f,
  1660.     rgb_line_stride = img->w * img->dpy_channels,
  1661.     byte_order = ImageByteOrder(img->dpy);
  1662. register unsigned long    pixval, *pixel_ptr;
  1663. register byte    *r;
  1664. register int    bw_value, mag=mag_f, w;
  1665. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  1666.     *line_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1667.  
  1668.     height /= mag_f;
  1669.     while (height-- > 0) {
  1670.     pixel_ptr = line_ptr;
  1671.     w = wd;
  1672.     r = rgb_line;
  1673.  
  1674.     while (w-- > 0) {
  1675.         bw_value = NDMAP(*r);
  1676.         *pixel_ptr++ = pixval = SHIFT_MASK_PIXEL_32(bw_value, bw_value, bw_value);
  1677.         if (mag_size < 0)
  1678.             r += mag;
  1679.         else for (r++, mag=mag_f; --mag;)
  1680.             *pixel_ptr++ = pixval;
  1681.     }
  1682.     mag = mag_f;
  1683.     if (mag_size < 0)
  1684.         rgb_line += rgb_line_stride * mag;
  1685.     else    {
  1686.         while (--mag)    {
  1687.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width << 2);
  1688.         line_ptr += image->bytes_per_line;
  1689.         }    rgb_line += rgb_line_stride;
  1690.     }
  1691.     line_ptr += image->bytes_per_line;
  1692.     }
  1693. }
  1694. /*
  1695.  * map_1_mono_color_32
  1696.  *
  1697.  * Inputs:
  1698.  *    rgb:        Pointers to buffers containing the red, green,
  1699.  *            and blue color rows.
  1700.  *    n:        Length of row.
  1701.  *    s:        Skip between pixels in original image.
  1702.  *    y:        Y position of row (necessary for dither)
  1703.  *    line:        Pointer to output buffer for dithered color data.
  1704.  */
  1705.  
  1706. static    void
  1707. map_1_mono_color_32 (img, rgb, ncolors, given_width, stride, y, x, image)
  1708. image_information *img;
  1709. byte    *rgb[3];
  1710. int    ncolors,
  1711.     given_width;
  1712. register int    stride;
  1713. int    y;
  1714. XImage    *image;
  1715. {
  1716. register byte    *r;
  1717. register unsigned long    pixval;
  1718. register byte    *pixel_ptr;
  1719. register int    width = given_width;
  1720. int    byte_order = ImageByteOrder(img->dpy);
  1721.  
  1722.     r = rgb[0];
  1723.  
  1724.     pixel_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1725.  
  1726.     while (width-- > 0) {
  1727.     pixval = img->pixel_table[ *r ];
  1728.     if (byte_order == MSBFirst)
  1729.     {
  1730.         pixel_ptr += 3;
  1731.         *pixel_ptr-- = pixval & 0xff;
  1732.         pixval >>= 8;
  1733.         *pixel_ptr-- = pixval & 0xff;
  1734.         pixval >>= 8;
  1735.         *pixel_ptr-- = pixval & 0xff;
  1736.         pixval >>= 8;
  1737.         *pixel_ptr = pixval & 0xff;
  1738.         pixel_ptr += 4;
  1739.     }
  1740.     else
  1741.     {
  1742.         *pixel_ptr++ = pixval & 0xff;
  1743.         pixval >>= 8;
  1744.         *pixel_ptr++ = pixval & 0xff;
  1745.         pixval >>= 8;
  1746.         *pixel_ptr++ = pixval & 0xff;
  1747.         pixval >>= 8;
  1748.         *pixel_ptr++ = pixval & 0xff;
  1749.     }
  1750.     r += stride;
  1751.     }
  1752.  
  1753. }
  1754. static    void
  1755. MAG_1_mono_color_32 (img, rle_x, rle_y, mag_size, x, y, width, height, image)
  1756. image_information *img;
  1757. int    rle_x, rle_y,
  1758.     width, height,
  1759.     mag_size,
  1760.     x, y;
  1761. XImage    *image;
  1762.  
  1763. {
  1764. int    mag_f = abs(mag_size), wd = width / mag_f,
  1765.     rgb_line_stride = img->w * img->dpy_channels,
  1766.     byte_order = ImageByteOrder(img->dpy);
  1767. register byte    *r;
  1768. register unsigned long    pixval, *pixel_ptr;
  1769. register int    mag=mag_f, w;
  1770. byte    *rgb_line = SAVED_RLE_ROW(img, rle_y) + rle_x,
  1771.     *line_ptr = (byte *)image->data + y * image->bytes_per_line + (x<<2);
  1772.  
  1773.     height /= mag;
  1774.     while (height-- > 0) {
  1775.     pixel_ptr = line_ptr;
  1776.     w = wd;
  1777.     r = rgb_line;
  1778.  
  1779.     while (w-- > 0) {
  1780.         *pixel_ptr++ = pixval = img->pixel_table[ *r ];
  1781.         if (mag_size < 0)
  1782.             r += mag;
  1783.         else for (r++, mag=mag_f; --mag;)
  1784.             *pixel_ptr++ = pixval;
  1785.     }
  1786.     mag = mag_f;
  1787.     if (mag_size < 0)
  1788.         rgb_line += rgb_line_stride * mag;
  1789.     else    {
  1790.         while (--mag)    {
  1791.         memcpy(line_ptr+image->bytes_per_line, line_ptr, width << 2);
  1792.         line_ptr += image->bytes_per_line;
  1793.         }    rgb_line += rgb_line_stride;
  1794.     }
  1795.     line_ptr += image->bytes_per_line;
  1796.     }
  1797. }
  1798.  
  1799. /*****************************************************************
  1800. * TAG(map_rgb_to_bw)
  1801. *
  1802. * Convert RGB to black and white through NTSC transform, but map
  1803. * RGB through a color map first.
  1804. * Inputs:
  1805. *    red_row, green_row, blue_row:    Given RGB pixel data.
  1806. *    map:        Array[3] of pointers to pixel arrays,
  1807. *            representing color map.
  1808. *    rowlen:        Number of pixels in the rows.
  1809. * Outputs:
  1810. *    bw_row:        Output B&W data.  May coincide with one of the
  1811. *            inputs.
  1812. * Algorithm:
  1813. *    BW = .35*map[0][R] + .55*map[1][G] + .10*map[2][B]
  1814. */
  1815. void
  1816. map_rgb_to_bw(img, rows, bw_row, rowlen)
  1817. image_information    *img;
  1818. rle_pixel        **rows;
  1819. register rle_pixel    *bw_row;
  1820. {
  1821. register rle_pixel    *red, *green, *blue;
  1822.  
  1823. rle_pixel    **map;
  1824. int        ncolors;
  1825.  
  1826.     map = img->in_cmap;
  1827.     ncolors = img->img_channels;
  1828.     if (rowlen < 1)
  1829.     rowlen = img->w;
  1830.  
  1831.     if (ncolors < 1)
  1832.     prgmerr('c', "map_rgb_to_bw given %d colors\n", ncolors);
  1833.  
  1834.     switch (ncolors) {
  1835.     case 1:
  1836.     red = rows[0];
  1837.     if (!map || img->mono_color)
  1838.         duff8(rowlen, *bw_row++ = *red++)
  1839.     else {
  1840.     register rle_pixel *cmap = map[0];
  1841.         duff8(rowlen, *bw_row++ = cmap[*red++])
  1842.     }
  1843.     break;
  1844.  
  1845.     case 2:
  1846.     red = rows[0];
  1847.     green = rows[1];
  1848.     if (!map)
  1849.         duff8(rowlen, *bw_row++ = (*red++ + *green++) >> 1)
  1850.     else {
  1851.     register rle_pixel **cmap = map;
  1852.         duff8(rowlen, *bw_row++ = (cmap[0][*red++] +
  1853.                     cmap[1][*green++]) >> 1)
  1854.     }
  1855.     break;
  1856.  
  1857.     default:
  1858.     case 3:
  1859.     red = rows[0];
  1860.     green = rows[1];
  1861.     blue = rows[2];
  1862.     if (!map)
  1863.         duff8(rowlen, *bw_row++ = (35 * *red++ + 55 * *green++ +
  1864.                     10 * *blue++) / 100)
  1865.     else {
  1866.     register rle_pixel **cmap = map;
  1867.         duff8(rowlen, *bw_row++ = (35 * cmap[0][*red++] +
  1868.                     55 * cmap[1][*green++] +
  1869.                     10 * cmap[2][*blue++]) / 100)
  1870.     }
  1871.     break;
  1872.     }
  1873. }
  1874.  
  1875. /*****************************************************************
  1876.  * TAG(map_rgb_to_rgb)
  1877.  *
  1878.  * Convert RGB to RGB through a colormap
  1879.  * Inputs:
  1880.  *     in_rows:    Given RGB pixel data.
  1881.  *    map:        Array[3] of pointers to pixel arrays,
  1882.  *            representing color map.
  1883.  *    rowlen:        Number of pixels in the rows.
  1884.  * Outputs:
  1885.  *     out_rows:       Output data.  May coincide with one of the inputs.
  1886.  */
  1887. void
  1888. map_rgb_to_rgb(img, in_rows, out_rows, rowlen)
  1889. image_information *img;
  1890. rle_pixel    **in_rows, **out_rows;
  1891. {
  1892. register rle_pixel    *in, *out, *cmap;
  1893. register int    w;
  1894. rle_pixel    **map=img->in_cmap;
  1895. int    ncolors = img->img_channels;
  1896.     if (rowlen < 1)
  1897.         rowlen = img->w;
  1898.  
  1899.     if (ncolors < 1)
  1900.         prgmerr('c', "map_rgb_to_rgb given %d colors\n", ncolors);
  1901.  
  1902.     if (map)
  1903.         while (ncolors--)    {
  1904.         in = in_rows[0];
  1905.         out = out_rows[0];
  1906.         cmap = map[0];
  1907.         w = rowlen;
  1908.  
  1909.         duff8(w, *out++ = cmap[*in++]);
  1910.  
  1911.         in_rows++;
  1912.         out_rows++;
  1913.         map++;
  1914.         }
  1915.     else
  1916.         while (ncolors--)    {
  1917.         if (in_rows[0] != out_rows[0])
  1918.             memcpy(out_rows[0], in_rows[0], rowlen);
  1919.  
  1920.         in_rows++;
  1921.         out_rows++;
  1922.         }
  1923. }
  1924.  
  1925.  
  1926. void
  1927. get_dither_arrays(img)
  1928. register image_information *img;
  1929. {
  1930.     if (!img->divN)
  1931.         img->divN = (int *) malloc (256 * sizeof(int));
  1932.     if (!img->modN)
  1933.         img->modN = (int *) malloc (256 * sizeof(int));
  1934.     if (!img->dm16)
  1935.         img->dm16 = (array16 *) malloc (16 * 16 * sizeof(int));
  1936.  
  1937.     if (!img->divN || !img->modN || !img->dm16)
  1938.         syserr("malloc error getting dither arrays");
  1939. }
  1940.  
  1941.  
  1942. shift_match_left (mask, high_bit_index)
  1943. Pixel    mask;
  1944. int    high_bit_index;
  1945. {
  1946. register int    shift;
  1947. register Pixel    high_bit;
  1948.  
  1949.     if (!mask) return    0;
  1950.  
  1951.     high_bit = 0x80000000;
  1952.  
  1953.     for (shift=(32 - high_bit_index); !(high_bit & mask); shift--)
  1954.         high_bit >>= 1;
  1955.  
  1956. return    shift;
  1957. }
  1958.  
  1959. shift_match_right (mask)
  1960. Pixel    mask;
  1961. {
  1962. register int    shift=0;
  1963. register Pixel    low_bit;
  1964.  
  1965. if (mask)
  1966.     for (low_bit = 1; (low_bit & mask) == 0; shift++)
  1967.         low_bit <<= 1;
  1968. return (shift);
  1969. }
  1970.