ATTENTION ALL FANS!!! THIS BLOG HAS MOVED!!!
go to: http://www.taotekaching.com

Showing posts with label code. Show all posts
Showing posts with label code. Show all posts

Thursday, January 08, 2009

Device Independent Bitmaps, C#, and Me…REDUX!


Well, after using the previously posted code in some projects at work, some limitations arose quickly. The two biggest were support for 8-bit bitmaps, and support for both 5-5-5 and 5-6-5 16-bit bitmaps.

The new code looks like the following:

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Imaging;

using System.Runtime.InteropServices;

using System.IO;

namespace DIBitmaps

{

static public class DIB

{

// our BITMAPINFOHEADER struct, as per gdi

// use LayoutKind to make sure data is marshalled as we've laid it out

[StructLayout(LayoutKind.Sequential)]

public struct BITMAPINFOHEADER

{

public uint biSize;

public int biWidth;

public int biHeight;

public ushort biPlanes;

public ushort biBitCount;

public uint biCompression;

public uint biSizeImage;

public int biXPelsPerMeter;

public int biYPelsPerMeter;

public uint biClrUsed;

public uint biClrImportant;

//public void Init()

//{

// biSize = (uint)Marshal.SizeOf(this);

//}

}

public static Bitmap BitmapFromDIB(MemoryStream dib)

{

// get byte array of device independent bitmap

byte[] dibBytes = dib.ToArray();

// get the handle for the byte array and "pin" that memory (i.e. prevent

// garbage collector from gobbling it up right away)...

GCHandle hdl = GCHandle.Alloc(dibBytes, GCHandleType.Pinned);

// marshal our data into a BITMAPINFOHEADER struct per Win32

// definition of BITMAPINFOHEADER

BITMAPINFOHEADER dibHdr = (BITMAPINFOHEADER)Marshal.PtrToStructure

(hdl.AddrOfPinnedObject(), typeof(BITMAPINFOHEADER));

bool is555 = true;

Bitmap bmp = null;

if (dibHdr.biBitCount == 8)

{

// set our pointer to end of BITMAPINFOHEADER

Int64 jumpTo = hdl.AddrOfPinnedObject().ToInt64() + dibHdr.biSize;

bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, PixelFormat.Format8bppIndexed);

bmp.SetResolution((100f * (float)dibHdr.biXPelsPerMeter) / 2.54f,

(100f * (float)dibHdr.biYPelsPerMeter) / 2.54f);

// set the colors in our palette

ColorPalette palette = bmp.Palette;

IntPtr ptr = IntPtr.Zero;

int colors = (int)(dibBytes.Length - (bmp.Width * bmp.Height) - dibHdr.biSize);

for (int i = 0; i < 256; i++)

{

ptr = new IntPtr(jumpTo);

uint bmiColor = (uint)Marshal.ReadInt32(ptr);

int r = (int)((bmiColor & 0xFF0000) >> 16),

g = (int)((bmiColor & 0xFF00) >> 8),

b = (int)((bmiColor & 0xFF));

palette.Entries[i] = Color.FromArgb(r, g, b);

jumpTo += 4;

}

bmp.Palette = palette;

// now write the remaining bmp data to our bitmap

BitmapData _8bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),

ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);

jumpTo -= hdl.AddrOfPinnedObject().ToInt64();

Marshal.Copy(dibBytes, (int)jumpTo, _8bd.Scan0, _8bd.Stride * _8bd.Height);

bmp.UnlockBits(_8bd);

}

else if ((dibHdr.biBitCount == 16) && (dibHdr.biCompression == 3))

{

Int64 jumpTo = (Int64)(dibHdr.biClrUsed * (uint)4 + dibHdr.biSize);

IntPtr ptr = new IntPtr(hdl.AddrOfPinnedObject().ToInt64() + jumpTo);

ushort redMask = (ushort)Marshal.ReadInt16(ptr);

ptr = new IntPtr(ptr.ToInt64() + (2 * Marshal.SizeOf(typeof(UInt16))));

ushort greenMask = (ushort)Marshal.ReadInt16(ptr);

ptr = new IntPtr(ptr.ToInt64() + (2 * Marshal.SizeOf(typeof(UInt16))));

ushort blueMask = (ushort)Marshal.ReadInt16(ptr);

is555 = ((redMask == 0x7C00) && (greenMask == 0x03E0) && (blueMask == 0x001F));

}

// go ahead and release the "pin" from our handle on that memory

hdl.Free();

// If the target device does not have one plane, or we're working with a bitmap other

// than a non-compressed (BI_RGB) bitmap, we're not gonna work woith it

if (dibHdr.biPlanes != 1 || (dibHdr.biCompression != 0 && dibHdr.biCompression != 3))

return null;

if (bmp == null)

{

// we need to know beforehand the pixel-depth of our bitmap

PixelFormat fmt = PixelFormat.Format24bppRgb;

switch (dibHdr.biBitCount)

{

case 32:

fmt = PixelFormat.Format32bppRgb;

break;

case 24:

fmt = PixelFormat.Format24bppRgb;

break;

case 16:

fmt = (is555) ? PixelFormat.Format16bppRgb555 :

PixelFormat.Format16bppRgb565;

break;

default:

return null;

}

// prepare for our output bitmap

bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, fmt);

// load our "empty" bitmap into memory and lock it for

// writing in the format we specified

BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height),

ImageLockMode.WriteOnly, fmt);

// marshal our device independent bitmap data over to our output bitmap

Marshal.Copy(dibBytes, Marshal.SizeOf(dibHdr), bd.Scan0, bd.Stride * bd.Height);

// we're done marshalling, so release our bitmapdata lock

bmp.UnlockBits(bd);

}

if (dibHdr.biHeight > 0)

{

// DIB data is upside-down for some reason, so flip it

bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);

}

// return our bitmap

return bmp;

}

}

}

The adjusted code can be downloaded here.

If you find any other issues, please let me know and I’ll get it updated ASAP.

~ZagNUT

Submit this story to DotNetKicks

Conway’s Game of Life, Pong, Screensavers, and Me…

Greetings, all:

Due to the massive increase in my blog traffic (I think I het around 20 / week or so) after I initially offered up my Game of Life screensaver, I now offer, in celebration of the new year, GoLPong!

GoLPong

That’s right, for 2009 you now can have a fancy new Game of Life screensaver.  BUT THIS ONE’S PACKED WITH NEW FEATURES!  Well, what are they?

  • Game of Life does both trails and no trails
  • Flickers between trails and non-trails
  • Pong played live by your computer against itself
  • Alternates randomly between these two!

Oh my god, you say, but how much does it cost?

Free.  Because I love you.

It is a beautifully dumb screensaver.  You can get it here.  The source code (uncommented, of course) is here.

Tell me how you like it.  Also, send me comments for the 2010 version you’d like to see.

~ZagNut

Submit this story to DotNetKicks

Thursday, December 04, 2008

Native MDI Containers, Managed Child Forms, and Me...

So, at work we have this (ugly) native C++ MFC application that the Powers-That-Be insist needs a complex web-services riddled interface to our social-networking-meets-file-sharing new website.  Initially, said interface was to be in MFC native code action.  I said, "sheeeeeeeeeiiiiiiiiiiiiiiiittt".  But then the light came: why not do the interface in a .NET form and pass the form handle somehow to the native application to pull it into its window as a child window.  Any interaction between the two can be handled easily through messaging calls.  I immediately began to Google on it.  I found nothing that directly addressed this problem.  I concluded it was one of two things: either it was so easy, no one bothered documenting it, or so rarely done, no one bothered documenting it.  Either way, no one bothered documenting it...UNTIL NOW!!!

Basically my solution was to grab the parent window's class using a call to GetClassName, then send this as a command line parameter to the .NET exe via a ShellExecute call.  Once in the .NET client, I use two DllImport-ed calls: FindWindow and SetParent -- FindWindow to get the window handle from the class name I passed in as a parameter, and SetParent to, well, set the parent of my form.

The sample code is here.  Note, you'll need to change the hardcoded path in the NativeMaster C++ solution to the output of the ManagedChild project.  Hope it's helpful...

~ZagNut

Submit this story to DotNetKicks

Monday, November 24, 2008

DIB, C#, and Me...

Ok, after pulling out my hair trying to generate thumbnails from device-independent bitmaps stored by a CArchive in an "old" MFC program, I finally got help here at the workplace on this.

I must say I could not find this easily with much Googling, ergo I'm gonna post this up here with comments for anyone else out there looking for the same thing.

Please suggest any updations to comments and / or code, if you see the need...

NOTE: This code has been updated. Look here for it.

// our BITMAPINFOHEADER struct, as per gdi
// use LayoutKind to make sure data is marshalled as we've laid it out
[StructLayout(LayoutKind.Sequential)]
public struct BITMAPINFOHEADER
{
public uint biSize;
public int biWidth;
public int biHeight;
public ushort biPlanes;
public ushort biBitCount;
public uint biCompression;
public uint biSizeImage;
public int biXPelsPerMeter;
public int biYPelsPerMeter;
public uint biClrUsed;
public uint biClrImportant;
public void Init()
{
biSize = (uint)Marshal.SizeOf(this);
}
}

public static Bitmap BitmapFromDIB(MemoryStream dib)
{
// get byte array of device independent bitmap
byte[] dibBytes = dib.ToArray();

// get the handle for the byte array and "pin" that memory (i.e. prevent garbage collector from
// gobbling it up right away)...
GCHandle hdl = GCHandle.Alloc(dibBytes, GCHandleType.Pinned);

// marshal our data into a BITMAPINFOHEADER struct per Win32 definition of BITMAPINFOHEADER
BITMAPINFOHEADER dibHdr = (BITMAPINFOHEADER)Marshal.PtrToStructure(hdl.AddrOfPinnedObject(), typeof(BITMAPINFOHEADER));

// go ahead and release the "pin" from our handle on that memory
hdl.Free();

// If the target device does not have one plane, or we're working with a bitmap other than a
// non-compressed (BI_RGB) bitmap, we're not gonna work woith it
if (dibHdr.biPlanes != 1 || dibHdr.biCompression != 0)
return null;

// we need to know beforehand the pixel-depth of our bitmap
PixelFormat fmt = PixelFormat.Format24bppRgb;
switch (dibHdr.biBitCount)
{
case 32:
fmt = PixelFormat.Format32bppRgb;
break;
case 24:
fmt = PixelFormat.Format24bppRgb;
break;
case 16:
fmt = PixelFormat.Format16bppRgb555;
break;
default:
return null;
}

// prepare for our output bitmap
Bitmap bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, fmt);

// load our "empty" bitmap into memory and lock it for writing in the format we specified
BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, fmt);

// marshal our device independent bitmap data over to our output bitmap
Marshal.Copy(dibBytes, Marshal.SizeOf(dibHdr), bd.Scan0, bd.Stride * bd.Height);

// we're done marshalling, so release our bitmapdata lock
bmp.UnlockBits(bd);

// DIB data is upside-down for some reason, so flip it
bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);

// return our bitmap
return bmp;
}


~simon

Submit this story to DotNetKicks

Saturday, October 04, 2008

Java, Dice, Programming Languages and Me...

So, I decided to write another Applet, this time one that gives the "popularity" of a programming language based on the number of instances found from a generic Dice.com search.

The source code is here.

Submit this story to DotNetKicks

Thursday, September 04, 2008

Flash RGB, C#, and Me...

Greetings,

So a co-worker of mine had to translate Flash RGB data into a Bitmap. He noted that finding that out was difficult, ergo, for your coding pleasure, here's a tasty little static function you can use just for that:




static Bitmap BmpOut(string rgb, int width, int height)
{
Bitmap bmp = null;
try
{
int bytes = (rgb.Length / (width * height));
bool IsArgb = (bytes == 8);
double dWidth = (double)width;
bmp = new Bitmap(width, height);
int counter = -1;
for (int i = 0; i < rgb.Length; i += bytes)
bmp.SetPixel(++counter % width, (int)Math.Floor((double)counter / dWidth),
Color.FromArgb(int.Parse(((!IsArgb) ? "FF" + rgb.Substring(i, 6) : rgb.Substring(i, 8)), System.Globalization.NumberStyles.HexNumber)));
}
catch { bmp = null; }
return bmp;
}


enjoy...

Submit this story to DotNetKicks

Tuesday, July 22, 2008

A Programming Job Interview Challenge #13 - Brackets, and Me...

Ok, I've been doing the programming quizzes here and have a solution...

In Perl:


$FILE = "expressions.txt";
open(FILE) or die("Could not open expressions file.");
foreach $OLINE (<FILE>)
{
$LINE = $OLINE;
if ($LINE =~ m/(^[\]}\)>])|([\[{\(<]$)/)
{ print "bad : $OLINE" }
else
{
while ($LINE =~ m/(\[\])|({})|(\(\))|(<>)/)
{ $LINE =~ s/(\[\])|({})|(\(\))|(<>)//g }
$strLen = length($LINE);
if ($strLen > 1)
{ print "bad : $OLINE" }
else
{ print "good : $OLINE" }
}
}

And a C# console app to generate the "sample" strings (i.e. the "expressions.txt" file used above):




using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Creator();
//Console.ReadKey();
}
static void Creator()
{
Random r = new Random((DateTime.Now.DayOfYear + DateTime.Now.Millisecond) * (DateTime.Now.Second + DateTime.Now.Minute + 1));
string encs = "[{(<>)}]";

string sb = "";
for (int i = 0; i < 100; i++)
{
sb = "";
bool good = (r.Next(0, 100) > 50) ? true : false;
int strlen = r.Next(1, 21) * 2;
for (int j = 0; j < strlen; j++)
{
if (!good)
sb = String.Format("{0}{1}", sb, encs[r.Next(0, encs.Length)]);
else
{
int p = r.Next(0, encs.Length / 2);
int q = r.Next(0, 3);
if (q == 0)
sb = String.Format("{0}{1}{2}", encs[p], sb, encs[encs.Length - p - 1]);
else if (q == 1)
sb = String.Format("{0}{1}{2}", sb, encs[p], encs[encs.Length - p - 1]);
else
sb = String.Format("{0}{1}{2}", encs[p], encs[encs.Length - p - 1], sb);
}
}
//Console.WriteLine(String.Format("{0}: {1}", good, sb.ToString()));
Console.WriteLine(sb);
}
}
}
}

I couldn't spend that much time on this, as I am at work. Ergo, I'm a little disappointed with the Perl, although it was my first Perl program ever!


I'm particularly curious about how I could have done some sort of recursive check. Please give any suggestions to the Perl script that would make it as close to a one-liner regex check.


~simon

Submit this story to DotNetKicks

Wednesday, July 09, 2008

Conway's Game of Life, Java, Smoking, and Me...

Ok, I've done it again. Another Conway's Game of Life, this time in Java:

The source code can be had here. It's called Gola (Game Of Life Applet).

So, I've quit smoking. I started July 6 at 11:27pm (my last cigarette). It is going much better this time.  This is my third time.  The first two times I quit for 2+ years each time.  I know this time is my final one.  Why?  I had a "moment" where I just didn't want them anymore.

That feeling stayed, even after I failed, so I set a quit date, got the patch, got lots of pretzel sticks, and made sure I didn't sit around and drink coffee in the morning.  This is the third day, and I had to stay home today.  I felt like I had the flu and slept until 1:00pm.  I've been a vegetable and sleeping on and off since.  It's 5:33pm now, and I'm finally getting a little energy back.  I wrote a little C# program for watching the "progress" of quitting.  I was going to include the health benefits stages as stages that would appear below the timer, but I slacked.  Here's the code and benefits list.

Submit this story to DotNetKicks

Thursday, May 29, 2008

Conway's Game of Life REDUX!, Screensavers, and Me...

NOTE as of 06.23.08
The source is now available through this page


I've become obsessed with this stupid Game of Life shite. All my other projects are on hold until I get this out of my system.

So far, I've gotten out a simple, plug-in based .NET version: Yagol.NET.

Now, for your pleasure, it's: The Yagol++ Screensaver!

yagol.screensaver

I added "traces" of where a cell used to be live up to five generations earlier.

The saver can be downloaded here. Now, here's the catch: if you want a link to the source, I'll post it as a comment reply after I've received some comments from you all requesting it. I NEED ATTENTION!

Thanx!

~simon

Submit this story to DotNetKicks

Tuesday, May 20, 2008

Multimedia-based Code Commenting, and Me...

Ok, a former colleague of mine decided to create an extension to Visual Studio to allow audio commenting of code.

Go here to check it out.

Submit this story to DotNetKicks