Files
libgphoto2/camlibs/jd11/decomp.c
Arnaud Launay b9d58ca88b replace (c) and (C) by �
git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@5969 67ed7778-7388-44ab-90cf-0a291f65f57c
2002-12-15 11:45:10 +00:00

172 lines
4.3 KiB
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"
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];
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(char *compressed,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(line));
memset(lastline,0,sizeof(line));
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(char *compressed,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;
}
}