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

📄 bmp.c

📁 PSlib是一个用来生成PostScript文件的类库。提供了一个生成PostScript文件的简单方法。
💻 C
📖 第 1 页 / 共 2 页
字号:
	else if (info_hdr.iSize == BIH_OS22SIZE || info_hdr.iSize == 16)		bmp_type = BMPT_OS22;	else		bmp_type = BMPT_WIN5;  	if (bmp_type == BMPT_WIN4 || bmp_type == BMPT_WIN5 || bmp_type == BMPT_OS22) {		read(fd, &info_hdr.iWidth, 4);		read(fd, &info_hdr.iHeight, 4);		read(fd, &info_hdr.iPlanes, 2);		read(fd, &info_hdr.iBitCount, 2);		read(fd, &info_hdr.iCompression, 4);		read(fd, &info_hdr.iSizeImage, 4);		read(fd, &info_hdr.iXPelsPerMeter, 4);		read(fd, &info_hdr.iYPelsPerMeter, 4);		read(fd, &info_hdr.iClrUsed, 4);		read(fd, &info_hdr.iClrImportant, 4);		read(fd, &info_hdr.iRedMask, 4);		read(fd, &info_hdr.iGreenMask, 4);		read(fd, &info_hdr.iBlueMask, 4);		read(fd, &info_hdr.iAlphaMask, 4);#ifdef WORDS_BIGENDIAN		BMPSwabLong(&info_hdr.iWidth);		BMPSwabLong(&info_hdr.iHeight);		BMPSwabShort(&info_hdr.iPlanes);		BMPSwabShort(&info_hdr.iBitCount);		BMPSwabLong(&info_hdr.iCompression);		BMPSwabLong(&info_hdr.iSizeImage);		BMPSwabLong(&info_hdr.iXPelsPerMeter);		BMPSwabLong(&info_hdr.iYPelsPerMeter);		BMPSwabLong(&info_hdr.iClrUsed);		BMPSwabLong(&info_hdr.iClrImportant);		BMPSwabLong(&info_hdr.iRedMask);		BMPSwabLong(&info_hdr.iGreenMask);		BMPSwabLong(&info_hdr.iBlueMask);		BMPSwabLong(&info_hdr.iAlphaMask);#endif		n_clr_elems = 4;		*xres = (int) ((double)info_hdr.iXPelsPerMeter * 2.54 + 0.05) / 100;		*yres = (int) ((double)info_hdr.iYPelsPerMeter * 2.54 + 0.05) / 100;	}	if (bmp_type == BMPT_OS22) {		/* 		 * FIXME: different info in different documents		 * regarding this!		 */		n_clr_elems = 3;	}	if (bmp_type == BMPT_OS21) {		int16 iShort;				read(fd, &iShort, 2);#ifdef WORDS_BIGENDIAN		BMPSwabShort(&iShort);#endif		info_hdr.iWidth = iShort;		read(fd, &iShort, 2);#ifdef WORDS_BIGENDIAN		BMPSwabShort(&iShort);#endif		info_hdr.iHeight = iShort;		read(fd, &iShort, 2);#ifdef WORDS_BIGENDIAN		BMPSwabShort(&iShort);#endif		info_hdr.iPlanes = iShort;		read(fd, &iShort, 2);#ifdef WORDS_BIGENDIAN		BMPSwabShort(&iShort);#endif		info_hdr.iBitCount = iShort;		info_hdr.iCompression = BMPC_RGB;		n_clr_elems = 3;	}	if (info_hdr.iBitCount != 1  && info_hdr.iBitCount != 4  &&	    info_hdr.iBitCount != 8  && info_hdr.iBitCount != 16 &&	    info_hdr.iBitCount != 24 && info_hdr.iBitCount != 32) {		ps_error(psdoc, PS_RuntimeError, _("Cannot process bmp file with bit count %d."), info_hdr.iBitCount);		close(fd);		return 0;	}	*w = info_hdr.iWidth;	*h = (info_hdr.iHeight > 0) ? info_hdr.iHeight : -info_hdr.iHeight;	switch (info_hdr.iBitCount) {		case 1:		case 4:		case 8:			*spp = 1;			*bps = info_hdr.iBitCount;			/* Allocate memory for colour table and read it. */			if (info_hdr.iClrUsed)				clr_tbl_size = ((uint32)(1 << *bps) < info_hdr.iClrUsed) ? 1 << *bps : info_hdr.iClrUsed;			else				clr_tbl_size = 1 << *bps;			clr_tbl = (unsigned char *) psdoc->malloc(psdoc, n_clr_elems * clr_tbl_size, _("Allocate memory for color table."));			if (!clr_tbl) {				ps_error(psdoc, PS_MemoryError, _("Cannot allocate memory for color table."));				goto bad;			}						/*printf ("n_clr_elems: %d, clr_tbl_size: %d\n",	n_clr_elems, clr_tbl_size); */						lseek(fd, BFH_SIZE + info_hdr.iSize, SEEK_SET);			read(fd, clr_tbl, n_clr_elems * clr_tbl_size);						/*for(clr = 0; clr < clr_tbl_size; ++clr) {			printf ("%d: r: %d g: %d b: %d\n",		clr,		clr_tbl[clr*n_clr_elems+2],		clr_tbl[clr*n_clr_elems+1],		clr_tbl[clr*n_clr_elems]);			}*/			break;		case 16:		case 24:			*spp = 3;			*bps = info_hdr.iBitCount / *spp;			break;				case 32:			*spp = 3;			*bps = 8;			break;				default:			break;	}	stride = (*w * *spp * *bps + 7) / 8;	/*printf ("w: %d, h: %d, spp: %d, bps: %d, colorspace: %d\n",	 *w, *h, *spp, *bps, info_hdr.iCompression); */	// detect old style bitmask images	if (info_hdr.iCompression == BMPC_RGB && info_hdr.iBitCount == 16) {		/*printf ("implicit non-RGB image\n"); */		info_hdr.iCompression = BMPC_BITFIELDS;		info_hdr.iBlueMask = 0x1f;		info_hdr.iGreenMask = 0x1f << 5;		info_hdr.iRedMask = 0x1f << 10;	}	/* -------------------------------------------------------------------- */	/*  Read uncompressed image data.                                       */	/* -------------------------------------------------------------------- */	switch (info_hdr.iCompression) {		case BMPC_BITFIELDS:			// we convert those to RGB for easier use			*bps = 8;			stride = (*w * *spp * *bps + 7) / 8;		case BMPC_RGB:		{      uint32 file_stride = ((*w * info_hdr.iBitCount + 7) / 8 + 3) / 4 * 4;            /*printf ("bitcount: %d, stride: %d, file stride: %d\n",	      info_hdr.iBitCount, stride, file_stride);            printf ("red mask: %x, green mask: %x, blue mask: %x\n",      info_hdr.iRedMask, info_hdr.iGreenMask, info_hdr.iBlueMask); */      			data = (unsigned char *) psdoc->malloc(psdoc, stride * *h, _("Allocate memory for image buffer."));            if (!data) {				ps_error(psdoc, PS_MemoryError, _("Cannot allocate memory for image buffer."));				goto bad1;      }            for (row = 0; row < *h; row++) {				uint32 offset;					if (info_hdr.iHeight > 0)					offset = file_hdr.iOffBits + (*h - row - 1) * file_stride;				else					offset = file_hdr.iOffBits + row * file_stride;					if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {					ps_error(psdoc, PS_Warning, _("Scanline %lu: Seek error."), (unsigned long) row);				}					if (read(fd, data + stride*row, stride) < 0) {					ps_error(psdoc, PS_Warning, _("Scanline %lu: Read error."), (unsigned long) row);				}					// convert to RGB				if (info_hdr.iCompression == BMPC_BITFIELDS) {					unsigned char* row_ptr = data + stride*row;					unsigned char* r16_ptr = row_ptr + file_stride - 2;					unsigned char* rgb_ptr = row_ptr + stride - 3;								int r_shift = last_bit_set (info_hdr.iRedMask) - 7;					int g_shift = last_bit_set (info_hdr.iGreenMask) - 7;					int b_shift = last_bit_set (info_hdr.iBlueMask) - 7;								for ( ; rgb_ptr >= row_ptr; r16_ptr -= 2, rgb_ptr -= 3) {						int val = (r16_ptr[0] << 0) + (r16_ptr[1] << 8);						if (r_shift > 0)							rgb_ptr[0] = (val & info_hdr.iRedMask) >> r_shift;						else							rgb_ptr[0] = (val & info_hdr.iRedMask) << -r_shift;						if (g_shift > 0)							rgb_ptr[1] = (val & info_hdr.iGreenMask) >> g_shift;						else							rgb_ptr[1] = (val & info_hdr.iGreenMask) << -g_shift;						if (b_shift > 0)							rgb_ptr[2] = (val & info_hdr.iBlueMask) >> b_shift;						else							rgb_ptr[2] = (val & info_hdr.iBlueMask) << -b_shift;					}				} else					rearrangePixels(data + stride*row, *w, info_hdr.iBitCount);			}		}		break;		/* -------------------------------------------------------------------- */		/*	Read compressed image data.																				 */		/* -------------------------------------------------------------------- */		case BMPC_RLE4:		case BMPC_RLE8:		{			uint32		i, j, k, runlength, x;			uint32		compr_size, uncompr_size;			unsigned char *comprbuf;			unsigned char *uncomprbuf;//      printf ("RLE%s compressed\n", info_hdr.iCompression == BMPC_RLE4 ? "4" : "8");			compr_size = file_hdr.iSize - file_hdr.iOffBits;			uncompr_size = *w * *h; 			comprbuf = (unsigned char *) psdoc->malloc(psdoc, compr_size, _("Allocate memory for compressed scanline buffer."));			if (!comprbuf) {				ps_error(psdoc, PS_MemoryError, _("Cannot allocate memory for compressed scanline buffer"));				goto bad1;			}			uncomprbuf = (unsigned char *) psdoc->malloc(psdoc, uncompr_size, _("Allocate memory for uncompressed scanline buffer."));			if (!uncomprbuf) {				ps_error(psdoc, PS_MemoryError, _("Cannot allocate memory for uncompressed scanline buffer"));				goto bad1;			}			lseek(fd, file_hdr.iOffBits, SEEK_SET);			read(fd, comprbuf, compr_size);			i = j = x = 0;			while( j < uncompr_size && i < compr_size ) {				if ( comprbuf[i] ) {					runlength = comprbuf[i++];					for ( k = 0;					runlength > 0 && j < uncompr_size && i < compr_size && x < *w;					++k, ++x) {						if (info_hdr.iBitCount == 8)							uncomprbuf[j++] = comprbuf[i];						else {							if ( k & 0x01 )								uncomprbuf[j++] = comprbuf[i] & 0x0F;							else								uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4;						}						runlength--;					}					i++;				} else {					i++;					if ( comprbuf[i] == 0 ) {         /* Next scanline */						i++;						x = 0;;					}					else if ( comprbuf[i] == 1 )    /* End of image */						break;					else if ( comprbuf[i] == 2 ) {  /* Move to... */						i++;						if ( i < compr_size - 1 ) {							j += comprbuf[i] + comprbuf[i+1] * *w;							i += 2;						}						else							break;					} else {                         /* Absolute mode */						runlength = comprbuf[i++];						for ( k = 0; k < runlength && j < uncompr_size && i < compr_size; k++, x++) {							if (info_hdr.iBitCount == 8)								uncomprbuf[j++] = comprbuf[i++];							else {								if ( k & 0x01 )									uncomprbuf[j++] = comprbuf[i++] & 0x0F;								else									uncomprbuf[j++] = (comprbuf[i] & 0xF0) >> 4;							}						}						/* word boundary alignment */						if (info_hdr.iBitCount == 4)							k /= 2;						if ( k & 0x01 )							i++;					}				}			}			psdoc->free(psdoc, comprbuf);			data = (unsigned char *) psdoc->malloc(psdoc, uncompr_size, _("Allocate memory for final uncompressed scanline buffer."));			if (!data) {				ps_error(psdoc, PS_MemoryError, _("Cannot allocate memory for final uncompressed scanline buffer."));				goto bad1;			}			// TODO: suboptimal, later improve the above to yield the corrent orientation natively			for (row = 0; row < *h; ++row) {				memcpy (data + row * *w, uncomprbuf + (*h - 1 - row) * *w, *w);				rearrangePixels(data + row * *w, *w, info_hdr.iBitCount);			}			psdoc->free(psdoc, uncomprbuf);			*bps = 8;		}		break;	} /* switch */	/* export the table */	*color_table = clr_tbl;	*color_table_size = clr_tbl_size;	*color_table_elements = n_clr_elems;	goto bad;bad1:	if (clr_tbl)		psdoc->free(psdoc, clr_tbl);	clr_tbl = NULL;bad:	close(fd);	return data;}

⌨️ 快捷键说明

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