📄 ibgdpixmapread.c
字号:
/* last edit: Ilja Schmelzer -------------- 28-FEB-1995 11:16:00.49 */
#include <stdio.h>
#include "ibg.h"
#include "ibglib.h"
#include "ibgoutput.h"
#include "ibgdpixmap.h"
/* assumes that a positive number follows. Reads and returns this number.
Returns -1 for other characters, -2 for EOF.
# as comment up to the end of line is allowed
*/
typedef struct{
char r;
char g;
char b;
}color;
static int getnumber(FILE *file)
{char cc;
int n;
beg:
cc = fgetc(file);
if(feof(file)) return -2;
if(cc=='#'){
do{
cc=fgetc(file);
if(feof(file)) return -2;
}while((cc != '\n'));
goto beg;
}
if((cc==' ')||(cc=='\t')||(cc=='\n')) goto beg;
n = 0;
do{
if((cc<'0')||(cc>'9')){
if((cc==' ')||(cc=='\t')||(cc=='\n')) return n;
return -1;
}
n *= 10; n += cc-'0';
cc = fgetc(file);
if(feof(file)) return n;
}while(n<100000);
return n;
}
int ibgdPixmapRead(ibgPixmap *p, int *colors, ibgColor *colmap, char *fname)
{unsigned char c0,cf,rr,gg,bb,ff;
unsigned char *cc,*prev,last;
color *m;
int f[3],fac,l1,l2,n,lines,rest,col,rc,i,j,k,c,c1,l,t,to,newt;
FILE* file = fopen(fname,"r");
if(file==NULL){
fprintf(stderr,"pixmap file %s not found\n",fname);
return ibgError;
}
c0 = fgetc(file);
cf = fgetc(file);
if((c0 != 'P')||(cf < '1') || (cf > '6')){
/* to include other graphic formats describing a true color picture
include here some other text reading this file format and go to colormap
*/
fprintf(stderr,"unknown format - currently only PBM implemented\n");
fprintf(stderr,"use f.e. xv to convert into PBM format\n");
return ibgError;
}
if((l1=getnumber(file)) < 0) goto error;
if((l2=getnumber(file)) < 0) goto error;
l = l1*l2;
m = malloc((l+5)*sizeof(color));
cc = malloc(l+5);
prev = malloc((*colors)+2);
switch(cf){
case '1':
for(i=0;i<l;i++){
n = getnumber(file);
if(n>0){
m[i].r = m[i].g = m[i].b = 0;
}else if(n==0){
m[i].r = m[i].g = m[i].b = 255;
}else{
goto error;
}
}
break;
case '2':
col = getnumber(file);
if(col>255) goto error;
if(col<255){
fac = (256/(col+1));
for(i=0;i<l;i++){
n = getnumber(file);
if(n>=0){
m[i].r = m[i].g = m[i].b = n*fac;
}else{
goto error;
}
}
}else{
for(i=0;i<l;i++){
n = getnumber(file);
if(n>=0){
m[i].r = m[i].g = m[i].b = n*255/col;
}else{
goto error;
}
}
}
break;
case '3':
col = getnumber(file);
if(col>255){ goto error;
}else if(col<255){fac = (256/(col+1));
for(i=0;i<l;i++){
m[i].r = getnumber(file)*fac;
if(m[i].r < 0) goto error;
m[i].g = getnumber(file)*fac;
if(m[i].g < 0) goto error;
m[i].b = getnumber(file)*fac;
if(m[i].b < 0) goto error;
}
}else{
for(i=0;i<l;i++){
m[i].r = getnumber(file);
if(m[i].r < 0) goto error;
m[i].g = getnumber(file);
if(m[i].g < 0) goto error;
m[i].b = getnumber(file);
if(m[i].b < 0) goto error;
}
}
break;
case '4':
lines = l/8;
rest = l%8; c = 0;
rc = fread(cc,1,lines+1,file);
for(i=0;i<lines;i++){
c1 = cc[i]; k=128;
for(j=0;j<8;j++){
if(c1 & k ){
m[c].r = m[c].g = m[c].b = 0;
}else{
m[c].r = m[c].g = m[c].b = 255;
}
c++; k /= 2;
}
}
for(j=0;j<rest;j++){
if(c1 & k ){
m[i].r = m[i].g = m[i].b = 0;
}else{
m[i].r = m[i].g = m[i].b = 255;
}
c++; k *= 2;
}
break;
case '5':
col = getnumber(file);
if(col > 255) goto error;
if(col < 255){fac = 256 / (col+1);
rc = fread(cc,sizeof(color),l,file);
for(i=0;i<l;i++){
m[i].r = m[i].g = m[i].b = cc[i]*fac;
}
}else{
rc = fread(cc,sizeof(color),l,file);
for(i=0;i<l;i++){
m[i].r = m[i].g = m[i].b = cc[i];
}
}
break;
case '6':
col = getnumber(file);
if(col > 255) goto error;
rc = fread(m,sizeof(color),l,file);
if(col < 255){fac = 256 / (col+1);
for(i=0;i<l;i++){
m[i].r *= fac;
m[i].g *= fac;
m[i].b *= fac;
}
}
break;
}
free(cc);
fclose(file);
/* now we have a true color pixmap. Now we create a colormap with maximal
number of colors defined by the initial value of colors:
*/
colormap:
ibgPixmapLx(*p) = l1;
ibgPixmapLy(*p) = l2;
ibgPixmapAlloc(*p);
f[0] = f[1] = f[2] = 1; ff = 1;
start:
c = 0; last = 255; newt=1;
for(i=l2-1;i>=0;i--){
for(j=0;j<l1;j++){
rr = m[c].r/f[0];
gg = m[c].g/f[1];
bb = m[c].b/f[2];
t = last;
while(t<255){
if(rr != colmap[t].r) {t = prev[to=t]; continue;}
if(gg != colmap[t].g) {t = prev[to=t]; continue;}
if(bb != colmap[t].b) {t = prev[to=t]; continue;}
break;
}
if(t==255){
t = newt; newt++;
if(newt>= *colors){
ff++; ff %= 3; f[ff] *= 2; goto start;
}
colmap[t].r = rr;
colmap[t].g = gg;
colmap[t].b = bb;
prev[t] = last; last = t;
}else if(t != last){
prev[to] = prev[t];
prev[t] = last; last = t;
}
ibgPixmapSegment(*p,j,i) = t;
c++;
}
}
*colors = newt;
for(t=1;t<*colors;t++){
colmap[t].r = ((colmap[t].r*f[0])*(((long unsigned)ibgColOn)+1))/256;
colmap[t].g = ((colmap[t].g*f[1])*(((long unsigned)ibgColOn)+1))/256;
colmap[t].b = ((colmap[t].b*f[2])*(((long unsigned)ibgColOn)+1))/256;
}
free(m);
free(prev);
fprintf(stderr,"pixmap file %s with %d x %d pixels and %d colors loaded\n",
fname,l1,l2,*colors-1);
return ibgSuccess;
error:
fprintf(stderr,"error reading pixmap file %s\n",fname);
return ibgError;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -