Monday, July 23, 2007

DOES A PICTURE SAY A THOUSAND WORDS 2?

Faced with the task of decoding that picture of a young african girl, I said to myself, small fry. It'll be handled in a breeze. After I finished writing the first blog of this series, I went outside to the fresh air, drank some water and popped some gums into my mouth. How long should this take me? An hour, two, or three at most. Trust me, this is work just for a Gothamite.

First course of action : I'd grab the image files through a Bufferedinputstream, decode the files using the default charset decoder and maybe a decoder also of the utf-8 charset and then write the decoded data out through a BufferedWriter. That should do it. I'd get a character representation of the image data. So, I set out coding and this is what i wrote.


Standards are what we'll be living by in our codes, like engineering standards, Web standards...etc





package examples;

import java.io.*;
import java.nio.BufferOverflowException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.*;

public class Tunes {

CharBuffer charBuf;
ByteBuffer byteBuf;
BufferedInputStream bin = null;
//writer wasn't called. i used Sysout to look ahead.
BufferedWriter bufWriter;
String strChar;
//default character set for my machine is windows-1252.
//tried default and also utf-8
Charset cs = Charset.defaultCharset();
byte[] toUse;
public void doFinal() throws FileNotFoundException,IOException {
try{
//create a buffered file inputstream
bin = new BufferedInputStream(new FileInputStream("amelipassport.jpg"));
//we want to use the default character encoding
//and the default byte buffer size
//we'll use a file writer on a file output stream'
bufWriter = new BufferedWriter (new FileWriter("writeout.txt"));
int c; // check on int returned by file read
//provided there are data in the file,
//keep reading your file and writing to output until
//you get to end of file
toUse = new byte[bin.available()];
while ((c =bin.read(toUse)) != -1){
byteBuf = ByteBuffer.wrap(toUse); //i have a byte buffer now
charBuf = byteBuf.asCharBuffer();
}
}
finally{
//call the charset decoder reset method
Tunes newTunes = new Tunes();
//i used a helper class, HelpDecode
Tunes.HelpDecode helpDecode = newTunes.new HelpDecode();
//follow api instructions to letter. first reset(), decode(),
//final decode(), then flush()
helpDecode.reset();
CoderResult coder = helpDecode.decode(byteBuf, charBuf,true);
//never used the buffer writer since i had to lookahead on
//what my machine was supposed to do
//decode returned malformed
//input byte sequence not legal for this character set,
//even on utf-8
System.out.println(coder.toString());
coder = helpDecode.flush(charBuf);
System.out.println(coder.toString());
System.out.println(charBuf.toString());
//close all your two streams if any is still open
if (bin != null) {bin.close();}
}
}

//helper class HelpDecode extends CharsetDecoder
private class HelpDecode extends CharsetDecoder{
protected HelpDecode(){
//let max and avg charsperbyte be similar
super(cs, 255.0f, 255.0f);
}

protected CoderResult decodeLoop(ByteBuffer in, CharBuffer out) {
//used underflow as a check on result
return CoderResult.UNDERFLOW;
}

}
public static void main(String[] args)
throws FileNotFoundException, IOException {
Tunes nTunes = new Tunes();
nTunes.doFinal();
}
}

From the code above you should realise that I can't decode the image file that way. It's not possible. I took a step from the code and asked myself: “what erroneous presumptions do I have about decoding this file?”

One, the “.jpg” file can be referenced by a File object.
Two, image files should be binary data.

The decoding process just can't do what I want it to do and by the way, my decoder class that was supposed to inherit from CharsetDecoder doesn't inherit any method that reads bytes and decodes them straight to char values, just as I expected.

Bad day. There goes my lunch. There must be a way.

Yes there is. I found one late at night. The java.awt.image package and the javax.imageio packages have just what I wanted. They can even decode images. Great. I had to write the third and definitive piece just for you.



No comments: