/* * Jenoptik JD11 Camera Driver * Copyright 1999-2001 Marcus Meissner * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #include "config.h" #include #include #include #include #include "decomp.h" struct chain { int left,val,right; }; 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]; unsigned int i; int 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;icl[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;i255) 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;i255) xbyte = 255; if (line[i]<0) xbyte = 0; *uncompressed++=xbyte; } } free (lastline); free (line); } /* 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; } }