source: abuse/trunk/src/imlib/pcxread.cpp @ 124

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