“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. 【转】iOS开发Xcode7真机调试教程

    原文网址:https://www.skyfox.org/ios-xcode7-debug-device.html 从Xcode7开始,Xcode 不需要$99/$299升级开发者直接可以进行真机调试 ...

  2. [PHP] 跳转以及回到原来的地址

    回到原来的地址: 1.PHP(PHP代码) Header('Location:'.$_SERVER["HTTP_REFERER"]); 2.JavaScript(相当于后退按钮,- ...

  3. HDOJ(HDU) 2520 我是菜鸟,我怕谁(等差数列)

    Problem Description lin2144是一只小菜鸟,都是笨鸟先飞,lin2144想来个菜鸟先飞,他从0点出发 一开始的飞行速度为1m/s,每过一个单位时间lin2144的飞行速度比上一 ...

  4. ExtJs 4: How To Add Grid Cell Tooltip

    最近忙一个项目的时候需要实现鼠标移到grid的某一行上提示消息.花了半天时间才解决.在网上找很久终于有找到一个有用的.我的版本是extjs4. 效果如图 Ext.onReady(function () ...

  5. js冲突怎么解决

    a.最容易出现的就是js的命名冲突①.变量名冲突变量有全局变量和局部变量当全局变量变量和局部变量名称一致时,就会js冲突,由于变量传递数值或地址不同就会产生JavaScript错误,甚至死循环.②.方 ...

  6. memcached与redis 对比

    一. 综述 读一个软件的源码,首先要弄懂软件是用作干什么的,那memcached和redis是干啥的?众所周知,数据一般会放在数据库中,但是查询数据会相对比较慢,特别是用户很多时,频繁的查询,需要耗费 ...

  7. javascript弹出框打印某个数值时,弹出NaN?(not a number)

    一.NaN:表示not a number null 未定义或空字符串 undefined 对象属性不存在 或是声明了变量但从未赋值. 二.出现这种情况有(1)此常数的值是零被零除所得到的结果. (2) ...

  8. Web App和Native App 谁将是未来

    未来是Web App的天下,还是Native App的天下?作为设计师,我们是应该努力把客户端的体验提升到最优,还是在网页应用层面上做更多的设计?这个一直是大家关心的话题.那么,我们首先应该立体的认识 ...

  9. Android内存优化之——static使用篇(使用MAT工具进行分析)

    这篇文章主要配套与Android内存优化之——static使用篇向大家介绍MAT工具的使用,我们分析的内存泄漏程序是上一篇文章中static的使用内存泄漏的比较不容易发现泄漏的第二情况和第三种情况—— ...

  10. Android 自定义View高级特效,神奇的贝塞尔曲线

    效果图 效果图中我们实现了一个简单的随手指滑动的二阶贝塞尔曲线,还有一个复杂点的,穿越所有已知点的贝塞尔曲线.学会使用贝塞尔曲线后可以实现例如QQ红点滑动删除啦,360动态球啦,bulabulabul ...