private Bitmap Export(byte[] Texture, string infile)
        {
            StructReader Reader = new StructReader(new MemoryStream(Texture));
            DatHeader    Header = new DatHeader();

            Reader.ReadStruct(ref Header);
            //Header.Blockh = (ushort)Math.Ceiling((float)Header.Heigth / (float)Header.Colorblock);
            Pixel32[] ColorPanel = new Pixel32[0];

            uint Signature  = Header.Signature;
            int  PixivBytes = 0;
            int  DatType    = 1;

            if (Signature == 0x00200102)
            {
                Console.WriteLine("DatType 1");//no colorpanel //32 or 24bit
            }
            else if (Signature == 0x04280102)
            {
                Console.WriteLine("DatType 2");//has colorpanel 256色 8bit
                DatType = 2;
            }
            else
            {
                Console.WriteLine("Unsupport Format Signature:" + Header.Signature);
                File.AppendAllText("ErrOutput.txt", "Unsupport Format Signature:" + Header.Signature + "\r\n" + infile + "\r\n");
            }

            if (Header.ColorbitsType == 0x80)
            {
                PixivBytes = 4;
            }
            else if (Header.ColorbitsType == 0xA8)
            {
                PixivBytes = 3;
            }
            else if (Header.ColorbitsType == 0x81)
            {
                PixivBytes = 1;
            }
            else
            {
                Console.WriteLine("Unsupport Format ColorbitsType:" + Header.ColorbitsType);
                File.AppendAllText("ErrOutput.txt", "Unsupport Format ColorbitsType:" + Header.ColorbitsType + "\r\n" + infile + "\r\n");
                return(null);
            }

            if (DatType == 2)
            {
                Pixel32 tmpPixel = new Pixel32();
                ColorPanel = new Pixel32[256];
                for (int j = 0; j < ColorPanel.Length; j++)
                {
                    //TODO 颜色表的 颜色还有错误
                    tmpPixel.R = (byte)(Reader.ReadByte());
                    tmpPixel.G = (byte)(Reader.ReadByte());
                    tmpPixel.B = (byte)(Reader.ReadByte());
                    tmpPixel.A = (byte)(Reader.ReadByte());
                    //tmpPixel.R = (byte)(tmpPixel.R == 0 ? 0xFF : tmpPixel.R);
                    //tmpPixel.G = (byte)(tmpPixel.G == 0 ? 0xFF : tmpPixel.G);
                    //tmpPixel.B = (byte)(tmpPixel.B == 0 ? 0xFF : tmpPixel.B);
                    //tmpPixel.A = (byte)(tmpPixel.A == 0 ? 0xFF : tmpPixel.A);
                    ColorPanel[j] = tmpPixel;
                }

                //256*4
                Reader.ReadUInt32();              //10 00 00 00  //16 Unknow
                Reader.ReadUInt32();              //38 04 00 00  //1080 Unknow
            }
            Reader.ReadUInt32();                  //totallennextbytes=blocksize_byteslen+compressedLen
            Reader.ReadUInt32();                  //w h
            Reader.ReadUInt16();                  //blocksize_byteslen=2+2+4+4+blockcount*8
            int BlockCount = Reader.ReadUInt16(); //block count

            uint decompressedLen = Reader.ReadUInt32();

            Console.WriteLine("decompressedTotalLen :" + decompressedLen);
            uint compressedLen = Reader.ReadUInt32();

            Console.WriteLine("compressedTotalLen :" + compressedLen);


            List <byte>            output             = new List <byte>();
            Dictionary <int, uint> rawSizeList        = new Dictionary <int, uint>();
            Dictionary <int, uint> compressedSizeList = new Dictionary <int, uint>();
            int i;

            for (i = 0; i < BlockCount; i++)
            {
                uint fileCompressedSize = Reader.ReadUInt32();
                uint fileRawSize        = Reader.ReadUInt32();
                rawSizeList.Add(i, fileRawSize);
                compressedSizeList.Add(i, fileCompressedSize);
            }

            for (i = 0; i < BlockCount; i++)
            {
                List <int>  lmzBytes   = new List <int>();
                List <byte> unBytes    = new List <byte>();
                int         totalcount = (int)compressedSizeList[i];
                for (int j = 0; j < totalcount / 2; j++)
                {
                    //st.Read(bytArray2Count, 0, 2);//

                    lmzBytes.Add(Reader.ReadUInt16());
                }
                //解压lzw
                string str = LzwUtil.Decompress2(lmzBytes);
                foreach (var c in str)
                {
                    unBytes.Add((byte)c);
                }

                //颜色填充方式
                if (Header.ColorbitsAlgorithm == 0x00)
                {
                    //raw
                }
                else if (Header.ColorbitsAlgorithm == 0x02)
                {
                    //diff
                    int pixivNum = unBytes.Count / PixivBytes;

                    int    lineBytesNum = Header.Width * PixivBytes;
                    byte[] pre_line     = new byte[lineBytesNum];
                    byte[] curr_line    = new byte[lineBytesNum];
                    for (int idx = 0; idx < Math.Ceiling((double)pixivNum / (double)Header.Width); idx++)
                    {
                        unBytes.CopyTo(idx * lineBytesNum, curr_line, 0, (idx + 1) * lineBytesNum < unBytes.Count ? lineBytesNum : unBytes.Count % lineBytesNum);
                        if (idx != 0)
                        {
                            for (int x = 0; x < lineBytesNum; x++)
                            {
                                curr_line[x] += pre_line[x];
                                curr_line[x]--;
                            }
                        }
                        for (int x = 0; x < lineBytesNum && idx * lineBytesNum + x < unBytes.Count; x++)
                        {
                            unBytes[idx * lineBytesNum + x] = curr_line[x];
                        }
                        curr_line.CopyTo(pre_line, 0);
                    }
                }
                output.AddRange(unBytes);
            }
            Bitmap       Picture = new Bitmap(Header.Width, Header.Heigth, PixelFormat.Format32bppArgb);
            Pixel32      Pixel   = new Pixel32();
            MemoryStream ms      = new MemoryStream(output.ToArray());

            byte[] bytArray4Count = new byte[4];
            ms.Seek(0, SeekOrigin.Begin);
            if (PixivBytes == 4)//32 argb
            {
                Picture = new Bitmap(Header.Width, Header.Heigth, PixelFormat.Format32bppArgb);
                for (int y = 0; y < Header.Heigth; y++)
                {
                    for (int x = 0; x < Header.Width; x++)
                    {
                        ms.Read(bytArray4Count, 0, 4); //

                        Pixel.R = --bytArray4Count[0]; // == 0 ? (byte)0xFF : bytArray4Count[0];
                        Pixel.G = --bytArray4Count[1]; // == 0 ? (byte)0xFF : bytArray4Count[1];
                        Pixel.B = --bytArray4Count[2]; // == 0 ? (byte)0xFF : bytArray4Count[2];
                        Pixel.A = --bytArray4Count[3]; // == 0 ? (byte)0xFF : bytArray4Count[3];

                        Picture.SetPixel(x, y, Color.FromArgb(Pixel.A, Pixel.R, Pixel.G, Pixel.B));
                    }
                }
            }

            else if (PixivBytes == 3)//24 rgb
            {
                Picture = new Bitmap(Header.Width, Header.Heigth, PixelFormat.Format24bppRgb);
                for (int y = 0; y < Header.Heigth; y++)
                {
                    for (int x = 0; x < Header.Width; x++)
                    {
                        ms.Read(bytArray4Count, 0, 3); //

                        Pixel.R = --bytArray4Count[0]; // == 0 ? (byte)0xFF : bytArray4Count[0];
                        Pixel.G = --bytArray4Count[1]; // == 0 ? (byte)0xFF : bytArray4Count[1];
                        Pixel.B = --bytArray4Count[2]; // == 0 ? (byte)0xFF : bytArray4Count[2];
                        //Pixel.A = bytArray4Count[3] == 0 ? (byte)0xFF : bytArray4Count[3];

                        Picture.SetPixel(x, y, Color.FromArgb(Pixel.R, Pixel.G, Pixel.B));
                    }
                }
            }

            else if (PixivBytes == 1)//8 argb
            {
                Picture = new Bitmap(Header.Width, Header.Heigth, PixelFormat.Format32bppArgb);
                for (int y = 0; y < Header.Heigth; y++)
                {
                    for (int x = 0; x < Header.Width; x++)
                    {
                        byte b = (byte)(ms.ReadByte() - 1); //
                        Pixel.R = ColorPanel[b].R;
                        Pixel.G = ColorPanel[b].G;
                        Pixel.B = ColorPanel[b].B;
                        Pixel.A = ColorPanel[b].A;

                        Picture.SetPixel(x, y, Color.FromArgb(Pixel.A, Pixel.R, Pixel.G, Pixel.B));
                    }
                }
            }


            Reader.Close();
            return(Picture);
        }
        //作者:Wetor
        //时间:2019.1.18
        public void PngToCZ1(string outfile)
        {
            Bitmap       Picture = new Bitmap(File.Open(outfile, FileMode.Open));
            StructWriter Writer  = new StructWriter(File.Open(outfile + ".cz1", FileMode.Create));
            CZ1Header    header;

            header.Signature    = "CZ1";
            header.HeaderLength = 0x10;
            header.Width        = (ushort)Picture.Width;
            header.Heigth       = (ushort)Picture.Height;
            header.Colorbits    = 8;
            Writer.WriteStruct(ref header);
            Writer.Seek(header.HeaderLength, SeekOrigin.Begin);


            Pixel32 Pixel = new Pixel32();

            Pixel.R = 255;
            Pixel.G = 255;
            Pixel.B = 255;
            for (int k = 0; k < 256; k++)
            {
                Pixel.A = (byte)k;
                Writer.WriteStruct(ref Pixel);
            }

            byte[] bytes = new byte[Picture.Height * Picture.Width];
            int    i     = 0;

            for (int y = 0; y < Picture.Height; y++)
            {
                for (int x = 0; x < Picture.Width; x++)
                {
                    bytes[i] = Picture.GetPixel(x, y).A;
                    i++;
                }
            }


            int file_num = bytes.Length / 130554 + 1;
            //System.Diagnostics.Debug.WriteLine("{0} {1} {2}", file_num, listBytes.Count, 130554);
            List <int[]> out_list = new List <int[]>();

            Writer.Write(file_num);
            for (int k = 0; k < file_num; k++)
            {
                List <int>    listBytes    = new List <int>();
                StringBuilder decompressed = new StringBuilder();
                byte[]        tmp_bytes    = new byte[130554];
                if (k == file_num - 1)
                {
                    Array.Copy(bytes, k * 130554, tmp_bytes, 0, bytes.Length - k * 130554);
                }
                else
                {
                    Array.Copy(bytes, k * 130554, tmp_bytes, 0, 130554);
                }


                foreach (char kk in tmp_bytes)
                {
                    decompressed.Append(kk);
                }
                listBytes = LzwUtil.Compress(decompressed.ToString());
                out_list.Add(listBytes.ToArray());
                Writer.Write(listBytes.Count);
                //string tmp_str;
                System.Diagnostics.Debug.WriteLine("{0}", k);

                /*if (k== file_num - 1)
                 * {
                 *  tmp_list.AddRange(listBytes.GetRange(130554 / 2 * k, listBytes.Count - 130554 / 2 * k));
                 *  tmp_list.Insert(0, 0);
                 *  tmp_str = Decompress(tmp_list);
                 * }
                 * else
                 * {
                 *  tmp_list.AddRange(listBytes.GetRange(130554 / 2 * k, 130554 / 2));
                 *  tmp_list.Insert(0, 0);
                 *  tmp_str = Decompress(tmp_list);
                 * }*/
                if (k == file_num - 1)
                {
                    Writer.Write(bytes.Length - k * 130554);
                }
                else
                {
                    Writer.Write(130554);
                }
                //Writer.Write(0xFFFD);
            }

            /*List<byte> output = new List<byte>();
             * string str = Decompress(listBytes);
             * foreach (var c in str)
             * {
             *  output.Add((byte)c);
             * }
             * // Writer.Write(output.ToArray());
             * System.Diagnostics.Debug.WriteLine(output.Count);*/

            for (int k = 0; k < out_list.Count; k++)
            {
                for (int kk = 0; kk < out_list[k].Length; kk++)
                {
                    Writer.Write((UInt16)out_list[k][kk]);
                }
            }
            Writer.Close();
        }
        public Bitmap Export(byte[] Texture)
        {
            StructReader Reader = new StructReader(new MemoryStream(Texture));
            CZ1Header    Header = new CZ1Header();

            Reader.ReadStruct(ref Header);

            if (Header.Signature != "CZ1\x0")
            {
                throw new BadImageFormatException();
            }

            Reader.Seek(Header.HeaderLength, SeekOrigin.Begin);
            Bitmap Picture = new Bitmap(Header.Width, Header.Heigth, PixelFormat.Format32bppArgb);

            if (Header.Colorbits == 4)//4bit
            {
                //字库格式
                //System.Diagnostics.Debug.WriteLine(4);
                //表
                Pixel32[] ColorPanel = new Pixel32[16];
                Pixel32   Pixel      = new Pixel32();
                for (int i = 0; i < ColorPanel.Length; i++)
                {
                    Reader.ReadStruct(ref Pixel);
                    ColorPanel[i] = Pixel;
                }

                //lmz解压
                var bytes = Decompress(Reader);

                //解压后的像素
                Queue <int> queue = new Queue <int>();
                foreach (var b in bytes)
                {
                    int low4bit  = b & 0x0F;
                    int high4bit = (b & 0xF0) >> 4;
                    queue.Enqueue(low4bit);
                    queue.Enqueue(high4bit);
                }

                for (int y = 0; y < Header.Heigth; y++)
                {
                    for (int x = 0; x < Header.Width; x++)
                    {
                        int index = queue.Dequeue();
                        Picture.SetPixel(x, y, Color.FromArgb(ColorPanel[index].A, ColorPanel[index].R, ColorPanel[index].G, ColorPanel[index].B));
                    }
                }
            }
            else if (Header.Colorbits == 8)//8bit
            {
                System.Diagnostics.Debug.WriteLine(8);
                Pixel32[] ColorPanel = new Pixel32[256];
                Pixel32   Pixel      = new Pixel32();
                for (int i = 0; i < ColorPanel.Length; i++)
                {
                    Reader.ReadStruct(ref Pixel);
                    ColorPanel[i] = Pixel;
                }

                var         bytes = Decompress(Reader);
                Queue <int> queue = new Queue <int>();
                foreach (var b in bytes)
                {
                    queue.Enqueue(b);
                }
                // var ie = bytes.GetEnumerator();
                for (int y = 0; y < Header.Heigth; y++)
                {
                    for (int x = 0; x < Header.Width; x++)
                    {
                        int index = queue.Dequeue();
                        //int index = BitConverter.ToInt16(new byte[] { ie.Current, 0x00 }, 0);
                        Picture.SetPixel(x, y, Color.FromArgb(ColorPanel[index].A, ColorPanel[index].R, ColorPanel[index].G, ColorPanel[index].B));
                    }
                }
            }
            //else if (Header.Colorbits == 24)
            //{

            //    for (int y = 0; y < Header.Heigth; y++)
            //    for (int x = 0; x < Header.Width; x++)
            //    {
            //        Pixel24 Pixel = new Pixel24();
            //        Reader.ReadStruct(ref Pixel);
            //        Picture.SetPixel(x, y, Color.FromArgb(Pixel.R, Pixel.G, Pixel.B));
            //    }
            //}
            //else if (Header.Colorbits == 32)//32
            //{

            //    for (int y = 0; y < Header.Heigth; y++)
            //    for (int x = 0; x < Header.Width; x++)
            //    {
            //        Pixel32 Pixel = new Pixel32();
            //        Reader.ReadStruct(ref Pixel);
            //        Picture.SetPixel(x, y, Color.FromArgb(Pixel.A, Pixel.R, Pixel.G, Pixel.B));
            //    }
            //}
            Reader.Close();
            return(Picture);
        }
Exemple #4
0
        //作者:Wetor
        //时间:2019.1.18
        public void PngToCZ1(string outfile)
        {
            Bitmap       Picture = new Bitmap(File.Open(outfile, FileMode.Open));
            StructWriter Writer  = new StructWriter(File.Open(outfile + ".cz1", FileMode.Create));
            CZ1Header    header;

            header.Signature    = "CZ1";
            header.HeaderLength = 0x10;
            header.Width        = (ushort)Picture.Width;
            header.Heigth       = (ushort)Picture.Height;
            header.Colorbits    = 4;
            Writer.WriteStruct(ref header);
            Writer.Seek(header.HeaderLength, SeekOrigin.Begin);


            Pixel32 Pixel = new Pixel32();

            Pixel.R = 255;
            Pixel.G = 255;
            Pixel.B = 255;
            //FF FF FF 00
            //FF FF FF 18
            //FF FF FF 26
            //FF FF FF 35
            //FF FF FF 45
            //FF FF FF 55
            //FF FF FF 65
            //FF FF FF 75
            //FF FF FF 85
            //FF FF FF 96
            //FF FF FF A7
            //FF FF FF B8
            //FF FF FF C9
            //FF FF FF DB
            //FF FF FF EC
            //FF FF FF FF


            Pixel.A = (byte)0x00; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x18; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x26; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x35; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x45; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x55; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x65; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x75; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x85; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0x96; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0xA7; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0xB8; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0xC9; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0xDB; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0xEC; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Pixel.A = (byte)0xFF; list.Add(Pixel.A);
            Writer.WriteStruct(ref Pixel);
            Queue <byte> queue = new Queue <byte>();
            int          i     = 0;

            for (int y = 0; y < Picture.Height; y++)
            {
                for (int x = 0; x < Picture.Width; x++)
                {
                    byte tmp = color256to16(Picture.GetPixel(x, y).A);
                    //bytes11[i] = (byte)list.IndexOf(tmp);
                    queue.Enqueue((byte)list.IndexOf(tmp));
                    i++;
                }
            }

            byte[] bytes2 = new byte[Picture.Height * Picture.Width / 2];

            for (int j = 0; j < bytes2.Length; j++)
            {
                var low4bit  = queue.Dequeue();
                var high4bit = queue.Dequeue();
                var b        = (uint)(high4bit << 4) + (uint)low4bit;
                bytes2[j] = (byte)b;
            }
            //foreach (var b in bytes2)
            //{
            //    int low4bit = b & 0x0F;
            //    int high4bit = (b & 0xF0) >> 4;
            //    queue.Enqueue(low4bit);
            //    queue.Enqueue(high4bit);
            //}

            int file_num = bytes2.Length / 130554 + 1;
            //System.Diagnostics.Debug.WriteLine("{0} {1} {2}", file_num, listBytes.Count, 130554);
            List <int[]> out_list = new List <int[]>();

            Writer.Write(file_num);
            for (int k = 0; k < file_num; k++)
            {
                List <int>    listBytes    = new List <int>();
                StringBuilder decompressed = new StringBuilder();
                byte[]        tmp_bytes    = new byte[130554];
                if (k == file_num - 1)
                {
                    Array.Copy(bytes2, k * 130554, tmp_bytes, 0, bytes2.Length - k * 130554);
                }
                else
                {
                    Array.Copy(bytes2, k * 130554, tmp_bytes, 0, 130554);
                }


                foreach (char kk in tmp_bytes)
                {
                    decompressed.Append(kk);
                }
                listBytes = LzwUtil.Compress(decompressed.ToString());
                out_list.Add(listBytes.ToArray());
                Writer.Write(listBytes.Count);
                //string tmp_str;
                System.Diagnostics.Debug.WriteLine("{0}", k);

                /*if (k== file_num - 1)
                 * {
                 *  tmp_list.AddRange(listBytes.GetRange(130554 / 2 * k, listBytes.Count - 130554 / 2 * k));
                 *  tmp_list.Insert(0, 0);
                 *  tmp_str = Decompress(tmp_list);
                 * }
                 * else
                 * {
                 *  tmp_list.AddRange(listBytes.GetRange(130554 / 2 * k, 130554 / 2));
                 *  tmp_list.Insert(0, 0);
                 *  tmp_str = Decompress(tmp_list);
                 * }*/
                if (k == file_num - 1)
                {
                    Writer.Write(bytes2.Length - k * 130554);
                }
                else
                {
                    Writer.Write(130554);
                }
                //Writer.Write(0xFFFD);
            }

            /*List<byte> output = new List<byte>();
             * string str = Decompress(listBytes);
             * foreach (var c in str)
             * {
             *  output.Add((byte)c);
             * }
             * // Writer.Write(output.ToArray());
             * System.Diagnostics.Debug.WriteLine(output.Count);*/

            for (int k = 0; k < out_list.Count; k++)
            {
                for (int kk = 0; kk < out_list[k].Length; kk++)
                {
                    Writer.Write((UInt16)out_list[k][kk]);
                }
            }
            Writer.Close();
        }