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