diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 78af56d12e974d58aefda55c77c73a384c6de511..ca514a49afd0f40a984ac3d9455a2c930f2b50b0 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -519,8 +519,8 @@ void CreateOutputFile(const std::string &fileName, int format, bool redraw)
       int repeat = (int)(CTX::instance()->post.animDelay * 24);
       if(repeat < 1) repeat = 1;
       std::string pattern("I");
-      // including P frames would lead to smaller files, but the
-      // quality degradation is perceptible:
+      // including P frames would lead to smaller files, but the quality
+      // degradation is perceptible:
       // for(int i = 1; i < repeat; i++) pattern += "P";
       fprintf(fp, "PATTERN %s\nBASE_FILE_FORMAT PPM\nGOP_SIZE %d\n"
               "SLICES_PER_FRAME 1\nPIXEL FULL\nRANGE 10\n"
diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp
index c5a51abbbb1fcd6972a7c9aaeee10ad617d3e800..b7dbc331ded7ebef063405b92f1e425a48327658 100644
--- a/Fltk/fileDialogs.cpp
+++ b/Fltk/fileDialogs.cpp
@@ -183,14 +183,16 @@ int genericBitmapFileDialog(const char *name, const char *title, int format)
 {
   struct _genericBitmapFileDialog{
     Fl_Window *window;
+    Fl_Value_Slider *s[2];
     Fl_Check_Button *b[3];
+    Fl_Value_Input *v[2];
     Fl_Button *ok, *cancel;
   };
   static _genericBitmapFileDialog *dialog = NULL;
 
   if(!dialog){
     dialog = new _genericBitmapFileDialog;
-    int h = 3 * WB + 4 * BH, w = 2 * BB + 3 * WB, y = WB;
+    int h = 3 * WB + 7 * BH, w = 2 * BB + 3 * WB, y = WB;
     dialog->window = new Fl_Double_Window(w, h);
     dialog->window->box(GMSH_WINDOW_BOX);
     dialog->window->set_modal();
@@ -203,16 +205,52 @@ int genericBitmapFileDialog(const char *name, const char *title, int format)
     dialog->b[2] = new Fl_Check_Button
       (WB, y, 2 * BB + WB, BH, "Composite all window tiles"); y += BH;
     dialog->b[2]->type(FL_TOGGLE_BUTTON);
+    dialog->v[0] = new Fl_Value_Input
+      (WB, y, BB / 2, BH);
+    dialog->v[0]->minimum(-1);
+    dialog->v[0]->maximum(5000);
+    dialog->v[0]->step(1);
+    dialog->v[1] = new Fl_Value_Input
+      (WB + BB / 2, y, BB - BB / 2, BH, "Dimensions"); y += BH;
+    dialog->v[1]->minimum(-1);
+    dialog->v[1]->maximum(5000);
+    dialog->v[1]->step(1);
+    dialog->v[1]->align(FL_ALIGN_RIGHT);
+    dialog->s[0] = new Fl_Value_Slider(WB, y, BB, BH, "Quality"); y += BH;
+    dialog->s[0]->type(FL_HOR_SLIDER);
+    dialog->s[0]->align(FL_ALIGN_RIGHT);
+    dialog->s[0]->minimum(1);
+    dialog->s[0]->maximum(100);
+    dialog->s[0]->step(1);
+    dialog->s[1] = new Fl_Value_Slider(WB, y, BB, BH, "Smoothing"); y += BH;
+    dialog->s[1]->type(FL_HOR_SLIDER);
+    dialog->s[1]->align(FL_ALIGN_RIGHT);
+    dialog->s[1]->minimum(0);
+    dialog->s[1]->maximum(100);
+    dialog->s[1]->step(1);
     dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
     dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
     dialog->window->end();
     dialog->window->hotspot(dialog->window);
   }
 
+  if(format == FORMAT_JPEG){
+    dialog->s[0]->activate();
+    dialog->s[1]->activate();
+  }
+  else{
+    dialog->s[0]->deactivate();
+    dialog->s[1]->deactivate();
+  }
+
   dialog->window->label(title);
+  dialog->s[0]->value(CTX::instance()->print.jpegQuality);
+  dialog->s[1]->value(CTX::instance()->print.jpegSmoothing);
   dialog->b[0]->value(CTX::instance()->print.text);
   dialog->b[1]->value(CTX::instance()->print.background);
   dialog->b[2]->value(CTX::instance()->print.compositeWindows);
+  dialog->v[0]->value(CTX::instance()->print.width);
+  dialog->v[1]->value(CTX::instance()->print.height);
   dialog->window->show();
 
   while(dialog->window->shown()){
@@ -221,9 +259,13 @@ int genericBitmapFileDialog(const char *name, const char *title, int format)
       Fl_Widget* o = Fl::readqueue();
       if (!o) break;
       if (o == dialog->ok) {
+        opt_print_jpeg_quality(0, GMSH_SET | GMSH_GUI, (int)dialog->s[0]->value());
+        opt_print_jpeg_smoothing(0, GMSH_SET | GMSH_GUI, (int)dialog->s[1]->value());
         opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b[0]->value());
         opt_print_background(0, GMSH_SET | GMSH_GUI, (int)dialog->b[1]->value());
         opt_print_composite_windows(0, GMSH_SET | GMSH_GUI, (int)dialog->b[2]->value());
+        opt_print_width(0, GMSH_SET | GMSH_GUI, (int)dialog->v[0]->value());
+        opt_print_height(0, GMSH_SET | GMSH_GUI, (int)dialog->v[1]->value());
         CreateOutputFile(name, format);
         dialog->window->hide();
         return 1;
@@ -286,82 +328,6 @@ int latexFileDialog(const char *name)
   return 0;
 }
 
-// Save jpeg dialog
-
-int jpegFileDialog(const char *name)
-{
-  struct _jpegFileDialog{
-    Fl_Window *window;
-    Fl_Value_Slider *s[2];
-    Fl_Check_Button *b[3];
-    Fl_Button *ok, *cancel;
-  };
-  static _jpegFileDialog *dialog = NULL;
-
-  if(!dialog){
-    dialog = new _jpegFileDialog;
-    int h = 3 * WB + 6 * BH, w = 2 * BB + 3 * WB, y = WB;
-    dialog->window = new Fl_Double_Window(w, h, "JPEG Options");
-    dialog->window->box(GMSH_WINDOW_BOX);
-    dialog->window->set_modal();
-    dialog->s[0] = new Fl_Value_Slider(WB, y, BB, BH, "Quality"); y += BH;
-    dialog->s[0]->type(FL_HOR_SLIDER);
-    dialog->s[0]->align(FL_ALIGN_RIGHT);
-    dialog->s[0]->minimum(1);
-    dialog->s[0]->maximum(100);
-    dialog->s[0]->step(1);
-    dialog->s[1] = new Fl_Value_Slider(WB, y, BB, BH, "Smoothing"); y += BH;
-    dialog->s[1]->type(FL_HOR_SLIDER);
-    dialog->s[1]->align(FL_ALIGN_RIGHT);
-    dialog->s[1]->minimum(0);
-    dialog->s[1]->maximum(100);
-    dialog->s[1]->step(1);
-    dialog->b[0] = new Fl_Check_Button
-      (WB, y, 2 * BB + WB, BH, "Print text strings"); y += BH;
-    dialog->b[0]->type(FL_TOGGLE_BUTTON);
-    dialog->b[1] = new Fl_Check_Button
-      (WB, y, 2 * BB + WB, BH, "Print background"); y += BH;
-    dialog->b[1]->type(FL_TOGGLE_BUTTON);
-    dialog->b[2] = new Fl_Check_Button
-      (WB, y, 2 * BB + WB, BH, "Composite all window tiles"); y += BH;
-    dialog->b[2]->type(FL_TOGGLE_BUTTON);
-    dialog->ok = new Fl_Return_Button(WB, y + WB, BB, BH, "OK");
-    dialog->cancel = new Fl_Button(2 * WB + BB, y + WB, BB, BH, "Cancel");
-    dialog->window->end();
-    dialog->window->hotspot(dialog->window);
-  }
-
-  dialog->s[0]->value(CTX::instance()->print.jpegQuality);
-  dialog->s[1]->value(CTX::instance()->print.jpegSmoothing);
-  dialog->b[0]->value(CTX::instance()->print.text);
-  dialog->b[1]->value(CTX::instance()->print.background);
-  dialog->b[2]->value(CTX::instance()->print.compositeWindows);
-  dialog->window->show();
-
-  while(dialog->window->shown()){
-    Fl::wait();
-    for (;;) {
-      Fl_Widget* o = Fl::readqueue();
-      if (!o) break;
-      if (o == dialog->ok) {
-        opt_print_jpeg_quality(0, GMSH_SET | GMSH_GUI, (int)dialog->s[0]->value());
-        opt_print_jpeg_smoothing(0, GMSH_SET | GMSH_GUI, (int)dialog->s[1]->value());
-        opt_print_text(0, GMSH_SET | GMSH_GUI, (int)dialog->b[0]->value());
-        opt_print_background(0, GMSH_SET | GMSH_GUI, (int)dialog->b[1]->value());
-        opt_print_composite_windows(0, GMSH_SET | GMSH_GUI, (int)dialog->b[2]->value());
-        CreateOutputFile(name, FORMAT_JPEG);
-        dialog->window->hide();
-        return 1;
-      }
-      if (o == dialog->window || o == dialog->cancel){
-        dialog->window->hide();
-        return 0;
-      }
-    }
-  }
-  return 0;
-}
-
 // Save mpeg dialog
 
 int mpegFileDialog(const char *name)
diff --git a/Fltk/fileDialogs.h b/Fltk/fileDialogs.h
index 8e2e23cf174b9b4518ce6a7f0b0c66fbb61e8e8d..9c8602068f044008fcd29a28887a7d853994d5c3 100644
--- a/Fltk/fileDialogs.h
+++ b/Fltk/fileDialogs.h
@@ -9,10 +9,10 @@
 #include <string>
 
 typedef enum {
-  FILE_CHOOSER_SINGLE, 
-  FILE_CHOOSER_MULTI, 
-  FILE_CHOOSER_CREATE, 
-  FILE_CHOOSER_DIRECTORY 
+  FILE_CHOOSER_SINGLE,
+  FILE_CHOOSER_MULTI,
+  FILE_CHOOSER_CREATE,
+  FILE_CHOOSER_DIRECTORY
 } FILE_CHOOSER_TYPE;
 
 int fileChooser(FILE_CHOOSER_TYPE type, const char *message,
@@ -21,7 +21,6 @@ std::string fileChooserGetName(int num);
 int fileChooserGetFilter();
 void fileChooserGetPosition(int *x, int *y);
 
-int jpegFileDialog(const char *filename);
 int mpegFileDialog(const char *filename);
 int gifFileDialog(const char *filename);
 int geoFileDialog(const char *filename);
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index 58838593ca86742b173552f6b5f48616b4fe698c..8e7038397c2ff6de4d5cadb18e4dff1708f63f7d 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -289,7 +289,8 @@ static int _save_ply2(const char *name){ return genericMeshFileDialog
 static int _save_eps(const char *name){ return gl2psFileDialog
     (name, "EPS Options", FORMAT_EPS); }
 static int _save_gif(const char *name){ return gifFileDialog(name); }
-static int _save_jpeg(const char *name){ return jpegFileDialog(name); }
+static int _save_jpeg(const char *name){ return genericBitmapFileDialog
+    (name, "JPEG Options", FORMAT_JPEG); }
 static int _save_mpeg(const char *name){ return mpegFileDialog(name); }
 static int _save_tex(const char *name){ return latexFileDialog(name); }
 static int _save_pdf(const char *name){ return gl2psFileDialog