1///////////////////////////////////////////////////////////////////////////// 2// Name: bmputils.h 3// Purpose: Utilities for manipulating bitmap and metafile images for 4// the purposes of conversion to RTF 5// Author: Julian Smart 6// Modified by: Wlodzimiez ABX Skiba 2003/2004 Unicode support 7// Ron Lee 8// Created: 7.9.93 9// RCS-ID: $Id: bmputils.h 29660 2004-10-05 15:38:40Z ABX $ 10// Copyright: (c) Julian Smart 11// Licence: wxWindows licence 12///////////////////////////////////////////////////////////////////////////// 13 14static char hexArray[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 15 'C', 'D', 'E', 'F' }; 16 17void DecToHex(int dec, wxChar *buf) 18{ 19 int firstDigit = (int)(dec/16.0); 20 int secondDigit = (int)(dec - (firstDigit*16.0)); 21 buf[0] = hexArray[firstDigit]; 22 buf[1] = hexArray[secondDigit]; 23 buf[2] = 0; 24} 25 26static unsigned int getshort(FILE *fp) 27{ 28 int c, c1; 29 c = getc(fp); c1 = getc(fp); 30 return ((unsigned int) c) + (((unsigned int) c1) << 8); 31} 32 33static unsigned long getint(FILE *fp) 34{ 35 int c, c1, c2, c3; 36 c = getc(fp); c1 = getc(fp); c2 = getc(fp); c3 = getc(fp); 37 return (long)((long) c) + 38 (((long) c1) << 8) + 39 (((long) c2) << 16) + 40 (((long) c3) << 24); 41} 42 43bool GetBMPHeader(FILE *fp, int *Width, int *Height, int *Planes, int *BitsPerPixel) 44{ 45 // Remember about all fields but store only important ones 46 unsigned long /* 47 bfSize, 48 bfOffBits, 49 biSize, 50 */ 51 biWidth, 52 biHeight, 53 biPlanes, 54 biBitCount 55 /* , 56 biCompression, 57 biSizeImage, 58 biXPelsPerMeter, 59 biYPelsPerMeter, 60 biClrUsed, 61 biClrImportant 62 */ 63 ; 64 65 /* read the file type (first two bytes) */ 66 int c = getc(fp); int c1 = getc(fp); 67 if (c!='B' || c1!='M') { return false; } 68 69 /* bfSize = */ getint(fp); 70 getshort(fp); /* reserved and ignored */ 71 getshort(fp); 72 /* bfOffBits = */ getint(fp); 73 74 /* biSize = */ getint(fp); 75 biWidth = getint(fp); 76 biHeight = getint(fp); 77 biPlanes = getshort(fp); 78 biBitCount = getshort(fp); 79 /* biCompression = */ getint(fp); 80 /* biSizeImage = */ getint(fp); 81 /* biXPelsPerMeter = */ getint(fp); 82 /* biYPelsPerMeter = */ getint(fp); 83 /* biClrUsed = */ getint(fp); 84 /* biClrImportant = */ getint(fp); 85 86 *Width = (int)biWidth; 87 *Height = (int)biHeight; 88 *Planes = (int)biPlanes; 89 *BitsPerPixel = (int)biBitCount; 90 91// fseek(fp, bfOffBits, SEEK_SET); 92 93 return true; 94} 95 96static int scanLineWidth = 0; 97 98bool OutputBitmapHeader(FILE *fd, bool isWinHelp = false) 99{ 100 int Width, Height, Planes, BitsPerPixel; 101 if (!GetBMPHeader(fd, &Width, &Height, &Planes, &BitsPerPixel)) 102 return false; 103 104 scanLineWidth = (int)((float)Width/(8.0/(float)BitsPerPixel)); 105 if ((float)((int)(scanLineWidth/2.0)) != (float)(scanLineWidth/2.0)) 106 scanLineWidth ++; 107 108 int goalW = 15*Width; 109 int goalH = 15*Height; 110 111 TexOutput(_T("{\\pict")); 112 if (isWinHelp) TexOutput(_T("\\wbitmap0")); 113 else TexOutput(_T("\\dibitmap)")); 114 115 wxChar buf[50]; 116 TexOutput(_T("\\picw")); wxSnprintf(buf, sizeof(buf), _T("%d"), Width); TexOutput(buf); 117 TexOutput(_T("\\pich")); wxSnprintf(buf, sizeof(buf), _T("%d"), Height); TexOutput(buf); 118 TexOutput(_T("\\wbmbitspixel")); wxSnprintf(buf, sizeof(buf), _T("%d"), BitsPerPixel); TexOutput(buf); 119 TexOutput(_T("\\wbmplanes")); wxSnprintf(buf, sizeof(buf), _T("%d"), Planes); TexOutput(buf); 120 TexOutput(_T("\\wbmwidthbytes")); wxSnprintf(buf, sizeof(buf), _T("%d"), scanLineWidth); TexOutput(buf); 121 TexOutput(_T("\\picwgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalW); TexOutput(buf); 122 TexOutput(_T("\\pichgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalH); TexOutput(buf); 123 TexOutput(_T("\n")); 124 return true; 125} 126 127 128bool OutputBitmapData(FILE *fd) 129{ 130 fseek(fd, 14, SEEK_SET); 131 int bytesSoFar = 0; 132 int ch = getc(fd); 133 wxChar hexBuf[3]; 134 while (ch != EOF) 135 { 136 if (bytesSoFar == scanLineWidth) 137 { 138 bytesSoFar = 0; 139 TexOutput(_T("\n")); 140 } 141 DecToHex(ch, hexBuf); 142 TexOutput(hexBuf); 143 bytesSoFar ++; 144 ch = getc(fd); 145 } 146 TexOutput(_T("\n}\n")); 147 return true; 148} 149 150#ifdef __WXMSW__ 151struct mfPLACEABLEHEADER { 152 DWORD key; 153 HANDLE hmf; 154 RECT bbox; 155 WORD inch; 156 DWORD reserved; 157 WORD checksum; 158}; 159 160// Returns size in TWIPS 161bool GetMetafileHeader(FILE *handle, int *width, int *height) 162{ 163 char buffer[40]; 164 mfPLACEABLEHEADER *theHeader = (mfPLACEABLEHEADER *)&buffer[0]; 165 fread((void *)theHeader, sizeof(char), sizeof(mfPLACEABLEHEADER), handle); 166 if (theHeader->key != 0x9AC6CDD7) 167 { 168 return false; 169 } 170 171 float widthInUnits = (float)theHeader->bbox.right - theHeader->bbox.left; 172 float heightInUnits = (float)theHeader->bbox.bottom - theHeader->bbox.top; 173 *width = (int)((widthInUnits*1440.0)/theHeader->inch); 174 *height = (int)((heightInUnits*1440.0)/theHeader->inch); 175 return true; 176} 177 178bool OutputMetafileHeader(FILE *handle, bool WXUNUSED(isWinHelp), int userWidth, int userHeight) 179{ 180 int Width, Height; 181 if (!GetMetafileHeader(handle, &Width, &Height)) 182 return false; 183 184 scanLineWidth = 64; 185 int goalW = Width; 186 int goalH = Height; 187 188 // Scale to user's dimensions if we have the information 189 if (userWidth > 0 && userHeight == 0) 190 { 191 double scaleFactor = ((double)userWidth/(double)goalW); 192 goalW = userWidth; 193 goalH = (int)((goalH * scaleFactor) + 0.5); 194 } 195 else if (userWidth == 0 && userHeight > 0) 196 { 197 double scaleFactor = ((double)userHeight/(double)goalH); 198 goalH = userHeight; 199 goalW = (int)((goalW * scaleFactor) + 0.5); 200 } 201 else if (userWidth > 0 && userHeight > 0) 202 { 203 goalW = userWidth; 204 goalH = userHeight; 205 } 206 207 TexOutput(_T("{\\pict")); 208 TexOutput(_T("\\wmetafile8")); 209 210 wxChar buf[50]; 211 TexOutput(_T("\\picw")); wxSnprintf(buf, sizeof(buf), _T("%d"), Width); TexOutput(buf); 212 TexOutput(_T("\\pich")); wxSnprintf(buf, sizeof(buf), _T("%d"), Height); TexOutput(buf); 213 TexOutput(_T("\\picwgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalW); TexOutput(buf); 214 TexOutput(_T("\\pichgoal")); wxSnprintf(buf, sizeof(buf), _T("%d"), goalH); TexOutput(buf); 215 TexOutput(_T("\n")); 216 return true; 217} 218 219bool OutputMetafileData(FILE *handle) 220{ 221 int bytesSoFar = 0; 222 wxChar hexBuf[3]; 223 int ch; 224 do 225 { 226 ch = getc(handle); 227 if (bytesSoFar == scanLineWidth) 228 { 229 bytesSoFar = 0; 230 TexOutput(_T("\n")); 231 } 232 if (ch != EOF) 233 { 234 DecToHex(ch, hexBuf); 235 TexOutput(hexBuf); 236 bytesSoFar ++; 237 } 238 } while (ch != EOF); 239 TexOutput(_T("\n}\n")); 240 return true; 241} 242 243#endif 244 245