Tiff文件解析和PackBits解压缩

实现了Tiff图片文件格式的解析,对Tiff文件中的PackBits压缩格式进行解压缩,对Tiff文件中每一个Frame转换成BufferedImage显示。

Java语言实现,Eclipse下开发,AWT显示图片。

public static TIFF Parse(final byte[] bytes) throws IllegalAccessException {
		BinaryBuffer is = new BinaryBuffer(bytes);
		
		TIFF tiff = new TIFF();
		FileHeader header = new FileHeader();
		header.setByteOrder( is.ReadAsciiString(2));
		
		if (header.getByteOrder().equals("II"))
			is.SetByteOrder(ByteOrder.LITTLE_ENDIAN);
		else if (header.getByteOrder().equals( "MM"))
			is.SetByteOrder(ByteOrder.BIG_ENDIAN);
		else
			throw new java.lang.IllegalAccessException(header.getByteOrder());

		header.setLabel( is.ReadBytes(2));
		header.setOffset( is.ReadUInt32());
		tiff.setHeader(header);
		
		int position = (int) header.getOffset();			
		
		while (position != 0 ) {
			is.SetPosition(position);
			FileDirectory ifd = new FileDirectory();
			ifd.setEntryCount( is.ReadUInt16() );
			
			for (int i=0; i<ifd.getEntryCount(); i++) {
				Entry entry = new Entry();
				entry.setTag( is.ReadUInt16() );
				entry.setType( is.ReadUInt16() );
				entry.setCount( is.ReadInt32() );
				entry.setValue( is.ReadInt32() );
				
				if (entry.getType() == 1) { // 8-bit unsigned integer
					int count = 1 * entry.getCount();
					
					if (count <=4)
						entry.setData(new byte[] {  });
					else {
						is.SavePoint();
						is.SetPosition(entry.getValue());
						entry.setData( is.ReadAsciiChar(entry.getCount()));
						is.RestorePoint();
					}
				}
				else if (entry.getType() == 2) { // 8-bit, NULL-terminated string
					int count = 1 * entry.getCount();
					
					if (count <=4)
						entry.setData(new char[] {  });
					else {
						is.SavePoint();
						is.SetPosition(entry.getValue());
						entry.setData( is.ReadAsciiChar(entry.getCount()));
						is.RestorePoint();
					}
				}
				else if (entry.getType() == 3) { // 16-bit unsigned integer
					int count = 2 * entry.getCount();
					
					if (count <= 4) {
						entry.setData( entry.getValue());
					}
					else {
						is.SavePoint();
						is.SetPosition(entry.getValue());
						entry.setData( is.ReadUInt16(entry.getCount()));
						is.RestorePoint();
					}
				}
				else if (entry.getType() == 4) { // 32-bit unsigned integer
					int count = 4 * entry.getCount();
					if (count <= 4 )
						entry.setData(entry.getValue());
					else {
						is.SavePoint();
						is.SetPosition(entry.getValue());
						entry.setData( is.ReadUInt32(entry.getCount()));
						is.RestorePoint();
					}
				}
				else if (entry.getType() == 5) { // Two 32-bit unsigned integers
					is.SavePoint();
					is.SetPosition(entry.getValue());
					entry.setData( 1.0 * is.ReadUInt32() / is.ReadUInt32() );
					is.RestorePoint();

				}
				else if (entry.getType() == 6) { // 8-bit signed integer
					throw new java.lang.UnsupportedOperationException();
				}
				else if (entry.getType() == 7) { // 8-bit byte
					int count = 1 * entry.getCount();
				
					if (count <=4)
						entry.setData(new byte[] {  });
					else {
						is.SavePoint();
						is.SetPosition(entry.getValue());
						entry.setData( is.ReadAsciiChar(entry.getCount()));
						is.RestorePoint();
					}
				}
				else if (entry.getType() == 9) { // 32-bit signed integer
					int count = 4 * entry.getCount();
					if (count <= 4 )
						entry.setData(entry.getValue());
					else {
						is.SavePoint();
						is.SetPosition(entry.getValue());
						entry.setData( is.ReadInt32(entry.getCount()));
						is.RestorePoint();
					}
				}
				else if (entry.getType() == 10) { // Two 32-bit signed integers
					entry.setData( 1.0 * is.ReadInt32() / is.ReadInt32() );
				}
				else if (entry.getType() == 11) { // 4-byte single-precision IEEE 
					throw new java.lang.UnsupportedOperationException();
				}
				else if (entry.getType() == 12) { // 8-byte double-precision IEEE 
					throw new java.lang.UnsupportedOperationException();
				}
				else 
					throw new java.lang.IllegalArgumentException(entry.getType() + "");
				
				ifd.getEntrys().add(entry);
			}
			
			ifd.setNext( is.ReadInt32());
			tiff.getDirectorys().add(ifd);
			position = ifd.getNext();
		}
		
		return tiff;
	}

解析Tiff文件第1个Frame的结构:

PackBits解压缩代码:

	public static byte[] uncompress(byte[] input) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		
		int i = 0;
		do {
			byte n = input[i++];
			
			if (n < 0 && n > -128) {
				byte b = input[i++];
				
				for (int j=0; j<-n+1; j++)
					os.write(b);
			}
			else if (n >= 0 && n<=127) {
				int count = n + 1;
				for (int j=0; j<count; j++)
					os.write(input[i++]);
			}
			
		} while (i<input.length);
		
		return os.toByteArray();
	}

在AWT显示Tiff图像中32个Frame图像,采用GridLayout布局,效果如下

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值