?? bmp.h
字號:
% %% %% %% R e a d B M P I m a g e %% %% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Method ReadBMPImage reads a Microsoft Windows bitmap image file and% returns it. It allocates the memory necessary for the new Image structure% and returns a pointer to the new image.%% The format of the ReadBMPImage method is:%% image=ReadBMPImage(image_info)%% A description of each parameter follows:%% o image: Method ReadBMPImage returns a pointer to the image after% reading. A null image is returned if there is a memory shortage or% if the image cannot be read.%% o image_info: Specifies a pointer to an ImageInfo structure.%% o exception: return any errors or warnings in this structure.%%*/static void ReadBMPImage (wmfAPI* API,wmfBMP* bmp,BMPSource* src){ BMPInfo bmp_info; BMPData* data = 0; int byte; long start_position = 0; unsigned char packet[4]; unsigned int bytes_per_line; unsigned int image_size; unsigned int packet_size; unsigned int i; unsigned long u; size_t bytes_read; data = (BMPData*) bmp->data; memset (&bmp_info,0,sizeof (BMPInfo)); bmp_info.ba_offset = 0; bmp_info.size = ReadBlobLSBLong (src); if (bmp_info.size == 12) { /* OS/2 BMP image file. */ bmp_info.width = ReadBlobLSBShort (src); bmp_info.height = ReadBlobLSBShort (src); bmp_info.planes = ReadBlobLSBShort (src); bmp_info.bits_per_pixel = ReadBlobLSBShort (src); bmp_info.x_pixels = 0; bmp_info.y_pixels = 0; bmp_info.number_colors = 0; bmp_info.compression = 0; bmp_info.image_size = 0; } else { /* Microsoft Windows BMP image file. */ bmp_info.width = ReadBlobLSBLong (src); bmp_info.height = ReadBlobLSBLong (src); bmp_info.planes = ReadBlobLSBShort (src); bmp_info.bits_per_pixel = ReadBlobLSBShort (src); bmp_info.compression = ReadBlobLSBLong (src); bmp_info.image_size = ReadBlobLSBLong (src); bmp_info.x_pixels = ReadBlobLSBLong (src); bmp_info.y_pixels = ReadBlobLSBLong (src); bmp_info.number_colors = ReadBlobLSBLong (src); bmp_info.colors_important = ReadBlobLSBLong (src); for (u = 0; u < (bmp_info.size - 40); u++) byte = ReadBlobByte (src); if ( (bmp_info.compression == 3) && ((bmp_info.bits_per_pixel == 16) || (bmp_info.bits_per_pixel == 32)) ) { bmp_info.red_mask = ReadBlobLSBShort (src); bmp_info.green_mask = ReadBlobLSBShort (src); bmp_info.blue_mask = ReadBlobLSBShort (src); if (bmp_info.size > 40) { /* Read color management information. */ bmp_info.alpha_mask = ReadBlobLSBShort (src); bmp_info.colorspace = ReadBlobLSBLong (src); bmp_info.red_primary.x = ReadBlobLSBLong (src); bmp_info.red_primary.y = ReadBlobLSBLong (src); bmp_info.red_primary.z = ReadBlobLSBLong (src); bmp_info.green_primary.x = ReadBlobLSBLong (src); bmp_info.green_primary.y = ReadBlobLSBLong (src); bmp_info.green_primary.z = ReadBlobLSBLong (src); bmp_info.blue_primary.x = ReadBlobLSBLong (src); bmp_info.blue_primary.y = ReadBlobLSBLong (src); bmp_info.blue_primary.z = ReadBlobLSBLong (src); bmp_info.gamma_scale.x = ReadBlobLSBShort (src); bmp_info.gamma_scale.y = ReadBlobLSBShort (src); bmp_info.gamma_scale.z = ReadBlobLSBShort (src); } } } if (bmp_info.height < 0) { bmp_info.height = - bmp_info.height; data->flipped = 1; } else { data->flipped = 0; } /* WMF may change bitmap size without changing bitmap header */ if (bmp->width == 0) bmp->width = (U16) bmp_info.width; if (bmp->height == 0) bmp->height = (U16) bmp_info.height; data->NColors = 0; if ((bmp_info.number_colors != 0) || (bmp_info.bits_per_pixel < 16)) { data->NColors = (unsigned int) bmp_info.number_colors; } if (data->NColors > 0) { /* Read BMP raster colormap. */ data->rgb = (wmfRGB*) wmf_malloc (API,data->NColors * sizeof (wmfRGB)); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); return; } if (bmp_info.size == 12) packet_size = 3; else packet_size = 4; for (i = 0; i < data->NColors; i++) { bytes_read = ReadBlob (src,packet_size,packet); if (bytes_read < packet_size) { WMF_ERROR (API,"Unexpected EOF"); API->err = wmf_E_EOF; break; } data->rgb[i].b = packet[0]; data->rgb[i].g = packet[1]; data->rgb[i].r = packet[2]; } if (ERR (API)) { WMF_DEBUG (API,"bailing..."); return; } } while (TellBlob (src) < (long) (start_position + bmp_info.offset_bits)) { byte = ReadBlobByte (src); } /* Read image data. */ if (bmp_info.compression == 2) bmp_info.bits_per_pixel <<= 1; bytes_per_line = 4 * ((bmp->width * bmp_info.bits_per_pixel + 31) / 32); image_size = bytes_per_line * bmp->height; data->image = (unsigned char*) wmf_malloc (API,image_size); if (ERR (API)) { WMF_DEBUG (API,"bailing..."); return; } if ((bmp_info.compression == 0) || (bmp_info.compression == 3)) { bytes_read = ReadBlob (src,image_size,data->image); if (bytes_read < image_size) { WMF_ERROR (API,"Unexpected EOF"); API->err = wmf_E_EOF; } } else { /* Convert run-length encoded raster pixels. */ DecodeImage (API,bmp,src,(unsigned int) bmp_info.compression,data->image); } if (ERR (API)) { WMF_DEBUG (API,"bailing..."); return; } data->bits_per_pixel = bmp_info.bits_per_pixel; data->bytes_per_line = bytes_per_line; data->masked = bmp_info.red_mask;}static int ExtractColor (wmfAPI* API,wmfBMP* bmp,wmfRGB* rgb,unsigned int x,unsigned int y){ int status = 0; BMPData* data = 0; int bit; unsigned int color; unsigned char opacity = WMF_BMP_OPAQUE; unsigned char* p; unsigned short word; data = (BMPData*) bmp->data; if (data->flipped) y = (bmp->height - 1) - y; switch (data->bits_per_pixel) { case 1: { p = data->image + (y * data->bytes_per_line) + (x >> 3); bit = 0x80 >> (x & 0x07); if ((*p) & bit) color = 1; else color = 0; if (data->rgb && (color < data->NColors)) { (*rgb) = data->rgb[color]; } else { if (color) { rgb->r = 0; rgb->g = 0; rgb->b = 0; } else { rgb->r = 0xff; rgb->g = 0xff; rgb->b = 0xff; } } break; } case 4: { p = data->image + (y * data->bytes_per_line) + (x >> 1); if (x & 1) color = (*p) & 0x0f; else color = ((*p) >> 4) & 0x0f; if (data->rgb && (color < data->NColors)) { (*rgb) = data->rgb[color]; } else { rgb->r = color << 4; rgb->g = color << 4; rgb->b = color << 4; } break; } case 8: { p = data->image + (y * data->bytes_per_line) + x; color = (*p); if (data->rgb && (color < data->NColors)) { (*rgb) = data->rgb[color]; } else { rgb->r = color; rgb->g = color; rgb->b = color; } break; } case 16: { p = data->image + (y * data->bytes_per_line) + (x << 1); word = (unsigned short) p[0] | (((unsigned short) p[1]) << 8); if (data->masked == 0) { rgb->r = ((word >> 10) & 0x1f) << 3; rgb->g = ((word >> 5) & 0x1f) << 3; rgb->b = ( word & 0x1f) << 3; } else { rgb->r = ((word >> 11) & 0x1f) << 3; rgb->g = ((word >> 5) & 0x3f) << 2; rgb->b = ( word & 0x1f) << 3; } break; } case 24: { p = data->image + (y * data->bytes_per_line) + (x + (x << 1)); rgb->b = p[0]; rgb->g = p[1]; rgb->r = p[2]; break; } case 32: { p = data->image + (y * data->bytes_per_line) + (x << 2); rgb->b = p[0]; rgb->g = p[1]; rgb->r = p[2]; opacity = p[3]; break; } default: if ((API->flags & WMF_OPT_IGNORE_NONFATAL) == 0) { WMF_ERROR (API,"Bitmap has bad format (illegal color depth)"); API->err = wmf_E_BadFormat; } status = -1; break; } if (status == 0) status = (int) opacity; return (status);}static void SetColor (wmfAPI* API,wmfBMP* bmp,wmfRGB* rgb,unsigned char opacity,unsigned int x,unsigned int y){ BMPData* data = 0; unsigned int i; unsigned int r_diff; unsigned int g_diff; unsigned int b_diff; unsigned int diff; unsigned int min_diff; unsigned int color; unsigned char bit; unsigned char* p; unsigned short word; data = (BMPData*) bmp->data; if (data->flipped) y = (bmp->height - 1) - y; switch (data->bits_per_pixel) { case 1: { p = data->image + (y * data->bytes_per_line) + (x >> 3); bit = 0x80 >> (x & 0x07); if (rgb->r || rgb->g || rgb->b) { (*p) |= ( bit & 0xff); } else { (*p) &= (~bit & 0xff); } break; } case 4: { p = data->image + (y * data->bytes_per_line) + (x >> 1); if (data->rgb == 0) break; min_diff = 766; color = 0; for (i = 0; i < data->NColors; i++) { r_diff = (unsigned int) ABS ((int) rgb->r - (int) data->rgb[i].r); g_diff = (unsigned int) ABS ((int) rgb->g - (int) data->rgb[i].g); b_diff = (unsigned int) ABS ((int) rgb->b - (int) data->rgb[i].b); diff = r_diff + g_diff + b_diff; if (min_diff > diff) { min_diff = diff; color = i; } } if (x & 1) { (*p) = ( ((unsigned char) color) | ((*p) & 0x0f)); } else { (*p) = ((((unsigned char) color) << 4) | ((*p) & 0xf0)); } break; } case 8: { p = data->image + (y * data->bytes_per_line) + x; if (data->rgb == 0) break; min_diff = 766; color = 0; for (i = 0; i < data->NColors; i++) { r_diff = (unsigned int) ABS ((int) rgb->r - (int) data->rgb[i].r); g_diff = (unsigned int) ABS ((int) rgb->g - (int) data->rgb[i].g); b_diff = (unsigned int) ABS ((int) rgb->b - (int) data->rgb[i].b); diff = r_diff + g_diff + b_diff; if (min_diff > diff) { min_diff = diff; color = i; } } (*p) = (unsigned char) color; break; } case 16: { p = data->image + (y * data->bytes_per_line) + (x << 1); word = 0; if (data->masked == 0) { word |= (rgb->r >> 3) << 10; word |= (rgb->g >> 3) << 5; word |= rgb->b >> 3; } else { word |= (rgb->r >> 3) << 11; word |= (rgb->g >> 2) << 5; word |= rgb->b >> 3; } p[0] = (unsigned char) ( word & 0x00ff ); p[1] = (unsigned char) ((word & 0xff00) >> 8); break; } case 24: { p = data->image + (y * data->bytes_per_line) + (x + (x << 1)); p[0] = rgb->b; p[1] = rgb->g; p[2] = rgb->r; break; } case 32: { p = data->image + (y * data->bytes_per_line) + (x << 2); p[0] = rgb->b; p[1] = rgb->g; p[2] = rgb->r; p[3] = opacity; break; } default: if ((API->flags & WMF_OPT_IGNORE_NONFATAL) == 0) { WMF_ERROR (API,"Bitmap has bad format (illegal color depth)"); API->err = wmf_E_BadFormat; } break; }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -