📄 ldrawpic.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 + -