예제 #1
0
        public void convert_4x4texel_b(byte[] tex, int width, int height, byte[] data, Color[] pal, ImageTexeler.LockBitmap rgbaOut)
        {
            var list1 = new List <uint>();

            for (int i = 0; i < (tex.Length + 1) / 4; ++i)
            {
                list1.Add(LibNDSFormats.Utils.Read4BytesAsUInt32(tex, i * 4));
            }

            var list2 = new List <UInt16>();

            for (int i = 0; i < (data.Length + 1) / 2; ++i)
            {
                list2.Add(LibNDSFormats.Utils.Read2BytesAsUInt16(data, i * 2));
            }
            var b = convert_4x4texel(list1.ToArray(), width, height, list2.ToArray(), pal, rgbaOut);
        }
        public ImageIndexer(List <Bitmap> bl, int paletteCount, bool useAlpha, int transpCol)
        {
            this.bl           = bl;
            this.paletteCount = paletteCount;
            this.useAlpha     = useAlpha;

            boxColorCount = bl.Count * 3;
            //COMPUTE FREQUENCY TABLE

            freqTable = new Dictionary <MultiColor, int>();

            //Quick check just in case...
            width  = bl[0].Width;
            height = bl[0].Height;
            foreach (Bitmap b in bl)
            {
                if (b.Width != width || b.Height != height)
                {
                    throw new Exception("Not all images have the same size!!");
                }
            }


            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    MultiColor c = new MultiColor(boxColorCount);
                    for (int i = 0; i < bl.Count; i++)
                    {
                        NSMBe4.NSBMD.ImageTexeler.LockBitmap iii = new NSBMD.ImageTexeler.LockBitmap(bl[i]);
                        iii.LockBits();
                        c.setColor(i, iii.GetPixel(x, y));
                        iii.UnlockBits();
                    }
                    c.calcHash();
                    if (!c.allTransparent())
                    {
                        if (freqTable.ContainsKey(c))
                        {
                            freqTable[c]++;
                        }
                        else
                        {
                            freqTable[c] = 1;
                        }
                    }
                }
            }

            int ct = 0;

            foreach (MultiColor c in freqTable.Keys)
            {
                if (c.someTransparent())
                {
                    ct++;
                }
            }
            Console.Out.WriteLine("Transparent: " + ct);


            Dictionary <MultiColor, int> newFreqTable = new Dictionary <MultiColor, int>();

            foreach (MultiColor c in freqTable.Keys)
            {
                if (!c.deleteFlag)
                {
                    int cnt = freqTable[c];
                    foreach (MultiColor c2 in freqTable.Keys)
                    {
                        if (c2 == null)
                        {
                            continue;
                        }
                        if (c2.deleteFlag)
                        {
                            continue;
                        }
                        if (c2 == c)
                        {
                            continue;
                        }

                        if (c.diff(c2) == 0)
                        {
                            cnt += freqTable[c2];
                            c.merge(c2);
                            c2.deleteFlag = true;
                        }
                    }
                    c.deleteFlag = true;
                    c.removeAllTransparent();
                    newFreqTable.Add(c, cnt);
                }
            }
            freqTable = newFreqTable;

            ct = 0;
            foreach (MultiColor c in freqTable.Keys)
            {
                if (c.someTransparent())
                {
                    ct++;
                }
            }
            Console.Out.WriteLine("Transparent2: " + ct);

            // NOW CREATE THE PALETTE ZONES
            Box startBox = shrinkBox(new Box(boxColorCount));

            boxes = new List <Box>();
            boxes.Add(startBox);

            while (boxes.Count < (useAlpha ? paletteCount - 1 : paletteCount))
            {
                Console.Out.WriteLine(boxes.Count);
                Box bo = getDominantBox();
                if (bo == null)
                {
                    break;
                }

                split(bo);
            }


            multiPalette = new MultiColor[paletteCount];
            for (int j = useAlpha ? 1 : 0; j < paletteCount; j++)
            {
                if ((useAlpha ? j : j + 1) <= boxes.Count)
                {
                    multiPalette[j] = boxes[useAlpha ? j - 1 : j].center();
                }
            }

            //NOW CREATE THE PALETTE COLORS
            palettes = new Color[bl.Count][];
            for (int i = 0; i < bl.Count; i++)
            {
                palettes[i] = new Color[paletteCount];
                for (int j = useAlpha ? 1 : 0; j < paletteCount; j++)
                {
                    if ((useAlpha ? j : j + 1) > boxes.Count)
                    {
                        palettes[i][j] = palettes[i][j - 1];//Color.Fuchsia;
                    }
                    else
                    {
                        palettes[i][j] = boxes[useAlpha ? j - 1 : j].center().getColor(i);
                    }
                    //                Console.Out.WriteLine(i + ": " + boxes[i] + ": "+ palette[i]);
                }
                if (useAlpha)
                {
                    palettes[i][0] = Color.Transparent;
                }
            }

            //NOW MAP ORIGINAL COLORS TO PALETTE ENTRIES
            colorTable = new Dictionary <MultiColor, byte>();
            foreach (MultiColor c in freqTable.Keys)
            {
                colorTable[c] = closestMultiColor(c);
            }

            //NOW INDEX THE WHOLE IMAGES
            imageData = new byte[width, height];
            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    MultiColor c = new MultiColor(boxColorCount);
                    for (int i = 0; i < bl.Count; i++)
                    {
                        NSMBe4.NSBMD.ImageTexeler.LockBitmap iii = new NSBMD.ImageTexeler.LockBitmap(bl[i]);
                        iii.LockBits();
                        c.setColor(i, iii.GetPixel(x, y));
                        iii.UnlockBits();
                    }
                    c.calcHash();
                    if (c.allTransparent())
                    {
                        imageData[x, y] = (byte)transpCol;
                    }
                    else
                    {
                        imageData[x, y] = closestMultiColor(c);
                    }
                }
            }

            Console.Out.WriteLine("DONE");

            /*
             *
             *  }*/
        }
예제 #3
0
        public bool convert_4x4texel(uint[] tex, int width, int height, UInt16[] data, Color[] pal, ImageTexeler.LockBitmap rgbaOut)
        {
            int w = width / 4;
            int h = height / 4;

            // traverse 'w x h blocks' of 4x4-texel
            for (int y = 0; y < h; y++)
            {
                for (int x = 0; x < w; x++)
                {
                    int    index = y * w + x;
                    UInt32 t     = tex[index];
                    UInt16 d     = data[index];
                    UInt16 addr  = (ushort)(d & 0x3fff);
                    UInt16 mode  = (ushort)((d >> 14) & 3);

                    // traverse every texel in the 4x4 texels
                    for (int r = 0; r < 4; r++)
                    {
                        for (int c = 0; c < 4; c++)
                        {
                            int   texel = (int)((t >> ((r * 4 + c) * 2)) & 3);
                            Color pixel = rgbaOut.GetPixel((x * 4 + c), (y * 4 + r));

                            switch (mode)
                            {
                            case 0:
                                pixel = pal[(addr << 1) + texel];
                                if (texel == 3)
                                {
                                    pixel = Color.Transparent;                 // make it transparent, alpha = 0
                                }
                                break;

                            case 2:
                                pixel = pal[(addr << 1) + texel];
                                break;

                            case 1:
                                switch (texel)
                                {
                                case 0:
                                case 1:
                                    pixel = pal[(addr << 1) + texel];
                                    break;

                                case 2:
                                    byte R = (byte)((pal[(addr << 1)].R + pal[(addr << 1) + 1].R) / 2L);
                                    byte G = (byte)((pal[(addr << 1)].G + pal[(addr << 1) + 1].G) / 2L);
                                    byte B = (byte)((pal[(addr << 1)].B + pal[(addr << 1) + 1].B) / 2L);
                                    byte A = 0xff;
                                    pixel = Color.FromArgb(A, R, G, B);
                                    break;

                                case 3:
                                    pixel = Color.Transparent;         // make it transparent, alpha = 0
                                    break;
                                }
                                break;

                            case 3:
                                switch (texel)
                                {
                                case 0:
                                case 1:
                                    pixel = pal[(addr << 1) + texel];
                                    break;

                                case 2:
                                {
                                    byte R = (byte)((pal[(addr << 1)].R * 5L + pal[(addr << 1) + 1].R * 3L) / 8);
                                    byte G = (byte)((pal[(addr << 1)].G * 5L + pal[(addr << 1) + 1].G * 3L) / 8);
                                    byte B = (byte)((pal[(addr << 1)].B * 5L + pal[(addr << 1) + 1].B * 3L) / 8);
                                    byte A = 0xff;
                                    pixel = Color.FromArgb(A, R, G, B);
                                    break;
                                }

                                case 3:
                                {
                                    byte R = (byte)((pal[(addr << 1)].R * 3L + pal[(addr << 1) + 1].R * 5L) / 8);
                                    byte G = (byte)((pal[(addr << 1)].G * 3L + pal[(addr << 1) + 1].G * 5L) / 8);
                                    byte B = (byte)((pal[(addr << 1)].B * 3L + pal[(addr << 1) + 1].B * 5L) / 8);
                                    byte A = 0xff;
                                    pixel = Color.FromArgb(A, R, G, B);
                                    break;
                                }
                                }
                                break;
                            }
                            rgbaOut.SetPixel((x * 4 + c), (y * 4 + r), pixel);
                            //rgbaOut[(y * 4 + r) * width + (x * 4 + c)] = pixel;
                        }
                    }
                }
            }
            return(true);
        }