source: trunk/third/gtk/gdk/gdkrgb.c @ 15781

Revision 15781, 137.2 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15780, which included commits to RCS files with non-trunk default branches.
Line 
1/* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20/* For more information on GdkRgb, see http://www.levien.com/gdkrgb/
21
22   Raph Levien <raph@acm.org>
23   */
24
25/*
26 * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
27 * file for a list of people on the GTK+ Team.  See the ChangeLog
28 * files for a list of changes.  These files are distributed with
29 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 */
31
32#include <math.h>
33
34#if HAVE_CONFIG_H
35#  include <config.h>
36#  if STDC_HEADERS
37#    include <stdio.h>
38#    include <stdlib.h>
39#    include <string.h>
40#  endif
41#else
42#  include <stdio.h>
43#  include <stdlib.h>
44#endif
45
46
47#define ENABLE_GRAYSCALE
48
49#ifdef GDK_RGB_STANDALONE
50
51/* Compiling as a standalone module (i.e. with Gtk 1.0) */
52/* gtk/gtk.h is already included in gdkrgbstub.c */
53#include "config.h"
54#include <gdk/gdkprivate.h>
55
56#else
57
58/* Compiling as a part of Gtk 1.1 or later */
59#include "../config.h"
60#include "gdk.h"
61#include "gdkprivate.h"
62
63#endif
64
65#include "gdkrgb.h"
66
67typedef struct _GdkRgbInfo   GdkRgbInfo;
68
69typedef void (*GdkRgbConvFunc) (GdkImage *image,
70                                gint x0, gint y0,
71                                gint width, gint height,
72                                guchar *buf, int rowstride,
73                                gint x_align, gint y_align,
74                                GdkRgbCmap *cmap);
75
76/* Some of these fields should go, as they're not being used at all.
77   Globals should generally migrate into here - it's very likely that
78   we'll want to run more than one GdkRgbInfo context at the same time
79   (i.e. some but not all windows have privately installed
80   colormaps). */
81
82struct _GdkRgbInfo
83{
84  GdkVisual *visual;
85  GdkColormap *cmap;
86
87  gulong *color_pixels;
88  gulong *gray_pixels;
89  gulong *reserved_pixels;
90
91  guint nred_shades;
92  guint ngreen_shades;
93  guint nblue_shades;
94  guint ngray_shades;
95  guint nreserved;
96
97  guint bpp;
98  gint cmap_alloced;
99  gdouble gamma;
100
101  /* Generally, the stage buffer is used to convert 32bit RGB, gray,
102     and indexed images into 24 bit packed RGB. */
103  guchar *stage_buf;
104
105  GdkRgbCmap *gray_cmap;
106
107  gboolean dith_default;
108
109  gboolean bitmap; /* set true if in 1 bit per pixel mode */
110  GdkGC *own_gc;
111
112  /* Convert functions */
113  GdkRgbConvFunc conv;
114  GdkRgbConvFunc conv_d;
115
116  GdkRgbConvFunc conv_32;
117  GdkRgbConvFunc conv_32_d;
118
119  GdkRgbConvFunc conv_gray;
120  GdkRgbConvFunc conv_gray_d;
121
122  GdkRgbConvFunc conv_indexed;
123  GdkRgbConvFunc conv_indexed_d;
124};
125
126static gboolean gdk_rgb_install_cmap = FALSE;
127static gint gdk_rgb_min_colors = 5 * 5 * 5;
128static gboolean gdk_rgb_verbose = FALSE;
129
130#define REGION_WIDTH 256
131#define STAGE_ROWSTRIDE (REGION_WIDTH * 3)
132#define REGION_HEIGHT 64
133
134/* We have N_REGION REGION_WIDTH x REGION_HEIGHT regions divided
135 * up between n_images different images. possible_n_images gives
136 * various divisors of N_REGIONS. The reason for allowing this
137 * flexibility is that we want to create as few images as possible,
138 * but we want to deal with the abberant systems that have a SHMMAX
139 * limit less than
140 *
141 * REGION_WIDTH * REGION_HEIGHT * N_REGIONS * 4 (384k)
142 *
143 * (Are there any such?)
144 */
145#define N_REGIONS 6
146static const int possible_n_images[] = { 1, 2, 3, 6 };
147
148static GdkRgbInfo *image_info = NULL;
149static GdkImage *static_image[N_REGIONS];
150static gint static_image_idx;
151static gint static_n_images;
152 
153
154static guchar *colorcube;
155static guchar *colorcube_d;
156
157static gint
158gdk_rgb_cmap_fail (const char *msg, GdkColormap *cmap, gulong *pixels)
159{
160  gulong free_pixels[256];
161  gint n_free;
162  gint i;
163
164#ifdef VERBOSE
165  g_print ("%s", msg);
166#endif
167  n_free = 0;
168  for (i = 0; i < 256; i++)
169    if (pixels[i] < 256)
170      free_pixels[n_free++] = pixels[i];
171  if (n_free)
172    gdk_colors_free (cmap, free_pixels, n_free, 0);
173  return 0;
174}
175
176static void
177gdk_rgb_make_colorcube (gulong *pixels, gint nr, gint ng, gint nb)
178{
179  guchar rt[16], gt[16], bt[16];
180  gint i;
181
182  colorcube = g_new (guchar, 4096);
183  for (i = 0; i < 16; i++)
184    {
185      rt[i] = ng * nb * ((i * 17 * (nr - 1) + 128) >> 8);
186      gt[i] = nb * ((i * 17 * (ng - 1) + 128) >> 8);
187      bt[i] = ((i * 17 * (nb - 1) + 128) >> 8);
188    }
189
190  for (i = 0; i < 4096; i++)
191    {
192      colorcube[i] = pixels[rt[i >> 8] + gt[(i >> 4) & 0x0f] + bt[i & 0x0f]];
193#ifdef VERBOSE
194      g_print ("%03x %02x %x %x %x\n", i, colorcube[i], rt[i >> 8], gt[(i >> 4) & 0x0f], bt[i & 0x0f]);
195#endif
196    }
197}
198
199/* this is the colorcube suitable for dithering */
200static void
201gdk_rgb_make_colorcube_d (gulong *pixels, gint nr, gint ng, gint nb)
202{
203  gint r, g, b;
204  gint i;
205
206  colorcube_d = g_new (guchar, 512);
207  for (i = 0; i < 512; i++)
208    {
209      r = MIN (nr - 1, i >> 6);
210      g = MIN (ng - 1, (i >> 3) & 7);
211      b = MIN (nb - 1, i & 7);
212      colorcube_d[i] = pixels[(r * ng + g) * nb + b];
213    }
214}
215
216/* Try installing a color cube of the specified size.
217   Make the colorcube and return TRUE on success */
218static gint
219gdk_rgb_try_colormap (gint nr, gint ng, gint nb)
220{
221  gint r, g, b;
222  gint ri, gi, bi;
223  gint r0, g0, b0;
224  GdkColormap *cmap;
225  GdkColor color;
226  gulong pixels[256];
227  gulong junk[256];
228  gint i;
229  gint d2;
230  gint colors_needed;
231  gint idx;
232  gint best[256];
233
234  if (!image_info->cmap_alloced && nr * ng * nb < gdk_rgb_min_colors)
235    return FALSE;
236
237  if (image_info->cmap_alloced)
238    cmap = image_info->cmap;
239  else
240    cmap = gdk_colormap_get_system ();
241
242  gdk_colormap_sync (cmap, FALSE);
243 
244  colors_needed = nr * ng * nb;
245  for (i = 0; i < 256; i++)
246    {
247      best[i] = 192;
248      pixels[i] = 256;
249    }
250
251#ifndef GAMMA
252  if (!gdk_rgb_install_cmap)
253  /* find color cube colors that are already present */
254  for (i = 0; i < MIN (256, cmap->size); i++)
255    {
256      r = cmap->colors[i].red >> 8;
257      g = cmap->colors[i].green >> 8;
258      b = cmap->colors[i].blue >> 8;
259      ri = (r * (nr - 1) + 128) >> 8;
260      gi = (g * (ng - 1) + 128) >> 8;
261      bi = (b * (nb - 1) + 128) >> 8;
262      r0 = ri * 255 / (nr - 1);
263      g0 = gi * 255 / (ng - 1);
264      b0 = bi * 255 / (nb - 1);
265      idx = ((ri * nr) + gi) * nb + bi;
266      d2 = (r - r0) * (r - r0) + (g - g0) * (g - g0) + (b - b0) * (b - b0);
267      if (d2 < best[idx]) {
268        if (pixels[idx] < 256)
269          gdk_colors_free (cmap, pixels + idx, 1, 0);
270        else
271          colors_needed--;
272        color = cmap->colors[i];
273        if (!gdk_color_alloc (cmap, &color))
274          return gdk_rgb_cmap_fail ("error allocating system color\n",
275                                    cmap, pixels);
276        pixels[idx] = color.pixel; /* which is almost certainly i */
277        best[idx] = d2;
278      }
279    }
280#endif
281
282  if (colors_needed)
283    {
284      if (!gdk_colors_alloc (cmap, 0, NULL, 0, junk, colors_needed))
285        {
286          char tmp_str[80];
287         
288          sprintf (tmp_str,
289                   "%d %d %d colormap failed (in gdk_colors_alloc)\n",
290                   nr, ng, nb);
291          return gdk_rgb_cmap_fail (tmp_str, cmap, pixels);
292        }
293
294      gdk_colors_free (cmap, junk, colors_needed, 0);
295    }
296
297  for (r = 0, i = 0; r < nr; r++)
298    for (g = 0; g < ng; g++)
299      for (b = 0; b < nb; b++, i++)
300        {
301          if (pixels[i] == 256)
302            {
303              color.red = r * 65535 / (nr - 1);
304              color.green = g * 65535 / (ng - 1);
305              color.blue = b * 65535 / (nb - 1);
306
307#ifdef GAMMA
308              color.red = 65535 * pow (color.red / 65535.0, 0.5);
309              color.green = 65535 * pow (color.green / 65535.0, 0.5);
310              color.blue = 65535 * pow (color.blue / 65535.0, 0.5);
311#endif
312
313              /* This should be a raw XAllocColor call */
314              if (!gdk_color_alloc (cmap, &color))
315                {
316                  char tmp_str[80];
317
318                  sprintf (tmp_str, "%d %d %d colormap failed\n",
319                           nr, ng, nb);
320                  return gdk_rgb_cmap_fail (tmp_str,
321                                            cmap, pixels);
322                }
323              pixels[i] = color.pixel;
324            }
325#ifdef VERBOSE
326          g_print ("%d: %lx\n", i, pixels[i]);
327#endif
328        }
329
330  image_info->nred_shades = nr;
331  image_info->ngreen_shades = ng;
332  image_info->nblue_shades = nb;
333  gdk_rgb_make_colorcube (pixels, nr, ng, nb);
334  gdk_rgb_make_colorcube_d (pixels, nr, ng, nb);
335  return TRUE;
336}
337
338/* Return TRUE on success. */
339static gboolean
340gdk_rgb_do_colormaps (void)
341{
342  static const gint sizes[][3] = {
343    /*    { 6, 7, 6 }, */
344    { 6, 6, 6 },
345    { 6, 6, 5 },
346    { 6, 6, 4 },
347    { 5, 5, 5 },
348    { 5, 5, 4 },
349    { 4, 4, 4 },
350    { 4, 4, 3 },
351    { 3, 3, 3 },
352    { 2, 2, 2 }
353  };
354  static const gint n_sizes = sizeof(sizes) / (3 * sizeof(gint));
355  gint i;
356
357  for (i = 0; i < n_sizes; i++)
358    if (gdk_rgb_try_colormap (sizes[i][0], sizes[i][1], sizes[i][2]))
359      return TRUE;
360  return FALSE;
361}
362
363/* Make a 2 x 2 x 2 colorcube */
364static void
365gdk_rgb_colorcube_222 (void)
366{
367  int i;
368  GdkColor color;
369  GdkColormap *cmap;
370
371  if (image_info->cmap_alloced)
372    cmap = image_info->cmap;
373  else
374    cmap = gdk_colormap_get_system ();
375
376  colorcube_d = g_new (guchar, 512);
377
378  for (i = 0; i < 8; i++)
379    {
380      color.red = ((i & 4) >> 2) * 65535;
381      color.green = ((i & 2) >> 1) * 65535;
382      color.blue = (i & 1) * 65535;
383      gdk_color_alloc (cmap, &color);
384      colorcube_d[((i & 4) << 4) | ((i & 2) << 2) | (i & 1)] = color.pixel;
385    }
386}
387
388void
389gdk_rgb_set_verbose (gboolean verbose)
390{
391  gdk_rgb_verbose = verbose;
392}
393
394void
395gdk_rgb_set_install (gboolean install)
396{
397  gdk_rgb_install_cmap = install;
398}
399
400void
401gdk_rgb_set_min_colors (gint min_colors)
402{
403  gdk_rgb_min_colors = min_colors;
404}
405
406static const gchar* visual_names[] =
407{
408  "static gray",
409  "grayscale",
410  "static color",
411  "pseudo color",
412  "true color",
413  "direct color",
414};
415
416/* Return a "score" based on the following criteria (in hex):
417
418   x000 is the quality - 1 is 1bpp, 2 is 4bpp,
419                         4 is 8bpp,
420                         7 is 15bpp truecolor, 8 is 16bpp truecolor,
421                         9 is 24bpp truecolor.
422   0x00 is the speed - 1 is the normal case,
423                       2 means faster than normal
424   00x0 gets a point for being the system visual
425   000x gets a point for being pseudocolor
426
427   A caveat: in the 8bpp modes, being the system visual seems to be
428   quite important. Thus, all of the 8bpp modes should be ranked at
429   the same speed.
430*/
431static guint32
432gdk_rgb_score_visual (GdkVisual *visual)
433{
434  guint32 quality, speed, sys, pseudo;
435
436  quality = 0;
437  speed = 1;
438  sys = 0;
439  if (visual->type == GDK_VISUAL_TRUE_COLOR ||
440      visual->type == GDK_VISUAL_DIRECT_COLOR)
441    {
442      if (visual->depth == 24)
443        {
444          quality = 9;
445          /* Should test for MSB visual here, and set speed if so. */
446        }
447      else if (visual->depth == 16)
448        quality = 8;
449      else if (visual->depth == 15)
450        quality = 7;
451      else if (visual->depth == 8)
452        quality = 4;
453    }
454  else if (visual->type == GDK_VISUAL_PSEUDO_COLOR ||
455           visual->type == GDK_VISUAL_STATIC_COLOR)
456    {
457      if (visual->depth == 8)
458        quality = 4;
459      else if (visual->depth == 4)
460        quality = 2;
461      else if (visual->depth == 1)
462        quality = 1;
463    }
464  else if (visual->type == GDK_VISUAL_STATIC_GRAY
465#ifdef ENABLE_GRAYSCALE
466           || visual->type == GDK_VISUAL_GRAYSCALE
467#endif
468           )
469    {
470      if (visual->depth == 8)
471        quality = 4;
472      else if (visual->depth == 4)
473        quality = 2;
474      else if (visual->depth == 1)
475        quality = 1;
476    }
477
478  if (quality == 0)
479    return 0;
480
481  sys = (visual == gdk_visual_get_system ());
482
483  pseudo = (visual->type == GDK_VISUAL_PSEUDO_COLOR || visual->type == GDK_VISUAL_TRUE_COLOR);
484
485  if (gdk_rgb_verbose)
486    g_print ("Visual 0x%x, type = %s, depth = %d, %x:%x:%x%s; score=%x\n",
487             (gint)(((GdkVisualPrivate *)visual)->xvisual->visualid),
488             visual_names[visual->type],
489             visual->depth,
490             visual->red_mask,
491             visual->green_mask,
492             visual->blue_mask,
493             sys ? " (system)" : "",
494             (quality << 12) | (speed << 8) | (sys << 4) | pseudo);
495
496  return (quality << 12) | (speed << 8) | (sys << 4) | pseudo;
497}
498
499static void
500gdk_rgb_choose_visual (void)
501{
502  GList *visuals, *tmp_list;
503  guint32 score, best_score;
504  GdkVisual *visual, *best_visual;
505
506  visuals = gdk_list_visuals ();
507  tmp_list = visuals;
508
509  best_visual = tmp_list->data;
510  best_score = gdk_rgb_score_visual (best_visual);
511  tmp_list = tmp_list->next;
512  while (tmp_list)
513    {
514      visual = tmp_list->data;
515      score = gdk_rgb_score_visual (visual);
516      if (score > best_score)
517        {
518          best_score = score;
519          best_visual = visual;
520        }
521      tmp_list = tmp_list->next;
522    }
523
524  g_list_free (visuals);
525
526  image_info->visual = best_visual;
527}
528
529static void gdk_rgb_select_conv (GdkImage *image);
530
531static void
532gdk_rgb_set_gray_cmap (GdkColormap *cmap)
533{
534  gint i;
535  GdkColor color;
536  gint status;
537  gulong pixels[256];
538  gint r, g, b, gray;
539
540  for (i = 0; i < 256; i++)
541    {
542      color.pixel = i;
543      color.red = i * 257;
544      color.green = i * 257;
545      color.blue = i * 257;
546      status = gdk_color_alloc (cmap, &color);
547      pixels[i] = color.pixel;
548#ifdef VERBOSE
549      g_print ("allocating pixel %d, %x %x %x, result %d\n",
550               color.pixel, color.red, color.green, color.blue, status);
551#endif
552    }
553
554  /* Now, we make fake colorcubes - we ultimately just use the pseudocolor
555     methods. */
556
557  colorcube = g_new (guchar, 4096);
558
559  for (i = 0; i < 4096; i++)
560    {
561      r = (i >> 4) & 0xf0;
562      r = r | r >> 4;
563      g = i & 0xf0;
564      g = g | g >> 4;
565      b = (i << 4 & 0xf0);
566      b = b | b >> 4;
567      gray = (g + ((r + b) >> 1)) >> 1;
568      colorcube[i] = pixels[gray];
569    }
570}
571
572static gboolean
573gdk_rgb_allocate_images (gint        n_images,
574                         gboolean    shared)
575{
576  gint i;
577 
578  for (i = 0; i < n_images; i++)
579    {
580      if (image_info->bitmap)
581        /* Use malloc() instead of g_malloc since X will free() this mem */
582        static_image[i] = gdk_image_new_bitmap (image_info->visual,
583                                                (gpointer) malloc (REGION_WIDTH * REGION_HEIGHT >> 3),
584                                                REGION_WIDTH * (N_REGIONS / n_images), REGION_HEIGHT);
585      else
586        static_image[i] = gdk_image_new (shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL,
587                                         image_info->visual,
588                                         REGION_WIDTH * (N_REGIONS / n_images), REGION_HEIGHT);
589     
590      if (!static_image[i])
591        {
592          gint j;
593         
594          for (j = 0; j < i; j++)
595            gdk_image_destroy (static_image[j]);
596         
597          return FALSE;
598        }
599    }
600 
601  return TRUE;
602}
603
604void
605gdk_rgb_init (void)
606{
607  gint i;
608  static const gint byte_order[1] = { 1 };
609
610  /* check endian sanity */
611#if G_BYTE_ORDER == G_BIG_ENDIAN
612  if (((char *)byte_order)[0] == 1)
613    g_error ("gdk_rgb_init: compiled for big endian, but this is a little endian machine.\n\n");
614#else
615  if (((char *)byte_order)[0] != 1)
616    g_error ("gdk_rgb_init: compiled for little endian, but this is a big endian machine.\n\n");
617#endif
618
619  if (image_info == NULL)
620    {
621      image_info = g_new0 (GdkRgbInfo, 1);
622
623      image_info->visual = NULL;
624      image_info->cmap = NULL;
625
626      image_info->color_pixels = NULL;
627      image_info->gray_pixels = NULL;
628      image_info->reserved_pixels = NULL;
629
630      image_info->nred_shades = 6;
631      image_info->ngreen_shades = 6;
632      image_info->nblue_shades = 4;
633      image_info->ngray_shades = 24;
634      image_info->nreserved = 0;
635
636      image_info->bpp = 0;
637      image_info->cmap_alloced = FALSE;
638      image_info->gamma = 1.0;
639
640      image_info->stage_buf = NULL;
641
642      image_info->own_gc = NULL;
643
644      gdk_rgb_choose_visual ();
645
646      if ((image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
647           image_info->visual->type == GDK_VISUAL_STATIC_COLOR) &&
648          image_info->visual->depth < 8 &&
649          image_info->visual->depth >= 3)
650        {
651          image_info->cmap = gdk_colormap_get_system ();
652          gdk_rgb_colorcube_222 ();
653        }
654      else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR)
655        {
656          if (gdk_rgb_install_cmap ||
657              image_info->visual != gdk_visual_get_system ())
658            {
659              image_info->cmap = gdk_colormap_new (image_info->visual, FALSE);
660              image_info->cmap_alloced = TRUE;
661            }
662          if (!gdk_rgb_do_colormaps ())
663            {
664              image_info->cmap = gdk_colormap_new (image_info->visual, FALSE);
665              image_info->cmap_alloced = TRUE;
666              gdk_rgb_do_colormaps ();
667            }
668          if (gdk_rgb_verbose)
669            g_print ("color cube: %d x %d x %d\n",
670                     image_info->nred_shades,
671                     image_info->ngreen_shades,
672                     image_info->nblue_shades);
673
674          if (!image_info->cmap_alloced)
675              image_info->cmap = gdk_colormap_get_system ();
676        }
677#ifdef ENABLE_GRAYSCALE
678      else if (image_info->visual->type == GDK_VISUAL_GRAYSCALE)
679        {
680          image_info->cmap = gdk_colormap_new (image_info->visual, FALSE);
681          gdk_rgb_set_gray_cmap (image_info->cmap);
682          image_info->cmap_alloced = TRUE;
683        }
684#endif
685      else
686        {
687          /* Always install colormap in direct color. */
688          if (image_info->visual->type != GDK_VISUAL_DIRECT_COLOR &&
689              image_info->visual == gdk_visual_get_system ())
690            image_info->cmap = gdk_colormap_get_system ();
691          else
692            {
693              image_info->cmap = gdk_colormap_new (image_info->visual, FALSE);
694              image_info->cmap_alloced = TRUE;
695            }
696        }
697
698      image_info->bitmap = (image_info->visual->depth == 1);
699
700      /* Try to allocate as few possible shared images */
701      for (i=0; i < sizeof (possible_n_images) / sizeof (possible_n_images[0]); i++)
702        {
703          if (gdk_rgb_allocate_images (possible_n_images[i], TRUE))
704            {
705              static_n_images = possible_n_images[i];
706              break;
707            }
708        }
709     
710      /* If that fails, just allocate N_REGIONS normal images */
711      if (i == sizeof (possible_n_images) / sizeof (possible_n_images[0]))
712        {
713          gdk_rgb_allocate_images (N_REGIONS, FALSE);
714          static_n_images = N_REGIONS;
715        }
716
717      image_info->bpp = static_image[0]->bpp;
718
719      gdk_rgb_select_conv (static_image[0]);
720
721    }
722}
723
724/* convert an rgb value into an X pixel code */
725gulong
726gdk_rgb_xpixel_from_rgb (guint32 rgb)
727{
728  gulong pixel = 0;
729
730  if (image_info->bitmap)
731    {
732      return ((rgb & 0xff0000) >> 16) +
733        ((rgb & 0xff00) >> 7) +
734        (rgb & 0xff) > 510;
735    }
736  else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR)
737    pixel = colorcube[((rgb & 0xf00000) >> 12) |
738                     ((rgb & 0xf000) >> 8) |
739                     ((rgb & 0xf0) >> 4)];
740  else if (image_info->visual->depth < 8 &&
741           image_info->visual->type == GDK_VISUAL_STATIC_COLOR)
742    {
743      pixel = colorcube_d[((rgb & 0x800000) >> 17) |
744                         ((rgb & 0x8000) >> 12) |
745                         ((rgb & 0x80) >> 7)];
746    }
747  else if (image_info->visual->type == GDK_VISUAL_TRUE_COLOR ||
748           image_info->visual->type == GDK_VISUAL_DIRECT_COLOR)
749    {
750#ifdef VERBOSE
751      g_print ("shift, prec: r %d %d g %d %d b %d %d\n",
752               image_info->visual->red_shift,
753               image_info->visual->red_prec,
754               image_info->visual->green_shift,
755               image_info->visual->green_prec,
756               image_info->visual->blue_shift,
757               image_info->visual->blue_prec);
758#endif
759
760      pixel = (((((rgb & 0xff0000) >> 16) >>
761                 (8 - image_info->visual->red_prec)) <<
762                image_info->visual->red_shift) +
763               ((((rgb & 0xff00) >> 8)  >>
764                 (8 - image_info->visual->green_prec)) <<
765                image_info->visual->green_shift) +
766               (((rgb & 0xff) >>
767                 (8 - image_info->visual->blue_prec)) <<
768                image_info->visual->blue_shift));
769    }
770  else if (image_info->visual->type == GDK_VISUAL_STATIC_GRAY ||
771           image_info->visual->type == GDK_VISUAL_GRAYSCALE)
772    {
773      int gray = ((rgb & 0xff0000) >> 16) +
774        ((rgb & 0xff00) >> 7) +
775        (rgb & 0xff);
776
777      return gray >> (10 - image_info->visual->depth);
778    }
779
780  return pixel;
781}
782
783void
784gdk_rgb_gc_set_foreground (GdkGC *gc, guint32 rgb)
785{
786  GdkColor color;
787
788  color.pixel = gdk_rgb_xpixel_from_rgb (rgb);
789  gdk_gc_set_foreground (gc, &color);
790}
791
792void
793gdk_rgb_gc_set_background (GdkGC *gc, guint32 rgb)
794{
795  GdkColor color;
796
797  color.pixel = gdk_rgb_xpixel_from_rgb (rgb);
798  gdk_gc_set_background (gc, &color);
799}
800
801#if G_BYTE_ORDER == G_LITTLE_ENDIAN
802#define HAIRY_CONVERT_8
803#endif
804
805#ifdef HAIRY_CONVERT_8
806static void
807gdk_rgb_convert_8 (GdkImage *image,
808                   gint x0, gint y0, gint width, gint height,
809                   guchar *buf, int rowstride,
810                   gint x_align, gint y_align, GdkRgbCmap *cmap)
811{
812  int x, y;
813  gint bpl;
814  guchar *obuf, *obptr;
815  guchar *bptr, *bp2;
816  gint r, g, b;
817
818  bptr = buf;
819  bpl = image->bpl;
820  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
821  for (y = 0; y < height; y++)
822    {
823      bp2 = bptr;
824      obptr = obuf;
825      if (((unsigned long)obuf | (unsigned long) bp2) & 3)
826        {
827          for (x = 0; x < width; x++)
828            {
829              r = *bp2++;
830              g = *bp2++;
831              b = *bp2++;
832              obptr[0] = colorcube[((r & 0xf0) << 4) |
833                                  (g & 0xf0) |
834                                  (b >> 4)];
835              obptr++;
836            }
837        }
838      else
839        {
840          for (x = 0; x < width - 3; x += 4)
841            {
842              guint32 r1b0g0r0;
843              guint32 g2r2b1g1;
844              guint32 b3g3r3b2;
845
846              r1b0g0r0 = ((guint32 *)bp2)[0];
847              g2r2b1g1 = ((guint32 *)bp2)[1];
848              b3g3r3b2 = ((guint32 *)bp2)[2];
849              ((guint32 *)obptr)[0] =
850                colorcube[((r1b0g0r0 & 0xf0) << 4) |
851                         ((r1b0g0r0 & 0xf000) >> 8) |
852                         ((r1b0g0r0 & 0xf00000) >> 20)] |
853                (colorcube[((r1b0g0r0 & 0xf0000000) >> 20) |
854                          (g2r2b1g1 & 0xf0) |
855                          ((g2r2b1g1 & 0xf000) >> 12)] << 8) |
856                (colorcube[((g2r2b1g1 & 0xf00000) >> 12) |
857                          ((g2r2b1g1 & 0xf0000000) >> 24) |
858                          ((b3g3r3b2 & 0xf0) >> 4)] << 16) |
859                (colorcube[((b3g3r3b2 & 0xf000) >> 4) |
860                          ((b3g3r3b2 & 0xf00000) >> 16) |
861                          (b3g3r3b2 >> 28)] << 24);
862              bp2 += 12;
863              obptr += 4;
864            }
865          for (; x < width; x++)
866            {
867              r = *bp2++;
868              g = *bp2++;
869              b = *bp2++;
870              obptr[0] = colorcube[((r & 0xf0) << 4) |
871                                  (g & 0xf0) |
872                                  (b >> 4)];
873              obptr++;
874            }
875        }
876      bptr += rowstride;
877      obuf += bpl;
878    }
879}
880#else
881static void
882gdk_rgb_convert_8 (GdkImage *image,
883                   gint x0, gint y0, gint width, gint height,
884                   guchar *buf, int rowstride,
885                   gint x_align, gint y_align, GdkRgbCmap *cmap)
886{
887  int x, y;
888  gint bpl;
889  guchar *obuf, *obptr;
890  guchar *bptr, *bp2;
891  gint r, g, b;
892
893  bptr = buf;
894  bpl = image->bpl;
895  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
896  for (y = 0; y < height; y++)
897    {
898      bp2 = bptr;
899      obptr = obuf;
900      for (x = 0; x < width; x++)
901        {
902          r = *bp2++;
903          g = *bp2++;
904          b = *bp2++;
905          obptr[0] = colorcube[((r & 0xf0) << 4) |
906                              (g & 0xf0) |
907                              (b >> 4)];
908          obptr++;
909        }
910      bptr += rowstride;
911      obuf += bpl;
912    }
913}
914#endif
915
916#if 1
917
918/* This dither table was generated by Raph Levien using patented
919   technology (US Patent 5,276,535). The dither table itself is in the
920   public domain. */
921
922#define DM_WIDTH 128
923#define DM_WIDTH_SHIFT 7
924#define DM_HEIGHT 128
925static const guchar DM[128][128] =
926{
927  { 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 },
928  { 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 },
929  { 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 },
930  { 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 },
931  { 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 },
932  { 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 },
933  { 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 },
934  { 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 },
935  { 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 },
936  { 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 },
937  { 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 },
938  { 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 },
939  { 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 },
940  { 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 },
941  { 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 },
942  { 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 },
943  { 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 },
944  { 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 },
945  { 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 },
946  { 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 },
947  { 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 },
948  { 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 },
949  { 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 },
950  { 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 },
951  { 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 },
952  { 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 },
953  { 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 },
954  { 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 },
955  { 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 },
956  { 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 },
957  { 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 },
958  { 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 },
959  { 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 },
960  { 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 },
961  { 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 },
962  { 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 },
963  { 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 },
964  { 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 },
965  { 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 },
966  { 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 },
967  { 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 },
968  { 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 },
969  { 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 },
970  { 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 },
971  { 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 },
972  { 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 },
973  { 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 },
974  { 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 },
975  { 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 },
976  { 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 },
977  { 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 },
978  { 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 },
979  { 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 },
980  { 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 },
981  { 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 },
982  { 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 },
983  { 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 },
984  { 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 },
985  { 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 },
986  { 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 },
987  { 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 },
988  { 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 },
989  { 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 },
990  { 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 },
991  { 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 },
992  { 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 },
993  { 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 },
994  { 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 },
995  { 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 },
996  { 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 },
997  { 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 },
998  { 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 },
999  { 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 },
1000  { 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 },
1001  { 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 },
1002  { 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 },
1003  { 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 },
1004  { 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 },
1005  { 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 },
1006  { 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 },
1007  { 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 },
1008  { 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 },
1009  { 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 },
1010  { 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 },
1011  { 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 },
1012  { 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 },
1013  { 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 },
1014  { 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 },
1015  { 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 },
1016  { 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 },
1017  { 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 },
1018  { 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 },
1019  { 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 },
1020  { 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 },
1021  { 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 },
1022  { 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 },
1023  { 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 },
1024  { 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 },
1025  { 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 },
1026  { 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 },
1027  { 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 },
1028  { 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 },
1029  { 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 },
1030  { 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 },
1031  { 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 },
1032  { 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 },
1033  { 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 },
1034  { 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 },
1035  { 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 },
1036  { 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 },
1037  { 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 },
1038  { 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 },
1039  { 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 },
1040  { 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 },
1041  { 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 },
1042  { 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 },
1043  { 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 },
1044  { 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 },
1045  { 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 },
1046  { 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 },
1047  { 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 },
1048  { 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 },
1049  { 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 },
1050  { 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 },
1051  { 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 },
1052  { 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 },
1053  { 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 },
1054  { 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 },
1055};
1056
1057#else
1058#define DM_WIDTH 8
1059#define DM_WIDTH_SHIFT 3
1060#define DM_HEIGHT 8
1061static const guchar DM[8][8] =
1062{
1063  { 0,  32, 8,  40, 2,  34, 10, 42 },
1064  { 48, 16, 56, 24, 50, 18, 58, 26 },
1065  { 12, 44, 4,  36, 14, 46, 6,  38 },
1066  { 60, 28, 52, 20, 62, 30, 54, 22 },
1067  { 3,  35, 11, 43, 1,  33, 9,  41 },
1068  { 51, 19, 59, 27, 49, 17, 57, 25 },
1069  { 15, 47, 7,  39, 13, 45, 5,  37 },
1070  { 63, 31, 55, 23, 61, 29, 53, 21 }
1071};
1072#endif
1073
1074static guint32 *DM_565 = NULL;
1075
1076static void
1077gdk_rgb_preprocess_dm_565 (void)
1078{
1079  int i;
1080  guint32 dith;
1081
1082  if (DM_565 == NULL)
1083    {
1084      DM_565 = g_new (guint32, DM_WIDTH * DM_HEIGHT);
1085      for (i = 0; i < DM_WIDTH * DM_HEIGHT; i++)
1086        {
1087          dith = DM[0][i] >> 3;
1088          DM_565[i] = (dith << 20) | dith | (((7 - dith) >> 1) << 10);
1089#ifdef VERBOSE
1090          g_print ("%i %x %x\n", i, dith, DM_565[i]);
1091#endif
1092        }
1093    }
1094}
1095
1096static void
1097gdk_rgb_convert_8_d666 (GdkImage *image,
1098                        gint x0, gint y0, gint width, gint height,
1099                        guchar *buf, int rowstride,
1100                        gint x_align, gint y_align, GdkRgbCmap *cmap)
1101{
1102  int x, y;
1103  gint bpl;
1104  guchar *obuf, *obptr;
1105  guchar *bptr, *bp2;
1106  gint r, g, b;
1107  const guchar *dmp;
1108  gint dith;
1109
1110  bptr = buf;
1111  bpl = image->bpl;
1112  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
1113  for (y = 0; y < height; y++)
1114    {
1115      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
1116      bp2 = bptr;
1117      obptr = obuf;
1118      for (x = 0; x < width; x++)
1119        {
1120          r = *bp2++;
1121          g = *bp2++;
1122          b = *bp2++;
1123          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 7;
1124          r = ((r * 5) + dith) >> 8;
1125          g = ((g * 5) + (262 - dith)) >> 8;
1126          b = ((b * 5) + dith) >> 8;
1127          obptr[0] = colorcube_d[(r << 6) | (g << 3) | b];
1128          obptr++;
1129        }
1130      bptr += rowstride;
1131      obuf += bpl;
1132    }
1133}
1134
1135static void
1136gdk_rgb_convert_8_d (GdkImage *image,
1137                     gint x0, gint y0, gint width, gint height,
1138                     guchar *buf, int rowstride,
1139                     gint x_align, gint y_align,
1140                     GdkRgbCmap *cmap)
1141{
1142  int x, y;
1143  gint bpl;
1144  guchar *obuf, *obptr;
1145  guchar *bptr, *bp2;
1146  gint r, g, b;
1147  const guchar *dmp;
1148  gint dith;
1149  gint rs, gs, bs;
1150
1151  bptr = buf;
1152  bpl = image->bpl;
1153  rs = image_info->nred_shades - 1;
1154  gs = image_info->ngreen_shades - 1;
1155  bs = image_info->nblue_shades - 1;
1156  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
1157  for (y = 0; y < height; y++)
1158    {
1159      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
1160      bp2 = bptr;
1161      obptr = obuf;
1162      for (x = 0; x < width; x++)
1163        {
1164          r = *bp2++;
1165          g = *bp2++;
1166          b = *bp2++;
1167          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 7;
1168          r = ((r * rs) + dith) >> 8;
1169          g = ((g * gs) + (262 - dith)) >> 8;
1170          b = ((b * bs) + dith) >> 8;
1171          obptr[0] = colorcube_d[(r << 6) | (g << 3) | b];
1172          obptr++;
1173        }
1174      bptr += rowstride;
1175      obuf += bpl;
1176    }
1177}
1178
1179static void
1180gdk_rgb_convert_8_indexed (GdkImage *image,
1181                           gint x0, gint y0, gint width, gint height,
1182                           guchar *buf, int rowstride,
1183                           gint x_align, gint y_align, GdkRgbCmap *cmap)
1184{
1185  int x, y;
1186  gint bpl;
1187  guchar *obuf, *obptr;
1188  guchar *bptr, *bp2;
1189  guchar c;
1190  guchar *lut;
1191
1192  lut = cmap->lut;
1193  bptr = buf;
1194  bpl = image->bpl;
1195  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
1196  for (y = 0; y < height; y++)
1197    {
1198      bp2 = bptr;
1199      obptr = obuf;
1200      for (x = 0; x < width; x++)
1201        {
1202          c = *bp2++;
1203          obptr[0] = lut[c];
1204          obptr++;
1205        }
1206      bptr += rowstride;
1207      obuf += bpl;
1208    }
1209}
1210
1211static void
1212gdk_rgb_convert_gray8 (GdkImage *image,
1213                       gint x0, gint y0, gint width, gint height,
1214                       guchar *buf, int rowstride,
1215                       gint x_align, gint y_align, GdkRgbCmap *cmap)
1216{
1217  int x, y;
1218  gint bpl;
1219  guchar *obuf, *obptr;
1220  guchar *bptr, *bp2;
1221  gint r, g, b;
1222
1223  bptr = buf;
1224  bpl = image->bpl;
1225  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
1226  for (y = 0; y < height; y++)
1227    {
1228      bp2 = bptr;
1229      obptr = obuf;
1230      for (x = 0; x < width; x++)
1231        {
1232          r = *bp2++;
1233          g = *bp2++;
1234          b = *bp2++;
1235          obptr[0] = (g + ((b + r) >> 1)) >> 1;
1236          obptr++;
1237        }
1238      bptr += rowstride;
1239      obuf += bpl;
1240    }
1241}
1242
1243static void
1244gdk_rgb_convert_gray8_gray (GdkImage *image,
1245                            gint x0, gint y0, gint width, gint height,
1246                            guchar *buf, int rowstride,
1247                            gint x_align, gint y_align, GdkRgbCmap *cmap)
1248{
1249  int y;
1250  gint bpl;
1251  guchar *obuf;
1252  guchar *bptr;
1253
1254  bptr = buf;
1255  bpl = image->bpl;
1256  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
1257  for (y = 0; y < height; y++)
1258    {
1259      memcpy (obuf, bptr, width);
1260      bptr += rowstride;
1261      obuf += bpl;
1262    }
1263}
1264
1265#if G_BYTE_ORDER == G_LITTLE_ENDIAN
1266#define HAIRY_CONVERT_565
1267#endif
1268
1269#ifdef HAIRY_CONVERT_565
1270/* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
1271   This assumes native byte ordering - what should really be done is to
1272   check whether static_image->byte_order is consistent with the _ENDIAN
1273   config flag, and if not, use a different function.
1274
1275   This one is even faster than the one below - its inner loop loads 3
1276   words (i.e. 4 24-bit pixels), does a lot of shifting and masking,
1277   then writes 2 words. */
1278static void
1279gdk_rgb_convert_565 (GdkImage *image,
1280                     gint x0, gint y0, gint width, gint height,
1281                     guchar *buf, int rowstride,
1282                     gint x_align, gint y_align, GdkRgbCmap *cmap)
1283{
1284  int x, y;
1285  guchar *obuf, *obptr;
1286  gint bpl;
1287  guchar *bptr, *bp2;
1288  guchar r, g, b;
1289
1290  bptr = buf;
1291  bpl = image->bpl;
1292  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1293  for (y = 0; y < height; y++)
1294    {
1295      bp2 = bptr;
1296      obptr = obuf;
1297      if (((unsigned long)obuf | (unsigned long) bp2) & 3)
1298        {
1299          for (x = 0; x < width; x++)
1300            {
1301              r = *bp2++;
1302              g = *bp2++;
1303              b = *bp2++;
1304              ((guint16 *)obptr)[0] = ((r & 0xf8) << 8) |
1305                ((g & 0xfc) << 3) |
1306                (b >> 3);
1307              obptr += 2;
1308            }
1309        }
1310      else
1311        {
1312          for (x = 0; x < width - 3; x += 4)
1313            {
1314              guint32 r1b0g0r0;
1315              guint32 g2r2b1g1;
1316              guint32 b3g3r3b2;
1317
1318              r1b0g0r0 = ((guint32 *)bp2)[0];
1319              g2r2b1g1 = ((guint32 *)bp2)[1];
1320              b3g3r3b2 = ((guint32 *)bp2)[2];
1321              ((guint32 *)obptr)[0] =
1322                ((r1b0g0r0 & 0xf8) << 8) |
1323                ((r1b0g0r0 & 0xfc00) >> 5) |
1324                ((r1b0g0r0 & 0xf80000) >> 19) |
1325                (r1b0g0r0 & 0xf8000000) |
1326                ((g2r2b1g1 & 0xfc) << 19) |
1327                ((g2r2b1g1 & 0xf800) << 5);
1328              ((guint32 *)obptr)[1] =
1329                ((g2r2b1g1 & 0xf80000) >> 8) |
1330                ((g2r2b1g1 & 0xfc000000) >> 21) |
1331                ((b3g3r3b2 & 0xf8) >> 3) |
1332                ((b3g3r3b2 & 0xf800) << 16) |
1333                ((b3g3r3b2 & 0xfc0000) << 3) |
1334                ((b3g3r3b2 & 0xf8000000) >> 11);
1335              bp2 += 12;
1336              obptr += 8;
1337            }
1338          for (; x < width; x++)
1339            {
1340              r = *bp2++;
1341              g = *bp2++;
1342              b = *bp2++;
1343              ((guint16 *)obptr)[0] = ((r & 0xf8) << 8) |
1344                ((g & 0xfc) << 3) |
1345                (b >> 3);
1346              obptr += 2;
1347            }
1348        }
1349      bptr += rowstride;
1350      obuf += bpl;
1351    }
1352}
1353#else
1354/* Render a 24-bit RGB image in buf into the GdkImage, without dithering.
1355   This assumes native byte ordering - what should really be done is to
1356   check whether static_image->byte_order is consistent with the _ENDIAN
1357   config flag, and if not, use a different function.
1358
1359   This routine is faster than the one included with Gtk 1.0 for a number
1360   of reasons:
1361
1362   1. Shifting instead of lookup tables (less memory traffic).
1363
1364   2. Much less register pressure, especially because shifts are
1365   in the code.
1366
1367   3. A memcpy is avoided (i.e. the transfer function).
1368
1369   4. On big-endian architectures, byte swapping is avoided.
1370
1371   That said, it wouldn't be hard to make it even faster - just make an
1372   inner loop that reads 3 words (i.e. 4 24-bit pixels), does a lot of
1373   shifting and masking, then writes 2 words.
1374*/
1375static void
1376gdk_rgb_convert_565 (GdkImage *image,
1377                     gint x0, gint y0, gint width, gint height,
1378                     guchar *buf, int rowstride,
1379                     gint x_align, gint y_align, GdkRgbCmap *cmap)
1380{
1381  int x, y;
1382  guchar *obuf;
1383  gint bpl;
1384  guchar *bptr, *bp2;
1385  guchar r, g, b;
1386
1387  bptr = buf;
1388  bpl = image->bpl;
1389  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1390  for (y = 0; y < height; y++)
1391    {
1392      bp2 = bptr;
1393      for (x = 0; x < width; x++)
1394        {
1395          r = *bp2++;
1396          g = *bp2++;
1397          b = *bp2++;
1398          ((unsigned short *)obuf)[x] = ((r & 0xf8) << 8) |
1399            ((g & 0xfc) << 3) |
1400            (b >> 3);
1401        }
1402      bptr += rowstride;
1403      obuf += bpl;
1404    }
1405}
1406#endif
1407
1408#ifdef HAIRY_CONVERT_565
1409static void
1410gdk_rgb_convert_565_gray (GdkImage *image,
1411                          gint x0, gint y0, gint width, gint height,
1412                          guchar *buf, int rowstride,
1413                          gint x_align, gint y_align, GdkRgbCmap *cmap)
1414{
1415  int x, y;
1416  guchar *obuf, *obptr;
1417  gint bpl;
1418  guchar *bptr, *bp2;
1419  guchar g;
1420
1421  bptr = buf;
1422  bpl = image->bpl;
1423  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1424  for (y = 0; y < height; y++)
1425    {
1426      bp2 = bptr;
1427      obptr = obuf;
1428      if (((unsigned long)obuf | (unsigned long) bp2) & 3)
1429        {
1430          for (x = 0; x < width; x++)
1431            {
1432              g = *bp2++;
1433              ((guint16 *)obptr)[0] = ((g & 0xf8) << 8) |
1434                ((g & 0xfc) << 3) |
1435                (g >> 3);
1436              obptr += 2;
1437            }
1438        }
1439      else
1440        {
1441          for (x = 0; x < width - 3; x += 4)
1442            {
1443              guint32 g3g2g1g0;
1444
1445              g3g2g1g0 = ((guint32 *)bp2)[0];
1446              ((guint32 *)obptr)[0] =
1447                ((g3g2g1g0 & 0xf8) << 8) |
1448                ((g3g2g1g0 & 0xfc) << 3) |
1449                ((g3g2g1g0 & 0xf8) >> 3) |
1450                (g3g2g1g0 & 0xf800) << 16 |
1451                ((g3g2g1g0 & 0xfc00) << 11) |
1452                ((g3g2g1g0 & 0xf800) << 5);
1453              ((guint32 *)obptr)[1] =
1454                ((g3g2g1g0 & 0xf80000) >> 8) |
1455                ((g3g2g1g0 & 0xfc0000) >> 13) |
1456                ((g3g2g1g0 & 0xf80000) >> 19) |
1457                (g3g2g1g0 & 0xf8000000) |
1458                ((g3g2g1g0 & 0xfc000000) >> 5) |
1459                ((g3g2g1g0 & 0xf8000000) >> 11);
1460              bp2 += 4;
1461              obptr += 8;
1462            }
1463          for (; x < width; x++)
1464            {
1465              g = *bp2++;
1466              ((guint16 *)obptr)[0] = ((g & 0xf8) << 8) |
1467                ((g & 0xfc) << 3) |
1468                (g >> 3);
1469              obptr += 2;
1470            }
1471        }
1472      bptr += rowstride;
1473      obuf += bpl;
1474    }
1475}
1476#else
1477static void
1478gdk_rgb_convert_565_gray (GdkImage *image,
1479                          gint x0, gint y0, gint width, gint height,
1480                          guchar *buf, int rowstride,
1481                          gint x_align, gint y_align, GdkRgbCmap *cmap)
1482{
1483  int x, y;
1484  guchar *obuf;
1485  gint bpl;
1486  guchar *bptr, *bp2;
1487  guchar g;
1488
1489  bptr = buf;
1490  bpl = image->bpl;
1491  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1492  for (y = 0; y < height; y++)
1493    {
1494      bp2 = bptr;
1495      for (x = 0; x < width; x++)
1496        {
1497          g = *bp2++;
1498          ((guint16 *)obuf)[x] = ((g & 0xf8) << 8) |
1499            ((g & 0xfc) << 3) |
1500            (g >> 3);
1501        }
1502      bptr += rowstride;
1503      obuf += bpl;
1504    }
1505}
1506#endif
1507
1508static void
1509gdk_rgb_convert_565_br (GdkImage *image,
1510                        gint x0, gint y0, gint width, gint height,
1511                        guchar *buf, int rowstride,
1512                        gint x_align, gint y_align, GdkRgbCmap *cmap)
1513{
1514  int x, y;
1515  guchar *obuf;
1516  gint bpl;
1517  guchar *bptr, *bp2;
1518  guchar r, g, b;
1519
1520  bptr = buf;
1521  bpl = image->bpl;
1522  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1523  for (y = 0; y < height; y++)
1524    {
1525      bp2 = bptr;
1526      for (x = 0; x < width; x++)
1527        {
1528          r = *bp2++;
1529          g = *bp2++;
1530          b = *bp2++;
1531          /* final word is:
1532             g4 g3 g2 b7 b6 b5 b4 b3  r7 r6 r5 r4 r3 g7 g6 g5
1533           */
1534          ((unsigned short *)obuf)[x] = (r & 0xf8) |
1535            ((g & 0xe0) >> 5) |
1536            ((g & 0x1c) << 11) |
1537            ((b & 0xf8) << 5);
1538        }
1539      bptr += rowstride;
1540      obuf += bpl;
1541    }
1542}
1543
1544/* Thanks to Ray Lehtiniemi for a patch that resulted in a ~25% speedup
1545   in this mode. */
1546#ifdef HAIRY_CONVERT_565
1547static void
1548gdk_rgb_convert_565_d (GdkImage *image,
1549                     gint x0, gint y0, gint width, gint height,
1550                     guchar *buf, int rowstride,
1551                     gint x_align, gint y_align, GdkRgbCmap *cmap)
1552{
1553  /* Now this is what I'd call some highly tuned code! */
1554  int x, y;
1555  guchar *obuf, *obptr;
1556  gint bpl;
1557  guchar *bptr, *bp2;
1558
1559  width += x_align;
1560  height += y_align;
1561 
1562  bptr = buf;
1563  bpl = image->bpl;
1564  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1565  for (y = y_align; y < height; y++)
1566    {
1567      guint32 *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT);
1568      bp2 = bptr;
1569      obptr = obuf;
1570      if (((unsigned long)obuf | (unsigned long) bp2) & 3)
1571        {
1572          for (x = x_align; x < width; x++)
1573            {
1574              gint32 rgb = *bp2++ << 20;
1575              rgb += *bp2++ << 10;
1576              rgb += *bp2++;
1577              rgb += dmp[x & (DM_WIDTH - 1)];
1578              rgb += 0x10040100
1579                - ((rgb & 0x1e0001e0) >> 5)
1580                - ((rgb & 0x00070000) >> 6);
1581
1582              ((unsigned short *)obptr)[0] =
1583                ((rgb & 0x0f800000) >> 12) |
1584                ((rgb & 0x0003f000) >> 7) |
1585                ((rgb & 0x000000f8) >> 3);
1586              obptr += 2;
1587            }
1588        }
1589      else
1590        {
1591          for (x = x_align; x < width - 3; x += 4)
1592            {
1593              guint32 r1b0g0r0;
1594              guint32 g2r2b1g1;
1595              guint32 b3g3r3b2;
1596              guint32 rgb02, rgb13;
1597
1598              r1b0g0r0 = ((guint32 *)bp2)[0];
1599              g2r2b1g1 = ((guint32 *)bp2)[1];
1600              b3g3r3b2 = ((guint32 *)bp2)[2];
1601              rgb02 =
1602                ((r1b0g0r0 & 0xff) << 20) +
1603                ((r1b0g0r0 & 0xff00) << 2) +
1604                ((r1b0g0r0 & 0xff0000) >> 16) +
1605                dmp[x & (DM_WIDTH - 1)];
1606              rgb02 += 0x10040100
1607                - ((rgb02 & 0x1e0001e0) >> 5)
1608                - ((rgb02 & 0x00070000) >> 6);
1609              rgb13 =
1610                ((r1b0g0r0 & 0xff000000) >> 4) +
1611                ((g2r2b1g1 & 0xff) << 10) +
1612                ((g2r2b1g1 & 0xff00) >> 8) +
1613                dmp[(x + 1) & (DM_WIDTH - 1)];
1614              rgb13 += 0x10040100
1615                - ((rgb13 & 0x1e0001e0) >> 5)
1616                - ((rgb13 & 0x00070000) >> 6);
1617              ((guint32 *)obptr)[0] =
1618                ((rgb02 & 0x0f800000) >> 12) |
1619                ((rgb02 & 0x0003f000) >> 7) |
1620                ((rgb02 & 0x000000f8) >> 3) |
1621                ((rgb13 & 0x0f800000) << 4) |
1622                ((rgb13 & 0x0003f000) << 9) |
1623                ((rgb13 & 0x000000f8) << 13);
1624              rgb02 =
1625                ((g2r2b1g1 & 0xff0000) << 4) +
1626                ((g2r2b1g1 & 0xff000000) >> 14) +
1627                (b3g3r3b2 & 0xff) +
1628                dmp[(x + 2) & (DM_WIDTH - 1)];
1629              rgb02 += 0x10040100
1630                - ((rgb02 & 0x1e0001e0) >> 5)
1631                - ((rgb02 & 0x00070000) >> 6);
1632              rgb13 =
1633                ((b3g3r3b2 & 0xff00) << 12) +
1634                ((b3g3r3b2 & 0xff0000) >> 6) +
1635                ((b3g3r3b2 & 0xff000000) >> 24) +
1636                dmp[(x + 3) & (DM_WIDTH - 1)];
1637              rgb13 += 0x10040100
1638                - ((rgb13 & 0x1e0001e0) >> 5)
1639                - ((rgb13 & 0x00070000) >> 6);
1640              ((guint32 *)obptr)[1] =
1641                ((rgb02 & 0x0f800000) >> 12) |
1642                ((rgb02 & 0x0003f000) >> 7) |
1643                ((rgb02 & 0x000000f8) >> 3) |
1644                ((rgb13 & 0x0f800000) << 4) |
1645                ((rgb13 & 0x0003f000) << 9) |
1646                ((rgb13 & 0x000000f8) << 13);
1647              bp2 += 12;
1648              obptr += 8;
1649            }
1650          for (; x < width; x++)
1651            {
1652              gint32 rgb = *bp2++ << 20;
1653              rgb += *bp2++ << 10;
1654              rgb += *bp2++;
1655              rgb += dmp[x & (DM_WIDTH - 1)];
1656              rgb += 0x10040100
1657                - ((rgb & 0x1e0001e0) >> 5)
1658                - ((rgb & 0x00070000) >> 6);
1659
1660              ((unsigned short *)obptr)[0] =
1661                ((rgb & 0x0f800000) >> 12) |
1662                ((rgb & 0x0003f000) >> 7) |
1663                ((rgb & 0x000000f8) >> 3);
1664              obptr += 2;
1665            }
1666        }
1667      bptr += rowstride;
1668      obuf += bpl;
1669    }
1670}
1671#else
1672static void
1673gdk_rgb_convert_565_d (GdkImage *image,
1674                       gint x0, gint y0, gint width, gint height,
1675                       guchar *buf, int rowstride,
1676                       gint x_align, gint y_align, GdkRgbCmap *cmap)
1677{
1678  int x, y;
1679  guchar *obuf;
1680  gint bpl;
1681  guchar *bptr;
1682
1683  width += x_align;
1684  height += y_align;
1685 
1686  bptr = buf;
1687  bpl = image->bpl;
1688  obuf = ((guchar *)image->mem) + y0 * bpl + (x0 - x_align) * 2;
1689
1690  for (y = y_align; y < height; y++)
1691    {
1692      guint32 *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT);
1693      guchar *bp2 = bptr;
1694
1695      for (x = x_align; x < width; x++)
1696        {
1697          gint32 rgb = *bp2++ << 20;
1698          rgb += *bp2++ << 10;
1699          rgb += *bp2++;
1700          rgb += dmp[x & (DM_WIDTH - 1)];
1701          rgb += 0x10040100
1702            - ((rgb & 0x1e0001e0) >> 5)
1703            - ((rgb & 0x00070000) >> 6);
1704
1705          ((unsigned short *)obuf)[x] =
1706            ((rgb & 0x0f800000) >> 12) |
1707            ((rgb & 0x0003f000) >> 7) |
1708            ((rgb & 0x000000f8) >> 3);
1709        }
1710
1711      bptr += rowstride;
1712      obuf += bpl;
1713    }
1714}
1715#endif
1716
1717static void
1718gdk_rgb_convert_555 (GdkImage *image,
1719                     gint x0, gint y0, gint width, gint height,
1720                     guchar *buf, int rowstride,
1721                     gint x_align, gint y_align, GdkRgbCmap *cmap)
1722{
1723  int x, y;
1724  guchar *obuf;
1725  gint bpl;
1726  guchar *bptr, *bp2;
1727  guchar r, g, b;
1728
1729  bptr = buf;
1730  bpl = image->bpl;
1731  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1732  for (y = 0; y < height; y++)
1733    {
1734      bp2 = bptr;
1735      for (x = 0; x < width; x++)
1736        {
1737          r = *bp2++;
1738          g = *bp2++;
1739          b = *bp2++;
1740          ((unsigned short *)obuf)[x] = ((r & 0xf8) << 7) |
1741            ((g & 0xf8) << 2) |
1742            (b >> 3);
1743        }
1744      bptr += rowstride;
1745      obuf += bpl;
1746    }
1747}
1748
1749static void
1750gdk_rgb_convert_555_br (GdkImage *image,
1751                        gint x0, gint y0, gint width, gint height,
1752                        guchar *buf, int rowstride,
1753                        gint x_align, gint y_align, GdkRgbCmap *cmap)
1754{
1755  int x, y;
1756  guchar *obuf;
1757  gint bpl;
1758  guchar *bptr, *bp2;
1759  guchar r, g, b;
1760
1761  bptr = buf;
1762  bpl = image->bpl;
1763  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2;
1764  for (y = 0; y < height; y++)
1765    {
1766      bp2 = bptr;
1767      for (x = 0; x < width; x++)
1768        {
1769          r = *bp2++;
1770          g = *bp2++;
1771          b = *bp2++;
1772          /* final word is:
1773             g5 g4 g3 b7 b6 b5 b4 b3  0 r7 r6 r5 r4 r3 g7 g6
1774           */
1775          ((unsigned short *)obuf)[x] = ((r & 0xf8) >> 1) |
1776            ((g & 0xc0) >> 6) |
1777            ((g & 0x38) << 10) |
1778            ((b & 0xf8) << 5);
1779        }
1780      bptr += rowstride;
1781      obuf += bpl;
1782    }
1783}
1784
1785static void
1786gdk_rgb_convert_888_msb (GdkImage *image,
1787                         gint x0, gint y0, gint width, gint height,
1788                         guchar *buf, int rowstride,
1789                         gint x_align, gint y_align, GdkRgbCmap *cmap)
1790{
1791  int y;
1792  guchar *obuf;
1793  gint bpl;
1794  guchar *bptr;
1795
1796  bptr = buf;
1797  bpl = image->bpl;
1798  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3;
1799  for (y = 0; y < height; y++)
1800    {
1801      memcpy (obuf, bptr, width + width + width);
1802      bptr += rowstride;
1803      obuf += bpl;
1804    }
1805}
1806
1807/* todo: optimize this */
1808#if G_BYTE_ORDER == G_LITTLE_ENDIAN
1809#define HAIRY_CONVERT_888
1810#endif
1811
1812#ifdef HAIRY_CONVERT_888
1813static void
1814gdk_rgb_convert_888_lsb (GdkImage *image,
1815                         gint x0, gint y0, gint width, gint height,
1816                         guchar *buf, int rowstride,
1817                         gint x_align, gint y_align, GdkRgbCmap *cmap)
1818{
1819  int x, y;
1820  guchar *obuf, *obptr;
1821  gint bpl;
1822  guchar *bptr, *bp2;
1823  int r, g, b;
1824
1825  bptr = buf;
1826  bpl = image->bpl;
1827  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3;
1828  for (y = 0; y < height; y++)
1829    {
1830      bp2 = bptr;
1831      obptr = obuf;
1832      if (((unsigned long)obuf | (unsigned long) bp2) & 3)
1833        {
1834          for (x = 0; x < width; x++)
1835            {
1836              r = bp2[0];
1837              g = bp2[1];
1838              b = bp2[2];
1839              *obptr++ = b;
1840              *obptr++ = g;
1841              *obptr++ = r;
1842              bp2 += 3;
1843            }
1844        }
1845      else
1846        {
1847          for (x = 0; x < width - 3; x += 4)
1848            {
1849              guint32 r1b0g0r0;
1850              guint32 g2r2b1g1;
1851              guint32 b3g3r3b2;
1852
1853              r1b0g0r0 = ((guint32 *)bp2)[0];
1854              g2r2b1g1 = ((guint32 *)bp2)[1];
1855              b3g3r3b2 = ((guint32 *)bp2)[2];
1856              ((guint32 *)obptr)[0] =
1857                (r1b0g0r0 & 0xff00) |
1858                ((r1b0g0r0 & 0xff0000) >> 16) |
1859                (((g2r2b1g1 & 0xff00) | (r1b0g0r0 & 0xff)) << 16);
1860              ((guint32 *)obptr)[1] =
1861                (g2r2b1g1 & 0xff0000ff) |
1862                ((r1b0g0r0 & 0xff000000) >> 16) |
1863                ((b3g3r3b2 & 0xff) << 16);
1864              ((guint32 *)obptr)[2] =
1865                (((g2r2b1g1 & 0xff0000) | (b3g3r3b2 & 0xff000000)) >> 16) |
1866                ((b3g3r3b2 & 0xff00) << 16) |
1867                ((b3g3r3b2 & 0xff0000));
1868              bp2 += 12;
1869              obptr += 12;
1870            }
1871          for (; x < width; x++)
1872            {
1873              r = bp2[0];
1874              g = bp2[1];
1875              b = bp2[2];
1876              *obptr++ = b;
1877              *obptr++ = g;
1878              *obptr++ = r;
1879              bp2 += 3;
1880            }
1881        }
1882      bptr += rowstride;
1883      obuf += bpl;
1884    }
1885}
1886#else
1887static void
1888gdk_rgb_convert_888_lsb (GdkImage *image,
1889                         gint x0, gint y0, gint width, gint height,
1890                         guchar *buf, int rowstride,
1891                         gint x_align, gint y_align, GdkRgbCmap *cmap)
1892{
1893  int x, y;
1894  guchar *obuf;
1895  gint bpl;
1896  guchar *bptr, *bp2;
1897  int r, g, b;
1898
1899  bptr = buf;
1900  bpl = image->bpl;
1901  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3;
1902  for (y = 0; y < height; y++)
1903    {
1904      bp2 = bptr;
1905      for (x = 0; x < width; x++)
1906        {
1907          r = bp2[0];
1908          g = bp2[1];
1909          b = bp2[2];
1910          obuf[x * 3] = b;
1911          obuf[x * 3 + 1] = g;
1912          obuf[x * 3 + 2] = r;
1913          bp2 += 3;
1914        }
1915      bptr += rowstride;
1916      obuf += bpl;
1917    }
1918}
1919#endif
1920
1921/* convert 24-bit packed to 32-bit unpacked */
1922/* todo: optimize this */
1923static void
1924gdk_rgb_convert_0888 (GdkImage *image,
1925                      gint x0, gint y0, gint width, gint height,
1926                      guchar *buf, int rowstride,
1927                      gint x_align, gint y_align, GdkRgbCmap *cmap)
1928{
1929  int x, y;
1930  guchar *obuf;
1931  gint bpl;
1932  guchar *bptr, *bp2;
1933  int r, g, b;
1934
1935  bptr = buf;
1936  bpl = image->bpl;
1937  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4;
1938  for (y = 0; y < height; y++)
1939    {
1940      bp2 = bptr;
1941      for (x = 0; x < width; x++)
1942        {
1943          r = bp2[0];
1944          g = bp2[1];
1945          b = bp2[2];
1946          ((guint32 *)obuf)[x] = (r << 16) | (g << 8) | b;
1947          bp2 += 3;
1948        }
1949      bptr += rowstride;
1950      obuf += bpl;
1951    }
1952}
1953
1954static void
1955gdk_rgb_convert_0888_br (GdkImage *image,
1956                         gint x0, gint y0, gint width, gint height,
1957                         guchar *buf, int rowstride,
1958                         gint x_align, gint y_align, GdkRgbCmap *cmap)
1959{
1960  int x, y;
1961  guchar *obuf;
1962  gint bpl;
1963  guchar *bptr, *bp2;
1964  int r, g, b;
1965
1966  bptr = buf;
1967  bpl = image->bpl;
1968  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4;
1969  for (y = 0; y < height; y++)
1970    {
1971      bp2 = bptr;
1972      for (x = 0; x < width; x++)
1973        {
1974          r = bp2[0];
1975          g = bp2[1];
1976          b = bp2[2];
1977          ((guint32 *)obuf)[x] = (b << 24) | (g << 16) | (r << 8);
1978          bp2 += 3;
1979        }
1980      bptr += rowstride;
1981      obuf += bpl;
1982    }
1983}
1984
1985static void
1986gdk_rgb_convert_8880_br (GdkImage *image,
1987                         gint x0, gint y0, gint width, gint height,
1988                         guchar *buf, int rowstride,
1989                         gint x_align, gint y_align, GdkRgbCmap *cmap)
1990{
1991  int x, y;
1992  guchar *obuf;
1993  gint bpl;
1994  guchar *bptr, *bp2;
1995  int r, g, b;
1996
1997  bptr = buf;
1998  bpl = image->bpl;
1999  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4;
2000  for (y = 0; y < height; y++)
2001    {
2002      bp2 = bptr;
2003      for (x = 0; x < width; x++)
2004        {
2005          r = bp2[0];
2006          g = bp2[1];
2007          b = bp2[2];
2008          ((guint32 *)obuf)[x] = (b << 16) | (g << 8) | r;
2009          bp2 += 3;
2010        }
2011      bptr += rowstride;
2012      obuf += bpl;
2013    }
2014}
2015
2016/* Generic truecolor/directcolor conversion function. Slow, but these
2017   are oddball modes. */
2018static void
2019gdk_rgb_convert_truecolor_lsb (GdkImage *image,
2020                               gint x0, gint y0, gint width, gint height,
2021                               guchar *buf, int rowstride,
2022                               gint x_align, gint y_align,
2023                               GdkRgbCmap *cmap)
2024{
2025  int x, y;
2026  guchar *obuf, *obptr;
2027  gint bpl;
2028  guchar *bptr, *bp2;
2029  gint r, g, b;
2030  gint r_right, r_left;
2031  gint g_right, g_left;
2032  gint b_right, b_left;
2033  gint bpp;
2034  guint32 pixel;
2035  gint i;
2036
2037  r_right = 8 - image_info->visual->red_prec;
2038  r_left = image_info->visual->red_shift;
2039  g_right = 8 - image_info->visual->green_prec;
2040  g_left = image_info->visual->green_shift;
2041  b_right = 8 - image_info->visual->blue_prec;
2042  b_left = image_info->visual->blue_shift;
2043  bpp = image_info->bpp;
2044  bptr = buf;
2045  bpl = image->bpl;
2046  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp;
2047  for (y = 0; y < height; y++)
2048    {
2049      obptr = obuf;
2050      bp2 = bptr;
2051      for (x = 0; x < width; x++)
2052        {
2053          r = bp2[0];
2054          g = bp2[1];
2055          b = bp2[2];
2056          pixel = ((r >> r_right) << r_left) |
2057            ((g >> g_right) << g_left) |
2058            ((b >> b_right) << b_left);
2059          for (i = 0; i < bpp; i++)
2060            {
2061              *obptr++ = pixel & 0xff;
2062              pixel >>= 8;
2063            }
2064          bp2 += 3;
2065        }
2066      bptr += rowstride;
2067      obuf += bpl;
2068    }
2069}
2070
2071static void
2072gdk_rgb_convert_truecolor_lsb_d (GdkImage *image,
2073                                 gint x0, gint y0, gint width, gint height,
2074                                 guchar *buf, int rowstride,
2075                                 gint x_align, gint y_align,
2076                                 GdkRgbCmap *cmap)
2077{
2078  int x, y;
2079  guchar *obuf, *obptr;
2080  gint bpl;
2081  guchar *bptr, *bp2;
2082  gint r, g, b;
2083  gint r_right, r_left, r_prec;
2084  gint g_right, g_left, g_prec;
2085  gint b_right, b_left, b_prec;
2086  gint bpp;
2087  guint32 pixel;
2088  gint i;
2089  gint dith;
2090  gint r1, g1, b1;
2091  const guchar *dmp;
2092
2093  r_right = 8 - image_info->visual->red_prec;
2094  r_left = image_info->visual->red_shift;
2095  r_prec = image_info->visual->red_prec;
2096  g_right = 8 - image_info->visual->green_prec;
2097  g_left = image_info->visual->green_shift;
2098  g_prec = image_info->visual->green_prec;
2099  b_right = 8 - image_info->visual->blue_prec;
2100  b_left = image_info->visual->blue_shift;
2101  b_prec = image_info->visual->blue_prec;
2102  bpp = image_info->bpp;
2103  bptr = buf;
2104  bpl = image->bpl;
2105  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp;
2106  for (y = 0; y < height; y++)
2107    {
2108      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
2109      obptr = obuf;
2110      bp2 = bptr;
2111      for (x = 0; x < width; x++)
2112        {
2113          r = bp2[0];
2114          g = bp2[1];
2115          b = bp2[2];
2116          dith = dmp[(x_align + x) & (DM_WIDTH - 1)] << 2;
2117          r1 = r + (dith >> r_prec);
2118          g1 = g + ((252 - dith) >> g_prec);
2119          b1 = b + (dith >> b_prec);
2120          pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) |
2121            (((g1 - (g1 >> g_prec)) >> g_right) << g_left) |
2122            (((b1 - (b1 >> b_prec)) >> b_right) << b_left);
2123          for (i = 0; i < bpp; i++)
2124            {
2125              *obptr++ = pixel & 0xff;
2126              pixel >>= 8;
2127            }
2128          bp2 += 3;
2129        }
2130      bptr += rowstride;
2131      obuf += bpl;
2132    }
2133}
2134
2135static void
2136gdk_rgb_convert_truecolor_msb (GdkImage *image,
2137                               gint x0, gint y0, gint width, gint height,
2138                               guchar *buf, int rowstride,
2139                               gint x_align, gint y_align,
2140                               GdkRgbCmap *cmap)
2141{
2142  int x, y;
2143  guchar *obuf, *obptr;
2144  gint bpl;
2145  guchar *bptr, *bp2;
2146  gint r, g, b;
2147  gint r_right, r_left;
2148  gint g_right, g_left;
2149  gint b_right, b_left;
2150  gint bpp;
2151  guint32 pixel;
2152  gint shift, shift_init;
2153
2154  r_right = 8 - image_info->visual->red_prec;
2155  r_left = image_info->visual->red_shift;
2156  g_right = 8 - image_info->visual->green_prec;
2157  g_left = image_info->visual->green_shift;
2158  b_right = 8 - image_info->visual->blue_prec;
2159  b_left = image_info->visual->blue_shift;
2160  bpp = image_info->bpp;
2161  bptr = buf;
2162  bpl = image->bpl;
2163  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp;
2164  shift_init = (bpp - 1) << 3;
2165  for (y = 0; y < height; y++)
2166    {
2167      obptr = obuf;
2168      bp2 = bptr;
2169      for (x = 0; x < width; x++)
2170        {
2171          r = bp2[0];
2172          g = bp2[1];
2173          b = bp2[2];
2174          pixel = ((r >> r_right) << r_left) |
2175            ((g >> g_right) << g_left) |
2176            ((b >> b_right) << b_left);
2177          for (shift = shift_init; shift >= 0; shift -= 8)
2178            {
2179              *obptr++ = (pixel >> shift) & 0xff;
2180            }
2181          bp2 += 3;
2182        }
2183      bptr += rowstride;
2184      obuf += bpl;
2185    }
2186}
2187
2188static void
2189gdk_rgb_convert_truecolor_msb_d (GdkImage *image,
2190                                 gint x0, gint y0, gint width, gint height,
2191                                 guchar *buf, int rowstride,
2192                                 gint x_align, gint y_align,
2193                                 GdkRgbCmap *cmap)
2194{
2195  int x, y;
2196  guchar *obuf, *obptr;
2197  gint bpl;
2198  guchar *bptr, *bp2;
2199  gint r, g, b;
2200  gint r_right, r_left, r_prec;
2201  gint g_right, g_left, g_prec;
2202  gint b_right, b_left, b_prec;
2203  gint bpp;
2204  guint32 pixel;
2205  gint shift, shift_init;
2206  gint dith;
2207  gint r1, g1, b1;
2208  const guchar *dmp;
2209
2210  r_right = 8 - image_info->visual->red_prec;
2211  r_left = image_info->visual->red_shift;
2212  r_prec = image_info->visual->red_prec;
2213  g_right = 8 - image_info->visual->green_prec;
2214  g_left = image_info->visual->green_shift;
2215  g_prec = image_info->visual->green_prec;
2216  b_right = 8 - image_info->visual->blue_prec;
2217  b_left = image_info->visual->blue_shift;
2218  b_prec = image_info->visual->blue_prec;
2219  bpp = image_info->bpp;
2220  bptr = buf;
2221  bpl = image->bpl;
2222  obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp;
2223  shift_init = (bpp - 1) << 3;
2224  for (y = 0; y < height; y++)
2225    {
2226      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
2227      obptr = obuf;
2228      bp2 = bptr;
2229      for (x = 0; x < width; x++)
2230        {
2231          r = bp2[0];
2232          g = bp2[1];
2233          b = bp2[2];
2234          dith = dmp[(x_align + x) & (DM_WIDTH - 1)] << 2;
2235          r1 = r + (dith >> r_prec);
2236          g1 = g + ((252 - dith) >> g_prec);
2237          b1 = b + (dith >> b_prec);
2238          pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) |
2239            (((g1 - (g1 >> g_prec)) >> g_right) << g_left) |
2240            (((b1 - (b1 >> b_prec)) >> b_right) << b_left);
2241          for (shift = shift_init; shift >= 0; shift -= 8)
2242            {
2243              *obptr++ = (pixel >> shift) & 0xff;
2244            }
2245          bp2 += 3;
2246        }
2247      bptr += rowstride;
2248      obuf += bpl;
2249    }
2250}
2251
2252/* This actually works for depths from 3 to 7 */
2253static void
2254gdk_rgb_convert_4 (GdkImage *image,
2255                   gint x0, gint y0, gint width, gint height,
2256                   guchar *buf, int rowstride,
2257                   gint x_align, gint y_align,
2258                   GdkRgbCmap *cmap)
2259{
2260  int x, y;
2261  gint bpl;
2262  guchar *obuf, *obptr;
2263  guchar *bptr, *bp2;
2264  gint r, g, b;
2265  const guchar *dmp;
2266  gint dith;
2267
2268  bptr = buf;
2269  bpl = image->bpl;
2270  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
2271  for (y = 0; y < height; y++)
2272    {
2273      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
2274      bp2 = bptr;
2275      obptr = obuf;
2276      for (x = 0; x < width; x += 1)
2277        {
2278          r = *bp2++;
2279          g = *bp2++;
2280          b = *bp2++;
2281          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3;
2282          obptr[0] = colorcube_d[(((r + dith) & 0x100) >> 2) |
2283                                (((g + 258 - dith) & 0x100) >> 5) |
2284                                (((b + dith) & 0x100) >> 8)];
2285          obptr++;
2286        }
2287      bptr += rowstride;
2288      obuf += bpl;
2289    }
2290}
2291
2292/* This actually works for depths from 3 to 7 */
2293static void
2294gdk_rgb_convert_gray4 (GdkImage *image,
2295                       gint x0, gint y0, gint width, gint height,
2296                       guchar *buf, int rowstride,
2297                       gint x_align, gint y_align, GdkRgbCmap *cmap)
2298{
2299  int x, y;
2300  gint bpl;
2301  guchar *obuf, *obptr;
2302  guchar *bptr, *bp2;
2303  gint r, g, b;
2304  gint shift;
2305
2306  bptr = buf;
2307  bpl = image->bpl;
2308  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
2309  shift = 9 - image_info->visual->depth;
2310  for (y = 0; y < height; y++)
2311    {
2312      bp2 = bptr;
2313      obptr = obuf;
2314      for (x = 0; x < width; x++)
2315        {
2316          r = *bp2++;
2317          g = *bp2++;
2318          b = *bp2++;
2319          obptr[0] = (g + ((b + r) >> 1)) >> shift;
2320          obptr++;
2321        }
2322      bptr += rowstride;
2323      obuf += bpl;
2324    }
2325}
2326
2327static void
2328gdk_rgb_convert_gray4_pack (GdkImage *image,
2329                            gint x0, gint y0, gint width, gint height,
2330                            guchar *buf, int rowstride,
2331                            gint x_align, gint y_align, GdkRgbCmap *cmap)
2332{
2333  int x, y;
2334  gint bpl;
2335  guchar *obuf, *obptr;
2336  guchar *bptr, *bp2;
2337  gint r, g, b;
2338  gint shift;
2339  guchar pix0, pix1;
2340  /* todo: this is hardcoded to big-endian. Make endian-agile. */
2341
2342  bptr = buf;
2343  bpl = image->bpl;
2344  obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1);
2345  shift = 9 - image_info->visual->depth;
2346  for (y = 0; y < height; y++)
2347    {
2348      bp2 = bptr;
2349      obptr = obuf;
2350      for (x = 0; x < width; x += 2)
2351        {
2352          r = *bp2++;
2353          g = *bp2++;
2354          b = *bp2++;
2355          pix0 = (g + ((b + r) >> 1)) >> shift;
2356          r = *bp2++;
2357          g = *bp2++;
2358          b = *bp2++;
2359          pix1 = (g + ((b + r) >> 1)) >> shift;
2360          obptr[0] = (pix0 << 4) | pix1;
2361          obptr++;
2362        }
2363      if (width & 1)
2364        {
2365          r = *bp2++;
2366          g = *bp2++;
2367          b = *bp2++;
2368          pix0 = (g + ((b + r) >> 1)) >> shift;
2369          obptr[0] = (pix0 << 4);
2370        }
2371      bptr += rowstride;
2372      obuf += bpl;
2373    }
2374}
2375
2376/* This actually works for depths from 3 to 7 */
2377static void
2378gdk_rgb_convert_gray4_d (GdkImage *image,
2379                       gint x0, gint y0, gint width, gint height,
2380                       guchar *buf, int rowstride,
2381                       gint x_align, gint y_align, GdkRgbCmap *cmap)
2382{
2383  int x, y;
2384  gint bpl;
2385  guchar *obuf, *obptr;
2386  guchar *bptr, *bp2;
2387  gint r, g, b;
2388  const guchar *dmp;
2389  gint prec, right;
2390  gint gray;
2391
2392  bptr = buf;
2393  bpl = image->bpl;
2394  obuf = ((guchar *)image->mem) + y0 * bpl + x0;
2395  prec = image_info->visual->depth;
2396  right = 8 - prec;
2397  for (y = 0; y < height; y++)
2398    {
2399      bp2 = bptr;
2400      obptr = obuf;
2401      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
2402      for (x = 0; x < width; x++)
2403        {
2404          r = *bp2++;
2405          g = *bp2++;
2406          b = *bp2++;
2407          gray = (g + ((b + r) >> 1)) >> 1;
2408          gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
2409          obptr[0] = (gray - (gray >> prec)) >> right;
2410          obptr++;
2411        }
2412      bptr += rowstride;
2413      obuf += bpl;
2414    }
2415}
2416
2417static void
2418gdk_rgb_convert_gray4_d_pack (GdkImage *image,
2419                              gint x0, gint y0, gint width, gint height,
2420                              guchar *buf, int rowstride,
2421                              gint x_align, gint y_align, GdkRgbCmap *cmap)
2422{
2423  int x, y;
2424  gint bpl;
2425  guchar *obuf, *obptr;
2426  guchar *bptr, *bp2;
2427  gint r, g, b;
2428  const guchar *dmp;
2429  gint prec, right;
2430  gint gray;
2431  guchar pix0, pix1;
2432  /* todo: this is hardcoded to big-endian. Make endian-agile. */
2433
2434  bptr = buf;
2435  bpl = image->bpl;
2436  obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1);
2437  prec = image_info->visual->depth;
2438  right = 8 - prec;
2439  for (y = 0; y < height; y++)
2440    {
2441      bp2 = bptr;
2442      obptr = obuf;
2443      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
2444      for (x = 0; x < width; x += 2)
2445        {
2446          r = *bp2++;
2447          g = *bp2++;
2448          b = *bp2++;
2449          gray = (g + ((b + r) >> 1)) >> 1;
2450          gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec;
2451          pix0 = (gray - (gray >> prec)) >> right;
2452          r = *bp2++;
2453          g = *bp2++;
2454          b = *bp2++;
2455          gray = (g + ((b + r) >> 1)) >> 1;
2456          gray += (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) >> prec;
2457          pix1 = (gray - (gray >> prec)) >> right;
2458          obptr[0] = (pix0 << 4) | pix1;
2459          obptr++;
2460        }
2461      if (width & 1)
2462        {
2463          r = *bp2++;
2464          g = *bp2++;
2465          b = *bp2++;
2466          gray = (g + ((b + r) >> 1)) >> 1;
2467          gray += (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) >> prec;
2468          pix0 = (gray - (gray >> prec)) >> right;
2469          obptr[0] = (pix0 << 4);
2470        }
2471      bptr += rowstride;
2472      obuf += bpl;
2473    }
2474}
2475
2476static void
2477gdk_rgb_convert_1 (GdkImage *image,
2478                   gint x0, gint y0, gint width, gint height,
2479                   guchar *buf, int rowstride,
2480                   gint x_align, gint y_align,
2481                   GdkRgbCmap *cmap)
2482{
2483  int x, y;
2484  gint bpl;
2485  guchar *obuf, *obptr;
2486  guchar *bptr, *bp2;
2487  gint r, g, b;
2488  const guchar *dmp;
2489  gint dith;
2490  guchar byte;
2491
2492  bptr = buf;
2493  bpl = image->bpl;
2494  obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 3);
2495  byte = 0; /* unnecessary, but it keeps gcc from complaining */
2496  for (y = 0; y < height; y++)
2497    {
2498      dmp = DM[(y_align + y) & (DM_HEIGHT - 1)];
2499      bp2 = bptr;
2500      obptr = obuf;
2501      for (x = 0; x < width; x++)
2502        {
2503          r = *bp2++;
2504          g = *bp2++;
2505          b = *bp2++;
2506          dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 4) | 4;
2507          byte += byte + (r + g + g + b + dith > 1020);
2508          if ((x & 7) == 7)
2509            {
2510              obptr[0] = byte;
2511              obptr++;
2512            }
2513        }
2514      if (x & 7)
2515        obptr[0] = byte << (8 - (x & 7));
2516      bptr += rowstride;
2517      obuf += bpl;
2518    }
2519}
2520
2521/* Returns a pointer to the stage buffer. */
2522static guchar *
2523gdk_rgb_ensure_stage (void)
2524{
2525  if (image_info->stage_buf == NULL)
2526    image_info->stage_buf = g_malloc (REGION_HEIGHT * STAGE_ROWSTRIDE);
2527  return image_info->stage_buf;
2528}
2529
2530/* This is slow. Speed me up, please. */
2531static void
2532gdk_rgb_32_to_stage (guchar *buf, gint rowstride, gint width, gint height)
2533{
2534  gint x, y;
2535  guchar *pi_start, *po_start;
2536  guchar *pi, *po;
2537
2538  pi_start = buf;
2539  po_start = gdk_rgb_ensure_stage ();
2540  for (y = 0; y < height; y++)
2541    {
2542      pi = pi_start;
2543      po = po_start;
2544      for (x = 0; x < width; x++)
2545        {
2546          *po++ = *pi++;
2547          *po++ = *pi++;
2548          *po++ = *pi++;
2549          pi++;
2550        }
2551      pi_start += rowstride;
2552      po_start += STAGE_ROWSTRIDE;
2553    }
2554}
2555
2556/* Generic 32bit RGB conversion function - convert to 24bit packed, then
2557   go from there. */
2558static void
2559gdk_rgb_convert_32_generic (GdkImage *image,
2560                            gint x0, gint y0, gint width, gint height,
2561                            guchar *buf, gint rowstride,
2562                            gint x_align, gint y_align, GdkRgbCmap *cmap)
2563{
2564  gdk_rgb_32_to_stage (buf, rowstride, width, height);
2565
2566  (*image_info->conv) (image, x0, y0, width, height,
2567                       image_info->stage_buf, STAGE_ROWSTRIDE,
2568                       x_align, y_align, cmap);
2569}
2570
2571/* Generic 32bit RGB conversion function - convert to 24bit packed, then
2572   go from there. */
2573static void
2574gdk_rgb_convert_32_generic_d (GdkImage *image,
2575                              gint x0, gint y0, gint width, gint height,
2576                              guchar *buf, gint rowstride,
2577                              gint x_align, gint y_align, GdkRgbCmap *cmap)
2578{
2579  gdk_rgb_32_to_stage (buf, rowstride, width, height);
2580
2581  (*image_info->conv_d) (image, x0, y0, width, height,
2582                         image_info->stage_buf, STAGE_ROWSTRIDE,
2583                         x_align, y_align, cmap);
2584}
2585
2586/* This is slow. Speed me up, please. */
2587static void
2588gdk_rgb_gray_to_stage (guchar *buf, gint rowstride, gint width, gint height)
2589{
2590  gint x, y;
2591  guchar *pi_start, *po_start;
2592  guchar *pi, *po;
2593  guchar gray;
2594
2595  pi_start = buf;
2596  po_start = gdk_rgb_ensure_stage ();
2597  for (y = 0; y < height; y++)
2598    {
2599      pi = pi_start;
2600      po = po_start;
2601      for (x = 0; x < width; x++)
2602        {
2603          gray = *pi++;
2604          *po++ = gray;
2605          *po++ = gray;
2606          *po++ = gray;
2607        }
2608      pi_start += rowstride;
2609      po_start += STAGE_ROWSTRIDE;
2610    }
2611}
2612
2613/* Generic gray conversion function - convert to 24bit packed, then go
2614   from there. */
2615static void
2616gdk_rgb_convert_gray_generic (GdkImage *image,
2617                              gint x0, gint y0, gint width, gint height,
2618                              guchar *buf, gint rowstride,
2619                              gint x_align, gint y_align, GdkRgbCmap *cmap)
2620{
2621  gdk_rgb_gray_to_stage (buf, rowstride, width, height);
2622
2623  (*image_info->conv) (image, x0, y0, width, height,
2624                       image_info->stage_buf, STAGE_ROWSTRIDE,
2625                       x_align, y_align, cmap);
2626}
2627
2628static void
2629gdk_rgb_convert_gray_generic_d (GdkImage *image,
2630                                gint x0, gint y0, gint width, gint height,
2631                                guchar *buf, gint rowstride,
2632                                gint x_align, gint y_align, GdkRgbCmap *cmap)
2633{
2634  gdk_rgb_gray_to_stage (buf, rowstride, width, height);
2635
2636  (*image_info->conv_d) (image, x0, y0, width, height,
2637                         image_info->stage_buf, STAGE_ROWSTRIDE,
2638                         x_align, y_align, cmap);
2639}
2640
2641/* Render grayscale using indexed method. */
2642static void
2643gdk_rgb_convert_gray_cmap (GdkImage *image,
2644                           gint x0, gint y0, gint width, gint height,
2645                           guchar *buf, gint rowstride,
2646                           gint x_align, gint y_align, GdkRgbCmap *cmap)
2647{
2648  (*image_info->conv_indexed) (image, x0, y0, width, height,
2649                               buf, rowstride,
2650                               x_align, y_align, image_info->gray_cmap);
2651}
2652
2653#if 0
2654static void
2655gdk_rgb_convert_gray_cmap_d (GdkImage *image,
2656                                gint x0, gint y0, gint width, gint height,
2657                                guchar *buf, gint rowstride,
2658                                gint x_align, gint y_align, GdkRgbCmap *cmap)
2659{
2660  (*image_info->conv_indexed_d) (image, x0, y0, width, height,
2661                                 buf, rowstride,
2662                                 x_align, y_align, image_info->gray_cmap);
2663}
2664#endif
2665
2666/* This is slow. Speed me up, please. */
2667static void
2668gdk_rgb_indexed_to_stage (guchar *buf, gint rowstride, gint width, gint height,
2669                          GdkRgbCmap *cmap)
2670{
2671  gint x, y;
2672  guchar *pi_start, *po_start;
2673  guchar *pi, *po;
2674  gint rgb;
2675
2676  pi_start = buf;
2677  po_start = gdk_rgb_ensure_stage ();
2678  for (y = 0; y < height; y++)
2679    {
2680      pi = pi_start;
2681      po = po_start;
2682      for (x = 0; x < width; x++)
2683        {
2684          rgb = cmap->colors[*pi++];
2685          *po++ = rgb >> 16;
2686          *po++ = (rgb >> 8) & 0xff;
2687          *po++ = rgb & 0xff;
2688        }
2689      pi_start += rowstride;
2690      po_start += STAGE_ROWSTRIDE;
2691    }
2692}
2693
2694/* Generic gray conversion function - convert to 24bit packed, then go
2695   from there. */
2696static void
2697gdk_rgb_convert_indexed_generic (GdkImage *image,
2698                                 gint x0, gint y0, gint width, gint height,
2699                                 guchar *buf, gint rowstride,
2700                                 gint x_align, gint y_align, GdkRgbCmap *cmap)
2701{
2702  gdk_rgb_indexed_to_stage (buf, rowstride, width, height, cmap);
2703
2704  (*image_info->conv) (image, x0, y0, width, height,
2705                       image_info->stage_buf, STAGE_ROWSTRIDE,
2706                       x_align, y_align, cmap);
2707}
2708
2709static void
2710gdk_rgb_convert_indexed_generic_d (GdkImage *image,
2711                                   gint x0, gint y0, gint width, gint height,
2712                                   guchar *buf, gint rowstride,
2713                                   gint x_align, gint y_align,
2714                                   GdkRgbCmap *cmap)
2715{
2716  gdk_rgb_indexed_to_stage (buf, rowstride, width, height, cmap);
2717
2718  (*image_info->conv_d) (image, x0, y0, width, height,
2719                         image_info->stage_buf, STAGE_ROWSTRIDE,
2720                         x_align, y_align, cmap);
2721}
2722
2723/* Select a conversion function based on the visual and a
2724   representative image. */
2725static void
2726gdk_rgb_select_conv (GdkImage *image)
2727{
2728  GdkByteOrder byte_order;
2729  gint depth, bpp, byterev;
2730  GdkVisualType vtype;
2731  guint32 red_mask, green_mask, blue_mask;
2732  GdkRgbConvFunc conv, conv_d;
2733  GdkRgbConvFunc conv_32, conv_32_d;
2734  GdkRgbConvFunc conv_gray, conv_gray_d;
2735  GdkRgbConvFunc conv_indexed, conv_indexed_d;
2736  gboolean mask_rgb, mask_bgr;
2737
2738  depth = image_info->visual->depth;
2739  bpp = ((GdkImagePrivate *)image)->ximage->bits_per_pixel;
2740
2741  byte_order = image->byte_order;
2742  if (gdk_rgb_verbose)
2743    g_print ("Chose visual 0x%x, image bpp=%d, %s first\n",
2744             (gint)(((GdkVisualPrivate *)image_info->visual)->xvisual->visualid),
2745             bpp, byte_order == GDK_LSB_FIRST ? "lsb" : "msb");
2746
2747#if G_BYTE_ORDER == G_BIG_ENDIAN
2748  byterev = (byte_order == GDK_LSB_FIRST);
2749#else
2750  byterev = (byte_order == GDK_MSB_FIRST);
2751#endif
2752
2753  vtype = image_info->visual->type;
2754  if (vtype == GDK_VISUAL_DIRECT_COLOR)
2755    vtype = GDK_VISUAL_TRUE_COLOR;
2756
2757  red_mask = image_info->visual->red_mask;
2758  green_mask = image_info->visual->green_mask;
2759  blue_mask = image_info->visual->blue_mask;
2760
2761  mask_rgb = red_mask == 0xff0000 && green_mask == 0xff00 && blue_mask == 0xff;
2762  mask_bgr = red_mask == 0xff && green_mask == 0xff00 && blue_mask == 0xff0000;
2763
2764  conv = NULL;
2765  conv_d = NULL;
2766
2767  conv_32 = gdk_rgb_convert_32_generic;
2768  conv_32_d = gdk_rgb_convert_32_generic_d;
2769
2770  conv_gray = gdk_rgb_convert_gray_generic;
2771  conv_gray_d = gdk_rgb_convert_gray_generic_d;
2772
2773  conv_indexed = gdk_rgb_convert_indexed_generic;
2774  conv_indexed_d = gdk_rgb_convert_indexed_generic_d;
2775
2776  image_info->dith_default = FALSE;
2777
2778  if (image_info->bitmap)
2779    conv = gdk_rgb_convert_1;
2780  else if (bpp == 16 && depth == 16 && !byterev &&
2781      red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f)
2782    {
2783      conv = gdk_rgb_convert_565;
2784      conv_d = gdk_rgb_convert_565_d;
2785      conv_gray = gdk_rgb_convert_565_gray;
2786      gdk_rgb_preprocess_dm_565 ();
2787    }
2788  else if (bpp == 16 && depth == 16 &&
2789           vtype == GDK_VISUAL_TRUE_COLOR && byterev &&
2790      red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f)
2791    conv = gdk_rgb_convert_565_br;
2792
2793  else if (bpp == 16 && depth == 15 &&
2794           vtype == GDK_VISUAL_TRUE_COLOR && !byterev &&
2795      red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f)
2796    conv = gdk_rgb_convert_555;
2797
2798  else if (bpp == 16 && depth == 15 &&
2799           vtype == GDK_VISUAL_TRUE_COLOR && byterev &&
2800      red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f)
2801    conv = gdk_rgb_convert_555_br;
2802
2803  /* I'm not 100% sure about the 24bpp tests - but testing will show*/
2804  else if (bpp == 24 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2805           ((mask_rgb && byte_order == GDK_LSB_FIRST) ||
2806            (mask_bgr && byte_order == GDK_MSB_FIRST)))
2807    conv = gdk_rgb_convert_888_lsb;
2808  else if (bpp == 24 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2809           ((mask_rgb && byte_order == GDK_MSB_FIRST) ||
2810            (mask_bgr && byte_order == GDK_LSB_FIRST)))
2811    conv = gdk_rgb_convert_888_msb;
2812#if G_BYTE_ORDER == G_BIG_ENDIAN
2813  else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2814           (mask_rgb && byte_order == GDK_LSB_FIRST))
2815    conv = gdk_rgb_convert_0888_br;
2816  else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2817           (mask_rgb && byte_order == GDK_MSB_FIRST))
2818    conv = gdk_rgb_convert_0888;
2819  else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2820           (mask_bgr && byte_order == GDK_MSB_FIRST))
2821    conv = gdk_rgb_convert_8880_br;
2822#else
2823  else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2824           (mask_rgb && byte_order == GDK_MSB_FIRST))
2825    conv = gdk_rgb_convert_0888_br;
2826  else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2827           (mask_rgb && byte_order == GDK_LSB_FIRST))
2828    conv = gdk_rgb_convert_0888;
2829  else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR &&
2830           (mask_bgr && byte_order == GDK_LSB_FIRST))
2831    conv = gdk_rgb_convert_8880_br;
2832#endif
2833
2834  else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST)
2835    {
2836      conv = gdk_rgb_convert_truecolor_lsb;
2837      conv_d = gdk_rgb_convert_truecolor_lsb_d;
2838    }
2839  else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_MSB_FIRST)
2840    {
2841      conv = gdk_rgb_convert_truecolor_msb;
2842      conv_d = gdk_rgb_convert_truecolor_msb_d;
2843    }
2844  else if (bpp == 8 && depth == 8 && (vtype == GDK_VISUAL_PSEUDO_COLOR
2845#ifdef ENABLE_GRAYSCALE
2846                                      || vtype == GDK_VISUAL_GRAYSCALE
2847#endif
2848                                      ))
2849    {
2850      image_info->dith_default = TRUE;
2851      conv = gdk_rgb_convert_8;
2852      if (vtype != GDK_VISUAL_GRAYSCALE)
2853        {
2854          if (image_info->nred_shades == 6 &&
2855              image_info->ngreen_shades == 6 &&
2856              image_info->nblue_shades == 6)
2857            conv_d = gdk_rgb_convert_8_d666;
2858          else
2859            conv_d = gdk_rgb_convert_8_d;
2860        }
2861      conv_indexed = gdk_rgb_convert_8_indexed;
2862      conv_gray = gdk_rgb_convert_gray_cmap;
2863    }
2864  else if (bpp == 8 && depth == 8 && (vtype == GDK_VISUAL_STATIC_GRAY
2865#ifdef not_ENABLE_GRAYSCALE
2866                                      || vtype == GDK_VISUAL_GRAYSCALE
2867#endif
2868                                      ))
2869    {
2870      conv = gdk_rgb_convert_gray8;
2871      conv_gray = gdk_rgb_convert_gray8_gray;
2872    }
2873  else if (bpp == 8 && depth < 8 && depth >= 2 &&
2874           (vtype == GDK_VISUAL_STATIC_GRAY
2875            || vtype == GDK_VISUAL_GRAYSCALE))
2876    {
2877      conv = gdk_rgb_convert_gray4;
2878      conv_d = gdk_rgb_convert_gray4_d;
2879    }
2880  else if (bpp == 8 && depth < 8 && depth >= 3)
2881    {
2882      conv = gdk_rgb_convert_4;
2883    }
2884  else if (bpp == 4 && depth <= 4 && depth >= 2 &&
2885           (vtype == GDK_VISUAL_STATIC_GRAY
2886            || vtype == GDK_VISUAL_GRAYSCALE))
2887    {
2888      conv = gdk_rgb_convert_gray4_pack;
2889      conv_d = gdk_rgb_convert_gray4_d_pack;
2890    }
2891
2892  if (!conv)
2893    {
2894      g_warning ("Visual type=%s depth=%d, image bpp=%d, %s first\n"
2895                 "is not supported by GdkRGB. Please submit a bug report\n"
2896                 "with the above values to bugzilla.gnome.org",
2897                 visual_names[vtype], depth, bpp,
2898                 byte_order == GDK_LSB_FIRST ? "lsb" : "msb");
2899      exit (1);
2900    }
2901 
2902  if (conv_d == NULL)
2903    conv_d = conv;
2904
2905  image_info->conv = conv;
2906  image_info->conv_d = conv_d;
2907
2908  image_info->conv_32 = conv_32;
2909  image_info->conv_32_d = conv_32_d;
2910
2911  image_info->conv_gray = conv_gray;
2912  image_info->conv_gray_d = conv_gray_d;
2913
2914  image_info->conv_indexed = conv_indexed;
2915  image_info->conv_indexed_d = conv_indexed_d;
2916}
2917
2918static gint horiz_idx;
2919static gint horiz_y = REGION_HEIGHT;
2920static gint vert_idx;
2921static gint vert_x = REGION_WIDTH;
2922static gint tile_idx;
2923static gint tile_x = REGION_WIDTH;
2924static gint tile_y1 = REGION_HEIGHT;
2925static gint tile_y2 = REGION_HEIGHT;
2926
2927#ifdef VERBOSE
2928static gint sincelast;
2929#endif
2930
2931/* Defining NO_FLUSH can cause inconsistent screen updates, but is useful
2932   for performance evaluation. */
2933
2934#undef NO_FLUSH
2935
2936static gint
2937gdk_rgb_alloc_scratch_image ()
2938{
2939  if (static_image_idx == N_REGIONS)
2940    {
2941#ifndef NO_FLUSH
2942      gdk_flush ();
2943#endif
2944#ifdef VERBOSE
2945      g_print ("flush, %d puts since last flush\n", sincelast);
2946      sincelast = 0;
2947#endif
2948      static_image_idx = 0;
2949
2950      /* Mark all regions that we might be filling in as completely
2951       * full, to force new tiles to be allocated for subsequent
2952       * images
2953       */
2954      horiz_y = REGION_HEIGHT;
2955      vert_x = REGION_WIDTH;
2956      tile_x = REGION_WIDTH;
2957      tile_y1 = tile_y2 = REGION_HEIGHT;
2958    }
2959  return static_image_idx++;
2960}
2961
2962static GdkImage *
2963gdk_rgb_alloc_scratch (gint width, gint height, gint *x0, gint *y0)
2964{
2965  GdkImage *image;
2966  gint idx;
2967
2968  if (width >= (REGION_WIDTH >> 1))
2969    {
2970      if (height >= (REGION_HEIGHT >> 1))
2971        {
2972          idx = gdk_rgb_alloc_scratch_image ();
2973          *x0 = 0;
2974          *y0 = 0;
2975        }
2976      else
2977        {
2978          if (height + horiz_y > REGION_HEIGHT)
2979            {
2980              horiz_idx = gdk_rgb_alloc_scratch_image ();
2981              horiz_y = 0;
2982            }
2983          idx = horiz_idx;
2984          *x0 = 0;
2985          *y0 = horiz_y;
2986          horiz_y += height;
2987        }
2988    }
2989  else
2990    {
2991      if (height >= (REGION_HEIGHT >> 1))
2992        {
2993          if (width + vert_x > REGION_WIDTH)
2994            {
2995              vert_idx = gdk_rgb_alloc_scratch_image ();
2996              vert_x = 0;
2997            }
2998          idx = vert_idx;
2999          *x0 = vert_x;
3000          *y0 = 0;
3001          /* using 3 and -4 would be slightly more efficient on 32-bit machines
3002             with > 1bpp displays */
3003          vert_x += (width + 7) & -8;
3004        }
3005      else
3006        {
3007          if (width + tile_x > REGION_WIDTH)
3008            {
3009              tile_y1 = tile_y2;
3010              tile_x = 0;
3011            }
3012          if (height + tile_y1 > REGION_HEIGHT)
3013            {
3014              tile_idx = gdk_rgb_alloc_scratch_image ();
3015              tile_x = 0;
3016              tile_y1 = 0;
3017              tile_y2 = 0;
3018            }
3019          if (height + tile_y1 > tile_y2)
3020            tile_y2 = height + tile_y1;
3021          idx = tile_idx;
3022          *x0 = tile_x;
3023          *y0 = tile_y1;
3024          tile_x += (width + 7) & -8;
3025        }
3026    }
3027  image = static_image[idx * static_n_images / N_REGIONS];
3028  *x0 += REGION_WIDTH * (idx % (N_REGIONS / static_n_images));
3029#ifdef VERBOSE
3030  g_print ("index %d, x %d, y %d (%d x %d)\n", idx, *x0, *y0, width, height);
3031  sincelast++;
3032#endif
3033  return image;
3034}
3035
3036static void
3037gdk_draw_rgb_image_core (GdkDrawable *drawable,
3038                         GdkGC *gc,
3039                         gint x,
3040                         gint y,
3041                         gint width,
3042                         gint height,
3043                         guchar *buf,
3044                         gint pixstride,
3045                         gint rowstride,
3046                         GdkRgbConvFunc conv,
3047                         GdkRgbCmap *cmap,
3048                         gint xdith,
3049                         gint ydith)
3050{
3051  gint y0, x0;
3052  gint xs0, ys0;
3053  GdkImage *image;
3054  gint width1, height1;
3055  guchar *buf_ptr;
3056
3057  if (image_info->bitmap)
3058    {
3059      if (image_info->own_gc == NULL)
3060        {
3061          GdkColor color;
3062
3063          image_info->own_gc = gdk_gc_new (drawable);
3064          gdk_color_white (image_info->cmap, &color);
3065          gdk_gc_set_foreground (image_info->own_gc, &color);
3066          gdk_color_black (image_info->cmap, &color);
3067          gdk_gc_set_background (image_info->own_gc, &color);
3068        }
3069      gc = image_info->own_gc;
3070    }
3071  for (y0 = 0; y0 < height; y0 += REGION_HEIGHT)
3072    {
3073      height1 = MIN (height - y0, REGION_HEIGHT);
3074      for (x0 = 0; x0 < width; x0 += REGION_WIDTH)
3075        {
3076          width1 = MIN (width - x0, REGION_WIDTH);
3077          buf_ptr = buf + y0 * rowstride + x0 * pixstride;
3078
3079          image = gdk_rgb_alloc_scratch (width1, height1, &xs0, &ys0);
3080
3081          conv (image, xs0, ys0, width1, height1, buf_ptr, rowstride,
3082                x + x0 + xdith, y + y0 + ydith, cmap);
3083
3084#ifndef DONT_ACTUALLY_DRAW
3085          gdk_draw_image (drawable, gc,
3086                          image, xs0, ys0, x + x0, y + y0, width1, height1);
3087#endif
3088        }
3089    }
3090}
3091
3092
3093void
3094gdk_draw_rgb_image (GdkDrawable *drawable,
3095                    GdkGC *gc,
3096                    gint x,
3097                    gint y,
3098                    gint width,
3099                    gint height,
3100                    GdkRgbDither dith,
3101                    guchar *rgb_buf,
3102                    gint rowstride)
3103{
3104  if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL &&
3105                                      !image_info->dith_default))
3106    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3107                             rgb_buf, 3, rowstride, image_info->conv, NULL,
3108                             0, 0);
3109  else
3110    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3111                             rgb_buf, 3, rowstride, image_info->conv_d, NULL,
3112                             0, 0);
3113}
3114
3115void
3116gdk_draw_rgb_image_dithalign (GdkDrawable *drawable,
3117                              GdkGC *gc,
3118                              gint x,
3119                              gint y,
3120                              gint width,
3121                              gint height,
3122                              GdkRgbDither dith,
3123                              guchar *rgb_buf,
3124                              gint rowstride,
3125                              gint xdith,
3126                              gint ydith)
3127{
3128  if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL &&
3129                                      !image_info->dith_default))
3130    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3131                             rgb_buf, 3, rowstride, image_info->conv, NULL,
3132                             xdith, ydith);
3133  else
3134    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3135                             rgb_buf, 3, rowstride, image_info->conv_d, NULL,
3136                             xdith, ydith);
3137}
3138
3139void
3140gdk_draw_rgb_32_image (GdkDrawable *drawable,
3141                       GdkGC *gc,
3142                       gint x,
3143                       gint y,
3144                       gint width,
3145                       gint height,
3146                       GdkRgbDither dith,
3147                       guchar *buf,
3148                       gint rowstride)
3149{
3150  if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL &&
3151                                      !image_info->dith_default))
3152    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3153                             buf, 4, rowstride,
3154                             image_info->conv_32, NULL, 0, 0);
3155  else
3156    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3157                             buf, 4, rowstride,
3158                             image_info->conv_32_d, NULL, 0, 0);
3159}
3160
3161static void
3162gdk_rgb_make_gray_cmap (GdkRgbInfo *info)
3163{
3164  guint32 rgb[256];
3165  gint i;
3166
3167  for (i = 0; i < 256; i++)
3168    rgb[i] = (i << 16)  | (i << 8) | i;
3169  info->gray_cmap = gdk_rgb_cmap_new (rgb, 256);
3170}
3171
3172void
3173gdk_draw_gray_image (GdkDrawable *drawable,
3174                     GdkGC *gc,
3175                     gint x,
3176                     gint y,
3177                     gint width,
3178                     gint height,
3179                     GdkRgbDither dith,
3180                     guchar *buf,
3181                     gint rowstride)
3182{
3183  if (image_info->bpp == 1 &&
3184      image_info->gray_cmap == NULL &&
3185      (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
3186       image_info->visual->type == GDK_VISUAL_GRAYSCALE))
3187    gdk_rgb_make_gray_cmap (image_info);
3188 
3189  if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL &&
3190                                      !image_info->dith_default))
3191    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3192                             buf, 1, rowstride,
3193                             image_info->conv_gray, NULL, 0, 0);
3194  else
3195    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3196                             buf, 1, rowstride,
3197                             image_info->conv_gray_d, NULL, 0, 0);
3198}
3199
3200GdkRgbCmap *
3201gdk_rgb_cmap_new (guint32 *colors, gint n_colors)
3202{
3203  GdkRgbCmap *cmap;
3204  int i, j;
3205  guint32 rgb;
3206
3207  g_return_val_if_fail (n_colors >= 0, NULL);
3208  g_return_val_if_fail (n_colors <= 256, NULL);
3209  cmap = g_new (GdkRgbCmap, 1);
3210  memcpy (cmap->colors, colors, n_colors * sizeof(guint32));
3211  if (image_info->bpp == 1 &&
3212      (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR ||
3213       image_info->visual->type == GDK_VISUAL_GRAYSCALE))
3214    for (i = 0; i < n_colors; i++)
3215      {
3216        rgb = colors[i];
3217        j = ((rgb & 0xf00000) >> 12) |
3218                   ((rgb & 0xf000) >> 8) |
3219                   ((rgb & 0xf0) >> 4);
3220#ifdef VERBOSE
3221        g_print ("%d %x %x %d\n", i, j, colorcube[j]);
3222#endif
3223        cmap->lut[i] = colorcube[j];
3224      }
3225  return cmap;
3226}
3227
3228void
3229gdk_rgb_cmap_free (GdkRgbCmap *cmap)
3230{
3231  g_free (cmap);
3232}
3233
3234void
3235gdk_draw_indexed_image (GdkDrawable *drawable,
3236                        GdkGC *gc,
3237                        gint x,
3238                        gint y,
3239                        gint width,
3240                        gint height,
3241                        GdkRgbDither dith,
3242                        guchar *buf,
3243                        gint rowstride,
3244                        GdkRgbCmap *cmap)
3245{
3246  if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL &&
3247                                      !image_info->dith_default))
3248    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3249                             buf, 1, rowstride,
3250                             image_info->conv_indexed, cmap, 0, 0);
3251  else
3252    gdk_draw_rgb_image_core (drawable, gc, x, y, width, height,
3253                             buf, 1, rowstride,
3254                             image_info->conv_indexed_d, cmap, 0, 0);
3255}
3256
3257gboolean
3258gdk_rgb_ditherable (void)
3259{
3260  return (image_info->conv != image_info->conv_d);
3261}
3262
3263GdkColormap *
3264gdk_rgb_get_cmap (void)
3265{
3266  gdk_rgb_init ();
3267  return image_info->cmap;
3268}
3269
3270GdkVisual *
3271gdk_rgb_get_visual (void)
3272{
3273  gdk_rgb_init ();
3274  return image_info->visual;
3275}
Note: See TracBrowser for help on using the repository browser.