Logo Search packages:      
Sourcecode: libgphoto2 version File versions  Download package

decomp.c

/*
 * Jenoptik JD11 Camera Driver
 * Copyright  1999-2001 Marcus Meissner <marcus@jet.franken.de>
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "config.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include <unistd.h>

#include "decomp.h"

00030 struct chain { int      left,val,right; };
00031 struct compstate {
    unsigned char curmask;
    unsigned char bytebuf;
    unsigned char *byteptr;

    struct chain  cl[200];
    int                 stackstart;
};

/* FLOAT_QUERY: 0.860000 1.030000 1.150000. */

/********************************************************/
/* The bit stage                                        */
/********************************************************/
static inline int
jd11_getbit(struct compstate *cs) {
    int     ret;
    if (cs->curmask == 0x80)
      cs->bytebuf = *cs->byteptr++;
    ret = cs->curmask & cs->bytebuf;
    cs->curmask >>=1;
    if (!cs->curmask) cs->curmask = 0x80;
    return !!ret;
}

/********************************************************/
/* The huffman compressor stage                         */
/********************************************************/
static int
decomp_1byte(struct compstate *cs) {
    int     xcs = cs->stackstart;
    int     xbit;

    while ((cs->cl[xcs].left>=0) && (cs->cl[xcs].right>=0)) {
      xbit = jd11_getbit(cs); 
      if (xbit)
          xcs = cs->cl[xcs].left;
      else
          xcs = cs->cl[xcs].right;
    }
    return cs->cl[xcs].val;
}

static void
build_huffmann_tree(struct compstate *cs) {
      int   xstack[200];
      int   i,curcl=0,curstack=0;
      const int df[] = {
          -180,180,1000,-90,1000,90,1000,-45,1000,45,1000,-20,1000,
           20,1000,-11,1000,11,1000,-6,1000,2,1000,6,-2,1000,1000
      };
      for (i=0;i<sizeof(df)/sizeof(df[0]);i++) {
            if (df[i]!=1000) {
                  cs->cl[curcl].left = -1;
                  cs->cl[curcl].right = -1;
                  cs->cl[curcl].val = df[i];
            } else {
                  cs->cl[curcl].right     = xstack[--curstack];
                  cs->cl[curcl].left      = xstack[--curstack];
            }
            xstack[curstack++] = curcl++;
      }
      cs->stackstart = xstack[0];
}

#define F1  0.5
#define F2  0.0
#define F3  0.5
#define F4  0.0

void
picture_decomp_v1(unsigned char *compressed,unsigned char *uncompressed,int width,int height) {
      struct      compstate cs;
      unsigned char xbyte;
      int   i=0,curbyte=0,diff,lastval;
      int   *line,*lastline;

      cs.curmask = 0x80; cs.bytebuf = 0; cs.byteptr = compressed;

      build_huffmann_tree(&cs);

      line  = (int*)malloc(sizeof(int)*width);
      lastline= (int*)malloc(sizeof(int)*width);
      curbyte=0;
      memset(line,0,sizeof(int)*width);
      memset(lastline,0,sizeof(int)*width);
      for (i=0;i<width;i++) {
            diff = decomp_1byte(&cs);
            curbyte+=diff;
            xbyte = curbyte;
            if (curbyte>255) xbyte = 255;
            if (curbyte<0) xbyte = 0;

            *uncompressed++=xbyte;

            line[i] = curbyte;
      }
      height--;
      while (height--) {
            lastval = line[0]; /* just before the copy */
            memcpy(lastline,line,width*sizeof(int));
            memset(line,0,width*sizeof(int));
            for (i=0;i<width;i++) {
                  diff = decomp_1byte(&cs);
                  line[i]=diff+lastval;
                  if (i<width-2) {
                        lastval = (int)((lastline[i+2]*F4+lastline[i]*F2+lastline[i+1]*F1+line[i]*F3));
                  } else {
                        if (i==width-2)
                              lastval = (int)(lastline[i]*F2+lastline[i+1]*F1+line[i]*F3);
                        else
                              lastval = line[i];
                  }

                  xbyte = line[i];
                  if (line[i]>255) xbyte = 255;
                  if (line[i]<0)     xbyte = 0;
                  *uncompressed++=xbyte;
            }
      }
}

/* Just blow up the picture from 6 bit uncompressed to 8 bit uncompressed */
void
picture_decomp_v2(unsigned char *compressed,unsigned char *uncompressed,int width,int height) {
      struct      compstate cs;
      int   i,j;
      unsigned char xbyte;

      cs.curmask = 0x80; cs.bytebuf = 0; cs.byteptr = compressed;
      for (i=width*height;i--;) {
            unsigned char xmask = 0x80;
            xbyte = 0;
            for (j=6;j--;) {
                  if (jd11_getbit(&cs))
                        xbyte|=xmask;
                  xmask>>=1;
            }
            *uncompressed++=xbyte;
      }
}

Generated by  Doxygen 1.6.0   Back to index