3dpcp/.svn/pristine/70/709c2a4e3cfa91c951dd223df9345344ace032c8.svn-base
2012-09-16 14:33:11 +02:00

153 lines
6 KiB
Text

/*
This is a Optical-Character-Recognition program
Copyright (C) 1999 Joerg Schulenburg
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
see README for EMAIL-address
*/
/* plan: use popen("ppm2pcx -packed ...","w"); for writing pcx */
#include <stdio.h>
#include <stdlib.h>
/* #include <assert.h> */
#include "pcx.h"
typedef unsigned char byte;
#define ERR(x) { fprintf(stderr,"ERROR "__FILE__" L%d: " x "\n",__LINE__);exit(1);}
int err;
/* --- needed for reading PCX-files */
unsigned char read_b(FILE *f1){
unsigned char c=0; c=fgetc(f1); if(feof(f1) || ferror(f1))err=1; return c;
}
/* something here is wrong! */
void readpcx(char *name,pix *p,int vvv){ /* see pcx.format.txt */
int page,pages,nx,ny,i,j,b,x,y,bpl,bits,pal[256][3];
FILE *f1;
unsigned char *pic,h[128],bb,b1,b2,b3;
err=0;
for(i=0;i<256;i++)for(j=0;j<3;j++)pal[i][j]=i;
f1=fopen(name,"rb"); if(!f1) ERR("open");
if(fread(h,1,128,f1)!=128)ERR("read PCX header"); /* 128 Byte lesen -> h[] */
if(h[0]!=10)ERR("no ZSoft sign"); /* ZSoft sign */
if(h[2]> 1)ERR("unknown coding"); /* run length encoding */
bits = h[3]; /* 1 or 8 */
if(bits!=1 && bits!=8)ERR("only 1 or 8 bits supported");
nx = h[ 9]*256+h[ 8] - h[ 5]*256-h[ 4] +1; /* Xmax-Xmin */
ny = h[11]*256+h[10] - h[ 7]*256-h[ 6] +1; /* Ymax-Ymin */
pages=h[65]; bpl=h[66]+256*h[67]; /* bytes per line */
if(vvv)
fprintf(stderr,"# PCX version=%d bits=%d x=%d y=%d HRes=%d VRes=%d\n"
"# NPlanes=%d BytesPerLine=%d Palette=%s",
h[1],bits,nx,ny,h[12]+256*h[13],h[14]+256*h[15],
pages,bpl,((h[68]==1)?"1=color/bw":"2=gray"));
/* line1(NP=4): RRRRR...,GGGG....,BBBBB...,IIII...., line2: RRRR...,GGGG.... */
/* C4 EF = (C4&3F)*EF = EF EF EF EF */
fflush(stdout);
/* palette: for(i=0;i<16;i++) for(j=0;j<3;j++) h[16+3*i+j] */
if(pages>1)for(b=0;b<16;b++) for(i=0;i<16;i++)
for(j=0;j< 3;j++) pal[b*16+i][j]=h[16+3*i+j]>>2;
if(bits>7){
fseek(f1,-3*256,2); if(fread(pal,3,256,f1)!=256)ERR("read palette");
for(i=0;i<256;i++) for(j=0;j<3;j++) pal[i][j]>>=2;
}
fseek(f1,128,0);
pic=(unsigned char *)malloc( nx*ny );
if(pic==NULL)ERR("no memory"); /* no memory */
x=y=0;
do {
for(page=0;page<pages;page++) /* 192 == 0xc0 => b1=counter */
do {
b1=1; bb=read_b(f1); b2=bb; if(b1==192)fprintf(stderr,"?");
if((b2>=192) && (h[2]==1)){b1=b2&63;bb=read_b(f1);b2=bb;}
if(err){fprintf(stderr,"\nread error x=%d y=%d\n",x,y);x=nx;y=ny;break;}
for(b3=0;b3<b1;b3++)for(b=0;b<8;b+=bits,x++)if(x<nx){
bb=(b2>>(8-bits-b)) & ~((~0)<<bits);
if(bits==1 && bb==1) bb=240;
if(page==0) pic[x+nx*y] =(byte)bb;
else pic[x+nx*y]|=(byte)bb<<(page*bits);
}
} while(x<(9-bits)*bpl); x=0; y++;
} while(y<ny);
/* */
fclose(f1);
p->p=pic; p->x=nx; p->y=ny; p->bpp=1;
if(vvv)fprintf(stderr,"\n");
}
/* -----------------------------------------------------------------------
// write bmp 8bit palette no RLE
// bit 2+3 used for color coding (markers)
// replaced by writeppm (ppm.gz) and is obsolate now, removed later
*/
void writebmp(char *name,pix p,int vvv){ /* see pcx.format.txt */
int nx,ny,i,y,rest[4]={0,0,0,0};
FILE *f1;
/*FIXME jb static*/static unsigned char *pic, h[54+4*256];
long fs,fo,hs,is; /* filesize, offset, headersize, imagesize */
nx=p.x; ny=p.y; pic=p.p;
if (nx&3) nx+=4-(nx&3); /* must be mod4 ? */
hs=40; /* bmi headersize fix */
is=nx*ny; /* imagesize */
fo=14+hs+4*256;
fs=fo+is;
for(i=0;i<54;i++){ h[i]=0; }
/* BITMAPFILEHEADER */
h[ 0]='B'; h[ 1]='M'; /* type of file BMP */
h[ 2]= fs &255; h[ 3]=(fs>> 8)&255;
h[ 4]=(fs>>16)&255; h[ 5]=(fs>>24)&255; /* size of file */
h[10]= fo &255; h[11]=(fo>> 8)&255;
h[12]=(fo>>16)&255; h[13]=(fo>>24)&255; /* offset to image data */
/* BITMAPINFO (BITMAPCOREHEADER not used here) */
/* 14 - HEADER */
h[14]= hs &255; h[15]=(hs>> 8)&255;
h[16]=(hs>>16)&255; h[17]=(hs>>24)&255; /* bmi-header size */
h[18]= nx &255; h[19]=(nx>> 8)&255;
h[20]=(0l>>16)&255; h[21]=(0l>>24)&255; /* WIDTH/pixel */
h[22]= ny &255; h[23]=(ny>> 8)&255;
h[24]=(0l>>16)&255; h[25]=(0l>>24)&255; /* HIGH/pixel */
h[26]=1; /* planes */
h[28]=8; /* bits/pixel 1,4,8,24 */
h[30]=0; /* compression */
h[34]= is &255; h[35]=(is>> 8)&255;
h[36]=(is>>16)&255; h[37]=(is>>24)&255; /* sizeImage (can be 0 if ~RLE) */
h[38]=0;h[39]=1; /* ca 100dpi, x/meter */
h[42]=0;h[43]=1; /* y/meter */
h[46]=0;h[47]=1; /* colorused (0=maximum) */
h[50]=0;h[51]=1; /* colorimportand (0=all) */
/* 54 - endofheader */
for(i=0;i<256;i++){
h[54+4*i+0]=((~((i & 2)*64)) & (i & (128+64)))|63;
h[54+4*i+1]=((~((i & 2)*64)) & (~((i & 4)*32)) & (i & (128+64)))|63;
h[54+4*i+2]=( ((i & 2)* 8) | ((~((i & 4)*32)) & (i & (128+64)))|63);
} /* blue-green-red */
f1=fopen(name,"wb"); if(!f1) fprintf(stderr," error opening file\n");
if(!f1)ERR("open"); /* open-error */
if(fwrite(h,1,54+4*256,f1)!=54+4*256)ERR("write head");
if(vvv) fprintf(stderr,"# write BMP x=%d y=%d\n",nx,ny);
for(y=ny-1;y>=0;y--){
if(((int)fwrite(pic+p.x*y,1,p.x,f1))!=p.x)ERR("write");
if(nx>p.x)
if(((int)fwrite(rest,1,nx-p.x,f1))!=nx-p.x)ERR("write");
}
fclose(f1);
}
/* ---------------------------------------------------------------------- */