home *** CD-ROM | disk | FTP | other *** search
/ Xentax forum attachments archive / xentax.7z / 7356 / GladiusPS2ImageExtractor.7z / GladiusPS2ImageExtractor / GladiusImage.cs < prev    next >
Encoding:
Text File  |  2014-05-21  |  24.6 KB  |  695 lines

  1. ∩╗┐// a greatly modified parser , originaly based on the targa reader by David Polomis (paloma_sw@cox.net)
  2. // now modified to extract image files from the ps2 version of LucasArts gladius.
  3.  
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Collections;
  7. using System.Text;
  8. using System.IO;
  9. using System.Drawing;
  10. using System.Drawing.Imaging;
  11. using System.Runtime.InteropServices;
  12.  
  13. namespace xexuxjy
  14. {
  15.     public class GladiusHeader
  16.     {
  17.         private short sColorMapFirstEntryIndex = 0;
  18.         private short sColorMapLength = 0;
  19.         private byte bColorMapEntrySize = 0;
  20.         public int Width = 0;
  21.         public int Height = 0;
  22.         private byte bPixelDepth = 0;
  23.         private byte bImageDescriptor = 0;
  24.         public byte[] RawColourMap;
  25.         public byte[] SwizzledColourMap;
  26.         public PixelFormat PixelFormat;
  27.  
  28.         public static char[] PTTPHeader = new char[] { 'P', 'T', 'T', 'P' };
  29.         public static char[] NMPTHeader = new char[] { 'N', 'M', 'P', 'T' };
  30.         public static char[] r2d2Header = new char[] { 'R', '2', 'D', '2', 'p', 's', 'x', '2' };
  31.         public static char[] tmapHeader = new char[] { 't', 'm', 'a', 'p' };
  32.  
  33.  
  34.         public static void TestGladius()
  35.         {
  36.             GladiusImage targaImage = new GladiusImage();
  37.  
  38.             String targetDirectory = @"C:/gladius-extracted/test-extract/";
  39.             //String filepath = @"D:\gladius-extracted\ps2-decompressed\converted1\";
  40.             //String filepath = @"D:\gladius-extracted\ps2-decompressed\PTTP\";
  41.             //String errorFile = @"D:\gladius-extracted\ps2-decompressed-errors";
  42.  
  43.             String filepath = @"C:\gladius-extracted\ps2-decompressed\PTTP\";
  44.             String errorFile = @"C:\gladius-extracted\ps2-decompressed-errors";
  45.  
  46.             System.IO.DirectoryInfo targetInfo = new DirectoryInfo(targetDirectory);
  47.             if (!targetInfo.Exists)
  48.             {
  49.                 targetInfo.Create();
  50.             }
  51.  
  52.             bool doDelete = true;
  53.             if (doDelete)
  54.             {
  55.                 foreach (FileInfo file in targetInfo.GetFiles())
  56.                 {
  57.                     file.Delete();
  58.                 }
  59.             }
  60.  
  61.             string[] filePaths = Directory.GetFiles(filepath);
  62.  
  63.             DirectoryInfo d = new DirectoryInfo(filepath);
  64.             FileInfo[] files = d.GetFiles(); //Getting Text files
  65.             using (StreamWriter errorStream = new StreamWriter(new FileStream(errorFile, FileMode.OpenOrCreate)))
  66.             {
  67.                 GladiusImage image = null;
  68.                 foreach (FileInfo file in files)
  69.                 {
  70.                     //if (file.Name != "File_000957")
  71.                     //if (file.Name != "File_000230")
  72.                     if (file.Name != "File_000024")
  73.                     {
  74.                         //continue;
  75.                     }
  76.                     using (FileStream fs = new FileStream(filepath + file.Name, FileMode.Open))
  77.                     using (BinaryReader binReader = new BinaryReader(fs))
  78.                     {
  79.                         int headerPadding = 0;
  80.  
  81.                         int subImageCounter = 0;
  82.  
  83.                         List<String> textureNameList = BuildImageList(binReader);
  84.  
  85.                         // if there were no texture names then reset the position of the stream to find the data.
  86.                         if (textureNameList.Count == 0)
  87.                         {
  88.                             binReader.BaseStream.Position = 0;
  89.                         }
  90.  
  91.                         while (ReadToNextTMapBlock(binReader, ref subImageCounter))
  92.                         {
  93.                             int adjustedCounter = subImageCounter-1;
  94.  
  95.                             image = new GladiusImage();
  96.  
  97.                             image.Header.LoadHeaderInfo(binReader, errorStream, file.Name);
  98.  
  99.                             bool saveImage = true;
  100.                             String outputFileName = null;
  101.                             if (textureNameList.Count > 0 && adjustedCounter < textureNameList.Count)
  102.                             {
  103.                                 //outputFileName = file.Name + "-" + textureNameList[adjustedCounter];
  104.                                 outputFileName = textureNameList[adjustedCounter];
  105.                             }
  106.                             else
  107.                             {
  108.                                 outputFileName = file.Name + "-" + (adjustedCounter);
  109.                             }
  110.  
  111.                             //outputFileName = file.Name + "-" + (subImageCounter);
  112.  
  113.                             errorStream.WriteLine(String.Format("Extracting [{0}][{1}][{2}]", file.Name, adjustedCounter, outputFileName));
  114.  
  115.                             int imagePadding = 0x13;// 0x24;
  116.  
  117.                             if (image.Header.PixelFormat == PixelFormat.Format8bppIndexed)
  118.                             {
  119.                                 //image.Header.Se
  120.                                 image.Header.ColorMapLength = 256;
  121.                                 image.Header.ColorMapEntrySize = 32;
  122.  
  123.                                 if (binReader.BaseStream.Position + 1024 > binReader.BaseStream.Length)
  124.                                 {
  125.                                     // not enough room for a colour map?
  126.                                     break;
  127.                                 }
  128.                                 image.Header.PixelDepth = 8;
  129.                                 image.LoadColourMapInfo(binReader);
  130.  
  131.                             }
  132.                             else if (image.Header.PixelFormat == PixelFormat.Format32bppArgb)
  133.                             {
  134.                                 image.Header.PixelDepth = 32;
  135.                             }
  136.                             else
  137.                             {
  138.                                 int ibreak = 0;
  139.                             }
  140.  
  141.                             if (image.Header.ValidSize() && image.Header.KnownFormat())
  142.                             {
  143.  
  144.  
  145.                                 binReader.BaseStream.Seek(imagePadding, SeekOrigin.Current);
  146.                                 try
  147.                                 {
  148.                                     image.LoadGladiusImage(binReader);
  149.                                     if (saveImage)
  150.                                     {
  151.                                         image.Image.Save(targetDirectory + outputFileName + ".png", ImageFormat.Png);
  152.                                     }
  153.                                 }
  154.                                 catch (AccessViolationException e)
  155.                                 {
  156.                                     // bleugh.
  157.                                 }
  158.  
  159.                                 bool writePalette = false;
  160.                                 if (writePalette)
  161.                                 {
  162.                                     using (var fs2 = new FileStream(targetDirectory + file.Name + "-pal.bin", FileMode.CreateNew))
  163.                                     {
  164.                                         using (var bw = new BinaryWriter(fs2))
  165.                                         {
  166.                                             bw.Write(image.Header.RawColourMap);
  167.                                         }
  168.                                     }
  169.  
  170.                                     using (var fs2 = new FileStream(targetDirectory + file.Name + "-cpal.bin", FileMode.CreateNew))
  171.                                     {
  172.                                         using (var bw = new BinaryWriter(fs2))
  173.                                         {
  174.                                             bw.Write(image.Header.SwizzledColourMap);
  175.                                         }
  176.                                     }
  177.                                 }
  178.                             }
  179.                         }
  180.                     }
  181.                 }
  182.             }
  183.  
  184.         }
  185.  
  186.         //readpfhd!
  187.  
  188.  
  189.         /// <summary>
  190.         /// Gets total number of color map entries included.
  191.         /// </summary>
  192.         public short ColorMapLength
  193.         {
  194.             get;set;
  195.         }
  196.  
  197.         /// <summary>
  198.         /// Gets the number of bits per entry in the Color Map. Typically 15, 16, 24 or 32-bit values are used.
  199.         /// </summary>
  200.         public byte ColorMapEntrySize
  201.         {
  202.             get;set;
  203.         }
  204.  
  205.  
  206.         /// <summary>
  207.         /// Gets the number of bits per pixel. This number includes
  208.         /// the Attribute or Alpha channel bits. Common values are 8, 16, 24 and 32.
  209.         /// </summary>
  210.         public byte PixelDepth
  211.         {
  212.             get;set;
  213.         }
  214.  
  215.  
  216.         /// <summary>
  217.         /// Gets the number of bytes per pixel.
  218.         /// </summary>
  219.         public int BytesPerPixel
  220.         {
  221.             get
  222.             {
  223.                 return (int)this.PixelDepth / 8;
  224.             }
  225.         }
  226.  
  227.         public static bool FindCharsInStream(BinaryReader binReader, char[] charsToFind)
  228.         {
  229.             bool found = false;
  230.             char c = ' ';
  231.             int lastFoundIndex = 0;
  232.             try
  233.             {
  234.                 while (true)
  235.                 {
  236.                     c = (char)binReader.ReadByte();
  237.                     if (c == charsToFind[lastFoundIndex])
  238.                     {
  239.                         lastFoundIndex++;
  240.                         if (lastFoundIndex == charsToFind.Length)
  241.                         {
  242.                             found = true;
  243.                             break;
  244.                         }
  245.                     }
  246.                     else
  247.                     {
  248.                         lastFoundIndex = 0;
  249.                     }
  250.                 }
  251.             }
  252.             catch (Exception e)
  253.             {
  254.                 int ibreak = 0;
  255.             }
  256.             return found;
  257.  
  258.         }
  259.  
  260.  
  261.         public static bool ReadToNextTMapBlock(BinaryReader binReader, ref int imageCount)
  262.         {
  263.             bool foundR2D2 = FindCharsInStream(binReader, GladiusHeader.r2d2Header);
  264.             bool foundTmap = false;
  265.             byte[] extra = new byte[8];
  266.  
  267.             while (foundR2D2)
  268.             {
  269.                 imageCount++;
  270.  
  271.                 binReader.Read(extra, 0, extra.Length);
  272.                 bool shouldHaveTmap = (extra[5] != 0x00);
  273.                 if (shouldHaveTmap)
  274.                 {
  275.                     foundTmap = FindCharsInStream(binReader, GladiusHeader.tmapHeader);
  276.                     //if (foundTmap)
  277.                     //{
  278.                     //    imageCount++;
  279.                     //}
  280.                     break;
  281.                 }
  282.                 foundR2D2 = FindCharsInStream(binReader, GladiusHeader.r2d2Header);
  283.             }
  284.  
  285.             return foundTmap;
  286.         }
  287.  
  288.  
  289.         public static List<String> BuildImageList(BinaryReader binReader)
  290.         {
  291.             List<String> textureNameList = new List<string>();
  292.  
  293.             List<String> ignoreList = new List<string>();
  294.  
  295.             // for some reason these seem to be referenced but not included in all(?) the files so ignore them.
  296.             //ignoreList.Add("teeth.tga");
  297.             //ignoreList.Add("skygold_R.rm.tga");
  298.  
  299.             // load header and map of image names.
  300.             if (FindCharsInStream(binReader, GladiusHeader.PTTPHeader))
  301.             {
  302.                 if (FindCharsInStream(binReader, GladiusHeader.NMPTHeader))
  303.                 {
  304.                     int unknown1 = binReader.ReadInt32();
  305.                     int unknown2 = binReader.ReadInt32();
  306.                     int numTextures = binReader.ReadInt32();
  307.  
  308.                     for (int i = 0; i < numTextures; ++i)
  309.                     {
  310.                         StringBuilder sb = new StringBuilder();
  311.                         char b = (char)binReader.ReadByte();
  312.                         while (b != 0x00)
  313.                         {
  314.                             if (b != 0x00)
  315.                             {
  316.                                 sb.Append(b);
  317.                             }
  318.                             b = (char)binReader.ReadByte();
  319.                         }
  320.                         String n = sb.ToString();
  321.                         if (!ignoreList.Contains(n))
  322.                         {
  323.                             textureNameList.Add(n);
  324.                         }
  325.                     }
  326.                 }
  327.  
  328.             }
  329.             return textureNameList;
  330.         }
  331.  
  332.  
  333.        
  334.  
  335.         public bool KnownFormat()
  336.         {
  337.             return PixelFormat == PixelFormat.Format8bppIndexed || PixelFormat == PixelFormat.Format32bppArgb;
  338.         }
  339.  
  340.         public bool ValidSize()
  341.         {
  342.             return !(Width <= 0 || Height <= 0 || Width > 1024 || Height > 1024);
  343.         }
  344.  
  345.  
  346.         public void LoadHeaderInfo(BinaryReader binReader, StreamWriter errorStream, String file)
  347.         {
  348.             int headerPadding = 0;
  349.  
  350.             byte[] extraHeader = new byte[24];
  351.             binReader.Read(extraHeader, 0, extraHeader.Length);
  352.  
  353.             //19th extra byte should determine image format (8bppIndexed,32rgba)
  354.             //20th extra byte should be FF
  355.             int imageSize = extraHeader[2];
  356.             int imageFormat = extraHeader[22];
  357.  
  358.             if (imageFormat == 0xB0)
  359.             {
  360.                 if (imageSize == 0x10)
  361.                 {
  362.                     Width = Height = 256;
  363.                 }
  364.                 else if (imageSize == 0x08)
  365.                 {
  366.                     Width = Height = 0x20;
  367.                 }
  368.                 else if (imageSize == 0x04)
  369.                 {
  370.                     Width = Height = 64;
  371.                 }
  372.                 else
  373.                 {
  374.                     errorStream.WriteLine(String.Format("Unknown size [{0}] File [{1}]", imageSize, file));
  375.                 }
  376.  
  377.                 PixelFormat = PixelFormat.Format32bppArgb;
  378.                 headerPadding = 101;
  379.             }
  380.             else if (imageFormat == 0xD8 || imageFormat == 0x60)
  381.             {
  382.                 PixelFormat = PixelFormat.Format8bppIndexed;
  383.                 headerPadding = 0x78 - 20;
  384.             }
  385.             else
  386.             {
  387.                 errorStream.WriteLine(String.Format("Unknown Output Format [{0}] File [{1}] Position[{2}]", imageFormat, file, binReader.BaseStream.Position));
  388.             }
  389.  
  390.             {
  391.                 binReader.BaseStream.Seek(headerPadding, SeekOrigin.Current);
  392.                 //return binReader.BaseStream.Position;
  393.  
  394.             }
  395.         }
  396.  
  397.         public static bool PositionReaderAtNextImage(BinaryReader binReader, StreamWriter errorStream, String file)
  398.         {
  399.             return FindCharsInStream(binReader, GladiusHeader.r2d2Header) && FindCharsInStream(binReader, GladiusHeader.tmapHeader);
  400.         }
  401.  
  402.         static int Main(string[] args)
  403.         {
  404.             GladiusHeader.TestGladius();
  405.             return 0;
  406.         }
  407.  
  408.     }
  409.  
  410.  
  411.  
  412.     public class GladiusImage : IDisposable
  413.     {
  414.         private GladiusHeader gladiusHeader = null;
  415.         private Bitmap bitmapImage = null;
  416.         private string strFileName = string.Empty;
  417.         private int intStride = 0;
  418.         private GCHandle ImageByteHandle;
  419.         private System.Collections.Generic.List<System.Collections.Generic.List<byte>> rows = new System.Collections.Generic.List<System.Collections.Generic.List<byte>>();
  420.         private System.Collections.Generic.List<byte> row = new System.Collections.Generic.List<byte>();
  421.  
  422.         /// <summary>
  423.         /// Creates a new instance of the TargaImage object.
  424.         /// </summary>
  425.         public GladiusImage()
  426.         {
  427.             this.gladiusHeader = new GladiusHeader();
  428.             this.bitmapImage = null;
  429.         }
  430.  
  431.  
  432.         /// <summary>
  433.         /// Gets a TargaHeader object that holds the Targa Header information of the loaded file.
  434.         /// </summary>
  435.         public GladiusHeader Header
  436.         {
  437.             get { return this.gladiusHeader; }
  438.             set { this.gladiusHeader = value; }
  439.         }
  440.  
  441.         /// <summary>
  442.         /// Gets a Bitmap representation of the loaded file.
  443.         /// </summary>
  444.         public Bitmap Image
  445.         {
  446.             get { return this.bitmapImage; }
  447.         }
  448.  
  449.         /// <summary>
  450.         /// Gets the full path and filename of the loaded file.
  451.         /// </summary>
  452.         public string FileName
  453.         {
  454.             get { return this.strFileName; }
  455.         }
  456.  
  457.  
  458.         /// <summary>
  459.         /// Gets the byte offset between the beginning of one scan line and the next. Used when loading the image into the Image Bitmap.
  460.         /// </summary>
  461.         /// <remarks>
  462.         /// The memory allocated for Microsoft Bitmaps must be aligned on a 32bit boundary.
  463.         /// The stride refers to the number of bytes allocated for one scanline of the bitmap.
  464.         /// </remarks>
  465.         public int Stride
  466.         {
  467.             get { return this.intStride; }
  468.         }
  469.  
  470.         ~GladiusImage()
  471.         {
  472.             Dispose(false);
  473.         }
  474.  
  475.         public void LoadColourMapInfo(BinaryReader binReader)
  476.         {
  477.             int paletteSize = 1024;
  478.  
  479.             this.gladiusHeader.RawColourMap = new byte[paletteSize];
  480.             this.gladiusHeader.SwizzledColourMap = new byte[paletteSize];
  481.  
  482.             int rawCounter = 0;
  483.  
  484.             while (rawCounter < paletteSize)
  485.             {
  486.                 int a = 0;
  487.                 int r = 0;
  488.                 int g = 0;
  489.                 int b = 0;
  490.  
  491.                 byte rbyte = binReader.ReadByte();
  492.                 byte gbyte = binReader.ReadByte();
  493.                 byte bbyte = binReader.ReadByte();
  494.                 byte abyte = binReader.ReadByte();
  495.  
  496.                 this.gladiusHeader.RawColourMap[rawCounter++] = rbyte;
  497.                 this.gladiusHeader.RawColourMap[rawCounter++] = gbyte;
  498.                 this.gladiusHeader.RawColourMap[rawCounter++] = bbyte;
  499.                 this.gladiusHeader.RawColourMap[rawCounter++] = abyte;
  500.             }
  501.  
  502.             byte[] src = this.gladiusHeader.RawColourMap;
  503.             byte[] tgt = this.gladiusHeader.SwizzledColourMap;
  504.  
  505.             int blockSize = 8;
  506.             int blockIncrement = blockSize * 4;
  507.             int offset = 0;
  508.             while (offset < src.Length)
  509.             {
  510.  
  511.                 for (int j = 0; j < blockSize; ++j)
  512.                 {
  513.                     tgt[offset + 0] = src[offset + 2];
  514.                     tgt[offset + 1] = src[offset + 1];
  515.                     tgt[offset + 2] = src[offset + 0];
  516.                     tgt[offset + 3] = src[offset + 3];
  517.                     offset += 4;
  518.                 }
  519.  
  520.                 for (int j = 0; j < blockSize; ++j)
  521.                 {
  522.                     tgt[offset + 0] = src[blockIncrement + offset + 2];
  523.                     tgt[offset + 1] = src[blockIncrement + offset + 1];
  524.                     tgt[offset + 2] = src[blockIncrement + offset + 0];
  525.                     tgt[offset + 3] = src[blockIncrement + offset + 3];
  526.                     offset += 4;
  527.                 }
  528.  
  529.                 for (int j = 0; j < blockSize; ++j)
  530.                 {
  531.                     tgt[offset + 0] = src[offset + 2 - (blockIncrement * 1)];
  532.                     tgt[offset + 1] = src[offset + 1 - (blockIncrement * 1)];
  533.                     tgt[offset + 2] = src[offset + 0 - (blockIncrement * 1)];
  534.                     tgt[offset + 3] = src[offset + 3 - (blockIncrement * 1)];
  535.                     offset += 4;
  536.                 }
  537.  
  538.                 for (int j = 0; j < blockSize; ++j)
  539.                 {
  540.                     tgt[offset + 0] = src[offset + 2];
  541.                     tgt[offset + 1] = src[offset + 1];
  542.                     tgt[offset + 2] = src[offset + 0];
  543.                     tgt[offset + 3] = src[offset + 3];
  544.                     offset += 4;
  545.                 }
  546.  
  547.             }
  548.  
  549.             // skip 12?
  550.             int a1 = binReader.ReadInt32();
  551.             int a2 = binReader.ReadInt32();
  552.             
  553.             this.gladiusHeader.Width = binReader.ReadInt16();
  554.             this.gladiusHeader.Height = binReader.ReadInt16();
  555.         }
  556.  
  557.         // assumes we've position the stream.
  558.         private byte[] LoadImageBytes(BinaryReader binReader)
  559.         {
  560.             byte[] data = null;
  561.             int intImageRowByteSize = (int)this.gladiusHeader.Width * ((int)this.gladiusHeader.BytesPerPixel);
  562.             
  563.             // get the size in bytes of the whole image
  564.             int intImageByteSize = intImageRowByteSize * (int)this.gladiusHeader.Height;
  565.             data = new byte[intImageByteSize];
  566.  
  567.             try
  568.             {
  569.                 if(Header.PixelFormat == PixelFormat.Format8bppIndexed)
  570.                 {
  571.                     for (int i = 0; i < data.Length; ++i)
  572.                     {
  573.  
  574.                         data[i] = binReader.ReadByte();
  575.                     }
  576.                 }
  577.                 else if (Header.PixelFormat == PixelFormat.Format32bppArgb)
  578.                 {
  579.                     byte[] subBytes = new byte[4];
  580.                     int adjustedLength = data.Length / 4;
  581.                     int counter = 0;
  582.                     for (int i = 0; i < adjustedLength; ++i)
  583.                     {
  584.                         subBytes[0] = binReader.ReadByte ();
  585.                         subBytes[1] = binReader.ReadByte ();
  586.                         subBytes[2] = binReader.ReadByte ();
  587.                         subBytes[3] = binReader.ReadByte ();
  588.  
  589.                         //bgr
  590.                         //Array.Reverse(subBytes);
  591.                         subBytes[3] = 0xff;
  592.                         data[counter++] = subBytes[2];
  593.                         data[counter++] = subBytes[1];
  594.                         data[counter++] = subBytes[0];
  595.                         data[counter++] = subBytes[3];
  596.                     }
  597.  
  598.                 }
  599.  
  600.  
  601.  
  602.  
  603.             }
  604.             catch (Exception e)
  605.             {
  606.                 // if we read past the end, somethings wrong, but try and return as much data as we could get..
  607.             }
  608.             // return the image byte array
  609.             return data;
  610.  
  611.         }
  612.  
  613.         public void LoadGladiusImage(BinaryReader binReader)
  614.         {
  615.             this.intStride = (((int)this.gladiusHeader.Width * (int)this.gladiusHeader.PixelDepth + 31) & ~31) >> 3; // width in bytes
  616.  
  617.             byte[] bimagedata = this.LoadImageBytes(binReader);
  618.  
  619.             this.ImageByteHandle = GCHandle.Alloc(bimagedata, GCHandleType.Pinned);
  620.  
  621.             PixelFormat pf = this.Header.PixelFormat;
  622.  
  623.  
  624.             this.bitmapImage = new Bitmap((int)this.gladiusHeader.Width,
  625.                                             (int)this.gladiusHeader.Height,
  626.                                             this.intStride,
  627.                                             pf,
  628.                                             this.ImageByteHandle.AddrOfPinnedObject());
  629.  
  630.             if (pf == PixelFormat.Format8bppIndexed)
  631.             {
  632.                 int numColourEntries = gladiusHeader.RawColourMap.Length / 4;
  633.                 if (numColourEntries > 0)
  634.                 {
  635.                     ColorPalette pal = this.bitmapImage.Palette;
  636.  
  637.                     byte[] map = gladiusHeader.RawColourMap;
  638.                     map = gladiusHeader.SwizzledColourMap;
  639.                     for (int i = 0; i < numColourEntries; i++)
  640.                     {
  641.                         Color c = Color.FromArgb(255, map[i * 4], map[(i * 4) + 1], map[(i * 4) + 2]);
  642.                         Color c2 = Color.FromArgb(c.A, c.B, c.G, c.R);
  643.                         pal.Entries[i] = c2;
  644.                     }
  645.                     this.bitmapImage.Palette = pal;
  646.                 }
  647.             }
  648.         }
  649.  
  650.         #region IDisposable Members
  651.  
  652.         public void Dispose()
  653.         {
  654.             Dispose(true);
  655.             // Take yourself off the Finalization queue 
  656.             // to prevent finalization code for this object
  657.             // from executing a second time.
  658.             //GC.SuppressFinalize(this);
  659.  
  660.         }
  661.  
  662.  
  663.         protected virtual void Dispose(bool disposing)
  664.         {
  665.             // Check to see if Dispose has already been called.
  666.             // If disposing equals true, dispose all managed 
  667.             // and unmanaged resources.
  668.             if (disposing)
  669.             {
  670.                 // Dispose managed resources.
  671.                 if (this.bitmapImage != null)
  672.                 {
  673.                     this.bitmapImage.Dispose();
  674.                 }
  675.  
  676.                 if (this.ImageByteHandle != null)
  677.                 {
  678.                     if (this.ImageByteHandle.IsAllocated)
  679.                     {
  680.                         this.ImageByteHandle.Free();
  681.                     }
  682.  
  683.                 }
  684.             }
  685.         }
  686.  
  687.  
  688.         #endregion
  689.     }
  690.  
  691.  
  692.  
  693.  
  694. }
  695.