TIFF6 Packbit algorithm
“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的更多相关文章
- 挑子学习笔记:两步聚类算法(TwoStep Cluster Algorithm)——改进的BIRCH算法
转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/twostep_cluster_algorithm.html 两步聚类算法是在SPSS Modeler中使用的 ...
- PE Checksum Algorithm的较简实现
这篇BLOG是我很早以前写的,因为现在搬移到CNBLOGS了,经过整理后重新发出来. 工作之前的几年一直都在搞计算机安全/病毒相关的东西(纯学习,不作恶),其中PE文件格式是必须知识.有些PE文件,比 ...
- [异常解决] windows用SSH和linux同步文件&linux开启SSH&ssh client 报 algorithm negotiation failed的解决方法之一
1.安装.配置与启动 SSH分客户端openssh-client和openssh-server 如果你只是想登陆别的机器的SSH只需要安装openssh-client(ubuntu有默认安装,如果没有 ...
- [Algorithm] 使用SimHash进行海量文本去重
在之前的两篇博文分别介绍了常用的hash方法([Data Structure & Algorithm] Hash那点事儿)以及局部敏感hash算法([Algorithm] 局部敏感哈希算法(L ...
- Backtracking algorithm: rat in maze
Sept. 10, 2015 Study again the back tracking algorithm using recursive solution, rat in maze, a clas ...
- [Algorithm & NLP] 文本深度表示模型——word2vec&doc2vec词向量模型
深度学习掀开了机器学习的新篇章,目前深度学习应用于图像和语音已经产生了突破性的研究进展.深度学习一直被人们推崇为一种类似于人脑结构的人工智能算法,那为什么深度学习在语义分析领域仍然没有实质性的进展呢? ...
- [Algorithm] 群体智能优化算法之粒子群优化算法
同进化算法(见博客<[Evolutionary Algorithm] 进化算法简介>,进化算法是受生物进化机制启发而产生的一系列算法)和人工神经网络算法(Neural Networks,简 ...
- [Evolutionary Algorithm] 进化算法简介
进化算法,也被成为是演化算法(evolutionary algorithms,简称EAs),它不是一个具体的算法,而是一个“算法簇”.进化算法的产生的灵感借鉴了大自然中生物的进化操作,它一般包括基因编 ...
- 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 ...
随机推荐
- python for selenium 数据驱动测试
# -*- coding:utf-8 -*- """ 数据驱动测试,从 csv 文件中读取数据 """ from selenium impo ...
- 任意轴算法 ( Arbitrary Axis Algorithm )
已知三维空间中任意单位向量,求以该向量为Z轴的local正交坐标系: 如上图,每个模型都有自己local 坐标系,已知其中一个朝向求另外两个方向. 在autodesk中采用的是Arbitrary Ax ...
- HDOJ(HDU) 2524 矩形A + B(推导公式、)
Problem Description 给你一个高为n ,宽为m列的网格,计算出这个网格中有多少个矩形,下图为高为2,宽为4的网格. Input 第一行输入一个t, 表示有t组数据,然后每行输入n,m ...
- vijosP1014 旅行商简化版
vijosP1014 旅行商简化版 链接:https://vijos.org/p/1014 [思路] 双线DP. 设ab,ab同时走.用d[i][j]表示ab所处结点i.j,且定义i>j,则有转 ...
- DBI接口和DPI接口的区别
1)DBI接口 A,也就是通常所讲的MCU借口,俗称80 system接口.The lcd interface between host processor and LCM device list a ...
- OpenStack Havana 部署在Ubuntu 12.04 Server 【OVS+GRE】——序
OpenStack Havana 部署在Ubuntu 12.04 Server [OVS+GRE](一)——控制节点的安装 OpenStack Havana 部署在Ubuntu 12.04 Serve ...
- 你不一定能做对的JavaScript闭包面试题
由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...
- Android四大组件之ContentProvider(二)读取设备上的图片、音频和视频
Android系统提供了MediaScanner,MediaProvider,MediaStore等接口,通过Content Provider的方式提供给用户.当设备开机或者有SD卡插拔等事件发生时, ...
- Spring 的注册与注入
之前和同学老是爱混淆注册与注入.今天再看一遍感觉多了一些理解. 注册就是声明bean.就是让spring能够找到这个bean服务. 注入就是把bean(A)加入到另一个bean(B)的属性中.让另外一 ...
- 洛谷 P1005 矩阵取数游戏
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...