dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetlib/DotGNU.Images IconReader.cs, NONE, 1


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetlib/DotGNU.Images IconReader.cs, NONE, 1.1 IconWriter.cs, NONE, 1.1 BmpWriter.cs, 1.1, 1.2 Frame.cs, 1.1, 1.2 Image.cs, 1.2, 1.3
Date: Wed, 09 Jul 2003 21:09:04 -0400

Update of /cvsroot/dotgnu-pnet/pnetlib/DotGNU.Images
In directory subversions:/tmp/cvs-serv24385/DotGNU.Images

Modified Files:
        BmpWriter.cs Frame.cs Image.cs 
Added Files:
        IconReader.cs IconWriter.cs 
Log Message:


Add Windows icon and cursor support to the "DotGNU.Images" library.


--- NEW FILE ---
/*
 * IconReader.cs - Implementation of the "DotGNU.Images.IconReader" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software, you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program, if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace DotGNU.Images
{

using System;
using System.IO;

internal sealed class IconReader
{
        // Load a Windows icon image from the specified stream.  The first
        // 4 bytes have already been read and discarded.  If "hotspots" is
        // "true", then the image is actually a Windows cursor with hotspots.
        public static void Load(Stream stream, Image image, bool hotspots)
                        {
                                byte[] buffer = new byte [1024];
                                int offset = 4;
                                int numImages, index;
                                int[] offsetList;
                                int width, height, colors;
                                PixelFormat format;
                                Frame frame;
                                int[] palette;
                                int paletteCount;
                                int paletteIndex;

                                // Read the number of images in the file.
                                if(stream.Read(buffer, 0, 2) != 2)
                                {
                                        throw new FormatException();
                                }
                                numImages = Utils.ReadUInt16(buffer, 0);
                                offset += 2;

                                // Read the resource directory.
                                offsetList = new int [numImages];
                                for(index = 0; index < numImages; ++index)
                                {
                                        if(stream.Read(buffer, 0, 16) != 16)
                                        {
                                                throw new FormatException();
                                        }
                                        offset += 16;
                                        width = buffer[0];
                                        height = buffer[1];
                                        colors = buffer[2];
                                        if(colors == 0)
                                        {
                                                colors = 256;
                                                format = 
PixelFormat.Format8bppIndexed;
                                        }
                                        else if(colors == 2)
                                        {
                                                format = 
PixelFormat.Format1bppIndexed;
                                        }
                                        else if(colors == 16)
                                        {
                                                format = 
PixelFormat.Format4bppIndexed;
                                        }
                                        else
                                        {
                                                throw new FormatException();
                                        }
                                        frame = image.AddFrame(width, height, 
format);
                                        if(hotspots)
                                        {
                                                frame.HotspotX = 
Utils.ReadUInt16(buffer, 4);
                                                frame.HotspotY = 
Utils.ReadUInt16(buffer, 6);
                                        }
                                        offsetList[index] = 
Utils.ReadInt32(buffer, 12);
                                }

                                // Read the contents of the images in the 
stream.
                                for(index = 0; index < numImages; ++index)
                                {
                                        // Seek to the start of the image.
                                        Utils.Seek(stream, offset, 
offsetList[index]);
                                        offset = offsetList[index];

                                        // Get the frame that this image 
corresponds to.
                                        frame = image.GetFrame(index);

                                        // Skip the DIB header, which we don't 
need.
                                        // Monochrome cursors don't have a DIB 
header.
                                        if(!hotspots ||
                                           frame.PixelFormat != 
PixelFormat.Format1bppIndexed)
                                        {
                                                if(stream.Read(buffer, 0, 40) 
!= 40)
                                                {
                                                        throw new 
FormatException();
                                                }
                                                offset += 40;
                                        }

                                        // Read the palette information if 
necessary.
                                        // Monochrome cursors don't have a 
palette.
                                        if(!hotspots ||
                                           frame.PixelFormat != 
PixelFormat.Format1bppIndexed)
                                        {
                                                paletteCount =
                                                        (1 << 
Utils.FormatToBitCount(frame.PixelFormat));
                                                if(stream.Read(buffer, 0, 
paletteCount * 4)
                                                                != paletteCount 
* 4)
                                                {
                                                        throw new 
FormatException();
                                                }
                                                offset += paletteCount * 4;
                                                palette = new int 
[paletteCount];
                                                for(paletteIndex = 0; 
paletteIndex < paletteCount;
                                                        ++paletteIndex)
                                                {
                                                        palette[paletteIndex] = 
Utils.ReadBGR
                                                                (buffer, 
paletteIndex * 4);
                                                }
                                        }
                                        else
                                        {
                                                palette = new int[] {0, 
0x00FFFFFF};
                                        }
                                        frame.Palette = palette;

                                        // Read the main part of the icon or 
cursor.
                                        BmpReader.LoadBitmapData(stream, frame, 
false);
                                        offset += frame.Height * frame.Stride;

                                        // Read the mask.
                                        BmpReader.LoadBitmapData(stream, frame, 
true);
                                        offset += frame.Height * 
frame.MaskStride;

                                        // Invert the mask, because we want 1 
to mean "active".
                                        InvertMask(frame);
                                }
                        }

        // Invert the mask in a frame.
        private static void InvertMask(Frame frame)
                        {
                                byte[] mask = frame.Mask;
                                int posn;
                                for(posn = 0; posn < mask.Length; ++posn)
                                {
                                        mask[posn] = (byte)(mask[posn] ^ 0xFF);
                                }
                        }

}; // class IconReader

}; // namespace DotGNU.Images

--- NEW FILE ---
/*
 * IconWriter.cs - Implementation of the "DotGNU.Images.IconWriter" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software, you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY, without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program, if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace DotGNU.Images
{

using System;
using System.IO;

internal sealed class IconWriter
{
        // Save a Windows icon image to the specified stream.  If "hotspots"
        // is "true", then the image is actually a Windows cursor with hotspots.
        public static void Save(Stream stream, Image image, bool hotspots)
                        {
                                byte[] buffer = new byte [1024];
                                int numImages = image.NumFrames;
                                int offset, index, size, bitCount;
                                int[] offsetList;
                                int[] sizeList;
                                Frame frame;

                                // Write the image header.
                                buffer[0] = 0;
                                buffer[1] = 0;
                                buffer[2] = (byte)(hotspots ? 2 : 1);
                                buffer[3] = 0;
                                Utils.WriteUInt16(buffer, 4, numImages);
                                stream.Write(buffer, 0, 6);

                                // Infer the starting offsets and sizes for 
each of the images.
                                offset = 6 + numImages * 16;
                                offsetList = new int [numImages];
                                sizeList = new int [numImages];
                                for(index = 0; index < numImages; ++index)
                                {
                                        frame = image.GetFrame(index);
                                        size = 0;
                                        if(!hotspots ||
                                           frame.PixelFormat != 
PixelFormat.Format1bppIndexed)
                                        {
                                                size += 40;
                                                size +=
                                                  4 * (1 << 
Utils.FormatToBitCount(frame.PixelFormat));
                                        }
                                        size += frame.Height * (frame.Stride + 
frame.MaskStride);
                                        offsetList[index] = offset;
                                        sizeList[index] = size;
                                        offset += size;
                                }

                                // Write the contents of the resource directory.
                                for(index = 0; index < image.NumFrames; ++index)
                                {
                                        frame = image.GetFrame(index);
                                        bitCount = 
Utils.FormatToBitCount(frame.PixelFormat);
                                        buffer[0] = (byte)(frame.Width);
                                        buffer[1] = (byte)(frame.Height);
                                        buffer[2] = (byte)(1 << bitCount);
                                        buffer[3] = 0;
                                        if(hotspots)
                                        {
                                                Utils.WriteUInt16(buffer, 4, 
frame.HotspotX);
                                                Utils.WriteUInt16(buffer, 6, 
frame.HotspotY);
                                        }
                                        else
                                        {
                                                Utils.WriteUInt16(buffer, 4, 0);
                                                Utils.WriteUInt16(buffer, 6, 0);
                                        }
                                        Utils.WriteInt32(buffer, 8, 
sizeList[index]);
                                        Utils.WriteInt32(buffer, 12, 
offsetList[index]);
                                        stream.Write(buffer, 0, 16);
                                }

                                // Write each of the images.
                                for(index = 0; index < image.NumFrames; ++index)
                                {
                                        frame = image.GetFrame(index);
                                        bitCount = 
Utils.FormatToBitCount(frame.PixelFormat);
                                        if(!hotspots || bitCount != 1)
                                        {
                                                BmpWriter.SaveBitmapInfo
                                                        (stream, frame, 
bitCount,
                                                         frame.Stride * 
frame.Height, buffer);
                                        }
                                        BmpWriter.SaveBitmapData(stream, frame, 
false, false);
                                        BmpWriter.SaveBitmapData(stream, frame, 
true, true);
                                }
                        }

}; // class IconWriter

}; // namespace DotGNU.Images

Index: BmpWriter.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/DotGNU.Images/BmpWriter.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** BmpWriter.cs        7 Jul 2003 01:37:41 -0000       1.1
--- BmpWriter.cs        10 Jul 2003 01:09:02 -0000      1.2
***************
*** 66,70 ****
  
                                // Write the bitmap data in the frame to the 
stream.
!                               SaveBitmapData(stream, frame, false);
                        }
  
--- 66,70 ----
  
                                // Write the bitmap data in the frame to the 
stream.
!                               SaveBitmapData(stream, frame, false, false);
                        }
  
***************
*** 111,119 ****
  
        // Save the bitmap data in a frame.
!       public static void SaveBitmapData(Stream stream, Frame frame, bool mask)
                        {
                                byte[] data;
                                int stride;
!                               int line;
  
                                // Get the buffer and stride for the frame.
--- 111,120 ----
  
        // Save the bitmap data in a frame.
!       public static void SaveBitmapData(Stream stream, Frame frame,
!                                                                         bool 
mask, bool inverted)
                        {
                                byte[] data;
                                int stride;
!                               int line, column;
  
                                // Get the buffer and stride for the frame.
***************
*** 131,137 ****
  
                                // BMP images are stored upside down in the 
stream.
!                               for(line = frame.Height - 1; line >= 0; --line)
                                {
!                                       stream.Write(data, line * stride, 
stride);
                                }
                        }
--- 132,152 ----
  
                                // BMP images are stored upside down in the 
stream.
!                               if(!inverted)
                                {
!                                       for(line = frame.Height - 1; line >= 0; 
--line)
!                                       {
!                                               stream.Write(data, line * 
stride, stride);
!                                       }
!                               }
!                               else
!                               {
!                                       for(line = frame.Height - 1; line >= 0; 
--line)
!                                       {
!                                               for(column = 0; column < 
stride; ++column)
!                                               {
!                                                       stream.WriteByte
!                                                               
((byte)(data[line * stride + column] ^ 0xFF));
!                                               }
!                                       }
                                }
                        }

Index: Frame.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/DotGNU.Images/Frame.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** Frame.cs    7 Jul 2003 01:37:41 -0000       1.1
--- Frame.cs    10 Jul 2003 01:09:02 -0000      1.2
***************
*** 36,39 ****
--- 36,41 ----
        private int[] palette;
        private int transparentPixel;
+       private int hotspotX;
+       private int hotspotY;
        private byte[] data;
        private byte[] mask;
***************
*** 50,53 ****
--- 52,57 ----
                                this.palette = null;
                                this.transparentPixel = -1;
+                               this.hotspotX = 0;
+                               this.hotspotY = 0;
                                this.data = new byte [width * stride];
                                this.mask = null;
***************
*** 76,79 ****
--- 80,85 ----
                                }
                                transparentPixel = frame.transparentPixel;
+                               hotspotX = frame.hotspotX;
+                               hotspotY = frame.hotspotY;
                                if(frame.data != null)
                                {
***************
*** 165,168 ****
--- 171,196 ----
                                {
                                        transparentPixel = value;
+                               }
+                       }
+       public int HotspotX
+                       {
+                               get
+                               {
+                                       return hotspotX;
+                               }
+                               set
+                               {
+                                       hotspotX = value;
+                               }
+                       }
+       public int HotspotY
+                       {
+                               get
+                               {
+                                       return hotspotY;
+                               }
+                               set
+                               {
+                                       hotspotY = value;
                                }
                        }

Index: Image.cs
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnetlib/DotGNU.Images/Image.cs,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Image.cs    7 Jul 2003 01:46:17 -0000       1.2
--- Image.cs    10 Jul 2003 01:09:02 -0000      1.3
***************
*** 44,47 ****
--- 44,48 ----
        public static readonly String Bmp = "bmp";
        public static readonly String Icon = "icon";
+       public static readonly String Cursor = "cursor";
  
        // Constructors.
***************
*** 250,254 ****
                        {
                                // TODO: other formats
!                               return (format == Bmp);
                        }
  
--- 251,256 ----
                        {
                                // TODO: other formats
!                               return (format == Bmp || format == Icon ||
!                                       format == Cursor);
                        }
  
***************
*** 257,261 ****
                        {
                                // TODO: other formats
!                               return (format == Bmp);
                        }
  
--- 259,264 ----
                        {
                                // TODO: other formats
!                               return (format == Bmp || format == Icon ||
!                                       format == Cursor);
                        }
  
***************
*** 283,286 ****
--- 286,290 ----
                                if(magic[0] == (byte)'B' && magic[1] == 
(byte)'M')
                                {
+                                       // Windows bitmap image.
                                        BmpReader.Load(stream, this);
                                }
***************
*** 288,292 ****
                                                magic[2] == 1 && magic[3] == 0)
                                {
!                                       // TODO: this is an icon file
                                }
                                // TODO: other formats
--- 292,303 ----
                                                magic[2] == 1 && magic[3] == 0)
                                {
!                                       // Windows icon image.
!                                       IconReader.Load(stream, this, false);
!                               }
!                               else if(magic[0] == 0 && magic[1] == 0 &&
!                                               magic[2] == 2 && magic[3] == 0)
!                               {
!                                       // Windows cursor image (same as icon, 
with hotspots).
!                                       IconReader.Load(stream, this, true);
                                }
                                // TODO: other formats
***************
*** 337,341 ****
--- 348,363 ----
                                if(format == Bmp)
                                {
+                                       // Windows bitmap image.
                                        BmpWriter.Save(stream, this);
+                               }
+                               else if(format == Icon)
+                               {
+                                       // Windows icon image.
+                                       IconWriter.Save(stream, this, false);
+                               }
+                               else if(format == Cursor)
+                               {
+                                       // Windows cursor image (same as icon, 
with hotspots).
+                                       IconWriter.Save(stream, this, true);
                                }
                                // TODO: other image formats





reply via email to

[Prev in Thread] Current Thread [Next in Thread]