static Bitmap Draw_Page(Page page, int block) { if (page.blocks.Count == 0) { return(null); } // Get image width BlockImage last_bi = page.blocks[page.blocks.Count - 1]; int img_width = (int)(last_bi.posX * 0x100 + last_bi.width); int img_height = (int)(last_bi.posY * 0x100 + last_bi.height); Bitmap bmp = new Bitmap(img_width, img_height); Graphics graphic = Graphics.FromImage(bmp); // Write image for (int i = 0; i < page.blocks.Count; i++) { // Save the JPG data to open it string temp = Path.GetTempFileName(); File.WriteAllBytes(temp, page.blocks[i].data[block]); Image img; try { img = Image.FromFile(temp); } catch { Console.WriteLine("Error opening JPG file!"); return(null); } // Draw it graphic.DrawImageUnscaled(img, (int)page.blocks[i].posX * 0x100, (int)page.blocks[i].posY * 0x100); img.Dispose(); img = null; File.Delete(temp); } graphic.Dispose(); graphic = null; return(bmp); }
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; }