Defines | Functions | Variables

pck.c File Reference

#include <stdio.h>
#include <stddef.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
Include dependency graph for pck.c:

Go to the source code of this file.

Defines

#define BYTE   char
#define WORD   short int
#define LONG   int
#define PACKIDENTIFIER   "\nCCP4 packed image, X: %04d, Y: %04d\n"
#define PACKBUFSIZ   BUFSIZ
#define DIFFBUFSIZ   16384L
#define max(x, y)   (((x) > (y)) ? (x) : (y))
#define min(x, y)   (((x) < (y)) ? (x) : (y))
#define abs(x)   (((x) < 0) ? (-(x)) : (x))
#define shift_left(x, n)   (((x) & setbits[32 - (n)]) << (n))
#define shift_right(x, n)   (((x) >> (n)) & setbits[32 - (n)])

Functions

LONG * diff_words (WORD *, int, int, LONG *, LONG)
void get_pck (FILE *, WORD *)
int put_pck (WORD *, int, int, int)
static int pack_chunk ()
static void unpack_word (FILE *, int, int, WORD *)
static void pack_longs ()
static int bits ()
static int bits (LONG *chunk, int n)
static int pack_chunk (LONG *lng, int nmbr, int bitsize, int fdesc)
static void pack_longs (LONG *lng, int n, BYTE **target, int *bit, int size)

Variables

const LONG setbits [33]

Define Documentation

#define abs (   x)    (((x) < 0) ? (-(x)) : (x))

Definition at line 28 of file pck.c.

Referenced by bits(), MarHW::mar_move_phi(), and MarHW::marTask().

#define BYTE   char

Definition at line 19 of file pck.c.

Referenced by pack_chunk(), and pack_longs().

#define DIFFBUFSIZ   16384L

Definition at line 25 of file pck.c.

Referenced by diff_words(), and put_pck().

#define LONG   int

Definition at line 21 of file pck.c.

Referenced by diff_words(), pack_chunk(), pack_longs(), put_pck(), and unpack_word().

#define max (   x,
 
)    (((x) > (y)) ? (x) : (y))

Definition at line 26 of file pck.c.

Referenced by bits(), and put_pck().

#define min (   x,
 
)    (((x) < (y)) ? (x) : (y))

Definition at line 27 of file pck.c.

#define PACKBUFSIZ   BUFSIZ

Definition at line 24 of file pck.c.

Referenced by pack_chunk().

#define PACKIDENTIFIER   "\nCCP4 packed image, X: %04d, Y: %04d\n"

Definition at line 23 of file pck.c.

Referenced by get_pck().

#define shift_left (   x,
 
)    (((x) & setbits[32 - (n)]) << (n))

Definition at line 38 of file pck.c.

Referenced by pack_longs(), and unpack_word().

#define shift_right (   x,
 
)    (((x) >> (n)) & setbits[32 - (n)])

Definition at line 39 of file pck.c.

Referenced by pack_longs(), and unpack_word().

#define WORD   short int

Definition at line 20 of file pck.c.

Referenced by unpack_word().


Function Documentation

static int bits ( ) [static]
static int bits ( LONG *  chunk,
int  n 
) [static]

Definition at line 116 of file pck.c.

References abs, i, and max.

{ 
  int size, maxsize, i;

  for (i = 1, maxsize = abs(chunk[0]); i < n; ++i)
    maxsize = max(maxsize, abs(chunk[i]));
  if (maxsize == 0)
    size = 0;
  else if (maxsize < 8)
    size = 4 * n;
  else if (maxsize < 16)
    size = 5 * n;
  else if (maxsize < 32)
    size = 6 * n;
  else if (maxsize < 64)
    size = 7 * n;
  else if (maxsize < 128)
    size = 8 * n;
  else if (maxsize < 65536)
    size = 16 * n;
  else
    size = 32 * n;
  return(size);
}
LONG * diff_words ( WORD *  word,
int  x,
int  y,
LONG *  diffs,
LONG  done 
)

Definition at line 187 of file pck.c.

References DIFFBUFSIZ, i, and LONG.

Referenced by put_pck().

{ 
LONG i = 0;
LONG tot = x * y;

        if(done == 0)
          { 
            *diffs = word[0];
            ++diffs;
            ++done;
            ++i;
          }
        while((done <= x) && (i < DIFFBUFSIZ))
          {
            *diffs = word[done] - word[done - 1];
            ++diffs;
            ++done;
            ++i;
          }
        while ((done < tot) && (i < DIFFBUFSIZ))
          {
            *diffs = word[done] - (word[done - 1] + word[done - x + 1] +
                     word[done - x] + word[done - x - 1] + 2) / 4;
            ++diffs;
            ++done;
            ++i;
          }
        return(--diffs);
}
void get_pck ( FILE *  fp,
WORD *  img 
)

Definition at line 271 of file pck.c.

References i, PACKIDENTIFIER, and unpack_word().

{ 
int x = 0, y = 0, i = 0, c = 0;
char header[BUFSIZ];

        if ( fp == NULL ) return;
        rewind ( fp );
        header[0] = '\n';
        header[1] = 0;

        while ((c != EOF) && ((x == 0) || (y == 0))) {
                c = i = x = y = 0;

                while ((++i < BUFSIZ) && (c != EOF) && (c != '\n') && (x==0) && (y==0))
                        if ((header[i] = c = getc(fp)) == '\n')
                                sscanf(header, PACKIDENTIFIER, &x, &y);
        }

        unpack_word(fp, x, y, img);
}
static int pack_chunk ( ) [static]

Referenced by put_pck().

static int pack_chunk ( LONG *  lng,
int  nmbr,
int  bitsize,
int  fdesc 
) [static]

Definition at line 145 of file pck.c.

References BYTE, i, j, LONG, pack_longs(), and PACKBUFSIZ.

{ 
static LONG     bitsize_encode[33] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0,
                                      0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
                                      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7};
LONG            descriptor[2], i, j;
static BYTE     *buffer = NULL;
static BYTE     *buffree = NULL;
static int      bitmark;

        if(buffer == NULL) {
            buffree = buffer = (BYTE *) malloc(PACKBUFSIZ);
            bitmark = 0;
        }

        if(lng != NULL) {
            for (i = nmbr, j = 0; i > 1; i /= 2, ++j);
            descriptor[0] = j;
            descriptor[1] = bitsize_encode[bitsize];
            if((buffree - buffer) > (PACKBUFSIZ - (130 * 4))) {
                if( write(fdesc, buffer,buffree - buffer) == -1 )
                        return( 0 );
                buffer[0] = buffree[0];
                buffree = buffer;
            }
            pack_longs(descriptor, 2, &buffree, &bitmark, 3);
            pack_longs(lng, nmbr, &buffree, &bitmark, bitsize);
         }
         else {
            if( write(fdesc,buffer,(buffree - buffer) + 1) == -1 )
                return( 0 );
            free((void *) buffer);
            buffer = NULL;
         }

        return( 1 );
}
static void pack_longs ( LONG *  lng,
int  n,
BYTE **  target,
int *  bit,
int  size 
) [static]

Definition at line 221 of file pck.c.

References bit, BYTE, i, LONG, setbits, shift_left, and shift_right.

  { 
        LONG mask, window;
        int valids, i, temp;
        int temp_bit = *bit;
        BYTE *temp_target = *target;

        if (size > 0)
          {
            mask = setbits[size];
            for(i = 0; i < n; ++i)
              {
                window = lng[i] & mask;
                valids = size;
                if(temp_bit == 0)
                        *temp_target = (BYTE) window;
                  else
                    {
                      temp = shift_left(window, temp_bit);
                      *temp_target |= temp;
                    }
                 window = shift_right(window, 8 - temp_bit);
                valids = valids - (8 - temp_bit);
                if(valids < 0)
                    temp_bit += size;
                  else
                    {
                      while (valids > 0)
                        { 
                          *++temp_target = (BYTE) window;
                          window = shift_right(window, 8);
                          valids -= 8;
                        }
                      temp_bit = 8 + valids;
                    }
                if(valids == 0)
                  { 
                    temp_bit = 0;
                    ++temp_target;
                  }
              }
            *target = temp_target;
            *bit = (*bit + (size * n)) % 8;
          }
}
static void pack_longs ( ) [static]

Referenced by pack_chunk().

int put_pck ( WORD *  img,
int  x,
int  y,
int  fdesc 
)

Definition at line 59 of file pck.c.

References bits(), diff_words(), DIFFBUFSIZ, LONG, max, and pack_chunk().

{ 
int             chunksiz, packsiz, nbits, next_nbits, tot_nbits;
LONG            buffer[DIFFBUFSIZ];
LONG            *diffs = buffer;
LONG            *end = diffs - 1;
LONG            done = 0;

        while(done < (x * y)) {
          
            end = diff_words(img, x, y, buffer, done);
            done += (end - buffer) + 1;

            diffs = buffer;
            while(diffs <= end) {
              
                packsiz = 0;
                chunksiz = 1;
                nbits = bits(diffs, 1);
                while(packsiz == 0) {
                  
                    if(end <= (diffs + chunksiz * 2))
                        packsiz = chunksiz;
                    else {
                
                          next_nbits = bits(diffs + chunksiz, chunksiz); 
                          tot_nbits = 2 * max(nbits, next_nbits);

                          if(tot_nbits >= (nbits + next_nbits + 6))
                              packsiz = chunksiz;
                          else {
                              
                                nbits = tot_nbits;
                                if(chunksiz == 64)
                                    packsiz = 128;
                                  else
                                    chunksiz *= 2;
                          }

                    }
                }

                if ( pack_chunk(diffs, packsiz, nbits / packsiz, fdesc) == 0)
                        return( 0 );
                diffs += packsiz;
             }
        }
        if ( pack_chunk(NULL, 0, 0, fdesc) == 0 );
                return( 1 );

        return( 1 );
}
static void unpack_word ( FILE *  packfile,
int  x,
int  y,
WORD *  img 
) [static]

Definition at line 296 of file pck.c.

References LONG, setbits, shift_left, shift_right, and WORD.

Referenced by get_pck().

{
int             valids = 0, spillbits = 0, usedbits, total = x * y;
LONG            window = 0L, spill, pixel = 0, nextint, bitnum, pixnum;
static int      bitdecode[8] = {0, 4, 5, 6, 7, 8, 16, 32};

    while (pixel < total) {
        if (valids < 6) {
          if (spillbits > 0) {
                window |= shift_left(spill, valids);
                valids += spillbits;
                spillbits = 0;
        }
        else {
                spill = (LONG) getc(packfile);
                spillbits = 8;
        }
    }
    else {
        pixnum = 1 << (window & setbits[3]);
        window = shift_right(window, 3);
        bitnum = bitdecode[window & setbits[3]];
        window = shift_right(window, 3);
        valids -= 6;
        while ((pixnum > 0) && (pixel < total)) {
                if (valids < bitnum) {
                        if (spillbits > 0) {
                                window |= shift_left(spill, valids);
                                if ((32 - valids) > spillbits) {
                                        valids += spillbits;
                                        spillbits = 0;
                                }
                                else {
                                        usedbits = 32 - valids;
                                        spill = shift_right(spill, usedbits);
                                        spillbits -= usedbits;
                                        valids = 32;
                                }
                        }
                        else {
                                spill = (LONG) getc(packfile);
                                spillbits = 8;
                        }
                }
                else {
                        --pixnum;
                        if (bitnum == 0) 
                                nextint = 0;
                        else {
                                nextint = window & setbits[bitnum];
                                valids -= bitnum;
                                window = shift_right(window, bitnum);
                                if ((nextint & (1 << (bitnum - 1))) != 0)
                                        nextint |= ~setbits[bitnum];}
                                if (pixel > x) {
                                        img[pixel] = (WORD) (nextint +
                                                (img[pixel-1] + img[pixel-x+1] +
                                                img[pixel-x] + img[pixel-x-1] + 2) / 4);
                                        ++pixel;
                                }
                                else if (pixel != 0) {
                                        img[pixel] = (WORD) (img[pixel - 1] + nextint);
                                        ++pixel;
                                }
                                else
                                        img[pixel++] = (WORD) nextint;
                        }
                }
        }
   }
}

Variable Documentation

const LONG setbits[33]
Initial value:
 {0x00000000L, 0x00000001L, 0x00000003L, 0x00000007L,
                          0x0000000FL, 0x0000001FL, 0x0000003FL, 0x0000007FL,
                          0x000000FFL, 0x000001FFL, 0x000003FFL, 0x000007FFL,
                          0x00000FFFL, 0x00001FFFL, 0x00003FFFL, 0x00007FFFL,
                          0x0000FFFFL, 0x0001FFFFL, 0x0003FFFFL, 0x0007FFFFL,
                          0x000FFFFFL, 0x001FFFFFL, 0x003FFFFFL, 0x007FFFFFL,
                          0x00FFFFFFL, 0x01FFFFFFL, 0x03FFFFFFL, 0x07FFFFFFL,
                          0x0FFFFFFFL, 0x1FFFFFFFL, 0x3FFFFFFFL, 0x7FFFFFFFL,
                          0xFFFFFFFFL}

Definition at line 29 of file pck.c.

Referenced by pack_longs(), and unpack_word().