]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/bitmap.cpp
93dcd2820d56413f454b33e6bf857326f4d52eed
[xonotic/netradiant.git] / contrib / gtkgensurf / bitmap.cpp
1 /*\r
2 GenSurf plugin for GtkRadiant\r
3 Copyright (C) 2001 David Hyde, Loki software and qeradiant.com\r
4 \r
5 This library is free software; you can redistribute it and/or\r
6 modify it under the terms of the GNU Lesser General Public\r
7 License as published by the Free Software Foundation; either\r
8 version 2.1 of the License, or (at your option) any later version.\r
9 \r
10 This library is distributed in the hope that it will be useful,\r
11 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13 Lesser General Public License for more details.\r
14 \r
15 You should have received a copy of the GNU Lesser General Public\r
16 License along with this library; if not, write to the Free Software\r
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
18 */\r
19 \r
20 #include <stdio.h>\r
21 #include <stdlib.h>\r
22 #include <math.h>\r
23 #include "gensurf.h"\r
24 \r
25 void GenerateBitmapMapping ()\r
26 {\r
27   double              value;\r
28   double              C0, C1;\r
29   double              x, y;\r
30   int                 i, j;\r
31   int                 O00,O01,O10,O11;\r
32   int                 r0, r1, c0, c1;\r
33   int                 color;\r
34   unsigned char       *colors;\r
35 \r
36   if (!gbmp.colors)\r
37     return;\r
38 \r
39   colors = gbmp.colors;\r
40 \r
41   for (j=0; j<=NV; j++)\r
42   {\r
43     y  = (double)(j*(gbmp.height-1))/(double)NV;\r
44     r0 = (int)floor(y);\r
45     r1 = (int)ceil(y);\r
46     for (i=0; i<=NH; i++)\r
47     {\r
48       x = (double)(i*(gbmp.width-1))/(double)NH;\r
49       c0 = (int)floor(x);\r
50       c1 = (int)ceil(x);\r
51       O00 = r0*gbmp.width + c0;\r
52       O01 = r0*gbmp.width + c1;\r
53       O10 = r1*gbmp.width + c0;\r
54       O11 = r1*gbmp.width + c1;\r
55       C0 = (double)colors[O00] + (double)(colors[O01]-colors[O00])*(x-(double)c0);\r
56       C1 = (double)colors[O10] + (double)(colors[O11]-colors[O10])*(x-(double)c0);\r
57       color = (int)(C0 + (C1-C0)*(y-r0));\r
58 \r
59       value = CalculateSnapValue(gbmp.black_value + color*((gbmp.white_value-gbmp.black_value)/255.));\r
60 \r
61       switch(Plane)\r
62       {\r
63       case PLANE_XZ0:\r
64       case PLANE_XZ1:\r
65         xyz[i][j].p[1] = value;\r
66         break;\r
67       case PLANE_YZ0:\r
68       case PLANE_YZ1:\r
69         xyz[i][j].p[0] = value;\r
70         break;\r
71       default:\r
72         xyz[i][j].p[2] = value;\r
73       }\r
74     }\r
75   }\r
76 }\r
77 \r
78 static unsigned char* OpenBitmapFile ()\r
79 {\r
80   int bmWidth;\r
81   int bmHeight;\r
82   unsigned char bmPlanes;\r
83   unsigned char bmBitsPixel;\r
84   unsigned char m1,m2;\r
85   unsigned long sizeimage;\r
86   short res1,res2;\r
87   long filesize, pixoff;\r
88   long bmisize, compression;\r
89   long xscale, yscale;\r
90   long colors, impcol;\r
91   unsigned long m_bytesRead = 0;\r
92   unsigned char *image;\r
93   FILE *fp;\r
94 \r
95   fp = fopen (gbmp.name, "rb");\r
96   if (fp == NULL)\r
97     return NULL;\r
98 \r
99   long rc;\r
100   rc = fread(&m1, 1, 1, fp);\r
101   m_bytesRead++;\r
102   if (rc == -1)\r
103   {\r
104     fclose(fp);\r
105     return NULL;\r
106   }\r
107 \r
108   rc = fread(&m2, 1, 1, fp);\r
109   m_bytesRead++;\r
110   if ((m1 != 'B') || (m2 != 'M'))\r
111   {\r
112     fclose(fp);\r
113     return NULL;\r
114   }\r
115 \r
116   rc = fread((long*)&(filesize),4,1,fp); m_bytesRead+=4;\r
117   if (rc != 1) { fclose(fp); return NULL; }\r
118 \r
119   rc = fread((int*)&(res1),2,1,fp); m_bytesRead+=2;\r
120   if (rc != 1) { fclose(fp); return NULL; }\r
121 \r
122   rc = fread((int*)&(res2),2,1,fp); m_bytesRead+=2;\r
123   if (rc != 1) { fclose(fp); return NULL; }\r
124 \r
125   rc = fread((long*)&(pixoff),4,1,fp); m_bytesRead+=4;\r
126   if (rc != 1) { fclose(fp); return NULL; }\r
127 \r
128   rc = fread((long*)&(bmisize),4,1,fp); m_bytesRead+=4;\r
129   if (rc != 1) { fclose(fp); return NULL; }\r
130 \r
131   rc = fread((long  *)&(bmWidth),4,1,fp); m_bytesRead+=4;\r
132   if (rc != 1) { fclose(fp); return NULL; }\r
133 \r
134   rc = fread((long*)&(bmHeight),4,1,fp); m_bytesRead+=4;\r
135   if (rc != 1) { fclose(fp); return NULL; }\r
136 \r
137   rc = fread((int*)&(bmPlanes),2,1,fp); m_bytesRead+=2;\r
138   if (rc != 1) { fclose(fp); return NULL; }\r
139 \r
140   rc = fread((int*)&(bmBitsPixel),2,1,fp); m_bytesRead+=2;\r
141   if (rc != 1) { fclose(fp); return NULL; }\r
142 \r
143   rc = fread((long*)&(compression),4,1,fp); m_bytesRead+=4;\r
144   if (rc != 1) { fclose(fp); return NULL; }\r
145 \r
146   rc = fread((long*)&(sizeimage),4,1,fp); m_bytesRead+=4;\r
147   if (rc != 1) {fclose(fp); return NULL; }\r
148 \r
149   rc = fread((long*)&(xscale),4,1,fp); m_bytesRead+=4;\r
150   if (rc != 1) { fclose(fp); return NULL; }\r
151 \r
152   rc = fread((long*)&(yscale),4,1,fp); m_bytesRead+=4;\r
153   if (rc != 1) { fclose(fp); return NULL; }\r
154 \r
155   rc = fread((long*)&(colors),4,1,fp); m_bytesRead+=4;\r
156   if (rc != 1) { fclose(fp); return NULL; }\r
157 \r
158   rc = fread((long*)&(impcol),4,1,fp); m_bytesRead+=4;\r
159   if (rc != 1) { fclose(fp); return NULL; }\r
160 \r
161   if (bmBitsPixel != 8)\r
162   {\r
163     g_FuncTable.m_pfnMessageBox (g_pWnd, "This is not an 8-bit image. GenSurf can't use it.",\r
164                                  "Bitmap", MB_ICONEXCLAMATION);\r
165     fclose(fp);\r
166     return NULL; \r
167   }\r
168 \r
169   if (colors == 0)\r
170     colors = 1 << bmBitsPixel;\r
171 \r
172   if (bmBitsPixel != 24)\r
173   {\r
174     int i;\r
175     for (i = 0; i < colors; i++)\r
176     {\r
177       unsigned char r ,g, b, dummy;\r
178 \r
179       rc = fread(&b, 1, 1, fp);\r
180       m_bytesRead++;\r
181       if (rc!=1)\r
182       {\r
183         fclose(fp);\r
184         return NULL;\r
185       }\r
186 \r
187       rc = fread(&g, 1, 1, fp); \r
188       m_bytesRead++;\r
189       if (rc!=1)\r
190       {\r
191         fclose(fp);\r
192         return NULL;\r
193       }\r
194 \r
195       rc = fread(&r, 1, 1, fp); \r
196       m_bytesRead++;\r
197       if (rc != 1)\r
198       {\r
199         fclose(fp);\r
200         return NULL;\r
201       }\r
202 \r
203       rc = fread(&dummy, 1, 1, fp); \r
204       m_bytesRead++;\r
205       if (rc != 1)\r
206       {\r
207         fclose(fp);\r
208         return NULL;\r
209       }\r
210     }\r
211   }\r
212 \r
213   if ((long)m_bytesRead > pixoff)\r
214   {\r
215     fclose(fp);\r
216     return NULL;\r
217   }\r
218 \r
219   while ((long)m_bytesRead < pixoff)\r
220   {\r
221     char dummy;\r
222     fread(&dummy,1,1,fp);\r
223     m_bytesRead++;\r
224   }\r
225 \r
226   int w = bmWidth;\r
227   int h = bmHeight;\r
228 \r
229   // set the output params\r
230   image = (unsigned char*)malloc(w*h);\r
231 \r
232   if (image != NULL) \r
233   {\r
234     gbmp.width = w;\r
235     gbmp.height = h;\r
236     unsigned char* outbuf = image;\r
237     long row = 0;\r
238     long rowOffset = 0;\r
239 \r
240     if (compression == 0) // BI_RGB\r
241     {\r
242       for (row = 0; row < bmHeight; row++)\r
243       {\r
244         // which row are we working on?\r
245         rowOffset = (long unsigned)row*w;                                                     \r
246 \r
247         {\r
248           // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them\r
249           int bit_count = 0;\r
250           unsigned long mask = (1 << bmBitsPixel) - 1;\r
251           unsigned char inbyte = 0;\r
252 \r
253           for (int col=0;col<w;col++)\r
254           {\r
255             int pix = 0;\r
256 \r
257             // if we need another byte\r
258             if (bit_count <= 0)\r
259             {\r
260               bit_count = 8;\r
261               if (fread(&inbyte,1,1,fp) != 1)\r
262               {\r
263                 free(image);\r
264                 fclose(fp);\r
265                 return NULL;\r
266               }\r
267               m_bytesRead++;\r
268             }\r
269 \r
270             // keep track of where we are in the bytes\r
271             bit_count -= bmBitsPixel;\r
272             pix = ( inbyte >> bit_count) & mask;\r
273 \r
274             // lookup the color from the colormap - stuff it in our buffer\r
275             // swap red and blue\r
276             *(outbuf + rowOffset + col) = pix;\r
277           }\r
278 \r
279           // read DWORD padding\r
280           while ((m_bytesRead-pixoff)&3)\r
281           {\r
282             char dummy;\r
283             if (fread(&dummy,1,1,fp)!=1)\r
284             {\r
285               free(image);\r
286               fclose(fp);\r
287               return NULL;\r
288             }\r
289             m_bytesRead++;\r
290           }\r
291         }\r
292       }\r
293     }\r
294     else    // compression != 0\r
295     {\r
296       int i, x = 0;\r
297       unsigned char c, c1 = 0, *pp;\r
298       row = 0;\r
299       pp = outbuf;\r
300 \r
301       if (bmBitsPixel == 8)\r
302       {\r
303         while (row < bmHeight)\r
304         {\r
305           c = getc(fp);\r
306 \r
307           if (c)\r
308           {\r
309             // encoded mode\r
310             c1 = getc(fp);\r
311             for (i = 0; i < c; x++, i++)\r
312             {\r
313               *pp = c1; pp++;\r
314             }\r
315           }\r
316           else\r
317           {\r
318             // c==0x00,  escape codes\r
319             c = getc(fp);\r
320 \r
321             if (c == 0x00) // end of line\r
322             {\r
323               row++;\r
324               x = 0;\r
325               pp = outbuf + row*bmWidth;\r
326             }\r
327             else if (c == 0x01)\r
328               break; // end of pic\r
329             else if (c == 0x02) // delta\r
330             {\r
331               c = getc(fp);\r
332               x += c;\r
333               c = getc(fp);\r
334               row += c;\r
335               pp = outbuf + x + row*bmWidth;\r
336             }\r
337             else // absolute mode\r
338             {\r
339               for (i = 0; i < c; x++, i++)\r
340               {\r
341                 c1 = getc(fp);\r
342                 *pp = c1; pp++;\r
343               }\r
344 \r
345               if (c & 1)\r
346                 getc(fp); // odd length run: read an extra pad byte\r
347             }\r
348           }\r
349         }\r
350       }\r
351       else if (bmBitsPixel == 4)\r
352       {\r
353         while (row < bmHeight)\r
354         {\r
355           c = getc(fp);\r
356 \r
357           if (c)\r
358           {\r
359             // encoded mode\r
360             c1 = getc(fp);\r
361             for (i = 0; i < c; x++, i++)\r
362             {\r
363               *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f); pp++;\r
364             }\r
365           }\r
366           else\r
367           {\r
368             // c==0x00,  escape codes\r
369             c = getc(fp);\r
370 \r
371             if (c == 0x00) // end of line\r
372             {\r
373               row++;\r
374               x = 0;\r
375               pp = outbuf + bmHeight*bmWidth;\r
376             }\r
377             else if (c == 0x01)\r
378               break; // end of pic\r
379             else if (c == 0x02) // delta\r
380             {\r
381               c = getc(fp);\r
382               x += c;\r
383               c = getc(fp);\r
384               row += c;\r
385               pp = outbuf + x + row*bmWidth;\r
386             }\r
387             else // absolute mode\r
388             {\r
389               for (i = 0; i < c; x++, i++)\r
390               {\r
391                 if ((i&1) == 0)\r
392                   c1 = getc(fp);\r
393                 *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f); pp++;\r
394               }\r
395 \r
396               if (((c&3) == 1) || ((c&3) == 2))\r
397                 getc(fp); // odd length run: read an extra pad byte\r
398             }\r
399           }\r
400         }\r
401       }\r
402     }\r
403   }\r
404   fclose(fp);\r
405   return image;\r
406 }\r
407 \r
408 bool OpenBitmap ()\r
409 {\r
410   if (gbmp.colors)\r
411     free (gbmp.colors);\r
412 \r
413   gbmp.colors = OpenBitmapFile ();\r
414 \r
415   if (!gbmp.colors)\r
416   {\r
417     char Text[256];\r
418 \r
419     sprintf (Text, "Error opening %s", gbmp.name);\r
420     g_FuncTable.m_pfnMessageBox (g_pWnd, Text, "Bitmap", MB_ICONEXCLAMATION);\r
421     strcpy (gbmp.name, "");\r
422   }\r
423 \r
424   if (g_pWnd)\r
425   {\r
426     gtk_entry_set_text (GTK_ENTRY (g_object_get_data (G_OBJECT (g_pWnd), "bmp_file")), gbmp.name);\r
427     gtk_widget_set_sensitive (GTK_WIDGET (g_object_get_data (G_OBJECT (g_pWnd), "bmp_reload")),\r
428                               strlen (gbmp.name) ? TRUE : FALSE);\r
429 \r
430     UpdatePreview (true);\r
431   }\r
432 \r
433   return (gbmp.colors != NULL);\r
434 }\r