home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / app / brightness_contrast.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-12-17  |  13.6 KB  |  493 lines

  1. /* The GIMP -- an image manipulation program
  2.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include <gtk/gtk.h>
  22.  
  23. #include "apptypes.h"
  24.  
  25. #include "appenv.h"
  26. #include "brightness_contrast.h"
  27. #include "drawable.h"
  28. #include "gimplut.h"
  29. #include "gimpui.h"
  30. #include "gdisplay.h"
  31. #include "image_map.h"
  32. #include "lut_funcs.h"
  33.  
  34. #include "libgimp/gimpintl.h"
  35.  
  36. #define SLIDER_WIDTH 200
  37.  
  38. #define BRIGHTNESS  0x1
  39. #define CONTRAST    0x2
  40. #define ALL        (BRIGHTNESS | CONTRAST)
  41.  
  42. /*  the brightness-contrast structures  */
  43.  
  44. typedef struct _BrightnessContrast BrightnessContrast;
  45.  
  46. struct _BrightnessContrast
  47. {
  48.   gint x, y;    /*  coords for last mouse click  */
  49. };
  50.  
  51. typedef struct _BrightnessContrastDialog BrightnessContrastDialog;
  52.  
  53. struct _BrightnessContrastDialog
  54. {
  55.   GtkWidget     *shell;
  56.   GtkWidget     *gimage_name;
  57.  
  58.   GtkAdjustment *brightness_data;
  59.   GtkAdjustment *contrast_data;
  60.  
  61.   GimpDrawable  *drawable;
  62.   ImageMap       image_map;
  63.  
  64.   gdouble        brightness;
  65.   gdouble        contrast;
  66.  
  67.   gboolean       preview;
  68.  
  69.   GimpLut       *lut;
  70. };
  71.  
  72.  
  73. /*  the brightness-contrast tool options  */
  74. static ToolOptions *brightness_contrast_options = NULL;
  75.  
  76. /*  the brightness-contrast dialog  */
  77. static BrightnessContrastDialog *brightness_contrast_dialog = NULL;
  78.  
  79.  
  80. /*  brightness contrast action functions  */
  81.  
  82. static void   brightness_contrast_control (Tool *, ToolAction, gpointer);
  83.  
  84. static BrightnessContrastDialog * brightness_contrast_dialog_new (void);
  85.  
  86. static void   brightness_contrast_update          (BrightnessContrastDialog *,
  87.                            gint);
  88. static void   brightness_contrast_preview         (BrightnessContrastDialog *);
  89. static void   brightness_contrast_reset_callback  (GtkWidget *, gpointer);
  90. static void   brightness_contrast_ok_callback     (GtkWidget *, gpointer);
  91. static void   brightness_contrast_cancel_callback (GtkWidget *, gpointer);
  92. static void   brightness_contrast_preview_update  (GtkWidget *, gpointer);
  93. static void   brightness_contrast_brightness_adjustment_update (GtkAdjustment *,
  94.                                 gpointer);
  95. static void   brightness_contrast_contrast_adjustment_update   (GtkAdjustment *,
  96.                                 gpointer);
  97.  
  98. /*  brightness-contrast select action functions  */
  99.  
  100. static void
  101. brightness_contrast_control (Tool       *tool,
  102.                  ToolAction  action,
  103.                  gpointer    gdisp_ptr)
  104. {
  105.   switch (action)
  106.     {
  107.     case PAUSE:
  108.       break;
  109.  
  110.     case RESUME:
  111.       break;
  112.  
  113.     case HALT:
  114.       brightness_contrast_dialog_hide ();
  115.       break;
  116.  
  117.     default:
  118.       break;
  119.     }
  120. }
  121.  
  122. Tool *
  123. tools_new_brightness_contrast (void)
  124. {
  125.   Tool * tool;
  126.   BrightnessContrast * private;
  127.  
  128.   /*  The tool options  */
  129.   if (!brightness_contrast_options)
  130.     {
  131.       brightness_contrast_options =
  132.     tool_options_new (_("Brightness-Contrast"));
  133.       tools_register (BRIGHTNESS_CONTRAST, brightness_contrast_options);
  134.    }
  135.  
  136.   tool = tools_new_tool (BRIGHTNESS_CONTRAST);
  137.   private = g_new0 (BrightnessContrast, 1);
  138.  
  139.   tool->scroll_lock = TRUE;   /*  Disallow scrolling  */
  140.   tool->preserve    = FALSE;  /*  Don't preserve on drawable change  */
  141.  
  142.   tool->private = (void *) private;
  143.  
  144.   tool->control_func = brightness_contrast_control;
  145.  
  146.   return tool;
  147. }
  148.  
  149. void
  150. brightness_contrast_dialog_hide (void)
  151. {
  152.   if (brightness_contrast_dialog)
  153.     brightness_contrast_cancel_callback (NULL,
  154.                                      (gpointer) brightness_contrast_dialog);
  155.   
  156. void
  157. tools_free_brightness_contrast (Tool *tool)
  158. {
  159.   BrightnessContrast * bc;
  160.  
  161.   bc = (BrightnessContrast *) tool->private;
  162.  
  163.   /*  Close the brightness-contrast dialog  */
  164.   brightness_contrast_dialog_hide ();
  165.  
  166.   g_free (bc);
  167. }
  168.  
  169. void
  170. brightness_contrast_initialize (GDisplay *gdisp)
  171. {
  172.   if (drawable_indexed (gimage_active_drawable (gdisp->gimage)))
  173.     {
  174.       g_message (_("Brightness-Contrast does not operate on indexed drawables."));
  175.       return;
  176.     }
  177.  
  178.   /*  The brightness-contrast dialog  */
  179.   if (!brightness_contrast_dialog)
  180.     brightness_contrast_dialog = brightness_contrast_dialog_new ();
  181.   else
  182.     if (!GTK_WIDGET_VISIBLE (brightness_contrast_dialog->shell))
  183.       gtk_widget_show (brightness_contrast_dialog->shell);
  184.  
  185.   brightness_contrast_dialog->brightness = 0.0;
  186.   brightness_contrast_dialog->contrast   = 0.0;
  187.  
  188.   brightness_contrast_dialog->drawable = gimage_active_drawable (gdisp->gimage);
  189.   brightness_contrast_dialog->image_map =
  190.     image_map_create (gdisp, brightness_contrast_dialog->drawable);
  191.  
  192.   brightness_contrast_update (brightness_contrast_dialog, ALL);
  193. }
  194.  
  195. /********************************/
  196. /*  Brightness Contrast dialog  */
  197. /********************************/
  198.  
  199. static BrightnessContrastDialog *
  200. brightness_contrast_dialog_new (void)
  201. {
  202.   BrightnessContrastDialog *bcd;
  203.   GtkWidget *vbox;
  204.   GtkWidget *hbox;
  205.   GtkWidget *table;
  206.   GtkWidget *label;
  207.   GtkWidget *abox;
  208.   GtkWidget *spinbutton;
  209.   GtkWidget *slider;
  210.   GtkWidget *toggle;
  211.   GtkObject *data;
  212.  
  213.   bcd = g_new (BrightnessContrastDialog, 1);
  214.   bcd->preview = TRUE;
  215.  
  216.   bcd->lut = gimp_lut_new ();
  217.  
  218.   /*  The shell and main vbox  */
  219.   bcd->shell =
  220.     gimp_dialog_new (_("Brightness-Contrast"), "brightness_contrast",
  221.              tools_help_func, NULL,
  222.              GTK_WIN_POS_NONE,
  223.              FALSE, TRUE, FALSE,
  224.  
  225.              _("OK"), brightness_contrast_ok_callback,
  226.              bcd, NULL, NULL, TRUE, FALSE,
  227.              _("Reset"), brightness_contrast_reset_callback,
  228.              bcd, NULL, NULL, TRUE, FALSE,
  229.              _("Cancel"), brightness_contrast_cancel_callback,
  230.              bcd, NULL, NULL, FALSE, TRUE,
  231.  
  232.              NULL);
  233.  
  234.   vbox = gtk_vbox_new (FALSE, 4);
  235.   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  236.   gtk_container_add (GTK_CONTAINER (GTK_DIALOG (bcd->shell)->vbox), vbox);
  237.  
  238.   /*  The table containing sliders  */
  239.   table = gtk_table_new (2, 3, FALSE);
  240.   gtk_table_set_col_spacings (GTK_TABLE (table), 4);
  241.   gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  242.   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
  243.  
  244.   /*  Create the brightness scale widget  */
  245.   label = gtk_label_new (_("Brightness:"));
  246.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
  247.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
  248.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  249.  
  250.   data = gtk_adjustment_new (0, -127, 127.0, 1.0, 10.0, 0.0);
  251.   bcd->brightness_data = GTK_ADJUSTMENT (data);
  252.   slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
  253.   gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
  254.   gtk_scale_set_digits (GTK_SCALE (slider), 0);
  255.   gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
  256.   gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
  257.   gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 0, 1);
  258.  
  259.   abox = gtk_vbox_new (FALSE, 0);
  260.   spinbutton = gtk_spin_button_new (bcd->brightness_data, 1.0, 0);
  261.   gtk_widget_set_usize (spinbutton, 75, -1);
  262.   gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
  263.   gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 0, 1,
  264.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  265.  
  266.   gtk_signal_connect (GTK_OBJECT (data), "value_changed",
  267.               GTK_SIGNAL_FUNC (brightness_contrast_brightness_adjustment_update),
  268.               bcd);
  269.  
  270.   gtk_widget_show (label);
  271.   gtk_widget_show (slider);
  272.   gtk_widget_show (spinbutton);
  273.   gtk_widget_show (abox);
  274.  
  275.   /*  Create the contrast scale widget  */
  276.   label = gtk_label_new (_("Contrast:"));
  277.   gtk_misc_set_alignment (GTK_MISC (label), 1.0, 1.0);
  278.   gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
  279.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  280.  
  281.   data = gtk_adjustment_new (0, -127.0, 127.0, 1.0, 10.0, 0.0);
  282.   bcd->contrast_data = GTK_ADJUSTMENT (data);
  283.   slider = gtk_hscale_new (GTK_ADJUSTMENT (data));
  284.   gtk_widget_set_usize (slider, SLIDER_WIDTH, -1);
  285.   gtk_scale_set_digits (GTK_SCALE (slider), 0);
  286.   gtk_scale_set_value_pos (GTK_SCALE (slider), GTK_POS_TOP);
  287.   gtk_range_set_update_policy (GTK_RANGE (slider), GTK_UPDATE_DELAYED);
  288.   gtk_table_attach_defaults (GTK_TABLE (table), slider, 1, 2, 1, 2);
  289.  
  290.   abox = gtk_vbox_new (FALSE, 0);
  291.   spinbutton = gtk_spin_button_new (bcd->contrast_data, 1.0, 0);
  292.   gtk_widget_set_usize (spinbutton, 75, -1);
  293.   gtk_box_pack_end (GTK_BOX (abox), spinbutton, FALSE, FALSE, 0);
  294.   gtk_table_attach (GTK_TABLE (table), abox, 2, 3, 1, 2,
  295.             GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  296.  
  297.   gtk_signal_connect (GTK_OBJECT (data), "value_changed",
  298.               GTK_SIGNAL_FUNC (brightness_contrast_contrast_adjustment_update),
  299.               bcd);
  300.  
  301.   gtk_widget_show (label);
  302.   gtk_widget_show (slider);
  303.   gtk_widget_show (spinbutton);
  304.   gtk_widget_show (abox);
  305.  
  306.   /*  Horizontal box for preview toggle button  */
  307.   hbox = gtk_hbox_new (FALSE, 4);
  308.   gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
  309.  
  310.   /*  The preview toggle  */
  311.   toggle = gtk_check_button_new_with_label (_("Preview"));
  312.   gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), bcd->preview);
  313.   gtk_box_pack_end (GTK_BOX (hbox), toggle, FALSE, FALSE, 0);
  314.   gtk_signal_connect (GTK_OBJECT (toggle), "toggled",
  315.               GTK_SIGNAL_FUNC (brightness_contrast_preview_update),
  316.               bcd);
  317.  
  318.   gtk_widget_show (toggle);
  319.   gtk_widget_show (hbox);
  320.  
  321.   gtk_widget_show (table);
  322.   gtk_widget_show (vbox);
  323.   gtk_widget_show (bcd->shell);
  324.  
  325.   return bcd;
  326. }
  327.  
  328. static void
  329. brightness_contrast_update (BrightnessContrastDialog *bcd,
  330.                 gint                      update)
  331. {
  332.   if (update & BRIGHTNESS)
  333.     {
  334.       gtk_adjustment_set_value (bcd->brightness_data, bcd->brightness);
  335.     }
  336.   if (update & CONTRAST)
  337.     {
  338.       gtk_adjustment_set_value (bcd->contrast_data, bcd->contrast);
  339.     }
  340. }
  341.  
  342. static void
  343. brightness_contrast_preview (BrightnessContrastDialog *bcd)
  344. {
  345.   if (!bcd->image_map)
  346.     {
  347.       g_message ("brightness_contrast_preview(): No image map");
  348.       return;
  349.     }
  350.  
  351.   active_tool->preserve = TRUE;
  352.   brightness_contrast_lut_setup (bcd->lut, bcd->brightness / 255.0,
  353.                  bcd->contrast / 127.0,
  354.                  gimp_drawable_bytes (bcd->drawable));
  355.   image_map_apply (bcd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
  356.            (void *) bcd->lut);
  357.   active_tool->preserve = FALSE;
  358. }
  359.  
  360. static void
  361. brightness_contrast_reset_callback (GtkWidget *widget,
  362.                     gpointer   data)
  363. {
  364.   BrightnessContrastDialog *bcd;
  365.  
  366.   bcd = (BrightnessContrastDialog *) data;
  367.  
  368.   bcd->brightness = 0.0;
  369.   bcd->contrast   = 0.0;
  370.  
  371.   brightness_contrast_update (bcd, ALL);
  372.  
  373.   if (bcd->preview)
  374.     brightness_contrast_preview (bcd);
  375. }
  376.  
  377. static void
  378. brightness_contrast_ok_callback (GtkWidget *widget,
  379.                  gpointer   data)
  380. {
  381.   BrightnessContrastDialog *bcd;
  382.  
  383.   bcd = (BrightnessContrastDialog *) data;
  384.  
  385.   gimp_dialog_hide (bcd->shell);
  386.  
  387.   active_tool->preserve = TRUE;
  388.  
  389.   if (!bcd->preview)
  390.   {
  391.     brightness_contrast_lut_setup (bcd->lut, bcd->brightness / 255.0,
  392.                    bcd->contrast / 127.0,
  393.                    gimp_drawable_bytes (bcd->drawable));
  394.     image_map_apply (bcd->image_map, (ImageMapApplyFunc) gimp_lut_process_2,
  395.              (void *) bcd->lut);
  396.   }
  397.  
  398.   if (bcd->image_map)
  399.     image_map_commit (bcd->image_map);
  400.  
  401.   active_tool->preserve = FALSE;
  402.  
  403.   bcd->image_map = NULL;
  404.  
  405.   active_tool->gdisp_ptr = NULL;
  406.   active_tool->drawable = NULL;
  407. }
  408.  
  409. static void
  410. brightness_contrast_cancel_callback (GtkWidget *widget,
  411.                      gpointer   data)
  412. {
  413.   BrightnessContrastDialog *bcd;
  414.  
  415.   bcd = (BrightnessContrastDialog *) data;
  416.  
  417.   gimp_dialog_hide (bcd->shell);
  418.  
  419.   if (bcd->image_map)
  420.     {
  421.       active_tool->preserve = TRUE;
  422.       image_map_abort (bcd->image_map);
  423.       active_tool->preserve = FALSE;
  424.  
  425.       bcd->image_map = NULL;
  426.       gdisplays_flush ();
  427.     }
  428.  
  429.   active_tool->gdisp_ptr = NULL;
  430.   active_tool->drawable = NULL;
  431. }
  432.  
  433. static void
  434. brightness_contrast_preview_update (GtkWidget *widget,
  435.                     gpointer   data)
  436. {
  437.   BrightnessContrastDialog *bcd;
  438.  
  439.   bcd = (BrightnessContrastDialog *) data;
  440.  
  441.   if (GTK_TOGGLE_BUTTON (widget)->active)
  442.     {
  443.       bcd->preview = TRUE;
  444.       brightness_contrast_preview (bcd);
  445.     }
  446.   else
  447.     {
  448.       bcd->preview = FALSE;
  449.       if (bcd->image_map)
  450.     {
  451.       active_tool->preserve = TRUE;
  452.       image_map_clear (bcd->image_map);
  453.       active_tool->preserve = FALSE;
  454.       gdisplays_flush ();
  455.     }
  456.     }
  457. }
  458.  
  459. static void
  460. brightness_contrast_brightness_adjustment_update (GtkAdjustment *adjustment,
  461.                           gpointer       data)
  462. {
  463.   BrightnessContrastDialog *bcd;
  464.  
  465.   bcd = (BrightnessContrastDialog *) data;
  466.  
  467.   if (bcd->brightness != adjustment->value)
  468.     {
  469.       bcd->brightness = adjustment->value;
  470.  
  471.       if (bcd->preview)
  472.     brightness_contrast_preview (bcd);
  473.     }
  474. }
  475.  
  476. static void
  477. brightness_contrast_contrast_adjustment_update (GtkAdjustment *adjustment,
  478.                         gpointer       data)
  479. {
  480.   BrightnessContrastDialog *bcd;
  481.  
  482.   bcd = (BrightnessContrastDialog *) data;
  483.  
  484.   if (bcd->contrast != adjustment->value)
  485.     {
  486.       bcd->contrast = adjustment->value;
  487.  
  488.       if (bcd->preview)
  489.     brightness_contrast_preview (bcd);
  490.     }
  491. }
  492.