“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. winphone 开发学习笔记(1)

    学习了winphone task 1.首先根据自己电脑下载sdk,,,win 7和win 8的Sdk安装包不一样, http://www.microsoft.com/en-hk/download/de ...

  2. Asp.Net MVC4新特性指南(1): 基本介绍

    这段时间项目不紧,没啥事,就琢磨着把MVC4了解下.看看有啥新特性,顺便发表个博文记录下.哈哈. MVC4我们就用到了微软的Visual Studio 2012(http://www.microsof ...

  3. 《University Calculus》-chape8-无穷序列和无穷级数-欧拉恒等式

    写在前面:写在前面的当然是对大天朝教材的吐槽啦. 曾记否,高中所学虚数和复平面的概念,如此虚无的概念到了大学一门叫<模拟电子技术>的课程中居然明目张胆的开始进行计算! 曾记否,高中的指对运 ...

  4. CentOS添加swap分区

    在多个VPS上尝试. 1.进入目录 cd /var/ 2.获取要增加的SWAP文件块(这里以1GB为例) dd if=/dev/zero of=swapfile bs=1024 count=10383 ...

  5. Div 3 - SGU 105(找规律)

    分析:很容易知道序列1,2,3, 4,5, 6......与3的关系就是1,2, 0,1, 2,0,......如果是在一个数后面添加一个数就变成了这种序列1, 0, 0, 1, 0, 0, 1, 0 ...

  6. TOYS - POJ 2318(计算几何,叉积判断)

    题目大意:给你一个矩形的左上角和右下角的坐标,然后这个矩形有 N 个隔板分割成 N+1 个区域,下面有 M 组坐标,求出来每个区域包含的坐标数.   分析:做的第一道计算几何题目....使用叉积判断方 ...

  7. hdoj 4786 Fibonacci Tree【并查集+最小生成树(kruskal算法)】

    Fibonacci Tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. 如何高性能的给UIImageView加个圆角?(不准说layer.cornerRadius!)

    豆电雨 搬砖自味精:http://awhisper.github.io/2016/03/12/滚动圆角卡顿刨根问底/ 使用Quartz2D直接绘制图片 步骤:  a.创建目标大小(cropWidth, ...

  9. BJUI 转

    B-JUI 前端框架B-JUI(Bootstrap for DWZ)是一个富客户端框架,基于DWZ-jUI富客户端框架修改. 本文是B-JUI中文使用手册,包括使用示例代码,感兴趣的同学参考下. 概览 ...

  10. SQL第二课-创建数据表

    查看有多少数据库 SHOW DATABASES; 进入数据库:USE <数据库名> 举例:USE test;//进入test数据库 查看当前进入的是哪个数据库 SELECT DATABAS ...