Example #1
0
        /// <summary>
        /// First-pass processing on saving selected files (Batch Mode).  Hands the data off to saveSingle() to finish.
        /// </summary>
        /// <param name="p"></param>
        private void saveSelected(string path)
        {
#if DEBUG // TimeSpan stuff
            DateTime tstart = DateTime.Now;
#endif
            int numFiles  = fileList.SelectedItems.Count;
            int padLength = numFiles.ToString().Length;
            toolStripProgressBar1.Value   = 0;
            toolStripProgressBar1.Maximum = numFiles;

            foreach (int index in fileList.SelectedIndices)
            {
                screenshotItem shot     = screenshots[index];
                string         savePath = path + "\\" + gamesTitlesSafe[shot.gameID] + "_" + (index).ToString().PadLeft(padLength, '0') + "_" + shot.shotTitle + ".jpg";
                toolStripStatusLabel1.Text = "Saving " + savePath;
                saveSingle(shot, savePath);
                toolStripProgressBar1.PerformStep();
                Application.DoEvents();
            }

            toolStripStatusLabel1.Text = "Saved " + numFiles + " screenshots to " + path;
            settings.fbdSavePath       = path;
            settings.Save();
#if DEBUG // TimeSpan stuff
            DateTime tend     = DateTime.Now;
            TimeSpan duration = tend - tstart;
            string   hours    = (duration.Hours != 0) ? duration.Hours + " hours," : "";
            string   secs     = (duration.Minutes != 0) ? duration.Minutes + " minutes," : "";
            string   mins     = (duration.Seconds != 0) ? duration.Seconds + " seconds," : "";
            string   mill     = (duration.Milliseconds != 0) ? duration.Milliseconds + " ms" : "";
            toolStripStatusLabel1.Text += " Total Time: " + hours + mins + secs + mill;
#endif
        }
Example #2
0
        /// <summary>
        /// Extracts and saves a single screenshot supplied by saveMulti()
        /// </summary>
        /// <param name="shot">screenshotItem containing information about the screenshot to be saved</param>
        /// <param name="savePath">The path on the harddrive where the screenshot will be saved</param>
        private void saveSingle(screenshotItem shot, string savePath)
        {
            FileStream   fSave = new FileStream(savePath, FileMode.Create, FileAccess.Write);
            BinaryWriter bw    = new BinaryWriter(fSave);

            bw.Write(reader.readFile(shot));

            bw.Close();
            fSave.Close();
        }
Example #3
0
        private void contextMenuSaveThis_Click(object sender, EventArgs e)
        {
            screenshotItem shot = screenshots[rightClickIndex];

            sfd.FileName = shot.shotTitle;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                saveSingle(shot, sfd.FileName);
                toolStripStatusLabel1.Text = "Saved " + sfd.FileName;
            }
        }
        public void showPreview(screenshotItem shot)
        {
            this.WindowState = FormWindowState.Normal;
            MemoryStream previewMem = new MemoryStream(reader.readFile(shot));
            Bitmap       preview    = new Bitmap(previewMem);

            previewMem.Close();
            previewMem.Dispose();

            this.Text         = "Previewing \"" + shot.shotTitle + "\"";
            pictureBox1.Image = preview;
            this.ClientSize   = new Size(preview.Width / 2, preview.Height / 2);
        }
Example #5
0
        internal screenshotItem shotReach(BinaryReader br, int fileStart, screenshotItem screenshot)
        {
            int headerStart = (fileStart - 49152) / 4096;

            br.BaseStream.Position = fileStart + 4;
            int blfLength = br.ReadBigInt32();

            br.BaseStream.Position = fileStart + blfLength + 4;
            int chdrLength = br.ReadBigInt32();

            br.BaseStream.Position = fileStart + blfLength + 12;
            int blfVersion = br.ReadBigInt16();

            br.BaseStream.Position += 46; // Move forward 46 bytes to get to the mapID
            int mapId = br.ReadBigInt32();

            if (screenshot.gameID == 4 && mapId == 10080)
            {
                mapId += 1;               // This is done to prevent a discrepancy with Halo: Reach's "Installation 04"
            }
            br.BaseStream.Position += 12; // Move forward 12 bytes to get to the created timestamp
            int createTime = br.ReadBigInt32();

            br.BaseStream.Position += 32;
            int modTime = br.ReadBigInt32();

            br.BaseStream.Position += 28; // Move forward 28 bytes to get to the title
            string shotTitle = Encoding.BigEndianUnicode.GetString(br.ReadBytes(256)).Trim('\0');

            br.BaseStream.Position = fileStart + blfLength + chdrLength + 4;
            int scncLength = br.ReadBigInt32();

            br.BaseStream.Position = screenshot.hashTable + ((headerStart * 24) + 21); // Since the header in Reach Retail screenshot files spans more than one block, we need to find out where to go next from the hash table
            int nextBlock   = (br.ReadBigInt24() * 4096) + 49152;
            int bytesRemain = (blfLength + chdrLength + scncLength) - 4096;

            br.BaseStream.Position = nextBlock + bytesRemain + 12;
            int jpegLength = br.ReadBigInt32();
            int jpegOffset = (int)br.BaseStream.Position;

            screenshot.blfVersion   = blfVersion;
            screenshot.headerLength = blfLength + chdrLength + scncLength + 16;
            screenshot.headerStart  = headerStart;
            screenshot.jpegLength   = jpegLength;
            screenshot.jpegOffset   = jpegOffset;
            screenshot.mapID        = mapId;
            screenshot.fileTime     = createTime;
            screenshot.shotTitle    = shotTitle;

            return(screenshot);
        }
Example #6
0
        internal screenshotItem shotHalo3ODST(BinaryReader br, int fileStart, screenshotItem screenshot)
        {
            br.BaseStream.Position = fileStart + 4;
            int blfLength = br.ReadBigInt32();

            br.BaseStream.Position = fileStart + blfLength + 4;
            int chdrLength = br.ReadBigInt32();

            br.BaseStream.Position = fileStart + blfLength + 12;
            int blfVersion = br.ReadBigInt16();

            br.BaseStream.Position += 10; // Move forward 10 bytes to get to the start of the title
            string shotTitle = Encoding.BigEndianUnicode.GetString(br.ReadBytes(32)).Trim('\0');

            br.BaseStream.Position += 172; // Move forward 172 bytes to get to the shot time
            int shotTime = br.ReadBigInt32();

            br.BaseStream.Position += 8;
            int mapId = br.ReadBigInt32();

            br.BaseStream.Position += 8;
            byte fireFight = br.ReadByte();

            if (fireFight != 0)
            {
                mapId += 10000 + fireFight;
            }
            br.BaseStream.Position = fileStart + blfLength + chdrLength + 4;
            int scncLength = 0; // The scnc block doesn't exist in versions prior to 12070, so we'll check for that

            if (blfVersion >= 12070)
            {
                scncLength = br.ReadBigInt32();
            }
            br.BaseStream.Position = fileStart + blfLength + chdrLength + scncLength + 12;
            int jpegLength = br.ReadBigInt32();
            int jpegOffset = (int)br.BaseStream.Position;

            screenshot.blfVersion   = blfVersion;
            screenshot.headerLength = blfLength + chdrLength + scncLength + 16;
            screenshot.headerStart  = (fileStart - 49152) / 4096;
            screenshot.jpegLength   = jpegLength;
            screenshot.jpegOffset   = jpegOffset;
            screenshot.fileTime     = shotTime;
            screenshot.mapID        = mapId;
            screenshot.shotTitle    = shotTitle;

            return(screenshot);
        }
Example #7
0
        internal screenshotItem shotReachBeta(BinaryReader br, int fileStart, screenshotItem screenshot)
        {
            br.BaseStream.Position = fileStart + 4;
            int blfLength = br.ReadBigInt32();

            br.BaseStream.Position = fileStart + blfLength + 4;
            int chdrLength = br.ReadBigInt32();

            br.BaseStream.Position = fileStart + blfLength + 12;
            int blfVersion = br.ReadBigInt16();

            br.BaseStream.Position += 46; // Move forward 46 bytes to get to the mapID
            int mapId = br.ReadBigInt32() + 10000;

            br.BaseStream.Position += 12; // Move forward 12 to get to the created time
            int shotTime = br.ReadBigInt32();

            br.BaseStream.Position += 64; // Move forward 64 bytes to get to the title
            string shotTitle = Encoding.BigEndianUnicode.GetString(br.ReadBytes(256)).Trim('\0');

            br.BaseStream.Position = fileStart + blfLength + chdrLength + 4;
            int scncLength = 0; // The scnc block doesn't exist in Halo: Reach Beta screenshots

            br.BaseStream.Position = fileStart + blfLength + chdrLength + scncLength + 12;
            int jpegLength = br.ReadBigInt32();
            int jpegOffset = (int)br.BaseStream.Position;

            screenshot.blfVersion   = blfVersion;
            screenshot.headerLength = blfLength + chdrLength + scncLength + 16;
            screenshot.headerStart  = (fileStart - 49152) / 4096;
            screenshot.jpegLength   = jpegLength;
            screenshot.jpegOffset   = jpegOffset;
            screenshot.mapID        = mapId;
            screenshot.fileTime     = shotTime;
            screenshot.shotTitle    = shotTitle;

            return(screenshot);
        }
Example #8
0
        /// <summary>
        /// Handles the extraction of a single screenshot from a supplied screenshot CON file
        /// </summary>
        /// <param name="savingFile">Bool determing whether the file will be automatically saved or not</param>
        /// <param name="warn">Bool determining whether the user will be warned of errors</param>
        private void processSingle(bool savingFile, bool warn)
        {
            if (!CONfirm())
            {
                if (warn)
                {
                    errorShow();
                }
                return;
            }
            if (!confirmShot())
            {
                if (warn)
                {
                    errorShow();
                }
                return;
            }

            // Begin reading the CON file list
            br.BaseStream.Position = contentStart + fileListAdd + 41;
            int numBlocks = br.ReadInt24();

            br.BaseStream.Position = contentStart + fileListAdd + 47;
            int fileStart = contentStart + (br.ReadInt24() * 4096); // I now know where my blf file starts, I can use this as a baseline to iterate through the various blf blocks.

            br.BaseStream.Position = contentStart + fileListAdd + 52;
            int fileSize = br.ReadBigInt32(); // And I also know how long my blf file is, but I don't think I'll need this.

            br.BaseStream.Position = contentStart + fileListAdd + 56;
            int fileTime = br.ReadBigInt32();                // FAT formatted time

            screenshotItem screenshot = new screenshotItem() // We need to set a few initial variables
            {
                fileName = finfo.FullName,
                //fileTime = fileTime,
                gameID    = gameID,
                hashTable = hashTable,
                numBlocks = numBlocks
            };

            switch (gameID)
            {
            case 0:     // Halo 3
                screenshot = reader.shotHalo3(br, fileStart, screenshot);
                break;

            case 1:     // Halo 3: ODST
                screenshot = reader.shotHalo3ODST(br, fileStart, screenshot);
                break;

            case 2:     // Halo: Reach Beta
                screenshot = reader.shotReachBeta(br, fileStart, screenshot);
                break;

            case 3:     // Halo: Reach
            case 4:     // Halo 4 (this is a test)
                screenshot = reader.shotReach(br, fileStart, screenshot);
                break;
            }

            if (savingFile)
            {
                sfd.FileName = screenshot.shotTitle;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    saveSingle(screenshot, sfd.FileName);
                    toolStripStatusLabel1.Text = "Saved " + sfd.FileName;
                }
                br.Close();
                fs.Close();
                return;
            }

            if (!screenshots.Contains(screenshot))
            {
                screenshots.Add(screenshot);
            }
            br.Close();
            fs.Close();
        }
Example #9
0
        public byte[] readFile(screenshotItem shot)
        {
#if DEBUG
            FileStream   debug = new FileStream(shot.fileName + "_debug.txt", FileMode.Create, FileAccess.ReadWrite);
            StreamWriter sw    = new StreamWriter(debug);
            sw.WriteLine("Total Filesize: " + shot.jpegLength + ", numBlocks: " + shot.numBlocks + " hashBlock: 0x" + shot.hashTable.ToString("X"));
            sw.Flush();
#endif
            FileStream   fs           = new FileStream(shot.fileName, FileMode.Open, FileAccess.Read);
            BinaryReader br           = new BinaryReader(fs);
            byte[]       file         = new byte[shot.jpegLength];
            int          count        = 0;
            int          copyTo       = 0;
            int          thisBlock    = shot.headerStart;
            int          headerLength = shot.headerLength;
            int          numBlocks    = shot.numBlocks;
            short        blockRemain  = (short)((numBlocks * 4096) - shot.jpegLength - headerLength);
            if (blockRemain > 4096)
            {
#if DEBUG
                sw.WriteLine("// Block Remainder: ((" + shot.numBlocks + " * 4096) - " + shot.jpegLength + " - " + shot.headerLength + ") = " + blockRemain + " //");
                sw.WriteLine("// Block remainder is greater than 4096, ignoring last block //");
#endif
                numBlocks--;
            }
            while (headerLength >= 4096) // This should only happen in Reach Retail files, because of the extra length of the SCNC block
            {
                numBlocks--;
                headerLength          -= 4096;
                br.BaseStream.Position = shot.hashTable + ((thisBlock * 24) + 21);
                thisBlock = br.ReadBigInt24();
            }
#if DEBUG
            sw.WriteLine();
            sw.Flush();
#endif
            while (count < numBlocks)
            {
                br.BaseStream.Position = (thisBlock * 4096) + 49152;
                byte[] buffer;
                int    readBytes = 4096;

                if (count == 0)
                {
                    br.BaseStream.Position += headerLength;
                    readBytes -= headerLength;
                }
                else if (count == (numBlocks - 1))
                {
                    readBytes -= (numBlocks * 4096) - headerLength - shot.jpegLength;
                }
#if DEBUG
                sw.WriteLine("count: " + count.ToString().PadLeft(shot.numBlocks.ToString().Length, ' ') +
                             ", thisBlock: " + thisBlock.ToString().PadLeft(shot.numBlocks.ToString().Length, ' ') +
                             ", hashTable: " + (int)(shot.hashTable + ((thisBlock * 24) + 21)) +
                             ", reading " + readBytes.ToString().PadLeft(4, ' ') + " bytes from " +
                             br.BaseStream.Position.ToString().PadLeft(shot.jpegLength.ToString().Length, ' ') +
                             " and copying to " + copyTo.ToString().PadLeft(shot.jpegLength.ToString().Length, ' '));
                sw.Flush();
#endif
                buffer = br.ReadBytes(readBytes);
                br.BaseStream.Position = shot.hashTable + ((thisBlock * 24) + 21);
                thisBlock = br.ReadBigInt24();
                count++;

                try
                {
                    buffer.CopyTo(file, copyTo);
                }
                catch (Exception e)
                {
#if DEBUG
                    sw.WriteLine();
                    sw.WriteLine("// Error occured at count " + count + ": " + e.Message + "//");
                    sw.WriteLine();
                    sw.Flush();
#endif
                }

                copyTo += readBytes;
            }

            br.Close();
            fs.Close();
#if DEBUG
            sw.Close();
            debug.Close();
#endif
            return(file);
        }