From 3425e135ec9bf9bf1648e3962796b88d4cde857a Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Sun, 19 Dec 1999 12:20:38 +0000 Subject: [PATCH] resolution support for the BMP plug-in --Sven --- ChangeLog | 8 +++ plug-ins/bmp/bmp.c | 39 +++++++----- plug-ins/bmp/bmpread.c | 93 ++++++++++++++++++++++----- plug-ins/bmp/bmpwrite.c | 137 ++++++++++++++++++++++++++++------------ 4 files changed, 205 insertions(+), 72 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad84bc327b..0a5a4ca7da 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sun Dec 19 13:16:51 CET 1999 Sven Neumann + + * plug-ins/bmp/bmp.c + * plug-ins/bmp/bmpread.c + * plug-ins/bmp/bmpwrite.c: + Applied a patch from muppet that adds resolution + support for the BMP plug-in. Did some code cleanup while I was on it. + Sat Dec 18 20:40:44 CET 1999 Sven Neumann * plug-ins/imagemap/imap_about.c diff --git a/plug-ins/bmp/bmp.c b/plug-ins/bmp/bmp.c index 12bc825e0e..abfc00340e 100644 --- a/plug-ins/bmp/bmp.c +++ b/plug-ins/bmp/bmp.c @@ -23,6 +23,7 @@ /* 16 and 32 bit images */ /* 28.11.1998 Bug in RLE-read-padding */ /* fixed. */ +/* 19.12.1999 Resolution support added */ /* * The GIMP -- an image manipulation program @@ -89,9 +90,9 @@ query () { static GParamDef load_args[] = { - { PARAM_INT32, "run_mode", "Interactive, non-interactive" }, - { PARAM_STRING, "filename", "The name of the file to load" }, - { PARAM_STRING, "raw_filename", "The name entered" }, + { PARAM_INT32, "run_mode", "Interactive, non-interactive" }, + { PARAM_STRING, "filename", "The name of the file to load" }, + { PARAM_STRING, "raw_filename", "The name entered" }, }; static GParamDef load_return_vals[] = { @@ -102,11 +103,11 @@ query () static GParamDef save_args[] = { - { PARAM_INT32, "run_mode", "Interactive, non-interactive" }, - { PARAM_IMAGE, "image", "Input image" }, - { PARAM_DRAWABLE, "drawable", "Drawable to save" }, - { PARAM_STRING, "filename", "The name of the file to save the image in" }, - { PARAM_STRING, "raw_filename", "The name entered" }, + { PARAM_INT32, "run_mode", "Interactive, non-interactive" }, + { PARAM_IMAGE, "image", "Input image" }, + { PARAM_DRAWABLE, "drawable", "Drawable to save" }, + { PARAM_STRING, "filename", "The name of the file to save the image in" }, + { PARAM_STRING, "raw_filename", "The name entered" }, }; static int nsave_args = sizeof (save_args) / sizeof (save_args[0]); @@ -135,7 +136,7 @@ query () save_args, NULL); gimp_register_magic_load_handler ("file_bmp_load", "bmp", "", "0,string,BM"); - gimp_register_save_handler ("file_bmp_save", "bmp", ""); + gimp_register_save_handler ("file_bmp_save", "bmp", ""); } static void @@ -180,7 +181,7 @@ run (char *name, break; } - image_ID = ReadBMP(param[1].data.d_string); + image_ID = ReadBMP (param[1].data.d_string); if (image_ID != -1) { @@ -254,17 +255,21 @@ run (char *name, } } -gint32 ToL(guchar *puffer) +gint32 +ToL (guchar *puffer) { - return(puffer[0] | puffer[1]<<8 | puffer[2]<<16 | puffer[3]<<24); + return (puffer[0] | puffer[1]<<8 | puffer[2]<<16 | puffer[3]<<24); } -gint16 ToS(guchar *puffer) +gint16 +ToS (guchar *puffer) { - return(puffer[0] | puffer[1]<<8); + return (puffer[0] | puffer[1]<<8); } -void FromL(gint32 wert, guchar *bopuffer) +void +FromL (gint32 wert, + guchar *bopuffer) { bopuffer[0]=(wert & 0x000000ff)>>0x00; bopuffer[1]=(wert & 0x0000ff00)>>0x08; @@ -272,7 +277,9 @@ void FromL(gint32 wert, guchar *bopuffer) bopuffer[3]=(wert & 0xff000000)>>0x18; } -void FromS(gint16 wert, guchar *bopuffer) +void +FromS (gint16 wert, + guchar *bopuffer) { bopuffer[0]=(wert & 0x00ff)>>0x00; bopuffer[1]=(wert & 0xff00)>>0x08; diff --git a/plug-ins/bmp/bmpread.c b/plug-ins/bmp/bmpread.c index 80de5f509d..b5d562bf0c 100644 --- a/plug-ins/bmp/bmpread.c +++ b/plug-ins/bmp/bmpread.c @@ -2,6 +2,26 @@ /* except OS2 bitmaps (wrong colors) */ /* Alexander.Schulz@stud.uni-karlsruhe.de */ +/* + * The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * ---------------------------------------------------------------------------- + */ + #include "config.h" #include #include @@ -11,8 +31,9 @@ #include "bmp.h" #include "libgimp/stdplugins-intl.h" -gint32 ReadBMP (name) - char *name; + +gint32 +ReadBMP (char *name) { FILE *fd; char *temp_buf; @@ -20,6 +41,7 @@ gint32 ReadBMP (name) int ColormapSize, SpeicherZeile, Maps, Grey; unsigned char ColorMap[256][3]; guchar puffer[50]; + gint32 image_ID; if (interactive_bmp) { @@ -141,18 +163,50 @@ gint32 ReadBMP (name) #endif /* Get the Image and return the ID or -1 on error*/ + image_ID = ReadImage (fd, + Bitmap_Head.biWidth, + Bitmap_Head.biHeight, + ColorMap, + Bitmap_Head.biClrUsed, + Bitmap_Head.biBitCnt, + Bitmap_Head.biCompr, + SpeicherZeile, + Grey); + +#ifdef GIMP_HAVE_RESOLUTION_INFO + { + /* quick hack by the muppet, scott@asofyet.org, 19 dec 1999 */ + double xresolution; + double yresolution; - return(ReadImage(fd, Bitmap_Head.biWidth, Bitmap_Head.biHeight, ColorMap, - Bitmap_Head.biClrUsed, Bitmap_Head.biBitCnt, Bitmap_Head.biCompr, SpeicherZeile, Grey)); + /* + * xresolution and yresolution are in dots per inch. + * the BMP spec says that biXPels and biYPels are in + * pixels per meter as long ints (actually, "DWORDS"). + * this means we've lost some accuracy in the numbers. + * typically, the dots per inch settings on BMPs will + * be integer numbers of dots per inch, which is freaky + * because they're stored in the BMP as metric. *sigh* + * so, we'll round this off, even though the gimp wants + * a floating point number... + */ + #define LROUND(x) ((long int)((x)+0.5)) + xresolution = LROUND((Bitmap_Head.biXPels * 2.54 / 100.0)); + yresolution = LROUND((Bitmap_Head.biYPels * 2.54 / 100.0)); + #undef LROUND + gimp_image_set_resolution (image_ID, xresolution, yresolution); + } +#endif /* GIMP_HAVE_RESOLUTION_INFO */ + return (image_ID); } -gint ReadColorMap (fd, buffer, number, size, grey) - FILE *fd; - int number; - unsigned char buffer[256][3]; - int size; - int *grey; +gint +ReadColorMap (FILE *fd, + unsigned char buffer[256][3], + int number, + int size, + int *grey) { int i; unsigned char rgb[4]; @@ -183,11 +237,16 @@ gint ReadColorMap (fd, buffer, number, size, grey) return(0); } -Image ReadImage (fd, len, height, cmap, ncols, bpp, compression, spzeile, grey) - FILE *fd; - int len, height; - unsigned char cmap[256][3]; - int ncols, bpp, compression, spzeile, grey; +Image +ReadImage (FILE *fd, + int len, + int height, + unsigned char cmap[256][3], + int ncols, + int bpp, + int compression, + int spzeile, + int grey) { char *name_buf; unsigned char v,wieviel; @@ -372,6 +431,6 @@ Image ReadImage (fd, len, height, cmap, ncols, bpp, compression, spzeile, grey) gimp_drawable_flush(drawable); gimp_drawable_detach(drawable); g_free(dest); - return(image); - + + return (image); } diff --git a/plug-ins/bmp/bmpwrite.c b/plug-ins/bmp/bmpwrite.c index 6aa92f5ace..003e3e25de 100644 --- a/plug-ins/bmp/bmpwrite.c +++ b/plug-ins/bmp/bmpwrite.c @@ -7,6 +7,26 @@ /* Alexander.Schulz@stud.uni-karlsruhe.de */ +/* + * The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * ---------------------------------------------------------------------------- + */ + #include "config.h" #include @@ -15,7 +35,7 @@ #ifdef HAVE_UNISTD_H #include #endif - + #include #include #include "bmp.h" @@ -39,18 +59,15 @@ static BMPSaveInterface gsint = int encoded = 0; -static gint save_dialog (); -static void save_close_callback (GtkWidget *widget, - gpointer data); -static void save_ok_callback (GtkWidget *widget, - gpointer data); -static void save_toggle_update (GtkWidget *widget, - gpointer data); +static gint save_dialog (void); +static void save_close_callback (GtkWidget *widget, gpointer data); +static void save_ok_callback (GtkWidget *widget, gpointer data); +static void save_toggle_update (GtkWidget *widget, gpointer data); gint -WriteBMP (filename,image,drawable_ID) - char *filename; - gint32 image,drawable_ID; +WriteBMP (char *filename, + gint32 image, + gint32 drawable_ID) { FILE *outfile; int Red[MAXCOLORS]; @@ -127,13 +144,14 @@ WriteBMP (filename,image,drawable_ID) } /* Perhaps someone wants RLE encoded Bitmaps */ - encoded = 0; - if (((BitsPerPixel==8) || (BitsPerPixel==4)) && interactive_bmp) {if (! save_dialog ()) {return -1;}} - - - /* Let's take some file */ - + if ((BitsPerPixel == 8 || BitsPerPixel == 4) && interactive_bmp) + { + if (! save_dialog ()) + return -1; + } + + /* Let's take some file */ outfile = fopen (filename, "wb"); if (!outfile) { @@ -181,10 +199,35 @@ WriteBMP (filename,image,drawable_ID) else if (BitsPerPixel==4) Bitmap_Head.biCompr=2; else Bitmap_Head.biCompr=0; Bitmap_Head.biSizeIm=SpZeile*rows; - Bitmap_Head.biXPels=1; - Bitmap_Head.biYPels=1; - if (BitsPerPixel<24) Bitmap_Head.biClrUsed=colors; - else Bitmap_Head.biClrUsed=0; +#ifdef GIMP_HAVE_RESOLUTION_INFO + { + double xresolution; + double yresolution; + gimp_image_get_resolution (image, &xresolution, &yresolution); + + if (xresolution > 1e-5 && yresolution > 1e-5) { + /* + * xresolution and yresolution are in dots per inch. + * the BMP spec says that biXPels and biYPels are in + * pixels per meter as long ints (actually, "DWORDS"), + * so... + * n dots inch 100 cm m dots + * ------ * ------- * ------ = ------ + * inch 2.54 cm m inch + */ + Bitmap_Head.biXPels = (long int) xresolution * 100.0 / 2.54; + Bitmap_Head.biYPels = (long int) yresolution * 100.0 / 2.54; + } + } +#else /* GIMP_HAVE_RESOLUTION_INFO */ + Bitmap_Head.biXPels = 1; + Bitmap_Head.biYPels = 1; +#endif /* GIMP_HAVE_RESOLUTION_INFO */ + if (BitsPerPixel<24) + Bitmap_Head.biClrUsed=colors; + else + Bitmap_Head.biClrUsed=0; + Bitmap_Head.biClrImp=Bitmap_Head.biClrUsed; #ifdef DEBUG @@ -230,8 +273,12 @@ WriteBMP (filename,image,drawable_ID) return TRUE; } -void WriteColorMap(FILE *f, int red[MAXCOLORS], int green[MAXCOLORS], - int blue[MAXCOLORS], int size) +void +WriteColorMap (FILE *f, + int red[MAXCOLORS], + int green[MAXCOLORS], + int blue[MAXCOLORS], + int size) { char trgb[4]; int i; @@ -247,14 +294,20 @@ void WriteColorMap(FILE *f, int red[MAXCOLORS], int green[MAXCOLORS], } } -void WriteImage(f, src, width, height, encoded, channels, bpp, spzeile, MapSize) - FILE *f; - guchar *src; - int width,height,encoded,channels,bpp,spzeile,MapSize; +void +WriteImage (FILE *f, + guchar *src, + int width, + int height, + int encoded, + int channels, + int bpp, + int spzeile, + int MapSize) { guchar buf[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0}; guchar puffer[8]; - guchar *temp,v,g; + guchar *temp,v; guchar *Zeile,*ketten; int xpos,ypos,i,j,rowstride,laenge,thiswidth; int breite, n, k; @@ -432,11 +485,10 @@ save_dialog () { GtkWidget *dlg; GtkWidget *button; + GtkWidget *hbbox; GtkWidget *toggle; GtkWidget *frame; GtkWidget *vbox; - gchar **argv; - gint argc; dlg = gtk_dialog_new (); gtk_window_set_title (GTK_WINDOW (dlg), _("Save as BMP")); @@ -446,30 +498,37 @@ save_dialog () NULL); /* Action area */ + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dlg)->action_area), 2); + gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (dlg)->action_area), FALSE); + hbbox = gtk_hbutton_box_new (); + gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbbox), 4); + gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dlg)->action_area), hbbox, FALSE, FALSE, 0); + gtk_widget_show (hbbox); + button = gtk_button_new_with_label (_("OK")); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_signal_connect (GTK_OBJECT (button), "clicked", - (GtkSignalFunc) save_ok_callback, - dlg); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0); + (GtkSignalFunc) save_ok_callback, + dlg); + gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0); gtk_widget_grab_default (button); gtk_widget_show (button); button = gtk_button_new_with_label (_("Cancel")); GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", - (GtkSignalFunc) gtk_widget_destroy, - GTK_OBJECT (dlg)); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->action_area), button, TRUE, TRUE, 0); + (GtkSignalFunc) gtk_widget_destroy, + GTK_OBJECT (dlg)); + gtk_box_pack_start (GTK_BOX (hbbox), button, FALSE, FALSE, 0); gtk_widget_show (button); /* parameter settings */ frame = gtk_frame_new (_("Save Options")); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); - gtk_container_border_width (GTK_CONTAINER (frame), 10); + gtk_container_border_width (GTK_CONTAINER (frame), 4); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), frame, TRUE, TRUE, 0); - vbox = gtk_vbox_new (FALSE, 5); - gtk_container_border_width (GTK_CONTAINER (vbox), 5); + vbox = gtk_vbox_new (FALSE, 4); + gtk_container_border_width (GTK_CONTAINER (vbox), 4); gtk_container_add (GTK_CONTAINER (frame), vbox); toggle = gtk_check_button_new_with_label (_("RLE encoded"));