⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldrawpic.cpp

📁 ldraw_DOS游戏开发包
💻 CPP
字号:
#include <ldraw.h>
#include <stdio.h>
#include <dos.h>
#include <string.h>

char *lrPicFile(char *picname,long offset,RGB *pal);
char  lsPcxFile(char *img,char *fname,RGB *pal);
/**************************************************************************/
static char *lrPcxFile(char *filename,long off,RGB *pal);
static char *lrBmpFile(char *filename,long off,RGB *pal);
static char *lrGifFile(char *filename,long off,RGB *pal);

char *lrPicFile(char *picname,long offset,RGB *pal)
{ short ret; uchar flag[2]; FILE *f; char *p;

  ldraw_error=0;
  if ((f=fopen(picname,"rb"))==NULL) {
     ldraw_error=LERR_NOTFIND;
     return NULL;
  }
  fseek(f,offset,SEEK_SET); fread(flag,1,2,f); fclose(f);
  if (flag[0]==0x0a&&flag[1]==0x05) p=lrPcxFile(picname,offset,pal);
     else
  if (flag[0]==0x42&&flag[1]==0x4d) p=lrBmpFile(picname,offset,pal);
     else
  if (flag[0]==0x47&&flag[1]==0x49) p=lrGifFile(picname,offset,pal);
     else { p=NULL; ldraw_error=LERR_UNKNOW; }
  return p;
}
/////////////////  PCX FILE OPERATION  ////////////////////////////////////
struct PcxHeader
{
  char manufacturer;    /* Always set to 10 */
  char version;         /* Always 5 for 256-color files */
  char encoding;        /* Always set to 1 */
  char bits_per_pixel;  /* Should be 8 for 256-color files */
  short xmin,ymin;      /* Coordinates for top left corner */
  short xmax,ymax;      /* Width and height of image */
  short hres;           /* Horizontal resolution of image */
  short vres;           /* Vertical resolution of image */
  char palette16[48];   /* EGA palette; not used for 256-color files */
  char reserved;        /* Reserved for future use */
  char color_planes;    /* Color planes */
  short bytes_per_line; /* Number of bytes in 1 line of pixels */
  short palette_type;   /* Should be 2 for color palette */
  char filler[58];      /* Nothing but junk */
};

struct PcxFile
{
  PcxHeader hdr;
  char *bitmap;
  char pal[768];
  int imagebytes,width,height;
};

enum {NORMAL=0,RLE=1,WRITE=2};

char  lsPcxFile(char *img,char *fname,RGB *pal)
{ PcxHeader *h; short len,wid,j; long size,i; char *p;
  static char myflag[30]="by Lin Wei Volunteer inc.2000";
  FILE *f; uchar abyte,nbytes=1,mode=NORMAL,*pp; RGB *defpal;
  lgetSize(&len,&wid,img); size=len; size*=wid; p=img+4;
  f=fopen(fname,"wb"); if (!f) return 0;
  h=new PcxHeader; if (!h) { fclose(f); return 0; }
  defpal=new RGB[256]; if (!defpal) { delete h; fclose(f); return 0; }
  memset(h,0,sizeof(PcxHeader)); lloadPal(defpal);

  h->manufacturer=10; h->version=5;
  h->encoding=1; h->bits_per_pixel=8; 
  h->xmin=0,h->ymin=0,h->xmax=len-1,h->ymax=wid-1;
  h->hres=0,h->vres=0; h->reserved=0; h->color_planes=1;
  h->bytes_per_line=len; h->palette_type=1;
  strcpy(h->filler,myflag); fwrite(h,sizeof(PcxHeader),1,f);
  for (j=0;j<wid;p+=len,j++)
    for (i=0;i<len;i++)
    { abyte=p[i]; 
      if (i<len-1&&abyte==p[i+1]&&nbytes<63) nbytes++; else mode=WRITE; 
      if (mode==WRITE) { 
        if (nbytes==1&&abyte<0xbf) fputc(abyte,f);
         else { fputc(0xc0|nbytes,f); fputc(abyte,f); }
        mode=NORMAL; nbytes=1;
      }
    } 
  fputc(0x0c,f); if (pal) pp=(uchar*)pal; else pp=(uchar*)defpal;
  for (i=0;i<256*3;pp++,i++) fputc((*pp)<<2,f);
  fclose(f); delete defpal,h;
  return 1;
}
static char *lrPcxFile(char *filename,long off,RGB *pal)
{     long i;
      int mode=NORMAL,nbytes,j=0;
      char abyte,*p,*img;
      FILE *f; PcxFile pcx1, *pcx=&pcx1;

      f=fopen(filename,"rb");
      if(f==NULL)
	{ pcx->bitmap = NULL;
	  ldraw_error=LERR_NOTFIND;
          return NULL;
	}
      fseek(f,off,SEEK_SET);
      fread(&pcx->hdr,sizeof(PcxHeader),1,f);
      pcx->width=1+pcx->hdr.xmax-pcx->hdr.xmin;
      pcx->height=1+pcx->hdr.ymax-pcx->hdr.ymin;
      pcx->imagebytes=(unsigned int)(pcx->width*pcx->height);

      p=new char[pcx->width*pcx->height+8]; img=p;
      if (!p) { 
         fclose(f); 
         ldraw_error=LERR_NOMEM;
         return NULL; 
      }
      *(short*)p = pcx->width;  p+=2;
      *(short*)p = pcx->height; p+=2;

      pcx->bitmap=p;
      for(i=0;i<pcx->imagebytes;i++,p++)
      {
	if(mode == NORMAL)
	{
	  abyte=fgetc(f);
	  if((unsigned char)abyte > 0xbf)
	  { nbytes=abyte & 0x3f; abyte=fgetc(f);
	    if(--nbytes > 0) mode=RLE;
	  }
	} else if(--nbytes == 0) mode=NORMAL;
	*p=abyte; 
      } 
      lsetHotXY(0,0,img);

      while ( !feof(f) && fgetc(f)!=0x0c );
      if (pal==NULL) { fclose(f); return img; }
      fread(pal,768,1,f);
      p=(char*)pal;
      for(i=0;i<768;i++)            // bit shift palette
	*p++=*p >>2;
      fclose(f);
      return img;                // return success
}


/////////////////  BMP FILE OPERATION  ////////////////////////////////////
static char *lrBmpFile(char *filename,long off,RGB *pal)
{ FILE *f; char *p,r,g,b,*img;
  short i,j,palCount,bit; int wByte, wPixel, h, len, wid;

  if ((f=fopen(filename,"rb"))==NULL) {
     ldraw_error=LERR_NOTFIND;
     return NULL;
  }

  fseek(f,2+off,SEEK_SET); fread(&wByte,4,1,f);
  fseek(f,10+off,SEEK_SET); fread(&wPixel,4,1,f);
  wByte-=wPixel; palCount=(wPixel-54)/4;
  fseek(f,18+off,SEEK_SET); fread(&wPixel,4,1,f);
  fread(&h,4,1,f); wByte/=h; len=wPixel; wid=h;

  p=new char[len*wid+8]; img=p;
  if (!p) { 
     fclose(f); ldraw_error=LERR_NOMEM;
     return NULL; 
  }
  *(short*)p=len; p+=2;
  *(short*)p=wid; p+=2; 

  fseek(f,2,SEEK_CUR); bit=fgetc(f)+(int)fgetc(f)*256; 
  fseek(f,54+off,SEEK_SET);

  for (i=0;i<palCount;i++) { 
      fscanf(f,"%c%c%c%*c",&b,&g,&r);
      if (pal) { pal[i].r=r>>2; pal[i].g=g>>2; pal[i].b=b>>2; }
  } p+=(int)len*(wid-1);
  for (i=0;i<wid;i++,p-=len) {
      for (j=0;j<len;j++) p[j]=j%256;
      fread(p,1,len,f); 
  }
  fclose(f); lsetHotXY(0,0,img);
  ldraw_error=LERR_NONE;
  return img;
}
////////////////////// Gif File Access Functions //////////////////////
static int   pack_mgetw(FILE *f);
static int   pack_igetw(FILE *f);
static void  select_palette(RGB *);
static void  unselect_palette();

#define pack_fseek(f,off) fseek(f,off,SEEK_CUR)

static struct
{
	short base;
	char  new_c;
	short length;
} str[4096];

static FILE *f;
static int empty_string, curr_bit_size, bit_overflow;
static int bit_pos, data_pos, data_len, entire, code;
static int cc, string_length, i, bit_size;
static unsigned char string[4096];
static LSURFACE *bmp;
static int image_x, image_y, image_w, image_h, x, y;
static int interlace, gif_len, gif_wid, gif_error;


void clear_table(void)
{
	empty_string = cc + 2;
	curr_bit_size = bit_size + 1;
	bit_overflow = 0;
}


static void get_code(void)
{
	if(bit_pos + curr_bit_size > 8) {
		if(data_pos >= data_len) { data_len = fgetc(f); data_pos = 0; }
		entire = (fgetc(f) << 8) + entire;
		data_pos ++;
	}
	if(bit_pos + curr_bit_size > 16) {
		if(data_pos >= data_len) { data_len = fgetc(f); data_pos = 0; }
		entire = (fgetc(f) << 16) + entire;
		data_pos ++;
	}
	code = (entire >> bit_pos) & ((1 << curr_bit_size) - 1);
	if(bit_pos + curr_bit_size > 8)
		entire >>= 8;
	if(bit_pos + curr_bit_size > 16)
		entire >>= 8;
	bit_pos = (bit_pos + curr_bit_size) % 8;
	if(bit_pos == 0) {
		if(data_pos >= data_len) { data_len = fgetc(f); data_pos = 0; }
		entire = fgetc(f);
		data_pos ++;
	}
}


static void get_string(int num)
{
	if(num < cc)
	{
		string_length = 1;
		string[0] = str[num].new_c;
	}
	else
	{
		i = str[num].length;
		string_length = i;
		while(i > 0)
		{
			i --;
			string[i] = str[num].new_c;
			num = str[num].base;
		}
		/* if(num != -1) **-{[ERROR]}-** */
	}
}

static void output_string(void)
{       int lptr;
	for(i = 0; i < string_length; i ++)
	{       lptr=bmp->index[y]+x;
                if (lptr>=0&&lptr<gif_len*gif_wid) bmp->memory[lptr]=string[i];
                  else gif_error=1;
		x ++;
		if(x >= image_x + image_w)
		{
			x = image_x;
			y += interlace;
			if(interlace)
			{
				if(y >= image_y + image_h)
				{
					if(interlace == 8 && (y - image_y) % 8 == 0) {
						interlace = 8;
						y = image_y + 4;
					}
					else if(interlace == 8  && (y - image_y) % 8 == 4) {
						interlace = 4;
						y = image_y + 2;
					}
					else if(interlace == 4) {
						interlace = 2;
						y = image_y + 1;
					}
				}
			}
		}
	}
}

static int   pack_mgetw(FILE *f)
{ unsigned short w[2],i;
  for (i=0;i<2;i++) w[i]=fgetc(f); 
  return (unsigned)w[0]*256+w[1];
}
static long  pack_mgetl(FILE *f)
{ unsigned w[4],i; 
  for (i=0;i<4;i++) w[i]=fgetc(f); 
  return (w[0]*256+w[1])*65536L+w[2]*256+w[3];
}
static int   pack_igetw(FILE *f)
{ int b1,b2;
  b1=fgetc(f); b2=fgetc(f);
  return ( (b2<<8) | b1 );
}
static void  select_palette(RGB *)
{
}
static void  unselect_palette()
{
}
/* load_gif:
 *  Loads a 2-256 colour GIF file onto a bitmap, returning the bitmap
 *  structure and storing the pallete data in the specified pallete (this
 *  should be an array of at least 256 RGB structures).
 */
static char *lrGifFile(char *filename,long off,RGB *pal)
{
	int width, height, depth;
	int old;
        char *bmp2,*p;
        static LSURFACE my_bmp;
	int dest_depth;

	f = fopen(filename, "rb");
	if (!f) /* can't open file */
          { sprintf(lsys_message,"File not find\n");
	    return NULL;
          } sprintf(lsys_message,"Find file %s",filename);
        fseek(f,off,SEEK_SET);
	i  = pack_mgetw(f) << 8;
	i += fgetc(f);
	if(i != 0x474946) /* is it really a GIF? */
	{       sprintf(lsys_message,"It is not a gif file\n");
		fclose(f);
		return NULL;
	} sprintf(lsys_message,"It is a gif file\n");
	pack_fseek(f, 3); /* skip version */

	width = pack_igetw(f);
	height = pack_igetw(f);

        bmp2=new char[width*height+8]; 
        if (bmp2==NULL) {
           sprintf(lsys_message,"Not enough memory");
           fclose(f);
           return NULL;
        } p=bmp2; *(short*)p=width; p+=2; *(short*)p=height;
        lsetHotXY(0,0,bmp2); bmp=&my_bmp;
        lCreateSurface(width, height, bmp, bmp2+4, LSM_SHADOW);
        gif_error=0; gif_len=width; gif_wid=height;
        if(bmp->mode==0) {
                fclose(f); 
                sprintf(lsys_message,"Creating Surface error");
                return NULL;
        }
	lClearSurface(bmp,0);
        sprintf(lsys_message,"Ready to load");

	i = fgetc(f);
	if(i & 128) /* no global colour table? */
		depth = (i & 7) + 1;
	else
		depth = 0;

	pack_fseek(f, 2);	/* skip background colour and aspect ratio */

	if(pal && depth) /* only read palette if pal and depth are not 0 */
	{
		for(i = 0; i < (1 << depth); i ++)
		{
			pal[i].r = fgetc(f) / 4;
			pal[i].g = fgetc(f) / 4;
			pal[i].b = fgetc(f) / 4;
		}
	}
	else
		if(depth)
			pack_fseek(f, (1 << depth) * 3);

	do
	{
		i = fgetc(f);
		switch(i)
		{
			case 0x2C: /* Image Descriptor */
				image_x = pack_igetw(f);
				image_y = pack_igetw(f); /* individual image dimensions */
				image_w = pack_igetw(f);
				image_h = pack_igetw(f);

				i = fgetc(f);
				if(i & 64)
					interlace = 8;
				else
					interlace = 1;

				if(i & 128)
				{
					depth = (i & 7) + 1;
					if(pal)
					{
						for(i = 0; i < (1 << depth); i ++)
						{
							pal[i].r = fgetc(f) / 4;
							pal[i].g = fgetc(f) / 4;
							pal[i].b = fgetc(f) / 4;
						}
					}
					else
						pack_fseek(f, (1 << depth) * 3);
				}

				/* lzw stream starts now */
				bit_size = fgetc(f);
				cc = 1 << bit_size;

				/* initialise string table */
				for(i = 0; i < cc; i ++)
				{
					str[i].base = -1;
					str[i].new_c = i;
					str[i].length = 1;
				}

				/* initialise the variables */
				bit_pos = 0;
				data_len = fgetc(f); data_pos = 0;
				entire = fgetc(f); data_pos ++;
				string_length = 0; x = image_x; y = image_y;

				/* starting code */
				clear_table();
				get_code();
				if(code == cc)
					get_code();
				get_string(code);
				output_string();
				old = code;

				while(TRUE)
				{
					get_code();

					if(code == cc)
					{
						/* starting code */
						clear_table();
						get_code();
						get_string(code);
						output_string();
						old = code;
					}
					else if(code == cc + 1)
					{
						break;
					}
					else if(code < empty_string)
					{
						get_string(code);
						output_string();

						if(bit_overflow == 0) {
							str[empty_string].base = old;
							str[empty_string].new_c = string[0];
							str[empty_string].length = str[old].length + 1;
							empty_string ++;
							if(empty_string == (1 << curr_bit_size))
								curr_bit_size ++;
							if(curr_bit_size == 13) {
								curr_bit_size = 12;
								bit_overflow = 1;
							}
						}

						old = code;
					}
					else
					{
						get_string(old);
						string[str[old].length] = string[0];
						string_length ++;

						if(bit_overflow == 0) {
							str[empty_string].base = old;
							str[empty_string].new_c = string[0];
							str[empty_string].length = str[old].length + 1;
							empty_string ++;
							if(empty_string == (1 << curr_bit_size))
								curr_bit_size ++;
							if(curr_bit_size == 13) {
								curr_bit_size = 12;
								bit_overflow = 1;
							}
						}

						output_string();
						old = code;
					}
				}
				break;
			case 0x21: /* Extension Introducer */
				i = fgetc(f);
				if(i == 0xF9) /* Graphic Control Extension */
				{
					pack_fseek(f, 1); /* skip size (it's 4) */
					i = fgetc(f);
					if(i & 1) /* is transparency enabled? */
					{
						pack_fseek(f, 2);
						fgetc(f); /* transparent colour */
					}
					else
						pack_fseek(f, 3);
				}
				i = fgetc(f);
				while(i) /* skip Data Sub-blocks */
				{
					pack_fseek(f, i);
					i = fgetc(f);
				}
				break;
                        case   -1:
			case 0x3B: /* Trailer - end of data */
				fclose(f);
                                sprintf(lsys_message,"Load gif successful");
                                lDeleteSurface(bmp);
				return bmp2;
                                break;
		}
	} while(!gif_error);
        lDeleteSurface(bmp);
        delete bmp2;
	return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -