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