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