예제 #1
0
        public static byte[] Save(TGA tga)
        {
            byte[] buffer;

            using (MemoryStream ms = new MemoryStream())
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    bw.Write((byte)0);      // ID length
                    bw.Write((byte)0);      // Colourmap type
                    bw.Write((byte)tga.Type);
                    bw.Write((short)0);     // Colourmap first entry
                    bw.Write((short)0);     // Colourmap length
                    bw.Write((byte)0);      // Colourmap entry size
                    bw.Write((short)0);     // X origin
                    bw.Write((short)0);     // Y origin
                    bw.Write((short)tga.Width);
                    bw.Write((short)tga.Height);
                    bw.Write(tga.PixelDepth);
                    bw.Write((byte)0);      // ImageDescriptor

                    bw.Write(tga.Data);

                    bw.Flush();
                    ms.Flush();

                    buffer = ms.ToArray();
                }

            return(buffer);
        }
예제 #2
0
        public static TGA Load(Stream stream, string name = null)
        {
            TGA tga = new TGA
            {
                Name = name
            };

            using (BinaryReader br = new BinaryReader(stream))
            {
                byte idLength      = br.ReadByte();
                byte colourMapType = br.ReadByte();
                tga.Type = (ImageType)br.ReadByte();

                if (idLength > 0)
                {
                    throw new NotImplementedException("No support for TGA files with ID sections!");
                }
                if (colourMapType == 0)
                {
                    br.ReadBytes(5);
                }
                else
                {
                    throw new NotImplementedException("No support for TGA files with ColourMaps!");
                }

                int xOrigin = br.ReadInt16();
                int yOrigin = br.ReadInt16();
                tga.Width      = br.ReadInt16();
                tga.Height     = br.ReadInt16();
                tga.PixelDepth = br.ReadByte();
                byte imageDescriptor = br.ReadByte();
                byte size            = (byte)(tga.PixelDepth / 8);

                switch (tga.Type)
                {
                case ImageType.TrueColourRLE:
                    tga.Data = br.ReadBytes((int)br.BaseStream.Length - 13);
                    break;

                default:
                    tga.Data = br.ReadBytes(tga.Width * tga.Height * size);
                    break;
                }
            }

            return(tga);
        }
예제 #3
0
        public static TGA FromBitmap(Bitmap bitmap)
        {
            TGA tga = new TGA
            {
                Width      = bitmap.Width,
                Height     = bitmap.Height,
                Type       = ImageType.TrueColour,
                PixelDepth = 32
            };

            byte[] raw = new byte[bitmap.Width * bitmap.Height * 4];

            BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            Marshal.Copy(data.Scan0, raw, 0, data.Stride * data.Height);
            bitmap.UnlockBits(data);

            tga.Data = new byte[raw.Length];

            using (MemoryStream ms = new MemoryStream(tga.Data))
                using (BinaryWriter bw = new BinaryWriter(ms))
                {
                    for (int y = data.Height - 1; y >= 0; y--)
                    {
                        for (int x = 0; x < data.Width; x++)
                        {
                            int offset = y * data.Stride + (x * 4);

                            bw.Write(raw[offset + 0]);
                            bw.Write(raw[offset + 1]);
                            bw.Write(raw[offset + 2]);
                            bw.Write(raw[offset + 3]);
                        }
                    }
                }

            return(tga);
        }
예제 #4
0
        public void SaveAs(string path, OutputFormat outputFormat)
        {
            if (Mode == 0)
            {
                switch (outputFormat)
                {
                case OutputFormat.PNG:
                    DDS.Decompress().Save(path, ImageFormat.Png);
                    break;

                case OutputFormat.DDS:
                    DDS.Save(path);
                    break;

                case OutputFormat.TGA:
                    TGA.FromBitmap(DDS.Decompress()).Save(path);
                    break;
                }
            }
            else
            {
                Raw.Save(path, ImageFormat.Png);
            }
        }
예제 #5
0
파일: TGA.cs 프로젝트: talberti/Breckfest
        public static TGA Load(byte[] data)
        {
            TGA tga = new TGA();

            using (MemoryStream ms = new MemoryStream(data))
            using (BinaryReader br = new BinaryReader(ms))
            {
                BitmapData bmpdata;
                PixelFormat format = PixelFormat.Format32bppArgb;

                byte idLength = br.ReadByte();
                byte colourMapType = br.ReadByte();
                byte imageType = br.ReadByte();

                if (idLength > 0) { throw new NotImplementedException("No support for TGA files with ID sections!"); }
                if (colourMapType == 0) { br.ReadBytes(5); } else { throw new NotImplementedException("No support for TGA files with ColourMaps!"); }

                int xOrigin = br.ReadInt16();
                int yOrigin = br.ReadInt16();
                int width = br.ReadInt16();
                int height = br.ReadInt16();
                byte pixelDepth = br.ReadByte();
                byte size = (byte)(pixelDepth / 8);
                byte imageDescriptor = br.ReadByte();

                if (size == 3) { format = PixelFormat.Format24bppRgb; }

                tga.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                bmpdata = tga.bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, format);

                if (imageType == 10)
                {
                    const int iRAWSection = 127;
                    uint j = 0;
                    int iStep = 0;
                    int bpCount = 0;
                    int currentPixel = 0;
                    int pixelCount = width * height;
                    var colorBuffer = new byte[size];
                    byte chunkHeader = 0;
                    byte[] buffer = br.ReadBytes((int)br.BaseStream.Length - 13);

                    using (var nms = new MemoryStream())
                    {
                        while (currentPixel < pixelCount)
                        {
                            chunkHeader = buffer[iStep];
                            iStep++;

                            if (chunkHeader <= iRAWSection)
                            {
                                chunkHeader++;
                                bpCount = size * chunkHeader;
                                nms.Write(buffer, iStep, bpCount);
                                iStep += bpCount;

                                currentPixel += chunkHeader;
                            }
                            else
                            {
                                chunkHeader -= iRAWSection;
                                Array.Copy(buffer, iStep, colorBuffer, 0, size);
                                iStep += size;
                                for (j = 0; j < chunkHeader; j++) { nms.Write(colorBuffer, 0, size); }
                                currentPixel += chunkHeader;
                            }
                        }

                        var contentBuffer = new byte[nms.Length];
                        nms.Position = 0;
                        nms.Read(contentBuffer, 0, contentBuffer.Length);

                        Marshal.Copy(contentBuffer, 0, bmpdata.Scan0, contentBuffer.Length);
                    }
                }
                else
                {
                    Marshal.Copy(br.ReadBytes(width * height * size), 0, bmpdata.Scan0, width * height * size);
                }

                tga.bitmap.UnlockBits(bmpdata);
            }

            return tga;
        }
예제 #6
0
        private static string processFile(string path)
        {
            BMAP   bmap      = new BMAP();
            string extension = Path.GetExtension(path).Substring(1);
            string outputName;

            if (settings.Raw)
            {
                if (Raw.IsValid(path))
                {
                    Console.WriteLine($"Loading  : {Path.GetFileName(path)}");
                    Raw.Load(path, true);

                    return(path);
                }
            }
            else if (settings.Compress)
            {
                if (Enum.TryParse(extension, out WreckfestExtensions we))
                {
                    using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path)))
                        using (BinaryReader br = new BinaryReader(ms))
                        {
                            if (
                                br.ReadInt32() != 4 ||
                                br.ReadByte() != extension[3] ||
                                br.ReadByte() != extension[2] ||
                                br.ReadByte() != extension[1] ||
                                br.ReadByte() != extension[0])
                            {
                                br.BaseStream.Position = 0;
                                byte[] input = br.ReadBytes((int)ms.Length);

                                File.Move(path, $"{path}.bak");

                                using (BinaryWriter bw = new BinaryWriter(new FileStream(path, FileMode.Create)))
                                {
                                    bw.Write(4);
                                    bw.Write(extension[3]);
                                    bw.Write(extension[2]);
                                    bw.Write(extension[1]);
                                    bw.Write(extension[0]);
                                    bw.Write((int)we);

                                    int[]  hashTable = new int[1 << (14 - 2)];
                                    byte[] output    = new byte[LZ4Compress.CalculateChunkSize(input.Length)];
                                    int    i         = 0;

                                    while (i < input.Length)
                                    {
                                        byte[] chunk = new byte[Math.Min(input.Length - i, output.Length)];

                                        Array.Copy(input, i, chunk, 0, chunk.Length);
                                        Array.Clear(hashTable, 0, hashTable.Length);

                                        int size = LZ4Compress.Compress(hashTable, chunk, output, chunk.Length, chunk.Length + 4);

                                        bw.Write(size);
                                        bw.Write(output, 0, size);

                                        i += chunk.Length;
                                    }
                                }
                            }
                            else
                            {
                                Console.WriteLine($"Skipping : {Path.GetFileName(path)} is already compressed");
                            }
                        }
                }
                else
                {
                    Console.WriteLine($"Error    : unsupported extension '{extension}'.");
                }
            }
            else if (extension == "bmap")
            {
                if (BMAP.IsBMAP(path))
                {
                    Console.WriteLine($"Loading  : {Path.GetFileName(path)}");
                    bmap = BMAP.Load(path, false);

                    outputName = $"{Path.GetFileNameWithoutExtension(path)}.{(bmap.Mode == 1 ? "clutter" : (bmap.DDS.Format == D3DFormat.A8R8G8B8 ? "raw" : bmap.DDS.Format.ToString().ToLower()))}.{settings.SaveAs}";

                    Console.WriteLine($"Saving   : {outputName}");
                    if (!overwrite($@"{Path.GetDirectoryName(path)}\{outputName}"))
                    {
                        return(null);
                    }
                    bmap.SaveAs(outputName, settings.SaveAs);

                    return(path);
                }
            }
            else if (extension == "dds")
            {
                string newExtension = $"{(settings.NoRename ? "" : ".x")}.bmap";

                Console.WriteLine($"Loading  : {Path.GetFileName(path)}");
                Console.WriteLine($"Saving   : {Path.GetFileNameWithoutExtension(path)}{newExtension}");

                bmap.Path = Path.GetFileName(path);
                bmap.DDS  = DDS.Load(path);
                if (!overwrite(path.Replace(".dds", newExtension)))
                {
                    return(null);
                }
                bmap.Save(path.Replace(".dds", newExtension));

                return(path);
            }
            else if (Array.IndexOf(new string[] { "png", "tga", "tif" }, extension) > -1)
            {
                Texture texture = null;
                Console.WriteLine($"Loading   : {Path.GetFileName(path)}");

                switch (extension)
                {
                case "tga":
                    texture = TGA.Load(path);
                    break;

                case "tif":
                case "png":
                    texture = Texture.Load(path);
                    break;
                }

                BreckfestSettings original = settings.Clone();

                if (Path.GetFileNameWithoutExtension(path).EndsWith(".clutter", StringComparison.OrdinalIgnoreCase))
                {
                    settings.Clutter = true;
                    path             = path.Replace(".clutter", "");
                }
                else if (Path.GetFileNameWithoutExtension(path).EndsWith(".raw", StringComparison.OrdinalIgnoreCase))
                {
                    settings.Format = D3DFormat.A8R8G8B8;
                    path            = path.Replace(".raw", "");
                }
                else if (Path.GetFileNameWithoutExtension(path).EndsWith(".dxt1", StringComparison.OrdinalIgnoreCase))
                {
                    settings.Format = D3DFormat.DXT1;
                    path            = path.Replace(".dxt1", "");
                }
                else if (Path.GetFileNameWithoutExtension(path).EndsWith(".dxt5", StringComparison.OrdinalIgnoreCase))
                {
                    settings.Format = D3DFormat.DXT5;
                    path            = path.Replace(".dxt5", "");
                }

                bmap.Path = Path.GetFileName(path);

                if (settings.Clutter)
                {
                    Console.WriteLine($"Cluttering: {texture.Bitmap.Width}x{texture.Bitmap.Height}");

                    bmap.Mode = 1;
                    bmap.Raw  = texture.Bitmap;
                }
                else
                {
                    if (settings.Format == D3DFormat.A8R8G8B8)
                    {
                        Console.WriteLine($"Formatting: {texture.Bitmap.Width}x{texture.Bitmap.Height} (this might take awhile)");
                    }
                    else
                    {
                        Console.WriteLine($"Squishing : {texture.Bitmap.Width}x{texture.Bitmap.Height} (this might take awhile)");
                    }

                    bmap.DDS = new DDS(settings.Format, texture.Bitmap);
                }

                string newExtension = $"{(settings.NoRename ? "" : ".x")}.bmap";

                Console.WriteLine($"Saving    : {Path.GetFileNameWithoutExtension(path)}{newExtension}");
                if (!overwrite(path.Replace($".{extension}", $"{newExtension}")))
                {
                    return(null);
                }
                bmap.Save(path.Replace($".{extension}", $"{newExtension}"), true);

                settings = original.Clone();

                return(path);
            }

            return(null);
        }
예제 #7
0
        public static TGA Load(byte[] data)
        {
            TGA tga = new TGA();

            using (MemoryStream ms = new MemoryStream(data))
                using (BinaryReader br = new BinaryReader(ms))
                {
                    BitmapData  bmpdata;
                    PixelFormat format = PixelFormat.Format32bppArgb;

                    byte idLength      = br.ReadByte();
                    byte colourMapType = br.ReadByte();
                    byte imageType     = br.ReadByte();

                    if (idLength > 0)
                    {
                        throw new NotImplementedException("No support for TGA files with ID sections!");
                    }
                    if (colourMapType == 0)
                    {
                        br.ReadBytes(5);
                    }
                    else
                    {
                        throw new NotImplementedException("No support for TGA files with ColourMaps!");
                    }

                    int  xOrigin         = br.ReadInt16();
                    int  yOrigin         = br.ReadInt16();
                    int  width           = br.ReadInt16();
                    int  height          = br.ReadInt16();
                    byte pixelDepth      = br.ReadByte();
                    byte size            = (byte)(pixelDepth / 8);
                    byte imageDescriptor = br.ReadByte();

                    if (size == 3)
                    {
                        format = PixelFormat.Format24bppRgb;
                    }

                    tga.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
                    bmpdata    = tga.bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, format);

                    if (imageType == 10)
                    {
                        const int iRAWSection  = 127;
                        uint      j            = 0;
                        int       iStep        = 0;
                        int       bpCount      = 0;
                        int       currentPixel = 0;
                        int       pixelCount   = width * height;
                        var       colorBuffer  = new byte[size];
                        byte      chunkHeader  = 0;
                        byte[]    buffer       = br.ReadBytes((int)br.BaseStream.Length - 13);

                        using (var nms = new MemoryStream())
                        {
                            while (currentPixel < pixelCount)
                            {
                                chunkHeader = buffer[iStep];
                                iStep++;

                                if (chunkHeader <= iRAWSection)
                                {
                                    chunkHeader++;
                                    bpCount = size * chunkHeader;
                                    nms.Write(buffer, iStep, bpCount);
                                    iStep += bpCount;

                                    currentPixel += chunkHeader;
                                }
                                else
                                {
                                    chunkHeader -= iRAWSection;
                                    Array.Copy(buffer, iStep, colorBuffer, 0, size);
                                    iStep += size;
                                    for (j = 0; j < chunkHeader; j++)
                                    {
                                        nms.Write(colorBuffer, 0, size);
                                    }
                                    currentPixel += chunkHeader;
                                }
                            }

                            var contentBuffer = new byte[nms.Length];
                            nms.Position = 0;
                            nms.Read(contentBuffer, 0, contentBuffer.Length);

                            Marshal.Copy(contentBuffer, 0, bmpdata.Scan0, contentBuffer.Length);
                        }
                    }
                    else
                    {
                        Marshal.Copy(br.ReadBytes(width * height * size), 0, bmpdata.Scan0, width * height * size);
                    }

                    tga.bitmap.UnlockBits(bmpdata);
                }

            return(tga);
        }
예제 #8
0
 public static new TGA Load(string path)
 {
     return(TGA.Load(File.ReadAllBytes(path)));
 }