help me write EOL into TIFF file which is compressed by MR

I create TIFF image from image data which hasn't got any tags. I got problem when I encode it throws RuntimeException "Scanline must begin with EOL code word." or "All fill bits preceding EOL code must be 0."Help me ....
[235 byte] By [luisnguyena] at [2007-11-27 1:17:30]
# 1
Could you please post some example code (it will help us help you)?Thanks!CowKing
IamCowKinga at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...
# 2

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

luisnguyena at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...
# 3

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

IamCowKinga at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...
# 4
I tried, but I haven't found way to add image data and metadata together into file yet.ThanksNguyen.
luisnguyena at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...
# 5

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

IamCowKinga at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...
# 6
The input data is image data which dosen't contain any TIFF tags. My mission is i have to add TIFF tags and image data together into file.Thanks CowKingNguyenMessage was edited by: luisnguyen
luisnguyena at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...
# 7
I resolved my problem.Thanks CowKing.Nguyen
luisnguyena at 2007-7-11 23:53:08 > top of Java-index,Security,Cryptography...