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

📄 convbmp.c

📁 Microwindows genesis was with the NanoGUI project, and is now the primary distribution for both th
💻 C
字号:
/* * Copyright (c) 1999, 2000 Greg Haerr <greg@censoft.com> * * Windows BMP to Microwindows image converter * * 6/9/1999 g haerr * * 05/01/2000 Michael Temari <Michael@TemWare.Com> * Modified to output .s ACK format for Minix */#include <stdio.h>#include <string.h>#include <stdlib.h>#include "../../include/device.h"/* separators for DOS & Unix file systems */#define OS_FILE_SEPARATOR   "/\\"#define PIX2BYTES(n)	(((n)+7)/8)#define BI_RGB		0L#define BI_RLE8		1L#define BI_RLE4		2L#define BI_BITFIELDS	3Ltypedef unsigned char	UCHAR;typedef unsigned char	BYTE;#if !_MINIXtypedef unsigned short	WORD;typedef unsigned long	DWORD;typedef long		LONG;#define	CASTWORD#define	CASTDWORD#define	CASTLONG#else/* The Minix ACK compiler cannot pack a structure so we do it the hardway */typedef unsigned char	WORD[2];typedef unsigned char	DWORD[4];typedef unsigned char	LONG[4];#define	CASTWORD	*(unsigned short *)&#define	CASTDWORD	*(unsigned long *)&#define	CASTLONG	*(long *)&#endif#pragma pack(1)/* windows style*/typedef struct {	/* BITMAPFILEHEADER*/	BYTE	bfType[2];	DWORD	bfSize;	WORD	bfReserved1;	WORD	bfReserved2;	DWORD	bfOffBits;	/* BITMAPINFOHEADER*/	DWORD	BiSize;	LONG	BiWidth;	LONG	BiHeight;	WORD	BiPlanes;	WORD	BiBitCount;	DWORD	BiCompression;	DWORD	BiSizeImage;	LONG	BiXpelsPerMeter;	LONG	BiYpelsPerMeter;	DWORD	BiClrUsed;	DWORD	BiClrImportant;} BMPHEAD;/* os/2 style*/typedef struct {	/* BITMAPFILEHEADER*/	BYTE	bfType[2];	DWORD	bfSize;	WORD	bfReserved1;	WORD	bfReserved2;	DWORD	bfOffBits;	/* BITMAPCOREHEADER*/	DWORD	bcSize;	WORD	bcWidth;	WORD	bcHeight;	WORD	bcPlanes;	WORD	bcBitCount;} BMPCOREHEAD;#pragma pack()int	ConvBMP(FILE *fp,char *name);void	outline(UCHAR *linebuffer, int bitdepth, int linesize, int y);int	DecodeRLE8(UCHAR *buf,FILE *fp);int	DecodeRLE4(UCHAR *buf,FILE *fp);void	put4(int b);int	s_flag = 0;int main(int argc,char *argv[]){FILE	*fp;char 	*p;char	name[64];char	oname[64];   /* skip the program name */   argc--;   argv++;   /* check for -s flag */   if(argc && strcmp(*argv, "-s") == 0) {	s_flag = -1;	argc--;	argv++;   }   /* need at least one file to convert */   if(argc == 0) {	fprintf(stderr, "Usage: convbmp [-s] <bmpfile>\n");	return(-1);   }   /* go back one since the first thing in the loop is to increment */   argv--;   while(argc--) {	argv++;	if((p = strrchr(*argv, '.')) != (char *)NULL)		*p = '\0';	strcpy(name, *argv);	strcpy(oname, *argv);	if(s_flag)		strcat(oname, ".s");	else		strcat(oname, ".c");	if(p != (char *)NULL)		*p = '.';	if((fp = fopen(*argv, "rb")) == (FILE *)NULL) {		fprintf(stderr, "Can't open file: %s\n", *argv);		continue;	}	if(freopen(oname, "w", stdout) == (FILE *)NULL) {		fclose(fp);		fprintf(stderr, "Could not open output file %s\n", oname);		continue;	}   /*       let's strip any directory from the path passed in.      This prevent problems if this utility is given       path is not for the curent directory.   */   p = name;   while( 1 )   {      char *p1 = p;      p1 = strpbrk( p, OS_FILE_SEPARATOR );      if( p1 )      {         p = p1+1;      }      else      {          break;      }   }	if(ConvBMP(fp, p)) {		fprintf(stderr, "Conversion failed: %s\n", *argv);		fclose(fp);		continue;	}	fclose(fp);   }   return(0);}/* decode a bmp file*/int ConvBMP(FILE *fp, char *name){BMPHEAD		bmp;BMPCOREHEAD	*bmc;int		i, palsize;UCHAR		*linebuffer = NULL;unsigned int	cx, cy, bitdepth, linesize;long		compression;MWPALENTRY	cmap[256];long l;int g;int bytesperpixel;UCHAR *p = (UCHAR *)&l;   /* read BMP header*/   if(fread(&bmp, 1, sizeof(BMPHEAD), fp) != sizeof(BMPHEAD)) {   	fprintf(stderr, "Error reading .bmp file header\n");	return(-1);   }   /* might be windows or os/2 header*/   if(CASTDWORD bmp.BiSize == 12) {	bmc = (BMPCOREHEAD *)&bmp;	cx = (int)CASTWORD bmc->bcWidth;	cy = (int)CASTWORD bmc->bcHeight;	bitdepth = CASTWORD bmc->bcBitCount;	palsize = 1 << bitdepth;	compression = BI_RGB;	fseek(fp, sizeof(BMPCOREHEAD), SEEK_SET);   } else {	cx = (int)CASTLONG bmp.BiWidth;	cy = (int)CASTLONG bmp.BiHeight;	bitdepth = CASTWORD bmp.BiBitCount;	palsize = (int)CASTDWORD bmp.BiClrUsed;	if(palsize == 0)		palsize = 1 << bitdepth;	compression = CASTDWORD bmp.BiCompression;   }   if(bitdepth > 8)	   palsize = 0;   /* currently only 1, 4, 8 and 24 bpp bitmaps*/   if(bitdepth > 8 && bitdepth != 24) {	fprintf(stderr, "Error: bits per pixel must be 1, 4, 8 or 24\n");	return(-1);   }   /* compute image line size and allocate line buffer*/   if(bitdepth == 1) {	linesize = PIX2BYTES(cx);	bytesperpixel = 1;   } else if(bitdepth <= 4) {	linesize = PIX2BYTES(cx<<2);	bytesperpixel = 1;   } else if(bitdepth <= 8) {	linesize = cx;	bytesperpixel = 1;   } else if(bitdepth <= 16) {	linesize = cx * 2;	bytesperpixel = 2;   } else if(bitdepth <= 24) {	linesize = cx * 3;	bytesperpixel = 3;   } else {	linesize = cx * 4;	bytesperpixel = 4;   }   linesize = (linesize+3) & ~3;   if((linebuffer = malloc(linesize)) == (UCHAR *)NULL) {   	fprintf(stderr, "Error with malloc(%d)\n", linesize);	return(-1);   }   if(!s_flag) {	printf("/* Generated by convbmp*/\n");	printf("#include \"device.h\"\n\n");	printf("/* MWIMAGEHDR image_%s converted from %s.bmp*/\n\n",		name, name);   }   /* get colormap*/   if(bitdepth <= 8) {	for(i=0; i<palsize; i++) {		cmap[i].b = fgetc(fp);		cmap[i].g = fgetc(fp);		cmap[i].r = fgetc(fp);		if(CASTDWORD bmp.BiSize != 12)			fgetc(fp);	}	if(!s_flag) {		/* extract palette*/		printf("static MWPALENTRY palette[%d] = {\n", palsize);		for(i=0; i<palsize; ++i)			printf("  RGBDEF( %3d, %3d, %3d ),\t/* pal %d*/\n",				cmap[i].r, cmap[i].g, cmap[i].b, i);		printf("};\n\n");	} else {		printf(".sect .text; .sect .rom; .sect .data; .sect .bss\n");		printf(".sect .data\n");		printf("__II0:\n");		l = 0L; g = 0; p = (UCHAR *)&l;		for(i=0; i<palsize; ++i) {			p[g++] = cmap[i].r;			if(g == 4)				{ g = 0; printf(".data4\t%ld\n", l); l = 0L; }			p[g++] = cmap[i].g;			if(g == 4)				{ g = 0; printf(".data4\t%ld\n", l); l = 0L; }			p[g++] = cmap[i].b;			if(g == 4)				{ g = 0; printf(".data4\t%ld\n", l); l = 0L; }		}		if(g)			printf(".data4\t%ld\n", l);	}   }   if(!s_flag) {	printf("static MWUCHAR imagebits[] = {\n");   } else {	printf("__II1:\n");	l = 0L; g = 0;   }   /* decode image data*/   fseek(fp, CASTDWORD bmp.bfOffBits, SEEK_SET);   if(compression == BI_RLE8) {	for(i = cy-1; i>= 0; i--) {		if(!DecodeRLE8(linebuffer, fp))			break;		outline(linebuffer, bitdepth, linesize, i);	}   } else if(compression == BI_RLE4) {	for(i = cy-1; i>= 0; i--) {		if(!DecodeRLE4(linebuffer, fp))			break;		outline(linebuffer, bitdepth, linesize, i);	}   } else {	for(i=0; i<cy; i++) {		if(fread(linebuffer, 1, linesize, fp) != (size_t)linesize) {			free(linebuffer);			fprintf(stderr, "Error fread\n");			return(-1);		}		outline(linebuffer, bitdepth, linesize, cy-i-1);	}   }   if(!s_flag) {	printf("};\n\n");	printf("MWIMAGEHDR image_%s = {\n", name);	printf("  %d, %d,\t/* width, height*/\n", cx, cy);	printf("  %d, %d,\t\t/* planes, bpp*/\n", 1, bitdepth);	printf("  %d, %d,\t/* pitch, bytesperpixel*/\n",		linesize, bytesperpixel);	printf("  %d, %d,\t/* compression, palsize*/\n", 1, palsize);	printf("  %ldL,\t\t/* transcolor*/\n", -1L);	if(palsize)		printf("  palette,\n");	else		printf("  0,\n");	printf("  imagebits,\n");	printf("};\n");   } else {	printf(".extern _image_%s\n", name);	printf("_image_%s:\n", name);	printf(".data4\t%ld\n",(long)cx);	printf(".data4\t%ld\n",(long)cy);	printf(".data4\t%ld\n",1L);	printf(".data4\t%ld\n",(long)bitdepth);	printf(".data4\t%ld\n",(long)linesize);	printf(".data4\t%ld\n",(long)bytesperpixel);	printf(".data4\t%ld\n",1L);	printf(".data4\t%ld\n",(long)palsize);	printf(".data4\t%ld\n",-1L);	printf(".data4\t__II0\n");	if(palsize)		printf(".data4\t__II1\n");	else		printf(".data4\t0\n");	printf(".sect .text\n");   }   free(linebuffer);   return(0);}void outline(UCHAR *linebuffer, int bitdepth, int linesize, int y){static int bc = 0;static long l = 0;static char *p = (char *)&l;int	n;   switch(bitdepth) {	case 1:	case 4:		for(n=0; n<linesize; ++n) {			if(!s_flag)				printf("0x%02x,", linebuffer[n]);			else {				p[bc++] = linebuffer[n];				if(bc == 4) {					bc = 0;					printf(".data4\t%ld\n", l);					l = 0L;				}			}		}		break;	case 8:	default:		for(n=0; n<linesize; ++n) {			if(!s_flag)				printf("%d,", linebuffer[n]);			else {				p[bc++] = linebuffer[n];				if(bc == 4) {					bc = 0;					printf(".data4\t%ld\n", l);					l = 0L;				}			}		}   }   if(!s_flag)	printf("\n");}/* * Decode one line of RLE8, return 0 when done with all bitmap data */int DecodeRLE8(UCHAR *buf,FILE *fp){int		c, n;UCHAR *	p = buf;   while(1) {	switch(n = fgetc(fp)) {		case EOF:			return(0);		case 0:					/* 0 = escape*/			switch(n = fgetc(fp)) {			case 0: 			/* 0 0 = end of current scan line*/				return(1);			case 1:				/* 0 1 = end of data*/				return(1);			case 2:				/* 0 2 xx yy delta mode - NOT SUPPORTED*/				(void)fgetc(fp);				(void)fgetc(fp);				continue;			default:			/* 0 3..255 xx nn uncompressed data*/				for(c=0; c<n; c++)					*p++ = fgetc(fp);				if(n & 1)					(void)fgetc(fp);				continue;			}		default:			c = fgetc(fp);			while(n--)				*p++ = c;			continue;		}	}}/* * Decode one line of RLE4, return 0 when done with all bitmap data */static UCHAR *p;static int	once;void put4(int b){static int	last;   last = (last << 4) | b;   if(++once == 2) {	*p++ = last;	once = 0;   }}int DecodeRLE4(UCHAR *buf, FILE *fp){int		c, n, c1, c2;   p = buf;   once = 0;   while(1) {	switch(n = fgetc(fp)) {		case EOF:			return(0);		case 0:					/* 0 = escape*/		switch(n = fgetc(fp)) {			case 0: 			/* 0 0 = end of current scan line*/				if(once)					put4(0);				return(1);			case 1:				/* 0 1 = end of data*/				if(once)					put4(0);				return(1);			case 2:				/* 0 2 xx yy delta mode - NOT SUPPORTED*/				(void)fgetc(fp);				(void)fgetc(fp);				continue;			default:			/* 0 3..255 xx nn uncompressed data*/				c2 = (n+3) & ~3;				for(c=0; c<c2; c++) {					if((c & 1) == 0)							c1 = fgetc(fp);					if(c < n)							put4((c1 >> 4) & 0x0f);					c1 <<= 4;				}				continue;			}		default:			c = fgetc(fp);			c1 = (c >> 4) & 0x0f;			c2 = c & 0x0f;			for(c=0; c<n; c++)				put4((c&1)? c2: c1);			continue;		}	}}

⌨️ 快捷键说明

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