TIFF6 Packbit algorithm

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   io   os   使用   ar   

“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 0 and 127 inclusive, copy the next n+1 bytes literally.Else if n is between -127 and -1 inclusive, copy the next byte -n+1times.Else if n is -128, 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).

Codingfunction declaration
// Packbit algorithm, make sure the _countof(Pack[*]) >= (count + count/128 +2);// return _countof(Pack[*]) actual count// AVC_FMACint  tiff6_PackBits(unsigned char array[], int count, unsigned char Pack[]);// return _countof(array[*]);// AVC_FMACint  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 = 0;    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 = 0;    signed char* Count = (signed char*)Pack;    while ((char*)Count < (Pack+count))    {        int c = *Count;        if (c<0)        {            int n = (1-c);            memset(&(array[nRes]), Count[1], n);            nRes += n;        }        else        {            int n = (1+c);            memcpy(&(array[nRes]), &Count[1], n);            nRes += n;        }        Count = (signed char*)End_byte(Count);    }    return nRes;}int unPack_count(char Pack[], int count){    int nRes = 0;    signed char* Count = (signed char*)Pack;    while ((char*)Count < (Pack+count))    {        int c = *Count;        if (c<0)            nRes += (1-c);        else            nRes += (1+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 = 0; Pack[1] = Byte;    return Cnt;}unsigned char* End_byte( signed char* Count ){    unsigned char* Pack = (unsigned char*)(Count+1);    signed char c = *Count;    if (c >0)         Pack = &(Pack[c+1]);    else Pack = &(Pack[1]);    return Pack;}signed char* Pack_byte( signed char* Count, unsigned char Byte ){    signed char c = *Count;    unsigned char* End = End_byte(Count);    if (127 == c || c == -127)        return Pack_init(End, Byte);    else    {        unsigned char* Pack = End-1;        if (*(Pack) == Byte)        {            if (c >0)            {                (*Count) = c-1;                Count = Pack_byte(Pack_init(Pack, Byte), Byte);            }            else (*Count)--;        }        else        {            if (c >= 0)            {                *End = Byte;                (*Count)++;            }            else Count = Pack_init(End, Byte);        }    }    return Count;}


另,本文明確使用了signed修飾char, 因為有些編譯環境下char預設是有符號的,但是筆者也曾遇到預設無符號的環境,因此為了使代碼在其中編譯能正確使用,則指明符號修飾。

 

TIFF6 Packbit algorithm

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.