this link is data http://www.freewebtown.com/htmn1001/library/test.dat
below is my code.
package test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
File f = new File("D:\\test.dat");
FileInputStream fis = null;
byte[] data = new byte[(int)f.length()];
try {
fis = new FileInputStream(f);
fis.read(data);
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
f = null;
TiffHeader fileHeader = new TiffHeader((short) 0x0B);
fileHeader.setField((short)0x0100, (short)0x4, 1, 368);// DPI
fileHeader.setField((short)0x0101, (short)0x4, 1, 368);// DPI
fileHeader.setField((short)0x0103, (short)0x3, 1, 0x03);
fileHeader.setField((short)0x0106, (short)0x3, 1, 0x00);
fileHeader.setField((short)0x010A, (short)0x3, 1, 0x01);
int stripPosition = fileHeader.getTiffHeaderLength();
fileHeader.setField((short)0x0111, (short)0x4, 1, stripPosition);
fileHeader.setField((short)0x0116, (short)0x4, 1, 368);// consider IMAGE_LENGTH
fileHeader.setField((short)0x0124, (short)0x4, 1, 0x05); // MR
fileHeader.setField((short)0x0117, (short)0x4, 1, data.length);
fileHeader.setX_Res_Value(204, 1);
fileHeader.setY_Res_Value(196, 1);
byte[] imageData = new byte[fileHeader.getTiffHeaderLength() + data.length];
System.arraycopy(fileHeader.getTiffHeader(), 0, imageData, 0, fileHeader.getTiffHeaderLength());
System.arraycopy(data, 0, imageData, fileHeader.getTiffHeaderLength(), data.length);
FileOutputStream fos = null;
try {
fos = new FileOutputStream("D:\\test.tif");
fos.write(imageData);
fos.close();
RenderedOp op = JAI.create("fileload", "D:\\test.tif");
fos = new FileOutputStream("D:\\test.bmp");
JAI.create("filestore", op, "tiff", fos, null);
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TiffHeader {
protected short byteOrder = 0x4D4D;
protected short fileIdentity = 0x002A;
protected int IFDOffset = 0x00000008;
protected short numberOfDirectoryEntries;
protected ArrayList<IFDEntry> entries = new ArrayList<IFDEntry>();
protected byte[] X_Res_Value, Y_Res_Value;
protected byte[] stripOffsetValue,stripByteCountValue;
protected int nextIFDOffset = 0x0;
protected int headerEndOffset;
public TiffHeader(short numberOfDirectoryEntries )
{
this.setNumberOfDirectoryEntries(numberOfDirectoryEntries);
}
/**
* Get index of a field
* @param tagValue the tag to look for in header
* @return index of a field.
*/
protected int getFieldIndex(short tagValue)
{
for (int i = 0; i < entries.size(); i++)
if ( ((IFDEntry)entries.get(i)).tag >= tagValue) return i;
return -1;
}
/**
* Get tiff header length (include extra fields)
* @return header length - int
*/
public int getTiffHeaderLength()
{
return (headerEndOffset + 2*0x8);
}
/**
* Set a TIFF field.
* If a new field, then add, othewise, change value
* @param tag
* @param type
* @param count
* @param offset
*/
public void setField(short tag,short type,int count, int offset)
{
//Move to higher position
if (type == 0x3) offset*=0x10000;
int index = getFieldIndex(tag);
if (index != -1)
{
if (((IFDEntry)entries.get(index)).tag == tag)
((IFDEntry)entries.get(index)).setValue(count, offset);
else
entries.add(index, new IFDEntry(tag, type, count, offset));
}
else
entries.add(new IFDEntry(tag, type, count, offset));
}
/**
* Set X_Resolution value
* @param nume numerator
* @param deno denominator
*/
public void setX_Res_Value(int nume,int deno)
{
X_Res_Value = new byte[0x8];
Util.copyArrayToArray(Util.intToByteArray(nume),X_Res_Value,0);
Util.copyArrayToArray(Util.intToByteArray(deno),X_Res_Value,4);
setField((short)0x011A, (short)0x5, 1, headerEndOffset);
}
/**
* Set Y_Resolution value
* @param nume numerator
* @param deno denominator
*/
public void setY_Res_Value(int nume, int deno)
{
Y_Res_Value = new byte[0x8];
Util.copyArrayToArray(Util.intToByteArray(nume),Y_Res_Value,0);
Util.copyArrayToArray(Util.intToByteArray(deno),Y_Res_Value,4);
setField((short)0x011B, (short)0x5, 1,
headerEndOffset + 0x05);
}
/**
* Get byte array contains tiff header information
* @return a byte array contains tiff header information
*/
public byte[] getTiffHeader()
{
byte[] header = new byte[this.getTiffHeaderLength()];
int i = 0;
Util.copyArrayToArray(Util.shortToByteArray(byteOrder),header,i);
i+=2;
Util.copyArrayToArray(Util.shortToByteArray(fileIdentity),header,i);
i+=2;
Util.copyArrayToArray(Util.intToByteArray(IFDOffset),header,i);
i+=4;
Util.copyArrayToArray(Util.shortToByteArray(numberOfDirectoryEntries),header,i);
i+=2;
for (int j = 0; j < entries.size(); j++)
{
Util.copyArrayToArray(entries.get(j).getValue(),header,i);
i+=12;
}
Util.copyArrayToArray(X_Res_Value,header,
entries.get(getFieldIndex((short)0x011A)).valueOffset);
Util.copyArrayToArray(Y_Res_Value,header,
entries.get(getFieldIndex((short)0x011B)).valueOffset);
return header;
}
/**
* @param byteOrder the byteOrder to set
*/
public void setByteOrder(short byteOrder) {
this.byteOrder = byteOrder;
}
/**
* @param offset the iFDOffset to set
*/
public void setIFDOffset(int offset) {
IFDOffset = offset;
}
/**
* Set number of directory entries in TIFF header
* @param numberOfDirectoryEntries the numberOfDirectoryEntries to set
*/
private void setNumberOfDirectoryEntries(short numberOfDirectoryEntries) {
this.numberOfDirectoryEntries = numberOfDirectoryEntries;
headerEndOffset = 14 + numberOfDirectoryEntries*12;
}
}
class IFDEntry {
protected short tag;
protected short type;
protected int count;
protected int valueOffset;
public IFDEntry(short tag,short type, int count, int valueOffset)
{
this.tag = tag;
this.type = type;
this.count = count;
this.valueOffset = valueOffset;
}
/**
* Change a TIFF field
* @param count
* @param valueOffset
*/
public void setValue(int count, int valueOffset)
{
this.count = count;
this.valueOffset = valueOffset;
}
/**
*
* @return 12 bytes array contains Tag,Type,Count,Offset
*/
public byte[] getValue()
{
byte[] ifd = new byte[12];
System.arraycopy(Util.shortToByteArray(tag),0,
ifd, 0,2);
System.arraycopy(Util.shortToByteArray(type),0,
ifd, 2,2);
System.arraycopy(Util.intToByteArray(count),0,
ifd, 4,4);
System.arraycopy(Util.intToByteArray(valueOffset),0,
ifd, 8,4);
return ifd;
}
}
class Util {
public static final void copyArrayToArray(byte[] source, byte[] dest, int position)
{
if (dest.length - position < source.length) return;
for (int i = 0; i < source.length; i++)
dest[position + i] = source[i];
}
/**
* Convert Int to array of bytes
* @param value
*/
public static final byte[] intToByteArray(int value) {
return new byte[]{
(byte)(value >> 24),
(byte)(value >> 16 & 0xff),
(byte)(value >> 8 & 0xff),
(byte)(value & 0xff) };
}
/**
* Convert int to array of bytes, fill 0 if not fit size
* Ex: value = 123, size = 5 -> return byte array = 00123
* @param value
* @param size
*/
public static final byte[] intToByteArray(int value,int size) {
byte[] data = new byte[size];
String str = Integer.toString(value);
int j = str.length() - 1;
for (int i = size - 1; i >= 0; i--)
{
if (j > -1) data[i] = (byte)str.charAt(j--);
else data[i] = 0x30;
}
return data;
}
/**
* Reads short into array of bytes.
* @param value short type.
*/
public static final byte[] shortToByteArray(short value) {
return new byte[]{
(byte)(value >> 8 & 0xff),
(byte)(value & 0xff) };
}
}
Thanks.
Nguyen
Oh wow... Sadly, I used to maintain code that went to depths like this. That's when I decided to rewrite our imaging algorithms with JAI 1.1. Simplified my world. My best suggestion, would be to do that.
But I understand that that isn't always an option.
This is starting to look like a TIFF metadata problem to me. If I were in your position, I'd start by looking at the ifdOffset and number of bytes you're using per tag. Remember that you need to pad your tag data to the appropriate byte length (I can't tell if you're doing this already). And I vaguely remember something about having to have everything end on a word boundary.
Again, my best suggestion is to use TIFFDirectory, TIFFTag, and TIFFField classes from JAI to generate your metadata. Then also use JAI to properly write out your image byte data.
You can see an example of creating and writing image metadata with JAI in this topic:
http://forum.java.sun.com/thread.jspa?threadID=5161294&tstart=0
Hope this helps,
CowKing
Alright, we need to start at the beginning of this whole process. You are trying to read in some raw image data from a file.
What is generating the input data? Do you know what format, or compression (if any), that the input data is in? If it is a TIFF format, than how come the raw data is being written out without any tags? Why isn't the generating program creating a valid TIFF image?
If you can find a way to bring the raw image data into the Java world, then we could go somewhere productive with this.
CowKing