1 // PixMap.cpp: implementation of the CPixMap class.
3 //////////////////////////////////////////////////////////////////////
11 #include <gdk/win32/gdkwin32.h>
16 //////////////////////////////////////////////////////////////////////
17 // Construction/Destruction
18 //////////////////////////////////////////////////////////////////////
30 unsigned char* CPixMap::load_bitmap_file (const char* filename,guint16* width, guint16* height)
32 gint32 bmWidth, bmHeight;
33 guint16 bmPlanes, bmBitsPixel;
35 unsigned char rgbBlue;
36 unsigned char rgbGreen;
38 unsigned char rgbReserved;
41 unsigned long sizeimage;
43 long filesize, pixoff;
44 long bmisize, compression;
47 unsigned long m_bytesRead = 0;
48 unsigned char *imagebits = NULL;
53 fp = fopen(filename,"rb");
58 rc = fread(&m1, 1, 1, fp);
66 rc = fread(&m2, 1, 1, fp);
68 if ((m1!='B') || (m2!='M'))
74 rc = fread((long*)&(filesize),4,1,fp); m_bytesRead+=4;
75 if (rc != 1) { fclose(fp); return NULL; }
77 rc = fread((int*)&(res1),2,1,fp); m_bytesRead+=2;
78 if (rc != 1) { fclose(fp); return NULL; }
80 rc = fread((int*)&(res2),2,1,fp); m_bytesRead+=2;
81 if (rc != 1) { fclose(fp); return NULL; }
83 rc = fread((long*)&(pixoff),4,1,fp); m_bytesRead+=4;
84 if (rc != 1) { fclose(fp); return NULL; }
86 rc = fread((long*)&(bmisize),4,1,fp); m_bytesRead+=4;
87 if (rc != 1) { fclose(fp); return NULL; }
89 rc = fread((long*)&(bmWidth),4,1,fp); m_bytesRead+=4;
90 if (rc != 1) { fclose(fp); return NULL; }
92 rc = fread((long*)&(bmHeight),4,1,fp); m_bytesRead+=4;
93 if (rc != 1) { fclose(fp); return NULL; }
95 rc = fread((int*)&(bmPlanes),2,1,fp); m_bytesRead+=2;
96 if (rc != 1) { fclose(fp); return NULL; }
98 rc = fread((int*)&(bmBitsPixel),2,1,fp); m_bytesRead+=2;
99 if (rc != 1) { fclose(fp); return NULL; }
101 rc = fread((long*)&(compression),4,1,fp); m_bytesRead+=4;
102 if (rc != 1) { fclose(fp); return NULL; }
104 rc = fread((long*)&(sizeimage),4,1,fp); m_bytesRead+=4;
105 if (rc != 1) {fclose(fp); return NULL; }
107 rc = fread((long*)&(xscale),4,1,fp); m_bytesRead+=4;
108 if (rc != 1) { fclose(fp); return NULL; }
110 rc = fread((long*)&(yscale),4,1,fp); m_bytesRead+=4;
111 if (rc != 1) { fclose(fp); return NULL; }
113 rc = fread((long*)&(colors),4,1,fp); m_bytesRead+=4;
114 if (rc != 1) { fclose(fp); return NULL; }
116 rc = fread((long*)&(impcol),4,1,fp); m_bytesRead+=4;
117 if (rc != 1) { fclose(fp); return NULL; }
120 colors = 1 << bmBitsPixel;
122 RGBQUAD *colormap = NULL;
124 if (bmBitsPixel != 24)
126 colormap = new RGBQUAD[colors];
127 if (colormap == NULL)
134 for (i = 0; i < colors; i++)
136 unsigned char r ,g, b, dummy;
138 rc = fread(&b, 1, 1, fp);
147 rc = fread(&g, 1, 1, fp);
156 rc = fread(&r, 1, 1, fp);
165 rc = fread(&dummy, 1, 1, fp);
174 colormap[i].rgbRed=r;
175 colormap[i].rgbGreen=g;
176 colormap[i].rgbBlue=b;
180 if ((long)m_bytesRead > pixoff)
187 while ((long)m_bytesRead < pixoff)
190 fread(&dummy,1,1,fp);
197 // set the output params
198 imagebits = (unsigned char*)malloc(w*h*3);
199 long row_size = w * 3;
201 if (imagebits != NULL)
205 unsigned char* outbuf = imagebits;
209 if (compression == 0) // BI_RGB
211 // read rows in reverse order
212 for (row=bmHeight-1;row>=0;row--)
214 // which row are we working on?
215 rowOffset = (long unsigned)row*row_size;
217 if (bmBitsPixel == 24)
219 for (int col=0;col<w;col++)
221 long offset = col * 3;
224 if (fread((void*)(pixel),1,3,fp)==3)
226 // we swap red and blue here
227 *(outbuf + rowOffset + offset + 0)=pixel[2]; // r
228 *(outbuf + rowOffset + offset + 1)=pixel[1]; // g
229 *(outbuf + rowOffset + offset + 2)=pixel[0]; // b
232 m_bytesRead += row_size;
234 // read DWORD padding
235 while ((m_bytesRead-pixoff)&3)
238 if (fread(&dummy,1,1,fp) != 1)
249 // pixels are packed as 1 , 4 or 8 bit vals. need to unpack them
251 unsigned long mask = (1 << bmBitsPixel) - 1;
252 unsigned char inbyte = 0;
254 for (int col=0;col<w;col++)
258 // if we need another byte
262 if (fread(&inbyte,1,1,fp) != 1)
272 // keep track of where we are in the bytes
273 bit_count -= bmBitsPixel;
274 pix = ( inbyte >> bit_count) & mask;
276 // lookup the color from the colormap - stuff it in our buffer
278 *(outbuf + rowOffset + col * 3 + 2) = colormap[pix].rgbBlue;
279 *(outbuf + rowOffset + col * 3 + 1) = colormap[pix].rgbGreen;
280 *(outbuf + rowOffset + col * 3 + 0) = colormap[pix].rgbRed;
283 // read DWORD padding
284 while ((m_bytesRead-pixoff)&3)
287 if (fread(&dummy,1,1,fp)!=1)
303 unsigned char c, c1 = 0, *pp;
305 pp = outbuf + (bmHeight-1)*bmWidth*3;
307 if (bmBitsPixel == 8)
309 while (row < bmHeight)
317 for (i = 0; i < c; x++, i++)
319 *pp = colormap[c1].rgbRed; pp++;
320 *pp = colormap[c1].rgbGreen; pp++;
321 *pp = colormap[c1].rgbBlue; pp++;
326 // c==0x00, escape codes
329 if (c == 0x00) // end of line
333 pp = outbuf + (bmHeight-row-1)*bmWidth*3;
337 else if (c == 0x02) // delta
343 pp = outbuf + x*3 + (bmHeight-row-1)*bmWidth*3;
345 else // absolute mode
347 for (i = 0; i < c; x++, i++)
350 *pp = colormap[c1].rgbRed; pp++;
351 *pp = colormap[c1].rgbGreen; pp++;
352 *pp = colormap[c1].rgbBlue; pp++;
356 getc(fp); // odd length run: read an extra pad byte
361 else if (bmBitsPixel == 4)
363 while (row < bmHeight)
371 for (i = 0; i < c; x++, i++)
373 *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbRed; pp++;
374 *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbGreen; pp++;
375 *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbBlue; pp++;
380 // c==0x00, escape codes
383 if (c == 0x00) // end of line
387 pp = outbuf + (bmHeight-row-1)*bmWidth*3;
391 else if (c == 0x02) // delta
397 pp = outbuf + x*3 + (bmHeight-row-1)*bmWidth*3;
399 else // absolute mode
401 for (i = 0; i < c; x++, i++)
405 *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbRed; pp++;
406 *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbGreen; pp++;
407 *pp = colormap[(i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f)].rgbBlue; pp++;
410 if (((c&3) == 1) || ((c&3) == 2))
411 getc(fp); // odd length run: read an extra pad byte
427 void CPixMap::bmp_to_pixmap (const char* filename, GdkPixmap **pixmap, GdkBitmap **mask)
429 guint16 width, height;
431 GdkWindow *window = GDK_ROOT_PARENT();
432 GdkColormap *colormap;
433 GdkGC* gc = gdk_gc_new (window);
437 *pixmap = *mask = NULL;
438 buf = load_bitmap_file (filename, &width, &height);
442 colormap = gdk_window_get_colormap (window);
443 *pixmap = gdk_pixmap_new (window, width, height, -1);
451 GPtrArray* pal = g_ptr_array_new ();
452 GdkColor** col = (GdkColor**)malloc (sizeof (GdkColor*) * height * width);
455 for (i = 0; i < height; i++)
456 for (j = 0; j < width; j++)
458 unsigned char* p = &buf[(i*width+j)*3];
460 for (k = 0; k < pal->len; k++)
462 PAL *pe = (PAL*)pal->pdata[k];
463 if ((pe->p[0] == p[0]) &&
464 (pe->p[1] == p[1]) &&
467 col[(i*width+j)] = &pe->c;
474 PAL *pe = (PAL*)malloc (sizeof (PAL));
476 pe->c.red = (gushort)(p[0]*0xFF);
477 pe->c.green = (gushort)(p[1]*0xFF);
478 pe->c.blue = (gushort)(p[2]*0xFF);
479 gdk_color_alloc (colormap, &pe->c);
480 col[(i*width+j)] = &pe->c;
482 g_ptr_array_add (pal, pe);
486 for (i = 0; i < height; i++)
487 for (j = 0; j < width; j++)
490 c.red = (gushort)(buf[(i*width+j)*3]*0xFF);
491 c.green = (gushort)(buf[(i*width+j)*3+1]*0xFF);
492 c.blue = (gushort)(buf[(i*width+j)*3+2]*0xFF);
493 gdk_color_alloc (colormap, &c);
494 gdk_gc_set_foreground(gc, &c);
495 gdk_draw_point(*pixmap, gc, j, i);
497 gdk_gc_set_foreground(gc, col[(i*width+j)]);
498 gdk_draw_point(*pixmap, gc, j, i);
502 for (k = 0; k < pal->len; k++)
503 free (pal->pdata[k]);
504 g_ptr_array_free (pal, TRUE);
507 *mask = gdk_pixmap_new (window, width, height, 1);
508 gc = gdk_gc_new (*mask);
510 for (i = 0; i < height; i++)
511 for (j = 0; j < width; j++)
513 GdkColor mask_pattern;
515 // pink is transparent
516 if ((buf[(i*width+j)*3] == 0xff) &&
517 (buf[(i*width+j)*3+1] == 0x00) &&
518 (buf[(i*width+j)*3+2] == 0xff))
519 mask_pattern.pixel = 0;
521 mask_pattern.pixel = 1;
523 gdk_gc_set_foreground (gc, &mask_pattern);
524 // possible Win32 Gtk bug here
525 // gdk_draw_point (*mask, gc, j, i);
526 gdk_draw_line (*mask, gc, j, i, j + 1, i);
533 void CPixMap::load_pixmap (const char* filename, GdkPixmap **gdkpixmap, GdkBitmap **mask)
537 str = g_strBitmapsPath;
539 bmp_to_pixmap (str.GetBuffer (),gdkpixmap, mask);
541 if (*gdkpixmap == NULL)
543 char *dummy[] = { "1 1 1 1", " c None", " " };
544 *gdkpixmap = gdk_pixmap_create_from_xpm_d (GDK_ROOT_PARENT(), mask, NULL, dummy);
548 // Load a xpm file and return a pixmap widget.
549 GtkWidget* CPixMap::new_pixmap (GtkWidget* widget, char* filename)
551 GdkPixmap *gdkpixmap;
555 load_pixmap (filename, &gdkpixmap, &mask);
556 pixmap = gtk_pixmap_new (gdkpixmap, mask);
558 gdk_pixmap_unref (gdkpixmap);
559 gdk_pixmap_unref (mask);
561 // g_FuncTable.m_pfnLoadBitmap( filename, &pixmap, &mask )
566 GtkWidget* CPixMap::pixmap_from_char(GtkWidget *window, gchar **xpm_data)
573 style = gtk_widget_get_style( window );
574 pixmap = gdk_pixmap_create_from_xpm_d( window->window, &mask,
575 &style->bg[GTK_STATE_NORMAL],
576 (gchar **)xpm_data );
578 widget = gtk_pixmap_new( pixmap, mask );