“Packbits” from ISO 12369

参考TIFF 6.0 Specification,点击TIFF, Version 6.0

@Section 9: PackBits Compression

> This section describes TIFF compression type 32773, a simple byte-oriented runlength scheme.

描述[摘录]

In choosing a simple byte-oriented run-length compression scheme, we arbitrarily chose the Apple Macintosh PackBits scheme. It has a good worst case behavior
(at most 1 extra byte for every 128 input bytes). For Macintosh users, the toolbox utilities PackBits and UnPackBits will do the work for you, but it is easy to implement your own routines.
A pseudo code fragment to unpack might look like this:

Loop until you get the number of unpacked bytes you are expecting:
Read the next source byte into n.
If n is between and inclusive, copy the next n+ bytes literally.
Else if n is between - and - inclusive, copy the next byte -n+
times.
Else if n is -, noop.
Endloop

In the inverse routine, it is best to encode a 2-byte repeat run as a replicate run except when preceded and followed by a literal run. In that case, it is best to merge
the three runs into one literal run. Always encode 3-byte repeats as replicate runs.
That is the essence of the algorithm. Here are some additional rules:
• Pack each row separately. Do not compress across row boundaries.
• The number of uncompressed bytes per row is defined to be (ImageWidth + 7)/8. If the uncompressed bitmap is required to have an even number of bytes per
row, decompress into word-aligned buffers.
• If a run is larger than 128 bytes, encode the remainder of the run as one or more additional replicate runs.
When PackBits data is decompressed, the result should be interpreted as per compression type 1 (no compression).

Coding

function declaration

// Packbit algorithm, make sure the _countof(Pack[*]) >= (count + count/128 +2);
// return _countof(Pack[*]) actual count
// AVC_FMAC
int tiff6_PackBits(unsigned char array[], int count, unsigned char Pack[]);
// return _countof(array[*]);
// AVC_FMAC
int tiff6_unPackBits(char Pack[], int count, unsigned char array[] /*= NULL*/);

implementation

static signed char* Pack_init(unsigned char Pack[], unsigned char Byte);
static signed char* Pack_byte(signed char* Count, unsigned char Byte);
static unsigned char* End_byte(signed char* Count);
int tiff6_PackBits(unsigned char array[], int count, unsigned char Pack[])
{
int i = ;
signed char* Count = Pack_init(Pack, array[i]); i++;
for (; i < count; i++) Count = Pack_byte(Count, array[i]);
unsigned char* End = End_byte(Count); *End = '\0';
return (End - Pack);
}
static int unPack_count(char Pack[], int count);
int tiff6_unPackBits(char Pack[], int count, unsigned char array[] /*= NULL*/)
{
if (!array) return unPack_count(Pack, count);
int nRes = ;
signed char* Count = (signed char*)Pack;
while ((char*)Count < (Pack+count))
{
int c = *Count;
if (c<)
{
int n = (-c);
memset(&(array[nRes]), Count[], n);
nRes += n;
}
else
{
int n = (+c);
memcpy(&(array[nRes]), &Count[], n);
nRes += n;
}
Count = (signed char*)End_byte(Count);
}
return nRes;
} int unPack_count(char Pack[], int count)
{
int nRes = ;
signed char* Count = (signed char*)Pack;
while ((char*)Count < (Pack+count))
{
int c = *Count;
if (c<)
nRes += (-c);
else
nRes += (+c);
Count = (signed char*)End_byte(Count);
}
return nRes;
}
signed char* Pack_init( unsigned char Pack[], unsigned char Byte )
{
signed char* Cnt = (signed char*)Pack;
*Cnt = ; Pack[] = Byte;
return Cnt;
}
unsigned char* End_byte( signed char* Count )
{
unsigned char* Pack = (unsigned char*)(Count+);
signed char c = *Count;
if (c >)
Pack = &(Pack[c+]);
else Pack = &(Pack[]);
return Pack;
}
signed char* Pack_byte( signed char* Count, unsigned char Byte )
{
signed char c = *Count;
unsigned char* End = End_byte(Count);
if ( == c || c == -)
return Pack_init(End, Byte);
else
{
unsigned char* Pack = End-;
if (*(Pack) == Byte)
{
if (c >)
{
(*Count) = c-;
Count = Pack_byte(Pack_init(Pack, Byte), Byte);
}
else (*Count)--;
}
else
{
if (c >= )
{
*End = Byte;
(*Count)++;
}
else Count = Pack_init(End, Byte);
}
}
return Count;
}

另,本文明确使用了signed修饰char, 因为有些编译环境下char默认是有符号的,但是笔者也曾遇到默认无符号的环境,因此为了使代码在其中编译能正确使用,则指明符号修饰。

TIFF6 Packbit algorithm的更多相关文章

  1. 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...

  2. PE Checksum Algorithm的较简实现

    这篇BLOG是我很早以前写的,因为现在搬移到CNBLOGS了,经过整理后重新发出来. 工作之前的几年一直都在搞计算机安全/病毒相关的东西(纯学习,不作恶),其中PE文件格式是必须知识.有些PE文件,比 ...

  3. [异常解决] windows用SSH和linux同步文件&linux开启SSH&ssh client 报 algorithm negotiation failed的解决方法之一

    1.安装.配置与启动 SSH分客户端openssh-client和openssh-server 如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有 ...

  4. [Algorithm] 使用SimHash进行海量文本去重

    在之前的两篇博文分别介绍了常用的hash方法([Data Structure & Algorithm] Hash那点事儿)以及局部敏感hash算法([Algorithm] 局部敏感哈希算法(L ...

  5. Backtracking algorithm: rat in maze

    Sept. 10, 2015 Study again the back tracking algorithm using recursive solution, rat in maze, a clas ...

  6. [Algorithm & NLP] 文本深度表示模型——word2vec&doc2vec词向量模型

    深度学习掀开了机器学习的新篇章,目前深度学习应用于图像和语音已经产生了突破性的研究进展.深度学习一直被人们推崇为一种类似于人脑结构的人工智能算法,那为什么深度学习在语义分析领域仍然没有实质性的进展呢? ...

  7. [Algorithm] 群体智能优化算法之粒子群优化算法

    同进化算法(见博客<[Evolutionary Algorithm] 进化算法简介>,进化算法是受生物进化机制启发而产生的一系列算法)和人工神经网络算法(Neural Networks,简 ...

  8. [Evolutionary Algorithm] 进化算法简介

    进化算法,也被成为是演化算法(evolutionary algorithms,简称EAs),它不是一个具体的算法,而是一个“算法簇”.进化算法的产生的灵感借鉴了大自然中生物的进化操作,它一般包括基因编 ...

  9. Debian 8 jessie, OpenSSH ssh connection server responded Algorithm negotiation failed

    安装了debian 8.5 就出问题了. root@debian8:~# lsb_release -aNo LSB modules are available.Distributor ID: Debi ...

随机推荐

  1. JAVA中IO技术:BIO、NIO、AIO

    1.同步异步.阻塞非阻塞概念        同步和异步是针对应用程序和内核的交互而言的. 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作 ...

  2. makefile 自动处理头文件的依赖关系 (zz)

    现在我们的Makefile写成这样: all: main main: main.o stack.o maze.ogcc $^ -o $@ main.o: main.h stack.h maze.hst ...

  3. JDK 1.6.0和 6.0 有啥区别,JavaTM SE 6 的平台名字和版本号的说明(转)

    一直这么理解,今天才看到官方的解释,真是有点汗颜. 核心就是 6.0用于平台和产品的名字,而1.6.0用于开发者. 他们指的是同一个东西. 原文地址:http://java.sun.com/javas ...

  4. Linux学习笔记10——文件I/O之一

    UNIX系统中的大多数文件I/O只需要用到5个函数:open,read,write,lseek以及close 文件描述符 文件描述符是一个非负整数,所有打开的文件都通过文件描述符引用 文件描述符的变化 ...

  5. HDOJ/HDU 1321 Reverse Text(倒序输出~)

    Problem Description In most languages, text is written from left to right. However, there are other ...

  6. Java IO复习(一)

    package com.zyw.file; import java.io.*; /** * Created by zyw on 2016/3/10. */ public class IOTest { ...

  7. CSS 属性 - 伪类和伪元素

    CSS 伪类用于向某些选择器添加特殊的效果. CSS 伪元素用于将特殊的效果添加到某些选择器. 可以明确两点,第一两者都与选择器相关,第二就是添加一些“特殊”的效果.这里特殊指的是两者描述了其他 cs ...

  8. VM虚拟机下在LINUX上安装ORACLE 11G单实例数据库

    1.环境及安装前规划:虚拟机及OS如下 环境:VMware Wordstation ACE版 6.0.2 操作系统:OracleLinux-R5-U8-Server-i386-dvd    3.2G ...

  9. Java中的成员初始化顺序和内存分配过程

    Java中的成员初始化顺序和内存分配过程 原帖是这样描述的: http://java.dzone.com/articles/java-object-initialization?utm_source= ...

  10. ICOPclient版本号,异步connect

    之前在网上看到一个服务端的ICOP模块,比較小巧,感觉还不错,后来在工作中,需要开发一个挂号的程序,监视大量server执行情况,初期连接数大概六七百,我就把这个ICOP模块改造成了一个client版 ...