Index: reactos/win32ss/gdi/ntgdi/palette.c
===================================================================
--- reactos/win32ss/gdi/ntgdi/palette.c	(revision 75391)
+++ reactos/win32ss/gdi/ntgdi/palette.c	(working copy)
@@ -515,10 +515,13 @@
 NtGdiCreateHalftonePalette(HDC  hDC)
 {
     int i, r, g, b;
-    PALETTEENTRY PalEntries[256];
+    BYTE *x, *y;
+    int c1, c2;
+    PALETTEENTRY clr;
     PPALETTE ppal;
     PDC pdc;
     HPALETTE hpal = NULL;
+    c2=0;
 
     pdc = DC_LockDc(hDC);
     if (!pdc)
@@ -527,28 +530,81 @@
         return NULL;
     }
 
-    RtlZeroMemory(PalEntries, sizeof(PalEntries));
-
-    /* First and last ten entries are default ones */
-    for (i = 0; i < 10; i++)
-    {
-        PalEntries[i].peRed = g_sysPalTemplate[i].peRed;
-        PalEntries[i].peGreen = g_sysPalTemplate[i].peGreen;
-        PalEntries[i].peBlue = g_sysPalTemplate[i].peBlue;
-
-        PalEntries[246 + i].peRed = g_sysPalTemplate[10 + i].peRed;
-        PalEntries[246 + i].peGreen = g_sysPalTemplate[10 + i].peGreen;
-        PalEntries[246 + i].peBlue = g_sysPalTemplate[10 + i].peBlue;
-    }
-
     ppal = PALETTE_ShareLockPalette(pdc->dclevel.hpal);
     if (ppal && (ppal->flFlags & PAL_INDEXED))
     {
-        /* FIXME: optimize the palette for the current palette */
-        UNIMPLEMENTED;
+        x=(BYTE *)ExAllocatePoolWithTag(PagedPool,256*sizeof(USHORT),TAG_PALETTE); // value
+        if(!x)
+        {
+           if (ppal) PALETTE_ShareUnlockPalette(ppal);
+           DC_UnlockDc(pdc);
+           return INVALID_HANDLE_VALUE;
+        }
+        y=(BYTE *)ExAllocatePoolWithTag(PagedPool,256*sizeof(USHORT),TAG_PALETTE); // index
+        if(!y)
+        {
+           ExFreePoolWithTag(x,TAG_PALETTE);
+           if (ppal) PALETTE_ShareUnlockPalette(ppal);
+           DC_UnlockDc(pdc);
+           return INVALID_HANDLE_VALUE;
+        }
+        // not using system colors here. As long as black and white are present, palette is valid for dither
+        // adjust the colors so their components can divide by 4, so dithering doesn't cause fractions
+        // while at it, sort the palette, while dithering it's easier to pick adjacent colors
+        // length is still O(n*n), huge. No way around that 
+        DPRINT1("NtGdiCreateHalftonePalette, indexed case. Beginning...\n");
+        for(i=0; i<(ppal->NumColors-1); i++)
+        {
+           x[i]=0;
+           for(c1=i; c1<ppal->NumColors; c1++)
+           {
+              c2=clr.peRed+clr.peGreen+clr.peBlue;
+              if(c2<x[i])
+              {
+                 x[i]=c2;
+                 y[i]=c1;
+              }
+           }
+           clr.peRed=ppal->IndexedColors[c1].peRed+1;
+           clr.peRed=clr.peRed-clr.peRed%4;
+           clr.peGreen=ppal->IndexedColors[c1].peGreen+1;
+           clr.peGreen=clr.peGreen-clr.peGreen%4;
+           clr.peBlue=ppal->IndexedColors[c1].peBlue+1;
+           clr.peBlue=clr.peBlue-clr.peBlue%4;
+           ppal->IndexedColors[i].peRed=clr.peRed;
+           ppal->IndexedColors[i].peGreen=clr.peGreen;
+           ppal->IndexedColors[i].peBlue=clr.peBlue;
+        }
+        ExFreePoolWithTag(x,TAG_PALETTE);
+        ExFreePoolWithTag(y,TAG_PALETTE);
+        c2=0;
+        for(c1=1; c1<ppal->NumColors; c1++)
+        {
+           if((ppal->IndexedColors[c1].peRed==ppal->IndexedColors[c1-1].peRed)&&
+              (ppal->IndexedColors[c1].peGreen==ppal->IndexedColors[c1-1].peGreen)&&
+              (ppal->IndexedColors[c1].peBlue==ppal->IndexedColors[c1-1].peBlue))
+              c2++;
+           if((c1+c2)<ppal->NumColors)
+           {
+              ppal->IndexedColors[c1].peRed=ppal->IndexedColors[c1+c2].peRed;
+              ppal->IndexedColors[c1].peGreen=ppal->IndexedColors[c1+c2].peGreen;
+              ppal->IndexedColors[c1].peBlue=ppal->IndexedColors[c1+c2].peBlue;
+           }
+        }
+        DPRINT1("-Complete.\n");
     }
     else
     {
+         /* First and last ten entries are default ones */
+         for (i = 1; i < 10; i++)
+         {
+            ppal->IndexedColors[i].peRed = g_sysPalTemplate[i].peRed;
+            ppal->IndexedColors[i].peGreen = g_sysPalTemplate[i].peGreen;
+            ppal->IndexedColors[i].peBlue = g_sysPalTemplate[i].peBlue;
+            ppal->IndexedColors[246 + i].peRed = g_sysPalTemplate[10 + i].peRed;
+            ppal->IndexedColors[246 + i].peGreen = g_sysPalTemplate[10 + i].peGreen;
+            ppal->IndexedColors[246 + i].peBlue = g_sysPalTemplate[10 + i].peBlue;
+        }
         for (r = 0; r < 6; r++)
         {
             for (g = 0; g < 6; g++)
@@ -556,19 +612,28 @@
                 for (b = 0; b < 6; b++)
                 {
                     i = r + g*6 + b*36 + 10;
-                    PalEntries[i].peRed = r * 51;
-                    PalEntries[i].peGreen = g * 51;
-                    PalEntries[i].peBlue = b * 51;
+                    ppal->IndexedColors[i].peRed = r * 44;
+                    ppal->IndexedColors[i].peGreen = g * 44;
+                    ppal->IndexedColors[i].peBlue = b * 44;
                 }
             }
         }
-
         for (i = 216; i < 246; i++)
         {
-            int v = (i - 216) << 3;
-            PalEntries[i].peRed = v;
-            PalEntries[i].peGreen = v;
-            PalEntries[i].peBlue = v;
+            clr.peRed=i+4;
+            clr.peGreen=i+4;
+            clr.peBlue=i+4;
+            ppal->IndexedColors[i].peRed = clr.peRed+4;
+            ppal->IndexedColors[i].peGreen = clr.peGreen;
+            ppal->IndexedColors[i].peBlue = clr.peBlue;
+            i++;
+            ppal->IndexedColors[i].peRed = clr.peRed;
+            ppal->IndexedColors[i].peGreen = clr.peGreen+4;
+            ppal->IndexedColors[i].peBlue = clr.peBlue;
+            i++;
+            ppal->IndexedColors[i].peRed = clr.peRed;
+            ppal->IndexedColors[i].peGreen = clr.peGreen;
+            ppal->IndexedColors[i].peBlue = clr.peBlue+4;
         }
     }
 
@@ -577,7 +642,7 @@
 
     DC_UnlockDc(pdc);
 
-    ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED, 256, PalEntries, 0, 0, 0);
+    ppal = PALETTE_AllocPalWithHandle(PAL_INDEXED, 256-c2, ppal->IndexedColors, 0, 0, 0);
     if (ppal)
     {
         hpal = ppal->BaseObject.hHmgr;
