git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@5969 67ed7778-7388-44ab-90cf-0a291f65f57c
172 lines
4.3 KiB
C
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;
|
|
}
|
|
}
|