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