示例#1
0
        public static string CodecString(N64Codec codec)
        {
            switch (codec)
            {
            case N64Codec.RGBA16: return("rgba16");

            case N64Codec.RGBA32: return("rgba32");

            case N64Codec.IA16: return("ia16");

            case N64Codec.IA8: return("ia8");

            case N64Codec.IA4: return("ia4");

            case N64Codec.I8: return("i8");

            case N64Codec.I4: return("i4");

            case N64Codec.CI8: return("ci8");

            case N64Codec.CI4: return("ci4");

            case N64Codec.ONEBPP: return("1bpp");
            }
            return("unk");
        }
示例#2
0
        private static N64Codec WhichCodec(int idx)
        {
            N64Codec viewerCodec = N64Codec.RGBA16;

            switch (idx)
            {
            case 0: viewerCodec = N64Codec.RGBA16; break;

            case 1: viewerCodec = N64Codec.RGBA32; break;

            case 2: viewerCodec = N64Codec.IA16; break;

            case 3: viewerCodec = N64Codec.IA8; break;

            case 4: viewerCodec = N64Codec.IA4; break;

            case 5: viewerCodec = N64Codec.I8; break;

            case 6: viewerCodec = N64Codec.I4; break;

            case 7: viewerCodec = N64Codec.CI8; break;

            case 8: viewerCodec = N64Codec.CI4; break;

            case 9: viewerCodec = N64Codec.ONEBPP; break;
            }
            return(viewerCodec);
        }
示例#3
0
        // return number of bytes needed to encode numPixels using codec
        public static int PixelsToBytes(N64Codec codec, int numPixels)
        {
            int numBytes = 0;

            switch (codec)
            {
            case N64Codec.RGBA16: numBytes = numPixels * 2; break;

            case N64Codec.RGBA32: numBytes = numPixels * 4; break;

            case N64Codec.IA16:   numBytes = numPixels * 2; break;

            case N64Codec.IA8:    numBytes = numPixels;  break;

            case N64Codec.IA4:    numBytes = numPixels / 2; break;

            case N64Codec.I8:     numBytes = numPixels;  break;

            case N64Codec.I4:     numBytes = numPixels / 2; break;

            case N64Codec.CI8:    numBytes = numPixels;  break;

            case N64Codec.CI4:    numBytes = numPixels / 2; break;

            case N64Codec.ONEBPP: numBytes = numPixels / 8; break;
            }
            return(numBytes);
        }
示例#4
0
        private void toolStripCodec_SelectedIndexChanged(object sender, EventArgs e)
        {
            N64Codec prevCodec = viewerCodec;

            viewerCodec = N64Codec.RGBA16;
            switch (toolStripCodec.SelectedIndex)
            {
            case 0: viewerCodec = N64Codec.RGBA16; break;

            case 1: viewerCodec = N64Codec.RGBA32; break;

            case 2: viewerCodec = N64Codec.IA16; break;

            case 3: viewerCodec = N64Codec.IA8; break;

            case 4: viewerCodec = N64Codec.IA4; break;

            case 5: viewerCodec = N64Codec.I8; break;

            case 6: viewerCodec = N64Codec.I4; break;

            case 7: viewerCodec = N64Codec.CI8; break;

            case 8: viewerCodec = N64Codec.CI4; break;

            case 9: viewerCodec = N64Codec.ONEBPP; break;
            }
            if (prevCodec != viewerCodec)
            {
                foreach (GraphicsViewer gv in viewers)
                {
                    gv.Codec = viewerCodec;
                    gv.Invalidate();
                }
                switch (viewerCodec)
                {
                case N64Codec.CI8:
                    gviewPalette.PixScale = 8;
                    break;

                case N64Codec.CI4:
                    gviewPalette.PixScale = 32;
                    break;
                }
                gviewPalette.Invalidate();
                groupBoxPalette.Visible = viewerCodec == N64Codec.CI8 || viewerCodec == N64Codec.CI4;
                toolStripAlpha.Enabled  = viewerCodec == N64Codec.I8 || viewerCodec == N64Codec.I4;
            }
        }
示例#5
0
        public static void FromColor(Color color, out byte[] data, N64Codec codec)
        {
            switch (codec)
            {
            case N64Codec.RGBA16:
                data = new byte[2];
                ColorRGBA16(color, out data[0], out data[1]);
                break;

            case N64Codec.RGBA32:
                data = new byte[] { color.R, color.G, color.B, color.A };
                break;

            default:
                data = new byte[] { };
                break;
            }
        }
示例#6
0
        private void InjectIMGBut_Click(object sender, EventArgs e)
        {
            OpenFileDialog open = new OpenFileDialog();

            open.Filter = "bin file|*.bin";
            DialogResult res = open.ShowDialog();

            if (res == DialogResult.OK)
            {
                byte[]   binfile = File.ReadAllBytes(open.FileName);
                Injector inj     = new Injector();
                N64Codec codec   = N64Codec.CI4;
                switch (SelectedCodec.SelectedItem)
                {
                case ("CI4"):
                {
                    codec = N64Codec.CI4;
                    break;
                }

                case ("CI8"):
                {
                    codec = N64Codec.CI8;
                    break;
                }
                }
                open.Filter = "bitmap file|*.bmp|png file|*.png|jpg file|*.jpg";
                res         = open.ShowDialog();
                if (res == DialogResult.OK)
                {
                    Bitmap         bmp    = new Bitmap(open.FileName);
                    byte[]         OutPut = inj.InjectImageIntoByteArray((int)ImgNum.Value, (int)PalleteNum.Value, binfile, bmp, codec);
                    SaveFileDialog save   = new SaveFileDialog();
                    save.Filter = "bin file|*.bin";
                    res         = save.ShowDialog();
                    if (res == DialogResult.OK)
                    {
                        File.WriteAllBytes(save.FileName, OutPut);
                    }
                }
            }
        }
示例#7
0
        public static void Convert(ref byte[] imageData, ref byte[] paletteData, N64Codec codec, Bitmap bm)
        {
            int numPixels = bm.Width * bm.Height;

            imageData = new byte[PixelsToBytes(codec, numPixels)];
            int palCount = 0;

            switch (codec)
            {
            case N64Codec.RGBA16:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col = bm.GetPixel(x, y);
                        byte  r, g, b;
                        r = SCALE_8_5(col.R);
                        g = SCALE_8_5(col.G);
                        b = SCALE_8_5(col.B);
                        byte c0  = (byte)((r << 3) | (g >> 2));
                        byte c1  = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
                        int  idx = 2 * (y * bm.Width + x);
                        imageData[idx + 0] = c0;
                        imageData[idx + 1] = c1;
                    }
                }
                break;

            case N64Codec.RGBA32:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col = bm.GetPixel(x, y);
                        int   idx = 4 * (y * bm.Width + x);
                        imageData[idx + 0] = col.R;
                        imageData[idx + 1] = col.G;
                        imageData[idx + 2] = col.B;
                        imageData[idx + 3] = col.A;
                    }
                }
                break;

            case N64Codec.IA16:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col       = bm.GetPixel(x, y);
                        int   sum       = col.R + col.G + col.B;
                        byte  intensity = (byte)(sum / 3);
                        byte  alpha     = col.A;
                        int   idx       = 2 * (y * bm.Width + x);
                        imageData[idx + 0] = intensity;
                        imageData[idx + 1] = alpha;
                    }
                }
                break;

            case N64Codec.IA8:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col       = bm.GetPixel(x, y);
                        int   sum       = col.R + col.G + col.B;
                        byte  intensity = SCALE_8_4((byte)(sum / 3));
                        byte  alpha     = SCALE_8_4(col.A);
                        int   idx       = y * bm.Width + x;
                        imageData[idx] = (byte)((intensity << 4) | alpha);
                    }
                }
                break;

            case N64Codec.IA4:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col       = bm.GetPixel(x, y);
                        int   sum       = col.R + col.G + col.B;
                        byte  intensity = SCALE_8_3((byte)(sum / 3));
                        byte  alpha     = (byte)(col.A > 0 ? 1 : 0);
                        int   idx       = y * bm.Width + x;
                        byte  old       = imageData[idx / 2];
                        if ((idx % 2) > 0)
                        {
                            imageData[idx / 2] = (byte)((old & 0xF0) | (intensity << 1) | alpha);
                        }
                        else
                        {
                            imageData[idx / 2] = (byte)((old & 0x0F) | (((intensity << 1) | alpha) << 4));
                        }
                    }
                }
                break;

            case N64Codec.I8:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col       = bm.GetPixel(x, y);
                        int   sum       = col.R + col.G + col.B;
                        byte  intensity = (byte)(sum / 3);
                        int   idx       = y * bm.Width + x;
                        imageData[idx] = intensity;
                    }
                }
                break;

            case N64Codec.I4:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col       = bm.GetPixel(x, y);
                        int   sum       = col.R + col.G + col.B;
                        byte  intensity = SCALE_8_4((byte)(sum / 3));
                        int   idx       = y * bm.Width + x;
                        byte  old       = imageData[idx / 2];
                        if ((idx % 2) > 0)
                        {
                            imageData[idx / 2] = (byte)((old & 0xF0) | intensity);
                        }
                        else
                        {
                            imageData[idx / 2] = (byte)((old & 0x0F) | (intensity << 4));
                        }
                    }
                }
                break;

            case N64Codec.CI4:
                paletteData = new byte[16 * 2];
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col = bm.GetPixel(x, y);
                        byte  r, g, b;
                        r = SCALE_8_5(col.R);
                        g = SCALE_8_5(col.G);
                        b = SCALE_8_5(col.B);
                        byte c0     = (byte)((r << 3) | (g >> 2));
                        byte c1     = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
                        int  idx    = y * bm.Width + x;
                        int  palIdx = paletteIndex(paletteData, palCount, c0, c1);
                        if (palIdx < 0)
                        {
                            if (palCount < paletteData.Length / 2)
                            {
                                palIdx = palCount;
                                paletteData[2 * palCount]     = c0;
                                paletteData[2 * palCount + 1] = c1;
                                palCount++;
                            }
                            else
                            {
                                palIdx = 0;
                                // TODO: out of palette entries. error or pick closest?
                            }
                        }
                        byte old = imageData[idx / 2];
                        if ((idx % 2) > 0)
                        {
                            imageData[idx / 2] = (byte)((old & 0xF0) | (byte)palIdx);
                        }
                        else
                        {
                            imageData[idx / 2] = (byte)((old & 0x0F) | ((byte)palIdx << 4));
                        }
                    }
                }
                break;

            case N64Codec.CI8:
                paletteData = new byte[256 * 2];
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col = bm.GetPixel(x, y);
                        byte  r, g, b;
                        r = SCALE_8_5(col.R);
                        g = SCALE_8_5(col.G);
                        b = SCALE_8_5(col.B);
                        byte c0     = (byte)((r << 3) | (g >> 2));
                        byte c1     = (byte)(((g & 0x3) << 6) | (b << 1) | ((col.A > 0) ? 1 : 0));
                        int  idx    = y * bm.Width + x;
                        int  palIdx = paletteIndex(paletteData, palCount, c0, c1);
                        if (palIdx < 0)
                        {
                            if (palCount < paletteData.Length / 2)
                            {
                                palIdx = palCount;
                                paletteData[2 * palCount]     = c0;
                                paletteData[2 * palCount + 1] = c1;
                                palCount++;
                            }
                            else
                            {
                                palIdx = 0;
                                // TODO: out of palette entries. error or pick closest?
                            }
                        }
                        imageData[idx] = (byte)palIdx;
                    }
                }
                break;

            case N64Codec.ONEBPP:
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color col       = bm.GetPixel(x, y);
                        int   sum       = col.R + col.G + col.B;
                        byte  intensity = (sum > 0) ? (byte)1 : (byte)0;
                        int   idx       = y * bm.Width + x;
                        byte  old       = imageData[idx / 8];
                        int   bit       = idx % 8;
                        int   mask      = ~(1 << bit);
                        imageData[idx / 8] = (byte)((old & mask) | (intensity << bit));
                    }
                }
                break;
            }
        }
示例#8
0
        public static void RenderTexture(Graphics g, byte[] data, byte[] palette, int offset, int width, int height, int scale, N64Codec codec, N64IMode mode)
        {
            Brush brush;

            for (int h = 0; h < height; h++)
            {
                for (int w = 0; w < width; w++)
                {
                    int pixOffset   = (h * width + w);
                    int bytesPerPix = 1;
                    int select      = 0;
                    switch (codec)
                    {
                    case N64Codec.RGBA16: bytesPerPix = 2; pixOffset *= bytesPerPix; break;

                    case N64Codec.RGBA32: bytesPerPix = 4; pixOffset *= bytesPerPix; break;

                    case N64Codec.IA16: bytesPerPix = 2; pixOffset *= bytesPerPix; break;

                    case N64Codec.IA8: break;

                    case N64Codec.IA4:
                        select     = pixOffset & 0x1;
                        pixOffset /= 2;
                        break;

                    case N64Codec.I8: break;

                    case N64Codec.I4:
                    case N64Codec.CI4:
                        select     = pixOffset & 0x1;
                        pixOffset /= 2;
                        break;

                    case N64Codec.CI8: break;

                    case N64Codec.ONEBPP:
                        select     = pixOffset & 0x7;
                        pixOffset /= 8;
                        break;
                    }
                    pixOffset += offset;
                    if (data.Length > pixOffset + bytesPerPix - 1)
                    {
                        brush = new SolidBrush(MakeColor(data, palette, pixOffset, select, codec, mode));
                        g.FillRectangle(brush, w * scale, h * scale, scale, scale);
                    }
                }
            }
        }
示例#9
0
        public static Color MakeColor(byte[] data, byte[] palette, int offset, int select, N64Codec codec, N64IMode mode)
        {
            Color color;

            switch (codec)
            {
            case N64Codec.RGBA16:
                color = RGBA16Color(data, offset);
                break;

            case N64Codec.RGBA32:
                color = RGBA32Color(data, offset);
                break;

            case N64Codec.IA16:
                color = IA16Color(data, offset);
                break;

            case N64Codec.IA8:
                color = IA8Color(data, offset);
                break;

            case N64Codec.IA4:
                color = IA4Color(data, offset, select);
                break;

            case N64Codec.I8:
                color = I8Color(data, offset, mode);
                break;

            case N64Codec.I4:
                color = I4Color(data, offset, select, mode);
                break;

            case N64Codec.CI8:
                color = CI8Color(data, palette, offset);
                break;

            case N64Codec.CI4:
                color = CI4Color(data, palette, offset, select);
                break;

            case N64Codec.ONEBPP:
                color = BPPColor(data, offset, select);
                break;

            default:
                color = RGBA16Color(data, offset);
                break;
            }
            return(color);
        }
示例#10
0
        //This works fine as shared
        /// <summary>
        /// Injects a custom bitmap into a .bin file
        /// </summary>
        /// <param name="OriginalData">The original file we want to import our image into</param>
        /// <param name="Image">Our image to import</param>
        /// <param name="Codec">The N64Codec to use</param>
        /// <param name="ImageOffset">The offset of the image within the file</param>
        /// <param name="PaletteOffset">The offset of the palette within the file</param>
        public byte[] InjectImageIntoByteArray(int ImageOffset, int PaletteOffset, byte[] OriginalData, Bitmap Image, N64Codec Codec)
        {
            byte[] imageData = null, paletteData = null;

            N64GraphicsCoding.Convert(ref imageData, ref paletteData, Codec, Image);

            ByteTools.TrimEnd(paletteData);

            Array.Copy(imageData, 0, OriginalData, ImageOffset, imageData.Length);
            Array.Copy(paletteData, 0, OriginalData, PaletteOffset, paletteData.Length);

            return(OriginalData);
        }
示例#11
0
        private void runTest(int idx, bool verbose, PictureBox pbIn, PictureBox pbOut)
        {
            int width  = 32;
            int height = 32;

            byte[] test       = new byte[width * height * 4]; // worst case
            byte[] result     = null;
            byte[] pal        = new byte[16 * 16 * 2];
            byte[] resultPal  = null;
            int    errorCount = 0;

            StringBuilder sb = new StringBuilder();

            N64Codec testCodec = WhichCodec(idx);

            // randomize inputs
            Random rng = new Random();

            rng.NextBytes(test);
            rng.NextBytes(pal);

            // if alpha bit clear, clear all bits
            switch (testCodec)
            {
            case N64Codec.RGBA16:
                for (int i = 0; i < test.Length; i += 2)
                {
                    if ((test[i + 1] & 0x1) == 0)
                    {
                        test[i]     = 0;
                        test[i + 1] = 0;
                    }
                }
                break;

            case N64Codec.IA16:
                for (int i = 0; i < test.Length; i += 2)
                {
                    if ((test[i + 1]) == 0)
                    {
                        test[i] = 0;
                    }
                }
                break;

            case N64Codec.IA8:
                for (int i = 0; i < test.Length; i++)
                {
                    if ((test[i] & 0x0F) == 0)
                    {
                        test[i] = 0;
                    }
                }
                break;

            case N64Codec.IA4:
                for (int i = 0; i < test.Length; i++)
                {
                    if ((test[i] & 0x10) == 0)
                    {
                        test[i] &= 0x0F;
                    }
                    if ((test[i] & 0x01) == 0)
                    {
                        test[i] &= 0xF0;
                    }
                }
                break;

            case N64Codec.CI4:
            case N64Codec.CI8:
                for (int i = 0; i < pal.Length; i += 2)
                {
                    if ((pal[i + 1] & 0x1) == 0)
                    {
                        pal[i]     = 0;
                        pal[i + 1] = 0;
                    }
                }
                break;
            }

            Bitmap   b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
            Graphics g = Graphics.FromImage(b);

            N64Graphics.RenderTexture(g, test, pal, 0, width, height, 1, testCodec, N64IMode.AlphaCopyIntensity);
            N64Graphics.Convert(ref result, ref resultPal, testCodec, b);
            Bitmap bres = new Bitmap(width, height, PixelFormat.Format32bppArgb);

            N64Graphics.RenderTexture(Graphics.FromImage(bres), result, resultPal, 0, width, height, 1, testCodec, N64IMode.AlphaCopyIntensity);
            for (int i = 0; i < result.Length; i++)
            {
                if (test[i] != result[i])
                {
                    errorCount++;
                }
                if (verbose)
                {
                    sb.AppendFormat("{0:X03} {1:X02} {2:X02}\r\n", i, test[i], result[i]);
                }
            }
            if (resultPal != null)
            {
                for (int i = 0; i < resultPal.Length; i++)
                {
                    if (pal[i] != resultPal[i])
                    {
                        errorCount++;
                    }
                    if (verbose)
                    {
                        sb.AppendFormat("P {0:X03} {1:X02} {2:X02}\r\n", i, pal[i], resultPal[i]);
                    }
                }
            }

            // publish results
            sb.AppendFormat("Test[{0}] {1}: {2} errors\r\n", idx, N64Graphics.CodecString(testCodec), errorCount);
            textBoxLog.AppendText(sb.ToString());
            pbIn.Image  = b;
            pbOut.Image = bres;
        }