Image MIME Type from the Byte[]

by Tyler Jensen 19. September 2006 03:00
A little puzzle came up today. Fetch an image out of a database and stream it down to the browser. The trick: we don't know what type of image is stored in the database. So I borrowed a little from our Python friends and this is what I ended up with.

A little puzzle came up today. Fetch an image out of a database and stream it down to the browser. The trick: we don't know what type of image is stored in the database. So I borrowed a little from our Python friends and this is what I ended up with.

internal static class ImageTypeFinder
{
    internal static string GetMimeType(byte[] image)
    {
        string retval = "image/jpeg";
        string imgtype = GetImageType(image);
        switch (imgtype)
        {
            case "bmp":
                retval = "image/bmp";
                break;
            case "gif":
                retval = "image/gif";
                break;
            case "tif":
                retval = "image/tiff";
                break;
            case "png":
                retval = "image/png";
                break;
        }
        return retval;
    }

    internal static string GetImageType(byte[] image)
    {
        int len = image.Length;
        if (len > 32) len = 32;
        string first32 = ASCIIEncoding.ASCII.GetString(image, 0, len);
        return GetImageType(first32);
    }

    internal static string GetImageType(string first32)
    {
        string retval = string.Empty;
        if (first32.StartsWith("GIF87a") || first32.StartsWith("GIF89a"))
            retval = "gif";
        else if (first32.StartsWith("MM") || first32.StartsWith("II"))
            retval = "tif";
        else if (first32.Substring(6, 4) == "JFIF" || first32.Substring(6, 4) == "Exif")
            retval = "jpg";
        else if (first32.StartsWith("BM"))
            retval = "bmp";
        else if (first32.Substring(1, 3) == "PNG")
            retval = "png";
        return retval;
    }

}

It's a bit of an esoteric puzzle, but if you're trying to solve this one, the above code should help.

Tags:

Code

Bad Code is Platform Independent

by Tyler Jensen 12. September 2006 17:17

I want a T-shirt with these words on it:

Bad Code is Platform Independent

All the political and religious debates about platform superiority all come to an end when running bad code. It amazes me how much bad code is out there (some of mine included). And yet we so often jump to blame the platform, runtime, operating system, tools, or some other outside element.

Where have all the good coders gone? More to the point. Were there ever any?

Bad coders never die, they just pick a new platform.

Tags:

Commentary

Take a POST for REST without a Form in ASP.NET

by Tyler Jensen 1. September 2006 09:52
Some time ago and again today, I had occasion to write an ASP.NET page that had no form in the .ASPX page but would accept and handle POST 'ed data. This was in an effort to support a REST-like interface for non-ASP.NET developers. Here's the way it turned out.

Some time ago and again today, I had occasion to write an ASP.NET page that had no form in the .ASPX page but would accept and handle POST 'ed data. This was in an effort to support a REST-like interface for non-ASP.NET developers. Here's the way it turned out.

The .ASPX page looks something like this:

<%@ Page Language="C#"
 
AutoEventWireup="true"
  CodeBehind="extract.aspx.cs"
  Inherits="KeyExtractWeb.extract" %>

There is nothing else in the file. Now the code behind looks like this:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace KeyExtractWeb
{
    public partial class extract : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string alldata = string.Empty;
            using (StreamReader sr = new StreamReader(this.Request.InputStream))
            {
                alldata = sr.ReadToEnd();
            }

            //convert to strings - assumes URL encoded data
            string[] pairs = alldata.Split('&');
            NameValueCollection form = new NameValueCollection(pairs.Length);
            foreach (string pair in pairs)
            {
                string[] keyvalue = pair.Split('=');
                if (keyvalue.Length == 2)
                {
                    form.Add(keyvalue[0], HttpUtility.UrlDecode(keyvalue[1]));
                }
            }

            if (alldata.Length > 0 && this.Request.HttpMethod.ToUpper() == "POST")
            {
                if (form["text"] != null)
                {
                    //TODO - do something with the data here
                }
                else
                    Response.Write("*** 501 Invalid data ***");
            }
            else
                Response.Write("*** 599 GET method not supported. ***");

            Response.End();
        }
    }
}

Well, there you have it. There are probably better ways to do this, but I didn't find one.

Tags:

Code

Captain Zilog - Redux

by Tyler Jensen 23. August 2006 04:09

Nothing like a great laugh to perk up your day. Stumbled onto this Captain Zilog on computerhistory.org today. Take a moment and read it. What happened to those good old days? Did the dolldrums of reality take over?

"Systems designer Nick Stacey works late into the night, unknown to him, a small eerie comet passes overhead..."

"I am known to men as...opportunity! I give you the key to man's destiny in a brave new world!"

"It is the beginning of a new freedom for man's imagination! It is a microprocessor! I bestow upon you all of the knowledge that goes with it, but use it wisely! Now, go!"

Corny? Yes. Prescient? Definitely. It was 1979. I was in junior high school. It was the battle of the little, inventive, hungry geek vs. the titans of business with deeper pockets than I could imagine. It was an epoc battle that went to the best and the brightest, not to the most powerful. Or so it seemed. But as a kid, I was only barely aware of the war that raged in the world of technology in those days. To me, it was just an exciting time of change.

Now, change is more terrifying because I have responsibilities. I have four kids, a mortgage and car payments. Just like everybody else I know. And a lot has changed in the last couple of months. And it's been terrifying. And exciting. Two days ago, I blogged about the ethics of meta-searching. It came as a shock to others involved in the project because I had not discussed it with them. I blindsided them. That was fundamentally unfair. And yet, even had I wrung my hands over the issue and discussed it with them, it would probably not have changed the end result. Things changed. And it scared the heck out me. Some of them are probably still angry with me. I don't blame them. I would be too.

Looking back to the days of Captain Zilog made me laugh. It also made me think. Zilog is not a player in the huge PC market. But it's still alive and from all appearances, it's doing well. They innovated. They struggled. They stayed alive and ultimately found a niche market that has served them well. Are they comparable to giants like Intel and Microsoft? No way. But did they survive? Did they make money. I'm guessing that they must have given the fact that they're still around and still selling the Z8 line.

So what is our challenge? We must find a way to survive. Find a way to innovate something truly useful. Believe in that thing. Work hard to make that thing succeed, even if it's in a market you had not originally foreseen. In other words, we must adapt without losing a sense of who we are or what we've created. Time will tell if we, as technologists and entrepreneurs will do just that.

 

Tags:

Commentary

Respecting Terms of Use -- The Ethics of Meta-Searching

by Tyler Jensen 21. August 2006 04:07

(Modified slightly on Monday, August 21, 2006, after considering issues of fairness and further introspection.)

For the first seven months of this year I worked on a project which, in part, was a meta-search tool designed to bypass the router pacing algorithms used by sites such as Google, Yahoo and MSN. I have come to believe that even if this were not a violation of their terms of use, it would be fundamentally unethical. I cannot claim the high road in having come to this conclusion. I did not arrive at this conclusion until some time after becoming unemployed and then re-employed.

Yesterday I began to question myself more seriously about the ethics of meta-searching than I had done before. Without doing any online research, a rarity for me, I just wrote down in long hand some basic questions and let one lead to another. My conclusion was that I could not ethically or morally justify the acquisition of data and resale of it in some form or another using meta-search techniques in violation of the source's terms of use.

On July 21, 2006, I was suddenly unemployed along with the rest of the development team at Provo Labs LLC, a Paul Allen (the lesser) venture. I didn't abandon the project even then. I looked for ways to keep the project alive. After all, I had spent months, including nearly every Saturday and Sunday, working on the code for this project. It was my baby. I was the only developer on it. A week or so after that fateful day in July, reality set in. I had no income and four children to feed. I had to find a job. And I did. A great job! The timing could not have been better.

In my first three days on the new job, I was impressed by the effort and expense the company is willing to expend to be sure that copyrighted material used in their product is properly licensed. This reminded me of a conversation I had had with management at Provo Labs earlier in the year. I had raised the question of the ethics of meta-searching and collecting data using automation from public search engines and other resources whose terms of use statements clearly prohibit such behavior. The discussion was brief and the subject was quickly swept aside. It boiled down to "everybody does it, including the search engines, so that makes it okay". I filed that rationalization away and kept going.

The intellectual property transfer from Provo Labs LLC to the new company Phil Burns is starting had not yet happened. I had even contemplated using my company, NetBrick Inc, an S corp of which I am the sole shareholder, as a holding company for this new venture. But I had become impatient and as Phil put it, "emotional and panicky".

I had my doubts about the whole deal and so today I pulled myself out of the deal entirely in part because I had lost faith that we would successfully negotiate the intellectual property rights to this product, in part because I did not believe I would have time to continue working on the project, but mostly because I had come to believe that it would simply be the wrong thing to do.

This process of introspection has been painful. I had to admit to myself that for the last seven months of my life, I have been building, enthusiastically, a product that was in large measure designed to violate the terms of use and possibly violate the law in the acquisition of meta-data from search engines and other sites for the express purpose of reselling that data in the form of market research and other such reports. I had rationalized this by thinking that we would not sell the data but only the conclusions we reached from the data. Splitting hairs like this was just another way to sweep the ethical inconsistency under the rug.

Today I informed Phil and Paul that I will no longer be involved with the project as it stands and that I will deliver the code in its existing form. I did not share with them my reasoning behind my decision because I really did not want to engage them in a debate on the merits of my decision. We had already been down that road.

After I informed Phil and Paul by email, I did some online research--something I really should have done, and unbelievably did not ever do, prior to starting the project. From any of the big three engines (Google, Yahoo, and MSN), you can click one or two links to get to the following terms of service information.

Google
http://www.google.com/intl/en/terms_of_service.html
"The Google Services are made available for your personal, non-commercial use only. You may not use the Google Services to sell a product or service, or to increase traffic to your Web site for commercial reasons... You may not take the results from a Google search and reformat and display them... You may not "meta-search" Google... You may not send automated queries of any sort to Google's system without express permission in advance from Google. Note that "sending automated queries" includes, among other things: using any software which sends queries to Google to determine how a website or webpage "ranks" on Google for various queries;
"meta-searching" Google; and performing "offline" searches on Google.

MSN
http://tou.live.com/en-us/
"In using the service, you may not:...use any automated process or service to access and/or use the service (such as a BOT, a spider, periodic caching of information stored by Microsoft, or “meta-searching”);"

Yahoo & Overture
http://docs.yahoo.com/info/terms/
"Except as expressly authorized by Yahoo! or advertisers, you agree not to modify, rent, lease, loan, sell, distribute or create derivative works based on the Service or the Software, in whole or in part."

Clearly, these search engines do not want you to use automated search software to mine their meta-data presented in search results and the results of other search related queries. It is clear that their intent is to only allow individual users through a normal web browser to access and use this information. Yahoo is more vague than the other two but the intent is still there.

So is the search engine behavior of crawling the content and indexing the content of other web sites unethical or immoral? Does that violate the terms of use posted by many other sites? Will the search engines remove your content from their site if you request it? I do not believe that it is unethical or immoral to drive traffic to a web site because its content contains what a search engine user probably wants to find. The search engine is not repackaging and reselling the data they find on the crawled sites. Yet they do profit in some measure from mining that content, for without the content, they would have no users. It seems to be a trade that most web site owners are willing to make.

I want to make it clear here and now that I believe that if I had made my concerns known to Provo Labs management more forcefully in the early days of this project, they would not have required me to work on it. They would have, I think, found something else for me to do. I hope this illustrates the flaw in my own character, which I hope to remedy in this, and does not leave the reader of this post to believe that Provo Labs LLC acted in an unethical manner.

The code is powerful and capable of being extended and used in a variety of ways. A friend of mine pointed out to me that not everything it does is a violation of terms of use document. In fact there is a lot of things that it is designed to do which goes no further than a typical web crawler in terms of gathering data. Perhaps a means can be found to make use of what it can do without violating terms of use policies. Perhaps the power of the code can be leveraged within the framework of licensed APIs. This is something that will have be determined.

Until that time, I'll continue my work at my new job and focus my personal coding efforts on my Forseti Project to keep my coding skills as sharp as I can. And I will take away an important lesson from this whole roller coaster ride: always examine and question the ethics of a project and then listen to your instincts.

If you'd like to comment and berate me here, go right ahead. I deserve it. If you're particularly vicious, I reserve the right to edit or remove the comment. If you've had similar experiences and stood up more valiantly, I'd like to hear about it and how it all turned out for you.

Tags:

Commentary

Me...

Tyler Jensen

Tyler Jensen
.NET Developer and Architect

Month List

Other Stuff