source: abuse/tags/pd/macabuse/imlib/pcxread.c @ 608

Last change on this file since 608 was 49, checked in by Sam Hocevar, 15 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 5.1 KB
Line 
1#include "pcxread.hpp"
2#include "specs.hpp"
3
4struct PCX_header_type
5{
6  char manufactururer,version,encoding,bits_per_pixel;
7  short xmin,ymin,xmax,ymax,hres,vres;
8  char palette[48];
9  char reserved,color_planes;
10  short bytes_per_line,palette_type;
11  char filter[58];
12} PCX_header;
13
14int read_PCX_header(FILE *fp)
15{
16  if (!fread(&PCX_header.manufactururer,1,1,fp)) return 0; 
17  if (!fread(&PCX_header.version,1,1,fp)) return 0; 
18  if (!fread(&PCX_header.encoding,1,1,fp)) return 0; 
19  if (!fread(&PCX_header.bits_per_pixel,1,1,fp)) return 0; 
20  PCX_header.xmin=read_short(fp);
21  PCX_header.ymin=read_short(fp); 
22  PCX_header.xmax=read_short(fp);
23  PCX_header.ymax=read_short(fp);
24  PCX_header.hres=read_short(fp);
25  PCX_header.vres=read_short(fp);
26  if (!fread(PCX_header.palette,1,48,fp)) return 0;
27  if (!fread(&PCX_header.reserved,1,1,fp)) return 0;
28  if (!fread(&PCX_header.color_planes,1,1,fp)) return 0;
29  PCX_header.bytes_per_line=read_short(fp);
30  PCX_header.palette_type=read_short(fp);
31  if (!fread(PCX_header.filter,1,58,fp)) return 0;
32  return 1;
33}
34
35int write_PCX_header(FILE *fp)
36{
37  if (!fwrite(&PCX_header.manufactururer,1,1,fp)) return 0; 
38  if (!fwrite(&PCX_header.version,1,1,fp)) return 0; 
39  if (!fwrite(&PCX_header.encoding,1,1,fp)) return 0; 
40  if (!fwrite(&PCX_header.bits_per_pixel,1,1,fp)) return 0; 
41  write_short(fp,PCX_header.xmin);
42  write_short(fp,PCX_header.ymin); 
43  write_short(fp,PCX_header.xmax);
44  write_short(fp,PCX_header.ymax);
45  write_short(fp,PCX_header.hres);
46  write_short(fp,PCX_header.vres);
47  if (!fwrite(PCX_header.palette,1,48,fp)) return 0;
48  if (!fwrite(&PCX_header.reserved,1,1,fp)) return 0;
49  if (!fwrite(&PCX_header.color_planes,1,1,fp)) return 0;
50  write_short(fp,PCX_header.bytes_per_line);
51  write_short(fp,PCX_header.palette_type);
52  if (!fwrite(PCX_header.filter,1,58,fp)) return 0;
53  return 1;
54}
55
56
57
58PCX_type PCX_file_type(char *filename)
59{
60  FILE *fp=fopen(filename,"rb"); 
61  if (!fp)
62  { set_error(imREAD_ERROR); 
63    return not_PCX;
64  }
65 
66  if (!read_PCX_header(fp))     
67  {
68    fclose(fp);   
69    set_error(imREAD_ERROR); 
70    return not_PCX;   
71  }
72  fclose(fp);     
73  if (PCX_header.manufactururer!=10)
74    return not_PCX; 
75  if (PCX_header.color_planes==3 && PCX_header.bits_per_pixel==8)
76    return PCX_24;
77  else if (PCX_header.color_planes==1 && PCX_header.bits_per_pixel==8)
78    return PCX_8;
79  else return not_PCX;   
80}
81
82void read_PCX_line(FILE *fp, unsigned char *start, short skip, int width)
83{
84  int c,n=0,i;
85 
86  do
87  {
88    c=fgetc(fp)&0xff;
89    if ((c&0xc0)==0xc0)
90    {
91      i=c&0x3f;
92      c=fgetc(fp);
93      while (i--)
94      {
95        *start=c;
96        start+=skip;
97        n++;   
98      }
99    }
100    else
101    {
102      *start=c;
103      start+=skip;
104      n++;
105    }   
106  } while (n<width);   
107}
108
109
110image24 *read_PCX24(char *filename)
111{
112  if (PCX_file_type(filename)!=PCX_24) return NULL; 
113  FILE *fp=fopen(filename,"rb");
114  read_PCX_header(fp); 
115  image24 *im=new image24(PCX_header.xmax-PCX_header.xmin+1,
116                          PCX_header.ymax-PCX_header.ymin+1);
117  int y;
118  for (y=0;y<im->height();y++)
119  {
120    read_PCX_line(fp,im->scan_line(y),3,PCX_header.bytes_per_line);
121    read_PCX_line(fp,im->scan_line(y)+1,3,PCX_header.bytes_per_line);
122    read_PCX_line(fp,im->scan_line(y)+2,3,PCX_header.bytes_per_line);   
123  }
124  fclose(fp);
125  return im; 
126}
127
128image *read_PCX(char *filename, palette *&pal)
129{
130  if (PCX_file_type(filename)!=PCX_8) return NULL; 
131  FILE *fp=fopen(filename,"rb");
132  read_PCX_header(fp);
133 
134  image *im=new image(PCX_header.xmax-PCX_header.xmin+1,
135                      PCX_header.ymax-PCX_header.ymin+1);
136  int y;
137  for (y=0;y<im->height();y++)
138    read_PCX_line(fp,im->scan_line(y),1,PCX_header.bytes_per_line);
139  unsigned char palette_confirm; 
140  if (!fread(&palette_confirm,1,1,fp) || palette_confirm!=12)
141  {   
142    pal=new palette;
143    pal->defaults();
144  }
145  else
146  {
147    pal=new palette;
148    fread(pal->addr(),1,256*3,fp);
149  }
150  fclose(fp);
151  return im; 
152
153
154void write_PCX(image *im, palette *pal, char *filename)
155{
156  FILE *fp=fopen(filename,"wb");
157  if (!fp)
158  {
159    set_error(imWRITE_ERROR);
160    return ;
161  }
162 
163 
164  PCX_header.manufactururer=10; 
165  PCX_header.version=5; 
166  PCX_header.encoding=1;
167  PCX_header.bits_per_pixel=8;
168  PCX_header.xmin=0;
169  PCX_header.ymin=0;
170  PCX_header.xmax=im->width()-1;
171  PCX_header.ymax=im->height()-1;
172  PCX_header.hres=320;
173  PCX_header.vres=200;
174  PCX_header.reserved=0;
175  PCX_header.color_planes=1;
176  PCX_header.bytes_per_line=im->width();
177  PCX_header.palette_type=0;
178  memset(PCX_header.filter,0,58);
179
180
181  if (!write_PCX_header(fp))
182  {
183    set_error( imWRITE_ERROR);
184    return ; 
185  }
186 
187  int y,run_length,x;
188  unsigned char *sl,code; 
189  for (y=0;y<im->height();y++)
190  {
191    sl=im->scan_line(y);
192    for (x=0;x<im->width();)
193    {
194      run_length=1;     
195      while (x+run_length<im->width() && sl[x]==sl[x+run_length])
196        run_length++;
197      if (run_length==1 && sl[x]<64)
198        fputc(sl[x],fp);     
199      else
200      {
201        if (run_length>=64)
202          run_length=63;
203        code=0xc0 | run_length;
204        fputc(code,fp);
205        fputc(sl[x],fp);
206       
207      }     
208      x+=run_length;
209     
210    }   
211  }
212  fputc(12,fp);  // note that there is a palette attached
213  fwrite(pal->addr(),1,256*3,fp);
214  fclose(fp);   
215}
216
217
218
Note: See TracBrowser for help on using the repository browser.