In my need to decode a JPEG 2000 file, I discovered like many that
there was no functionality for this in the .NET Framework. Instead of
forking out a pile of cash to do this, I came up with the idea that
costs nothing and it is inheritently built into the Framework. So here
is the solution...
When you use the WebRequest and WebResponse classes to obtain graphics
from a web site, these classes have built-in decoding for JPEG 2000
files. Now before we go any further, this article is not about
downloading and decoding files over the Internet. It is about decoding
JPEG 2000 files locally or using any of the internal decoding
mechanisms that are part of WebResponse and probably Internet Explorer
for that matter. Too bad Microsoft didn't expose the underlying APIs
for decoding. But being the code thieves that we all are, we look for
other ways to get in.
The concept is very simple. It consists of the following steps:
1. Set up a mini web server in your code using TcpListener.
2. Create a HTTP request to the server.
3. Use WebRequest and WebResponse to call your web server.
4. Return the encoded JPEG file from the web server.
5. Your done.
Now for a few specifics. When you setup a mini web server, you use the
address 127.0.0.1 and any free port.
You then use WebRequest to call http://127.0.0.1:54321 (or whatever
port you are using).
In your web server, you simply return a response with a 200 code with
a few headers followed by the actual encoded JPEG.
Your web server must remain running until the GetResponseStream that
you use to retrieve the data has completed. If the web server
terminates, you will fail to read all of the data. Only after you have
retrieved the data should you shutdown the web server.
Here is some coding example. Note: this code was partially copied and
pasted from my own code, so it may not work. Use it only to give you
an idea what needs to be done. Take care that the newsgroup wraps the
text, so you need to unwrap it:
using System;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Collections;
private bool webServerStarted = false;
private string encodedJPEGFile;
private bool finishedRetrieving = false
..
..
..
// Read in your encoded JPEG 2000 file or get it from somewhere else
such as a stream.
// You must use the 1252 encoding to make sure that the binary data is
read correctly as string data.
StreamReader stream = new StreamReader(@"C:\temp\EncodedFile.jpg",
Encoding.GetEncoding(1252));
string picture = stream.ReadToEnd();
stream.Close();
// Setup a thread for your web server
StringBuilder data = new StringBuilder();
this.webServerStarted = false;
Thread webServerThread = new Thread(new ThreadStart(WebServer));
webServerThread.Start();
// Wait until the thread has started.
while(!this.webServerStarted)
{
Application.DoEvents();
}
// Request the file.
WebRequest WReq = WebRequest.Create("http://127.0.0.1:54321");
// The GetResponse takes care of all conversions
WebResponse WResp = WReq.GetResponse();
Stream responseStream = WResp.GetResponseStream();
while(true)
{
int bytesRead = responseStream.Read(buffer, 0, buffer.Length);
if (bytesRead == 0)
break;
string packet = Encoding.GetEncoding(1252).GetString(buffer, 0,
bytesRead);
data.Append(packet);
}
// Tell your web server that you are done.
this.finishedRetrieving = true;
// Here is your decoded picture - Smile!
pictureData = data.ToString();
public void WebServer()
{
try
{
int bytesSent;
// Create the http response. Note the double CrLf prior to
appending your jpeg data.
string http =
"HTTP/1.1 200 OK\r\n" +
"Content-Type: image/jpeg\r\n" +
"Connection: Keep-Alive\r\n\r\n" +
this.encodedJPEGFile;
// 16777343 is the equivalent of the address 127.0.0.1. Note,
localhost does not always work, so use 127.0.0.1
IPAddress localAddress = new IPAddress(16777343);
TcpListener listener = new TcpListener(localAddress, 59501);
listener.Start();
// Tell the calling client that the server is now running.
this.webServerStarted = true;
Socket socket = listener.AcceptSocket();
if (socket.Connected)
{
// Write the response to the browser.
byte[] bufferOut = Encoding.GetEncoding(1252).GetBytes(http);
int bytesSent = socket.Send(bufferOut, bufferOut.Length, 0);
// Wait until the caller has received the data.
while(!this.finishedRetrieving)
{
Application.DoEvents();
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
catch(Exception ex)
{
string message = ex.Message;
}
}
Hope it Helps!
Johann Blake