Back to index

scribus-ng  1.3.4.dfsg+svn20071115
gdk-pixbuf-xlibrgb.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
00002  *
00003  * The contents of this file are subject to the Mozilla Public License
00004  * Version 1.1 (the "MPL"); you may not use this file except in
00005  * compliance with the MPL.  You may obtain a copy of the MPL at
00006  * http://www.mozilla.org/MPL/
00007  *
00008  * Software distributed under the MPL is distributed on an "AS IS" basis,
00009  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the MPL
00010  * for the specific language governing rights and limitations under the
00011  * MPL.
00012  *
00013  * Alternatively, the contents of this file may be used under the
00014  * terms of the GNU Library General Public License (the "LGPL"), in
00015  * which case the provisions of the LGPL are applicable instead of
00016  * those above.  If you wish to allow use of your version of this file
00017  * only under the terms of the LGPL and not to allow others to use
00018  * your version of this file under the MPL, indicate your decision by
00019  * deleting the provisions above and replace them with the notice and
00020  * other provisions required by the LGPL.  If you do not delete the
00021  * provisions above, a recipient may use your version of this file
00022  * under either the MPL or the LGPL.
00023  */
00024 
00025 /*
00026  * This code is derived from GdkRgb.
00027  * For more information on GdkRgb, see http://www.levien.com/gdkrgb/
00028  * Raph Levien <raph@acm.org>
00029  */
00030 
00031 /* Ported by Christopher Blizzard to Xlib.  With permission from the
00032  * original authors and the copyright holders of this file, the
00033  * contents of this file are also redistributable under the terms of
00034  * the Mozilla Public license.  For information about the Mozilla
00035  * Public License, please see the license information at
00036  * http://www.mozilla.org/MPL/ */
00037 
00038 /* This code is copyright the following authors:
00039  * Raph Levien          <raph@acm.org>
00040  * Manish Singh         <manish@gtk.org>
00041  * Tim Janik            <timj@gtk.org>
00042  * Peter Mattis         <petm@xcf.berkeley.edu>
00043  * Spencer Kimball      <spencer@xcf.berkeley.edu>
00044  * Josh MacDonald       <jmacd@xcf.berkeley.edu>
00045  * Christopher Blizzard <blizzard@redhat.com>
00046  * Owen Taylor          <otaylor@redhat.com>
00047  * Shawn T. Amundson    <amundson@gtk.org>
00048 */
00049 
00050 #include <math.h>
00051 
00052 #if HAVE_CONFIG_H
00053 #  include "scconfig.h"
00054 #  if STDC_HEADERS
00055 #    include <stdio.h>
00056 #    include <stdlib.h>
00057 #    include <string.h>
00058 #  endif
00059 #else
00060 #  include <stdio.h>
00061 #  include <stdlib.h>
00062 #endif
00063 
00064 #define ENABLE_GRAYSCALE
00065 
00066 /* include this before so that we can get endian definitions if
00067    they are there... */
00068 
00069 #include "gdk-pixbuf-xlibrgb.h"
00070 #include "gdk-pixbuf-xlib-private.h"
00071 
00072 #ifndef MIN
00073 #define MIN(a, b)  (((a) < (b)) ? (a) : (b))
00074 #endif
00075 
00076 #ifndef MAX
00077 #define MAX(a, b)  (((a) > (b)) ? (a) : (b))
00078 #endif
00079 
00080 typedef enum {
00081   LSB_FIRST,
00082   MSB_FIRST
00083 } ByteOrder;
00084 
00085 
00086 typedef struct _XlibRgbInfo   XlibRgbInfo;
00087 
00088 typedef void (*XlibRgbConvFunc) (XImage *image,
00089                              int ax, int ay,
00090                              int width, int height,
00091                              unsigned char *buf, int rowstride,
00092                              int x_align, int y_align,
00093                              XlibRgbCmap *cmap);
00094 
00095 /* Some of these fields should go, as they're not being used at all.
00096    Globals should generally migrate into here - it's very likely that
00097    we'll want to run more than one GdkRgbInfo context at the same time
00098    (i.e. some but not all windows have privately installed
00099    colormaps). */
00100 
00101 struct _XlibRgbInfo
00102 {
00103   Display          *display;
00104   Screen           *screen;
00105   int               screen_num;
00106   XVisualInfo      *x_visual_info;
00107   Colormap          cmap;
00108   XColor           *cmap_colors;
00109   Visual           *default_visualid;
00110   Colormap          default_colormap;
00111 
00112   unsigned long    *color_pixels;
00113   unsigned long    *gray_pixels;
00114   unsigned long    *reserved_pixels;
00115 
00116   unsigned long     red_shift;
00117   unsigned long     red_prec;
00118   unsigned long     blue_shift;
00119   unsigned long     blue_prec;
00120   unsigned long     green_shift;
00121   unsigned long     green_prec;
00122 
00123   unsigned int      nred_shades;
00124   unsigned int      ngreen_shades;
00125   unsigned int      nblue_shades;
00126   unsigned int      ngray_shades;
00127   unsigned int      nreserved;
00128 
00129   unsigned int      bpp;
00130   unsigned int      cmap_alloced;
00131   double            gamma_val;
00132 
00133   /* Generally, the stage buffer is used to convert 32bit RGB, gray,
00134      and indexed images into 24 bit packed RGB. */
00135   unsigned char *stage_buf;
00136 
00137   XlibRgbCmap *gray_cmap;
00138 
00139   Bool dith_default;
00140 
00141   Bool bitmap; /* set true if in 1 bit per pixel mode */
00142   GC own_gc;
00143 
00144   /* Convert functions */
00145   XlibRgbConvFunc conv;
00146   XlibRgbConvFunc conv_d;
00147 
00148   XlibRgbConvFunc conv_32;
00149   XlibRgbConvFunc conv_32_d;
00150 
00151   XlibRgbConvFunc conv_gray;
00152   XlibRgbConvFunc conv_gray_d;
00153 
00154   XlibRgbConvFunc conv_indexed;
00155   XlibRgbConvFunc conv_indexed_d;
00156 };
00157 
00158 static Bool xlib_rgb_install_cmap = FALSE;
00159 static int xlib_rgb_min_colors = 5 * 5 * 5;
00160 static Bool xlib_rgb_verbose = FALSE;
00161 
00162 #define IMAGE_WIDTH 256
00163 #define STAGE_ROWSTRIDE (IMAGE_WIDTH * 3)
00164 #define IMAGE_HEIGHT 64
00165 #define N_IMAGES 6
00166 
00167 static XlibRgbInfo *image_info = NULL;
00168 static XImage *static_image[N_IMAGES];
00169 static int static_image_idx;
00170 
00171 static unsigned char *colorcube;
00172 static unsigned char *colorcube_d;
00173 
00174 static unsigned long
00175 xlib_get_prec_from_mask(unsigned long val)
00176 {
00177   unsigned long retval = 0;
00178   unsigned int cur_bit = 0;
00179   /* walk through the number, incrementing the value if
00180      the bit in question is set. */
00181   while (cur_bit < (sizeof(unsigned long) * 8)) {
00182     if ((val >> cur_bit) & 0x1) {
00183       retval++;
00184     }
00185     cur_bit++;
00186   }
00187   return retval;
00188 }
00189 
00190 static unsigned long
00191 xlib_get_shift_from_mask(unsigned long val)
00192 {
00193   unsigned long cur_bit = 0;
00194   /* walk through the number, looking for the first 1 */
00195   while (cur_bit < (sizeof(unsigned long) * 8)) {
00196     if ((val >> cur_bit) & 0x1) {
00197       return cur_bit;
00198     }
00199     cur_bit++;
00200   }
00201   return cur_bit;
00202 }
00203 
00204 
00205 static int
00206 xlib_rgb_cmap_fail (const char *msg, Colormap cmap, unsigned long *pixels)
00207 {
00208   unsigned long free_pixels[256];
00209   int n_free;
00210   int i;
00211 
00212 #ifdef VERBOSE
00213   printf ("%s", msg);
00214 #endif
00215   n_free = 0;
00216   for (i = 0; i < 256; i++)
00217     if (pixels[i] < 256)
00218       free_pixels[n_free++] = pixels[i];
00219   
00220   if (n_free)
00221     XFreeColors(image_info->display,
00222               cmap,
00223               free_pixels,
00224               n_free,
00225               0);
00226   return 0;
00227 }
00228 
00229 static void
00230 xlib_rgb_make_colorcube (unsigned long *pixels, int nr, int ng, int nb)
00231 {
00232   unsigned char rt[16], gt[16], bt[16];
00233   int i;
00234 
00235   colorcube = (unsigned char *) malloc(sizeof(unsigned char) * 4096);
00236   memset(colorcube, 0, (sizeof(unsigned char) * 4096));
00237   for (i = 0; i < 16; i++)
00238     {
00239       rt[i] = ng * nb * ((i * 17 * (nr - 1) + 128) >> 8);
00240       gt[i] = nb * ((i * 17 * (ng - 1) + 128) >> 8);
00241       bt[i] = ((i * 17 * (nb - 1) + 128) >> 8);
00242     }
00243 
00244   for (i = 0; i < 4096; i++)
00245     {
00246       colorcube[i] = pixels[rt[i >> 8] + gt[(i >> 4) & 0x0f] + bt[i & 0x0f]];
00247 #ifdef VERBOSE
00248       printf ("%03x %02x %x %x %x\n", i, colorcube[i], rt[i >> 8], gt[(i >> 4) & 0x0f], bt[i & 0x0f]);
00249 #endif
00250     }
00251 }
00252 
00253 /* this is the colorcube suitable for dithering */
00254 static void
00255 xlib_rgb_make_colorcube_d (unsigned long *pixels, int nr, int ng, int nb)
00256 {
00257   int r, g, b;
00258   int i;
00259 
00260   colorcube_d = (unsigned char *) malloc(sizeof(unsigned char) * 512);
00261   memset(colorcube_d, 0, (sizeof(unsigned char) * 512));
00262   for (i = 0; i < 512; i++)
00263     {
00264       r = MIN (nr - 1, i >> 6);
00265       g = MIN (ng - 1, (i >> 3) & 7);
00266       b = MIN (nb - 1, i & 7);
00267       colorcube_d[i] = pixels[(r * ng + g) * nb + b];
00268     }
00269 }
00270 
00271 /* Try installing a color cube of the specified size.
00272    Make the colorcube and return TRUE on success */
00273 static int
00274 xlib_rgb_try_colormap (int nr, int ng, int nb)
00275 {
00276   int r, g, b;
00277   int ri, gi, bi;
00278   int r0, g0, b0;
00279   Colormap     cmap;
00280   XVisualInfo *visual;
00281   XColor      *colors = NULL;
00282   XColor       color;
00283   unsigned long pixels[256];
00284   unsigned long junk[256];
00285   int i;
00286   int d2;
00287   unsigned int colors_needed;
00288   int idx;
00289   int best[256];
00290 
00291   if (nr * ng * nb < xlib_rgb_min_colors)
00292     return FALSE;
00293 
00294   if (image_info->cmap_alloced) {
00295     cmap = image_info->cmap;
00296     visual = image_info->x_visual_info;
00297   }
00298   else {
00299     cmap = image_info->default_colormap;
00300     visual = image_info->x_visual_info;
00301   }
00302   colors_needed = nr * ng * nb;
00303   for (i = 0; i < 256; i++)
00304     {
00305       best[i] = 192;
00306       pixels[i] = 256;
00307     }
00308 
00309 #ifndef GAMMA
00310   if (!xlib_rgb_install_cmap) {
00311     /* go out and get the colors for this colormap. */
00312     colors = (XColor *) malloc(sizeof(XColor) * visual->colormap_size);
00313     for (i=0; i < visual->colormap_size; i++){
00314       colors[i].pixel = i;
00315     }
00316     XQueryColors (image_info->display,
00317                 cmap,
00318                 colors, visual->colormap_size);
00319     /* find color cube colors that are already present */
00320     for (i = 0; i < MIN (256, visual->colormap_size); i++)
00321       {
00322        r = colors[i].red >> 8;
00323        g = colors[i].green >> 8;
00324        b = colors[i].blue >> 8;
00325        ri = (r * (nr - 1) + 128) >> 8;
00326        gi = (g * (ng - 1) + 128) >> 8;
00327        bi = (b * (nb - 1) + 128) >> 8;
00328        r0 = ri * 255 / (nr - 1);
00329        g0 = gi * 255 / (ng - 1);
00330        b0 = bi * 255 / (nb - 1);
00331        idx = ((ri * nr) + gi) * nb + bi;
00332        d2 = (r - r0) * (r - r0) + (g - g0) * (g - g0) + (b - b0) * (b - b0);
00333        if (d2 < best[idx]) {
00334          if (pixels[idx] < 256)
00335            XFreeColors(image_info->display,
00336                      cmap,
00337                      pixels + idx,
00338                      1, 0);
00339          else
00340            colors_needed--;
00341          color.pixel = colors[i].pixel;
00342          color.red = colors[i].red;
00343          color.green = colors[i].green;
00344          color.blue = colors[i].blue;
00345          color.flags = 0;
00346          if (!XAllocColor(image_info->display, cmap, &color))
00347            return xlib_rgb_cmap_fail ("error allocating system color\n",
00348                                   cmap, pixels);
00349          pixels[idx] = color.pixel; /* which is almost certainly i */
00350          best[idx] = d2;
00351        }
00352       }
00353   }
00354 
00355 #endif
00356 
00357   if (colors_needed)
00358     {
00359       if (!XAllocColorCells(image_info->display, cmap, 0, NULL, 0, junk, colors_needed))
00360        {
00361          char tmp_str[80];
00362          
00363          sprintf (tmp_str,
00364                  "%d %d %d colormap failed (in XAllocColorCells)\n",
00365                  nr, ng, nb);
00366          return xlib_rgb_cmap_fail (tmp_str, cmap, pixels);
00367        }
00368       XFreeColors(image_info->display, cmap, junk, (int)colors_needed, 0);
00369     }
00370 
00371   for (r = 0, i = 0; r < nr; r++)
00372     for (g = 0; g < ng; g++)
00373       for (b = 0; b < nb; b++, i++)
00374        {
00375          if (pixels[i] == 256)
00376            {
00377              color.red = r * 65535 / (nr - 1);
00378              color.green = g * 65535 / (ng - 1);
00379              color.blue = b * 65535 / (nb - 1);
00380 
00381 #ifdef GAMMA
00382              color.red = 65535 * pow (color.red / 65535.0, 0.5);
00383              color.green = 65535 * pow (color.green / 65535.0, 0.5);
00384              color.blue = 65535 * pow (color.blue / 65535.0, 0.5);
00385 #endif
00386 
00387              /* This should be a raw XAllocColor call */
00388              if (!XAllocColor(image_info->display, cmap, &color))
00389               {
00390                 char tmp_str[80];
00391 
00392                 sprintf (tmp_str, "%d %d %d colormap failed\n",
00393                         nr, ng, nb);
00394                 return xlib_rgb_cmap_fail (tmp_str,
00395                                        cmap, pixels);
00396               }
00397              pixels[i] = color.pixel;
00398            }
00399 #ifdef VERBOSE
00400          printf ("%d: %lx\n", i, pixels[i]);
00401 #endif
00402        }
00403 
00404   image_info->nred_shades = nr;
00405   image_info->ngreen_shades = ng;
00406   image_info->nblue_shades = nb;
00407   xlib_rgb_make_colorcube (pixels, nr, ng, nb);
00408   xlib_rgb_make_colorcube_d (pixels, nr, ng, nb);
00409   if (colors)
00410     free(colors);
00411   return TRUE;
00412 }
00413 
00414 /* Return TRUE on success. */
00415 static Bool
00416 xlib_rgb_do_colormaps (void)
00417 {
00418   static const int sizes[][3] = {
00419     /*    { 6, 7, 6 }, */
00420     { 6, 6, 6 }, 
00421     { 6, 6, 5 }, 
00422     { 6, 6, 4 }, 
00423     { 5, 5, 5 }, 
00424     { 5, 5, 4 }, 
00425     { 4, 4, 4 }, 
00426     { 4, 4, 3 }, 
00427     { 3, 3, 3 }, 
00428     { 2, 2, 2 }
00429   };
00430   static const int n_sizes = sizeof(sizes) / (3 * sizeof(int));
00431   int i;
00432   
00433   for (i = 0; i < n_sizes; i++)
00434     if (xlib_rgb_try_colormap (sizes[i][0], sizes[i][1], sizes[i][2]))
00435       return TRUE;
00436   return FALSE;
00437 }
00438 
00439 /* Make a 2 x 2 x 2 colorcube */
00440 static void
00441 xlib_rgb_colorcube_222 (void)
00442 {
00443   int i;
00444   XColor color;
00445   Colormap cmap;
00446 
00447   if (image_info->cmap_alloced)
00448     cmap = image_info->cmap;
00449   else
00450     cmap = image_info->default_colormap;
00451 
00452   colorcube_d = (unsigned char *) malloc(sizeof(unsigned char) * 512);
00453 
00454   for (i = 0; i < 8; i++)
00455     {
00456       color.red = ((i & 4) >> 2) * 65535;
00457       color.green = ((i & 2) >> 1) * 65535;
00458       color.blue = (i & 1) * 65535;
00459       XAllocColor (image_info->display, cmap, &color);
00460       colorcube_d[((i & 4) << 4) | ((i & 2) << 2) | (i & 1)] = color.pixel;
00461     }
00462 }
00463 
00470 void
00471 xlib_rgb_set_verbose (Bool verbose)
00472 {
00473   xlib_rgb_verbose = verbose;
00474 }
00475 
00482 void
00483 xlib_rgb_set_install (Bool install)
00484 {
00485   xlib_rgb_install_cmap = install;
00486 }
00487 
00494 void
00495 xlib_rgb_set_min_colors (int min_colors)
00496 {
00497   xlib_rgb_min_colors = min_colors;
00498 }
00499 
00500 /* Return a "score" based on the following criteria (in hex):
00501 
00502    x000 is the quality - 1 is 1bpp, 2 is 4bpp,
00503                          4 is 8bpp,
00504                       7 is 15bpp truecolor, 8 is 16bpp truecolor,
00505                       9 is 24bpp truecolor.
00506    0x00 is the speed - 1 is the normal case,
00507                        2 means faster than normal
00508    00x0 gets a point for being the system visual
00509    000x gets a point for being pseudocolor
00510 
00511    A caveat: in the 8bpp modes, being the system visual seems to be
00512    quite important. Thus, all of the 8bpp modes should be ranked at
00513    the same speed.
00514 */
00515 
00516 static unsigned int
00517 xlib_rgb_score_visual (XVisualInfo *visual)
00518 {
00519   unsigned int quality, speed, pseudo, sys;
00520   static const char* visual_names[] =
00521   {
00522     "static gray",
00523     "grayscale",
00524     "static color",
00525     "pseudo color",
00526     "true color",
00527     "direct color",
00528   };
00529   
00530   
00531   quality = 0;
00532   speed = 1;
00533   sys = 0;
00534   if (visual->class == TrueColor ||
00535       visual->class == DirectColor)
00536     {
00537       if (visual->depth == 24)
00538        {
00539          quality = 9;
00540          /* Should test for MSB visual here, and set speed if so. */
00541        }
00542       else if (visual->depth == 16)
00543        quality = 8;
00544       else if (visual->depth == 15)
00545        quality = 7;
00546       else if (visual->depth == 8)
00547        quality = 4;
00548     }
00549   else if (visual->class == PseudoColor ||
00550           visual->class == StaticColor)
00551     {
00552       if (visual->depth == 8)
00553        quality = 4;
00554       else if (visual->depth == 4)
00555        quality = 2;
00556       else if (visual->depth == 1)
00557        quality = 1;
00558     }
00559   else if (visual->class == StaticGray
00560 #ifdef ENABLE_GRAYSCALE
00561           || visual->class == GrayScale
00562 #endif
00563           )
00564     {
00565       if (visual->depth == 8)
00566        quality = 4;
00567       else if (visual->depth == 4)
00568        quality = 2;
00569       else if (visual->depth == 1)
00570        quality = 1;
00571     }
00572 
00573   if (quality == 0)
00574     return 0;
00575 
00576   sys = (visual->visualid == image_info->default_visualid->visualid);
00577   
00578   pseudo = (visual->class == PseudoColor || visual->class == TrueColor);
00579 
00580   if (xlib_rgb_verbose)
00581     printf ("Visual 0x%x, type = %s, depth = %d, %ld:%ld:%ld%s; score=%x\n",
00582            (int)visual->visualid,
00583            visual_names[visual->class],
00584            visual->depth,
00585            visual->red_mask,
00586            visual->green_mask,
00587            visual->blue_mask,
00588            sys ? " (system)" : "",
00589            (quality << 12) | (speed << 8) | (sys << 4) | pseudo);
00590   
00591   return (quality << 12) | (speed << 8) | (sys << 4) | pseudo;
00592 }
00593 
00594 static void
00595 xlib_rgb_choose_visual (void)
00596 {
00597   XVisualInfo *visuals;
00598   XVisualInfo *visual;
00599   XVisualInfo *best_visual;
00600   XVisualInfo *final_visual;
00601   XVisualInfo template;
00602   int num_visuals;
00603   unsigned int score, best_score;
00604   int cur_visual = 1;
00605   int i;
00606   
00607   template.screen = image_info->screen_num;
00608   visuals = XGetVisualInfo(image_info->display, VisualScreenMask,
00609                         &template, &num_visuals);
00610   
00611   best_visual = visuals;
00612   best_score = xlib_rgb_score_visual (best_visual);
00613 
00614   for (i = cur_visual; i < num_visuals; i++)
00615     {
00616       visual = &visuals[i];
00617       score = xlib_rgb_score_visual  (visual);
00618       if (score > best_score)
00619        {
00620          best_score = score;
00621          best_visual = visual;
00622        }
00623     }
00624   /* make a copy of the visual so that we can free
00625      the allocated visual list above. */
00626   final_visual = (XVisualInfo *) malloc(sizeof(XVisualInfo));
00627   memcpy(final_visual, best_visual, sizeof(XVisualInfo));
00628   image_info->x_visual_info = final_visual;
00629   XFree(visuals);
00630   /* set up the shift and the precision for the red, green and blue.
00631      this only applies to cool visuals like true color and direct color. */
00632   if (image_info->x_visual_info->class == TrueColor ||
00633       image_info->x_visual_info->class == DirectColor) {
00634     image_info->red_shift = xlib_get_shift_from_mask(image_info->x_visual_info->red_mask);
00635     image_info->red_prec = xlib_get_prec_from_mask(image_info->x_visual_info->red_mask);
00636     image_info->green_shift = xlib_get_shift_from_mask(image_info->x_visual_info->green_mask);
00637     image_info->green_prec = xlib_get_prec_from_mask(image_info->x_visual_info->green_mask);
00638     image_info->blue_shift = xlib_get_shift_from_mask(image_info->x_visual_info->blue_mask);
00639     image_info->blue_prec = xlib_get_prec_from_mask(image_info->x_visual_info->blue_mask);
00640   }
00641 }
00642 
00643 static void
00644 xlib_rgb_choose_visual_for_xprint (int aDepth)
00645 {
00646   XVisualInfo *visuals;
00647   XVisualInfo *visual;
00648   XVisualInfo *best_visual;
00649   XVisualInfo *final_visual;
00650   XVisualInfo template;
00651   int num_visuals;
00652   int cur_visual = 1;
00653   int i;
00654 
00655   XWindowAttributes win_att;
00656   Status ret_stat;
00657   Visual      *root_visual;
00658 
00659   ret_stat = XGetWindowAttributes(image_info->display, 
00660                      RootWindow(image_info->display, image_info->screen_num),
00661                      &win_att);
00662   root_visual = win_att.visual;
00663   template.screen = image_info->screen_num;
00664   visuals = XGetVisualInfo(image_info->display, VisualScreenMask,
00665                         &template, &num_visuals);
00666  
00667   best_visual = visuals;
00668   if (best_visual->visual != root_visual) {
00669      for (i = cur_visual; i < num_visuals; i++) {
00670         visual = &visuals[i];
00671         if (visual->visual == root_visual) {
00672            best_visual = visual;
00673            break;
00674         }
00675       }
00676    }
00677   /* make a copy of the visual so that we can free
00678      the allocated visual list above. */
00679   final_visual = (XVisualInfo *) malloc(sizeof(XVisualInfo));
00680   memcpy(final_visual, best_visual, sizeof(XVisualInfo));
00681   image_info->x_visual_info = final_visual;
00682   XFree(visuals);
00683   /* set up the shift and the precision for the red, green and blue.
00684      this only applies to cool visuals like true color and direct color. */
00685   if (image_info->x_visual_info->class == TrueColor ||
00686       image_info->x_visual_info->class == DirectColor) {
00687     image_info->red_shift = xlib_get_shift_from_mask(image_info->x_visual_info->red_mask);
00688     image_info->red_prec = xlib_get_prec_from_mask(image_info->x_visual_info->red_mask);
00689     image_info->green_shift = xlib_get_shift_from_mask(image_info->x_visual_info->green_mask);
00690     image_info->green_prec = xlib_get_prec_from_mask(image_info->x_visual_info->green_mask);
00691     image_info->blue_shift = xlib_get_shift_from_mask(image_info->x_visual_info->blue_mask);
00692     image_info->blue_prec = xlib_get_prec_from_mask(image_info->x_visual_info->blue_mask);
00693   }
00694 }
00695 
00696 static void xlib_rgb_select_conv (XImage *image, ByteOrder byte_order);
00697 
00698 static void
00699 xlib_rgb_set_gray_cmap (Colormap cmap)
00700 {
00701   int i;
00702   XColor color;
00703   int status;
00704   unsigned long pixels[256];
00705   int r, g, b, gray;
00706 
00707   for (i = 0; i < 256; i++)
00708     {
00709       color.pixel = i;
00710       color.red = i * 257;
00711       color.green = i * 257;
00712       color.blue = i * 257;
00713       status = XAllocColor(image_info->display, cmap, &color);
00714       pixels[i] = color.pixel;
00715 #ifdef VERBOSE
00716       printf ("allocating pixel %d, %x %x %x, result %d\n",
00717               color.pixel, color.red, color.green, color.blue, status);
00718 #endif
00719     }
00720 
00721   /* Now, we make fake colorcubes - we ultimately just use the pseudocolor
00722      methods. */
00723 
00724   colorcube = (unsigned char *) malloc(sizeof(unsigned char) * 4096);
00725 
00726   for (i = 0; i < 4096; i++)
00727     {
00728       r = (i >> 4) & 0xf0;
00729       r = r | r >> 4;
00730       g = i & 0xf0;
00731       g = g | g >> 4;
00732       b = (i << 4 & 0xf0);
00733       b = b | b >> 4;
00734       gray = (g + ((r + b) >> 1)) >> 1;
00735       colorcube[i] = pixels[gray];
00736     }
00737 }
00738 
00749 void
00750 xlib_rgb_init (Display *display, Screen *screen)
00751 {
00752   int prefDepth = -1;            /*  let the function do the visual scoring */
00753   xlib_rgb_init_with_depth(display, screen, prefDepth);
00754 }
00755 
00768 void
00769 xlib_rgb_init_with_depth (Display *display, Screen *screen, int prefDepth)
00770 {
00771   int i;
00772   static const int byte_order[1] = { 1 };
00773 
00774   static int initialized = 0;
00775 
00776   if (initialized)
00777   {
00778     return;
00779   }
00780 
00781   initialized = 1;
00782 
00783 #ifdef WORDS_BIGENDIAN
00784   if (((char *)byte_order)[0] == 1) {
00785     printf ("xlib_rgb_init: compiled for big endian, but this is a little endian machine.\n\n");
00786     exit(1);
00787   }
00788 #else
00789   if (((char *)byte_order)[0] != 1) {
00790     printf ("xlib_rgb_init: compiled for little endian, but this is a big endian machine.\n\n");
00791     exit(1);
00792   }
00793 #endif
00794 
00795   if (image_info == NULL)
00796     {
00797       image_info = (XlibRgbInfo *) malloc(sizeof(XlibRgbInfo));
00798       memset(image_info, 0, sizeof(XlibRgbInfo));
00799 
00800       image_info->display = display;
00801       image_info->screen = screen;
00802       image_info->screen_num = XScreenNumberOfScreen(screen);
00803       image_info->x_visual_info = NULL;
00804       image_info->cmap = 0;
00805       image_info->default_visualid = DefaultVisual(display, image_info->screen_num);
00806       image_info->default_colormap = DefaultColormap(display, image_info->screen_num);
00807 
00808       image_info->color_pixels = NULL;
00809       image_info->gray_pixels = NULL;
00810       image_info->reserved_pixels = NULL;
00811 
00812       image_info->nred_shades = 6;
00813       image_info->ngreen_shades = 6;
00814       image_info->nblue_shades = 4;
00815       image_info->ngray_shades = 24;
00816       image_info->nreserved = 0;
00817 
00818       image_info->bpp = 0;
00819       image_info->cmap_alloced = FALSE;
00820       image_info->gamma_val = 1.0;
00821 
00822       image_info->stage_buf = NULL;
00823 
00824       image_info->own_gc = 0;
00825       
00826       image_info->red_shift = 0;
00827       image_info->red_prec = 0;
00828       image_info->green_shift = 0;
00829       image_info->green_prec = 0;
00830       image_info->blue_shift = 0;
00831       image_info->blue_prec = 0;
00832 
00833       if (prefDepth != -1)
00834         xlib_rgb_choose_visual_for_xprint (prefDepth);
00835       else
00836         xlib_rgb_choose_visual ();
00837 
00838       if ((image_info->x_visual_info->class == PseudoColor ||
00839           image_info->x_visual_info->class == StaticColor) &&
00840          image_info->x_visual_info->depth < 8 &&
00841          image_info->x_visual_info->depth >= 3)
00842        {
00843          image_info->cmap = image_info->default_colormap;
00844          xlib_rgb_colorcube_222 ();
00845        }
00846       else if (image_info->x_visual_info->class == PseudoColor)
00847        {
00848          if (xlib_rgb_install_cmap ||
00849              image_info->x_visual_info->visualid != image_info->default_visualid->visualid)
00850            {
00851              image_info->cmap = XCreateColormap(image_info->display,
00852                                            RootWindow(image_info->display, image_info->screen_num),
00853                                            image_info->x_visual_info->visual,
00854                                            AllocNone);
00855              image_info->cmap_alloced = TRUE;
00856            }
00857          if (!xlib_rgb_do_colormaps ())
00858            {
00859              image_info->cmap = XCreateColormap(image_info->display,
00860                                            RootWindow(image_info->display, image_info->screen_num),
00861                                            image_info->x_visual_info->visual,
00862                                            AllocNone);
00863              image_info->cmap_alloced = TRUE;
00864              xlib_rgb_do_colormaps ();
00865            }
00866          if (xlib_rgb_verbose)
00867            printf ("color cube: %d x %d x %d\n",
00868                   image_info->nred_shades,
00869                   image_info->ngreen_shades,
00870                   image_info->nblue_shades);
00871 
00872          if (!image_info->cmap_alloced)
00873              image_info->cmap = image_info->default_colormap;
00874        }
00875 #ifdef ENABLE_GRAYSCALE
00876       else if (image_info->x_visual_info->class == GrayScale)
00877        {
00878          image_info->cmap = XCreateColormap(image_info->display,
00879                                         RootWindow(image_info->display, image_info->screen_num),
00880                                         image_info->x_visual_info->visual,
00881                                         AllocNone);
00882          xlib_rgb_set_gray_cmap (image_info->cmap);
00883          image_info->cmap_alloced = TRUE;
00884        }
00885 #endif
00886       else
00887        {
00888          /* Always install colormap in direct color. */
00889          if (image_info->x_visual_info->class != DirectColor && 
00890              image_info->x_visual_info->visualid == image_info->default_visualid->visualid)
00891            image_info->cmap = image_info->default_colormap;
00892          else
00893            {
00894              image_info->cmap = XCreateColormap(image_info->display,
00895                                            RootWindow(image_info->display, image_info->screen_num),
00896                                            image_info->x_visual_info->visual,
00897                                            AllocNone);
00898              image_info->cmap_alloced = TRUE;
00899            }
00900        }
00901 
00902       image_info->bitmap = (image_info->x_visual_info->depth == 1);
00903 
00904       for (i = 0; i < N_IMAGES; i++) {
00905        if (image_info->bitmap) {
00906          /* Use malloc() instead of g_malloc since X will free() this mem */
00907          static_image[i] = XCreateImage(image_info->display,
00908                                     image_info->x_visual_info->visual,
00909                                     1,
00910                                     XYBitmap,
00911                                     0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
00912                                     8,
00913                                     0);
00914          static_image[i]->data = (char *) malloc(IMAGE_WIDTH * IMAGE_HEIGHT >> 3);
00915          static_image[i]->bitmap_bit_order = MSBFirst;
00916          static_image[i]->byte_order = MSBFirst;
00917        }
00918        else {
00919          static_image[i] = XCreateImage(image_info->display,
00920                                     image_info->x_visual_info->visual,
00921                                     (unsigned int)image_info->x_visual_info->depth,
00922                                     ZPixmap,
00923                                     0, 0,
00924                                     IMAGE_WIDTH,
00925                                     IMAGE_HEIGHT,
00926                                     32, 0);
00927          /* remove this when we are using shared memory.. */
00928          static_image[i]->data = (char *) malloc((size_t)IMAGE_WIDTH * IMAGE_HEIGHT * image_info->x_visual_info->depth);
00929          static_image[i]->bitmap_bit_order = MSBFirst;
00930          static_image[i]->byte_order = MSBFirst;
00931        }
00932       }
00933       /* ok, so apparently, image_info->bpp is actually
00934         BYTES per pixel.  What fun! */
00935       switch (static_image[0]->bits_per_pixel) {
00936       case 1:
00937       case 8:
00938        image_info->bpp = 1;
00939        break;
00940       case 16:
00941        image_info->bpp = 2;
00942        break;
00943       case 24:
00944        image_info->bpp = 3;
00945        break;
00946       case 32:
00947        image_info->bpp = 4;
00948        break;
00949       }
00950       xlib_rgb_select_conv (static_image[0], MSB_FIRST);
00951     }
00952 }
00953 
00964 unsigned long
00965 xlib_rgb_xpixel_from_rgb (unsigned int rgb)
00966 {
00967   unsigned long pixel = 0;
00968 
00969   if (image_info->bitmap)
00970     {
00971       return ((rgb & 0xff0000) >> 16) +
00972        ((rgb & 0xff00) >> 7) +
00973        (rgb & 0xff) > 510;
00974     }
00975   else if (image_info->x_visual_info->class == PseudoColor)
00976     pixel = colorcube[((rgb & 0xf00000) >> 12) |
00977                    ((rgb & 0xf000) >> 8) |
00978                    ((rgb & 0xf0) >> 4)];
00979   else if (image_info->x_visual_info->depth < 8 &&
00980           image_info->x_visual_info->class == StaticColor)
00981     {
00982       pixel = colorcube_d[((rgb & 0x800000) >> 17) |
00983                       ((rgb & 0x8000) >> 12) |
00984                       ((rgb & 0x80) >> 7)];
00985     }
00986   else if (image_info->x_visual_info->class == TrueColor ||
00987           image_info->x_visual_info->class == DirectColor)
00988     {
00989 #ifdef VERBOSE
00990       printf ("shift, prec: r %d %d g %d %d b %d %d\n",
00991              image_info->red_shift,
00992              image_info->red_prec,
00993              image_info->green_shift,
00994              image_info->green_prec,
00995              image_info->blue_shift,
00996              image_info->blue_prec);
00997 #endif
00998 
00999       pixel = (((((rgb & 0xff0000) >> 16) >>
01000                (8 - image_info->red_prec)) <<
01001               image_info->red_shift) +
01002               ((((rgb & 0xff00) >> 8)  >>
01003                (8 - image_info->green_prec)) <<
01004               image_info->green_shift) +
01005               (((rgb & 0xff) >>
01006                (8 - image_info->blue_prec)) <<
01007               image_info->blue_shift));
01008     }
01009   else if (image_info->x_visual_info->class == StaticGray ||
01010           image_info->x_visual_info->class == GrayScale)
01011     {
01012       int gray = ((rgb & 0xff0000) >> 16) +
01013        ((rgb & 0xff00) >> 7) +
01014        (rgb & 0xff);
01015 
01016       return gray >> (10 - image_info->x_visual_info->depth);
01017     }
01018 
01019   return pixel;
01020 }
01021 
01031 void
01032 xlib_rgb_gc_set_foreground (GC gc, unsigned int rgb)
01033 {
01034   unsigned long color;
01035 
01036   color = xlib_rgb_xpixel_from_rgb (rgb);
01037   XSetForeground(image_info->display, gc, color);
01038 }
01039 
01049 void
01050 xlib_rgb_gc_set_background (GC gc, unsigned int rgb)
01051 {
01052   unsigned long color;
01053 
01054   color = xlib_rgb_xpixel_from_rgb (rgb);
01055   XSetBackground(image_info->display, gc, color);
01056 }
01057 
01058 #ifndef WORDS_BIGENDIAN
01059 #define HAIRY_CONVERT_8
01060 #endif
01061 
01062 #ifdef HAIRY_CONVERT_8
01063 static void
01064 xlib_rgb_convert_8 (XImage *image,
01065                  int ax, int ay, int width, int height,
01066                  unsigned char *buf, int rowstride,
01067                  int x_align, int y_align, XlibRgbCmap *cmap)
01068 {
01069   int x, y;
01070   int bpl;
01071   unsigned char *obuf, *obptr;
01072   unsigned char *bptr, *bp2;
01073   int r, g, b;
01074 
01075   bptr = buf;
01076   bpl = image->bytes_per_line;
01077   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01078   for (y = 0; y < height; y++)
01079     {
01080       bp2 = bptr;
01081       obptr = obuf;
01082       if (((unsigned long)obuf | (unsigned long) bp2) & 3)
01083        {
01084          for (x = 0; x < width; x++)
01085            {
01086              r = *bp2++;
01087              g = *bp2++;
01088              b = *bp2++;
01089              obptr[0] = colorcube[((r & 0xf0) << 4) |
01090                               (g & 0xf0) |
01091                               (b >> 4)];
01092              obptr++;
01093            }
01094        }
01095       else
01096        {
01097          for (x = 0; x < width - 3; x += 4)
01098            {
01099              unsigned int r1b0g0r0;
01100              unsigned int g2r2b1g1;
01101              unsigned int b3g3r3b2;
01102 
01103              r1b0g0r0 = ((unsigned int *)bp2)[0];
01104              g2r2b1g1 = ((unsigned int *)bp2)[1];
01105              b3g3r3b2 = ((unsigned int *)bp2)[2];
01106              ((unsigned int *)obptr)[0] =
01107               colorcube[((r1b0g0r0 & 0xf0) << 4) | 
01108                       ((r1b0g0r0 & 0xf000) >> 8) |
01109                       ((r1b0g0r0 & 0xf00000) >> 20)] |
01110               (colorcube[((r1b0g0r0 & 0xf0000000) >> 20) |
01111                        (g2r2b1g1 & 0xf0) |
01112                        ((g2r2b1g1 & 0xf000) >> 12)] << 8) |
01113               (colorcube[((g2r2b1g1 & 0xf00000) >> 12) |
01114                        ((g2r2b1g1 & 0xf0000000) >> 24) |
01115                        ((b3g3r3b2 & 0xf0) >> 4)] << 16) |
01116               (colorcube[((b3g3r3b2 & 0xf000) >> 4) |
01117                        ((b3g3r3b2 & 0xf00000) >> 16) |
01118                        (b3g3r3b2 >> 28)] << 24);
01119              bp2 += 12;
01120              obptr += 4;
01121            }
01122          for (; x < width; x++)
01123            {
01124              r = *bp2++;
01125              g = *bp2++;
01126              b = *bp2++;
01127              obptr[0] = colorcube[((r & 0xf0) << 4) |
01128                               (g & 0xf0) |
01129                               (b >> 4)];
01130              obptr++;
01131            }
01132        }
01133       bptr += rowstride;
01134       obuf += bpl;
01135     }
01136 }
01137 #else
01138 static void
01139 xlib_rgb_convert_8 (XImage *image,
01140                  int ax, int ay, int width, int height,
01141                  unsigned char *buf, int rowstride,
01142                  int x_align, int y_align, XlibRgbCmap *cmap)
01143 {
01144   int x, y;
01145   int bpl;
01146   unsigned char *obuf, *obptr;
01147   unsigned char *bptr, *bp2;
01148   int r, g, b;
01149 
01150   bptr = buf;
01151   bpl = image->bytes_per_line;
01152   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01153   for (y = 0; y < height; y++)
01154     {
01155       bp2 = bptr;
01156       obptr = obuf;
01157       for (x = 0; x < width; x++)
01158        {
01159          r = *bp2++;
01160          g = *bp2++;
01161          b = *bp2++;
01162          obptr[0] = colorcube[((r & 0xf0) << 4) |
01163                            (g & 0xf0) |
01164                            (b >> 4)];
01165          obptr++;
01166        }
01167       bptr += rowstride;
01168       obuf += bpl;
01169     }
01170 }
01171 #endif
01172 
01173 #if 1
01174 
01175 /* This dither table was generated by Raph Levien using patented
01176    technology (US Patent 5,276,535). The dither table itself is in the
01177    public domain. */
01178 
01179 #define DM_WIDTH 128
01180 #define DM_WIDTH_SHIFT 7
01181 #define DM_HEIGHT 128
01182 static const unsigned char DM[128][128] =
01183 {
01184   { 0, 41, 23, 5, 17, 39, 7, 15, 62, 23, 40, 51, 31, 47, 9, 32, 52, 27, 57, 25, 6, 61, 27, 52, 37, 7, 40, 63, 18, 36, 10, 42, 25, 62, 45, 34, 20, 42, 37, 14, 35, 29, 50, 10, 61, 2, 40, 8, 37, 12, 58, 22, 5, 41, 10, 39, 0, 60, 11, 46, 2, 55, 38, 17, 36, 59, 13, 54, 37, 56, 8, 29, 16, 13, 63, 22, 41, 55, 7, 20, 49, 14, 23, 55, 37, 23, 19, 36, 15, 49, 23, 63, 30, 14, 38, 27, 53, 13, 22, 41, 19, 31, 7, 19, 50, 30, 49, 16, 3, 32, 56, 40, 29, 34, 8, 48, 19, 45, 4, 51, 12, 46, 35, 49, 16, 42, 12, 62 },
01185   { 30, 57, 36, 54, 47, 34, 52, 27, 43, 4, 28, 7, 17, 36, 62, 13, 44, 7, 18, 48, 33, 21, 44, 14, 30, 47, 12, 33, 5, 55, 31, 58, 13, 30, 4, 17, 52, 10, 60, 26, 46, 0, 39, 27, 42, 22, 47, 25, 60, 32, 9, 38, 48, 17, 59, 30, 49, 18, 34, 25, 51, 19, 5, 48, 21, 8, 28, 46, 1, 32, 41, 19, 54, 47, 37, 18, 28, 11, 44, 30, 39, 56, 2, 33, 8, 42, 61, 28, 58, 8, 46, 9, 41, 4, 58, 7, 21, 48, 59, 10, 52, 14, 42, 57, 12, 25, 7, 53, 42, 24, 11, 50, 17, 59, 42, 2, 36, 60, 32, 17, 63, 29, 21, 7, 59, 32, 24, 39 },
01186   { 22, 8, 16, 32, 3, 25, 13, 57, 18, 45, 58, 39, 55, 20, 5, 42, 23, 34, 63, 1, 51, 10, 58, 4, 60, 23, 53, 27, 44, 21, 3, 48, 8, 50, 43, 54, 27, 32, 5, 55, 21, 58, 12, 53, 6, 36, 14, 50, 17, 29, 53, 15, 24, 52, 7, 36, 13, 42, 4, 53, 9, 35, 61, 26, 56, 32, 49, 15, 62, 23, 6, 60, 2, 31, 4, 48, 58, 38, 15, 61, 5, 25, 47, 28, 50, 15, 7, 40, 3, 32, 33, 52, 25, 50, 35, 42, 61, 3, 28, 36, 23, 63, 4, 33, 46, 62, 36, 23, 60, 6, 54, 28, 4, 37, 23, 55, 25, 8, 42, 54, 14, 6, 56, 38, 19, 52, 4, 46 },
01187   { 48, 53, 43, 12, 45, 63, 30, 37, 9, 34, 21, 1, 25, 47, 29, 58, 3, 54, 15, 39, 29, 17, 38, 35, 20, 43, 1, 49, 15, 59, 29, 39, 22, 35, 16, 23, 1, 47, 39, 18, 8, 44, 25, 31, 57, 19, 63, 4, 45, 3, 42, 61, 1, 31, 45, 20, 57, 29, 62, 21, 32, 41, 14, 44, 3, 39, 5, 34, 10, 43, 51, 35, 23, 52, 40, 10, 21, 1, 53, 18, 51, 43, 12, 62, 18, 54, 26, 51, 20, 57, 14, 1, 62, 16, 11, 18, 32, 39, 17, 44, 1, 48, 26, 37, 18, 2, 51, 14, 28, 45, 35, 18, 57, 13, 47, 11, 51, 20, 2, 39, 31, 47, 25, 1, 50, 11, 60, 7 },
01188   { 18, 28, 1, 56, 21, 10, 51, 2, 46, 54, 14, 61, 11, 50, 13, 38, 19, 31, 45, 9, 55, 24, 47, 5, 54, 9, 62, 11, 35, 8, 51, 14, 57, 6, 63, 40, 58, 14, 51, 28, 62, 34, 15, 48, 1, 41, 30, 35, 55, 21, 34, 11, 49, 37, 8, 52, 4, 23, 15, 43, 1, 58, 11, 23, 53, 16, 55, 26, 58, 18, 27, 12, 45, 14, 25, 63, 42, 33, 27, 35, 9, 31, 21, 38, 1, 44, 34, 12, 48, 38, 21, 44, 29, 47, 26, 53, 1, 46, 54, 8, 59, 29, 11, 55, 22, 41, 33, 20, 39, 1, 48, 9, 44, 32, 5, 62, 29, 44, 57, 23, 10, 58, 34, 43, 15, 37, 26, 33 },
01189   { 51, 38, 59, 24, 35, 42, 19, 60, 5, 32, 41, 26, 43, 33, 7, 53, 48, 11, 59, 23, 42, 2, 61, 30, 16, 40, 32, 24, 56, 41, 19, 33, 37, 26, 47, 9, 31, 22, 2, 45, 9, 54, 4, 37, 21, 52, 11, 23, 7, 57, 16, 25, 55, 18, 63, 27, 46, 39, 56, 10, 50, 37, 29, 47, 19, 63, 24, 9, 46, 2, 39, 60, 9, 57, 30, 7, 49, 11, 59, 3, 45, 57, 5, 60, 29, 22, 5, 60, 30, 9, 59, 18, 40, 6, 57, 36, 30, 12, 24, 34, 15, 40, 52, 6, 49, 9, 58, 4, 63, 12, 26, 61, 22, 53, 38, 16, 35, 14, 28, 50, 42, 17, 5, 28, 62, 20, 54, 12 },
01190   { 26, 6, 31, 15, 49, 6, 38, 27, 22, 49, 16, 56, 2, 62, 30, 21, 0, 36, 28, 6, 49, 32, 13, 52, 26, 50, 19, 46, 3, 26, 62, 0, 53, 12, 29, 3, 53, 41, 60, 24, 38, 13, 58, 16, 43, 9, 59, 39, 46, 28, 44, 40, 2, 33, 13, 41, 16, 6, 47, 31, 26, 17, 57, 6, 38, 0, 42, 36, 29, 52, 20, 31, 48, 0, 34, 56, 20, 36, 23, 54, 14, 41, 24, 37, 10, 55, 46, 25, 16, 45, 36, 4, 55, 23, 15, 8, 50, 62, 5, 56, 44, 20, 13, 28, 59, 31, 24, 47, 31, 52, 37, 17, 40, 0, 26, 49, 3, 60, 7, 33, 0, 61, 53, 40, 8, 45, 2, 41 },
01191   { 16, 63, 43, 4, 61, 24, 56, 13, 53, 8, 36, 12, 24, 41, 16, 46, 60, 26, 52, 39, 14, 57, 21, 37, 0, 45, 7, 59, 38, 17, 43, 10, 45, 20, 61, 43, 19, 11, 33, 17, 50, 32, 23, 61, 28, 49, 26, 0, 18, 51, 5, 60, 22, 58, 29, 0, 59, 34, 19, 62, 3, 52, 7, 44, 30, 59, 13, 50, 15, 62, 7, 17, 38, 22, 44, 15, 40, 4, 47, 28, 33, 17, 49, 16, 51, 40, 10, 56, 0, 53, 13, 49, 28, 38, 60, 21, 43, 19, 37, 27, 3, 51, 34, 39, 0, 45, 15, 43, 10, 21, 3, 55, 8, 33, 59, 10, 41, 18, 52, 24, 46, 20, 30, 13, 58, 22, 36, 57 },
01192   { 50, 34, 11, 47, 29, 17, 44, 0, 33, 63, 28, 46, 52, 5, 57, 10, 42, 18, 4, 63, 20, 8, 44, 10, 56, 34, 14, 29, 5, 54, 23, 59, 32, 49, 7, 34, 49, 27, 56, 0, 42, 7, 46, 3, 40, 6, 54, 32, 62, 13, 36, 10, 47, 8, 35, 49, 24, 51, 12, 40, 22, 35, 60, 12, 22, 51, 33, 4, 40, 25, 43, 55, 5, 54, 12, 61, 26, 51, 8, 62, 0, 53, 7, 63, 2, 32, 19, 34, 42, 24, 31, 63, 2, 10, 45, 33, 0, 48, 9, 61, 22, 47, 8, 62, 18, 56, 7, 54, 27, 57, 46, 30, 50, 19, 45, 30, 56, 36, 22, 47, 11, 38, 3, 51, 32, 48, 18, 9 },
01193   { 0, 21, 40, 19, 52, 9, 37, 48, 20, 40, 3, 18, 27, 38, 35, 22, 31, 56, 13, 35, 46, 28, 60, 40, 27, 18, 61, 50, 41, 30, 7, 36, 2, 25, 16, 57, 5, 15, 47, 29, 55, 19, 30, 52, 15, 34, 20, 12, 43, 30, 20, 54, 25, 44, 53, 12, 38, 5, 55, 27, 48, 15, 33, 27, 45, 8, 19, 28, 56, 11, 33, 49, 18, 36, 29, 2, 45, 16, 39, 19, 31, 43, 27, 35, 20, 52, 26, 6, 61, 11, 41, 17, 29, 51, 20, 56, 25, 32, 41, 17, 53, 31, 25, 14, 42, 23, 35, 16, 38, 6, 34, 12, 15, 62, 6, 21, 13, 1, 63, 9, 55, 27, 43, 25, 14, 4, 31, 55 },
01194   { 44, 29, 61, 2, 35, 58, 26, 15, 60, 10, 51, 59, 14, 55, 8, 50, 2, 44, 25, 51, 1, 33, 16, 4, 48, 36, 2, 21, 12, 57, 48, 13, 51, 55, 40, 28, 37, 62, 8, 39, 12, 63, 36, 10, 59, 24, 56, 47, 9, 50, 41, 1, 32, 17, 6, 21, 61, 30, 9, 43, 1, 54, 41, 2, 54, 37, 48, 61, 1, 46, 21, 3, 58, 24, 50, 32, 60, 10, 57, 25, 46, 12, 59, 4, 45, 13, 57, 47, 27, 39, 5, 58, 47, 14, 35, 4, 52, 13, 60, 6, 36, 10, 45, 55, 4, 50, 29, 2, 61, 50, 25, 58, 44, 24, 36, 42, 54, 28, 40, 32, 16, 56, 6, 62, 46, 39, 60, 23 },
01195   { 7, 48, 14, 54, 23, 40, 4, 45, 30, 22, 42, 32, 1, 44, 20, 29, 58, 8, 37, 19, 41, 54, 24, 58, 9, 53, 25, 46, 34, 16, 23, 38, 27, 11, 18, 1, 52, 21, 35, 22, 48, 5, 25, 45, 18, 38, 2, 27, 35, 4, 57, 15, 62, 39, 57, 28, 42, 16, 36, 60, 24, 18, 10, 63, 20, 5, 16, 23, 37, 14, 59, 27, 41, 8, 13, 42, 21, 35, 6, 50, 3, 38, 15, 48, 30, 39, 17, 3, 49, 14, 53, 33, 24, 7, 61, 44, 11, 39, 23, 49, 19, 58, 1, 32, 36, 12, 60, 41, 20, 13, 41, 4, 39, 1, 48, 8, 18, 51, 14, 44, 5, 37, 21, 34, 1, 26, 10, 37 },
01196   { 53, 36, 27, 9, 50, 12, 32, 55, 2, 57, 7, 17, 48, 34, 63, 15, 40, 26, 62, 11, 49, 6, 31, 39, 22, 42, 6, 63, 1, 39, 60, 4, 42, 61, 32, 45, 24, 44, 2, 60, 16, 41, 53, 1, 33, 61, 49, 17, 63, 23, 45, 26, 33, 3, 23, 46, 2, 50, 20, 4, 45, 34, 49, 30, 39, 58, 44, 31, 53, 34, 6, 52, 30, 47, 63, 1, 53, 22, 42, 31, 58, 23, 54, 22, 61, 8, 36, 59, 22, 35, 21, 1, 55, 40, 27, 16, 30, 54, 2, 29, 43, 16, 39, 63, 21, 46, 26, 10, 48, 32, 19, 53, 30, 56, 26, 60, 33, 4, 61, 23, 49, 59, 15, 53, 19, 58, 42, 16 },
01197   { 20, 5, 59, 46, 25, 62, 7, 19, 43, 25, 37, 61, 11, 24, 4, 54, 12, 52, 3, 32, 17, 61, 12, 47, 15, 55, 18, 31, 53, 28, 9, 50, 21, 6, 55, 9, 58, 14, 54, 26, 33, 7, 31, 58, 13, 21, 8, 42, 29, 6, 37, 11, 48, 52, 14, 60, 11, 39, 56, 32, 14, 58, 7, 26, 17, 4, 42, 8, 11, 47, 19, 38, 10, 17, 26, 37, 9, 55, 28, 13, 18, 40, 6, 33, 1, 43, 25, 11, 51, 7, 62, 43, 18, 37, 3, 57, 45, 9, 38, 58, 5, 52, 27, 7, 17, 53, 5, 57, 37, 2, 63, 9, 22, 15, 11, 38, 25, 45, 35, 0, 28, 10, 41, 30, 50, 8, 31, 57 },
01198   { 49, 33, 16, 38, 1, 42, 51, 34, 53, 14, 28, 49, 30, 56, 36, 23, 43, 20, 38, 56, 22, 45, 28, 0, 62, 35, 26, 44, 11, 19, 52, 35, 44, 15, 30, 38, 10, 31, 40, 4, 46, 50, 20, 40, 27, 44, 51, 14, 56, 53, 19, 59, 7, 29, 41, 19, 35, 25, 8, 52, 22, 44, 13, 53, 50, 32, 61, 24, 56, 25, 63, 0, 45, 57, 33, 59, 16, 46, 4, 62, 50, 11, 60, 37, 52, 19, 55, 29, 37, 46, 13, 26, 48, 10, 50, 34, 21, 63, 26, 13, 42, 33, 22, 55, 35, 28, 43, 15, 24, 51, 27, 34, 46, 49, 58, 3, 52, 9, 57, 19, 48, 55, 3, 35, 12, 45, 24, 3 },
01199   { 41, 11, 56, 28, 18, 31, 22, 10, 37, 6, 47, 13, 3, 41, 9, 46, 0, 48, 29, 6, 34, 10, 55, 37, 20, 8, 49, 3, 41, 59, 14, 25, 0, 63, 19, 47, 27, 51, 17, 57, 23, 10, 61, 6, 54, 3, 38, 31, 0, 22, 34, 43, 20, 55, 31, 0, 49, 63, 29, 38, 3, 62, 28, 40, 0, 22, 14, 35, 2, 48, 15, 43, 23, 14, 3, 29, 49, 20, 39, 34, 0, 44, 29, 9, 15, 47, 5, 42, 0, 31, 58, 5, 31, 61, 23, 15, 0, 47, 19, 50, 24, 3, 59, 11, 44, 0, 31, 59, 6, 42, 17, 60, 0, 39, 20, 31, 43, 17, 29, 40, 12, 25, 60, 22, 52, 15, 63, 29 },
01200   { 20, 52, 8, 44, 62, 4, 59, 49, 17, 63, 21, 39, 60, 18, 52, 27, 33, 59, 14, 51, 59, 43, 24, 5, 51, 30, 57, 17, 32, 5, 37, 56, 48, 34, 42, 3, 60, 5, 36, 13, 43, 37, 18, 34, 25, 12, 59, 24, 47, 36, 11, 50, 3, 38, 9, 58, 16, 5, 43, 18, 47, 10, 37, 18, 59, 46, 29, 52, 40, 12, 34, 28, 56, 36, 53, 7, 43, 8, 24, 52, 26, 17, 56, 43, 24, 32, 63, 20, 57, 16, 22, 52, 36, 8, 41, 56, 29, 32, 54, 7, 35, 57, 14, 48, 20, 62, 13, 39, 53, 29, 8, 45, 13, 29, 7, 61, 14, 54, 6, 63, 38, 32, 18, 43, 2, 39, 6, 47 },
01201   { 0, 58, 23, 35, 13, 46, 12, 39, 0, 31, 55, 24, 5, 35, 15, 61, 17, 5, 39, 25, 18, 2, 50, 33, 41, 13, 39, 23, 62, 46, 29, 12, 22, 8, 56, 25, 20, 49, 32, 62, 0, 56, 11, 46, 63, 42, 9, 16, 55, 5, 60, 15, 62, 26, 45, 21, 36, 51, 13, 57, 31, 24, 55, 6, 35, 9, 57, 5, 20, 60, 7, 51, 5, 19, 40, 25, 61, 32, 56, 12, 36, 48, 21, 2, 58, 12, 39, 28, 9, 50, 40, 12, 44, 18, 25, 49, 6, 38, 11, 62, 18, 46, 30, 9, 40, 25, 49, 19, 10, 36, 55, 22, 33, 52, 41, 18, 37, 27, 49, 21, 2, 46, 7, 53, 33, 61, 27, 35 },
01202   { 41, 31, 5, 39, 51, 26, 33, 57, 27, 41, 9, 44, 54, 29, 48, 7, 44, 36, 57, 10, 31, 63, 16, 45, 11, 60, 1, 47, 7, 20, 43, 3, 58, 36, 13, 52, 39, 7, 15, 28, 22, 48, 30, 21, 1, 29, 49, 44, 27, 17, 40, 30, 24, 42, 12, 53, 33, 7, 47, 20, 1, 42, 11, 49, 25, 43, 17, 32, 45, 27, 41, 21, 31, 62, 11, 49, 2, 15, 42, 5, 63, 7, 41, 27, 49, 6, 54, 23, 46, 34, 2, 28, 54, 3, 59, 12, 46, 17, 42, 28, 40, 1, 37, 51, 5, 55, 2, 34, 47, 16, 3, 62, 47, 5, 23, 56, 1, 44, 12, 34, 51, 16, 57, 11, 25, 17, 54, 13 },
01203   { 60, 26, 55, 18, 3, 60, 20, 6, 52, 15, 50, 19, 32, 11, 23, 53, 26, 21, 1, 47, 42, 27, 8, 58, 21, 27, 53, 36, 26, 54, 31, 50, 17, 30, 45, 1, 29, 59, 44, 53, 41, 4, 35, 58, 51, 19, 32, 4, 52, 34, 48, 8, 51, 5, 56, 2, 25, 61, 27, 38, 54, 27, 62, 21, 51, 1, 39, 62, 10, 50, 1, 58, 13, 47, 38, 18, 35, 54, 22, 51, 30, 19, 59, 34, 14, 32, 44, 4, 60, 15, 52, 62, 20, 43, 30, 35, 21, 60, 4, 52, 12, 24, 61, 18, 30, 42, 23, 61, 25, 50, 27, 38, 11, 59, 12, 35, 50, 30, 59, 24, 8, 42, 28, 37, 48, 9, 44, 21 },
01204   { 10, 47, 15, 50, 30, 43, 8, 45, 29, 2, 36, 59, 1, 58, 41, 3, 63, 31, 54, 20, 13, 55, 35, 38, 4, 44, 15, 9, 61, 2, 14, 38, 61, 10, 23, 54, 18, 12, 24, 2, 14, 55, 16, 8, 38, 14, 41, 60, 10, 23, 1, 58, 32, 17, 28, 37, 41, 15, 3, 60, 15, 33, 4, 36, 16, 59, 28, 14, 23, 55, 37, 18, 44, 28, 2, 57, 30, 10, 27, 46, 14, 38, 3, 53, 21, 61, 17, 35, 10, 41, 26, 7, 33, 9, 57, 1, 53, 37, 26, 20, 56, 48, 9, 33, 58, 16, 37, 7, 45, 1, 57, 15, 32, 26, 42, 23, 7, 20, 4, 54, 31, 62, 22, 1, 59, 30, 4, 51 },
01205   { 36, 2, 38, 11, 24, 36, 54, 22, 62, 47, 25, 8, 28, 45, 16, 38, 12, 43, 9, 37, 49, 3, 23, 52, 18, 30, 50, 33, 19, 42, 49, 26, 6, 40, 47, 35, 63, 38, 50, 33, 60, 26, 36, 47, 24, 57, 6, 26, 39, 63, 19, 44, 14, 46, 61, 9, 50, 30, 45, 23, 10, 50, 44, 8, 31, 54, 6, 46, 36, 4, 30, 54, 8, 52, 22, 41, 4, 60, 40, 0, 58, 24, 45, 10, 37, 1, 48, 30, 56, 17, 38, 48, 24, 47, 19, 39, 14, 8, 45, 32, 2, 34, 27, 44, 4, 52, 11, 56, 31, 21, 40, 19, 44, 51, 2, 63, 46, 58, 36, 43, 14, 5, 50, 38, 14, 56, 40, 23 },
01206   { 61, 46, 32, 63, 54, 1, 14, 34, 12, 40, 18, 49, 37, 10, 61, 30, 51, 24, 60, 7, 29, 40, 62, 11, 46, 58, 6, 56, 24, 10, 34, 52, 21, 59, 16, 3, 27, 5, 20, 46, 9, 40, 7, 62, 2, 30, 53, 15, 48, 10, 28, 35, 54, 6, 21, 34, 18, 55, 7, 40, 57, 19, 26, 60, 41, 13, 24, 51, 19, 61, 9, 25, 34, 15, 63, 11, 45, 17, 20, 47, 33, 8, 31, 62, 43, 26, 53, 7, 24, 59, 0, 13, 55, 4, 62, 27, 51, 31, 63, 15, 58, 7, 54, 14, 46, 22, 28, 43, 12, 63, 8, 54, 5, 17, 39, 33, 15, 10, 27, 17, 47, 34, 19, 45, 27, 12, 33, 17 },
01207   { 5, 28, 21, 7, 17, 48, 42, 58, 23, 4, 63, 14, 55, 21, 34, 5, 19, 0, 45, 17, 52, 15, 25, 32, 0, 22, 40, 13, 45, 62, 18, 0, 43, 11, 33, 55, 30, 42, 57, 19, 51, 31, 22, 43, 18, 45, 34, 0, 43, 31, 56, 3, 23, 40, 59, 0, 44, 13, 48, 35, 2, 32, 46, 0, 21, 48, 35, 3, 40, 32, 43, 59, 0, 48, 33, 26, 53, 36, 55, 12, 51, 16, 55, 5, 18, 29, 11, 39, 51, 19, 45, 31, 42, 21, 35, 6, 22, 47, 10, 38, 23, 50, 20, 36, 0, 60, 38, 4, 50, 35, 48, 34, 24, 57, 9, 53, 28, 48, 61, 0, 56, 24, 53, 3, 63, 6, 42, 57 },
01208   { 13, 53, 45, 40, 58, 27, 6, 16, 38, 51, 33, 30, 43, 2, 47, 56, 40, 50, 33, 57, 27, 5, 47, 42, 60, 36, 16, 54, 28, 4, 37, 57, 28, 51, 22, 8, 45, 14, 6, 39, 0, 54, 11, 59, 28, 12, 50, 21, 61, 13, 19, 38, 49, 11, 25, 37, 58, 29, 22, 63, 14, 56, 12, 53, 30, 63, 9, 57, 26, 12, 47, 16, 23, 39, 50, 6, 31, 2, 25, 6, 28, 41, 36, 22, 50, 57, 42, 3, 34, 8, 28, 61, 11, 50, 16, 54, 41, 0, 55, 43, 5, 29, 41, 63, 25, 16, 53, 18, 26, 10, 21, 0, 61, 30, 41, 22, 3, 38, 20, 39, 29, 8, 41, 16, 36, 52, 22, 19 },
01209   { 55, 34, 0, 25, 10, 32, 56, 44, 28, 0, 57, 7, 26, 53, 23, 8, 13, 35, 22, 12, 36, 60, 20, 8, 14, 29, 48, 2, 41, 49, 23, 13, 39, 7, 48, 58, 25, 53, 34, 62, 28, 16, 48, 4, 37, 56, 27, 5, 36, 52, 46, 7, 62, 33, 52, 11, 17, 53, 5, 28, 41, 24, 38, 17, 5, 39, 20, 45, 15, 56, 5, 38, 60, 8, 14, 57, 21, 48, 62, 39, 59, 13, 1, 60, 9, 32, 16, 63, 44, 25, 52, 15, 36, 2, 60, 29, 12, 33, 25, 17, 59, 45, 13, 8, 49, 32, 6, 40, 59, 29, 45, 37, 13, 47, 6, 55, 30, 45, 9, 52, 13, 59, 25, 47, 32, 1, 49, 30 },
01210   { 9, 39, 14, 61, 49, 37, 3, 20, 50, 13, 41, 19, 46, 17, 38, 59, 28, 62, 4, 44, 54, 1, 34, 51, 55, 7, 63, 32, 21, 8, 56, 31, 62, 19, 36, 1, 41, 17, 24, 12, 42, 35, 25, 52, 20, 8, 44, 59, 25, 2, 22, 42, 16, 29, 4, 46, 20, 36, 43, 9, 51, 8, 49, 26, 58, 33, 54, 1, 37, 29, 52, 20, 27, 45, 19, 35, 42, 16, 10, 32, 20, 49, 46, 27, 40, 4, 47, 22, 13, 55, 4, 47, 26, 44, 23, 40, 58, 19, 48, 13, 31, 2, 57, 34, 42, 19, 61, 32, 14, 55, 5, 51, 26, 19, 58, 16, 49, 14, 62, 5, 33, 44, 21, 7, 60, 26, 11, 41 },
01211   { 62, 24, 47, 29, 8, 19, 53, 11, 60, 24, 32, 61, 4, 55, 31, 2, 49, 16, 39, 9, 31, 24, 43, 17, 26, 38, 11, 25, 58, 43, 12, 35, 3, 46, 15, 32, 63, 4, 49, 56, 2, 60, 10, 32, 63, 17, 39, 12, 55, 30, 57, 9, 48, 55, 39, 24, 60, 2, 58, 31, 19, 61, 34, 3, 42, 11, 22, 46, 7, 61, 10, 42, 3, 55, 32, 1, 58, 28, 44, 54, 4, 34, 23, 15, 56, 20, 37, 58, 6, 30, 38, 18, 63, 9, 32, 5, 51, 3, 62, 37, 52, 18, 39, 23, 3, 51, 9, 47, 1, 23, 43, 15, 60, 35, 11, 40, 1, 36, 31, 26, 57, 2, 37, 54, 18, 44, 58, 16 },
01212   { 5, 51, 3, 33, 43, 62, 21, 42, 35, 9, 48, 15, 36, 10, 22, 42, 20, 46, 26, 56, 50, 12, 59, 3, 48, 19, 45, 53, 1, 27, 47, 17, 52, 24, 56, 11, 51, 21, 37, 30, 20, 46, 14, 41, 1, 47, 33, 7, 41, 17, 35, 27, 20, 1, 14, 54, 26, 33, 18, 47, 1, 44, 14, 59, 16, 52, 28, 18, 49, 31, 25, 34, 63, 13, 51, 24, 9, 50, 3, 23, 38, 63, 7, 52, 29, 46, 11, 33, 50, 22, 57, 36, 1, 57, 49, 17, 39, 28, 9, 35, 6, 27, 53, 15, 55, 30, 24, 58, 36, 41, 11, 52, 32, 3, 44, 25, 62, 23, 51, 15, 42, 22, 50, 10, 39, 4, 31, 35 },
01213   { 46, 22, 57, 17, 12, 39, 26, 5, 31, 59, 1, 45, 27, 62, 52, 7, 58, 33, 6, 18, 39, 22, 33, 41, 57, 5, 35, 18, 40, 16, 60, 5, 29, 42, 7, 39, 27, 44, 9, 47, 8, 26, 54, 22, 51, 29, 24, 49, 15, 61, 4, 51, 31, 63, 43, 6, 50, 8, 39, 12, 53, 37, 23, 30, 40, 6, 62, 43, 14, 53, 2, 49, 7, 36, 17, 41, 61, 37, 18, 56, 11, 18, 44, 35, 2, 19, 61, 0, 41, 14, 8, 30, 43, 12, 24, 46, 14, 54, 42, 21, 44, 61, 10, 46, 37, 11, 44, 7, 18, 63, 20, 29, 7, 49, 28, 54, 8, 43, 4, 48, 18, 63, 12, 29, 48, 24, 59, 20 },
01214   { 13, 36, 28, 54, 35, 2, 56, 46, 16, 49, 22, 40, 11, 34, 14, 43, 29, 12, 63, 48, 2, 61, 7, 15, 28, 30, 50, 9, 61, 33, 38, 23, 54, 13, 61, 33, 3, 59, 16, 35, 58, 40, 5, 38, 13, 57, 3, 58, 37, 21, 45, 12, 39, 7, 35, 30, 13, 56, 22, 62, 27, 6, 55, 10, 48, 21, 33, 2, 38, 23, 40, 20, 44, 29, 59, 4, 26, 12, 33, 47, 28, 53, 31, 13, 59, 41, 27, 49, 26, 54, 45, 16, 53, 21, 35, 7, 59, 26, 11, 56, 1, 24, 33, 4, 28, 62, 21, 49, 31, 2, 56, 39, 24, 58, 13, 17, 37, 21, 56, 10, 38, 0, 34, 55, 15, 43, 1, 52 },
01215   { 42, 9, 50, 6, 25, 60, 14, 38, 10, 29, 53, 18, 57, 3, 25, 51, 0, 53, 25, 17, 29, 37, 52, 46, 0, 62, 14, 37, 4, 50, 10, 44, 0, 46, 20, 25, 50, 19, 55, 0, 23, 31, 62, 34, 11, 45, 19, 32, 0, 53, 10, 59, 23, 47, 18, 60, 42, 28, 37, 3, 50, 15, 35, 44, 0, 51, 27, 60, 9, 57, 16, 58, 11, 22, 46, 15, 53, 48, 7, 42, 0, 60, 5, 49, 24, 54, 9, 17, 39, 5, 34, 62, 3, 40, 60, 31, 0, 47, 29, 16, 49, 39, 59, 17, 50, 0, 40, 13, 53, 38, 16, 46, 0, 42, 34, 60, 2, 53, 29, 31, 58, 46, 27, 6, 61, 8, 37, 28 },
01216   { 0, 63, 21, 40, 45, 18, 51, 23, 63, 34, 6, 43, 28, 38, 55, 19, 40, 35, 8, 41, 54, 10, 21, 32, 39, 23, 53, 26, 55, 28, 22, 63, 30, 34, 9, 48, 6, 38, 29, 43, 49, 6, 18, 52, 27, 61, 9, 43, 28, 42, 33, 26, 56, 3, 51, 23, 0, 48, 16, 45, 32, 25, 63, 20, 57, 17, 42, 12, 35, 47, 5, 31, 39, 56, 6, 30, 34, 21, 61, 25, 14, 40, 22, 38, 15, 6, 36, 56, 20, 60, 25, 12, 51, 27, 10, 56, 42, 20, 36, 63, 32, 6, 21, 41, 12, 34, 60, 26, 5, 48, 27, 10, 62, 19, 6, 47, 39, 14, 45, 7, 24, 17, 41, 32, 23, 51, 19, 56 },
01217   { 45, 31, 15, 59, 4, 33, 7, 47, 0, 41, 13, 61, 4, 47, 9, 23, 60, 14, 57, 31, 4, 45, 59, 6, 58, 10, 44, 20, 8, 42, 15, 6, 55, 17, 58, 31, 53, 12, 61, 10, 15, 57, 43, 2, 23, 35, 48, 14, 54, 6, 18, 49, 15, 38, 11, 34, 62, 9, 21, 58, 11, 41, 4, 31, 38, 8, 29, 55, 19, 36, 27, 52, 0, 25, 50, 43, 1, 39, 8, 55, 35, 51, 10, 30, 45, 62, 29, 2, 46, 10, 32, 48, 18, 38, 5, 22, 33, 8, 51, 3, 14, 44, 54, 25, 57, 30, 18, 52, 33, 22, 59, 28, 36, 52, 32, 21, 26, 50, 5, 55, 35, 60, 14, 54, 4, 40, 16, 33 },
01218   { 27, 3, 49, 10, 30, 40, 55, 27, 57, 24, 52, 21, 32, 17, 60, 30, 5, 44, 27, 49, 19, 34, 13, 24, 43, 36, 3, 49, 31, 59, 37, 48, 26, 41, 2, 41, 14, 36, 21, 32, 40, 26, 13, 49, 55, 5, 16, 40, 25, 60, 36, 1, 63, 29, 17, 44, 25, 40, 52, 5, 29, 47, 54, 13, 46, 24, 60, 4, 51, 22, 63, 14, 45, 18, 12, 62, 17, 57, 19, 42, 3, 26, 58, 48, 1, 21, 40, 52, 23, 37, 44, 1, 29, 58, 43, 50, 15, 61, 19, 45, 58, 28, 7, 48, 2, 46, 8, 42, 3, 55, 8, 50, 12, 4, 55, 10, 63, 33, 20, 40, 11, 3, 46, 20, 48, 26, 61, 11 },
01219   { 44, 56, 24, 36, 53, 19, 12, 37, 16, 44, 7, 36, 49, 54, 11, 37, 48, 21, 15, 1, 62, 25, 47, 56, 16, 18, 51, 12, 40, 1, 24, 11, 52, 16, 23, 59, 28, 1, 45, 53, 4, 60, 37, 21, 39, 30, 63, 20, 52, 10, 30, 45, 8, 41, 54, 4, 57, 7, 34, 55, 36, 18, 23, 59, 2, 48, 11, 32, 44, 1, 41, 8, 33, 54, 38, 23, 30, 46, 6, 29, 62, 18, 32, 16, 55, 34, 14, 11, 61, 7, 55, 16, 53, 13, 23, 2, 55, 37, 26, 10, 33, 23, 36, 16, 38, 22, 56, 15, 24, 43, 35, 17, 44, 40, 25, 46, 16, 1, 57, 25, 49, 36, 28, 62, 9, 35, 7, 53 },
01220   { 17, 38, 8, 61, 1, 50, 26, 62, 3, 31, 56, 15, 1, 26, 40, 2, 34, 51, 56, 36, 42, 9, 38, 2, 29, 60, 32, 57, 19, 62, 34, 47, 4, 57, 39, 7, 44, 63, 24, 18, 46, 28, 8, 54, 1, 34, 7, 46, 3, 37, 50, 23, 57, 21, 13, 46, 31, 20, 43, 15, 1, 61, 8, 33, 37, 17, 56, 26, 15, 49, 24, 59, 28, 3, 56, 9, 52, 32, 13, 49, 10, 43, 5, 45, 8, 25, 59, 42, 28, 33, 19, 40, 8, 63, 35, 47, 25, 4, 40, 52, 1, 60, 12, 53, 63, 9, 29, 60, 37, 19, 1, 62, 31, 20, 58, 12, 41, 30, 43, 9, 18, 52, 22, 1, 39, 30, 58, 21 },
01221   { 13, 47, 29, 18, 43, 34, 5, 48, 20, 42, 10, 45, 30, 58, 20, 63, 24, 11, 6, 28, 54, 14, 22, 52, 41, 7, 26, 5, 45, 15, 53, 13, 35, 27, 18, 50, 12, 33, 5, 56, 10, 17, 45, 24, 59, 15, 50, 26, 56, 13, 19, 5, 32, 52, 27, 36, 2, 61, 12, 26, 49, 40, 27, 52, 13, 50, 6, 39, 61, 34, 10, 37, 48, 20, 41, 27, 2, 36, 59, 24, 54, 33, 63, 20, 38, 50, 3, 17, 52, 4, 58, 27, 45, 21, 32, 11, 48, 17, 57, 20, 46, 38, 25, 43, 4, 34, 51, 6, 13, 45, 57, 26, 6, 48, 2, 35, 53, 23, 61, 34, 59, 6, 42, 56, 13, 51, 2, 41 },
01222   { 32, 5, 55, 23, 58, 14, 22, 52, 29, 15, 61, 25, 51, 8, 43, 13, 53, 41, 46, 20, 3, 33, 63, 11, 48, 21, 54, 38, 28, 3, 30, 43, 21, 62, 9, 31, 55, 22, 51, 29, 37, 62, 32, 12, 42, 29, 41, 9, 33, 44, 62, 28, 43, 1, 59, 19, 48, 30, 51, 39, 24, 4, 58, 19, 42, 29, 22, 43, 3, 18, 53, 5, 13, 50, 16, 60, 45, 21, 7, 40, 15, 0, 26, 53, 13, 31, 43, 24, 47, 31, 15, 49, 2, 41, 6, 59, 29, 42, 9, 30, 14, 7, 49, 18, 31, 47, 20, 39, 49, 32, 11, 41, 54, 15, 61, 18, 7, 38, 4, 13, 44, 28, 15, 32, 45, 19, 27, 49 },
01223   { 63, 34, 11, 39, 2, 45, 37, 8, 59, 39, 33, 4, 36, 17, 48, 5, 29, 18, 32, 61, 39, 50, 5, 27, 35, 0, 46, 12, 22, 49, 60, 6, 54, 0, 38, 49, 2, 42, 15, 40, 0, 47, 20, 51, 3, 57, 18, 61, 22, 0, 39, 16, 55, 12, 35, 8, 41, 22, 6, 59, 16, 45, 10, 36, 0, 62, 9, 54, 30, 58, 21, 43, 63, 31, 7, 35, 12, 48, 58, 28, 47, 37, 41, 9, 57, 20, 61, 0, 36, 11, 57, 35, 23, 52, 37, 18, 0, 62, 22, 55, 35, 62, 27, 54, 0, 15, 61, 28, 2, 59, 22, 9, 37, 27, 33, 51, 29, 48, 19, 50, 25, 37, 10, 57, 5, 37, 60, 8 },
01224   { 20, 25, 46, 52, 31, 60, 12, 55, 0, 19, 11, 46, 62, 35, 23, 38, 57, 0, 55, 10, 16, 30, 58, 44, 17, 59, 29, 63, 42, 8, 36, 20, 33, 46, 16, 61, 25, 35, 8, 54, 26, 7, 58, 22, 34, 6, 47, 14, 53, 31, 48, 9, 37, 25, 49, 63, 16, 55, 45, 14, 34, 63, 21, 53, 25, 33, 46, 16, 35, 7, 46, 29, 0, 39, 25, 55, 22, 34, 18, 4, 56, 11, 23, 51, 28, 6, 39, 14, 62, 44, 19, 8, 60, 12, 56, 28, 50, 34, 39, 5, 51, 3, 41, 12, 57, 35, 10, 53, 25, 17, 52, 30, 47, 0, 43, 14, 5, 57, 31, 55, 0, 63, 47, 23, 54, 24, 14, 43 },
01225   { 0, 57, 16, 6, 26, 19, 35, 28, 49, 42, 54, 26, 21, 1, 59, 27, 9, 47, 26, 44, 50, 22, 13, 40, 8, 37, 10, 34, 17, 56, 25, 58, 13, 27, 44, 9, 20, 58, 31, 17, 60, 36, 10, 41, 53, 25, 36, 39, 4, 24, 58, 17, 60, 4, 22, 38, 10, 32, 0, 50, 31, 7, 28, 47, 12, 57, 5, 26, 52, 23, 14, 40, 57, 17, 47, 5, 53, 1, 44, 31, 19, 60, 46, 2, 35, 48, 30, 54, 22, 5, 51, 39, 25, 31, 4, 43, 14, 9, 45, 16, 24, 44, 19, 29, 40, 23, 44, 7, 38, 42, 4, 63, 12, 54, 23, 59, 22, 42, 8, 15, 40, 21, 8, 34, 3, 41, 30, 50 },
01226   { 39, 10, 48, 33, 41, 54, 5, 47, 23, 13, 32, 7, 52, 44, 14, 39, 58, 18, 35, 6, 37, 2, 60, 24, 55, 19, 53, 2, 51, 32, 1, 41, 51, 4, 40, 29, 47, 3, 52, 44, 13, 49, 28, 16, 1, 62, 11, 27, 52, 35, 5, 42, 29, 47, 14, 56, 28, 53, 26, 38, 9, 56, 40, 3, 38, 15, 41, 60, 1, 37, 50, 25, 11, 28, 61, 19, 42, 62, 10, 52, 39, 6, 32, 14, 58, 17, 7, 26, 42, 34, 27, 10, 54, 40, 20, 63, 26, 53, 21, 61, 32, 7, 59, 48, 3, 56, 18, 31, 58, 14, 49, 21, 36, 16, 45, 9, 36, 24, 62, 45, 27, 31, 53, 17, 49, 12, 62, 18 },
01227   { 28, 59, 21, 58, 2, 16, 38, 9, 62, 3, 56, 41, 10, 31, 50, 4, 32, 52, 12, 63, 23, 46, 33, 31, 4, 48, 25, 43, 14, 23, 47, 11, 22, 55, 14, 60, 23, 37, 11, 39, 23, 2, 45, 56, 31, 43, 19, 55, 16, 46, 21, 51, 11, 33, 44, 2, 41, 18, 5, 52, 23, 44, 17, 60, 27, 49, 11, 32, 44, 10, 54, 2, 56, 33, 8, 38, 13, 29, 36, 16, 24, 63, 27, 51, 21, 43, 56, 12, 49, 3, 59, 48, 1, 15, 46, 7, 36, 2, 47, 11, 50, 27, 37, 13, 33, 8, 51, 46, 1, 34, 28, 40, 3, 33, 60, 29, 47, 1, 35, 11, 59, 42, 2, 60, 26, 46, 6, 35 },
01228   { 4, 43, 9, 29, 36, 63, 24, 44, 20, 50, 30, 17, 60, 22, 16, 43, 25, 3, 42, 19, 51, 15, 8, 54, 42, 15, 61, 5, 39, 57, 18, 61, 31, 48, 34, 2, 50, 19, 57, 5, 63, 33, 19, 38, 13, 27, 48, 7, 32, 61, 2, 26, 58, 6, 24, 50, 13, 61, 42, 20, 62, 2, 35, 20, 51, 4, 62, 18, 23, 58, 20, 31, 43, 15, 51, 45, 26, 50, 4, 55, 45, 3, 35, 9, 38, 1, 32, 61, 20, 45, 17, 33, 24, 57, 29, 51, 22, 58, 38, 30, 15, 1, 54, 21, 63, 43, 26, 12, 24, 56, 8, 60, 50, 19, 5, 52, 13, 54, 17, 50, 4, 16, 36, 12, 32, 56, 22, 54 },
01229   { 51, 25, 40, 53, 12, 49, 15, 57, 34, 7, 38, 47, 2, 36, 55, 8, 61, 30, 56, 7, 28, 59, 48, 11, 27, 35, 21, 45, 28, 36, 9, 38, 6, 16, 24, 63, 10, 32, 28, 43, 21, 53, 5, 60, 8, 57, 3, 45, 11, 37, 15, 54, 40, 20, 62, 36, 27, 34, 11, 48, 30, 15, 54, 8, 30, 42, 22, 34, 48, 13, 35, 63, 4, 37, 22, 2, 59, 9, 41, 23, 13, 41, 49, 18, 59, 24, 40, 5, 37, 30, 9, 61, 44, 6, 37, 11, 33, 17, 5, 55, 41, 60, 23, 39, 17, 5, 30, 62, 41, 16, 46, 25, 11, 56, 39, 26, 20, 38, 29, 39, 22, 52, 44, 20, 48, 1, 38, 14 },
01230   { 15, 33, 2, 18, 44, 6, 27, 0, 32, 61, 25, 12, 58, 28, 40, 20, 47, 13, 34, 43, 38, 1, 23, 62, 40, 0, 51, 10, 63, 3, 52, 26, 44, 30, 45, 6, 41, 54, 0, 51, 12, 30, 46, 24, 49, 22, 40, 33, 63, 23, 43, 30, 9, 47, 0, 17, 54, 7, 57, 3, 37, 47, 24, 46, 13, 55, 7, 52, 2, 42, 6, 26, 49, 18, 60, 34, 16, 57, 33, 20, 61, 30, 8, 54, 14, 46, 12, 53, 16, 55, 38, 13, 22, 53, 18, 59, 46, 27, 43, 19, 32, 10, 45, 6, 49, 36, 52, 2, 20, 55, 6, 39, 32, 15, 44, 3, 58, 10, 63, 6, 56, 30, 7, 58, 9, 40, 19, 63 },
01231   { 10, 47, 61, 23, 55, 31, 52, 42, 17, 45, 4, 51, 27, 6, 15, 53, 0, 49, 26, 10, 56, 18, 36, 6, 20, 58, 32, 30, 13, 49, 19, 56, 0, 59, 12, 53, 27, 17, 38, 25, 48, 9, 15, 36, 14, 30, 59, 17, 0, 50, 8, 58, 18, 56, 31, 45, 21, 41, 29, 19, 60, 6, 32, 59, 0, 36, 29, 39, 19, 59, 46, 12, 55, 30, 10, 47, 24, 3, 28, 48, 0, 55, 44, 27, 33, 4, 63, 29, 49, 0, 26, 50, 34, 2, 42, 14, 0, 62, 9, 56, 3, 52, 28, 34, 58, 9, 20, 48, 37, 32, 22, 53, 0, 62, 27, 49, 34, 46, 21, 33, 41, 14, 25, 37, 53, 29, 31, 45 },
01232   { 56, 28, 7, 37, 11, 36, 20, 9, 54, 14, 39, 19, 34, 63, 45, 37, 24, 17, 60, 31, 21, 45, 53, 29, 47, 15, 7, 55, 40, 23, 34, 14, 42, 20, 37, 35, 15, 59, 7, 62, 34, 40, 59, 1, 51, 42, 10, 28, 54, 21, 35, 5, 38, 13, 36, 4, 59, 12, 39, 53, 15, 43, 9, 21, 39, 62, 16, 56, 25, 9, 32, 38, 0, 41, 14, 51, 40, 53, 43, 11, 37, 17, 5, 22, 57, 39, 19, 7, 42, 21, 60, 10, 31, 63, 25, 52, 30, 49, 36, 25, 48, 17, 61, 14, 22, 42, 29, 13, 60, 11, 47, 18, 35, 41, 7, 23, 4, 16, 51, 11, 0, 48, 61, 3, 17, 50, 5, 24 },
01233   { 0, 42, 21, 49, 60, 3, 57, 40, 29, 48, 23, 56, 42, 11, 22, 5, 59, 39, 4, 50, 3, 41, 12, 57, 25, 50, 44, 18, 4, 46, 7, 62, 33, 50, 4, 56, 21, 32, 43, 18, 3, 23, 55, 34, 20, 4, 53, 38, 12, 46, 29, 52, 25, 61, 23, 51, 26, 46, 1, 34, 25, 57, 28, 51, 26, 11, 50, 3, 44, 28, 53, 21, 57, 27, 62, 6, 31, 19, 8, 63, 26, 59, 36, 47, 15, 29, 50, 25, 35, 47, 18, 41, 4, 48, 8, 40, 12, 23, 6, 44, 13, 40, 1, 31, 55, 0, 61, 43, 4, 50, 26, 58, 9, 53, 24, 61, 42, 55, 31, 43, 57, 20, 34, 27, 43, 8, 59, 39 },
01234   { 18, 51, 30, 13, 26, 16, 46, 22, 2, 59, 8, 30, 1, 48, 33, 51, 29, 9, 46, 16, 62, 14, 33, 2, 38, 9, 27, 60, 37, 26, 53, 17, 28, 10, 24, 46, 2, 49, 8, 57, 29, 45, 6, 26, 62, 44, 18, 25, 61, 3, 42, 14, 49, 10, 43, 6, 17, 32, 63, 10, 49, 4, 40, 14, 45, 33, 22, 37, 12, 61, 5, 17, 43, 7, 23, 37, 15, 58, 49, 13, 39, 21, 10, 52, 1, 62, 9, 56, 12, 2, 58, 28, 36, 16, 56, 28, 56, 35, 20, 63, 24, 37, 51, 8, 45, 25, 16, 33, 27, 38, 2, 44, 13, 30, 17, 36, 12, 26, 5, 18, 28, 47, 13, 60, 23, 45, 13, 33 },
01235   { 55, 4, 62, 34, 52, 38, 7, 63, 32, 37, 13, 53, 25, 62, 18, 12, 55, 41, 27, 35, 24, 49, 31, 52, 17, 63, 34, 1, 56, 12, 41, 2, 48, 58, 39, 16, 61, 27, 41, 52, 13, 19, 50, 39, 11, 31, 57, 6, 32, 40, 20, 55, 1, 28, 33, 57, 48, 8, 37, 22, 44, 18, 53, 1, 61, 5, 54, 16, 47, 36, 50, 24, 55, 34, 48, 45, 1, 30, 33, 46, 2, 50, 32, 42, 25, 34, 43, 21, 38, 52, 23, 45, 14, 54, 21, 4, 44, 16, 53, 29, 10, 47, 19, 57, 12, 54, 39, 10, 51, 15, 63, 21, 57, 40, 51, 1, 48, 57, 37, 62, 2, 38, 9, 52, 1, 35, 58, 22 },
01236   { 36, 46, 10, 42, 1, 27, 43, 15, 50, 21, 45, 16, 41, 3, 35, 44, 20, 1, 57, 11, 55, 7, 43, 8, 22, 42, 13, 46, 21, 39, 31, 60, 22, 5, 29, 44, 11, 35, 20, 4, 36, 58, 32, 15, 47, 2, 36, 48, 16, 60, 8, 35, 44, 63, 16, 2, 40, 26, 55, 14, 58, 35, 24, 31, 19, 42, 31, 58, 1, 29, 10, 40, 2, 19, 12, 54, 22, 61, 7, 24, 56, 5, 28, 16, 54, 3, 15, 58, 6, 30, 8, 62, 1, 43, 31, 47, 7, 59, 1, 38, 58, 4, 34, 27, 38, 5, 31, 59, 7, 46, 30, 3, 34, 6, 28, 59, 20, 8, 32, 15, 53, 24, 55, 31, 19, 49, 11, 26 },
01237   { 2, 24, 16, 58, 19, 55, 5, 35, 10, 61, 4, 28, 57, 24, 58, 7, 31, 47, 22, 38, 19, 28, 61, 36, 54, 5, 59, 29, 6, 52, 15, 11, 43, 36, 8, 54, 52, 1, 62, 25, 47, 9, 1, 60, 28, 53, 24, 14, 46, 27, 51, 22, 12, 24, 38, 53, 20, 11, 51, 3, 29, 7, 48, 63, 8, 49, 9, 21, 52, 14, 63, 32, 46, 60, 35, 4, 41, 16, 52, 35, 18, 42, 59, 7, 36, 61, 45, 27, 33, 51, 19, 39, 34, 11, 61, 18, 33, 41, 28, 15, 54, 22, 42, 3, 49, 21, 47, 18, 36, 23, 55, 19, 48, 24, 45, 10, 33, 44, 50, 40, 7, 35, 15, 41, 63, 6, 40, 54 },
01238   { 62, 41, 32, 8, 47, 28, 60, 24, 44, 30, 38, 49, 9, 33, 14, 40, 50, 14, 60, 2, 54, 40, 0, 20, 25, 39, 16, 49, 24, 35, 57, 47, 19, 61, 33, 18, 23, 37, 13, 55, 31, 43, 22, 41, 17, 8, 42, 58, 0, 37, 5, 56, 31, 54, 7, 30, 60, 33, 42, 17, 59, 39, 12, 27, 38, 17, 35, 41, 27, 45, 20, 7, 25, 15, 29, 58, 27, 47, 11, 40, 14, 54, 23, 46, 19, 31, 11, 40, 13, 49, 5, 58, 24, 51, 26, 6, 50, 20, 49, 9, 32, 46, 17, 60, 14, 63, 24, 1, 57, 41, 9, 43, 14, 62, 16, 52, 3, 27, 14, 22, 61, 45, 4, 28, 9, 47, 29, 17 },
01239   { 5, 50, 12, 53, 38, 18, 11, 51, 0, 55, 17, 6, 47, 54, 19, 63, 5, 26, 34, 45, 13, 30, 47, 58, 10, 48, 32, 3, 62, 9, 26, 0, 25, 14, 50, 3, 47, 30, 42, 16, 6, 63, 12, 49, 33, 55, 21, 10, 34, 63, 18, 41, 3, 47, 19, 43, 0, 49, 8, 28, 46, 20, 52, 0, 56, 24, 60, 3, 59, 5, 39, 57, 48, 52, 9, 38, 3, 21, 26, 60, 0, 32, 12, 38, 4, 48, 53, 0, 60, 15, 29, 44, 18, 10, 38, 57, 13, 60, 2, 26, 62, 7, 50, 29, 35, 8, 40, 53, 28, 12, 60, 33, 38, 5, 37, 29, 60, 39, 56, 0, 30, 18, 50, 34, 59, 25, 14, 44 },
01240   { 20, 31, 60, 22, 3, 49, 33, 25, 40, 13, 34, 59, 22, 36, 0, 28, 37, 56, 8, 18, 51, 16, 4, 45, 27, 12, 53, 42, 18, 44, 51, 31, 55, 40, 28, 58, 7, 60, 10, 51, 27, 37, 24, 56, 5, 26, 44, 29, 50, 23, 45, 11, 34, 15, 59, 27, 13, 23, 62, 37, 4, 57, 15, 32, 42, 6, 47, 11, 30, 43, 23, 13, 0, 36, 18, 44, 63, 51, 37, 29, 49, 20, 57, 27, 62, 9, 24, 35, 23, 53, 37, 3, 42, 55, 0, 36, 23, 39, 31, 43, 17, 37, 24, 11, 52, 43, 19, 32, 5, 50, 26, 0, 56, 21, 54, 11, 19, 6, 47, 25, 59, 42, 12, 54, 21, 3, 38, 57 },
01241   { 48, 0, 35, 27, 44, 14, 59, 7, 57, 46, 26, 2, 42, 12, 52, 43, 10, 27, 53, 42, 32, 62, 37, 21, 34, 61, 7, 23, 36, 4, 38, 12, 41, 5, 17, 45, 22, 27, 39, 21, 59, 0, 45, 18, 39, 62, 3, 38, 14, 7, 54, 26, 61, 39, 9, 52, 45, 36, 18, 50, 10, 34, 44, 22, 50, 14, 36, 55, 17, 34, 53, 62, 33, 26, 56, 6, 31, 12, 6, 53, 9, 44, 2, 50, 20, 40, 55, 17, 47, 7, 26, 63, 22, 32, 48, 16, 46, 8, 52, 12, 57, 41, 0, 56, 25, 3, 61, 14, 45, 35, 18, 44, 12, 46, 23, 42, 32, 51, 35, 10, 17, 36, 23, 1, 45, 52, 32, 10 },
01242   { 37, 15, 43, 8, 63, 39, 21, 31, 16, 37, 19, 62, 30, 46, 17, 60, 21, 48, 1, 23, 6, 25, 11, 56, 1, 40, 30, 58, 15, 54, 21, 59, 9, 63, 35, 56, 11, 51, 2, 46, 34, 14, 53, 7, 30, 11, 51, 19, 60, 40, 30, 1, 24, 50, 20, 32, 3, 56, 5, 25, 31, 13, 61, 2, 29, 60, 25, 20, 51, 2, 27, 8, 18, 42, 10, 45, 21, 34, 43, 17, 62, 29, 41, 14, 34, 6, 30, 43, 2, 57, 33, 13, 45, 12, 27, 62, 4, 55, 21, 35, 5, 27, 45, 33, 16, 47, 30, 54, 22, 10, 51, 27, 63, 7, 49, 1, 58, 22, 15, 43, 53, 7, 57, 39, 27, 12, 61, 24 },
01243   { 56, 51, 26, 56, 19, 2, 41, 54, 5, 52, 9, 48, 6, 23, 39, 4, 32, 15, 63, 35, 59, 49, 43, 15, 52, 19, 50, 9, 46, 33, 1, 29, 48, 20, 32, 1, 38, 33, 19, 54, 9, 32, 24, 48, 58, 35, 16, 48, 4, 52, 13, 57, 33, 5, 45, 59, 15, 29, 41, 55, 47, 39, 23, 53, 9, 40, 4, 57, 10, 44, 48, 40, 50, 14, 61, 24, 55, 1, 59, 22, 33, 8, 51, 25, 58, 46, 11, 59, 20, 41, 17, 51, 6, 56, 35, 25, 42, 30, 15, 58, 48, 18, 61, 9, 58, 39, 13, 2, 37, 59, 40, 2, 31, 16, 34, 41, 8, 30, 62, 3, 29, 48, 33, 5, 63, 16, 41, 7 },
01244   { 22, 4, 46, 11, 33, 51, 29, 10, 62, 24, 43, 27, 15, 58, 50, 25, 54, 44, 9, 38, 18, 3, 29, 57, 32, 5, 26, 43, 17, 61, 24, 52, 8, 42, 23, 53, 15, 61, 7, 28, 57, 43, 4, 40, 20, 2, 43, 25, 32, 35, 21, 43, 17, 48, 10, 22, 38, 54, 11, 21, 1, 58, 16, 30, 48, 18, 46, 32, 38, 13, 22, 4, 59, 35, 2, 51, 30, 39, 15, 47, 4, 56, 13, 37, 1, 28, 16, 52, 32, 9, 61, 29, 38, 19, 3, 52, 10, 48, 1, 32, 11, 40, 20, 36, 6, 22, 49, 29, 55, 6, 20, 56, 36, 52, 19, 60, 26, 46, 18, 54, 40, 13, 20, 46, 35, 19, 49, 29 },
01245   { 61, 17, 34, 53, 23, 6, 48, 35, 20, 40, 1, 56, 36, 29, 11, 34, 7, 41, 14, 30, 55, 20, 46, 8, 24, 38, 63, 2, 37, 10, 45, 14, 34, 49, 6, 13, 44, 25, 49, 41, 21, 12, 61, 15, 54, 29, 63, 12, 56, 8, 49, 2, 62, 36, 28, 61, 0, 25, 41, 63, 35, 8, 44, 6, 37, 62, 7, 21, 63, 28, 55, 31, 16, 24, 41, 19, 9, 57, 27, 36, 18, 42, 31, 62, 22, 55, 38, 4, 27, 47, 1, 40, 14, 54, 43, 20, 60, 23, 38, 63, 25, 51, 2, 53, 26, 63, 10, 42, 17, 34, 47, 25, 13, 5, 44, 11, 55, 2, 38, 27, 6, 60, 52, 25, 9, 55, 1, 40 },
01246   { 8, 30, 58, 3, 42, 61, 17, 38, 13, 59, 32, 10, 54, 3, 51, 20, 61, 26, 57, 2, 46, 33, 12, 60, 41, 13, 48, 29, 55, 20, 39, 27, 57, 18, 62, 29, 55, 2, 31, 16, 37, 50, 26, 36, 6, 46, 9, 41, 27, 57, 23, 39, 26, 6, 51, 12, 31, 46, 7, 16, 27, 52, 19, 56, 26, 12, 33, 53, 1, 41, 8, 57, 46, 7, 54, 32, 47, 5, 49, 11, 60, 23, 5, 48, 10, 43, 19, 63, 35, 24, 49, 21, 59, 5, 31, 37, 14, 44, 7, 42, 6, 30, 46, 13, 44, 32, 19, 50, 4, 58, 8, 30, 62, 38, 28, 53, 21, 36, 13, 50, 21, 33, 15, 2, 44, 31, 14, 47 },
01247   { 37, 13, 39, 16, 28, 9, 57, 0, 25, 49, 21, 45, 18, 47, 12, 42, 0, 49, 22, 39, 16, 53, 25, 36, 0, 52, 22, 16, 6, 60, 4, 51, 0, 26, 37, 47, 10, 36, 63, 5, 57, 0, 18, 59, 23, 33, 51, 19, 0, 44, 15, 11, 54, 17, 42, 35, 53, 18, 58, 33, 49, 4, 34, 42, 0, 50, 43, 25, 16, 49, 34, 20, 37, 28, 12, 63, 16, 38, 25, 44, 0, 40, 52, 17, 35, 3, 50, 14, 8, 53, 11, 36, 25, 45, 9, 62, 0, 54, 28, 17, 50, 55, 15, 24, 57, 0, 53, 34, 23, 41, 15, 45, 0, 49, 16, 4, 48, 9, 63, 45, 0, 42, 58, 37, 61, 22, 54, 26 },
01248   { 0, 50, 21, 47, 54, 36, 27, 45, 52, 4, 34, 15, 63, 29, 37, 59, 17, 31, 6, 61, 28, 5, 48, 18, 59, 27, 34, 56, 44, 31, 35, 12, 41, 59, 16, 3, 40, 20, 50, 22, 30, 40, 52, 10, 45, 3, 59, 22, 37, 61, 29, 46, 31, 58, 2, 22, 9, 43, 3, 39, 14, 61, 24, 54, 15, 29, 11, 60, 39, 17, 5, 61, 0, 44, 50, 3, 31, 14, 58, 21, 54, 28, 15, 45, 60, 26, 33, 58, 44, 22, 60, 2, 57, 34, 49, 27, 18, 34, 21, 59, 29, 4, 36, 41, 8, 39, 28, 11, 62, 26, 53, 20, 35, 24, 59, 32, 29, 39, 24, 31, 57, 23, 11, 28, 5, 36, 11, 59 },
01249   { 44, 32, 63, 5, 20, 12, 41, 7, 30, 61, 42, 8, 39, 5, 33, 8, 24, 53, 45, 11, 37, 58, 7, 44, 10, 50, 3, 40, 8, 22, 53, 19, 46, 9, 33, 52, 24, 58, 8, 44, 13, 47, 8, 34, 38, 30, 14, 47, 7, 34, 4, 55, 9, 19, 40, 49, 56, 26, 60, 21, 30, 45, 10, 19, 40, 58, 23, 36, 3, 52, 45, 23, 54, 13, 22, 42, 53, 45, 7, 33, 10, 36, 57, 6, 29, 12, 41, 0, 30, 15, 41, 30, 17, 7, 16, 53, 40, 56, 2, 39, 12, 61, 10, 52, 31, 60, 16, 45, 1, 37, 7, 61, 40, 10, 43, 17, 58, 7, 54, 14, 4, 51, 39, 49, 18, 56, 42, 20 },
01250   { 14, 6, 24, 36, 56, 49, 22, 60, 18, 14, 23, 51, 26, 57, 21, 52, 41, 14, 35, 50, 19, 31, 40, 23, 33, 14, 63, 17, 32, 47, 7, 62, 23, 30, 56, 11, 42, 27, 14, 60, 35, 19, 28, 61, 17, 55, 25, 39, 53, 17, 42, 21, 38, 63, 25, 5, 14, 36, 12, 50, 1, 37, 59, 32, 2, 51, 6, 56, 27, 32, 11, 30, 38, 26, 60, 8, 26, 19, 62, 39, 50, 2, 21, 39, 53, 23, 56, 19, 49, 39, 5, 46, 55, 23, 42, 4, 31, 11, 47, 26, 45, 22, 48, 18, 21, 5, 48, 25, 57, 14, 47, 30, 3, 56, 12, 50, 1, 42, 19, 47, 35, 17, 8, 30, 45, 25, 4, 51 },
01251   { 28, 58, 43, 1, 31, 8, 33, 2, 44, 55, 32, 1, 60, 12, 46, 27, 4, 62, 23, 1, 56, 13, 62, 2, 54, 36, 25, 51, 1, 57, 26, 42, 3, 49, 17, 38, 1, 48, 31, 4, 54, 3, 50, 24, 1, 49, 5, 63, 13, 27, 52, 1, 48, 13, 45, 33, 52, 30, 46, 20, 55, 28, 6, 48, 24, 38, 20, 47, 14, 62, 48, 9, 58, 4, 36, 30, 56, 1, 34, 12, 18, 63, 25, 48, 4, 16, 37, 7, 62, 10, 52, 28, 13, 50, 36, 63, 24, 51, 15, 58, 8, 33, 1, 38, 56, 35, 42, 9, 33, 51, 22, 18, 48, 32, 27, 37, 23, 61, 33, 11, 59, 29, 62, 1, 53, 10, 60, 33 },
01252   { 12, 39, 17, 52, 26, 46, 53, 38, 25, 11, 48, 36, 16, 43, 2, 35, 55, 17, 39, 29, 43, 9, 28, 45, 20, 5, 46, 12, 42, 28, 13, 52, 36, 6, 60, 22, 54, 17, 62, 39, 25, 42, 15, 55, 44, 20, 31, 10, 35, 57, 24, 32, 29, 6, 59, 18, 7, 62, 3, 41, 10, 44, 16, 54, 13, 62, 31, 9, 41, 1, 21, 43, 18, 47, 15, 40, 11, 49, 28, 55, 46, 30, 8, 43, 32, 61, 28, 47, 25, 34, 21, 61, 32, 1, 20, 9, 46, 6, 35, 19, 41, 54, 27, 63, 14, 3, 51, 20, 62, 2, 38, 55, 8, 21, 63, 6, 46, 9, 26, 51, 3, 24, 43, 34, 16, 41, 18, 48 },
01253   { 62, 23, 55, 9, 15, 62, 19, 13, 58, 40, 6, 30, 54, 19, 50, 31, 10, 44, 6, 59, 21, 47, 51, 15, 60, 39, 30, 54, 21, 61, 19, 33, 14, 29, 43, 11, 34, 45, 7, 21, 10, 56, 36, 6, 38, 11, 58, 42, 2, 47, 11, 60, 50, 16, 41, 28, 38, 23, 47, 17, 35, 63, 22, 33, 42, 5, 45, 17, 53, 35, 25, 56, 33, 6, 51, 19, 60, 23, 43, 15, 5, 40, 58, 13, 51, 1, 45, 11, 54, 3, 43, 8, 37, 48, 59, 29, 39, 21, 61, 43, 3, 31, 10, 44, 24, 29, 60, 12, 28, 40, 11, 25, 43, 52, 14, 41, 16, 57, 44, 20, 40, 55, 12, 21, 57, 27, 35, 2 },
01254   { 37, 6, 31, 42, 40, 4, 29, 50, 0, 20, 63, 28, 9, 58, 14, 24, 63, 26, 48, 16, 34, 4, 32, 38, 23, 11, 58, 4, 37, 9, 45, 5, 63, 48, 26, 57, 2, 28, 32, 51, 46, 29, 13, 62, 27, 46, 28, 18, 50, 15, 40, 4, 19, 34, 54, 0, 53, 9, 26, 58, 28, 5, 49, 0, 57, 27, 19, 60, 29, 8, 59, 12, 37, 63, 24, 46, 3, 37, 6, 52, 26, 32, 20, 36, 9, 22, 59, 18, 35, 51, 14, 57, 17, 24, 12, 44, 56, 0, 30, 13, 59, 20, 49, 17, 54, 43, 6, 34, 46, 17, 58, 36, 0, 34, 29, 54, 25, 2, 36, 15, 60, 6, 37, 46, 4, 50, 9, 45 },
01255   { 19, 59, 48, 3, 24, 60, 44, 22, 34, 51, 15, 45, 41, 5, 33, 47, 0, 37, 12, 55, 25, 54, 8, 57, 0, 47, 18, 34, 49, 15, 55, 24, 40, 20, 8, 35, 53, 13, 41, 18, 0, 59, 22, 33, 4, 52, 8, 60, 24, 36, 31, 56, 45, 26, 10, 43, 15, 56, 36, 4, 51, 14, 39, 30, 12, 55, 36, 2, 39, 49, 4, 44, 17, 0, 32, 13, 53, 35, 59, 17, 62, 0, 55, 24, 52, 38, 31, 6, 42, 19, 29, 40, 4, 54, 33, 5, 16, 27, 52, 37, 23, 55, 7, 37, 0, 39, 23, 49, 4, 53, 31, 15, 59, 10, 50, 4, 60, 34, 48, 7, 31, 49, 27, 14, 62, 22, 53, 29 },
01256   { 46, 21, 14, 51, 36, 17, 7, 57, 10, 32, 3, 37, 22, 60, 39, 18, 56, 20, 42, 3, 36, 10, 44, 26, 41, 29, 53, 27, 2, 39, 30, 52, 0, 59, 15, 48, 23, 61, 6, 58, 37, 12, 40, 49, 16, 39, 20, 44, 0, 62, 8, 21, 3, 59, 23, 32, 49, 31, 12, 44, 22, 59, 18, 50, 24, 7, 43, 52, 15, 23, 41, 26, 51, 28, 55, 39, 21, 27, 10, 42, 12, 45, 27, 47, 3, 15, 63, 26, 55, 0, 60, 26, 45, 18, 62, 38, 58, 49, 8, 47, 4, 33, 46, 29, 57, 13, 56, 16, 59, 21, 5, 47, 23, 39, 18, 44, 13, 22, 28, 53, 19, 0, 58, 32, 41, 7, 26, 13 },
01257   { 0, 56, 34, 28, 11, 55, 31, 47, 26, 41, 56, 13, 53, 28, 11, 49, 7, 52, 32, 61, 50, 22, 63, 17, 13, 56, 7, 19, 43, 62, 10, 21, 37, 32, 43, 4, 38, 19, 44, 25, 31, 54, 5, 23, 61, 30, 53, 12, 35, 22, 43, 53, 37, 48, 7, 62, 20, 2, 61, 41, 8, 34, 47, 9, 63, 34, 28, 10, 55, 33, 14, 57, 7, 47, 9, 61, 4, 49, 31, 50, 21, 38, 8, 16, 57, 44, 33, 5, 49, 36, 12, 50, 7, 34, 10, 25, 2, 22, 36, 15, 26, 61, 18, 9, 22, 46, 32, 8, 27, 37, 44, 30, 55, 3, 62, 24, 38, 56, 5, 45, 38, 24, 43, 10, 19, 54, 39, 61 },
01258   { 41, 30, 8, 63, 43, 23, 38, 3, 62, 19, 8, 49, 25, 1, 58, 30, 23, 40, 9, 28, 18, 40, 6, 38, 49, 22, 35, 59, 8, 27, 50, 5, 56, 17, 11, 50, 30, 9, 55, 2, 51, 19, 34, 47, 9, 41, 6, 26, 48, 57, 14, 28, 17, 12, 39, 13, 37, 46, 25, 19, 54, 27, 1, 37, 16, 45, 20, 60, 1, 48, 20, 38, 31, 22, 42, 15, 19, 44, 1, 61, 6, 34, 56, 40, 29, 10, 20, 46, 13, 22, 41, 23, 59, 42, 30, 51, 45, 13, 63, 53, 42, 12, 51, 38, 62, 2, 26, 41, 50, 1, 61, 10, 19, 42, 31, 8, 49, 32, 12, 63, 9, 52, 16, 56, 36, 2, 31, 16 },
01259   { 52, 5, 47, 20, 1, 53, 12, 50, 16, 35, 43, 21, 33, 43, 16, 44, 3, 59, 14, 46, 1, 30, 60, 33, 2, 45, 12, 42, 31, 47, 14, 33, 46, 25, 55, 27, 60, 36, 16, 42, 14, 46, 26, 1, 55, 15, 63, 32, 2, 38, 5, 47, 33, 61, 30, 52, 4, 57, 6, 38, 11, 43, 61, 24, 52, 3, 31, 22, 42, 10, 62, 3, 59, 11, 35, 57, 33, 54, 24, 14, 29, 48, 18, 2, 60, 41, 53, 24, 32, 62, 3, 53, 15, 1, 55, 17, 32, 40, 6, 31, 1, 40, 28, 5, 35, 52, 19, 63, 13, 33, 17, 41, 52, 26, 15, 57, 1, 20, 42, 17, 35, 27, 48, 5, 25, 50, 44, 11 },
01260   { 35, 25, 38, 57, 33, 17, 40, 6, 59, 27, 54, 5, 61, 10, 52, 26, 36, 19, 51, 35, 57, 48, 11, 20, 54, 25, 61, 16, 1, 58, 24, 61, 3, 39, 7, 47, 1, 22, 49, 28, 63, 10, 58, 32, 17, 36, 45, 19, 51, 29, 59, 10, 50, 1, 23, 42, 18, 29, 51, 21, 56, 32, 14, 5, 40, 58, 47, 13, 54, 35, 29, 45, 18, 52, 26, 2, 38, 8, 46, 36, 58, 11, 52, 35, 17, 28, 1, 58, 9, 39, 17, 28, 37, 48, 20, 9, 57, 24, 50, 19, 58, 16, 48, 25, 43, 11, 35, 6, 45, 24, 56, 4, 36, 7, 47, 35, 52, 28, 59, 30, 2, 61, 21, 33, 63, 12, 18, 59 },
01261   { 3, 49, 15, 10, 27, 61, 25, 45, 30, 0, 14, 47, 31, 38, 17, 62, 7, 55, 27, 4, 15, 24, 42, 52, 10, 34, 5, 51, 36, 18, 41, 11, 35, 21, 62, 13, 33, 57, 8, 35, 5, 40, 21, 43, 52, 3, 24, 56, 11, 16, 33, 25, 41, 20, 55, 8, 60, 35, 15, 48, 2, 57, 30, 49, 18, 25, 6, 39, 17, 57, 7, 25, 43, 5, 49, 16, 62, 22, 55, 4, 25, 43, 23, 7, 50, 11, 37, 48, 14, 51, 33, 57, 7, 27, 39, 46, 4, 29, 11, 43, 34, 56, 7, 60, 20, 54, 30, 57, 22, 49, 9, 33, 54, 14, 63, 23, 6, 43, 10, 40, 50, 13, 44, 8, 38, 33, 46, 23 },
01262   { 55, 39, 22, 50, 44, 4, 36, 9, 52, 23, 37, 59, 21, 2, 46, 13, 31, 41, 11, 45, 62, 29, 6, 37, 19, 48, 30, 23, 44, 7, 53, 28, 54, 16, 41, 29, 44, 18, 52, 24, 60, 15, 48, 7, 27, 59, 9, 34, 42, 54, 7, 63, 4, 46, 31, 27, 45, 0, 40, 26, 34, 17, 37, 10, 53, 29, 36, 50, 2, 27, 51, 11, 61, 37, 23, 41, 30, 7, 18, 50, 39, 14, 63, 32, 45, 61, 19, 30, 25, 44, 2, 47, 23, 63, 11, 34, 59, 37, 60, 3, 22, 14, 44, 30, 15, 0, 47, 15, 3, 38, 61, 20, 27, 45, 11, 39, 51, 16, 55, 3, 22, 54, 29, 58, 1, 57, 6, 29 },
01263   { 9, 17, 60, 2, 34, 56, 20, 62, 39, 12, 49, 6, 29, 56, 34, 48, 0, 58, 22, 38, 18, 43, 56, 0, 63, 14, 55, 3, 59, 31, 15, 45, 0, 49, 6, 58, 3, 38, 12, 45, 0, 37, 29, 57, 13, 39, 30, 49, 0, 23, 44, 36, 16, 57, 13, 54, 11, 24, 63, 9, 53, 7, 62, 42, 0, 59, 15, 23, 63, 34, 40, 16, 32, 0, 53, 12, 48, 28, 59, 33, 0, 53, 9, 27, 3, 22, 54, 5, 56, 9, 61, 13, 42, 14, 52, 19, 0, 21, 47, 27, 53, 36, 3, 50, 39, 58, 25, 40, 53, 28, 12, 50, 0, 59, 32, 2, 21, 34, 26, 46, 37, 7, 18, 47, 24, 14, 53, 42 },
01264   { 61, 32, 13, 54, 29, 7, 46, 13, 28, 57, 18, 41, 53, 15, 9, 39, 24, 49, 33, 3, 53, 9, 26, 32, 40, 28, 46, 39, 25, 9, 56, 21, 63, 37, 26, 22, 51, 27, 17, 56, 31, 53, 4, 43, 22, 46, 12, 18, 60, 40, 20, 26, 50, 21, 39, 5, 49, 33, 16, 44, 22, 46, 20, 32, 24, 45, 8, 43, 12, 46, 4, 48, 56, 20, 29, 58, 3, 40, 10, 42, 31, 21, 47, 41, 56, 38, 15, 42, 36, 27, 20, 33, 55, 3, 26, 44, 31, 54, 12, 35, 9, 63, 28, 10, 21, 32, 9, 60, 17, 8, 43, 29, 40, 16, 36, 48, 60, 7, 57, 14, 62, 31, 42, 15, 36, 40, 20, 26 },
01265   { 0, 37, 47, 23, 41, 18, 32, 48, 1, 35, 8, 25, 4, 26, 63, 20, 54, 8, 16, 61, 35, 23, 51, 15, 58, 7, 12, 20, 50, 34, 42, 4, 38, 10, 32, 47, 8, 60, 41, 20, 9, 25, 50, 19, 62, 1, 37, 56, 28, 8, 53, 11, 3, 58, 34, 43, 19, 60, 38, 4, 58, 31, 3, 51, 11, 55, 38, 30, 21, 58, 19, 26, 9, 44, 36, 13, 46, 20, 62, 24, 13, 60, 5, 28, 12, 34, 7, 59, 0, 53, 45, 6, 38, 30, 50, 7, 62, 16, 41, 5, 46, 18, 55, 42, 51, 5, 45, 23, 34, 48, 19, 58, 5, 25, 54, 19, 13, 41, 28, 21, 0, 49, 10, 60, 4, 51, 9, 45 },
01266   { 19, 28, 6, 58, 10, 51, 4, 22, 55, 42, 60, 45, 34, 51, 42, 5, 30, 45, 27, 40, 13, 47, 4, 49, 21, 38, 60, 29, 2, 57, 17, 27, 52, 19, 61, 14, 30, 34, 2, 44, 63, 33, 11, 35, 16, 51, 25, 6, 14, 47, 31, 61, 37, 29, 18, 8, 52, 2, 28, 54, 13, 41, 15, 62, 35, 18, 2, 60, 6, 33, 41, 61, 31, 6, 56, 17, 34, 50, 6, 52, 44, 35, 16, 51, 59, 24, 48, 18, 31, 40, 16, 49, 21, 60, 17, 39, 10, 49, 32, 57, 24, 39, 1, 25, 18, 62, 37, 12, 56, 1, 37, 11, 52, 44, 9, 30, 47, 4, 51, 40, 55, 25, 34, 27, 56, 30, 32, 54 },
01267   { 63, 40, 49, 15, 43, 26, 63, 38, 16, 20, 30, 12, 57, 14, 19, 60, 36, 12, 59, 2, 57, 17, 42, 31, 1, 44, 16, 35, 47, 11, 32, 48, 13, 43, 1, 39, 51, 12, 57, 23, 6, 40, 53, 3, 55, 31, 39, 60, 35, 44, 5, 15, 45, 1, 62, 41, 26, 14, 47, 22, 36, 27, 50, 9, 26, 47, 52, 28, 54, 16, 1, 13, 51, 39, 23, 63, 1, 30, 15, 26, 2, 57, 19, 37, 1, 44, 21, 50, 13, 63, 8, 24, 56, 1, 35, 25, 58, 20, 2, 28, 14, 51, 33, 59, 13, 30, 4, 49, 31, 24, 63, 26, 33, 3, 58, 38, 62, 24, 32, 8, 17, 45, 5, 48, 18, 3, 43, 11 },
01268   { 21, 4, 24, 34, 59, 1, 37, 11, 53, 5, 47, 2, 22, 40, 32, 1, 24, 50, 21, 29, 38, 25, 63, 8, 55, 24, 53, 6, 62, 23, 59, 3, 54, 20, 58, 24, 5, 46, 15, 38, 48, 14, 27, 42, 23, 7, 46, 10, 17, 58, 25, 52, 23, 32, 49, 12, 55, 30, 40, 7, 59, 1, 56, 21, 39, 4, 23, 15, 37, 46, 55, 42, 21, 4, 48, 8, 45, 54, 37, 55, 32, 8, 46, 10, 30, 54, 4, 41, 25, 29, 36, 48, 11, 43, 14, 47, 5, 43, 53, 36, 61, 10, 45, 6, 41, 54, 27, 43, 16, 55, 6, 46, 18, 42, 23, 15, 1, 45, 12, 60, 37, 22, 62, 12, 39, 59, 16, 52 },
01269   { 47, 35, 56, 7, 19, 46, 31, 50, 33, 24, 61, 35, 50, 7, 53, 44, 55, 6, 46, 10, 52, 5, 21, 43, 36, 10, 18, 41, 26, 37, 8, 29, 40, 36, 9, 49, 34, 26, 61, 21, 7, 59, 18, 62, 29, 54, 20, 32, 51, 0, 40, 10, 55, 6, 20, 36, 9, 61, 5, 51, 44, 19, 33, 43, 13, 57, 40, 63, 8, 24, 29, 10, 60, 34, 27, 40, 25, 18, 10, 42, 21, 49, 26, 62, 38, 12, 33, 61, 5, 57, 2, 19, 54, 28, 62, 22, 38, 31, 16, 7, 22, 47, 29, 17, 35, 8, 20, 51, 2, 40, 22, 50, 13, 61, 28, 53, 35, 20, 56, 30, 2, 53, 14, 41, 23, 34, 8, 31 },
01270   { 12, 2, 42, 29, 52, 13, 21, 8, 55, 14, 41, 17, 28, 58, 23, 11, 17, 36, 31, 62, 17, 34, 50, 14, 28, 61, 33, 52, 2, 51, 17, 45, 7, 25, 62, 30, 18, 55, 0, 42, 30, 35, 45, 1, 12, 48, 3, 63, 21, 36, 30, 48, 19, 59, 43, 27, 46, 17, 34, 25, 12, 29, 53, 6, 48, 31, 11, 34, 49, 3, 36, 50, 19, 47, 14, 61, 11, 36, 58, 4, 60, 14, 39, 22, 6, 52, 15, 35, 17, 46, 31, 42, 9, 34, 3, 52, 12, 60, 26, 56, 40, 2, 53, 23, 57, 38, 62, 14, 36, 59, 10, 31, 39, 6, 49, 9, 41, 26, 5, 48, 43, 27, 33, 58, 1, 50, 25, 57 },
01271   { 61, 37, 15, 61, 3, 39, 58, 43, 26, 0, 44, 10, 47, 3, 37, 63, 28, 43, 13, 39, 3, 57, 30, 59, 0, 48, 5, 43, 13, 22, 60, 33, 55, 15, 42, 4, 52, 10, 45, 13, 54, 4, 24, 49, 37, 26, 41, 14, 42, 9, 61, 13, 38, 23, 3, 53, 0, 58, 21, 42, 63, 10, 17, 61, 25, 0, 58, 28, 17, 44, 57, 12, 27, 0, 55, 5, 52, 28, 23, 47, 29, 0, 43, 17, 58, 28, 47, 23, 55, 10, 58, 23, 51, 40, 18, 33, 45, 0, 49, 8, 32, 61, 19, 48, 0, 26, 7, 47, 29, 18, 44, 0, 56, 34, 20, 59, 15, 51, 37, 18, 10, 52, 7, 20, 46, 9, 38, 17 },
01272   { 6, 27, 48, 23, 45, 29, 5, 18, 38, 62, 27, 56, 20, 32, 15, 9, 48, 0, 54, 22, 45, 20, 7, 41, 23, 39, 19, 27, 58, 31, 44, 0, 12, 50, 23, 56, 20, 39, 32, 59, 16, 52, 33, 9, 57, 22, 6, 58, 28, 50, 24, 2, 56, 35, 16, 45, 32, 38, 15, 54, 2, 38, 46, 22, 35, 45, 20, 5, 52, 25, 7, 35, 59, 32, 22, 43, 38, 3, 51, 16, 34, 53, 32, 50, 3, 40, 8, 43, 0, 39, 27, 4, 14, 61, 8, 55, 15, 41, 20, 44, 27, 13, 39, 11, 46, 42, 54, 33, 4, 52, 23, 61, 14, 25, 43, 2, 33, 11, 63, 29, 61, 17, 40, 55, 22, 62, 28, 44 },
01273   { 20, 54, 8, 56, 35, 10, 63, 31, 52, 12, 48, 6, 59, 41, 52, 33, 19, 58, 25, 49, 11, 37, 47, 12, 54, 15, 56, 35, 7, 47, 16, 53, 28, 34, 5, 37, 28, 8, 48, 3, 28, 38, 18, 61, 16, 43, 53, 32, 4, 17, 47, 27, 44, 8, 63, 10, 25, 49, 6, 37, 24, 52, 32, 3, 50, 12, 41, 56, 38, 14, 62, 20, 40, 16, 53, 31, 18, 63, 41, 9, 59, 7, 13, 25, 57, 20, 63, 26, 53, 18, 48, 62, 30, 46, 21, 25, 58, 29, 36, 4, 55, 34, 6, 60, 31, 16, 21, 12, 58, 38, 9, 29, 47, 7, 52, 30, 57, 44, 22, 0, 35, 45, 3, 31, 14, 36, 0, 51 },
01274   { 42, 14, 33, 24, 16, 49, 40, 2, 22, 33, 16, 36, 25, 1, 21, 61, 38, 8, 33, 4, 62, 26, 29, 60, 6, 46, 30, 11, 63, 4, 36, 40, 19, 57, 46, 11, 41, 63, 22, 25, 58, 10, 46, 2, 34, 27, 11, 38, 56, 34, 12, 53, 18, 33, 41, 51, 13, 28, 60, 20, 47, 14, 29, 59, 16, 62, 8, 22, 32, 47, 9, 49, 2, 44, 7, 12, 45, 6, 20, 27, 45, 24, 62, 42, 36, 11, 33, 15, 37, 7, 32, 10, 37, 1, 35, 50, 6, 11, 63, 24, 52, 15, 50, 24, 3, 37, 56, 27, 34, 22, 49, 16, 36, 62, 17, 39, 4, 15, 54, 24, 50, 8, 58, 26, 49, 54, 11, 30 },
01275   { 4, 59, 41, 1, 53, 12, 25, 45, 59, 7, 51, 39, 54, 14, 46, 4, 27, 53, 16, 44, 18, 51, 1, 32, 25, 2, 50, 40, 20, 54, 24, 9, 62, 2, 27, 60, 1, 17, 36, 50, 6, 40, 30, 55, 41, 19, 49, 1, 21, 60, 40, 5, 62, 1, 22, 30, 57, 4, 43, 31, 1, 55, 40, 7, 27, 37, 30, 54, 1, 19, 42, 30, 56, 26, 62, 49, 24, 57, 37, 56, 2, 39, 16, 5, 30, 55, 3, 49, 60, 23, 56, 44, 17, 52, 13, 42, 28, 48, 18, 45, 9, 37, 21, 41, 58, 10, 48, 1, 63, 5, 41, 57, 2, 24, 12, 48, 27, 42, 32, 46, 13, 38, 19, 34, 5, 41, 25, 60 },
01276   { 39, 28, 21, 46, 32, 57, 36, 9, 19, 42, 4, 29, 11, 43, 30, 49, 13, 42, 35, 56, 9, 39, 15, 52, 36, 61, 18, 26, 45, 14, 31, 48, 21, 43, 14, 33, 49, 54, 14, 44, 21, 62, 13, 23, 8, 62, 15, 51, 44, 7, 30, 37, 20, 42, 56, 7, 39, 18, 50, 11, 61, 9, 19, 43, 57, 2, 48, 11, 39, 60, 28, 4, 37, 17, 35, 1, 33, 11, 31, 14, 48, 19, 35, 51, 46, 21, 44, 29, 12, 41, 2, 22, 58, 26, 54, 4, 59, 38, 2, 33, 57, 1, 63, 13, 28, 51, 15, 40, 18, 45, 8, 30, 43, 37, 54, 19, 8, 59, 21, 6, 60, 29, 55, 10, 63, 15, 47, 17 },
01277   { 3, 50, 10, 62, 18, 5, 27, 49, 60, 23, 55, 18, 62, 24, 56, 10, 59, 28, 2, 23, 34, 59, 43, 20, 10, 42, 8, 49, 1, 37, 57, 6, 51, 29, 53, 7, 23, 31, 5, 32, 51, 0, 35, 54, 45, 31, 5, 26, 36, 24, 55, 15, 48, 29, 14, 48, 26, 60, 21, 41, 36, 26, 50, 33, 14, 44, 17, 24, 52, 15, 46, 23, 54, 6, 47, 21, 60, 50, 4, 53, 29, 61, 8, 23, 1, 60, 19, 6, 53, 16, 47, 34, 6, 39, 16, 31, 12, 20, 53, 22, 30, 43, 25, 46, 35, 6, 44, 32, 53, 26, 55, 19, 11, 59, 5, 33, 51, 1, 35, 53, 25, 3, 42, 23, 44, 32, 7, 53 },
01278   { 22, 44, 37, 6, 26, 51, 38, 0, 34, 13, 31, 46, 3, 37, 6, 19, 40, 21, 47, 63, 12, 5, 29, 55, 22, 58, 34, 28, 60, 22, 11, 41, 17, 38, 9, 44, 59, 39, 56, 19, 11, 47, 25, 15, 3, 39, 57, 17, 61, 11, 46, 3, 58, 9, 54, 35, 2, 34, 8, 45, 15, 56, 5, 23, 53, 33, 63, 35, 4, 59, 10, 51, 13, 61, 29, 41, 15, 25, 43, 19, 40, 10, 54, 33, 41, 12, 38, 51, 31, 26, 61, 9, 30, 45, 24, 62, 49, 40, 10, 61, 14, 49, 5, 17, 54, 20, 60, 23, 3, 13, 35, 50, 32, 23, 46, 27, 38, 63, 16, 12, 39, 48, 18, 51, 1, 27, 56, 35 },
01279   { 63, 15, 30, 55, 43, 14, 57, 17, 53, 44, 7, 48, 26, 50, 32, 60, 0, 53, 14, 31, 50, 24, 46, 0, 38, 13, 4, 52, 16, 45, 30, 59, 0, 25, 55, 35, 16, 10, 26, 42, 58, 29, 60, 38, 50, 22, 28, 47, 0, 50, 28, 19, 33, 39, 11, 44, 16, 52, 24, 59, 3, 38, 27, 51, 0, 21, 7, 42, 26, 34, 21, 40, 33, 18, 39, 3, 54, 38, 8, 59, 0, 44, 27, 15, 58, 28, 57, 9, 43, 0, 36, 50, 20, 59, 8, 34, 0, 27, 47, 7, 36, 19, 56, 32, 0, 38, 11, 29, 62, 47, 6, 61, 0, 41, 14, 56, 10, 23, 45, 31, 57, 8, 36, 13, 58, 38, 11, 19 },
01280   { 0, 34, 12, 47, 21, 2, 40, 30, 11, 25, 61, 20, 40, 15, 35, 22, 45, 36, 7, 41, 17, 57, 9, 48, 32, 62, 44, 24, 35, 3, 54, 13, 33, 63, 19, 4, 48, 22, 62, 2, 37, 8, 33, 6, 20, 52, 9, 32, 43, 13, 39, 63, 25, 4, 49, 23, 62, 32, 9, 30, 48, 18, 63, 12, 46, 29, 58, 13, 48, 8, 57, 31, 0, 51, 9, 58, 12, 22, 47, 29, 35, 22, 49, 5, 46, 4, 34, 20, 63, 24, 56, 11, 41, 3, 51, 19, 56, 35, 17, 58, 28, 42, 9, 45, 59, 26, 51, 42, 17, 36, 25, 15, 53, 21, 44, 3, 30, 55, 5, 50, 21, 28, 61, 32, 6, 49, 28, 46 },
01281   { 58, 42, 60, 4, 31, 59, 22, 63, 35, 38, 9, 54, 1, 57, 8, 51, 16, 58, 27, 53, 3, 38, 30, 15, 27, 6, 19, 56, 10, 50, 21, 36, 47, 5, 43, 28, 51, 32, 13, 46, 18, 54, 16, 43, 63, 12, 36, 59, 22, 34, 5, 52, 17, 59, 27, 41, 0, 19, 55, 37, 13, 43, 6, 34, 41, 10, 36, 55, 19, 44, 3, 16, 58, 27, 49, 25, 32, 62, 17, 55, 13, 63, 18, 52, 25, 37, 17, 48, 13, 32, 5, 46, 28, 37, 14, 43, 25, 5, 51, 39, 3, 52, 33, 22, 8, 40, 12, 4, 57, 9, 46, 39, 28, 58, 13, 62, 17, 42, 19, 36, 0, 47, 16, 43, 24, 21, 54, 13 },
01282   { 25, 9, 23, 50, 36, 8, 45, 14, 3, 51, 16, 28, 44, 12, 42, 29, 4, 26, 10, 47, 22, 61, 18, 54, 51, 39, 46, 13, 41, 26, 58, 7, 18, 39, 12, 57, 15, 1, 52, 27, 41, 23, 48, 1, 27, 45, 18, 2, 57, 26, 55, 8, 43, 31, 6, 58, 14, 51, 40, 5, 61, 31, 24, 54, 17, 60, 22, 1, 39, 30, 53, 45, 36, 13, 43, 5, 45, 2, 37, 6, 34, 42, 2, 39, 10, 62, 7, 54, 40, 18, 60, 15, 52, 21, 63, 8, 55, 46, 15, 30, 23, 13, 62, 16, 50, 24, 58, 31, 48, 21, 34, 2, 49, 7, 31, 37, 26, 48, 9, 61, 40, 11, 52, 2, 60, 40, 4, 37 },
01283   { 52, 28, 39, 16, 54, 19, 29, 55, 42, 20, 58, 33, 24, 63, 18, 55, 39, 62, 43, 34, 12, 40, 6, 35, 2, 25, 8, 62, 34, 1, 31, 42, 61, 27, 53, 24, 40, 61, 34, 8, 59, 4, 30, 56, 40, 6, 53, 42, 10, 48, 16, 37, 12, 46, 21, 36, 47, 11, 28, 45, 22, 10, 57, 2, 49, 31, 14, 44, 61, 11, 25, 6, 23, 63, 18, 36, 28, 56, 20, 51, 11, 48, 27, 56, 32, 22, 45, 30, 2, 42, 27, 39, 1, 44, 23, 31, 38, 22, 11, 61, 43, 54, 4, 47, 35, 2, 44, 16, 28, 54, 12, 62, 18, 43, 10, 52, 1, 58, 33, 15, 29, 56, 20, 34, 9, 30, 48, 17 },
01284   { 46, 2, 56, 11, 41, 1, 49, 6, 27, 47, 2, 48, 5, 32, 37, 3, 13, 19, 32, 1, 55, 28, 60, 17, 43, 59, 32, 20, 49, 16, 55, 23, 14, 46, 2, 36, 6, 30, 20, 49, 12, 47, 35, 14, 21, 60, 29, 14, 35, 24, 46, 1, 56, 29, 53, 8, 33, 23, 56, 1, 35, 46, 20, 39, 26, 4, 53, 28, 17, 38, 60, 34, 48, 9, 55, 15, 46, 7, 41, 31, 60, 24, 16, 36, 1, 59, 19, 52, 35, 6, 55, 11, 59, 33, 7, 57, 4, 29, 48, 1, 19, 26, 37, 30, 18, 63, 37, 6, 59, 1, 40, 24, 56, 33, 46, 22, 35, 7, 24, 53, 39, 5, 26, 45, 55, 18, 62, 7 },
01285   { 20, 60, 29, 34, 20, 62, 33, 52, 10, 36, 13, 60, 41, 21, 50, 27, 56, 49, 8, 51, 21, 45, 11, 48, 8, 23, 53, 3, 29, 44, 5, 52, 9, 32, 50, 17, 43, 56, 3, 38, 24, 10, 62, 25, 51, 9, 33, 49, 61, 7, 30, 62, 22, 19, 2, 42, 63, 5, 49, 18, 60, 15, 52, 7, 43, 56, 23, 50, 5, 50, 2, 20, 41, 30, 1, 52, 22, 61, 14, 26, 3, 43, 53, 7, 47, 28, 11, 14, 23, 58, 33, 25, 47, 13, 50, 17, 40, 54, 34, 60, 41, 6, 59, 14, 50, 7, 25, 55, 20, 42, 51, 8, 27, 4, 16, 60, 28, 50, 44, 3, 22, 49, 63, 12, 33, 1, 43, 31 },
01286   { 36, 5, 46, 8, 44, 24, 13, 39, 25, 57, 31, 18, 8, 52, 10, 45, 6, 30, 36, 24, 63, 4, 33, 26, 57, 40, 15, 56, 37, 12, 40, 25, 37, 58, 11, 63, 21, 45, 16, 60, 31, 53, 18, 33, 3, 45, 23, 0, 20, 54, 40, 15, 50, 38, 60, 16, 25, 42, 29, 38, 7, 41, 25, 62, 18, 33, 8, 35, 42, 16, 32, 56, 12, 39, 59, 19, 34, 9, 49, 38, 57, 12, 21, 50, 14, 40, 61, 44, 50, 9, 49, 19, 3, 29, 35, 62, 12, 24, 7, 18, 52, 32, 10, 46, 21, 41, 32, 11, 36, 29, 14, 34, 60, 38, 54, 11, 41, 14, 19, 57, 32, 16, 7, 41, 51, 25, 14, 57 },
01287   { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 63, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 },
01288   { 23, 39, 61, 3, 37, 28, 48, 31, 0, 34, 51, 23, 2, 26, 58, 0, 53, 11, 46, 1, 57, 29, 52, 14, 37, 61, 21, 35, 2, 49, 7, 34, 47, 55, 4, 33, 54, 13, 58, 52, 19, 50, 22, 7, 13, 29, 36, 11, 51, 17, 60, 25, 55, 4, 34, 51, 0, 35, 20, 48, 32, 3, 51, 30, 59, 28, 40, 3, 46, 29, 54, 43, 7, 62, 47, 11, 39, 4, 23, 46, 55, 8, 63, 5, 25, 37, 18, 46, 21, 56, 31, 5, 36, 8, 45, 58, 26, 15, 2, 36, 47, 21, 29, 44, 25, 34, 3, 27, 43, 10, 52, 0, 45, 30, 24, 36, 43, 18, 34, 59, 0, 52, 61, 15, 44, 19, 30, 49 },
01289   { 0, 27, 12, 43, 54, 9, 22, 53, 21, 46, 15, 55, 29, 47, 20, 33, 39, 28, 59, 35, 9, 44, 5, 24, 47, 7, 52, 17, 56, 22, 30, 42, 14, 26, 45, 18, 49, 1, 24, 34, 11, 27, 55, 32, 61, 47, 2, 56, 6, 44, 13, 47, 36, 27, 58, 22, 16, 47, 40, 4, 57, 38, 21, 45, 16, 9, 56, 26, 11, 38, 0, 22, 36, 17, 33, 57, 16, 30, 62, 15, 35, 40, 20, 45, 59, 10, 54, 8, 63, 13, 52, 27, 22, 57, 28, 12, 32, 51, 55, 22, 63, 4, 16, 54, 12, 62, 45, 19, 58, 13, 32, 40, 20, 56, 7, 57, 9, 54, 6, 29, 42, 21, 8, 55, 35, 47, 6, 41 },
01290   { 56, 33, 58, 32, 19, 35, 42, 6, 59, 11, 38, 5, 49, 12, 62, 7, 52, 17, 5, 25, 54, 20, 61, 31, 54, 27, 41, 11, 44, 5, 59, 12, 36, 51, 10, 61, 28, 41, 48, 9, 43, 63, 5, 40, 20, 8, 49, 26, 34, 21, 58, 1, 18, 45, 7, 39, 61, 26, 8, 50, 23, 10, 63, 5, 55, 37, 19, 49, 52, 15, 59, 47, 13, 54, 1, 25, 42, 58, 10, 48, 3, 27, 50, 1, 17, 48, 34, 41, 16, 40, 2, 45, 10, 39, 17, 61, 5, 38, 19, 9, 41, 31, 60, 38, 5, 23, 36, 8, 30, 55, 24, 63, 12, 48, 14, 51, 31, 20, 45, 25, 12, 50, 32, 2, 28, 11, 62, 14 },
01291   { 44, 16, 7, 48, 1, 62, 16, 50, 27, 33, 61, 25, 17, 44, 31, 14, 22, 43, 32, 48, 18, 40, 8, 36, 3, 16, 33, 62, 23, 38, 25, 53, 2, 21, 41, 6, 22, 15, 59, 29, 16, 37, 26, 15, 52, 42, 23, 15, 54, 39, 10, 30, 53, 11, 49, 24, 2, 43, 55, 17, 34, 44, 15, 31, 24, 44, 2, 32, 7, 35, 25, 5, 40, 45, 29, 51, 6, 21, 37, 52, 24, 60, 13, 31, 53, 23, 2, 28, 49, 24, 31, 60, 20, 51, 1, 34, 48, 14, 59, 33, 50, 1, 18, 33, 48, 60, 17, 51, 39, 6, 38, 2, 35, 29, 40, 23, 1, 62, 15, 53, 37, 17, 46, 57, 40, 51, 24, 22 },
01292   { 5, 37, 52, 24, 45, 13, 40, 3, 45, 9, 19, 42, 56, 4, 37, 46, 56, 2, 63, 11, 51, 1, 49, 13, 59, 45, 39, 1, 48, 15, 58, 9, 46, 31, 54, 35, 57, 38, 3, 46, 56, 4, 47, 57, 1, 30, 38, 63, 3, 46, 28, 63, 41, 14, 33, 62, 19, 32, 13, 28, 61, 1, 53, 42, 11, 60, 22, 62, 27, 42, 61, 31, 19, 8, 61, 12, 32, 55, 2, 18, 33, 12, 43, 36, 9, 62, 30, 55, 6, 58, 35, 7, 43, 29, 54, 23, 43, 30, 3, 25, 11, 45, 52, 28, 7, 14, 42, 1, 22, 50, 16, 53, 19, 59, 4, 46, 33, 41, 4, 35, 58, 5, 26, 13, 20, 2, 34, 54 },
01293   { 30, 63, 21, 10, 26, 55, 29, 59, 23, 39, 53, 1, 36, 24, 59, 27, 10, 34, 23, 38, 30, 60, 22, 42, 28, 19, 9, 57, 30, 19, 43, 33, 13, 63, 3, 19, 11, 50, 31, 20, 14, 34, 10, 35, 17, 59, 7, 31, 19, 25, 50, 5, 20, 57, 29, 6, 52, 41, 4, 46, 20, 37, 26, 17, 49, 6, 39, 18, 53, 14, 3, 49, 57, 23, 34, 48, 14, 41, 28, 38, 56, 6, 58, 25, 39, 19, 43, 15, 37, 11, 47, 18, 53, 4, 37, 9, 62, 21, 53, 40, 57, 24, 13, 40, 56, 26, 47, 31, 59, 25, 45, 27, 10, 43, 21, 61, 13, 27, 48, 9, 23, 43, 31, 62, 38, 59, 9, 47 },
01294   { 25, 4, 40, 60, 34, 6, 18, 36, 8, 57, 12, 30, 49, 14, 6, 54, 41, 16, 50, 6, 43, 15, 34, 4, 53, 24, 50, 35, 4, 51, 7, 55, 28, 24, 39, 44, 60, 7, 25, 62, 42, 53, 24, 61, 28, 45, 52, 12, 48, 37, 9, 35, 43, 3, 37, 48, 12, 58, 30, 52, 9, 59, 6, 57, 33, 29, 48, 4, 37, 45, 20, 34, 10, 39, 0, 60, 22, 45, 8, 63, 21, 42, 14, 49, 3, 56, 11, 46, 21, 61, 0, 42, 25, 13, 63, 17, 36, 8, 46, 16, 6, 35, 63, 0, 21, 37, 4, 57, 9, 34, 5, 61, 48, 32, 8, 37, 54, 17, 56, 30, 60, 0, 50, 16, 7, 29, 42, 17 },
01295   { 32, 50, 15, 48, 2, 43, 52, 25, 47, 16, 32, 63, 21, 52, 40, 19, 0, 61, 29, 58, 20, 56, 26, 46, 12, 55, 6, 22, 62, 32, 17, 40, 0, 49, 34, 8, 27, 32, 48, 0, 21, 39, 5, 44, 12, 6, 22, 40, 0, 57, 16, 60, 23, 17, 54, 22, 36, 15, 24, 39, 19, 34, 47, 23, 0, 54, 13, 51, 24, 9, 55, 16, 52, 27, 44, 20, 4, 54, 26, 49, 0, 30, 46, 16, 29, 51, 34, 4, 52, 28, 33, 15, 57, 39, 26, 49, 0, 56, 27, 31, 48, 20, 43, 29, 53, 11, 46, 19, 41, 13, 55, 18, 0, 57, 26, 51, 2, 44, 6, 38, 14, 40, 22, 45, 36, 53, 3, 57 },
01296   { 44, 12, 37, 28, 22, 57, 11, 38, 0, 51, 9, 41, 4, 29, 11, 47, 33, 45, 12, 26, 3, 36, 9, 63, 31, 16, 38, 44, 14, 47, 25, 61, 20, 58, 15, 47, 17, 57, 13, 36, 9, 51, 18, 29, 50, 36, 54, 20, 61, 27, 32, 13, 53, 44, 9, 27, 0, 63, 45, 2, 56, 10, 14, 43, 41, 28, 58, 11, 35, 60, 30, 41, 6, 63, 11, 51, 37, 32, 15, 10, 35, 53, 5, 61, 22, 7, 26, 59, 23, 9, 44, 48, 21, 3, 51, 32, 24, 41, 12, 61, 2, 55, 9, 15, 35, 58, 28, 15, 62, 30, 37, 23, 42, 29, 11, 17, 35, 24, 63, 20, 52, 28, 8, 55, 11, 23, 47, 19 },
01297   { 0, 56, 8, 53, 14, 31, 61, 20, 55, 28, 62, 18, 35, 60, 25, 57, 7, 23, 39, 54, 47, 17, 43, 0, 40, 59, 29, 2, 56, 10, 37, 5, 43, 11, 29, 52, 1, 23, 54, 41, 59, 30, 55, 1, 62, 15, 33, 4, 43, 10, 47, 39, 1, 31, 40, 60, 49, 33, 7, 55, 26, 50, 31, 61, 8, 18, 21, 32, 44, 1, 25, 47, 18, 36, 30, 23, 59, 7, 40, 59, 27, 19, 38, 32, 44, 54, 40, 17, 38, 60, 27, 6, 35, 55, 10, 14, 44, 5, 50, 17, 38, 26, 42, 50, 18, 3, 44, 52, 2, 49, 7, 52, 15, 46, 62, 39, 55, 10, 31, 48, 3, 58, 33, 18, 61, 34, 13, 59 },
01298   { 39, 27, 63, 20, 35, 41, 4, 45, 26, 5, 38, 13, 44, 2, 50, 17, 37, 52, 2, 13, 28, 58, 24, 51, 21, 8, 34, 48, 27, 42, 18, 51, 31, 56, 5, 36, 38, 44, 4, 17, 26, 11, 38, 23, 42, 8, 56, 39, 24, 51, 5, 56, 21, 59, 14, 6, 18, 42, 22, 35, 16, 37, 3, 25, 39, 46, 63, 5, 50, 17, 58, 8, 55, 3, 50, 12, 43, 17, 47, 2, 51, 9, 62, 12, 1, 35, 13, 50, 1, 37, 12, 51, 19, 29, 46, 59, 22, 58, 33, 45, 22, 60, 10, 32, 61, 39, 8, 33, 25, 36, 20, 60, 38, 4, 21, 5, 28, 45, 12, 18, 42, 11, 49, 1, 27, 40, 6, 30 },
01299   { 24, 16, 42, 1, 50, 10, 48, 17, 33, 43, 24, 48, 21, 55, 31, 42, 10, 21, 63, 35, 49, 6, 33, 13, 41, 53, 10, 20, 60, 6, 53, 26, 12, 41, 22, 60, 14, 28, 63, 33, 49, 3, 45, 16, 48, 26, 14, 46, 18, 30, 35, 26, 8, 50, 29, 51, 25, 57, 12, 47, 53, 9, 62, 20, 54, 2, 36, 15, 40, 28, 33, 13, 38, 24, 46, 1, 29, 56, 33, 20, 44, 24, 41, 26, 57, 20, 63, 8, 30, 55, 5, 41, 62, 8, 34, 2, 37, 10, 19, 6, 37, 1, 53, 23, 5, 27, 58, 22, 43, 12, 50, 26, 9, 34, 54, 32, 49, 1, 59, 37, 22, 46, 25, 36, 51, 15, 54, 46 },
01300   { 52, 7, 45, 33, 26, 58, 14, 60, 7, 54, 3, 58, 8, 34, 14, 5, 59, 30, 18, 44, 8, 22, 48, 62, 3, 26, 55, 38, 23, 16, 39, 1, 62, 24, 49, 9, 53, 19, 46, 7, 19, 60, 31, 58, 2, 34, 53, 7, 59, 2, 62, 42, 46, 19, 36, 11, 44, 4, 38, 28, 1, 43, 32, 51, 12, 29, 56, 22, 52, 2, 62, 49, 22, 60, 14, 35, 63, 5, 25, 57, 14, 53, 4, 46, 18, 31, 42, 22, 47, 20, 58, 31, 16, 43, 23, 54, 30, 42, 52, 57, 29, 49, 30, 13, 45, 48, 16, 55, 6, 63, 1, 44, 14, 58, 19, 47, 15, 24, 51, 34, 6, 55, 5, 63, 20, 41, 21, 9 },
01301   { 30, 62, 18, 55, 5, 23, 39, 29, 49, 30, 15, 36, 28, 46, 60, 25, 39, 46, 4, 32, 61, 40, 15, 30, 36, 45, 14, 2, 49, 33, 57, 45, 18, 32, 3, 45, 30, 2, 35, 52, 40, 27, 13, 21, 38, 63, 20, 28, 37, 23, 16, 10, 13, 55, 2, 62, 21, 32, 60, 17, 58, 23, 5, 40, 16, 48, 7, 45, 10, 26, 43, 19, 6, 31, 52, 21, 39, 16, 48, 9, 37, 28, 36, 55, 7, 48, 3, 59, 15, 45, 25, 1, 53, 13, 47, 7, 62, 15, 4, 25, 12, 41, 18, 60, 38, 11, 34, 19, 39, 31, 29, 56, 23, 42, 3, 27, 60, 41, 8, 16, 61, 29, 43, 9, 32, 2, 60, 34 },
01302   { 3, 38, 13, 37, 52, 44, 2, 19, 12, 42, 63, 19, 40, 1, 20, 50, 12, 55, 15, 56, 27, 1, 54, 11, 57, 18, 32, 63, 44, 4, 29, 13, 37, 61, 35, 16, 42, 57, 12, 22, 6, 55, 43, 10, 50, 5, 44, 11, 48, 52, 34, 58, 28, 41, 38, 30, 7, 52, 11, 49, 30, 14, 45, 27, 59, 34, 21, 38, 32, 58, 11, 36, 56, 42, 9, 41, 3, 54, 31, 42, 0, 60, 16, 11, 39, 24, 52, 33, 6, 36, 10, 40, 32, 60, 26, 20, 39, 28, 47, 34, 63, 8, 54, 3, 24, 56, 0, 51, 13, 47, 16, 40, 7, 35, 52, 11, 36, 4, 57, 30, 39, 13, 18, 50, 58, 28, 12, 48 },
01303   { 57, 24, 49, 21, 10, 31, 61, 36, 56, 0, 22, 53, 11, 56, 32, 7, 36, 27, 41, 9, 46, 19, 34, 42, 25, 7, 50, 9, 28, 21, 54, 8, 50, 7, 27, 59, 10, 25, 48, 62, 37, 0, 33, 58, 25, 18, 32, 61, 0, 15, 45, 5, 50, 3, 23, 55, 47, 17, 40, 6, 60, 34, 53, 8, 41, 0, 61, 13, 54, 4, 46, 28, 0, 17, 48, 27, 58, 13, 23, 61, 33, 21, 50, 30, 62, 8, 14, 29, 56, 27, 61, 49, 17, 2, 44, 11, 51, 0, 59, 17, 40, 20, 32, 47, 36, 21, 42, 28, 60, 4, 54, 10, 59, 17, 30, 62, 21, 43, 26, 48, 0, 56, 36, 25, 8, 44, 39, 17 },
01304   { 10, 42, 4, 59, 27, 47, 8, 23, 51, 32, 45, 6, 37, 26, 48, 43, 62, 0, 21, 53, 38, 12, 51, 5, 60, 47, 24, 37, 59, 15, 35, 47, 22, 55, 0, 50, 21, 40, 6, 29, 15, 52, 24, 8, 41, 55, 13, 29, 40, 56, 24, 31, 19, 33, 61, 15, 0, 35, 24, 42, 21, 2, 19, 57, 24, 15, 30, 50, 20, 25, 40, 16, 57, 34, 61, 8, 29, 45, 6, 49, 11, 47, 2, 44, 19, 57, 38, 50, 12, 42, 21, 4, 35, 52, 28, 56, 23, 36, 13, 45, 4, 52, 27, 14, 6, 62, 9, 45, 21, 37, 25, 46, 33, 49, 0, 44, 7, 53, 13, 19, 53, 31, 3, 47, 15, 56, 22, 51 },
01305   { 35, 28, 53, 32, 1, 16, 54, 40, 9, 17, 25, 58, 14, 59, 3, 22, 16, 51, 31, 5, 23, 58, 28, 17, 35, 20, 0, 42, 11, 52, 3, 31, 41, 17, 43, 13, 32, 54, 18, 60, 32, 45, 17, 49, 2, 36, 51, 22, 7, 36, 9, 63, 48, 12, 46, 26, 43, 28, 63, 13, 48, 37, 51, 33, 5, 47, 55, 9, 42, 63, 7, 51, 24, 12, 37, 19, 55, 34, 18, 38, 15, 28, 54, 34, 5, 43, 22, 0, 48, 14, 54, 24, 58, 9, 38, 5, 32, 55, 21, 30, 49, 9, 59, 43, 30, 51, 35, 26, 7, 53, 2, 22, 14, 27, 57, 18, 38, 24, 33, 45, 10, 41, 20, 60, 37, 5, 32, 0 },
01306   { 63, 19, 15, 40, 62, 35, 14, 28, 46, 61, 4, 49, 35, 10, 29, 54, 33, 8, 45, 62, 37, 1, 43, 55, 10, 52, 61, 30, 19, 40, 25, 62, 11, 38, 27, 58, 36, 3, 46, 8, 39, 4, 62, 28, 47, 20, 4, 54, 47, 27, 43, 1, 21, 38, 8, 58, 10, 54, 4, 56, 9, 26, 12, 39, 60, 27, 18, 37, 1, 31, 35, 5, 45, 50, 2, 43, 26, 1, 59, 23, 56, 40, 7, 26, 58, 17, 32, 63, 25, 39, 7, 31, 45, 19, 63, 15, 48, 8, 37, 61, 16, 34, 1, 56, 18, 3, 15, 58, 49, 32, 63, 41, 55, 5, 40, 22, 50, 6, 59, 2, 63, 23, 52, 11, 26, 61, 44, 23 },
01307   { 11, 56, 46, 6, 22, 43, 58, 3, 34, 21, 38, 30, 18, 44, 52, 13, 41, 57, 17, 28, 14, 49, 25, 7, 33, 39, 26, 6, 56, 48, 1, 20, 56, 5, 46, 9, 19, 51, 30, 25, 56, 21, 35, 14, 57, 42, 16, 33, 10, 57, 17, 59, 41, 25, 53, 37, 20, 40, 30, 18, 31, 62, 44, 22, 3, 44, 11, 48, 23, 53, 18, 60, 29, 22, 62, 15, 53, 47, 10, 41, 3, 19, 52, 36, 13, 46, 10, 35, 3, 61, 41, 16, 1, 50, 26, 42, 18, 46, 2, 25, 54, 20, 39, 23, 47, 31, 41, 12, 38, 17, 8, 19, 31, 48, 12, 61, 9, 54, 29, 35, 15, 38, 6, 43, 34, 14, 7, 47 },
01308   { 39, 2, 33, 26, 53, 8, 18, 50, 41, 12, 53, 1, 63, 24, 19, 39, 2, 24, 47, 10, 60, 38, 19, 63, 48, 4, 15, 45, 32, 14, 60, 36, 29, 53, 23, 63, 34, 12, 61, 1, 43, 11, 53, 30, 1, 26, 60, 45, 23, 39, 3, 29, 12, 50, 4, 16, 51, 3, 45, 36, 50, 1, 16, 54, 35, 14, 57, 30, 58, 9, 46, 14, 41, 10, 32, 38, 4, 30, 21, 51, 32, 63, 25, 1, 60, 27, 53, 18, 51, 22, 28, 55, 34, 12, 40, 3, 60, 29, 57, 41, 6, 44, 11, 53, 8, 61, 24, 57, 1, 28, 44, 59, 36, 3, 34, 25, 41, 31, 16, 44, 22, 47, 28, 58, 1, 49, 54, 29 },
01309   { 58, 25, 50, 13, 38, 30, 60, 24, 6, 57, 27, 42, 9, 45, 6, 61, 30, 50, 4, 34, 29, 3, 46, 13, 22, 42, 58, 28, 9, 39, 23, 44, 7, 15, 44, 2, 40, 15, 47, 41, 23, 37, 7, 59, 38, 11, 34, 6, 62, 14, 52, 35, 55, 19, 32, 61, 33, 24, 57, 6, 22, 59, 29, 7, 49, 25, 40, 3, 17, 39, 27, 52, 0, 55, 16, 57, 24, 61, 36, 6, 29, 12, 48, 39, 20, 44, 6, 40, 33, 5, 48, 10, 57, 36, 22, 51, 33, 9, 24, 12, 62, 29, 50, 35, 14, 43, 5, 33, 47, 52, 13, 23, 10, 51, 56, 16, 46, 1, 49, 4, 61, 9, 52, 18, 31, 21, 36, 17 },
01310   { 19, 42, 9, 48, 2, 44, 11, 37, 48, 20, 33, 16, 55, 35, 49, 15, 37, 20, 59, 16, 53, 22, 56, 31, 50, 11, 34, 54, 16, 51, 4, 49, 33, 53, 21, 28, 56, 24, 31, 9, 52, 16, 48, 24, 44, 13, 51, 20, 31, 49, 18, 6, 34, 2, 44, 14, 47, 8, 15, 43, 13, 41, 33, 52, 20, 61, 7, 51, 34, 62, 4, 20, 36, 33, 43, 8, 46, 13, 53, 17, 45, 42, 9, 31, 52, 11, 30, 56, 13, 59, 17, 44, 27, 6, 62, 11, 43, 17, 49, 38, 26, 2, 16, 27, 58, 21, 54, 18, 26, 5, 35, 61, 43, 27, 7, 39, 14, 58, 37, 55, 20, 33, 13, 40, 62, 10, 55, 5 },
01311   { 51, 14, 61, 29, 59, 20, 55, 31, 0, 49, 11, 60, 3, 26, 22, 56, 0, 40, 12, 43, 41, 8, 36, 0, 17, 57, 24, 2, 46, 26, 61, 18, 0, 38, 12, 59, 6, 49, 3, 57, 19, 63, 5, 33, 18, 54, 28, 56, 0, 43, 26, 46, 63, 27, 56, 22, 27, 54, 38, 28, 63, 24, 10, 45, 0, 31, 42, 21, 12, 25, 44, 49, 59, 6, 26, 50, 3, 34, 27, 59, 0, 35, 62, 16, 4, 58, 47, 0, 43, 24, 37, 2, 54, 20, 46, 31, 0, 56, 34, 5, 55, 45, 60, 37, 0, 40, 10, 38, 63, 46, 15, 20, 0, 53, 21, 62, 30, 11, 24, 27, 40, 0, 57, 26, 3, 45, 27, 35 },
01312 };
01313 
01314 #else
01315 #define DM_WIDTH 8
01316 #define DM_WIDTH_SHIFT 3
01317 #define DM_HEIGHT 8
01318 static const unsigned char DM[8][8] =
01319 {
01320   { 0,  32, 8,  40, 2,  34, 10, 42 },
01321   { 48, 16, 56, 24, 50, 18, 58, 26 },
01322   { 12, 44, 4,  36, 14, 46, 6,  38 },
01323   { 60, 28, 52, 20, 62, 30, 54, 22 },
01324   { 3,  35, 11, 43, 1,  33, 9,  41 },
01325   { 51, 19, 59, 27, 49, 17, 57, 25 },
01326   { 15, 47, 7,  39, 13, 45, 5,  37 },
01327   { 63, 31, 55, 23, 61, 29, 53, 21 }
01328 };
01329 #endif
01330 
01331 static unsigned int *DM_565 = NULL;
01332 
01333 static void
01334 xlib_rgb_preprocess_dm_565 (void)
01335 {
01336   int i;
01337   unsigned int dith;
01338 
01339   if (DM_565 == NULL)
01340     {
01341       DM_565 = (unsigned int *) malloc(sizeof(unsigned int) * DM_WIDTH * DM_HEIGHT);
01342       for (i = 0; i < DM_WIDTH * DM_HEIGHT; i++)
01343        {
01344          dith = DM[0][i] >> 3;
01345          DM_565[i] = (dith << 20) | dith | (((7 - dith) >> 1) << 10);
01346 #ifdef VERBOSE
01347          printf ("%i %x %x\n", i, dith, DM_565[i]);
01348 #endif
01349        }
01350     }
01351 }
01352 
01353 static void
01354 xlib_rgb_convert_8_d666 (XImage *image,
01355                      int ax, int ay, int width, int height,
01356                      unsigned char *buf, int rowstride,
01357                      int x_align, int y_align, XlibRgbCmap *cmap)
01358 {
01359   int x, y;
01360   int bpl;
01361   unsigned char *obuf, *obptr;
01362   unsigned char *bptr, *bp2;
01363   int r, g, b;
01364   const unsigned char *dmp;
01365   int dith;
01366 
01367   bptr = buf;
01368   bpl = image->bytes_per_line;
01369   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01370   for (y = 0; y < height; y++)
01371     {
01372       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
01373       bp2 = bptr;
01374       obptr = obuf;
01375       for (x = 0; x < width; x++)
01376        {
01377          r = *bp2++;
01378          g = *bp2++;
01379          b = *bp2++;
01380          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 7;
01381          r = ((r * 5) + dith) >> 8;
01382          g = ((g * 5) + (262 - dith)) >> 8;
01383          b = ((b * 5) + dith) >> 8;
01384          obptr[0] = colorcube_d[(r << 6) | (g << 3) | b];
01385          obptr++;
01386        }
01387       bptr += rowstride;
01388       obuf += bpl;
01389     }
01390 }
01391 
01392 static void
01393 xlib_rgb_convert_8_d (XImage *image,
01394                    int ax, int ay, int width, int height,
01395                    unsigned char *buf, int rowstride,
01396                    int x_align, int y_align,
01397                    XlibRgbCmap *cmap)
01398 {
01399   int x, y;
01400   int bpl;
01401   unsigned char *obuf, *obptr;
01402   unsigned char *bptr, *bp2;
01403   int r, g, b;
01404   const unsigned char *dmp;
01405   int dith;
01406   int rs, gs, bs;
01407 
01408   bptr = buf;
01409   bpl = image->bytes_per_line;
01410   rs = image_info->nred_shades - 1;
01411   gs = image_info->ngreen_shades - 1;
01412   bs = image_info->nblue_shades - 1;
01413   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01414   for (y = 0; y < height; y++)
01415     {
01416       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
01417       bp2 = bptr;
01418       obptr = obuf;
01419       for (x = 0; x < width; x++)
01420        {
01421          r = *bp2++;
01422          g = *bp2++;
01423          b = *bp2++;
01424          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 7;
01425          r = ((r * rs) + dith) >> 8;
01426          g = ((g * gs) + (262 - dith)) >> 8;
01427          b = ((b * bs) + dith) >> 8;
01428          obptr[0] = colorcube_d[(r << 6) | (g << 3) | b];
01429          obptr++;
01430        }
01431       bptr += rowstride;
01432       obuf += bpl;
01433     }
01434 }
01435 
01436 static void
01437 xlib_rgb_convert_8_indexed (XImage *image,
01438                         int ax, int ay, int width, int height,
01439                         unsigned char *buf, int rowstride,
01440                         int x_align, int y_align, XlibRgbCmap *cmap)
01441 {
01442   int x, y;
01443   int bpl;
01444   unsigned char *obuf, *obptr;
01445   unsigned char *bptr, *bp2;
01446   unsigned char c;
01447   unsigned char *lut;
01448 
01449   lut = cmap->lut;
01450   bptr = buf;
01451   bpl = image->bytes_per_line;
01452   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01453   for (y = 0; y < height; y++)
01454     {
01455       bp2 = bptr;
01456       obptr = obuf;
01457       for (x = 0; x < width; x++)
01458        {
01459          c = *bp2++;
01460          obptr[0] = lut[c];
01461          obptr++;
01462        }
01463       bptr += rowstride;
01464       obuf += bpl;
01465     }
01466 }
01467 
01468 static void
01469 xlib_rgb_convert_gray8 (XImage *image,
01470                      int ax, int ay, int width, int height,
01471                      unsigned char *buf, int rowstride,
01472                      int x_align, int y_align, XlibRgbCmap *cmap)
01473 {
01474   int x, y;
01475   int bpl;
01476   unsigned char *obuf, *obptr;
01477   unsigned char *bptr, *bp2;
01478   int r, g, b;
01479 
01480   bptr = buf;
01481   bpl = image->bytes_per_line;
01482   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01483   for (y = 0; y < height; y++)
01484     {
01485       bp2 = bptr;
01486       obptr = obuf;
01487       for (x = 0; x < width; x++)
01488        {
01489          r = *bp2++;
01490          g = *bp2++;
01491          b = *bp2++;
01492          obptr[0] = (g + ((b + r) >> 1)) >> 1;
01493          obptr++;
01494        }
01495       bptr += rowstride;
01496       obuf += bpl;
01497     }
01498 }
01499 
01500 static void
01501 xlib_rgb_convert_gray8_gray (XImage *image,
01502                          int ax, int ay, int width, int height,
01503                          unsigned char *buf, int rowstride,
01504                          int x_align, int y_align, XlibRgbCmap *cmap)
01505 {
01506   int y;
01507   int bpl;
01508   unsigned char *obuf;
01509   unsigned char *bptr;
01510 
01511   bptr = buf;
01512   bpl = image->bytes_per_line;
01513   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
01514   for (y = 0; y < height; y++)
01515     {
01516       memcpy (obuf, bptr, (unsigned int)width);
01517       bptr += rowstride;
01518       obuf += bpl;
01519     }
01520 }
01521 
01522 #ifndef WORDS_BIGENDIAN
01523 #define HAIRY_CONVERT_565
01524 #endif
01525 
01526 #ifdef HAIRY_CONVERT_565
01527 /* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
01528    This assumes native byte ordering - what should really be done is to
01529    check whether static_image->byte_order is consistent with the _ENDIAN
01530    config flag, and if not, use a different function.
01531 
01532    This one is even faster than the one below - its inner loop loads 3
01533    words (i.e. 4 24-bit pixels), does a lot of shifting and masking,
01534    then writes 2 words. */
01535 static void
01536 xlib_rgb_convert_565 (XImage *image,
01537                    int ax, int ay, int width, int height,
01538                    unsigned char *buf, int rowstride,
01539                    int x_align, int y_align, XlibRgbCmap *cmap)
01540 {
01541   int x, y;
01542   unsigned char *obuf, *obptr;
01543   int bpl;
01544   unsigned char *bptr, *bp2;
01545   unsigned char r, g, b;
01546 
01547   bptr = buf;
01548   bpl = image->bytes_per_line;
01549   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01550   for (y = 0; y < height; y++)
01551     {
01552       bp2 = bptr;
01553       obptr = obuf;
01554       if (((unsigned long)obuf | (unsigned long) bp2) & 3)
01555        {
01556          for (x = 0; x < width; x++)
01557            {
01558              r = *bp2++;
01559              g = *bp2++;
01560              b = *bp2++;
01561              ((unsigned short *)obptr)[0] = ((r & 0xf8) << 8) |
01562               ((g & 0xfc) << 3) |
01563               (b >> 3);
01564              obptr += 2;
01565            }
01566        }
01567       else
01568        {
01569          for (x = 0; x < width - 3; x += 4)
01570            {
01571              unsigned int r1b0g0r0;
01572              unsigned int g2r2b1g1;
01573              unsigned int b3g3r3b2;
01574 
01575              r1b0g0r0 = ((unsigned int *)bp2)[0];
01576              g2r2b1g1 = ((unsigned int *)bp2)[1];
01577              b3g3r3b2 = ((unsigned int *)bp2)[2];
01578              ((unsigned int *)obptr)[0] =
01579               ((r1b0g0r0 & 0xf8) << 8) |
01580               ((r1b0g0r0 & 0xfc00) >> 5) |
01581               ((r1b0g0r0 & 0xf80000) >> 19) |
01582               (r1b0g0r0 & 0xf8000000) |
01583               ((g2r2b1g1 & 0xfc) << 19) |
01584               ((g2r2b1g1 & 0xf800) << 5);
01585              ((unsigned int *)obptr)[1] =
01586               ((g2r2b1g1 & 0xf80000) >> 8) |
01587               ((g2r2b1g1 & 0xfc000000) >> 21) |
01588               ((b3g3r3b2 & 0xf8) >> 3) |
01589               ((b3g3r3b2 & 0xf800) << 16) |
01590               ((b3g3r3b2 & 0xfc0000) << 3) |
01591               ((b3g3r3b2 & 0xf8000000) >> 11);
01592              bp2 += 12;
01593              obptr += 8;
01594            }
01595          for (; x < width; x++)
01596            {
01597              r = *bp2++;
01598              g = *bp2++;
01599              b = *bp2++;
01600              ((unsigned short *)obptr)[0] = ((r & 0xf8) << 8) |
01601               ((g & 0xfc) << 3) |
01602               (b >> 3);
01603              obptr += 2;
01604            }
01605        }
01606       bptr += rowstride;
01607       obuf += bpl;
01608     }
01609 }
01610 #else
01611 /* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
01612    This assumes native byte ordering - what should really be done is to
01613    check whether static_image->byte_order is consistent with the _ENDIAN
01614    config flag, and if not, use a different function.
01615 
01616    This routine is faster than the one included with Gtk 1.0 for a number
01617    of reasons:
01618 
01619    1. Shifting instead of lookup tables (less memory traffic).
01620 
01621    2. Much less register pressure, especially because shifts are
01622    in the code.
01623 
01624    3. A memcpy is avoided (i.e. the transfer function).
01625 
01626    4. On big-endian architectures, byte swapping is avoided.
01627 
01628    That said, it wouldn't be hard to make it even faster - just make an
01629    inner loop that reads 3 words (i.e. 4 24-bit pixels), does a lot of
01630    shifting and masking, then writes 2 words.
01631 */
01632 static void
01633 xlib_rgb_convert_565 (XImage *image,
01634                    int ax, int ay, int width, int height,
01635                    unsigned char *buf, int rowstride,
01636                    int x_align, int y_align, XlibRgbCmap *cmap)
01637 {
01638   int x, y;
01639   unsigned char *obuf;
01640   int bpl;
01641   unsigned char *bptr, *bp2;
01642   unsigned char r, g, b;
01643 
01644   bptr = buf;
01645   bpl = image->bytes_per_line;
01646   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01647   for (y = 0; y < height; y++)
01648     {
01649       bp2 = bptr;
01650       for (x = 0; x < width; x++)
01651        {
01652          r = *bp2++;
01653          g = *bp2++;
01654          b = *bp2++;
01655          ((unsigned short *)obuf)[x] = ((r & 0xf8) << 8) |
01656            ((g & 0xfc) << 3) |
01657            (b >> 3);
01658        }
01659       bptr += rowstride;
01660       obuf += bpl;
01661     }
01662 }
01663 #endif
01664 
01665 #ifdef HAIRY_CONVERT_565
01666 static void
01667 xlib_rgb_convert_565_gray (XImage *image,
01668                        int ax, int ay, int width, int height,
01669                        unsigned char *buf, int rowstride,
01670                        int x_align, int y_align, XlibRgbCmap *cmap)
01671 {
01672   int x, y;
01673   unsigned char *obuf, *obptr;
01674   int bpl;
01675   unsigned char *bptr, *bp2;
01676   unsigned char g;
01677 
01678   bptr = buf;
01679   bpl = image->bytes_per_line;
01680   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01681   for (y = 0; y < height; y++)
01682     {
01683       bp2 = bptr;
01684       obptr = obuf;
01685       if (((unsigned long)obuf | (unsigned long) bp2) & 3)
01686        {
01687          for (x = 0; x < width; x++)
01688            {
01689              g = *bp2++;
01690              ((unsigned short *)obptr)[0] = ((g & 0xf8) << 8) |
01691               ((g & 0xfc) << 3) |
01692               (g >> 3);
01693              obptr += 2;
01694            }
01695        }
01696       else
01697        {
01698          for (x = 0; x < width - 3; x += 4)
01699            {
01700              unsigned int g3g2g1g0;
01701 
01702              g3g2g1g0 = ((unsigned int *)bp2)[0];
01703              ((unsigned int *)obptr)[0] =
01704               ((g3g2g1g0 & 0xf8) << 8) |
01705               ((g3g2g1g0 & 0xfc) << 3) |
01706               ((g3g2g1g0 & 0xf8) >> 3) |
01707               (g3g2g1g0 & 0xf800) << 16 |
01708               ((g3g2g1g0 & 0xfc00) << 11) |
01709               ((g3g2g1g0 & 0xf800) << 5);
01710              ((unsigned int *)obptr)[1] =
01711               ((g3g2g1g0 & 0xf80000) >> 8) |
01712               ((g3g2g1g0 & 0xfc0000) >> 13) |
01713               ((g3g2g1g0 & 0xf80000) >> 19) |
01714               (g3g2g1g0 & 0xf8000000) |
01715               ((g3g2g1g0 & 0xfc000000) >> 5) |
01716               ((g3g2g1g0 & 0xf8000000) >> 11);
01717              bp2 += 4;
01718              obptr += 8;
01719            }
01720          for (; x < width; x++)
01721            {
01722              g = *bp2++;
01723              ((unsigned short *)obptr)[0] = ((g & 0xf8) << 8) |
01724               ((g & 0xfc) << 3) |
01725               (g >> 3);
01726              obptr += 2;
01727            }
01728        }
01729       bptr += rowstride;
01730       obuf += bpl;
01731     }
01732 }
01733 #else
01734 static void
01735 xlib_rgb_convert_565_gray (XImage *image,
01736                        int ax, int ay, int width, int height,
01737                        unsigned char *buf, int rowstride,
01738                        int x_align, int y_align, XlibRgbCmap *cmap)
01739 {
01740   int x, y;
01741   unsigned char *obuf;
01742   int bpl;
01743   unsigned char *bptr, *bp2;
01744   unsigned char g;
01745 
01746   bptr = buf;
01747   bpl = image->bytes_per_line;
01748   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01749   for (y = 0; y < height; y++)
01750     {
01751       bp2 = bptr;
01752       for (x = 0; x < width; x++)
01753        {
01754          g = *bp2++;
01755          ((unsigned short *)obuf)[x] = ((g & 0xf8) << 8) |
01756            ((g & 0xfc) << 3) |
01757            (g >> 3);
01758        }
01759       bptr += rowstride;
01760       obuf += bpl;
01761     }
01762 }
01763 #endif
01764 
01765 static void
01766 xlib_rgb_convert_565_br (XImage *image,
01767                       int ax, int ay, int width, int height,
01768                       unsigned char *buf, int rowstride,
01769                       int x_align, int y_align, XlibRgbCmap *cmap)
01770 {
01771   int x, y;
01772   unsigned char *obuf;
01773   int bpl;
01774   unsigned char *bptr, *bp2;
01775   unsigned char r, g, b;
01776 
01777   bptr = buf;
01778   bpl = image->bytes_per_line;
01779   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01780   for (y = 0; y < height; y++)
01781     {
01782       bp2 = bptr;
01783       for (x = 0; x < width; x++)
01784        {
01785          r = *bp2++;
01786          g = *bp2++;
01787          b = *bp2++;
01788          /* final word is:
01789             g4 g3 g2 b7 b6 b5 b4 b3  r7 r6 r5 r4 r3 g7 g6 g5
01790           */
01791          ((unsigned short *)obuf)[x] = (r & 0xf8) |
01792            ((g & 0xe0) >> 5) |
01793            ((g & 0x1c) << 11) |
01794            ((b & 0xf8) << 5);
01795        }
01796       bptr += rowstride;
01797       obuf += bpl;
01798     }
01799 }
01800 
01801 /* Thanks to Ray Lehtiniemi for a patch that resulted in a ~25% speedup
01802    in this mode. */
01803 #ifdef HAIRY_CONVERT_565
01804 static void
01805 xlib_rgb_convert_565_d (XImage *image,
01806                    int ax, int ay, int width, int height,
01807                    unsigned char *buf, int rowstride,
01808                    int x_align, int y_align, XlibRgbCmap *cmap)
01809 {
01810   /* Now this is what I'd call some highly tuned code! */
01811   int x, y;
01812   unsigned char *obuf, *obptr;
01813   int bpl;
01814   unsigned char *bptr, *bp2;
01815 
01816   width += x_align;
01817   height += y_align;
01818   
01819   bptr = buf;
01820   bpl = image->bytes_per_line;
01821   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01822   for (y = y_align; y < height; y++)
01823     {
01824       unsigned int *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT);
01825       bp2 = bptr;
01826       obptr = obuf;
01827       if (((unsigned long)obuf | (unsigned long) bp2) & 3)
01828        {
01829          for (x = x_align; x < width; x++)
01830            {
01831              int rgb = *bp2++ << 20;
01832              rgb += *bp2++ << 10;
01833              rgb += *bp2++;
01834              rgb += dmp[x & (DM_WIDTH - 1)];
01835              rgb += 0x10040100
01836               - ((rgb & 0x1e0001e0) >> 5)
01837               - ((rgb & 0x00070000) >> 6);
01838 
01839              ((unsigned short *)obptr)[0] =
01840               ((rgb & 0x0f800000) >> 12) |
01841               ((rgb & 0x0003f000) >> 7) |
01842               ((rgb & 0x000000f8) >> 3);
01843              obptr += 2;
01844            }
01845        }
01846       else
01847        {
01848          for (x = x_align; x < width - 3; x += 4)
01849            {
01850              unsigned int r1b0g0r0;
01851              unsigned int g2r2b1g1;
01852              unsigned int b3g3r3b2;
01853              unsigned int rgb02, rgb13;
01854 
01855              r1b0g0r0 = ((unsigned int *)bp2)[0];
01856              g2r2b1g1 = ((unsigned int *)bp2)[1];
01857              b3g3r3b2 = ((unsigned int *)bp2)[2];
01858              rgb02 =
01859               ((r1b0g0r0 & 0xff) << 20) +
01860               ((r1b0g0r0 & 0xff00) << 2) +
01861               ((r1b0g0r0 & 0xff0000) >> 16) +
01862               dmp[x & (DM_WIDTH - 1)];
01863              rgb02 += 0x10040100
01864               - ((rgb02 & 0x1e0001e0) >> 5)
01865               - ((rgb02 & 0x00070000) >> 6);
01866              rgb13 =
01867               ((r1b0g0r0 & 0xff000000) >> 4) +
01868               ((g2r2b1g1 & 0xff) << 10) +
01869               ((g2r2b1g1 & 0xff00) >> 8) +
01870               dmp[(x + 1) & (DM_WIDTH - 1)];
01871              rgb13 += 0x10040100
01872               - ((rgb13 & 0x1e0001e0) >> 5)
01873               - ((rgb13 & 0x00070000) >> 6);
01874              ((unsigned int *)obptr)[0] =
01875               ((rgb02 & 0x0f800000) >> 12) |
01876               ((rgb02 & 0x0003f000) >> 7) |
01877               ((rgb02 & 0x000000f8) >> 3) |
01878               ((rgb13 & 0x0f800000) << 4) |
01879               ((rgb13 & 0x0003f000) << 9) |
01880               ((rgb13 & 0x000000f8) << 13);
01881              rgb02 =
01882               ((g2r2b1g1 & 0xff0000) << 4) +
01883               ((g2r2b1g1 & 0xff000000) >> 14) +
01884               (b3g3r3b2 & 0xff) +
01885               dmp[(x + 2) & (DM_WIDTH - 1)];
01886              rgb02 += 0x10040100
01887               - ((rgb02 & 0x1e0001e0) >> 5)
01888               - ((rgb02 & 0x00070000) >> 6);
01889              rgb13 =
01890               ((b3g3r3b2 & 0xff00) << 12) +
01891               ((b3g3r3b2 & 0xff0000) >> 6) +
01892               ((b3g3r3b2 & 0xff000000) >> 24) +
01893               dmp[(x + 3) & (DM_WIDTH - 1)];
01894              rgb13 += 0x10040100
01895               - ((rgb13 & 0x1e0001e0) >> 5)
01896               - ((rgb13 & 0x00070000) >> 6);
01897              ((unsigned int *)obptr)[1] =
01898               ((rgb02 & 0x0f800000) >> 12) |
01899               ((rgb02 & 0x0003f000) >> 7) |
01900               ((rgb02 & 0x000000f8) >> 3) |
01901               ((rgb13 & 0x0f800000) << 4) |
01902               ((rgb13 & 0x0003f000) << 9) |
01903               ((rgb13 & 0x000000f8) << 13);
01904              bp2 += 12;
01905              obptr += 8;
01906            }
01907          for (; x < width; x++)
01908            {
01909              int rgb = *bp2++ << 20;
01910              rgb += *bp2++ << 10;
01911              rgb += *bp2++;
01912              rgb += dmp[x & (DM_WIDTH - 1)];
01913              rgb += 0x10040100
01914               - ((rgb & 0x1e0001e0) >> 5)
01915               - ((rgb & 0x00070000) >> 6);
01916 
01917              ((unsigned short *)obptr)[0] =
01918               ((rgb & 0x0f800000) >> 12) |
01919               ((rgb & 0x0003f000) >> 7) |
01920               ((rgb & 0x000000f8) >> 3);
01921              obptr += 2;
01922            }
01923        }
01924       bptr += rowstride;
01925       obuf += bpl;
01926     }
01927 }
01928 #else
01929 static void
01930 xlib_rgb_convert_565_d (XImage *image,
01931                        int ax, int ay, int width, int height,
01932                        unsigned char *buf, int rowstride,
01933                        int x_align, int y_align, XlibRgbCmap *cmap)
01934 {
01935   int x, y;
01936   unsigned char *obuf;
01937   int bpl;
01938   unsigned char *bptr;
01939 
01940   width += x_align;
01941   height += y_align;
01942   
01943   bptr = buf;
01944   bpl = image->bytes_per_line;
01945   obuf = ((unsigned char *)image->data) + ay * bpl + (ax - x_align) * 2;
01946 
01947   for (y = y_align; y < height; y++)
01948     {
01949       unsigned int *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT);
01950       unsigned char *bp2 = bptr;
01951 
01952       for (x = x_align; x < width; x++)
01953         {
01954           int rgb = *bp2++ << 20;
01955           rgb += *bp2++ << 10;
01956           rgb += *bp2++;
01957          rgb += dmp[x & (DM_WIDTH - 1)];
01958           rgb += 0x10040100
01959             - ((rgb & 0x1e0001e0) >> 5)
01960             - ((rgb & 0x00070000) >> 6);
01961 
01962           ((unsigned short *)obuf)[x] =
01963             ((rgb & 0x0f800000) >> 12) |
01964             ((rgb & 0x0003f000) >> 7) |
01965             ((rgb & 0x000000f8) >> 3);
01966         }
01967 
01968       bptr += rowstride;
01969       obuf += bpl;
01970     }
01971 }
01972 #endif
01973 
01974 static void
01975 xlib_rgb_convert_555 (XImage *image,
01976                    int ax, int ay, int width, int height,
01977                    unsigned char *buf, int rowstride,
01978                    int x_align, int y_align, XlibRgbCmap *cmap)
01979 {
01980   int x, y;
01981   unsigned char *obuf;
01982   int bpl;
01983   unsigned char *bptr, *bp2;
01984   unsigned char r, g, b;
01985 
01986   bptr = buf;
01987   bpl = image->bytes_per_line;
01988   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
01989   for (y = 0; y < height; y++)
01990     {
01991       bp2 = bptr;
01992       for (x = 0; x < width; x++)
01993        {
01994          r = *bp2++;
01995          g = *bp2++;
01996          b = *bp2++;
01997          ((unsigned short *)obuf)[x] = ((r & 0xf8) << 7) |
01998            ((g & 0xf8) << 2) |
01999            (b >> 3);
02000        }
02001       bptr += rowstride;
02002       obuf += bpl;
02003     }
02004 }
02005 
02006 static void
02007 xlib_rgb_convert_555_br (XImage *image,
02008                      int ax, int ay, int width, int height,
02009                      unsigned char *buf, int rowstride,
02010                      int x_align, int y_align, XlibRgbCmap *cmap)
02011 {
02012   int x, y;
02013   unsigned char *obuf;
02014   int bpl;
02015   unsigned char *bptr, *bp2;
02016   unsigned char r, g, b;
02017 
02018   bptr = buf;
02019   bpl = image->bytes_per_line;
02020   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 2;
02021   for (y = 0; y < height; y++)
02022     {
02023       bp2 = bptr;
02024       for (x = 0; x < width; x++)
02025        {
02026          r = *bp2++;
02027          g = *bp2++;
02028          b = *bp2++;
02029          /* final word is:
02030             g5 g4 g3 b7 b6 b5 b4 b3  0 r7 r6 r5 r4 r3 g7 g6
02031           */
02032          ((unsigned short *)obuf)[x] = ((r & 0xf8) >> 1) |
02033            ((g & 0xc0) >> 6) |
02034            ((g & 0x18) << 10) |
02035            ((b & 0xf8) << 5);
02036        }
02037       bptr += rowstride;
02038       obuf += bpl;
02039     }
02040 }
02041 
02042 static void
02043 xlib_rgb_convert_888_msb (XImage *image,
02044                       int ax, int ay, int width, int height,
02045                       unsigned char *buf, int rowstride,
02046                       int x_align, int y_align, XlibRgbCmap *cmap)
02047 {
02048   int y;
02049   unsigned char *obuf;
02050   int bpl;
02051   unsigned char *bptr;
02052 
02053   bptr = buf;
02054   bpl = image->bytes_per_line;
02055   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 3;
02056   for (y = 0; y < height; y++)
02057     {
02058       memcpy (obuf, bptr, (unsigned int)(width + width + width));
02059       bptr += rowstride;
02060       obuf += bpl;
02061     }
02062 }
02063 
02064 /* todo: optimize this */
02065 #ifndef WORDS_BIGENDIAN
02066 #define HAIRY_CONVERT_888
02067 #endif
02068 
02069 #ifdef HAIRY_CONVERT_888
02070 static void
02071 xlib_rgb_convert_888_lsb (XImage *image,
02072                        int ax, int ay, int width, int height,
02073                        unsigned char *buf, int rowstride,
02074                        int x_align, int y_align, XlibRgbCmap *cmap)
02075 {
02076   int x, y;
02077   unsigned char *obuf, *obptr;
02078   int bpl;
02079   unsigned char *bptr, *bp2;
02080   int r, g, b;
02081 
02082   bptr = buf;
02083   bpl = image->bytes_per_line;
02084   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 3;
02085   for (y = 0; y < height; y++)
02086     {
02087       bp2 = bptr;
02088       obptr = obuf;
02089       if (((unsigned long)obuf | (unsigned long) bp2) & 3)
02090        {
02091          for (x = 0; x < width; x++)
02092            {
02093              r = bp2[0];
02094              g = bp2[1];
02095              b = bp2[2];
02096              *obptr++ = b;
02097              *obptr++ = g;
02098              *obptr++ = r;
02099              bp2 += 3;
02100            }
02101        }
02102       else
02103        {
02104          for (x = 0; x < width - 3; x += 4)
02105            {
02106              unsigned int r1b0g0r0;
02107              unsigned int g2r2b1g1;
02108              unsigned int b3g3r3b2;
02109 
02110              r1b0g0r0 = ((unsigned int *)bp2)[0];
02111              g2r2b1g1 = ((unsigned int *)bp2)[1];
02112              b3g3r3b2 = ((unsigned int *)bp2)[2];
02113              ((unsigned int *)obptr)[0] =
02114               (r1b0g0r0 & 0xff00) |
02115               ((r1b0g0r0 & 0xff0000) >> 16) |
02116               (((g2r2b1g1 & 0xff00) | (r1b0g0r0 & 0xff)) << 16);
02117              ((unsigned int *)obptr)[1] =
02118               (g2r2b1g1 & 0xff0000ff) |
02119               ((r1b0g0r0 & 0xff000000) >> 16) |
02120               ((b3g3r3b2 & 0xff) << 16);
02121              ((unsigned int *)obptr)[2] =
02122               (((g2r2b1g1 & 0xff0000) | (b3g3r3b2 & 0xff000000)) >> 16) |
02123               ((b3g3r3b2 & 0xff00) << 16) |
02124               ((b3g3r3b2 & 0xff0000));
02125              bp2 += 12;
02126              obptr += 12;
02127            }
02128          for (; x < width; x++)
02129            {
02130              r = bp2[0];
02131              g = bp2[1];
02132              b = bp2[2];
02133              *obptr++ = b;
02134              *obptr++ = g;
02135              *obptr++ = r;
02136              bp2 += 3;
02137            }
02138        }
02139       bptr += rowstride;
02140       obuf += bpl;
02141     }
02142 }
02143 #else
02144 static void
02145 xlib_rgb_convert_888_lsb (XImage *image,
02146                       int ax, int ay, int width, int height,
02147                       unsigned char *buf, int rowstride,
02148                       int x_align, int y_align, XlibRgbCmap *cmap)
02149 {
02150   int x, y;
02151   unsigned char *obuf;
02152   int bpl;
02153   unsigned char *bptr, *bp2;
02154   int r, g, b;
02155 
02156   bptr = buf;
02157   bpl = image->bytes_per_line;
02158   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 3;
02159   for (y = 0; y < height; y++)
02160     {
02161       bp2 = bptr;
02162       for (x = 0; x < width; x++)
02163        {
02164          r = bp2[0];
02165          g = bp2[1];
02166          b = bp2[2];
02167          obuf[x * 3] = b;
02168          obuf[x * 3 + 1] = g;
02169          obuf[x * 3 + 2] = r;
02170          bp2 += 3;
02171        }
02172       bptr += rowstride;
02173       obuf += bpl;
02174     }
02175 }
02176 #endif
02177 
02178 /* convert 24-bit packed to 32-bit unpacked */
02179 /* todo: optimize this */
02180 static void
02181 xlib_rgb_convert_0888 (XImage *image,
02182                     int ax, int ay, int width, int height,
02183                     unsigned char *buf, int rowstride,
02184                     int x_align, int y_align, XlibRgbCmap *cmap)
02185 {
02186   int x, y;
02187   unsigned char *obuf;
02188   int bpl;
02189   unsigned char *bptr, *bp2;
02190   int r, g, b;
02191 
02192   bptr = buf;
02193   bpl = image->bytes_per_line;
02194   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 4;
02195   for (y = 0; y < height; y++)
02196     {
02197       bp2 = bptr;
02198       for (x = 0; x < width; x++)
02199        {
02200          r = bp2[0];
02201          g = bp2[1];
02202          b = bp2[2];
02203          ((unsigned int *)obuf)[x] = (r << 16) | (g << 8) | b;
02204          bp2 += 3;
02205        }
02206       bptr += rowstride;
02207       obuf += bpl;
02208     }
02209 }
02210 
02211 static void
02212 xlib_rgb_convert_0888_br (XImage *image,
02213                       int ax, int ay, int width, int height,
02214                       unsigned char *buf, int rowstride,
02215                       int x_align, int y_align, XlibRgbCmap *cmap)
02216 {
02217   int x, y;
02218   unsigned char *obuf;
02219   int bpl;
02220   unsigned char *bptr, *bp2;
02221   int r, g, b;
02222 
02223   bptr = buf;
02224   bpl = image->bytes_per_line;
02225   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 4;
02226   for (y = 0; y < height; y++)
02227     {
02228       bp2 = bptr;
02229       for (x = 0; x < width; x++)
02230        {
02231          r = bp2[0];
02232          g = bp2[1];
02233          b = bp2[2];
02234          ((unsigned int *)obuf)[x] = (b << 24) | (g << 16) | (r << 8);
02235          bp2 += 3;
02236        }
02237       bptr += rowstride;
02238       obuf += bpl;
02239     }
02240 }
02241 
02242 static void
02243 xlib_rgb_convert_8880_br (XImage *image,
02244                       int ax, int ay, int width, int height,
02245                       unsigned char *buf, int rowstride,
02246                       int x_align, int y_align, XlibRgbCmap *cmap)
02247 {
02248   int x, y;
02249   unsigned char *obuf;
02250   int bpl;
02251   unsigned char *bptr, *bp2;
02252   int r, g, b;
02253 
02254   bptr = buf;
02255   bpl = image->bytes_per_line;
02256   obuf = ((unsigned char *)image->data) + ay * bpl + ax * 4;
02257   for (y = 0; y < height; y++)
02258     {
02259       bp2 = bptr;
02260       for (x = 0; x < width; x++)
02261        {
02262          r = bp2[0];
02263          g = bp2[1];
02264          b = bp2[2];
02265          ((unsigned int *)obuf)[x] = (b << 16) | (g << 8) | r;
02266          bp2 += 3;
02267        }
02268       bptr += rowstride;
02269       obuf += bpl;
02270     }
02271 }
02272 
02273 /* Generic truecolor/directcolor conversion function. Slow, but these
02274    are oddball modes. */
02275 static void
02276 xlib_rgb_convert_truecolor_lsb (XImage *image,
02277                             int ax, int ay, int width, int height,
02278                             unsigned char *buf, int rowstride,
02279                             int x_align, int y_align,
02280                             XlibRgbCmap *cmap)
02281 {
02282   int x, y;
02283   unsigned char *obuf, *obptr;
02284   int bpl;
02285   unsigned char *bptr, *bp2;
02286   int r, g, b;
02287   int r_right, r_left;
02288   int g_right, g_left;
02289   int b_right, b_left;
02290   int bpp;
02291   unsigned int pixel;
02292   int i;
02293 
02294   r_right = 8 - image_info->red_prec;
02295   r_left = image_info->red_shift;
02296   g_right = 8 - image_info->green_prec;
02297   g_left = image_info->green_shift;
02298   b_right = 8 - image_info->blue_prec;
02299   b_left = image_info->blue_shift;
02300   bpp = image_info->bpp;
02301   bptr = buf;
02302   bpl = image->bytes_per_line;
02303   obuf = ((unsigned char *)image->data) + ay * bpl + ax * bpp;
02304   for (y = 0; y < height; y++)
02305     {
02306       obptr = obuf;
02307       bp2 = bptr;
02308       for (x = 0; x < width; x++)
02309        {
02310          r = bp2[0];
02311          g = bp2[1];
02312          b = bp2[2];
02313          pixel = ((r >> r_right) << r_left) |
02314            ((g >> g_right) << g_left) |
02315            ((b >> b_right) << b_left);
02316          for (i = 0; i < bpp; i++)
02317            {
02318              *obptr++ = pixel & 0xff;
02319              pixel >>= 8;
02320            }
02321          bp2 += 3;
02322        }
02323       bptr += rowstride;
02324       obuf += bpl;
02325     }
02326 }
02327 
02328 static void
02329 xlib_rgb_convert_truecolor_lsb_d (XImage *image,
02330                              int ax, int ay, int width, int height,
02331                              unsigned char *buf, int rowstride,
02332                              int x_align, int y_align,
02333                              XlibRgbCmap *cmap)
02334 {
02335   int x, y;
02336   unsigned char *obuf, *obptr;
02337   int bpl;
02338   unsigned char *bptr, *bp2;
02339   int r, g, b;
02340   int r_right, r_left, r_prec;
02341   int g_right, g_left, g_prec;
02342   int b_right, b_left, b_prec;
02343   int bpp;
02344   unsigned int pixel;
02345   int i;
02346   int dith;
02347   int r1, g1, b1;
02348   const unsigned char *dmp;
02349 
02350   r_right = 8 - image_info->red_prec;
02351   r_left = image_info->red_shift;
02352   r_prec = image_info->red_prec;
02353   g_right = 8 - image_info->green_prec;
02354   g_left = image_info->green_shift;
02355   g_prec = image_info->green_prec;
02356   b_right = 8 - image_info->blue_prec;
02357   b_left = image_info->blue_shift;
02358   b_prec = image_info->blue_prec;
02359   bpp = image_info->bpp;
02360   bptr = buf;
02361   bpl = image->bytes_per_line;
02362   obuf = ((unsigned char *)image->data) + ay * bpl + ax * bpp;
02363   for (y = 0; y < height; y++)
02364     {
02365       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
02366       obptr = obuf;
02367       bp2 = bptr;
02368       for (x = 0; x < width; x++)
02369        {
02370          r = bp2[0];
02371          g = bp2[1];
02372          b = bp2[2];
02373          dith = dmp[(x_align + x) & (DM_WIDTH - 1)] << 2;
02374          r1 = r + (dith >> r_prec);
02375          g1 = g + ((252 - dith) >> g_prec);
02376          b1 = b + (dith >> b_prec);
02377          pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) |
02378            (((g1 - (g1 >> g_prec)) >> g_right) << g_left) |
02379            (((b1 - (b1 >> b_prec)) >> b_right) << b_left);
02380          for (i = 0; i < bpp; i++)
02381            {
02382              *obptr++ = pixel & 0xff;
02383              pixel >>= 8;
02384            }
02385          bp2 += 3;
02386        }
02387       bptr += rowstride;
02388       obuf += bpl;
02389     }
02390 }
02391 
02392 static void
02393 xlib_rgb_convert_truecolor_msb (XImage *image,
02394                             int ax, int ay, int width, int height,
02395                             unsigned char *buf, int rowstride,
02396                             int x_align, int y_align,
02397                             XlibRgbCmap *cmap)
02398 {
02399   int x, y;
02400   unsigned char *obuf, *obptr;
02401   int bpl;
02402   unsigned char *bptr, *bp2;
02403   int r, g, b;
02404   int r_right, r_left;
02405   int g_right, g_left;
02406   int b_right, b_left;
02407   int bpp;
02408   unsigned int pixel;
02409   int shift, shift_init;
02410 
02411   r_right = 8 - image_info->red_prec;
02412   r_left = image_info->red_shift;
02413   g_right = 8 - image_info->green_prec;
02414   g_left = image_info->green_shift;
02415   b_right = 8 - image_info->blue_prec;
02416   b_left = image_info->blue_shift;
02417   bpp = image_info->bpp;
02418   bptr = buf;
02419   bpl = image->bytes_per_line;
02420   obuf = ((unsigned char *)image->data) + ay * bpl + ax * bpp;
02421   shift_init = (bpp - 1) << 3;
02422   for (y = 0; y < height; y++)
02423     {
02424       obptr = obuf;
02425       bp2 = bptr;
02426       for (x = 0; x < width; x++)
02427        {
02428          r = bp2[0];
02429          g = bp2[1];
02430          b = bp2[2];
02431          pixel = ((r >> r_right) << r_left) |
02432            ((g >> g_right) << g_left) |
02433            ((b >> b_right) << b_left);
02434          for (shift = shift_init; shift >= 0; shift -= 8)
02435            {
02436              *obptr++ = (pixel >> shift) & 0xff;
02437            }
02438          bp2 += 3;
02439        }
02440       bptr += rowstride;
02441       obuf += bpl;
02442     }
02443 }
02444 
02445 static void
02446 xlib_rgb_convert_truecolor_msb_d (XImage *image,
02447                              int ax, int ay, int width, int height,
02448                              unsigned char *buf, int rowstride,
02449                              int x_align, int y_align,
02450                              XlibRgbCmap *cmap)
02451 {
02452   int x, y;
02453   unsigned char *obuf, *obptr;
02454   int bpl;
02455   unsigned char *bptr, *bp2;
02456   int r, g, b;
02457   int r_right, r_left, r_prec;
02458   int g_right, g_left, g_prec;
02459   int b_right, b_left, b_prec;
02460   int bpp;
02461   unsigned int pixel;
02462   int shift, shift_init;
02463   int dith;
02464   int r1, g1, b1;
02465   const unsigned char *dmp;
02466 
02467   r_right = 8 - image_info->red_prec;
02468   r_left = image_info->red_shift;
02469   r_prec = image_info->red_prec;
02470   g_right = 8 - image_info->green_prec;
02471   g_left = image_info->green_shift;
02472   g_prec = image_info->green_prec;
02473   b_right = 8 - image_info->blue_prec;
02474   b_left = image_info->blue_shift;
02475   b_prec = image_info->blue_prec;
02476   bpp = image_info->bpp;
02477   bptr = buf;
02478   bpl = image->bytes_per_line;
02479   obuf = ((unsigned char *)image->data) + ay * bpl + ax * bpp;
02480   shift_init = (bpp - 1) << 3;
02481   for (y = 0; y < height; y++)
02482     {
02483       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
02484       obptr = obuf;
02485       bp2 = bptr;
02486       for (x = 0; x < width; x++)
02487        {
02488          r = bp2[0];
02489          g = bp2[1];
02490          b = bp2[2];
02491          dith = dmp[(x_align + x) & (DM_WIDTH - 1)] << 2;
02492          r1 = r + (dith >> r_prec);
02493          g1 = g + ((252 - dith) >> g_prec);
02494          b1 = b + (dith >> b_prec);
02495          pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) |
02496            (((g1 - (g1 >> g_prec)) >> g_right) << g_left) |
02497            (((b1 - (b1 >> b_prec)) >> b_right) << b_left);
02498          for (shift = shift_init; shift >= 0; shift -= 8)
02499            {
02500              *obptr++ = (pixel >> shift) & 0xff;
02501            }
02502          bp2 += 3;
02503        }
02504       bptr += rowstride;
02505       obuf += bpl;
02506     }
02507 }
02508 
02509 /* This actually works for depths from 3 to 7 */
02510 static void
02511 xlib_rgb_convert_4 (XImage *image,
02512                  int ax, int ay, int width, int height,
02513                  unsigned char *buf, int rowstride,
02514                  int x_align, int y_align,
02515                  XlibRgbCmap *cmap)
02516 {
02517   int x, y;
02518   int bpl;
02519   unsigned char *obuf, *obptr;
02520   unsigned char *bptr, *bp2;
02521   int r, g, b;
02522   const unsigned char *dmp;
02523   int dith;
02524 
02525   bptr = buf;
02526   bpl = image->bytes_per_line;
02527   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
02528   for (y = 0; y < height; y++)
02529     {
02530       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
02531       bp2 = bptr;
02532       obptr = obuf;
02533       for (x = 0; x < width; x += 1)
02534        {
02535          r = *bp2++;
02536          g = *bp2++;
02537          b = *bp2++;
02538          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
02539          obptr[0] = colorcube_d[(((r + dith) & 0x100) >> 2) |
02540                             (((g + 258 - dith) & 0x100) >> 5) |
02541                             (((b + dith) & 0x100) >> 8)];
02542          obptr++;
02543        }
02544       bptr += rowstride;
02545       obuf += bpl;
02546     }
02547 }
02548 
02549 /* This actually works for depths from 3 to 7 */
02550 static void
02551 xlib_rgb_convert_gray4 (XImage *image,
02552                      int ax, int ay, int width, int height,
02553                      unsigned char *buf, int rowstride,
02554                      int x_align, int y_align, XlibRgbCmap *cmap)
02555 {
02556   int x, y;
02557   int bpl;
02558   unsigned char *obuf, *obptr;
02559   unsigned char *bptr, *bp2;
02560   int r, g, b;
02561   int shift;
02562 
02563   bptr = buf;
02564   bpl = image->bytes_per_line;
02565   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
02566   shift = 9 - image_info->x_visual_info->depth;
02567   for (y = 0; y < height; y++)
02568     {
02569       bp2 = bptr;
02570       obptr = obuf;
02571       for (x = 0; x < width; x++)
02572        {
02573          r = *bp2++;
02574          g = *bp2++;
02575          b = *bp2++;
02576          obptr[0] = (g + ((b + r) >> 1)) >> shift;
02577          obptr++;
02578        }
02579       bptr += rowstride;
02580       obuf += bpl;
02581     }
02582 }
02583 
02584 static void
02585 xlib_rgb_convert_gray4_pack (XImage *image,
02586                          int ax, int ay, int width, int height,
02587                          unsigned char *buf, int rowstride,
02588                          int x_align, int y_align, XlibRgbCmap *cmap)
02589 {
02590   int x, y;
02591   int bpl;
02592   unsigned char *obuf, *obptr;
02593   unsigned char *bptr, *bp2;
02594   int r, g, b;
02595   int shift;
02596   unsigned char pix0, pix1;
02597   /* todo: this is hardcoded to big-endian. Make endian-agile. */
02598 
02599   bptr = buf;
02600   bpl = image->bytes_per_line;
02601   obuf = ((unsigned char *)image->data) + ay * bpl + (ax >> 1);
02602   shift = 9 - image_info->x_visual_info->depth;
02603   for (y = 0; y < height; y++)
02604     {
02605       bp2 = bptr;
02606       obptr = obuf;
02607       for (x = 0; x < width; x += 2)
02608        {
02609          r = *bp2++;
02610          g = *bp2++;
02611          b = *bp2++;
02612          pix0 = (g + ((b + r) >> 1)) >> shift;
02613          r = *bp2++;
02614          g = *bp2++;
02615          b = *bp2++;
02616          pix1 = (g + ((b + r) >> 1)) >> shift;
02617          obptr[0] = (pix0 << 4) | pix1;
02618          obptr++;
02619        }
02620       if (width & 1)
02621        {
02622          r = *bp2++;
02623          g = *bp2++;
02624          b = *bp2++;
02625          pix0 = (g + ((b + r) >> 1)) >> shift;
02626          obptr[0] = (pix0 << 4);
02627        }
02628       bptr += rowstride;
02629       obuf += bpl;
02630     }
02631 }
02632 
02633 /* This actually works for depths from 3 to 7 */
02634 static void
02635 xlib_rgb_convert_gray4_d (XImage *image,
02636                      int ax, int ay, int width, int height,
02637                      unsigned char *buf, int rowstride,
02638                      int x_align, int y_align, XlibRgbCmap *cmap)
02639 {
02640   int x, y;
02641   int bpl;
02642   unsigned char *obuf, *obptr;
02643   unsigned char *bptr, *bp2;
02644   int r, g, b;
02645   const unsigned char *dmp;
02646   int prec, right;
02647   int gray;
02648 
02649   bptr = buf;
02650   bpl = image->bytes_per_line;
02651   obuf = ((unsigned char *)image->data) + ay * bpl + ax;
02652   prec = image_info->x_visual_info->depth;
02653   right = 8 - prec;
02654   for (y = 0; y < height; y++)
02655     {
02656       bp2 = bptr;
02657       obptr = obuf;
02658       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
02659       for (x = 0; x < width; x++)
02660        {
02661          r = *bp2++;
02662          g = *bp2++;
02663          b = *bp2++;
02664          gray = (g + ((b + r) >> 1)) >> 1;
02665          gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
02666          obptr[0] = (gray - (gray >> prec)) >> right;
02667          obptr++;
02668        }
02669       bptr += rowstride;
02670       obuf += bpl;
02671     }
02672 }
02673 
02674 static void
02675 xlib_rgb_convert_gray4_d_pack (XImage *image,
02676                            int ax, int ay, int width, int height,
02677                            unsigned char *buf, int rowstride,
02678                            int x_align, int y_align, XlibRgbCmap *cmap)
02679 {
02680   int x, y;
02681   int bpl;
02682   unsigned char *obuf, *obptr;
02683   unsigned char *bptr, *bp2;
02684   int r, g, b;
02685   const unsigned char *dmp;
02686   int prec, right;
02687   int gray;
02688   unsigned char pix0, pix1;
02689   /* todo: this is hardcoded to big-endian. Make endian-agile. */
02690 
02691   bptr = buf;
02692   bpl = image->bytes_per_line;
02693   obuf = ((unsigned char *)image->data) + ay * bpl + (ax >> 1);
02694   prec = image_info->x_visual_info->depth;
02695   right = 8 - prec;
02696   for (y = 0; y < height; y++)
02697     {
02698       bp2 = bptr;
02699       obptr = obuf;
02700       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
02701       for (x = 0; x < width; x += 2)
02702        {
02703          r = *bp2++;
02704          g = *bp2++;
02705          b = *bp2++;
02706          gray = (g + ((b + r) >> 1)) >> 1;
02707          gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
02708          pix0 = (gray - (gray >> prec)) >> right;
02709          r = *bp2++;
02710          g = *bp2++;
02711          b = *bp2++;
02712          gray = (g + ((b + r) >> 1)) >> 1;
02713          gray += (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) >> prec;
02714          pix1 = (gray - (gray >> prec)) >> right;
02715          obptr[0] = (pix0 << 4) | pix1;
02716          obptr++;
02717        }
02718       if (width & 1)
02719        {
02720          r = *bp2++;
02721          g = *bp2++;
02722          b = *bp2++;
02723          gray = (g + ((b + r) >> 1)) >> 1;
02724          gray += (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) >> prec;
02725          pix0 = (gray - (gray >> prec)) >> right;
02726          obptr[0] = (pix0 << 4);
02727        }
02728       bptr += rowstride;
02729       obuf += bpl;
02730     }
02731 }
02732 
02733 static void
02734 xlib_rgb_convert_1 (XImage *image,
02735                  int ax, int ay, int width, int height,
02736                  unsigned char *buf, int rowstride,
02737                  int x_align, int y_align,
02738                  XlibRgbCmap *cmap)
02739 {
02740   int x, y;
02741   int bpl;
02742   unsigned char *obuf, *obptr;
02743   unsigned char *bptr, *bp2;
02744   int r, g, b;
02745   const unsigned char *dmp;
02746   int dith;
02747   unsigned char byte;
02748 
02749   bptr = buf;
02750   bpl = image->bytes_per_line;
02751   obuf = ((unsigned char *)image->data) + ay * bpl + (ax >> 3);
02752   byte = 0; /* unnecessary, but it keeps gcc from complaining */
02753   for (y = 0; y < height; y++)
02754     {
02755       dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
02756       bp2 = bptr;
02757       obptr = obuf;
02758       for (x = 0; x < width; x++)
02759        {
02760          r = *bp2++;
02761          g = *bp2++;
02762          b = *bp2++;
02763          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 4) | 4;
02764          byte += byte + (r + g + g + b + dith > 1020);
02765          if ((x & 7) == 7)
02766            {
02767              obptr[0] = byte;
02768              obptr++;
02769            }
02770        }
02771       if (x & 7)
02772        obptr[0] = byte << (8 - (x & 7));
02773       bptr += rowstride;
02774       obuf += bpl;
02775     }
02776 }
02777 
02778 /* Returns a pointer to the stage buffer. */
02779 static unsigned char *
02780 xlib_rgb_ensure_stage (void)
02781 {
02782   if (image_info->stage_buf == NULL)
02783     image_info->stage_buf = (unsigned char *) malloc (IMAGE_HEIGHT * STAGE_ROWSTRIDE);
02784   return image_info->stage_buf;
02785 }
02786 
02787 /* This is slow. Speed me up, please. */
02788 static void
02789 xlib_rgb_32_to_stage (unsigned char *buf, int rowstride, int width, int height)
02790 {
02791   int x, y;
02792   unsigned char *pi_start, *po_start;
02793   unsigned char *pi, *po;
02794 
02795   pi_start = buf;
02796   po_start = xlib_rgb_ensure_stage ();
02797   for (y = 0; y < height; y++)
02798     {
02799       pi = pi_start;
02800       po = po_start;
02801       for (x = 0; x < width; x++)
02802        {
02803          *po++ = *pi++;
02804          *po++ = *pi++;
02805          *po++ = *pi++;
02806          pi++;
02807        }
02808       pi_start += rowstride;
02809       po_start += STAGE_ROWSTRIDE;
02810     }
02811 }
02812 
02813 /* Generic 32bit RGB conversion function - convert to 24bit packed, then
02814    go from there. */
02815 static void
02816 xlib_rgb_convert_32_generic (XImage *image,
02817                          int ax, int ay, int width, int height,
02818                          unsigned char *buf, int rowstride,
02819                          int x_align, int y_align, XlibRgbCmap *cmap)
02820 {
02821   xlib_rgb_32_to_stage (buf, rowstride, width, height);
02822 
02823   (*image_info->conv) (image, ax, ay, width, height,
02824                      image_info->stage_buf, STAGE_ROWSTRIDE,
02825                      x_align, y_align, cmap);
02826 }
02827 
02828 /* Generic 32bit RGB conversion function - convert to 24bit packed, then
02829    go from there. */
02830 static void
02831 xlib_rgb_convert_32_generic_d (XImage *image,
02832                            int ax, int ay, int width, int height,
02833                            unsigned char *buf, int rowstride,
02834                            int x_align, int y_align, XlibRgbCmap *cmap)
02835 {
02836   xlib_rgb_32_to_stage (buf, rowstride, width, height);
02837 
02838   (*image_info->conv_d) (image, ax, ay, width, height,
02839                       image_info->stage_buf, STAGE_ROWSTRIDE,
02840                       x_align, y_align, cmap);
02841 }
02842 
02843 /* This is slow. Speed me up, please. */
02844 static void
02845 xlib_rgb_gray_to_stage (unsigned char *buf, int rowstride, int width, int height)
02846 {
02847   int x, y;
02848   unsigned char *pi_start, *po_start;
02849   unsigned char *pi, *po;
02850   unsigned char gray;
02851 
02852   pi_start = buf;
02853   po_start = xlib_rgb_ensure_stage ();
02854   for (y = 0; y < height; y++)
02855     {
02856       pi = pi_start;
02857       po = po_start;
02858       for (x = 0; x < width; x++)
02859        {
02860          gray = *pi++;
02861          *po++ = gray;
02862          *po++ = gray;
02863          *po++ = gray;
02864        }
02865       pi_start += rowstride;
02866       po_start += STAGE_ROWSTRIDE;
02867     }
02868 }
02869 
02870 /* Generic gray conversion function - convert to 24bit packed, then go
02871    from there. */
02872 static void
02873 xlib_rgb_convert_gray_generic (XImage *image,
02874                            int ax, int ay, int width, int height,
02875                            unsigned char *buf, int rowstride,
02876                            int x_align, int y_align, XlibRgbCmap *cmap)
02877 {
02878   xlib_rgb_gray_to_stage (buf, rowstride, width, height);
02879 
02880   (*image_info->conv) (image, ax, ay, width, height,
02881                      image_info->stage_buf, STAGE_ROWSTRIDE,
02882                      x_align, y_align, cmap);
02883 }
02884 
02885 static void
02886 xlib_rgb_convert_gray_generic_d (XImage *image,
02887                             int ax, int ay, int width, int height,
02888                             unsigned char *buf, int rowstride,
02889                             int x_align, int y_align, XlibRgbCmap *cmap)
02890 {
02891   xlib_rgb_gray_to_stage (buf, rowstride, width, height);
02892 
02893   (*image_info->conv_d) (image, ax, ay, width, height,
02894                       image_info->stage_buf, STAGE_ROWSTRIDE,
02895                       x_align, y_align, cmap);
02896 }
02897 
02898 /* Render grayscale using indexed method. */
02899 static void
02900 xlib_rgb_convert_gray_cmap (XImage *image,
02901                         int ax, int ay, int width, int height,
02902                         unsigned char *buf, int rowstride,
02903                         int x_align, int y_align, XlibRgbCmap *cmap)
02904 {
02905   (*image_info->conv_indexed) (image, ax, ay, width, height,
02906                             buf, rowstride,
02907                             x_align, y_align, image_info->gray_cmap);
02908 }
02909 
02910 #if 0
02911 static void
02912 xlib_rgb_convert_gray_cmap_d (XImage *image,
02913                             int ax, int ay, int width, int height,
02914                             unsigned char *buf, int rowstride,
02915                             int x_align, int y_align, XlibRgbCmap *cmap)
02916 {
02917   (*image_info->conv_indexed_d) (image, ax, ay, width, height,
02918                              buf, rowstride,
02919                              x_align, y_align, image_info->gray_cmap);
02920 }
02921 #endif
02922 
02923 /* This is slow. Speed me up, please. */
02924 static void
02925 xlib_rgb_indexed_to_stage (unsigned char *buf, int rowstride, int width, int height,
02926                        XlibRgbCmap *cmap)
02927 {
02928   int x, y;
02929   unsigned char *pi_start, *po_start;
02930   unsigned char *pi, *po;
02931   int rgb;
02932 
02933   pi_start = buf;
02934   po_start = xlib_rgb_ensure_stage ();
02935   for (y = 0; y < height; y++)
02936     {
02937       pi = pi_start;
02938       po = po_start;
02939       for (x = 0; x < width; x++)
02940        {
02941          rgb = cmap->colors[*pi++];
02942          *po++ = rgb >> 16;
02943          *po++ = (rgb >> 8) & 0xff;
02944          *po++ = rgb & 0xff;
02945        }
02946       pi_start += rowstride;
02947       po_start += STAGE_ROWSTRIDE;
02948     }
02949 }
02950 
02951 /* Generic gray conversion function - convert to 24bit packed, then go
02952    from there. */
02953 static void
02954 xlib_rgb_convert_indexed_generic (XImage *image,
02955                              int ax, int ay, int width, int height,
02956                              unsigned char *buf, int rowstride,
02957                              int x_align, int y_align, XlibRgbCmap *cmap)
02958 {
02959   xlib_rgb_indexed_to_stage (buf, rowstride, width, height, cmap);
02960 
02961   (*image_info->conv) (image, ax, ay, width, height,
02962                      image_info->stage_buf, STAGE_ROWSTRIDE,
02963                      x_align, y_align, cmap);
02964 }
02965 
02966 static void
02967 xlib_rgb_convert_indexed_generic_d (XImage *image,
02968                                int ax, int ay, int width, int height,
02969                                unsigned char *buf, int rowstride,
02970                                int x_align, int y_align,
02971                                XlibRgbCmap *cmap)
02972 {
02973   xlib_rgb_indexed_to_stage (buf, rowstride, width, height, cmap);
02974 
02975   (*image_info->conv_d) (image, ax, ay, width, height,
02976                       image_info->stage_buf, STAGE_ROWSTRIDE,
02977                       x_align, y_align, cmap);
02978 }
02979 
02980 /* Select a conversion function based on the visual and a
02981    representative image. */
02982 static void
02983 xlib_rgb_select_conv (XImage *image, ByteOrder byte_order)
02984 {
02985   int depth, byterev;
02986   int vtype; /* visual type */
02987   int bpp; /* bits per pixel - from the visual */
02988   unsigned int red_mask, green_mask, blue_mask;
02989   XlibRgbConvFunc conv, conv_d;
02990   XlibRgbConvFunc conv_32, conv_32_d;
02991   XlibRgbConvFunc conv_gray, conv_gray_d;
02992   XlibRgbConvFunc conv_indexed, conv_indexed_d;
02993   Bool mask_rgb, mask_bgr;
02994 
02995   depth = image_info->x_visual_info->depth;
02996   bpp = image->bits_per_pixel;
02997   if (xlib_rgb_verbose)
02998     printf ("Chose visual 0x%x, image bpp=%d, %s first\n",
02999            (int)image_info->x_visual_info->visual->visualid,
03000            bpp, byte_order == LSB_FIRST ? "lsb" : "msb");
03001 
03002 #ifdef WORDS_BIGENDIAN
03003   byterev = (byte_order == LSB_FIRST);
03004 #else
03005   byterev = (byte_order == MSB_FIRST);
03006 #endif
03007 
03008   vtype = image_info->x_visual_info->class;
03009   if (vtype == DirectColor)
03010     vtype = TrueColor;
03011 
03012   red_mask = image_info->x_visual_info->red_mask;
03013   green_mask = image_info->x_visual_info->green_mask;
03014   blue_mask = image_info->x_visual_info->blue_mask;
03015 
03016   mask_rgb = red_mask == 0xff0000 && green_mask == 0xff00 && blue_mask == 0xff;
03017   mask_bgr = red_mask == 0xff && green_mask == 0xff00 && blue_mask == 0xff0000;
03018 
03019   conv = NULL;
03020   conv_d = NULL;
03021 
03022   conv_32 = xlib_rgb_convert_32_generic;
03023   conv_32_d = xlib_rgb_convert_32_generic_d;
03024 
03025   conv_gray = xlib_rgb_convert_gray_generic;
03026   conv_gray_d = xlib_rgb_convert_gray_generic_d;
03027 
03028   conv_indexed = xlib_rgb_convert_indexed_generic;
03029   conv_indexed_d = xlib_rgb_convert_indexed_generic_d;
03030 
03031   image_info->dith_default = FALSE;
03032 
03033   if (image_info->bitmap)
03034     conv = xlib_rgb_convert_1;
03035   else if (bpp == 16 && depth == 16 && !byterev &&
03036       red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f)
03037     {
03038       conv = xlib_rgb_convert_565;
03039       conv_d = xlib_rgb_convert_565_d;
03040       conv_gray = xlib_rgb_convert_565_gray;
03041       xlib_rgb_preprocess_dm_565 ();
03042     }
03043   else if (bpp == 16 && depth == 16 &&
03044           vtype == TrueColor&& byterev &&
03045       red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f)
03046     conv = xlib_rgb_convert_565_br;
03047 
03048   else if (bpp == 16 && depth == 15 &&
03049           vtype == TrueColor && !byterev &&
03050       red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f)
03051     conv = xlib_rgb_convert_555;
03052 
03053   else if (bpp == 16 && depth == 15 &&
03054           vtype == TrueColor && byterev &&
03055       red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f)
03056     conv = xlib_rgb_convert_555_br;
03057 
03058   /* I'm not 100% sure about the 24bpp tests - but testing will show*/
03059   else if (bpp == 24 && depth == 24 && vtype == TrueColor &&
03060           ((mask_rgb && byte_order == LSB_FIRST) ||
03061            (mask_bgr && byte_order == MSB_FIRST)))
03062     conv = xlib_rgb_convert_888_lsb;
03063   else if (bpp == 24 && depth == 24 && vtype == TrueColor &&
03064           ((mask_rgb && byte_order == MSB_FIRST) ||
03065            (mask_bgr && byte_order == LSB_FIRST)))
03066     conv = xlib_rgb_convert_888_msb;
03067 #ifdef WORDS_BIGENDIAN
03068   else if (bpp == 32 && depth == 24 && vtype == TrueColor &&
03069           (mask_rgb && byte_order == LSB_FIRST))
03070     conv = xlib_rgb_convert_0888_br;
03071   else if (bpp == 32 && depth == 24 && vtype == TrueColor &&
03072           (mask_rgb && byte_order == MSB_FIRST))
03073     conv = xlib_rgb_convert_0888;
03074   else if (bpp == 32 && depth == 24 && vtype == TrueColor &&
03075           (mask_bgr && byte_order == MSB_FIRST))
03076     conv = xlib_rgb_convert_8880_br;
03077 #else
03078   else if (bpp == 32 && depth == 24 && vtype == TrueColor &&
03079           (mask_rgb && byte_order == MSB_FIRST))
03080     conv = xlib_rgb_convert_0888_br;
03081   else if (bpp == 32 && (depth == 32 || depth == 24) && vtype == TrueColor &&
03082           (mask_rgb && byte_order == LSB_FIRST))
03083     conv = xlib_rgb_convert_0888;
03084   else if (bpp == 32 && depth == 24 && vtype == TrueColor &&
03085           (mask_bgr && byte_order == LSB_FIRST))
03086     conv = xlib_rgb_convert_8880_br;
03087 #endif
03088 
03089   else if (vtype == TrueColor && byte_order == LSB_FIRST)
03090     {
03091       conv = xlib_rgb_convert_truecolor_lsb;
03092       conv_d = xlib_rgb_convert_truecolor_lsb_d;
03093     }
03094   else if (vtype == TrueColor && byte_order == MSB_FIRST)
03095     {
03096       conv = xlib_rgb_convert_truecolor_msb;
03097       conv_d = xlib_rgb_convert_truecolor_msb_d;
03098     }
03099   else if (bpp == 8 && depth == 8 && (vtype == PseudoColor
03100 #ifdef ENABLE_GRAYSCALE
03101                                   || vtype == GrayScale
03102 #endif
03103                                   ))
03104     {
03105       image_info->dith_default = TRUE;
03106       conv = xlib_rgb_convert_8;
03107       if (vtype != GrayScale)
03108        {
03109          if (image_info->nred_shades == 6 &&
03110              image_info->ngreen_shades == 6 &&
03111              image_info->nblue_shades == 6)
03112            conv_d = xlib_rgb_convert_8_d666;
03113          else
03114            conv_d = xlib_rgb_convert_8_d;
03115        }
03116       conv_indexed = xlib_rgb_convert_8_indexed;
03117       conv_gray = xlib_rgb_convert_gray_cmap;
03118     }
03119   else if (bpp == 8 && depth == 8 && (vtype == StaticGray
03120 #ifdef not_ENABLE_GRAYSCALE
03121                                   || vtype == GrayScale
03122 #endif
03123                                   ))
03124     {
03125       conv = xlib_rgb_convert_gray8;
03126       conv_gray = xlib_rgb_convert_gray8_gray;
03127     }
03128   else if (bpp == 8 && depth < 8 && depth >= 2 &&
03129           (vtype == StaticGray
03130            || vtype == GrayScale))
03131     {
03132       conv = xlib_rgb_convert_gray4;
03133       conv_d = xlib_rgb_convert_gray4_d;
03134     }
03135   else if (bpp == 8 && depth < 8 && depth >= 3)
03136     {
03137       conv = xlib_rgb_convert_4;
03138     }
03139   else if (bpp == 4 && depth <= 4 && depth >= 2 &&
03140           (vtype == StaticGray
03141            || vtype == GrayScale))
03142     {
03143       conv = xlib_rgb_convert_gray4_pack;
03144       conv_d = xlib_rgb_convert_gray4_d_pack;
03145     }
03146 
03147   if (conv_d == NULL)
03148     conv_d = conv;
03149 
03150   image_info->conv = conv;
03151   image_info->conv_d = conv_d;
03152 
03153   image_info->conv_32 = conv_32;
03154   image_info->conv_32_d = conv_32_d;
03155 
03156   image_info->conv_gray = conv_gray;
03157   image_info->conv_gray_d = conv_gray_d;
03158 
03159   image_info->conv_indexed = conv_indexed;
03160   image_info->conv_indexed_d = conv_indexed_d;
03161 }
03162 
03163 static int horiz_idx;
03164 static int horiz_y = IMAGE_HEIGHT;
03165 static int vert_idx;
03166 static int vert_x = IMAGE_WIDTH;
03167 static int tile_idx;
03168 static int tile_x = IMAGE_WIDTH;
03169 static int tile_y1 = IMAGE_HEIGHT;
03170 static int tile_y2 = IMAGE_HEIGHT;
03171 
03172 #ifdef VERBOSE
03173 static int sincelast;
03174 #endif
03175 
03176 /* Defining NO_FLUSH can cause inconsistent screen updates, but is useful
03177    for performance evaluation. */
03178 
03179 #undef NO_FLUSH
03180 
03181 static int
03182 xlib_rgb_alloc_scratch_image (void)
03183 {
03184   if (static_image_idx == N_IMAGES)
03185     {
03186 #ifndef NO_FLUSH
03187       XFlush(image_info->display);
03188 #endif
03189 #ifdef VERBOSE
03190       printf ("flush, %d puts since last flush\n", sincelast);
03191       sincelast = 0;
03192 #endif
03193       static_image_idx = 0;
03194       horiz_y = IMAGE_HEIGHT;
03195       vert_x = IMAGE_WIDTH;
03196       tile_x = IMAGE_WIDTH;
03197       tile_y1 = tile_y2 = IMAGE_HEIGHT;
03198     }
03199   return static_image_idx++;
03200 }
03201 
03202 static XImage *
03203 xlib_rgb_alloc_scratch (int width, int height, int *ax, int *ay)
03204 {
03205   XImage *image;
03206   int idx;
03207 
03208   if (width >= (IMAGE_WIDTH >> 1))
03209     {
03210       if (height >= (IMAGE_HEIGHT >> 1))
03211        {
03212          idx = xlib_rgb_alloc_scratch_image ();
03213          *ax = 0;
03214          *ay = 0;
03215        }
03216       else
03217        {
03218          if (height + horiz_y > IMAGE_HEIGHT)
03219            {
03220              horiz_idx = xlib_rgb_alloc_scratch_image ();
03221              horiz_y = 0;
03222            }
03223          idx = horiz_idx;
03224          *ax = 0;
03225          *ay = horiz_y;
03226          horiz_y += height;
03227        }
03228     }
03229   else
03230     {
03231       if (height >= (IMAGE_HEIGHT >> 1))
03232        {
03233          if (width + vert_x > IMAGE_WIDTH)
03234            {
03235              vert_idx = xlib_rgb_alloc_scratch_image ();
03236              vert_x = 0;
03237            }
03238          idx = vert_idx;
03239          *ax = vert_x;
03240          *ay = 0;
03241          /* using 3 and -4 would be slightly more efficient on 32-bit machines
03242             with > 1bpp displays */
03243          vert_x += (width + 7) & -8;
03244        }
03245       else
03246        {
03247          if (width + tile_x > IMAGE_WIDTH)
03248            {
03249              tile_y1 = tile_y2;
03250              tile_x = 0;
03251            }
03252          if (height + tile_y1 > IMAGE_HEIGHT)
03253            {
03254              tile_idx = xlib_rgb_alloc_scratch_image ();
03255              tile_x = 0;
03256              tile_y1 = 0;
03257              tile_y2 = 0;
03258            }
03259          if (height + tile_y1 > tile_y2)
03260            tile_y2 = height + tile_y1;
03261          idx = tile_idx;
03262          *ax = tile_x;
03263          *ay = tile_y1;
03264          tile_x += (width + 7) & -8;
03265        }
03266     }
03267   image = static_image[idx];
03268 #ifdef VERBOSE
03269   printf ("index %d, x %d, y %d (%d x %d)\n", idx, *ax, *ay, width, height);
03270   sincelast++;
03271 #endif
03272   return image;
03273 }
03274 
03275 static void
03276 xlib_draw_rgb_image_core (Drawable drawable,
03277                        GC gc,
03278                        int x,
03279                        int y,
03280                        int width,
03281                        int height,
03282                        unsigned char *buf,
03283                        int pixstride,
03284                        int rowstride,
03285                        XlibRgbConvFunc conv,
03286                        XlibRgbCmap *cmap,
03287                        int xdith,
03288                        int ydith)
03289 {
03290   int ay, ax;
03291   int xs0, ys0;
03292   XImage *image;
03293   int width1, height1;
03294   unsigned char *buf_ptr;
03295 
03296   if (image_info->bitmap)
03297     {
03298       if (image_info->own_gc == 0)
03299        {
03300          XColor color;
03301 
03302          image_info->own_gc = XCreateGC(image_info->display,
03303                                     drawable,
03304                                     0, NULL);
03305          color.pixel = WhitePixel(image_info->display,
03306                                image_info->screen_num);
03307          XSetForeground(image_info->display, image_info->own_gc, color.pixel);
03308          color.pixel = BlackPixel(image_info->display,
03309                                image_info->screen_num);
03310          XSetBackground(image_info->display, image_info->own_gc, color.pixel);
03311        }
03312       gc = image_info->own_gc;
03313     }
03314   for (ay = 0; ay < height; ay += IMAGE_HEIGHT)
03315     {
03316       height1 = MIN (height - ay, IMAGE_HEIGHT);
03317       for (ax = 0; ax < width; ax += IMAGE_WIDTH)
03318        {
03319          width1 = MIN (width - ax, IMAGE_WIDTH);
03320          buf_ptr = buf + ay * rowstride + ax * pixstride;
03321 
03322          image = xlib_rgb_alloc_scratch (width1, height1, &xs0, &ys0);
03323 
03324          conv (image, xs0, ys0, width1, height1, buf_ptr, rowstride,
03325               x + ax + xdith, y + ay + ydith, cmap);
03326 
03327 #ifndef DONT_ACTUALLY_DRAW
03328          XPutImage(image_info->display, drawable, gc, image,
03329                   xs0, ys0, x + ax, y + ay, (unsigned int)width1, (unsigned int)height1);
03330 #endif
03331        }
03332     }
03333 }
03334 
03335 
03355 void
03356 xlib_draw_rgb_image (Drawable drawable,
03357                    GC gc,
03358                    int x,
03359                    int y,
03360                    int width,
03361                    int height,
03362                    XlibRgbDither dith,
03363                    unsigned char *rgb_buf,
03364                    int rowstride)
03365 {
03366   if (dith == XLIB_RGB_DITHER_NONE || (dith == XLIB_RGB_DITHER_NORMAL &&
03367                                   !image_info->dith_default))
03368     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03369                            rgb_buf, 3, rowstride, image_info->conv, NULL,
03370                            0, 0);
03371   else
03372     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03373                            rgb_buf, 3, rowstride, image_info->conv_d, NULL,
03374                            0, 0);
03375 }
03376 
03399 void
03400 xlib_draw_rgb_image_dithalign (Drawable drawable,
03401                            GC gc,
03402                            int x,
03403                            int y,
03404                            int width,
03405                            int height,
03406                            XlibRgbDither dith,
03407                            unsigned char *rgb_buf,
03408                            int rowstride,
03409                            int xdith,
03410                            int ydith)
03411 {
03412   if (dith == XLIB_RGB_DITHER_NONE || (dith == XLIB_RGB_DITHER_NORMAL &&
03413                                    !image_info->dith_default))
03414     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03415                            rgb_buf, 3, rowstride, image_info->conv, NULL,
03416                            xdith, ydith);
03417   else
03418     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03419                            rgb_buf, 3, rowstride, image_info->conv_d, NULL,
03420                            xdith, ydith);
03421 }
03422 
03442 void
03443 xlib_draw_rgb_32_image (Drawable drawable,
03444                      GC gc,
03445                      int x,
03446                      int y,
03447                      int width,
03448                      int height,
03449                      XlibRgbDither dith,
03450                      unsigned char *buf,
03451                      int rowstride)
03452 {
03453   if (dith == XLIB_RGB_DITHER_NONE || (dith == XLIB_RGB_DITHER_NORMAL &&
03454                                    !image_info->dith_default))
03455     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03456                            buf, 4, rowstride,
03457                            image_info->conv_32, NULL, 0, 0);
03458   else
03459     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03460                            buf, 4, rowstride,
03461                            image_info->conv_32_d, NULL, 0, 0);
03462 }
03463 
03464 static void
03465 xlib_rgb_make_gray_cmap (XlibRgbInfo *info)
03466 {
03467   unsigned int rgb[256];
03468   int i;
03469 
03470   for (i = 0; i < 256; i++)
03471     rgb[i] = (i << 16)  | (i << 8) | i;
03472   info->gray_cmap = xlib_rgb_cmap_new (rgb, 256);
03473 }
03474 
03492 void
03493 xlib_draw_gray_image (Drawable drawable,
03494                     GC gc,
03495                     int x,
03496                     int y,
03497                     int width,
03498                     int height,
03499                     XlibRgbDither dith,
03500                     unsigned char *buf,
03501                     int rowstride)
03502 {
03503   if (image_info->bpp == 1 &&
03504       image_info->gray_cmap == NULL &&
03505       (image_info->x_visual_info->class == PseudoColor ||
03506        image_info->x_visual_info->class == GrayScale))
03507     xlib_rgb_make_gray_cmap (image_info);
03508   
03509   if (dith == XLIB_RGB_DITHER_NONE || (dith == XLIB_RGB_DITHER_NORMAL &&
03510                                   !image_info->dith_default))
03511     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03512                            buf, 1, rowstride,
03513                            image_info->conv_gray, NULL, 0, 0);
03514   else
03515     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03516                            buf, 1, rowstride,
03517                            image_info->conv_gray_d, NULL, 0, 0);
03518 }
03519 
03529 XlibRgbCmap *
03530 xlib_rgb_cmap_new (unsigned int *colors, int n_colors)
03531 {
03532   XlibRgbCmap *cmap;
03533   int i, j;
03534   unsigned int rgb;
03535 
03536   if (n_colors < 0)
03537     return NULL;
03538   if (n_colors > 256)
03539     return NULL;
03540   cmap = (XlibRgbCmap *) malloc(sizeof(XlibRgbCmap));
03541   memcpy (cmap->colors, colors, n_colors * sizeof(unsigned int));
03542   if (image_info->bpp == 1 &&
03543       (image_info->x_visual_info->class == PseudoColor ||
03544        image_info->x_visual_info->class == GrayScale))
03545     for (i = 0; i < n_colors; i++)
03546       {
03547        rgb = colors[i];
03548        j = ((rgb & 0xf00000) >> 12) |
03549                  ((rgb & 0xf000) >> 8) |
03550                  ((rgb & 0xf0) >> 4);
03551 #ifdef VERBOSE
03552        printf ("%d %x %x %d\n", i, j, colorcube[j]);
03553 #endif
03554        cmap->lut[i] = colorcube[j];
03555       }
03556   return cmap;
03557 }
03558 
03565 void
03566 xlib_rgb_cmap_free (XlibRgbCmap *cmap)
03567 {
03568   free (cmap);
03569 }
03570 
03586 void
03587 xlib_draw_indexed_image (Drawable drawable,
03588                      GC gc,
03589                      int x,
03590                      int y,
03591                      int width,
03592                      int height,
03593                      XlibRgbDither dith,
03594                      unsigned char *buf,
03595                      int rowstride,
03596                      XlibRgbCmap *cmap)
03597 {
03598   if (dith == XLIB_RGB_DITHER_NONE || (dith == XLIB_RGB_DITHER_NORMAL &&
03599                                    !image_info->dith_default))
03600     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03601                            buf, 1, rowstride,
03602                            image_info->conv_indexed, cmap, 0, 0);
03603   else
03604     xlib_draw_rgb_image_core (drawable, gc, x, y, width, height,
03605                            buf, 1, rowstride,
03606                            image_info->conv_indexed_d, cmap, 0, 0);
03607 }
03608 
03617 Bool
03618 xlib_rgb_ditherable (void)
03619 {
03620   return (image_info->conv != image_info->conv_d);
03621 }
03622 
03630 Colormap
03631 xlib_rgb_get_cmap (void)
03632 {
03633   /* xlib_rgb_init (); */
03634   if (image_info)
03635     return image_info->cmap;
03636   else
03637     return 0;
03638 }
03639 
03647 Visual *
03648 xlib_rgb_get_visual (void)
03649 {
03650   /* xlib_rgb_init (); */
03651   if (image_info)
03652     return image_info->x_visual_info->visual;
03653   else
03654     return 0;
03655 }
03656 
03664 XVisualInfo *
03665 xlib_rgb_get_visual_info (void)
03666 {
03667   /* xlib_rgb_init (); */
03668   if (image_info)
03669     return image_info->x_visual_info;
03670   else
03671     return 0;
03672 }
03673 
03681 int
03682 xlib_rgb_get_depth (void)
03683 {
03684   XVisualInfo * v = xlib_rgb_get_visual_info();
03685 
03686   if (v)
03687   {
03688     return v->depth;
03689   }
03690 
03691   return 0;
03692 }
03693 
03701 Display *
03702 xlib_rgb_get_display (void)
03703 {
03704   if (image_info)
03705     return image_info->display;
03706   
03707   return NULL;
03708 }
03709 
03717 Screen *
03718 xlib_rgb_get_screen (void)
03719 {
03720   if (image_info)
03721     return image_info->screen;
03722   
03723   return NULL;
03724 }