1 /*
2  * Jenoptik JD11 Camera Driver
3  * Copyright 1999-2001 Marcus Meissner <marcus@jet.franken.de>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA  02110-1301  USA
19  */
20 
21 #include "config.h"
22 #include <stdio.h>
23 #include <string.h>
24 #include <assert.h>
25 #include <stdlib.h>
26 
27 #include "decomp.h"
28 
29 struct chain { int 	left,val,right; };
30 struct compstate {
31     unsigned char	curmask;
32     unsigned char	bytebuf;
33     unsigned char	*byteptr;
34 
35     struct chain	cl[200];
36     int			stackstart;
37 };
38 
39 /* FLOAT_QUERY: 0.860000 1.030000 1.150000. */
40 
41 /********************************************************/
42 /* The bit stage                                        */
43 /********************************************************/
44 static inline int
jd11_getbit(struct compstate * cs)45 jd11_getbit(struct compstate *cs) {
46     int	ret;
47     if (cs->curmask == 0x80)
48 	cs->bytebuf = *cs->byteptr++;
49     ret = cs->curmask & cs->bytebuf;
50     cs->curmask >>=1;
51     if (!cs->curmask) cs->curmask = 0x80;
52     return !!ret;
53 }
54 
55 /********************************************************/
56 /* The huffman compressor stage                         */
57 /********************************************************/
58 static int
decomp_1byte(struct compstate * cs)59 decomp_1byte(struct compstate *cs) {
60     int	xcs = cs->stackstart;
61     int	xbit;
62 
63     while ((cs->cl[xcs].left>=0) && (cs->cl[xcs].right>=0)) {
64 	xbit = jd11_getbit(cs);
65 	if (xbit)
66 	    xcs = cs->cl[xcs].left;
67 	else
68 	    xcs = cs->cl[xcs].right;
69     }
70     return cs->cl[xcs].val;
71 }
72 
73 static void
build_huffmann_tree(struct compstate * cs)74 build_huffmann_tree(struct compstate *cs) {
75 	int	xstack[200];
76 	unsigned int	i;
77 	int	curcl=0,curstack=0;
78 	const int df[] = {
79 	    -180,180,1000,-90,1000,90,1000,-45,1000,45,1000,-20,1000,
80 	     20,1000,-11,1000,11,1000,-6,1000,2,1000,6,-2,1000,1000
81 	};
82 	for (i=0;i<sizeof(df)/sizeof(df[0]);i++) {
83 		if (df[i]!=1000) {
84 			cs->cl[curcl].left = -1;
85 			cs->cl[curcl].right = -1;
86 			cs->cl[curcl].val = df[i];
87 		} else {
88 			cs->cl[curcl].right	= xstack[--curstack];
89 			cs->cl[curcl].left	= xstack[--curstack];
90 		}
91 		xstack[curstack++] = curcl++;
92 	}
93 	cs->stackstart = xstack[0];
94 }
95 
96 #define F1	0.5
97 #define F2	0.0
98 #define F3	0.5
99 #define F4	0.0
100 
101 void
picture_decomp_v1(unsigned char * compressed,unsigned char * uncompressed,int width,int height)102 picture_decomp_v1(unsigned char *compressed,unsigned char *uncompressed,int width,int height) {
103 	struct	compstate cs;
104 	unsigned char xbyte;
105 	int	i=0,curbyte=0,diff,lastval;
106 	int	*line,*lastline;
107 
108 	cs.curmask = 0x80; cs.bytebuf = 0; cs.byteptr = compressed;
109 
110 	build_huffmann_tree(&cs);
111 
112 	line	= (int*)malloc(sizeof(int)*width);
113 	lastline= (int*)malloc(sizeof(int)*width);
114 	curbyte=0;
115 	memset(line,0,sizeof(int)*width);
116 	memset(lastline,0,sizeof(int)*width);
117 	for (i=0;i<width;i++) {
118 		diff = decomp_1byte(&cs);
119 		curbyte+=diff;
120 		xbyte = curbyte;
121 		if (curbyte>255) xbyte = 255;
122 		if (curbyte<0) xbyte = 0;
123 
124 		*uncompressed++=xbyte;
125 
126 		line[i] = curbyte;
127 	}
128 	height--;
129 	while (height--) {
130 		lastval = line[0]; /* just before the copy */
131 		memcpy(lastline,line,width*sizeof(int));
132 		memset(line,0,width*sizeof(int));
133 		for (i=0;i<width;i++) {
134 			diff = decomp_1byte(&cs);
135 			line[i]=diff+lastval;
136 			if (i<width-2) {
137 				lastval = (int)((lastline[i+2]*F4+lastline[i]*F2+lastline[i+1]*F1+line[i]*F3));
138 			} else {
139 				if (i==width-2)
140 					lastval = (int)(lastline[i]*F2+lastline[i+1]*F1+line[i]*F3);
141 				else
142 					lastval = line[i];
143 			}
144 
145 			xbyte = line[i];
146 			if (line[i]>255) xbyte = 255;
147 			if (line[i]<0)	 xbyte = 0;
148 			*uncompressed++=xbyte;
149 		}
150 	}
151 	free (lastline);
152 	free (line);
153 }
154 
155 /* Just blow up the picture from 6 bit uncompressed to 8 bit uncompressed */
156 void
picture_decomp_v2(unsigned char * compressed,unsigned char * uncompressed,int width,int height)157 picture_decomp_v2(unsigned char *compressed,unsigned char *uncompressed,int width,int height) {
158 	struct	compstate cs;
159 	int	i,j;
160 	unsigned char xbyte;
161 
162 	cs.curmask = 0x80; cs.bytebuf = 0; cs.byteptr = compressed;
163 	for (i=width*height;i--;) {
164 		unsigned char xmask = 0x80;
165 		xbyte = 0;
166 		for (j=6;j--;) {
167 			if (jd11_getbit(&cs))
168 				xbyte|=xmask;
169 			xmask>>=1;
170 		}
171 		*uncompressed++=xbyte;
172 	}
173 }
174