예제 #1
0
파일: Program.cs 프로젝트: usnail/Ninokuni
        static void Read_GVD(BinaryReaderBE br, sGVD gvd, string folderOut)
        {
            br.BaseStream.Position = gvd.offset;

            // Read header
            byte[] header = br.ReadBytes(0x10);                     // GVEW0100JPEG0100
            gvd.bigSize = new Size(br.ReadInt32(), br.ReadInt32()); // Size of the biggest quality

            Console.Write("\t\tHeader:\t"); Show_String(header);
            Console.WriteLine("\t\tBiggest size: {0}", gvd.bigSize.ToString() + " px");

            // Read first BLK_ section (contains TOC)
            BLK_Header blk1 = new BLK_Header();

            blk1.type = br.ReadUInt32();
            if (blk1.type != 0x424C4B5F)
            {
                Console.WriteLine("Error Invalid header! BLK_");
                return;
            }
            blk1.size    = br.ReadUInt32();
            blk1.id      = br.ReadUInt32();
            blk1.padding = br.ReadUInt32();

            // Unknown values, inside the BLK_ section
            br.ReadUInt32();    // Unknown: Always 0x20
            br.ReadUInt32();    // Unknown: Always 0x04

            // Start of the TOC section
            uint num_entries  = blk1.size / BlockImage.ENTRY_SIZE;
            uint curroffset   = gvd.offset + blk1.size + sGVD.HEADER_SIZE + 2 * BLK_Header.HEADER_SIZE;
            uint entry_offset = gvd.offset + sGVD.HEADER_SIZE + BLK_Header.HEADER_SIZE + 0x08;      // 0x08 = unknown values

            Page[] page = new Page[BlockImage.MAX_QUALITY];
            for (int i = 0; i < page.Length; i++)
            {
                page[i].blocks = new List <BlockImage>();
            }

            // Read each TOC entry into a BlockImage structure
            for (int i = 0; i < num_entries; i++)
            {
                br.BaseStream.Position = entry_offset + i * BlockImage.ENTRY_SIZE;

                BlockImage bi = new BlockImage();
                bi.posX      = br.ReadUInt32();
                bi.posY      = br.ReadUInt32();
                bi.quality   = br.ReadUInt32();
                bi.data_size = br.ReadUInt32();
                bi.unk1      = br.ReadUInt32();
                bi.padding   = br.ReadUInt32();
                bi.width     = br.ReadUInt32();
                bi.height    = br.ReadUInt32();

                // Get image data, it could be compressed in a GVMP structure
                // for blocked and unblocked images
                br.BaseStream.Position = curroffset;
                bi.data    = new byte[1][];
                bi.data[0] = br.ReadBytes((int)bi.data_size);
                if (Encoding.ASCII.GetString(bi.data[0], 0, 4) == "GVMP")
                {
                    bi.data = Decompress_GVMP(bi.data[0]);
                }
                if (bi.data == null)
                {
                    continue;
                }

                page[bi.quality].blocks.Add(bi);

                // Pad size and add to the current offset
                curroffset += bi.data_size;
                if (curroffset % 0x10 != 0)
                {
                    curroffset += 0x10 - (curroffset % 0x10);
                }
            }

            // Draw and save page
            for (int i = 0; i < page.Length; i++)
            {
                if (quality != -1 && quality != i)
                {
                    continue;
                }

                if (page[i].blocks.Count == 0)
                {
                    continue;
                }

                // For blocked and unblocked
                for (int j = 0; j < page[i].blocks[0].data.Length; j++)
                {
                    // Check if we should extract that page
                    bool extract = (page[i].blocks[0].data.Length == 1);    // Only if there are blocked and unblocked pages
                    if (blocked == 0)
                    {
                        extract = true;
                    }
                    else if (blocked == 1 && j == 0)
                    {
                        extract = true;
                    }
                    else if (blocked == 2 && j == 1)
                    {
                        extract = true;
                    }
                    if (!extract)
                    {
                        continue;
                    }

                    string img_out = Path.Combine(folderOut, gvd.name + '_' + i.ToString());
                    if (j != 0)
                    {
                        img_out += "_unblocked";
                    }
                    img_out += ".jpg";

                    Bitmap bmp = Draw_Page(page[i], j);
                    if (bmp != null)
                    {
                        if (File.Exists(img_out))
                        {
                            File.Delete(img_out);
                        }
                        bmp.Save(img_out, System.Drawing.Imaging.ImageFormat.Jpeg);

                        // Add it to the pdf
                        if (convert == 1)
                        {
                            pdf.SetPageSize(new iTextSharp.text.Rectangle(0, 0, bmp.Width, bmp.Height));
                            pdf.NewPage();
                            iTextSharp.text.Image jpg = iTextSharp.text.Jpeg.GetInstance(img_out);
                            //jpg.Alignment = iTextSharp.text.Image.ORIGINAL_JPEG;
                            jpg.SetAbsolutePosition(0, 0);
                            pdf.Add(jpg);
                        }

                        bmp.Dispose();
                        bmp = null;
                    }
                }

                page[i].blocks.Clear();
            }
            page = null;
        }
예제 #2
0
파일: Program.cs 프로젝트: usnail/Ninokuni
        static void Read_BookPack(string fileIn, string folderOut)
        {
            Console.WriteLine("Reading\t\t{0}", fileIn);
            Console.WriteLine("Output folder\t{0}\n", folderOut);

            BinaryReaderBE br;

            try { br = new BinaryReaderBE(fileIn); }
            catch (Exception ex) { Console.WriteLine("ERROR opening file: {0}", ex.Message); return; }

            // Read header
            ulong header = br.ReadUInt64();     // TGDT0100

            if (header != 0x5447445430313030)
            {
                Console.WriteLine("ERROR Invalid header! BOOK");
                return;
            }
            uint num_entries = br.ReadUInt32(); // Should be 0xB5
            uint data_offset = br.ReadUInt32(); // 0xB5 * 0x10 + padding

            Console.Write("Header:\t"); Show_String(header);
            Console.WriteLine("Pages:\t{0}", num_entries.ToString());

            sGVD[] gvds = new sGVD[num_entries];
            for (int i = 0; i < num_entries; i++)
            {
                br.BaseStream.Position = i * 0x10 + 0x10;             // Each entry is 0x10 bytes

                uint pageName_offset = br.ReadUInt32() + data_offset; // Relative offset to page name
                uint pageName_size   = br.ReadUInt32();
                gvds[i].offset = br.ReadUInt32() + data_offset;       // Relative offset to page data
                gvds[i].size   = br.ReadUInt32();

                // Get page name
                br.BaseStream.Position = pageName_offset;
                gvds[i].name           = Encoding.ASCII.GetString(br.ReadBytes((int)pageName_size));
                gvds[i].extension      = Path.GetExtension(gvds[i].name);       // Separate extension from name
                gvds[i].name           = Path.GetFileNameWithoutExtension(gvds[i].name);

                // Check if we should extract this page
                bool extract = false;
                if (mode == 0)      // Extract everything
                {
                    extract = true;
                }
                if (mode == 1)      // Extract page by number
                {
                    for (int n = 0; n < pages_num.Length; n++)
                    {
                        if (pages_num[n] == i)
                        {
                            extract = true;
                        }
                    }
                }
                else if (mode == 2) // Extract page by name
                {
                    for (int n = 0; n < pages_name.Length; n++)
                    {
                        if (pages_name[n] == gvds[i].name)
                        {
                            extract = true;
                        }
                    }
                }
                if (!extract)
                {
                    continue;
                }

                string folderPage = folderOut;
                if (!nofolder)
                {
                    folderPage = Path.Combine(folderOut, gvds[i].name);
                    if (!Directory.Exists(folderPage))
                    {
                        Directory.CreateDirectory(folderPage);
                    }
                }

                Console.WriteLine("\t| Reading (GVD) page {0} ({1})", i.ToString(), gvds[i].name);
                Read_GVD(br, gvds[i], folderPage);
            }

            br.Close();
            br = null;
        }