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); }
//作者: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(); }